Skip to content

Commit db96428

Browse files
committed
Add configurable debounce time
Time to wait before logging a disconnect can be configured
1 parent e2fbec3 commit db96428

File tree

3 files changed

+53
-45
lines changed

3 files changed

+53
-45
lines changed

cmd/tunneld/options.go

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,19 @@ func init() {
3939

4040
// options specify arguments read command line arguments.
4141
type options struct {
42-
httpAddr string
43-
httpsAddr string
44-
tunnelAddr string
45-
apiAddr string
46-
sniAddr string
47-
tlsCrt string
48-
tlsKey string
49-
rootCA string
50-
clients string
51-
keepAlive string
52-
logLevel int
53-
version bool
42+
httpAddr string
43+
httpsAddr string
44+
tunnelAddr string
45+
apiAddr string
46+
sniAddr string
47+
tlsCrt string
48+
tlsKey string
49+
rootCA string
50+
clients string
51+
keepAlive string
52+
debounceLog string
53+
logLevel int
54+
version bool
5455
}
5556

5657
func parseArgs() *options {
@@ -64,22 +65,24 @@ func parseArgs() *options {
6465
rootCA := flag.String("rootCA", "", "Path to the trusted certificate chian used for client certificate authentication, if empty any client certificate is accepted")
6566
clients := flag.String("clients", "", "Comma-separated list of tunnel client ids, if empty accept all clients")
6667
keepAlive := flag.String("keepAlive", "45s", "TCP keep alive configuration")
68+
debounceLog := flag.String("debounceLog", "2s", "How long to keep disconnected log message before actually writing it to the log")
6769
logLevel := flag.Int("logLevel", 1, "Level of messages to log, 0-3")
6870
version := flag.Bool("version", false, "Prints tunneld version")
6971
flag.Parse()
7072

7173
return &options{
72-
httpAddr: *httpAddr,
73-
httpsAddr: *httpsAddr,
74-
tunnelAddr: *tunnelAddr,
75-
apiAddr: *apiAddr,
76-
sniAddr: *sniAddr,
77-
tlsCrt: *tlsCrt,
78-
tlsKey: *tlsKey,
79-
rootCA: *rootCA,
80-
clients: *clients,
81-
keepAlive: *keepAlive,
82-
logLevel: *logLevel,
83-
version: *version,
74+
httpAddr: *httpAddr,
75+
httpsAddr: *httpsAddr,
76+
tunnelAddr: *tunnelAddr,
77+
apiAddr: *apiAddr,
78+
sniAddr: *sniAddr,
79+
tlsCrt: *tlsCrt,
80+
tlsKey: *tlsKey,
81+
rootCA: *rootCA,
82+
clients: *clients,
83+
keepAlive: *keepAlive,
84+
debounceLog: *debounceLog,
85+
logLevel: *logLevel,
86+
version: *version,
8487
}
8588
}

cmd/tunneld/tunneld.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ import (
1313
"net/http"
1414
"os"
1515
"strings"
16+
"time"
1617

1718
"golang.org/x/net/http2"
1819

20+
"github.com/bep/debounce"
1921
tunnel "github.com/hons82/go-http-tunnel"
2022
"github.com/hons82/go-http-tunnel/connection"
2123
"github.com/hons82/go-http-tunnel/id"
@@ -46,6 +48,14 @@ func main() {
4648
fatal("failed to parse KeepaliveConfig: %s", err)
4749
}
4850

51+
debounceLog, err := time.ParseDuration(opts.debounceLog)
52+
if err != nil {
53+
fatal("failed to parse keepalive interval [%s], [%v]", opts.debounceLog, err)
54+
}
55+
debounced := &tunnel.Debounced{
56+
Execute: debounce.New(debounceLog),
57+
}
58+
4959
// setup server
5060
server, err := tunnel.NewServer(&tunnel.ServerConfig{
5161
Addr: opts.tunnelAddr,
@@ -54,6 +64,7 @@ func main() {
5464
TLSConfig: tlsconf,
5565
Logger: logger,
5666
KeepAlive: *keepAlive,
67+
Debounce: *debounced,
5768
})
5869
if err != nil {
5970
fatal("failed to create server: %s", err)

server.go

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import (
1818

1919
"golang.org/x/net/http2"
2020

21-
"github.com/bep/debounce"
2221
"github.com/hons82/go-http-tunnel/connection"
2322
"github.com/hons82/go-http-tunnel/id"
2423
"github.com/hons82/go-http-tunnel/log"
@@ -28,43 +27,40 @@ import (
2827

2928
// ServerConfig defines configuration for the Server.
3029
type ServerConfig struct {
31-
// Addr is TCP address to listen for client connections. If empty ":0"
32-
// is used.
30+
// Addr is TCP address to listen for client connections. If empty ":0" is used.
3331
Addr string
34-
// AutoSubscribe if enabled will automatically subscribe new clients on
35-
// first call.
32+
// AutoSubscribe if enabled will automatically subscribe new clients on first call.
3633
AutoSubscribe bool
3734
// TLSConfig specifies the tls configuration to use with tls.Listener.
3835
TLSConfig *tls.Config
39-
// Listener specifies optional listener for client connections. If nil
40-
// tls.Listen("tcp", Addr, TLSConfig) is used.
36+
// Listener specifies optional listener for client connections. If nil tls.Listen("tcp", Addr, TLSConfig) is used.
4137
Listener net.Listener
4238
// Logger is optional logger. If nil logging is disabled.
4339
Logger log.Logger
4440
// Addr is TCP address to listen for TLS SNI connections
4541
SNIAddr string
4642
// Used to configure the keepalive for the server -> client tcp connection
4743
KeepAlive connection.KeepAliveConfig
44+
// How long should a disconnected message been hold before sending it to the log
45+
Debounce Debounced
4846
}
4947

5048
// Server is responsible for proxying public connections to the client over a
5149
// tunnel connection.
5250
type Server struct {
5351
*registry
54-
config *ServerConfig
55-
52+
config *ServerConfig
5653
listener net.Listener
5754
connPool *connPool
5855
httpClient *http.Client
5956
logger log.Logger
57+
debounce Debounced
6058
vhostMuxer *vhost.TLSMuxer
61-
62-
debounce Debounced
6359
}
6460

6561
// Debounced Hold IDs that are disconnected for a short time before executing the function.
6662
type Debounced struct {
67-
debounced func(f func())
63+
Execute func(f func())
6864
disconnectedIDs []id.ID
6965
}
7066

@@ -80,16 +76,12 @@ func NewServer(config *ServerConfig) (*Server, error) {
8076
logger = log.NewNopLogger()
8177
}
8278

83-
debounced := &Debounced{
84-
debounced: debounce.New(1000 * time.Millisecond),
85-
}
86-
8779
s := &Server{
8880
registry: newRegistry(logger),
8981
config: config,
9082
listener: listener,
9183
logger: logger,
92-
debounce: *debounced,
84+
debounce: config.Debounce,
9385
}
9486

9587
t := &http2.Transport{}
@@ -169,12 +161,11 @@ func listener(config *ServerConfig) (net.Listener, error) {
169161
return net.Listen("tcp", config.Addr)
170162
}
171163

172-
// disconnected clears resources used by client, it's invoked by connection pool
173-
// when client goes away.
164+
// disconnected clears resources used by client, it's invoked by connection pool when client goes away.
174165
func (s *Server) disconnected(identifier id.ID) {
175166
s.debounce.disconnectedIDs = append(s.debounce.disconnectedIDs, identifier)
176167

177-
s.debounce.debounced(func() {
168+
s.debounce.Execute(func() {
178169
for _, id := range s.debounce.disconnectedIDs {
179170
s.logger.Log(
180171
"level", 1,
@@ -612,15 +603,18 @@ func (s *Server) listen(l net.Listener, identifier id.ID) {
612603
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
613604
resp, err := s.RoundTrip(r)
614605
if err != nil {
606+
level := 0
615607
code := http.StatusBadGateway
616608
if err == errUnauthorised {
617609
w.Header().Set("WWW-Authenticate", "Basic realm=\"User Visible Realm\"")
610+
level = 1
618611
code = http.StatusUnauthorized
619612
} else if err == errClientNotSubscribed {
613+
level = 2
620614
code = http.StatusNotFound
621615
}
622616
s.logger.Log(
623-
"level", 0,
617+
"level", level,
624618
"action", "round trip failed",
625619
"addr", r.RemoteAddr,
626620
"host", r.Host,

0 commit comments

Comments
 (0)