github.com/sagernet/sing@v0.4.0-beta.19.0.20240518125136-f67a0988a636/common/tls/config.go (about)

     1  package tls
     2  
     3  import (
     4  	"context"
     5  	"crypto/tls"
     6  	"net"
     7  )
     8  
     9  type (
    10  	STDConfig       = tls.Config
    11  	STDConn         = tls.Conn
    12  	ConnectionState = tls.ConnectionState
    13  )
    14  
    15  type Config interface {
    16  	ServerName() string
    17  	SetServerName(serverName string)
    18  	NextProtos() []string
    19  	SetNextProtos(nextProto []string)
    20  	Config() (*STDConfig, error)
    21  	Client(conn net.Conn) (Conn, error)
    22  	Clone() Config
    23  }
    24  
    25  type ConfigCompat interface {
    26  	Config
    27  	ClientHandshake(ctx context.Context, conn net.Conn) (Conn, error)
    28  }
    29  
    30  type ServerConfig interface {
    31  	Config
    32  	Start() error
    33  	Close() error
    34  	Server(conn net.Conn) (Conn, error)
    35  }
    36  
    37  type ServerConfigCompat interface {
    38  	ServerConfig
    39  	ServerHandshake(ctx context.Context, conn net.Conn) (Conn, error)
    40  }
    41  
    42  type WithSessionIDGenerator interface {
    43  	SetSessionIDGenerator(generator func(clientHello []byte, sessionID []byte) error)
    44  }
    45  
    46  type Conn interface {
    47  	net.Conn
    48  	NetConn() net.Conn
    49  	HandshakeContext(ctx context.Context) error
    50  	ConnectionState() ConnectionState
    51  }
    52  
    53  func ClientHandshake(ctx context.Context, conn net.Conn, config Config) (Conn, error) {
    54  	if compatServer, isCompat := config.(ConfigCompat); isCompat {
    55  		return compatServer.ClientHandshake(ctx, conn)
    56  	}
    57  	tlsConn, err := config.Client(conn)
    58  	if err != nil {
    59  		return nil, err
    60  	}
    61  	err = tlsConn.HandshakeContext(ctx)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  	return tlsConn, nil
    66  }
    67  
    68  func ServerHandshake(ctx context.Context, conn net.Conn, config ServerConfig) (Conn, error) {
    69  	if compatServer, isCompat := config.(ServerConfigCompat); isCompat {
    70  		return compatServer.ServerHandshake(ctx, conn)
    71  	}
    72  	tlsConn, err := config.Server(conn)
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  	err = tlsConn.HandshakeContext(ctx)
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  	return tlsConn, nil
    81  }