forked from quic-go/quic-go
select the H3 ALPN based on the QUIC version in use (for the H3 server)
This commit is contained in:
@@ -10,11 +10,13 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/lucas-clemente/quic-go"
|
||||
"github.com/lucas-clemente/quic-go/internal/handshake"
|
||||
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||
"github.com/marten-seemann/qpack"
|
||||
)
|
||||
@@ -25,7 +27,12 @@ var (
|
||||
quicListenAddr = quic.ListenAddrEarly
|
||||
)
|
||||
|
||||
const nextProtoH3 = "h3-29"
|
||||
const (
|
||||
nextProtoH3Draft29 = "h3-29"
|
||||
nextProtoH3Draft32 = "h3-32"
|
||||
)
|
||||
|
||||
var supportedVersions = []string{nextProtoH3Draft29, nextProtoH3Draft32}
|
||||
|
||||
// contextKey is a value for use with context.WithValue. It's used as
|
||||
// a pointer so it fits in an interface{} without allocation.
|
||||
@@ -115,32 +122,36 @@ func (s *Server) serveImpl(tlsConf *tls.Config, conn net.PacketConn) error {
|
||||
s.logger = utils.DefaultLogger.WithPrefix("server")
|
||||
})
|
||||
|
||||
if tlsConf == nil {
|
||||
tlsConf = &tls.Config{}
|
||||
} else {
|
||||
tlsConf = tlsConf.Clone()
|
||||
}
|
||||
// Replace existing ALPNs by H3
|
||||
tlsConf.NextProtos = []string{nextProtoH3}
|
||||
if tlsConf.GetConfigForClient != nil {
|
||||
getConfigForClient := tlsConf.GetConfigForClient
|
||||
tlsConf.GetConfigForClient = func(ch *tls.ClientHelloInfo) (*tls.Config, error) {
|
||||
conf, err := getConfigForClient(ch)
|
||||
if err != nil || conf == nil {
|
||||
return conf, err
|
||||
// The tls.Config we pass to Listen needs to have the GetConfigForClient callback set.
|
||||
// That way, we can get the QUIC version and set the correct ALPN value.
|
||||
baseConf := &tls.Config{
|
||||
GetConfigForClient: func(ch *tls.ClientHelloInfo) (*tls.Config, error) {
|
||||
// determine the ALPN from the QUIC version used
|
||||
proto := nextProtoH3Draft29
|
||||
if qconn, ok := ch.Conn.(handshake.ConnWithVersion); ok && qconn.GetQUICVersion() == quic.VersionDraft32 {
|
||||
proto = nextProtoH3Draft32
|
||||
}
|
||||
conf := tlsConf
|
||||
if tlsConf.GetConfigForClient != nil {
|
||||
getConfigForClient := tlsConf.GetConfigForClient
|
||||
var err error
|
||||
conf, err = getConfigForClient(ch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
conf = conf.Clone()
|
||||
conf.NextProtos = []string{nextProtoH3}
|
||||
conf.NextProtos = []string{proto}
|
||||
return conf, nil
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
var ln quic.EarlyListener
|
||||
var err error
|
||||
if conn == nil {
|
||||
ln, err = quicListenAddr(s.Addr, tlsConf, s.QuicConfig)
|
||||
ln, err = quicListenAddr(s.Addr, baseConf, s.QuicConfig)
|
||||
} else {
|
||||
ln, err = quicListen(conn, tlsConf, s.QuicConfig)
|
||||
ln, err = quicListen(conn, baseConf, s.QuicConfig)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -344,8 +355,11 @@ func (s *Server) SetQuicHeaders(hdr http.Header) error {
|
||||
atomic.StoreUint32(&s.port, port)
|
||||
}
|
||||
|
||||
hdr.Add("Alt-Svc", fmt.Sprintf(`%s=":%d"; ma=2592000`, nextProtoH3, port))
|
||||
|
||||
altSvc := make([]string, len(supportedVersions))
|
||||
for i, v := range supportedVersions {
|
||||
altSvc[i] = fmt.Sprintf(`%s=":%d"; ma=2592000`, v, port)
|
||||
}
|
||||
hdr.Add("Alt-Svc", strings.Join(altSvc, ","))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user