[client] set TLS ServerName for hostname-based QUIC connections (#3673)

* fix: set TLS ServerName for hostname-based QUIC connections

When connecting to a relay server by hostname, certificates are
validated against the IP address instead of the hostname.
This change sets ServerName in the TLS config when connecting
via hostname, ensuring proper certificate validation.

* use default port if port is missing in URL string
This commit is contained in:
Alin Trăistaru
2025-05-05 12:20:54 +02:00
committed by GitHub
parent 055df9854c
commit ffdd115ded

View File

@@ -28,6 +28,16 @@ func (d Dialer) Dial(ctx context.Context, address string) (net.Conn, error) {
return nil, err return nil, err
} }
// Get the base TLS config
tlsClientConfig := quictls.ClientQUICTLSConfig()
// Set ServerName to hostname if not an IP address
host, _, splitErr := net.SplitHostPort(quicURL)
if splitErr == nil && net.ParseIP(host) == nil {
// It's a hostname, not an IP - modify directly
tlsClientConfig.ServerName = host
}
quicConfig := &quic.Config{ quicConfig := &quic.Config{
KeepAlivePeriod: 30 * time.Second, KeepAlivePeriod: 30 * time.Second,
MaxIdleTimeout: 4 * time.Minute, MaxIdleTimeout: 4 * time.Minute,
@@ -47,7 +57,7 @@ func (d Dialer) Dial(ctx context.Context, address string) (net.Conn, error) {
return nil, err return nil, err
} }
session, err := quic.Dial(ctx, udpConn, udpAddr, quictls.ClientQUICTLSConfig(), quicConfig) session, err := quic.Dial(ctx, udpConn, udpAddr, tlsClientConfig, quicConfig)
if err != nil { if err != nil {
if errors.Is(err, context.Canceled) { if errors.Is(err, context.Canceled) {
return nil, err return nil, err
@@ -61,12 +71,29 @@ func (d Dialer) Dial(ctx context.Context, address string) (net.Conn, error) {
} }
func prepareURL(address string) (string, error) { func prepareURL(address string) (string, error) {
if !strings.HasPrefix(address, "rel://") && !strings.HasPrefix(address, "rels://") { var host string
var defaultPort string
switch {
case strings.HasPrefix(address, "rels://"):
host = address[7:]
defaultPort = "443"
case strings.HasPrefix(address, "rel://"):
host = address[6:]
defaultPort = "80"
default:
return "", fmt.Errorf("unsupported scheme: %s", address) return "", fmt.Errorf("unsupported scheme: %s", address)
} }
if strings.HasPrefix(address, "rels://") { finalHost, finalPort, err := net.SplitHostPort(host)
return address[7:], nil if err != nil {
if strings.Contains(err.Error(), "missing port") {
return host + ":" + defaultPort, nil
} }
return address[6:], nil
// return any other split error as is
return "", err
}
return finalHost + ":" + finalPort, nil
} }