istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pkg/dns/client/proxy.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package client 16 17 import ( 18 "net" 19 "time" 20 21 "github.com/miekg/dns" 22 ) 23 24 type dnsProxy struct { 25 serveMux *dns.ServeMux 26 server *dns.Server 27 28 // This is the upstream Client used to make upstream DNS queries 29 // in case the data is not in our name table. 30 upstreamClient *dns.Client 31 protocol string 32 resolver *LocalDNSServer 33 } 34 35 func newDNSProxy(protocol, addr string, resolver *LocalDNSServer) (*dnsProxy, error) { 36 p := &dnsProxy{ 37 serveMux: dns.NewServeMux(), 38 server: &dns.Server{}, 39 upstreamClient: &dns.Client{ 40 Net: protocol, 41 DialTimeout: 5 * time.Second, 42 ReadTimeout: 5 * time.Second, 43 WriteTimeout: 5 * time.Second, 44 }, 45 protocol: protocol, 46 resolver: resolver, 47 } 48 49 var err error 50 p.serveMux.Handle(".", p) 51 p.server.Handler = p.serveMux 52 if protocol == "udp" { 53 p.server.PacketConn, err = net.ListenPacket("udp", addr) 54 } else { 55 p.server.Listener, err = net.Listen("tcp", addr) 56 } 57 log.Infof("Starting local %s DNS server on %v", p.protocol, addr) 58 if err != nil { 59 log.Errorf("Failed to listen on %s port %s: %v", protocol, addr, err) 60 return nil, err 61 } 62 return p, nil 63 } 64 65 func (p *dnsProxy) start() { 66 err := p.server.ActivateAndServe() 67 if err != nil { 68 log.Errorf("Local %s DNS server terminated: %v", p.protocol, err) 69 } 70 } 71 72 func (p *dnsProxy) close() { 73 if p.server != nil { 74 if err := p.server.Shutdown(); err != nil { 75 log.Errorf("error in shutting down %s dns downstreamUDPServer :%v", p.protocol, err) 76 } 77 } 78 } 79 80 func (p *dnsProxy) Address() string { 81 if p.server != nil { 82 if p.server.Listener != nil { 83 return p.server.Listener.Addr().String() 84 } 85 if p.server.PacketConn != nil { 86 return p.server.PacketConn.LocalAddr().String() 87 } 88 } 89 return "" 90 } 91 92 func (p *dnsProxy) ServeDNS(w dns.ResponseWriter, req *dns.Msg) { 93 p.resolver.ServeDNS(p, w, req) 94 }