Documentation
¶
Index ¶
- type CertManager
- type Listener
- type Server
- func (s *Server) GetTLSConfig() *tls.Config
- func (s *Server) HasListener(proto string) bool
- func (s *Server) InlineReady() bool
- func (s *Server) Quiesced() bool
- func (s *Server) ReloadCertificate() error
- func (s *Server) Run(ctx context.Context) error
- func (s *Server) ServeDNS(w dns.ResponseWriter, r *dns.Msg)
- func (s *Server) ServeDNSContext(parent context.Context, w dns.ResponseWriter, r *dns.Msg)
- func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (s *Server) ServeMsg(parent context.Context, w middleware.Transport, r *dns.Msg)
- func (s *Server) ServeRaw(w middleware.Transport, raw []byte, readTime time.Time) bool
- func (s *Server) ServeRawInline(w middleware.Transport, raw []byte, readTime time.Time) (handled bool)
- func (s *Server) ServeRawReplay(w middleware.Transport, raw []byte, readTime time.Time) bool
- func (s *Server) Stop()
- func (s *Server) Stopped() bool
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CertManager ¶ added in v1.6.0
type CertManager struct {
// contains filtered or unexported fields
}
CertManager manages TLS certificates with automatic reloading
func NewCertManager ¶ added in v1.6.0
func NewCertManager(certPath, keyPath string) (*CertManager, error)
NewCertManager creates a new certificate manager
func (*CertManager) GetCertificate ¶ added in v1.6.0
func (cm *CertManager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error)
GetCertificate returns the current certificate
func (*CertManager) GetTLSConfig ¶ added in v1.6.0
func (cm *CertManager) GetTLSConfig() *tls.Config
GetTLSConfig returns a TLS config that uses dynamic certificate loading Each call returns a fresh config to avoid race conditions
func (*CertManager) Reload ¶ added in v1.6.0
func (cm *CertManager) Reload() error
Reload forces a certificate reload
func (*CertManager) Stop ¶ added in v1.6.0
func (cm *CertManager) Stop()
Stop stops the certificate manager and waits for cleanup
type Listener ¶ added in v1.6.4
type Listener interface {
// Proto returns the transport tag — "udp", "tcp", "tls", "doh",
// "doh3", "doq" — used for logging and metrics.
Proto() string
// Addr returns the configured bind address.
Addr() string
// Bind acquires the underlying socket (and any TLS material it
// needs) synchronously. A non-nil return means the listener is
// not ready to serve.
Bind(ctx context.Context) error
// Serve blocks until Shutdown is called or the socket is closed.
// It must only be called after a successful Bind.
Serve(ctx context.Context) error
// Shutdown releases the underlying socket. Safe to call before
// Serve or after Serve has already returned.
Shutdown(ctx context.Context) error
// Critical reports whether a Bind failure on this listener should
// abort server startup. Plain DNS (UDP+TCP on cfg.Bind) is
// critical; optional services (TLS, DoH, DoH3, DoQ) are not —
// a missing cert or misconfigured addr only disables that service.
Critical() bool
// Serving reports whether the Serve loop is currently active.
// This is stricter than "Bind succeeded": QUIC-based listeners
// (DoH3, DoQ) complete their real startup inside Serve, so a
// listener can be bound but not actually serving if Serve
// returned an error during its own setup phase.
Serving() bool
}
Listener is the lifecycle contract for a single DNS service endpoint (UDP, TCP, DoT, DoH, DoH3, DoQ). It separates bind from serve so that the Server can fail fast on port-in-use, missing cert, etc. instead of swallowing the error inside a background goroutine.
Lifecycle: Bind → Serve → Shutdown. Bind may be called at most once. Serve returns when Shutdown is called or the underlying socket closes. Shutdown is idempotent.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server type.
func (*Server) GetTLSConfig ¶ added in v1.6.4
GetTLSConfig satisfies certProvider. It lazily materialises the shared CertManager on first TLS listener Bind and hands out its live TLS config (with rotation hooks) to each listener that asks.
func (*Server) HasListener ¶ added in v1.6.4
func (*Server) InlineReady ¶ added in v1.8.0
InlineReady reports whether the pipeline carries an inline barrier; the engines enable the reader fast path only when it does.
func (*Server) Quiesced ¶ added in v1.8.0
HasListener reports whether a listener with the given proto tag is actually serving right now — stricter than "Bind succeeded". DoH3 and DoQ do their real QUIC bring-up inside Serve, so checking only membership in s.active can report success even when the transport never started. Asking the listener via Serving() gives the truth. Quiesced reports whether every owned transport has all of its job slabs back in the ring: nothing is being read into, served, or staged for a send.
It is the completion barrier a measurement needs. A client holding its last reply proves the bytes left, not that the slab that carried them was released — the release runs after the send, on the server's own goroutine — so anything that samples the process at that moment (an allocation gate, a leak check, a drain assertion) is otherwise reduced to sleeping and hoping. Transports that own no slabs are quiescent by construction and answer for themselves.
func (*Server) ReloadCertificate ¶ added in v1.6.0
ReloadCertificate forces a certificate reload on all TLS listeners.
func (*Server) Run ¶
Run binds every configured listener synchronously, returns a non-nil error if a critical listener (plain DNS UDP/TCP) could not bind, and otherwise spawns Serve goroutines that run until ctx is cancelled. Run itself is non-blocking — main waits on ctx and polls Stopped for graceful shutdown.
func (*Server) ServeDNS ¶
func (s *Server) ServeDNS(w dns.ResponseWriter, r *dns.Msg)
ServeDNS keeps *Server a dns.Handler for embedders: the rewrite moved the owned transports off this entry, but code that mounts a Server under the library's mux did not change. A dns.ResponseWriter is a Transport already; nothing here is on the serving path.
func (*Server) ServeDNSContext ¶ added in v1.7.4
ServeDNSContext is ServeDNS with a caller-owned parent context, kept for the same embedders.
func (*Server) ServeHTTP ¶
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP implements http.Handler (DoH + DoH3).
func (*Server) ServeMsg ¶ added in v1.8.0
ServeMsg serves one decoded DNS request under the transport's lifetime and the configured end-to-end middleware/resolution timeout. It is the entry for transports that already hold a message — DNS-over-HTTP and DNS-over-QUIC supply client-aware parents — and for embedders. Its writers made no byte-sink promise, so they never receive raw packed bytes; the owned raw transports enter through ServeRaw instead, which is the one road to the direct-pack capability.
func (*Server) ServeRaw ¶ added in v1.8.0
ServeRaw is the single raw-transport ingress. An eligible packet on a job transport enters the chain as a wire-born request on the job carrier — no decode, no context allocation; anything else decodes here and takes the ordinary lazy-deadline entry with the direct-pack capability (the owned transports are raw byte sinks).
func (*Server) ServeRawInline ¶ added in v1.8.0
func (s *Server) ServeRawInline(w middleware.Transport, raw []byte, readTime time.Time) (handled bool)
ServeRawInline is ServeRaw for a transport reader that must not block: the full chain runs with the inline-only mark, and the cache — the one handler whose downstream can block on the network — declines a query it cannot answer from its wire ladder, unwritten. handled reports whether the query reached a terminal here; a false return with handoff true means the caller owns an admitted, guarded, unanswered job it must replay on a worker with ServeRawReplay. A packet the strict path cannot carry is a handoff outright: the decoded fallback resolves, and resolving blocks.
func (*Server) ServeRawReplay ¶ added in v1.8.0
ServeRawReplay finishes a query the inline pass handed off. The full pipeline runs with the replay mark: handlers whose entry effects fired on the inline pass skip them, and the middlewares that key off the response fire here, once, when this pass writes.
func (*Server) Stop ¶ added in v1.6.0
func (s *Server) Stop()
Stop releases long-lived resources (currently just the cert manager).
func (*Server) Stopped ¶ added in v1.3.2
Stopped reports whether the shutdown is complete: every Serve goroutine has exited *and* the supervisor has finished with every listener. That is the question a caller polling for shutdown actually has, because the only use for the answer is doing something else with what the server held — exiting, or binding the same addresses again.
Both halves are needed. The plain UDP and TCP listeners close their sockets inside Shutdown before the Serve they unblock returns, so for them the goroutine count alone would do. QUIC does not work that way: http3 and DoQ hand their accept loop a PacketConn they do not own, so Serve returns as soon as the server stops accepting while the socket stays open until the supervisor closes it a few statements later. A caller that rebound on the goroutine count alone met "address already in use", rarely for DoH3 and often for DoQ.
It does not mean nothing is running. A handler that outlasts its listener's drain deadline is force-closed and left to finish on its own — the alternative is a shutdown that a single stuck request can hang forever — so work can outlive this by as long as that handler takes. Process exit is the backstop for that, and an in-process restart is safe from the socket's point of view but not a guarantee that the old server's last requests have unwound.
Source Files
¶
- certmanager.go
- ingress_bounds.go
- ingress_platform_linux.go
- listener.go
- listener_doh.go
- listener_doh3.go
- listener_doq.go
- listener_tcp.go
- listener_tls.go
- listener_udp.go
- metrics.go
- pktinfo_linux.go
- reader_reserve_batch.go
- reuseport_linux.go
- server.go
- slab_cache.go
- strict.go
- sysmem_linux.go
- tcp_engine.go
- tcp_stream.go
- trim.go
- udp_batch_linux.go
- udp_engine.go
- udp_support.go
- udp_tx.go