mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-05-15 00:50:25 +02:00
Improving Mac discovery
This commit is contained in:
committed by
Cuong Manh Le
parent
3007cb86ec
commit
76d2e2c226
@@ -1138,6 +1138,7 @@ func validateConfig(cfg *ctrld.Config) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// NOTE: Add more case here once new validation tag is used in ctrld.Config struct.
|
||||
func fieldErrorMsg(fe validator.FieldError) string {
|
||||
switch fe.Tag() {
|
||||
case "oneof":
|
||||
@@ -1165,6 +1166,8 @@ func fieldErrorMsg(fe validator.FieldError) string {
|
||||
return fmt.Sprintf("must be one of: %q", strings.Join(ipStacks, " "))
|
||||
case "iporempty":
|
||||
return fmt.Sprintf("invalid IP format: %s", fe.Value())
|
||||
case "file":
|
||||
return fmt.Sprintf("filed does not exist: %s", fe.Value())
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
+22
-9
@@ -55,7 +55,10 @@ func (p *prog) serveDNS(listenerNum string) error {
|
||||
q := m.Question[0]
|
||||
domain := canonicalName(q.Name)
|
||||
reqId := requestID()
|
||||
remoteAddr := spoofRemoteAddr(w.RemoteAddr(), p.mt.GetClientInfoByMac(macFromMsg(m)))
|
||||
remoteIP, _, _ := net.SplitHostPort(w.RemoteAddr().String())
|
||||
mac := macFromMsg(m)
|
||||
ci := p.getClientInfo(remoteIP, mac)
|
||||
remoteAddr := spoofRemoteAddr(w.RemoteAddr(), ci)
|
||||
fmtSrcToDest := fmtRemoteToLocal(listenerNum, remoteAddr.String(), w.LocalAddr().String())
|
||||
t := time.Now()
|
||||
ctx := context.WithValue(context.Background(), ctrld.ReqIdCtxKey{}, reqId)
|
||||
@@ -66,7 +69,7 @@ func (p *prog) serveDNS(listenerNum string) error {
|
||||
answer = new(dns.Msg)
|
||||
answer.SetRcode(m, dns.RcodeRefused)
|
||||
} else {
|
||||
answer = p.proxy(ctx, upstreams, failoverRcodes, m)
|
||||
answer = p.proxy(ctx, upstreams, failoverRcodes, m, ci)
|
||||
rtt := time.Since(t)
|
||||
ctrld.Log(ctx, mainLog.Debug(), "received response of %d bytes in %s", answer.Len(), rtt)
|
||||
}
|
||||
@@ -202,7 +205,7 @@ networkRules:
|
||||
return upstreams, matched
|
||||
}
|
||||
|
||||
func (p *prog) proxy(ctx context.Context, upstreams []string, failoverRcodes []int, msg *dns.Msg) *dns.Msg {
|
||||
func (p *prog) proxy(ctx context.Context, upstreams []string, failoverRcodes []int, msg *dns.Msg, ci *ctrld.ClientInfo) *dns.Msg {
|
||||
var staleAnswer *dns.Msg
|
||||
serveStaleCache := p.cache != nil && p.cfg.Service.CacheServeStale
|
||||
upstreamConfigs := p.upstreamConfigsFromUpstreamNumbers(upstreams)
|
||||
@@ -245,12 +248,9 @@ func (p *prog) proxy(ctx context.Context, upstreams []string, failoverRcodes []i
|
||||
return dnsResolver.Resolve(resolveCtx, msg)
|
||||
}
|
||||
resolve := func(n int, upstreamConfig *ctrld.UpstreamConfig, msg *dns.Msg) *dns.Msg {
|
||||
if upstreamConfig.UpstreamSendClientInfo() {
|
||||
ci := p.mt.GetClientInfoByMac(macFromMsg(msg))
|
||||
if ci != nil {
|
||||
ctrld.Log(ctx, mainLog.Debug(), "including client info with the request")
|
||||
ctx = context.WithValue(ctx, ctrld.ClientInfoCtxKey{}, ci)
|
||||
}
|
||||
if upstreamConfig.UpstreamSendClientInfo() && ci != nil {
|
||||
ctrld.Log(ctx, mainLog.Debug(), "including client info with the request")
|
||||
ctx = context.WithValue(ctx, ctrld.ClientInfoCtxKey{}, ci)
|
||||
}
|
||||
answer, err := resolve1(n, upstreamConfig, msg)
|
||||
if err != nil {
|
||||
@@ -510,3 +510,16 @@ func inContainer() bool {
|
||||
})
|
||||
return ret
|
||||
}
|
||||
|
||||
func (p *prog) getClientInfo(ip, mac string) *ctrld.ClientInfo {
|
||||
ci := &ctrld.ClientInfo{}
|
||||
if mac != "" {
|
||||
ci.Mac = mac
|
||||
ci.IP = p.ciTable.LookupIP(mac)
|
||||
} else {
|
||||
ci.IP = ip
|
||||
ci.Mac = p.ciTable.LookupMac(ip)
|
||||
}
|
||||
ci.Hostname = p.ciTable.LookupHostname(ci.IP, ci.Mac)
|
||||
return ci
|
||||
}
|
||||
|
||||
@@ -149,8 +149,8 @@ func TestCache(t *testing.T) {
|
||||
answer2.SetRcode(msg, dns.RcodeRefused)
|
||||
prog.cache.Add(dnscache.NewKey(msg, "upstream.0"), dnscache.NewValue(answer2, time.Now().Add(time.Minute)))
|
||||
|
||||
got1 := prog.proxy(context.Background(), []string{"upstream.1"}, nil, msg)
|
||||
got2 := prog.proxy(context.Background(), []string{"upstream.0"}, nil, msg)
|
||||
got1 := prog.proxy(context.Background(), []string{"upstream.1"}, nil, msg, nil)
|
||||
got2 := prog.proxy(context.Background(), []string{"upstream.0"}, nil, msg, nil)
|
||||
assert.NotSame(t, got1, got2)
|
||||
assert.Equal(t, answer1.Rcode, got1.Rcode)
|
||||
assert.Equal(t, answer2.Rcode, got2.Rcode)
|
||||
|
||||
+16
-18
@@ -48,11 +48,11 @@ type prog struct {
|
||||
logConn net.Conn
|
||||
cs *controlServer
|
||||
|
||||
cfg *ctrld.Config
|
||||
cache dnscache.Cacher
|
||||
sema semaphore
|
||||
mt *clientinfo.MacTable
|
||||
router router.Router
|
||||
cfg *ctrld.Config
|
||||
cache dnscache.Cacher
|
||||
sema semaphore
|
||||
ciTable *clientinfo.Table
|
||||
router router.Router
|
||||
|
||||
started chan struct{}
|
||||
onStarted []func()
|
||||
@@ -106,24 +106,22 @@ func (p *prog) run() {
|
||||
uc.Init()
|
||||
if uc.BootstrapIP == "" {
|
||||
uc.SetupBootstrapIP()
|
||||
mainLog.Info().Msgf("Bootstrap IPs for upstream.%s: %q", n, uc.BootstrapIPs())
|
||||
mainLog.Info().Msgf("bootstrap IPs for upstream.%s: %q", n, uc.BootstrapIPs())
|
||||
} else {
|
||||
mainLog.Info().Str("bootstrap_ip", uc.BootstrapIP).Msgf("Using bootstrap IP for upstream.%s", n)
|
||||
mainLog.Info().Str("bootstrap_ip", uc.BootstrapIP).Msgf("using bootstrap IP for upstream.%s", n)
|
||||
}
|
||||
uc.SetCertPool(rootCertPool)
|
||||
go uc.Ping()
|
||||
}
|
||||
|
||||
p.mt = clientinfo.NewMacTable()
|
||||
if p.cfg.HasUpstreamSendClientInfo() {
|
||||
mainLog.Debug().Msg("Sending client info enabled")
|
||||
if err := p.mt.Init(); err == nil {
|
||||
mainLog.Debug().Msg("Start watching client info changes")
|
||||
go p.mt.WatchLeaseFiles()
|
||||
} else {
|
||||
mainLog.Warn().Err(err).Msg("could not record client info")
|
||||
}
|
||||
p.ciTable = clientinfo.NewTable(&cfg)
|
||||
if leaseFile := p.cfg.Service.DHCPLeaseFile; leaseFile != "" {
|
||||
mainLog.Debug().Msgf("watching custom lease file: %s", leaseFile)
|
||||
format := ctrld.LeaseFileFormat(p.cfg.Service.DHCPLeaseFileFormat)
|
||||
p.ciTable.AddLeaseFile(leaseFile, format)
|
||||
}
|
||||
p.ciTable.Init()
|
||||
go p.ciTable.RefreshLoop(p.stopCh)
|
||||
go p.watchLinkState()
|
||||
|
||||
for listenerNum := range p.cfg.Listener {
|
||||
@@ -136,7 +134,7 @@ func (p *prog) run() {
|
||||
mainLog.Warn().Msgf("no default upstream for: [listener.%s]", listenerNum)
|
||||
}
|
||||
addr := net.JoinHostPort(listenerConfig.IP, strconv.Itoa(listenerConfig.Port))
|
||||
mainLog.Info().Msgf("Starting DNS server on listener.%s: %s", listenerNum, addr)
|
||||
mainLog.Info().Msgf("starting DNS server on listener.%s: %s", listenerNum, addr)
|
||||
err := p.serveDNS(listenerNum)
|
||||
if err != nil && !defaultConfigWritten && cdUID == "" {
|
||||
mainLog.Fatal().Err(err).Msgf("Unable to start dns proxy on listener.%s", listenerNum)
|
||||
@@ -162,7 +160,7 @@ func (p *prog) run() {
|
||||
p.cfg.Service.AllocateIP = true
|
||||
p.mu.Unlock()
|
||||
p.preRun()
|
||||
mainLog.Info().Msgf("Starting DNS server on listener.%s: %s", listenerNum, net.JoinHostPort(ip, strconv.Itoa(port)))
|
||||
mainLog.Info().Msgf("starting DNS server on listener.%s: %s", listenerNum, net.JoinHostPort(ip, strconv.Itoa(port)))
|
||||
if err := p.serveDNS(listenerNum); err != nil {
|
||||
mainLog.Fatal().Err(err).Msgf("Unable to start dns proxy on listener.%s", listenerNum)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user