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 }