| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 | 
							- package anytls
 
- import (
 
- 	"context"
 
- 	"net"
 
- 	"os"
 
- 	"github.com/sagernet/sing-box/adapter"
 
- 	"github.com/sagernet/sing-box/adapter/outbound"
 
- 	"github.com/sagernet/sing-box/common/dialer"
 
- 	"github.com/sagernet/sing-box/common/tls"
 
- 	C "github.com/sagernet/sing-box/constant"
 
- 	"github.com/sagernet/sing-box/log"
 
- 	"github.com/sagernet/sing-box/option"
 
- 	"github.com/sagernet/sing/common"
 
- 	M "github.com/sagernet/sing/common/metadata"
 
- 	N "github.com/sagernet/sing/common/network"
 
- 	"github.com/sagernet/sing/common/uot"
 
- 	anytls "github.com/anytls/sing-anytls"
 
- )
 
- func RegisterOutbound(registry *outbound.Registry) {
 
- 	outbound.Register[option.AnyTLSOutboundOptions](registry, C.TypeAnyTLS, NewOutbound)
 
- }
 
- type Outbound struct {
 
- 	outbound.Adapter
 
- 	dialer    tls.Dialer
 
- 	server    M.Socksaddr
 
- 	tlsConfig tls.Config
 
- 	client    *anytls.Client
 
- 	uotClient *uot.Client
 
- 	logger    log.ContextLogger
 
- }
 
- func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.AnyTLSOutboundOptions) (adapter.Outbound, error) {
 
- 	outbound := &Outbound{
 
- 		Adapter: outbound.NewAdapterWithDialerOptions(C.TypeAnyTLS, tag, []string{N.NetworkTCP, N.NetworkUDP}, options.DialerOptions),
 
- 		server:  options.ServerOptions.Build(),
 
- 		logger:  logger,
 
- 	}
 
- 	if options.TLS == nil || !options.TLS.Enabled {
 
- 		return nil, C.ErrTLSRequired
 
- 	}
 
- 	tlsConfig, err := tls.NewClient(ctx, logger, options.Server, common.PtrValueOrDefault(options.TLS))
 
- 	if err != nil {
 
- 		return nil, err
 
- 	}
 
- 	outbound.tlsConfig = tlsConfig
 
- 	outboundDialer, err := dialer.NewWithOptions(dialer.Options{
 
- 		Context:        ctx,
 
- 		Options:        options.DialerOptions,
 
- 		RemoteIsDomain: options.ServerIsDomain(),
 
- 	})
 
- 	if err != nil {
 
- 		return nil, err
 
- 	}
 
- 	outbound.dialer = tls.NewDialer(outboundDialer, tlsConfig)
 
- 	client, err := anytls.NewClient(ctx, anytls.ClientConfig{
 
- 		Password:                 options.Password,
 
- 		IdleSessionCheckInterval: options.IdleSessionCheckInterval.Build(),
 
- 		IdleSessionTimeout:       options.IdleSessionTimeout.Build(),
 
- 		MinIdleSession:           options.MinIdleSession,
 
- 		DialOut:                  outbound.dialOut,
 
- 		Logger:                   logger,
 
- 	})
 
- 	if err != nil {
 
- 		return nil, err
 
- 	}
 
- 	outbound.client = client
 
- 	outbound.uotClient = &uot.Client{
 
- 		Dialer:  (anytlsDialer)(client.CreateProxy),
 
- 		Version: uot.Version,
 
- 	}
 
- 	return outbound, nil
 
- }
 
- type anytlsDialer func(ctx context.Context, destination M.Socksaddr) (net.Conn, error)
 
- func (d anytlsDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
 
- 	return d(ctx, destination)
 
- }
 
- func (d anytlsDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
 
- 	return nil, os.ErrInvalid
 
- }
 
- func (h *Outbound) dialOut(ctx context.Context) (net.Conn, error) {
 
- 	return h.dialer.DialTLSContext(ctx, h.server)
 
- }
 
- func (h *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
 
- 	ctx, metadata := adapter.ExtendContext(ctx)
 
- 	metadata.Outbound = h.Tag()
 
- 	metadata.Destination = destination
 
- 	switch N.NetworkName(network) {
 
- 	case N.NetworkTCP:
 
- 		h.logger.InfoContext(ctx, "outbound connection to ", destination)
 
- 		return h.client.CreateProxy(ctx, destination)
 
- 	case N.NetworkUDP:
 
- 		h.logger.InfoContext(ctx, "outbound UoT packet connection to ", destination)
 
- 		return h.uotClient.DialContext(ctx, network, destination)
 
- 	}
 
- 	return nil, os.ErrInvalid
 
- }
 
- func (h *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
 
- 	ctx, metadata := adapter.ExtendContext(ctx)
 
- 	metadata.Outbound = h.Tag()
 
- 	metadata.Destination = destination
 
- 	h.logger.InfoContext(ctx, "outbound UoT packet connection to ", destination)
 
- 	return h.uotClient.ListenPacket(ctx, destination)
 
- }
 
- func (h *Outbound) Close() error {
 
- 	return common.Close(h.client)
 
- }
 
 
  |