chore: update quic-go, adapt to lack of write tracking (#10456)

Signed-off-by: Jakob Borg <jakob@kastelo.net>
This commit is contained in:
Jakob Borg
2025-11-16 00:48:28 +01:00
committed by GitHub
parent 9241a475e9
commit 488c33aef5
5 changed files with 35 additions and 85 deletions
+2 -6
View File
@@ -102,14 +102,10 @@ func (t *quicListener) serve(ctx context.Context) error {
}
defer udpConn.Close()
tracer := &writeTrackingTracer{}
quicTransport := &quic.Transport{
Conn: udpConn,
Tracer: tracer.loggingTracer(),
}
quicTransport := &quic.Transport{Conn: udpConn}
defer quicTransport.Close()
svc := stun.New(t.cfg, t, &transportPacketConn{tran: quicTransport}, tracer)
svc := stun.New(t.cfg, t, &transportPacketConn{tran: quicTransport})
stunCtx, cancel := context.WithCancel(ctx)
defer cancel()
go svc.Serve(stunCtx)
+4 -24
View File
@@ -18,7 +18,6 @@ import (
"time"
"github.com/quic-go/quic-go"
"github.com/quic-go/quic-go/logging"
"github.com/syncthing/syncthing/lib/osutil"
)
@@ -40,8 +39,8 @@ func quicNetwork(uri *url.URL) string {
}
type quicTlsConn struct {
quic.Connection
quic.Stream
*quic.Conn
*quic.Stream
// If we created this connection, we should be the ones closing it.
createdConn net.PacketConn
@@ -49,7 +48,7 @@ type quicTlsConn struct {
func (q *quicTlsConn) Close() error {
sterr := q.Stream.Close()
seerr := q.Connection.CloseWithError(0, "closing")
seerr := q.Conn.CloseWithError(0, "closing")
var pcerr error
if q.createdConn != nil {
pcerr = q.createdConn.Close()
@@ -64,7 +63,7 @@ func (q *quicTlsConn) Close() error {
}
func (q *quicTlsConn) ConnectionState() tls.ConnectionState {
return q.Connection.ConnectionState().TLS
return q.Conn.ConnectionState().TLS
}
func transportConnUnspecified(conn any) bool {
@@ -77,25 +76,6 @@ func transportConnUnspecified(conn any) bool {
return err == nil && ip.IsUnspecified()
}
type writeTrackingTracer struct {
lastWrite atomic.Int64 // unix nanos
}
func (t *writeTrackingTracer) loggingTracer() *logging.Tracer {
return &logging.Tracer{
SentPacket: func(net.Addr, *logging.Header, logging.ByteCount, []logging.Frame) {
t.lastWrite.Store(time.Now().UnixNano())
},
SentVersionNegotiationPacket: func(net.Addr, logging.ArbitraryLenConnectionID, logging.ArbitraryLenConnectionID, []logging.Version) {
t.lastWrite.Store(time.Now().UnixNano())
},
}
}
func (t *writeTrackingTracer) LastWrite() time.Time {
return time.Unix(0, t.lastWrite.Load())
}
// A transportPacketConn is a net.PacketConn that uses a quic.Transport.
type transportPacketConn struct {
tran *quic.Transport
+2 -22
View File
@@ -54,17 +54,11 @@ type Service struct {
subscriber Subscriber
client *stun.Client
lastWriter LastWriter
natType NATType
addr *Host
}
type LastWriter interface {
LastWrite() time.Time
}
func New(cfg config.Wrapper, subscriber Subscriber, conn net.PacketConn, lastWriter LastWriter) *Service {
func New(cfg config.Wrapper, subscriber Subscriber, conn net.PacketConn) *Service {
// Construct the client to use the stun conn
client := stun.NewClientWithConnection(conn)
client.SetSoftwareName("") // Explicitly unset this, seems to freak some servers out.
@@ -83,8 +77,6 @@ func New(cfg config.Wrapper, subscriber Subscriber, conn net.PacketConn, lastWri
subscriber: subscriber,
client: client,
lastWriter: lastWriter,
natType: NATUnknown,
addr: nil,
}
@@ -219,18 +211,13 @@ func (s *Service) stunKeepAlive(ctx context.Context, addr string, extAddr *Host)
}
// Adjust the keepalives to fire only nextSleep after last write.
lastWrite := ourLastWrite
if quicLastWrite := s.lastWriter.LastWrite(); quicLastWrite.After(lastWrite) {
lastWrite = quicLastWrite
}
minSleep := time.Duration(s.cfg.Options().StunKeepaliveMinS) * time.Second
if nextSleep < minSleep {
nextSleep = minSleep
}
tryLater:
sleepFor := nextSleep
timeUntilNextKeepalive := time.Until(lastWrite.Add(sleepFor))
timeUntilNextKeepalive := time.Until(ourLastWrite.Add(sleepFor))
if timeUntilNextKeepalive > 0 {
sleepFor = timeUntilNextKeepalive
}
@@ -250,13 +237,6 @@ func (s *Service) stunKeepAlive(ctx context.Context, addr string, extAddr *Host)
return errors.New("disabled")
}
// Check if any writes happened while we were sleeping, if they did, sleep again
lastWrite = s.lastWriter.LastWrite()
if gap := time.Since(lastWrite); gap < nextSleep {
l.Debugf("%s stun last write gap less than next sleep: %s < %s. Will try later", s, gap, nextSleep)
goto tryLater
}
l.Debugf("%s stun keepalive", s)
extAddr, err = s.client.Keepalive()