github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/common/tls/client.go (about)

     1  package tls
     2  
     3  import (
     4  	"context"
     5  	"net"
     6  	"os"
     7  
     8  	"github.com/inazumav/sing-box/adapter"
     9  	C "github.com/inazumav/sing-box/constant"
    10  	"github.com/inazumav/sing-box/option"
    11  	M "github.com/sagernet/sing/common/metadata"
    12  	N "github.com/sagernet/sing/common/network"
    13  	aTLS "github.com/sagernet/sing/common/tls"
    14  )
    15  
    16  func NewDialerFromOptions(ctx context.Context, router adapter.Router, dialer N.Dialer, serverAddress string, options option.OutboundTLSOptions) (N.Dialer, error) {
    17  	if !options.Enabled {
    18  		return dialer, nil
    19  	}
    20  	config, err := NewClient(ctx, serverAddress, options)
    21  	if err != nil {
    22  		return nil, err
    23  	}
    24  	return NewDialer(dialer, config), nil
    25  }
    26  
    27  func NewClient(ctx context.Context, serverAddress string, options option.OutboundTLSOptions) (Config, error) {
    28  	if !options.Enabled {
    29  		return nil, nil
    30  	}
    31  	if options.ECH != nil && options.ECH.Enabled {
    32  		return NewECHClient(ctx, serverAddress, options)
    33  	} else if options.Reality != nil && options.Reality.Enabled {
    34  		return NewRealityClient(ctx, serverAddress, options)
    35  	} else if options.UTLS != nil && options.UTLS.Enabled {
    36  		return NewUTLSClient(ctx, serverAddress, options)
    37  	} else {
    38  		return NewSTDClient(ctx, serverAddress, options)
    39  	}
    40  }
    41  
    42  func ClientHandshake(ctx context.Context, conn net.Conn, config Config) (Conn, error) {
    43  	ctx, cancel := context.WithTimeout(ctx, C.TCPTimeout)
    44  	defer cancel()
    45  	return aTLS.ClientHandshake(ctx, conn, config)
    46  }
    47  
    48  type Dialer struct {
    49  	dialer N.Dialer
    50  	config Config
    51  }
    52  
    53  func NewDialer(dialer N.Dialer, config Config) N.Dialer {
    54  	return &Dialer{dialer, config}
    55  }
    56  
    57  func (d *Dialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
    58  	if network != N.NetworkTCP {
    59  		return nil, os.ErrInvalid
    60  	}
    61  	conn, err := d.dialer.DialContext(ctx, network, destination)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  	return ClientHandshake(ctx, conn, d.config)
    66  }
    67  
    68  func (d *Dialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
    69  	return nil, os.ErrInvalid
    70  }