TUN-6191: Update quic-go to v0.27.1 and with custom patch to allow keep alive period to be configurable

The idle period is set to 5sec.

We now also ping every second since last activity.
This makes the quic.Connection less prone to being closed with
no network activity, since we send multiple pings per idle
period, and thus a single packet loss cannot cause the problem.
This commit is contained in:
Nuno Diegues
2022-06-06 14:15:35 +01:00
parent 4ccef23dbc
commit 475939a77f
49 changed files with 671 additions and 486 deletions

View File

@@ -14,7 +14,7 @@ import (
)
type client struct {
conn sendConn
sconn sendConn
// If the client is created with DialAddr, we create a packet conn.
// If it is started with Dial, we take a packet conn as a parameter.
createdPacketConn bool
@@ -35,7 +35,7 @@ type client struct {
handshakeChan chan struct{}
session quicSession
conn quicConn
tracer logging.ConnectionTracer
tracingID uint64
@@ -49,26 +49,26 @@ var (
)
// DialAddr establishes a new QUIC connection to a server.
// It uses a new UDP connection and closes this connection when the QUIC session is closed.
// It uses a new UDP connection and closes this connection when the QUIC connection is closed.
// The hostname for SNI is taken from the given address.
// The tls.Config.CipherSuites allows setting of TLS 1.3 cipher suites.
func DialAddr(
addr string,
tlsConf *tls.Config,
config *Config,
) (Session, error) {
) (Connection, error) {
return DialAddrContext(context.Background(), addr, tlsConf, config)
}
// DialAddrEarly establishes a new 0-RTT QUIC connection to a server.
// It uses a new UDP connection and closes this connection when the QUIC session is closed.
// It uses a new UDP connection and closes this connection when the QUIC connection is closed.
// The hostname for SNI is taken from the given address.
// The tls.Config.CipherSuites allows setting of TLS 1.3 cipher suites.
func DialAddrEarly(
addr string,
tlsConf *tls.Config,
config *Config,
) (EarlySession, error) {
) (EarlyConnection, error) {
return DialAddrEarlyContext(context.Background(), addr, tlsConf, config)
}
@@ -79,13 +79,13 @@ func DialAddrEarlyContext(
addr string,
tlsConf *tls.Config,
config *Config,
) (EarlySession, error) {
sess, err := dialAddrContext(ctx, addr, tlsConf, config, true)
) (EarlyConnection, error) {
conn, err := dialAddrContext(ctx, addr, tlsConf, config, true)
if err != nil {
return nil, err
}
utils.Logger.WithPrefix(utils.DefaultLogger, "client").Debugf("Returning early session")
return sess, nil
utils.Logger.WithPrefix(utils.DefaultLogger, "client").Debugf("Returning early connection")
return conn, nil
}
// DialAddrContext establishes a new QUIC connection to a server using the provided context.
@@ -95,7 +95,7 @@ func DialAddrContext(
addr string,
tlsConf *tls.Config,
config *Config,
) (Session, error) {
) (Connection, error) {
return dialAddrContext(ctx, addr, tlsConf, config, false)
}
@@ -105,7 +105,7 @@ func dialAddrContext(
tlsConf *tls.Config,
config *Config,
use0RTT bool,
) (quicSession, error) {
) (quicConn, error) {
udpAddr, err := net.ResolveUDPAddr("udp", addr)
if err != nil {
return nil, err
@@ -131,7 +131,7 @@ func Dial(
host string,
tlsConf *tls.Config,
config *Config,
) (Session, error) {
) (Connection, error) {
return dialContext(context.Background(), pconn, remoteAddr, host, tlsConf, config, false, false)
}
@@ -146,7 +146,7 @@ func DialEarly(
host string,
tlsConf *tls.Config,
config *Config,
) (EarlySession, error) {
) (EarlyConnection, error) {
return DialEarlyContext(context.Background(), pconn, remoteAddr, host, tlsConf, config)
}
@@ -159,7 +159,7 @@ func DialEarlyContext(
host string,
tlsConf *tls.Config,
config *Config,
) (EarlySession, error) {
) (EarlyConnection, error) {
return dialContext(ctx, pconn, remoteAddr, host, tlsConf, config, true, false)
}
@@ -172,7 +172,7 @@ func DialContext(
host string,
tlsConf *tls.Config,
config *Config,
) (Session, error) {
) (Connection, error) {
return dialContext(ctx, pconn, remoteAddr, host, tlsConf, config, false, false)
}
@@ -185,7 +185,7 @@ func dialContext(
config *Config,
use0RTT bool,
createdPacketConn bool,
) (quicSession, error) {
) (quicConn, error) {
if tlsConf == nil {
return nil, errors.New("quic: tls.Config not set")
}
@@ -203,21 +203,21 @@ func dialContext(
}
c.packetHandlers = packetHandlers
c.tracingID = nextSessionTracingID()
c.tracingID = nextConnTracingID()
if c.config.Tracer != nil {
c.tracer = c.config.Tracer.TracerForConnection(
context.WithValue(ctx, SessionTracingKey, c.tracingID),
context.WithValue(ctx, ConnectionTracingKey, c.tracingID),
protocol.PerspectiveClient,
c.destConnID,
)
}
if c.tracer != nil {
c.tracer.StartedConnection(c.conn.LocalAddr(), c.conn.RemoteAddr(), c.srcConnID, c.destConnID)
c.tracer.StartedConnection(c.sconn.LocalAddr(), c.sconn.RemoteAddr(), c.srcConnID, c.destConnID)
}
if err := c.dial(ctx); err != nil {
return nil, err
}
return c.session, nil
return c.conn, nil
}
func newClient(
@@ -265,7 +265,7 @@ func newClient(
c := &client{
srcConnID: srcConnID,
destConnID: destConnID,
conn: newSendPconn(pconn, remoteAddr),
sconn: newSendPconn(pconn, remoteAddr),
createdPacketConn: createdPacketConn,
use0RTT: use0RTT,
tlsConf: tlsConf,
@@ -278,10 +278,10 @@ func newClient(
}
func (c *client) dial(ctx context.Context) error {
c.logger.Infof("Starting new connection to %s (%s -> %s), source connection ID %s, destination connection ID %s, version %s", c.tlsConf.ServerName, c.conn.LocalAddr(), c.conn.RemoteAddr(), c.srcConnID, c.destConnID, c.version)
c.logger.Infof("Starting new connection to %s (%s -> %s), source connection ID %s, destination connection ID %s, version %s", c.tlsConf.ServerName, c.sconn.LocalAddr(), c.sconn.RemoteAddr(), c.srcConnID, c.destConnID, c.version)
c.session = newClientSession(
c.conn,
c.conn = newClientConnection(
c.sconn,
c.packetHandlers,
c.destConnID,
c.srcConnID,
@@ -295,11 +295,11 @@ func (c *client) dial(ctx context.Context) error {
c.logger,
c.version,
)
c.packetHandlers.Add(c.srcConnID, c.session)
c.packetHandlers.Add(c.srcConnID, c.conn)
errorChan := make(chan error, 1)
go func() {
err := c.session.run() // returns as soon as the session is closed
err := c.conn.run() // returns as soon as the connection is closed
if e := (&errCloseForRecreating{}); !errors.As(err, &e) && c.createdPacketConn {
c.packetHandlers.Destroy()
@@ -308,15 +308,15 @@ func (c *client) dial(ctx context.Context) error {
}()
// only set when we're using 0-RTT
// Otherwise, earlySessionChan will be nil. Receiving from a nil chan blocks forever.
var earlySessionChan <-chan struct{}
// Otherwise, earlyConnChan will be nil. Receiving from a nil chan blocks forever.
var earlyConnChan <-chan struct{}
if c.use0RTT {
earlySessionChan = c.session.earlySessionReady()
earlyConnChan = c.conn.earlyConnReady()
}
select {
case <-ctx.Done():
c.session.shutdown()
c.conn.shutdown()
return ctx.Err()
case err := <-errorChan:
var recreateErr *errCloseForRecreating
@@ -327,10 +327,10 @@ func (c *client) dial(ctx context.Context) error {
return c.dial(ctx)
}
return err
case <-earlySessionChan:
case <-earlyConnChan:
// ready to send 0-RTT data
return nil
case <-c.session.HandshakeComplete().Done():
case <-c.conn.HandshakeComplete().Done():
// handshake successfully completed
return nil
}