-
Notifications
You must be signed in to change notification settings - Fork 65
/
adminlistener.go
115 lines (97 loc) · 2.53 KB
/
adminlistener.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package rdns
import (
"context"
"crypto/tls"
"expvar"
"fmt"
"net"
"net/http"
"time"
"github.com/quic-go/quic-go"
"github.com/quic-go/quic-go/http3"
"github.com/sirupsen/logrus"
)
// Read/Write timeout in the admin server
const adminServerTimeout = 10 * time.Second
// AdminListener is a DNS listener/server for admin services.
type AdminListener struct {
httpServer *http.Server
quicServer *http3.Server
id string
addr string
opt AdminListenerOptions
mux *http.ServeMux
}
var _ Listener = &AdminListener{}
// AdminListenerOptions contains options used by the admin service.
type AdminListenerOptions struct {
ListenOptions
// Transport protocol to run HTTPS over. "quic" or "tcp", defaults to "tcp".
Transport string
TLSConfig *tls.Config
}
// NewAdminListener returns an instance of an admin service listener.
func NewAdminListener(id, addr string, opt AdminListenerOptions) (*AdminListener, error) {
switch opt.Transport {
case "tcp", "":
opt.Transport = "tcp"
case "quic":
opt.Transport = "quic"
default:
return nil, fmt.Errorf("unknown protocol: '%s'", opt.Transport)
}
l := &AdminListener{
id: id,
addr: addr,
opt: opt,
mux: http.NewServeMux(),
}
// Serve metrics.
l.mux.Handle("/routedns/vars", expvar.Handler())
return l, nil
}
// Start the admin server.
func (s *AdminListener) Start() error {
Log.WithFields(logrus.Fields{"id": s.id, "protocol": s.opt.Transport, "addr": s.addr}).Info("starting listener")
if s.opt.Transport == "quic" {
return s.startQUIC()
}
return s.startTCP()
}
// Start the admin server with TCP transport.
func (s *AdminListener) startTCP() error {
s.httpServer = &http.Server{
Addr: s.addr,
TLSConfig: s.opt.TLSConfig,
Handler: s.mux,
ReadTimeout: adminServerTimeout,
WriteTimeout: adminServerTimeout,
}
ln, err := net.Listen("tcp", s.addr)
if err != nil {
return err
}
defer ln.Close()
return s.httpServer.ServeTLS(ln, "", "")
}
// Start the admin server with QUIC transport.
func (s *AdminListener) startQUIC() error {
s.quicServer = &http3.Server{
Addr: s.addr,
TLSConfig: s.opt.TLSConfig,
Handler: s.mux,
QUICConfig: &quic.Config{},
}
return s.quicServer.ListenAndServe()
}
// Stop the server.
func (s *AdminListener) Stop() error {
Log.WithFields(logrus.Fields{"id": s.id, "protocol": s.opt.Transport, "addr": s.addr}).Info("stopping listener")
if s.opt.Transport == "quic" {
return s.quicServer.Close()
}
return s.httpServer.Shutdown(context.Background())
}
func (s *AdminListener) String() string {
return s.id
}