package connect import ( "context" "crypto/rand" "crypto/rsa" "crypto/tls" "crypto/x509" "encoding/pem" "fmt" "math/big" "net" "time" "github.com/quic-go/quic-go" "go.uber.org/zap" ) // QUICListener QUIC 监听器 type QUICListener struct { listener *quic.Listener } // NewQUICListener 创建 QUIC 监听器 func NewQUICListener(addr string, logger *zap.Logger) (*QUICListener, error) { // 生成自签名证书(用于测试) cert, err := generateSelfSignedCert() if err != nil { return nil, fmt.Errorf("生成证书失败:%w", err) } tlsConf := &tls.Config{ Certificates: []tls.Certificate{cert}, NextProtos: []string{"meshray-quic"}, } udpAddr, err := net.ResolveUDPAddr("udp", addr) if err != nil { return nil, err } udpConn, err := net.ListenUDP("udp", udpAddr) if err != nil { return nil, err } listener, err := quic.Listen(udpConn, tlsConf, nil) if err != nil { return nil, fmt.Errorf("创建 QUIC 监听器失败:%w", err) } logger.Info("QUIC 监听器已启动", zap.String("addr", addr)) return &QUICListener{ listener: listener, }, nil } // Accept 接受 QUIC 连接 func (l *QUICListener) Accept(ctx context.Context) (*quic.Conn, error) { return l.listener.Accept(ctx) } // Close 关闭监听器 func (l *QUICListener) Close() error { return l.listener.Close() } // QUICClient QUIC 客户端 type QUICClient struct { servers []string logger *zap.Logger } // NewQUICClient 创建 QUIC 客户端 func NewQUICClient(servers []string, logger *zap.Logger) *QUICClient { return &QUICClient{ servers: servers, logger: logger, } } // Connect 建立 QUIC 连接 func (c *QUICClient) Connect(ctx context.Context) (net.Conn, error) { if len(c.servers) == 0 { return nil, fmt.Errorf("未配置 QUIC 服务器") } // 使用不安全的 TLS 配置(跳过证书验证,用于测试) tlsConf := &tls.Config{ InsecureSkipVerify: true, NextProtos: []string{"meshray-quic"}, } // 尝试连接第一个服务器 for _, server := range c.servers { _, err := net.ResolveUDPAddr("udp", server) if err != nil { c.logger.Warn("解析 QUIC 服务器地址失败", zap.String("server", server), zap.Error(err)) continue } var conn *quic.Conn conn, err = quic.DialAddr(ctx, server, tlsConf, nil) if err == nil { c.logger.Info("QUIC 连接已建立", zap.String("server", server), zap.String("local_addr", conn.LocalAddr().String())) return newQUICConn(conn), nil } c.logger.Warn("QUIC 连接失败", zap.String("server", server), zap.Error(err)) } return nil, fmt.Errorf("所有 QUIC 服务器连接失败") } // quicConn QUIC 连接包装器(实现 net.Conn) type quicConn struct { conn *quic.Conn // quic-go v0.59.0 使用 *quic.Conn stream *quic.Stream // 使用 *quic.Stream } // newQUICConn 创建 QUIC 连接包装器 func newQUICConn(conn *quic.Conn) *quicConn { return &quicConn{ conn: conn, } } // OpenStream 打开流 func (c *quicConn) OpenStream() error { stream, err := c.conn.OpenStreamSync(context.Background()) if err != nil { return err } c.stream = stream return nil } // Read 实现 net.Conn func (c *quicConn) Read(b []byte) (n int, err error) { if c.stream == nil { stream, err := c.conn.OpenStreamSync(context.Background()) if err != nil { return 0, err } c.stream = stream } return c.stream.Read(b) } // Write 实现 net.Conn func (c *quicConn) Write(b []byte) (n int, err error) { if c.stream == nil { stream, err := c.conn.OpenStreamSync(context.Background()) if err != nil { return 0, err } c.stream = stream } return c.stream.Write(b) } // Close 实现 net.Conn func (c *quicConn) Close() error { if c.stream != nil { c.stream.Close() } return c.conn.CloseWithError(0, "closed") } // LocalAddr 实现 net.Conn func (c *quicConn) LocalAddr() net.Addr { return c.conn.LocalAddr() } // RemoteAddr 实现 net.Conn func (c *quicConn) RemoteAddr() net.Addr { return c.conn.RemoteAddr() } // SetDeadline 实现 net.Conn func (c *quicConn) SetDeadline(t time.Time) error { if c.stream != nil { return (*c.stream).SetDeadline(t) } return nil } // SetReadDeadline 实现 net.Conn func (c *quicConn) SetReadDeadline(t time.Time) error { if c.stream != nil { return (*c.stream).SetReadDeadline(t) } return nil } // SetWriteDeadline 实现 net.Conn func (c *quicConn) SetWriteDeadline(t time.Time) error { if c.stream != nil { return (*c.stream).SetWriteDeadline(t) } return nil } // generateSelfSignedCert 生成自签名证书(仅用于测试) func generateSelfSignedCert() (tls.Certificate, error) { // 生成私钥 priv, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return tls.Certificate{}, err } // 生成证书模板 template := x509.Certificate{ SerialNumber: big.NewInt(1), NotBefore: time.Now(), NotAfter: time.Now().Add(365 * 24 * time.Hour), DNSNames: []string{"localhost"}, } // 自签名 certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { return tls.Certificate{}, err } // 编码证书和私钥 certPEM := pem.EncodeToMemory(&pem.Block{ Type: "CERTIFICATE", Bytes: certDER, }) keyPEM := pem.EncodeToMemory(&pem.Block{ Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv), }) // 加载证书 return tls.X509KeyPair(certPEM, keyPEM) } // NewTURNFactoryQUIC 创建 QUIC TURN 工厂(用于 9 层降级策略) // 注意:当前版本暂不启用 QUIC 支持,返回 nil func NewTURNFactoryQUIC(servers []string, username, password string, logger *zap.Logger) *TURNFactory { logger.Warn("QUIC 传输模式暂不支持,已跳过") return nil // 暂时返回 nil,未来实现 QUIC 支持时再完善 }