Quellcode durchsuchen

fix: apply idle timeout to domain fronting relay connections

Domain fronting relay (for non-Telegram traffic) had no idle timeout,
causing worker pool exhaustion under traffic spikes.

The ProxyOpts.IdleTimeout field existed but was never wired into the
proxy. Now domain fronting connections are wrapped with per-read/write
deadlines reset to the configured idle timeout (default 1m), so stale
or slowloris-style connections are reaped promptly.

Fixes #378
tags/v2.2.5^2^2
Alexey Dolotov vor 1 Monat
Ursprung
Commit
836090ebdf
4 geänderte Dateien mit 32 neuen und 2 gelöschten Zeilen
  1. 1
    0
      internal/cli/run_proxy.go
  2. 19
    0
      mtglib/conns.go
  3. 4
    2
      mtglib/proxy.go
  4. 8
    0
      mtglib/proxy_opts.go

+ 1
- 0
internal/cli/run_proxy.go Datei anzeigen

262
 
262
 
263
 		AllowFallbackOnUnknownDC: conf.AllowFallbackOnUnknownDC.Get(false),
263
 		AllowFallbackOnUnknownDC: conf.AllowFallbackOnUnknownDC.Get(false),
264
 		TolerateTimeSkewness:     conf.TolerateTimeSkewness.Value,
264
 		TolerateTimeSkewness:     conf.TolerateTimeSkewness.Value,
265
+		IdleTimeout:              conf.Network.Timeout.Idle.Get(mtglib.DefaultIdleTimeout),
265
 
266
 
266
 		DoppelGangerURLs:    doppelGangerURLs,
267
 		DoppelGangerURLs:    doppelGangerURLs,
267
 		DoppelGangerPerRaid: conf.Defense.Doppelganger.Repeats.Get(mtglib.DoppelGangerPerRaid),
268
 		DoppelGangerPerRaid: conf.Defense.Doppelganger.Repeats.Get(mtglib.DoppelGangerPerRaid),

+ 19
- 0
mtglib/conns.go Datei anzeigen

6
 	"fmt"
6
 	"fmt"
7
 	"io"
7
 	"io"
8
 	"net"
8
 	"net"
9
+	"time"
9
 
10
 
10
 	"github.com/9seconds/mtg/v2/essentials"
11
 	"github.com/9seconds/mtg/v2/essentials"
11
 	"github.com/pires/go-proxyproto"
12
 	"github.com/pires/go-proxyproto"
95
 		sourceAddr: source.RemoteAddr(),
96
 		sourceAddr: source.RemoteAddr(),
96
 	}
97
 	}
97
 }
98
 }
99
+
100
+type connIdleTimeout struct {
101
+	essentials.Conn
102
+
103
+	timeout time.Duration
104
+}
105
+
106
+func (c connIdleTimeout) Read(b []byte) (int, error) {
107
+	c.Conn.SetReadDeadline(time.Now().Add(c.timeout)) //nolint: errcheck
108
+
109
+	return c.Conn.Read(b) //nolint: wrapcheck
110
+}
111
+
112
+func (c connIdleTimeout) Write(b []byte) (int, error) {
113
+	c.Conn.SetWriteDeadline(time.Now().Add(c.timeout)) //nolint: errcheck
114
+
115
+	return c.Conn.Write(b) //nolint: wrapcheck
116
+}

+ 4
- 2
mtglib/proxy.go Datei anzeigen

27
 
27
 
28
 	allowFallbackOnUnknownDC    bool
28
 	allowFallbackOnUnknownDC    bool
29
 	tolerateTimeSkewness        time.Duration
29
 	tolerateTimeSkewness        time.Duration
30
+	idleTimeout                 time.Duration
30
 	domainFrontingPort          int
31
 	domainFrontingPort          int
31
 	domainFrontingIP            string
32
 	domainFrontingIP            string
32
 	domainFrontingProxyProtocol bool
33
 	domainFrontingProxyProtocol bool
306
 	relay.Relay(
307
 	relay.Relay(
307
 		ctx,
308
 		ctx,
308
 		ctx.logger.Named("domain-fronting"),
309
 		ctx.logger.Named("domain-fronting"),
309
-		frontConn,
310
-		conn,
310
+		connIdleTimeout{Conn: frontConn, timeout: p.idleTimeout},
311
+		connIdleTimeout{Conn: conn, timeout: p.idleTimeout},
311
 	)
312
 	)
312
 }
313
 }
313
 
314
 
339
 		domainFrontingPort:       opts.getDomainFrontingPort(),
340
 		domainFrontingPort:       opts.getDomainFrontingPort(),
340
 		domainFrontingIP:         opts.DomainFrontingIP,
341
 		domainFrontingIP:         opts.DomainFrontingIP,
341
 		tolerateTimeSkewness:     opts.getTolerateTimeSkewness(),
342
 		tolerateTimeSkewness:     opts.getTolerateTimeSkewness(),
343
+		idleTimeout:              opts.getIdleTimeout(),
342
 		allowFallbackOnUnknownDC: opts.AllowFallbackOnUnknownDC,
344
 		allowFallbackOnUnknownDC: opts.AllowFallbackOnUnknownDC,
343
 		telegram:                 tg,
345
 		telegram:                 tg,
344
 		doppelGanger: doppel.NewGanger(
346
 		doppelGanger: doppel.NewGanger(

+ 8
- 0
mtglib/proxy_opts.go Datei anzeigen

216
 	return p.PreferIP
216
 	return p.PreferIP
217
 }
217
 }
218
 
218
 
219
+func (p ProxyOpts) getIdleTimeout() time.Duration {
220
+	if p.IdleTimeout == 0 {
221
+		return DefaultIdleTimeout
222
+	}
223
+
224
+	return p.IdleTimeout
225
+}
226
+
219
 func (p ProxyOpts) getLogger(name string) Logger {
227
 func (p ProxyOpts) getLogger(name string) Logger {
220
 	return p.Logger.Named(name)
228
 	return p.Logger.Named(name)
221
 }
229
 }

Laden…
Abbrechen
Speichern