serve_mux.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package dns
  2. import (
  3. "sync"
  4. )
  5. // ServeMux is an DNS request multiplexer. It matches the zone name of
  6. // each incoming request against a list of registered patterns add calls
  7. // the handler for the pattern that most closely matches the zone name.
  8. //
  9. // ServeMux is DNSSEC aware, meaning that queries for the DS record are
  10. // redirected to the parent zone (if that is also registered), otherwise
  11. // the child gets the query.
  12. //
  13. // ServeMux is also safe for concurrent access from multiple goroutines.
  14. //
  15. // The zero ServeMux is empty and ready for use.
  16. type ServeMux struct {
  17. z map[string]Handler
  18. m sync.RWMutex
  19. }
  20. // NewServeMux allocates and returns a new ServeMux.
  21. func NewServeMux() *ServeMux {
  22. return new(ServeMux)
  23. }
  24. // DefaultServeMux is the default ServeMux used by Serve.
  25. var DefaultServeMux = NewServeMux()
  26. func (mux *ServeMux) match(q string, t uint16) Handler {
  27. mux.m.RLock()
  28. defer mux.m.RUnlock()
  29. if mux.z == nil {
  30. return nil
  31. }
  32. q = CanonicalName(q)
  33. var handler Handler
  34. for off, end := 0, false; !end; off, end = NextLabel(q, off) {
  35. if h, ok := mux.z[q[off:]]; ok {
  36. if t != TypeDS {
  37. return h
  38. }
  39. // Continue for DS to see if we have a parent too, if so delegate to the parent
  40. handler = h
  41. }
  42. }
  43. // Wildcard match, if we have found nothing try the root zone as a last resort.
  44. if h, ok := mux.z["."]; ok {
  45. return h
  46. }
  47. return handler
  48. }
  49. // Handle adds a handler to the ServeMux for pattern.
  50. func (mux *ServeMux) Handle(pattern string, handler Handler) {
  51. if pattern == "" {
  52. panic("dns: invalid pattern " + pattern)
  53. }
  54. mux.m.Lock()
  55. if mux.z == nil {
  56. mux.z = make(map[string]Handler)
  57. }
  58. mux.z[CanonicalName(pattern)] = handler
  59. mux.m.Unlock()
  60. }
  61. // HandleFunc adds a handler function to the ServeMux for pattern.
  62. func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
  63. mux.Handle(pattern, HandlerFunc(handler))
  64. }
  65. // HandleRemove deregisters the handler specific for pattern from the ServeMux.
  66. func (mux *ServeMux) HandleRemove(pattern string) {
  67. if pattern == "" {
  68. panic("dns: invalid pattern " + pattern)
  69. }
  70. mux.m.Lock()
  71. delete(mux.z, CanonicalName(pattern))
  72. mux.m.Unlock()
  73. }
  74. // ServeDNS dispatches the request to the handler whose pattern most
  75. // closely matches the request message.
  76. //
  77. // ServeDNS is DNSSEC aware, meaning that queries for the DS record
  78. // are redirected to the parent zone (if that is also registered),
  79. // otherwise the child gets the query.
  80. //
  81. // If no handler is found, or there is no question, a standard REFUSED
  82. // message is returned
  83. func (mux *ServeMux) ServeDNS(w ResponseWriter, req *Msg) {
  84. var h Handler
  85. if len(req.Question) >= 1 { // allow more than one question
  86. h = mux.match(req.Question[0].Name, req.Question[0].Qtype)
  87. }
  88. if h != nil {
  89. h.ServeDNS(w, req)
  90. } else {
  91. handleRefused(w, req)
  92. }
  93. }
  94. // Handle registers the handler with the given pattern
  95. // in the DefaultServeMux. The documentation for
  96. // ServeMux explains how patterns are matched.
  97. func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
  98. // HandleRemove deregisters the handle with the given pattern
  99. // in the DefaultServeMux.
  100. func HandleRemove(pattern string) { DefaultServeMux.HandleRemove(pattern) }
  101. // HandleFunc registers the handler function with the given pattern
  102. // in the DefaultServeMux.
  103. func HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
  104. DefaultServeMux.HandleFunc(pattern, handler)
  105. }