1// DNS server implementation. 2 3package dns 4 5import ( 6 "context" 7 "crypto/tls" 8 "encoding/binary" 9 "errors" 10 "io" 11 "net" 12 "strings" 13 "sync" 14 "time" 15) 16 17// Default maximum number of TCP queries before we close the socket. 18const maxTCPQueries = 128 19 20// aLongTimeAgo is a non-zero time, far in the past, used for 21// immediate cancelation of network operations. 22var aLongTimeAgo = time.Unix(1, 0) 23 24// Handler is implemented by any value that implements ServeDNS. 25type Handler interface { 26 ServeDNS(w ResponseWriter, r *Msg) 27} 28 29// The HandlerFunc type is an adapter to allow the use of 30// ordinary functions as DNS handlers. If f is a function 31// with the appropriate signature, HandlerFunc(f) is a 32// Handler object that calls f. 33type HandlerFunc func(ResponseWriter, *Msg) 34 35// ServeDNS calls f(w, r). 36func (f HandlerFunc) ServeDNS(w ResponseWriter, r *Msg) { 37 f(w, r) 38} 39 40// A ResponseWriter interface is used by an DNS handler to 41// construct an DNS response. 42type ResponseWriter interface { 43 // LocalAddr returns the net.Addr of the server 44 LocalAddr() net.Addr 45 // RemoteAddr returns the net.Addr of the client that sent the current request. 46 RemoteAddr() net.Addr 47 // WriteMsg writes a reply back to the client. 48 WriteMsg(*Msg) error 49 // Write writes a raw buffer back to the client. 50 Write([]byte) (int, error) 51 // Close closes the connection. 52 Close() error 53 // TsigStatus returns the status of the Tsig. 54 TsigStatus() error 55 // TsigTimersOnly sets the tsig timers only boolean. 56 TsigTimersOnly(bool) 57 // Hijack lets the caller take over the connection. 58 // After a call to Hijack(), the DNS package will not do anything with the connection. 59 Hijack() 60} 61 62// A ConnectionStater interface is used by a DNS Handler to access TLS connection state 63// when available. 64type ConnectionStater interface { 65 ConnectionState() *tls.ConnectionState 66} 67 68type response struct { 69 closed bool // connection has been closed 70 hijacked bool // connection has been hijacked by handler 71 tsigTimersOnly bool 72 tsigStatus error 73 tsigRequestMAC string 74 tsigSecret map[string]string // the tsig secrets 75 udp net.PacketConn // i/o connection if UDP was used 76 tcp net.Conn // i/o connection if TCP was used 77 udpSession *SessionUDP // oob data to get egress interface right 78 pcSession net.Addr // address to use when writing to a generic net.PacketConn 79 writer Writer // writer to output the raw DNS bits 80} 81 82// handleRefused returns a HandlerFunc that returns REFUSED for every request it gets. 83func handleRefused(w ResponseWriter, r *Msg) { 84 m := new(Msg) 85 m.SetRcode(r, RcodeRefused) 86 w.WriteMsg(m) 87} 88 89// HandleFailed returns a HandlerFunc that returns SERVFAIL for every request it gets. 90// Deprecated: This function is going away. 91func HandleFailed(w ResponseWriter, r *Msg) { 92 m := new(Msg) 93 m.SetRcode(r, RcodeServerFailure) 94 // does not matter if this write fails 95 w.WriteMsg(m) 96} 97 98// ListenAndServe Starts a server on address and network specified Invoke handler 99// for incoming queries. 100func ListenAndServe(addr string, network string, handler Handler) error { 101 server := &Server{Addr: addr, Net: network, Handler: handler} 102 return server.ListenAndServe() 103} 104 105// ListenAndServeTLS acts like http.ListenAndServeTLS, more information in 106// http://golang.org/pkg/net/http/#ListenAndServeTLS 107func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error { 108 cert, err := tls.LoadX509KeyPair(certFile, keyFile) 109 if err != nil { 110 return err 111 } 112 113 config := tls.Config{ 114 Certificates: []tls.Certificate{cert}, 115 } 116 117 server := &Server{ 118 Addr: addr, 119 Net: "tcp-tls", 120 TLSConfig: &config, 121 Handler: handler, 122 } 123 124 return server.ListenAndServe() 125} 126 127// ActivateAndServe activates a server with a listener from systemd, 128// l and p should not both be non-nil. 129// If both l and p are not nil only p will be used. 130// Invoke handler for incoming queries. 131func ActivateAndServe(l net.Listener, p net.PacketConn, handler Handler) error { 132 server := &Server{Listener: l, PacketConn: p, Handler: handler} 133 return server.ActivateAndServe() 134} 135 136// Writer writes raw DNS messages; each call to Write should send an entire message. 137type Writer interface { 138 io.Writer 139} 140 141// Reader reads raw DNS messages; each call to ReadTCP or ReadUDP should return an entire message. 142type Reader interface { 143 // ReadTCP reads a raw message from a TCP connection. Implementations may alter 144 // connection properties, for example the read-deadline. 145 ReadTCP(conn net.Conn, timeout time.Duration) ([]byte, error) 146 // ReadUDP reads a raw message from a UDP connection. Implementations may alter 147 // connection properties, for example the read-deadline. 148 ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) 149} 150 151// PacketConnReader is an optional interface that Readers can implement to support using generic net.PacketConns. 152type PacketConnReader interface { 153 Reader 154 155 // ReadPacketConn reads a raw message from a generic net.PacketConn UDP connection. Implementations may 156 // alter connection properties, for example the read-deadline. 157 ReadPacketConn(conn net.PacketConn, timeout time.Duration) ([]byte, net.Addr, error) 158} 159 160// defaultReader is an adapter for the Server struct that implements the Reader and 161// PacketConnReader interfaces using the readTCP, readUDP and readPacketConn funcs 162// of the embedded Server. 163type defaultReader struct { 164 *Server 165} 166 167var _ PacketConnReader = defaultReader{} 168 169func (dr defaultReader) ReadTCP(conn net.Conn, timeout time.Duration) ([]byte, error) { 170 return dr.readTCP(conn, timeout) 171} 172 173func (dr defaultReader) ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) { 174 return dr.readUDP(conn, timeout) 175} 176 177func (dr defaultReader) ReadPacketConn(conn net.PacketConn, timeout time.Duration) ([]byte, net.Addr, error) { 178 return dr.readPacketConn(conn, timeout) 179} 180 181// DecorateReader is a decorator hook for extending or supplanting the functionality of a Reader. 182// Implementations should never return a nil Reader. 183// Readers should also implement the optional PacketConnReader interface. 184// PacketConnReader is required to use a generic net.PacketConn. 185type DecorateReader func(Reader) Reader 186 187// DecorateWriter is a decorator hook for extending or supplanting the functionality of a Writer. 188// Implementations should never return a nil Writer. 189type DecorateWriter func(Writer) Writer 190 191// A Server defines parameters for running an DNS server. 192type Server struct { 193 // Address to listen on, ":dns" if empty. 194 Addr string 195 // if "tcp" or "tcp-tls" (DNS over TLS) it will invoke a TCP listener, otherwise an UDP one 196 Net string 197 // TCP Listener to use, this is to aid in systemd's socket activation. 198 Listener net.Listener 199 // TLS connection configuration 200 TLSConfig *tls.Config 201 // UDP "Listener" to use, this is to aid in systemd's socket activation. 202 PacketConn net.PacketConn 203 // Handler to invoke, dns.DefaultServeMux if nil. 204 Handler Handler 205 // Default buffer size to use to read incoming UDP messages. If not set 206 // it defaults to MinMsgSize (512 B). 207 UDPSize int 208 // The net.Conn.SetReadTimeout value for new connections, defaults to 2 * time.Second. 209 ReadTimeout time.Duration 210 // The net.Conn.SetWriteTimeout value for new connections, defaults to 2 * time.Second. 211 WriteTimeout time.Duration 212 // TCP idle timeout for multiple queries, if nil, defaults to 8 * time.Second (RFC 5966). 213 IdleTimeout func() time.Duration 214 // Secret(s) for Tsig map[<zonename>]<base64 secret>. The zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2). 215 TsigSecret map[string]string 216 // If NotifyStartedFunc is set it is called once the server has started listening. 217 NotifyStartedFunc func() 218 // DecorateReader is optional, allows customization of the process that reads raw DNS messages. 219 DecorateReader DecorateReader 220 // DecorateWriter is optional, allows customization of the process that writes raw DNS messages. 221 DecorateWriter DecorateWriter 222 // Maximum number of TCP queries before we close the socket. Default is maxTCPQueries (unlimited if -1). 223 MaxTCPQueries int 224 // Whether to set the SO_REUSEPORT socket option, allowing multiple listeners to be bound to a single address. 225 // It is only supported on go1.11+ and when using ListenAndServe. 226 ReusePort bool 227 // AcceptMsgFunc will check the incoming message and will reject it early in the process. 228 // By default DefaultMsgAcceptFunc will be used. 229 MsgAcceptFunc MsgAcceptFunc 230 231 // Shutdown handling 232 lock sync.RWMutex 233 started bool 234 shutdown chan struct{} 235 conns map[net.Conn]struct{} 236 237 // A pool for UDP message buffers. 238 udpPool sync.Pool 239} 240 241func (srv *Server) isStarted() bool { 242 srv.lock.RLock() 243 started := srv.started 244 srv.lock.RUnlock() 245 return started 246} 247 248func makeUDPBuffer(size int) func() interface{} { 249 return func() interface{} { 250 return make([]byte, size) 251 } 252} 253 254func (srv *Server) init() { 255 srv.shutdown = make(chan struct{}) 256 srv.conns = make(map[net.Conn]struct{}) 257 258 if srv.UDPSize == 0 { 259 srv.UDPSize = MinMsgSize 260 } 261 if srv.MsgAcceptFunc == nil { 262 srv.MsgAcceptFunc = DefaultMsgAcceptFunc 263 } 264 if srv.Handler == nil { 265 srv.Handler = DefaultServeMux 266 } 267 268 srv.udpPool.New = makeUDPBuffer(srv.UDPSize) 269} 270 271func unlockOnce(l sync.Locker) func() { 272 var once sync.Once 273 return func() { once.Do(l.Unlock) } 274} 275 276// ListenAndServe starts a nameserver on the configured address in *Server. 277func (srv *Server) ListenAndServe() error { 278 unlock := unlockOnce(&srv.lock) 279 srv.lock.Lock() 280 defer unlock() 281 282 if srv.started { 283 return &Error{err: "server already started"} 284 } 285 286 addr := srv.Addr 287 if addr == "" { 288 addr = ":domain" 289 } 290 291 srv.init() 292 293 switch srv.Net { 294 case "tcp", "tcp4", "tcp6": 295 l, err := listenTCP(srv.Net, addr, srv.ReusePort) 296 if err != nil { 297 return err 298 } 299 srv.Listener = l 300 srv.started = true 301 unlock() 302 return srv.serveTCP(l) 303 case "tcp-tls", "tcp4-tls", "tcp6-tls": 304 if srv.TLSConfig == nil || (len(srv.TLSConfig.Certificates) == 0 && srv.TLSConfig.GetCertificate == nil) { 305 return errors.New("dns: neither Certificates nor GetCertificate set in Config") 306 } 307 network := strings.TrimSuffix(srv.Net, "-tls") 308 l, err := listenTCP(network, addr, srv.ReusePort) 309 if err != nil { 310 return err 311 } 312 l = tls.NewListener(l, srv.TLSConfig) 313 srv.Listener = l 314 srv.started = true 315 unlock() 316 return srv.serveTCP(l) 317 case "udp", "udp4", "udp6": 318 l, err := listenUDP(srv.Net, addr, srv.ReusePort) 319 if err != nil { 320 return err 321 } 322 u := l.(*net.UDPConn) 323 if e := setUDPSocketOptions(u); e != nil { 324 u.Close() 325 return e 326 } 327 srv.PacketConn = l 328 srv.started = true 329 unlock() 330 return srv.serveUDP(u) 331 } 332 return &Error{err: "bad network"} 333} 334 335// ActivateAndServe starts a nameserver with the PacketConn or Listener 336// configured in *Server. Its main use is to start a server from systemd. 337func (srv *Server) ActivateAndServe() error { 338 unlock := unlockOnce(&srv.lock) 339 srv.lock.Lock() 340 defer unlock() 341 342 if srv.started { 343 return &Error{err: "server already started"} 344 } 345 346 srv.init() 347 348 if srv.PacketConn != nil { 349 // Check PacketConn interface's type is valid and value 350 // is not nil 351 if t, ok := srv.PacketConn.(*net.UDPConn); ok && t != nil { 352 if e := setUDPSocketOptions(t); e != nil { 353 return e 354 } 355 } 356 srv.started = true 357 unlock() 358 return srv.serveUDP(srv.PacketConn) 359 } 360 if srv.Listener != nil { 361 srv.started = true 362 unlock() 363 return srv.serveTCP(srv.Listener) 364 } 365 return &Error{err: "bad listeners"} 366} 367 368// Shutdown shuts down a server. After a call to Shutdown, ListenAndServe and 369// ActivateAndServe will return. 370func (srv *Server) Shutdown() error { 371 return srv.ShutdownContext(context.Background()) 372} 373 374// ShutdownContext shuts down a server. After a call to ShutdownContext, 375// ListenAndServe and ActivateAndServe will return. 376// 377// A context.Context may be passed to limit how long to wait for connections 378// to terminate. 379func (srv *Server) ShutdownContext(ctx context.Context) error { 380 srv.lock.Lock() 381 if !srv.started { 382 srv.lock.Unlock() 383 return &Error{err: "server not started"} 384 } 385 386 srv.started = false 387 388 if srv.PacketConn != nil { 389 srv.PacketConn.SetReadDeadline(aLongTimeAgo) // Unblock reads 390 } 391 392 if srv.Listener != nil { 393 srv.Listener.Close() 394 } 395 396 for rw := range srv.conns { 397 rw.SetReadDeadline(aLongTimeAgo) // Unblock reads 398 } 399 400 srv.lock.Unlock() 401 402 if testShutdownNotify != nil { 403 testShutdownNotify.Broadcast() 404 } 405 406 var ctxErr error 407 select { 408 case <-srv.shutdown: 409 case <-ctx.Done(): 410 ctxErr = ctx.Err() 411 } 412 413 if srv.PacketConn != nil { 414 srv.PacketConn.Close() 415 } 416 417 return ctxErr 418} 419 420var testShutdownNotify *sync.Cond 421 422// getReadTimeout is a helper func to use system timeout if server did not intend to change it. 423func (srv *Server) getReadTimeout() time.Duration { 424 if srv.ReadTimeout != 0 { 425 return srv.ReadTimeout 426 } 427 return dnsTimeout 428} 429 430// serveTCP starts a TCP listener for the server. 431func (srv *Server) serveTCP(l net.Listener) error { 432 defer l.Close() 433 434 if srv.NotifyStartedFunc != nil { 435 srv.NotifyStartedFunc() 436 } 437 438 var wg sync.WaitGroup 439 defer func() { 440 wg.Wait() 441 close(srv.shutdown) 442 }() 443 444 for srv.isStarted() { 445 rw, err := l.Accept() 446 if err != nil { 447 if !srv.isStarted() { 448 return nil 449 } 450 if neterr, ok := err.(net.Error); ok && neterr.Temporary() { 451 continue 452 } 453 return err 454 } 455 srv.lock.Lock() 456 // Track the connection to allow unblocking reads on shutdown. 457 srv.conns[rw] = struct{}{} 458 srv.lock.Unlock() 459 wg.Add(1) 460 go srv.serveTCPConn(&wg, rw) 461 } 462 463 return nil 464} 465 466// serveUDP starts a UDP listener for the server. 467func (srv *Server) serveUDP(l net.PacketConn) error { 468 defer l.Close() 469 470 reader := Reader(defaultReader{srv}) 471 if srv.DecorateReader != nil { 472 reader = srv.DecorateReader(reader) 473 } 474 475 lUDP, isUDP := l.(*net.UDPConn) 476 readerPC, canPacketConn := reader.(PacketConnReader) 477 if !isUDP && !canPacketConn { 478 return &Error{err: "PacketConnReader was not implemented on Reader returned from DecorateReader but is required for net.PacketConn"} 479 } 480 481 if srv.NotifyStartedFunc != nil { 482 srv.NotifyStartedFunc() 483 } 484 485 var wg sync.WaitGroup 486 defer func() { 487 wg.Wait() 488 close(srv.shutdown) 489 }() 490 491 rtimeout := srv.getReadTimeout() 492 // deadline is not used here 493 for srv.isStarted() { 494 var ( 495 m []byte 496 sPC net.Addr 497 sUDP *SessionUDP 498 err error 499 ) 500 if isUDP { 501 m, sUDP, err = reader.ReadUDP(lUDP, rtimeout) 502 } else { 503 m, sPC, err = readerPC.ReadPacketConn(l, rtimeout) 504 } 505 if err != nil { 506 if !srv.isStarted() { 507 return nil 508 } 509 if netErr, ok := err.(net.Error); ok && netErr.Temporary() { 510 continue 511 } 512 return err 513 } 514 if len(m) < headerSize { 515 if cap(m) == srv.UDPSize { 516 srv.udpPool.Put(m[:srv.UDPSize]) 517 } 518 continue 519 } 520 wg.Add(1) 521 go srv.serveUDPPacket(&wg, m, l, sUDP, sPC) 522 } 523 524 return nil 525} 526 527// Serve a new TCP connection. 528func (srv *Server) serveTCPConn(wg *sync.WaitGroup, rw net.Conn) { 529 w := &response{tsigSecret: srv.TsigSecret, tcp: rw} 530 if srv.DecorateWriter != nil { 531 w.writer = srv.DecorateWriter(w) 532 } else { 533 w.writer = w 534 } 535 536 reader := Reader(defaultReader{srv}) 537 if srv.DecorateReader != nil { 538 reader = srv.DecorateReader(reader) 539 } 540 541 idleTimeout := tcpIdleTimeout 542 if srv.IdleTimeout != nil { 543 idleTimeout = srv.IdleTimeout() 544 } 545 546 timeout := srv.getReadTimeout() 547 548 limit := srv.MaxTCPQueries 549 if limit == 0 { 550 limit = maxTCPQueries 551 } 552 553 for q := 0; (q < limit || limit == -1) && srv.isStarted(); q++ { 554 m, err := reader.ReadTCP(w.tcp, timeout) 555 if err != nil { 556 // TODO(tmthrgd): handle error 557 break 558 } 559 srv.serveDNS(m, w) 560 if w.closed { 561 break // Close() was called 562 } 563 if w.hijacked { 564 break // client will call Close() themselves 565 } 566 // The first read uses the read timeout, the rest use the 567 // idle timeout. 568 timeout = idleTimeout 569 } 570 571 if !w.hijacked { 572 w.Close() 573 } 574 575 srv.lock.Lock() 576 delete(srv.conns, w.tcp) 577 srv.lock.Unlock() 578 579 wg.Done() 580} 581 582// Serve a new UDP request. 583func (srv *Server) serveUDPPacket(wg *sync.WaitGroup, m []byte, u net.PacketConn, udpSession *SessionUDP, pcSession net.Addr) { 584 w := &response{tsigSecret: srv.TsigSecret, udp: u, udpSession: udpSession, pcSession: pcSession} 585 if srv.DecorateWriter != nil { 586 w.writer = srv.DecorateWriter(w) 587 } else { 588 w.writer = w 589 } 590 591 srv.serveDNS(m, w) 592 wg.Done() 593} 594 595func (srv *Server) serveDNS(m []byte, w *response) { 596 dh, off, err := unpackMsgHdr(m, 0) 597 if err != nil { 598 // Let client hang, they are sending crap; any reply can be used to amplify. 599 return 600 } 601 602 req := new(Msg) 603 req.setHdr(dh) 604 605 switch action := srv.MsgAcceptFunc(dh); action { 606 case MsgAccept: 607 if req.unpack(dh, m, off) == nil { 608 break 609 } 610 611 fallthrough 612 case MsgReject, MsgRejectNotImplemented: 613 opcode := req.Opcode 614 req.SetRcodeFormatError(req) 615 req.Zero = false 616 if action == MsgRejectNotImplemented { 617 req.Opcode = opcode 618 req.Rcode = RcodeNotImplemented 619 } 620 621 // Are we allowed to delete any OPT records here? 622 req.Ns, req.Answer, req.Extra = nil, nil, nil 623 624 w.WriteMsg(req) 625 fallthrough 626 case MsgIgnore: 627 if w.udp != nil && cap(m) == srv.UDPSize { 628 srv.udpPool.Put(m[:srv.UDPSize]) 629 } 630 631 return 632 } 633 634 w.tsigStatus = nil 635 if w.tsigSecret != nil { 636 if t := req.IsTsig(); t != nil { 637 if secret, ok := w.tsigSecret[t.Hdr.Name]; ok { 638 w.tsigStatus = TsigVerify(m, secret, "", false) 639 } else { 640 w.tsigStatus = ErrSecret 641 } 642 w.tsigTimersOnly = false 643 w.tsigRequestMAC = req.Extra[len(req.Extra)-1].(*TSIG).MAC 644 } 645 } 646 647 if w.udp != nil && cap(m) == srv.UDPSize { 648 srv.udpPool.Put(m[:srv.UDPSize]) 649 } 650 651 srv.Handler.ServeDNS(w, req) // Writes back to the client 652} 653 654func (srv *Server) readTCP(conn net.Conn, timeout time.Duration) ([]byte, error) { 655 // If we race with ShutdownContext, the read deadline may 656 // have been set in the distant past to unblock the read 657 // below. We must not override it, otherwise we may block 658 // ShutdownContext. 659 srv.lock.RLock() 660 if srv.started { 661 conn.SetReadDeadline(time.Now().Add(timeout)) 662 } 663 srv.lock.RUnlock() 664 665 var length uint16 666 if err := binary.Read(conn, binary.BigEndian, &length); err != nil { 667 return nil, err 668 } 669 670 m := make([]byte, length) 671 if _, err := io.ReadFull(conn, m); err != nil { 672 return nil, err 673 } 674 675 return m, nil 676} 677 678func (srv *Server) readUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) { 679 srv.lock.RLock() 680 if srv.started { 681 // See the comment in readTCP above. 682 conn.SetReadDeadline(time.Now().Add(timeout)) 683 } 684 srv.lock.RUnlock() 685 686 m := srv.udpPool.Get().([]byte) 687 n, s, err := ReadFromSessionUDP(conn, m) 688 if err != nil { 689 srv.udpPool.Put(m) 690 return nil, nil, err 691 } 692 m = m[:n] 693 return m, s, nil 694} 695 696func (srv *Server) readPacketConn(conn net.PacketConn, timeout time.Duration) ([]byte, net.Addr, error) { 697 srv.lock.RLock() 698 if srv.started { 699 // See the comment in readTCP above. 700 conn.SetReadDeadline(time.Now().Add(timeout)) 701 } 702 srv.lock.RUnlock() 703 704 m := srv.udpPool.Get().([]byte) 705 n, addr, err := conn.ReadFrom(m) 706 if err != nil { 707 srv.udpPool.Put(m) 708 return nil, nil, err 709 } 710 m = m[:n] 711 return m, addr, nil 712} 713 714// WriteMsg implements the ResponseWriter.WriteMsg method. 715func (w *response) WriteMsg(m *Msg) (err error) { 716 if w.closed { 717 return &Error{err: "WriteMsg called after Close"} 718 } 719 720 var data []byte 721 if w.tsigSecret != nil { // if no secrets, dont check for the tsig (which is a longer check) 722 if t := m.IsTsig(); t != nil { 723 data, w.tsigRequestMAC, err = TsigGenerate(m, w.tsigSecret[t.Hdr.Name], w.tsigRequestMAC, w.tsigTimersOnly) 724 if err != nil { 725 return err 726 } 727 _, err = w.writer.Write(data) 728 return err 729 } 730 } 731 data, err = m.Pack() 732 if err != nil { 733 return err 734 } 735 _, err = w.writer.Write(data) 736 return err 737} 738 739// Write implements the ResponseWriter.Write method. 740func (w *response) Write(m []byte) (int, error) { 741 if w.closed { 742 return 0, &Error{err: "Write called after Close"} 743 } 744 745 switch { 746 case w.udp != nil: 747 if u, ok := w.udp.(*net.UDPConn); ok { 748 return WriteToSessionUDP(u, m, w.udpSession) 749 } 750 return w.udp.WriteTo(m, w.pcSession) 751 case w.tcp != nil: 752 if len(m) > MaxMsgSize { 753 return 0, &Error{err: "message too large"} 754 } 755 756 msg := make([]byte, 2+len(m)) 757 binary.BigEndian.PutUint16(msg, uint16(len(m))) 758 copy(msg[2:], m) 759 return w.tcp.Write(msg) 760 default: 761 panic("dns: internal error: udp and tcp both nil") 762 } 763} 764 765// LocalAddr implements the ResponseWriter.LocalAddr method. 766func (w *response) LocalAddr() net.Addr { 767 switch { 768 case w.udp != nil: 769 return w.udp.LocalAddr() 770 case w.tcp != nil: 771 return w.tcp.LocalAddr() 772 default: 773 panic("dns: internal error: udp and tcp both nil") 774 } 775} 776 777// RemoteAddr implements the ResponseWriter.RemoteAddr method. 778func (w *response) RemoteAddr() net.Addr { 779 switch { 780 case w.udpSession != nil: 781 return w.udpSession.RemoteAddr() 782 case w.pcSession != nil: 783 return w.pcSession 784 case w.tcp != nil: 785 return w.tcp.RemoteAddr() 786 default: 787 panic("dns: internal error: udpSession, pcSession and tcp are all nil") 788 } 789} 790 791// TsigStatus implements the ResponseWriter.TsigStatus method. 792func (w *response) TsigStatus() error { return w.tsigStatus } 793 794// TsigTimersOnly implements the ResponseWriter.TsigTimersOnly method. 795func (w *response) TsigTimersOnly(b bool) { w.tsigTimersOnly = b } 796 797// Hijack implements the ResponseWriter.Hijack method. 798func (w *response) Hijack() { w.hijacked = true } 799 800// Close implements the ResponseWriter.Close method 801func (w *response) Close() error { 802 if w.closed { 803 return &Error{err: "connection already closed"} 804 } 805 w.closed = true 806 807 switch { 808 case w.udp != nil: 809 // Can't close the udp conn, as that is actually the listener. 810 return nil 811 case w.tcp != nil: 812 return w.tcp.Close() 813 default: 814 panic("dns: internal error: udp and tcp both nil") 815 } 816} 817 818// ConnectionState() implements the ConnectionStater.ConnectionState() interface. 819func (w *response) ConnectionState() *tls.ConnectionState { 820 type tlsConnectionStater interface { 821 ConnectionState() tls.ConnectionState 822 } 823 if v, ok := w.tcp.(tlsConnectionStater); ok { 824 t := v.ConnectionState() 825 return &t 826 } 827 return nil 828} 829