all: add router client info detection

This commit add the ability for ctrld to gather client information,
including mac/ip/hostname, and send to Control-D server through a
config per upstream.

 - Add send_client_info upstream config.
 - Read/Watch dnsmasq leases files on supported platforms.
 - Add corresponding client info to DoH query header

All of these only apply for Control-D upstream, though.
This commit is contained in:
Cuong Manh Le
2023-04-20 23:16:20 +07:00
committed by Cuong Manh Le
parent d52cd11322
commit 0645a738ad
17 changed files with 370 additions and 27 deletions
+30 -2
View File
@@ -12,12 +12,22 @@ import (
"github.com/miekg/dns"
)
const (
DoHMacHeader = "Dns-Mac"
DoHIPHeader = "Dns-IP"
DoHHostHeader = "Dns-Host"
headerContentTypeValue = "application/dns-message"
headerAcceptValue = "application/dns-message"
)
func newDohResolver(uc *UpstreamConfig) *dohResolver {
r := &dohResolver{
endpoint: uc.u,
isDoH3: uc.Type == ResolverTypeDOH3,
transport: uc.transport,
http3RoundTripper: uc.http3RoundTripper,
sendClientInfo: uc.UpstreamSendClientInfo(),
}
return r
}
@@ -27,6 +37,7 @@ type dohResolver struct {
isDoH3 bool
transport *http.Transport
http3RoundTripper http.RoundTripper
sendClientInfo bool
}
func (r *dohResolver) Resolve(ctx context.Context, msg *dns.Msg) (*dns.Msg, error) {
@@ -45,8 +56,7 @@ func (r *dohResolver) Resolve(ctx context.Context, msg *dns.Msg) (*dns.Msg, erro
if err != nil {
return nil, fmt.Errorf("could not create request: %w", err)
}
req.Header.Set("Content-Type", "application/dns-message")
req.Header.Set("Accept", "application/dns-message")
addHeader(ctx, req, r.sendClientInfo)
c := http.Client{Transport: r.transport}
if r.isDoH3 {
@@ -78,3 +88,21 @@ func (r *dohResolver) Resolve(ctx context.Context, msg *dns.Msg) (*dns.Msg, erro
answer := new(dns.Msg)
return answer, answer.Unpack(buf)
}
func addHeader(ctx context.Context, req *http.Request, sendClientInfo bool) {
req.Header.Set("Content-Type", headerContentTypeValue)
req.Header.Set("Accept", headerAcceptValue)
if sendClientInfo {
if ci, ok := ctx.Value(ClientInfoCtxKey{}).(*ClientInfo); ok && ci != nil {
if ci.Mac != "" {
req.Header.Set(DoHMacHeader, ci.Mac)
}
if ci.IP != "" {
req.Header.Set(DoHIPHeader, ci.IP)
}
if ci.Hostname != "" {
req.Header.Set(DoHHostHeader, ci.Hostname)
}
}
}
}