Kaynağa Gözat

Replace QUIC version IETF-draft-24 with IETF-draft-29

Rod Hynes 5 yıl önce
ebeveyn
işleme
d9a4f9a33b

+ 8 - 3
psiphon/common/protocol/protocol.go

@@ -366,7 +366,7 @@ const (
 	QUIC_VERSION_GQUIC43      = "gQUICv43"
 	QUIC_VERSION_GQUIC44      = "gQUICv44"
 	QUIC_VERSION_OBFUSCATED   = "OBFUSCATED"
-	QUIC_VERSION_IETF_DRAFT24 = "IETF-draft-24"
+	QUIC_VERSION_IETF_DRAFT29 = "IETF-draft-29"
 )
 
 var SupportedQUICVersions = QUICVersions{
@@ -374,7 +374,11 @@ var SupportedQUICVersions = QUICVersions{
 	QUIC_VERSION_GQUIC43,
 	QUIC_VERSION_GQUIC44,
 	QUIC_VERSION_OBFUSCATED,
-	QUIC_VERSION_IETF_DRAFT24,
+	QUIC_VERSION_IETF_DRAFT29,
+}
+
+var legacyQUICVersions = QUICVersions{
+	"IETF-draft-24",
 }
 
 func QUICVersionIsObfuscated(version string) bool {
@@ -385,7 +389,8 @@ type QUICVersions []string
 
 func (versions QUICVersions) Validate() error {
 	for _, v := range versions {
-		if !common.Contains(SupportedQUICVersions, v) {
+		if !common.Contains(SupportedQUICVersions, v) &&
+			!common.Contains(legacyQUICVersions, v) {
 			return errors.Tracef("invalid QUIC version: %s", v)
 		}
 	}

+ 1 - 1
psiphon/common/quic/obfuscator.go

@@ -508,5 +508,5 @@ func isIETFQUICClientHello(buffer []byte) bool {
 	return buffer[1] == 0xff &&
 		buffer[2] == 0 &&
 		buffer[3] == 0 &&
-		buffer[4] == 0x18
+		buffer[4] == 0x1d
 }

+ 45 - 24
psiphon/common/quic/quic.go

@@ -61,8 +61,8 @@ import (
 	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/quic/gquic-go/h2quic"
 	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/quic/gquic-go/qerr"
 	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/values"
-	ietf_quic "github.com/Psiphon-Labs/quic-go"
-	"github.com/Psiphon-Labs/quic-go/http3"
+	ietf_quic "github.com/lucas-clemente/quic-go"
+	"github.com/lucas-clemente/quic-go/http3"
 )
 
 const (
@@ -76,14 +76,14 @@ func Enabled() bool {
 	return true
 }
 
-const ietfQUICDraft24VersionNumber = 0xff000018
+const ietfQUICDraft29VersionNumber = 0xff00001d
 
 var supportedVersionNumbers = map[string]uint32{
 	protocol.QUIC_VERSION_GQUIC39:      uint32(gquic.VersionGQUIC39),
 	protocol.QUIC_VERSION_GQUIC43:      uint32(gquic.VersionGQUIC43),
 	protocol.QUIC_VERSION_GQUIC44:      uint32(gquic.VersionGQUIC44),
 	protocol.QUIC_VERSION_OBFUSCATED:   uint32(gquic.VersionGQUIC43),
-	protocol.QUIC_VERSION_IETF_DRAFT24: ietfQUICDraft24VersionNumber,
+	protocol.QUIC_VERSION_IETF_DRAFT29: ietfQUICDraft29VersionNumber,
 }
 
 func isObfuscated(quicVersion string) bool {
@@ -91,11 +91,11 @@ func isObfuscated(quicVersion string) bool {
 }
 
 func isIETFVersion(versionNumber uint32) bool {
-	return versionNumber == ietfQUICDraft24VersionNumber
+	return versionNumber == ietfQUICDraft29VersionNumber
 }
 
 func getALPN(versionNumber uint32) string {
-	return "h3-24"
+	return "h3-29"
 }
 
 // quic_test overrides the server idle timeout.
@@ -223,7 +223,8 @@ func Dial(
 		packetConn,
 		remoteAddr,
 		quicSNIAddress,
-		versionNumber)
+		versionNumber,
+		false)
 	if err != nil {
 		packetConn.Close()
 		return nil, errors.Trace(err)
@@ -495,12 +496,12 @@ func (t *QUICTransporter) closePacketConn() {
 }
 
 func (t *QUICTransporter) dialIETFQUIC(
-	_, _ string, _ *tls.Config, _ *ietf_quic.Config) (ietf_quic.Session, error) {
+	_, _ string, _ *tls.Config, _ *ietf_quic.Config) (ietf_quic.EarlySession, error) {
 	session, err := t.dialQUIC()
 	if err != nil {
 		return nil, errors.Trace(err)
 	}
-	return session.(*ietfQUICSession).Session, nil
+	return session.(*ietfQUICSession).Session.(ietf_quic.EarlySession), nil
 }
 
 func (t *QUICTransporter) dialgQUIC(
@@ -546,7 +547,8 @@ func (t *QUICTransporter) dialQUIC() (retSession quicSession, retErr error) {
 		packetConn,
 		remoteAddr,
 		t.quicSNIAddress,
-		versionNumber)
+		versionNumber,
+		true)
 	if err != nil {
 		packetConn.Close()
 		return nil, errors.Trace(err)
@@ -645,6 +647,10 @@ func (s *ietfQUICSession) OpenStream() (quicStream, error) {
 	return s.Session.OpenStream()
 }
 
+func (s *ietfQUICSession) Close() error {
+	return s.Session.CloseWithError(0, "")
+}
+
 func (s *ietfQUICSession) isErrorIndicatingClosed(err error) bool {
 	if err == nil {
 		return false
@@ -701,13 +707,14 @@ func dialQUIC(
 	packetConn net.PacketConn,
 	remoteAddr *net.UDPAddr,
 	quicSNIAddress string,
-	versionNumber uint32) (quicSession, error) {
+	versionNumber uint32,
+	dialEarly bool) (quicSession, error) {
 
 	if isIETFVersion(versionNumber) {
 
 		quicConfig := &ietf_quic.Config{
 			HandshakeTimeout: time.Duration(1<<63 - 1),
-			IdleTimeout:      CLIENT_IDLE_TIMEOUT,
+			MaxIdleTimeout:   CLIENT_IDLE_TIMEOUT,
 			KeepAlive:        true,
 			Versions: []ietf_quic.VersionNumber{
 				ietf_quic.VersionNumber(versionNumber)},
@@ -718,16 +725,30 @@ func dialQUIC(
 			quicConfig.HandshakeTimeout = time.Until(deadline)
 		}
 
-		dialSession, err := ietf_quic.DialContext(
-			ctx,
-			packetConn,
-			remoteAddr,
-			quicSNIAddress,
-			&tls.Config{
-				InsecureSkipVerify: true,
-				NextProtos:         []string{getALPN(versionNumber)},
-			},
-			quicConfig)
+		var dialSession ietf_quic.Session
+		var err error
+		tlsConfig := &tls.Config{
+			InsecureSkipVerify: true,
+			NextProtos:         []string{getALPN(versionNumber)},
+		}
+
+		if dialEarly {
+			dialSession, err = ietf_quic.DialEarlyContext(
+				ctx,
+				packetConn,
+				remoteAddr,
+				quicSNIAddress,
+				tlsConfig,
+				quicConfig)
+		} else {
+			dialSession, err = ietf_quic.DialContext(
+				ctx,
+				packetConn,
+				remoteAddr,
+				quicSNIAddress,
+				tlsConfig,
+				quicConfig)
+		}
 		if err != nil {
 			return nil, errors.Trace(err)
 		}
@@ -879,12 +900,12 @@ func newMuxListener(
 
 	tlsConfig := &tls.Config{
 		Certificates: []tls.Certificate{tlsCertificate},
-		NextProtos:   []string{getALPN(ietfQUICDraft24VersionNumber)},
+		NextProtos:   []string{getALPN(ietfQUICDraft29VersionNumber)},
 	}
 
 	ietfQUICConfig := &ietf_quic.Config{
 		HandshakeTimeout:      SERVER_HANDSHAKE_TIMEOUT,
-		IdleTimeout:           serverIdleTimeout,
+		MaxIdleTimeout:        serverIdleTimeout,
 		MaxIncomingStreams:    1,
 		MaxIncomingUniStreams: -1,
 		KeepAlive:             true,