Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
61b59517fc | |||
b801bf699f | |||
e34b880a55 | |||
ac0ef71d9f |
@ -52,6 +52,8 @@ type Client struct {
|
||||
timeNow func() time.Time
|
||||
generateXID func() uint32
|
||||
|
||||
timeoutCount int
|
||||
|
||||
// last DHCPACK packet for renewal/release
|
||||
Ack *layers.DHCPv4
|
||||
}
|
||||
@ -129,7 +131,18 @@ func (c *Client) ObtainOrRenew() bool {
|
||||
ack, err := c.dhcpRequest()
|
||||
if err != nil {
|
||||
if errno, ok := err.(syscall.Errno); ok && errno == syscall.EAGAIN {
|
||||
c.err = fmt.Errorf("DHCP: timeout (server(s) unreachable)")
|
||||
var serverip net.IP
|
||||
for _, opt := range c.Ack.Options {
|
||||
if opt.Type == layers.DHCPOptServerID {
|
||||
serverip = opt.Data
|
||||
}
|
||||
}
|
||||
c.err = fmt.Errorf("DHCP: timeout (server(s) unreachable: %v)", serverip)
|
||||
c.timeoutCount++
|
||||
if c.timeoutCount > 3 {
|
||||
c.timeoutCount = 0
|
||||
c.Ack = nil // start over at DHCPDISCOVER it has failed 3 times
|
||||
}
|
||||
return true // temporary error
|
||||
}
|
||||
if err == errNAK {
|
||||
@ -154,6 +167,7 @@ func (c *Client) ObtainOrRenew() bool {
|
||||
}
|
||||
}
|
||||
c.cfg.RenewAfter = c.timeNow().Add(lease.RenewalTime)
|
||||
c.timeoutCount = 0
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -92,8 +92,8 @@ func NewServer(addr, domain string) *Server {
|
||||
// https://developers.google.com/speed/public-dns/docs/using#google_public_dns_ip_addresses
|
||||
"1.1.1.1:53",
|
||||
"1.0.0.1:53",
|
||||
"2606:4700:4700::1111:53",
|
||||
"2606:4700:4700::1001:53",
|
||||
"[2606:4700:4700::1111]:53",
|
||||
"[2606:4700:4700::1001]:53",
|
||||
"8.8.8.8:53",
|
||||
"8.8.4.4:53",
|
||||
"[2001:4860:4860::8888]:53",
|
||||
@ -536,37 +536,63 @@ func (s *Server) handleRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||
|
||||
s.promInc("DNS", r)
|
||||
|
||||
for idx, u := range s.upstreams() {
|
||||
in, _, err := s.client.Exchange(r, u)
|
||||
if err != nil {
|
||||
if s.sometimes.Allow() {
|
||||
log.Printf("resolving %v failed: %v", r.Question, err)
|
||||
if r.RecursionDesired {
|
||||
for idx, u := range s.upstreams() {
|
||||
in, _, err := s.client.Exchange(r, u)
|
||||
if err != nil {
|
||||
if s.sometimes.Allow() {
|
||||
log.Printf("resolving %v failed: %v", r.Question, err)
|
||||
}
|
||||
continue // fall back to next-slower upstream
|
||||
}
|
||||
continue // fall back to next-slower upstream
|
||||
}
|
||||
if len(in.Answer) > 1 {
|
||||
if in.Answer[0].Header().Rrtype == dns.TypeCNAME {
|
||||
for _, rr := range in.Answer {
|
||||
if rr.Header().Rrtype == dns.TypeA {
|
||||
if newRR, err := s.resolveSubname("", dns.Question{strings.ToLower(rr.Header().Name), dns.TypeA, dns.ClassINET}); err == nil {
|
||||
in.Answer[len(in.Answer)-1] = newRR
|
||||
if len(in.Answer) > 1 {
|
||||
if in.Answer[0].Header().Rrtype == dns.TypeCNAME {
|
||||
for i, rr := range in.Answer {
|
||||
if rr != nil && rr.Header() != nil && rr.Header().Rrtype == dns.TypeA {
|
||||
newRR, err := s.resolveSubname(string(s.domain), dns.Question{strings.ToLower(rr.Header().Name), dns.TypeA, dns.ClassINET})
|
||||
if err == nil && newRR != nil {
|
||||
in.Answer[i] = newRR
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
w.WriteMsg(in)
|
||||
if idx > 0 {
|
||||
// re-order this upstream to the front of s.upstream.
|
||||
s.upstreamMu.Lock()
|
||||
// if the upstreams were reordered in the meantime leave them alone
|
||||
if s.upstream[idx] == u {
|
||||
s.upstream = append(append([]string{u}, s.upstream[:idx]...), s.upstream[idx+1:]...)
|
||||
w.WriteMsg(in)
|
||||
if idx > 0 {
|
||||
// re-order this upstream to the front of s.upstream.
|
||||
s.upstreamMu.Lock()
|
||||
// if the upstreams were reordered in the meantime leave them alone
|
||||
if s.upstream[idx] == u {
|
||||
s.upstream = append(append([]string{u}, s.upstream[:idx]...), s.upstream[idx+1:]...)
|
||||
}
|
||||
s.upstreamMu.Unlock()
|
||||
}
|
||||
return
|
||||
}
|
||||
} else {
|
||||
for _, u := range s.upstreams() {
|
||||
nr := r.Copy()
|
||||
nr.Question[0].Qtype = dns.TypeSOA
|
||||
nr.RecursionDesired = true
|
||||
soa, _, err := s.client.Exchange(nr, u)
|
||||
fmt.Println(err, soa)
|
||||
fmt.Println()
|
||||
fmt.Println(soa.Ns)
|
||||
|
||||
if len(soa.Ns) > 0 {
|
||||
soa2 := soa.Ns[0].(*dns.SOA)
|
||||
in, _, err := s.client.Exchange(r, strings.TrimRight(soa2.Ns, ".")+":53")
|
||||
fmt.Println(err, in)
|
||||
if err != nil {
|
||||
if s.sometimes.Allow() {
|
||||
log.Printf("resolving %v failed: %v", r.Question, err)
|
||||
}
|
||||
continue // fall back to next-slower upstream
|
||||
}
|
||||
w.WriteMsg(in)
|
||||
return
|
||||
}
|
||||
s.upstreamMu.Unlock()
|
||||
}
|
||||
return
|
||||
}
|
||||
// DNS has no reply for resolving errors
|
||||
}
|
||||
|
Reference in New Issue
Block a user