mirror of
				https://github.com/bolucat/Archive.git
				synced 2025-10-30 03:22:11 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			143 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			143 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package shadowtls
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"net"
 | |
| 
 | |
| 	"github.com/sagernet/sing-box/adapter"
 | |
| 	"github.com/sagernet/sing-box/adapter/inbound"
 | |
| 	"github.com/sagernet/sing-box/common/dialer"
 | |
| 	"github.com/sagernet/sing-box/common/listener"
 | |
| 	C "github.com/sagernet/sing-box/constant"
 | |
| 	"github.com/sagernet/sing-box/log"
 | |
| 	"github.com/sagernet/sing-box/option"
 | |
| 	"github.com/sagernet/sing-shadowtls"
 | |
| 	"github.com/sagernet/sing/common"
 | |
| 	"github.com/sagernet/sing/common/auth"
 | |
| 	E "github.com/sagernet/sing/common/exceptions"
 | |
| 	"github.com/sagernet/sing/common/logger"
 | |
| 	M "github.com/sagernet/sing/common/metadata"
 | |
| 	N "github.com/sagernet/sing/common/network"
 | |
| )
 | |
| 
 | |
| func RegisterInbound(registry *inbound.Registry) {
 | |
| 	inbound.Register[option.ShadowTLSInboundOptions](registry, C.TypeShadowTLS, NewInbound)
 | |
| }
 | |
| 
 | |
| type Inbound struct {
 | |
| 	inbound.Adapter
 | |
| 	router   adapter.Router
 | |
| 	logger   logger.ContextLogger
 | |
| 	listener *listener.Listener
 | |
| 	service  *shadowtls.Service
 | |
| }
 | |
| 
 | |
| func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowTLSInboundOptions) (adapter.Inbound, error) {
 | |
| 	inbound := &Inbound{
 | |
| 		Adapter: inbound.NewAdapter(C.TypeShadowTLS, tag),
 | |
| 		router:  router,
 | |
| 		logger:  logger,
 | |
| 	}
 | |
| 
 | |
| 	if options.Version == 0 {
 | |
| 		options.Version = 1
 | |
| 	}
 | |
| 
 | |
| 	var handshakeForServerName map[string]shadowtls.HandshakeConfig
 | |
| 	if options.Version > 1 {
 | |
| 		handshakeForServerName = make(map[string]shadowtls.HandshakeConfig)
 | |
| 		if options.HandshakeForServerName != nil {
 | |
| 			for _, entry := range options.HandshakeForServerName.Entries() {
 | |
| 				handshakeDialer, err := dialer.New(ctx, entry.Value.DialerOptions, entry.Value.ServerIsDomain())
 | |
| 				if err != nil {
 | |
| 					return nil, err
 | |
| 				}
 | |
| 				handshakeForServerName[entry.Key] = shadowtls.HandshakeConfig{
 | |
| 					Server: entry.Value.ServerOptions.Build(),
 | |
| 					Dialer: handshakeDialer,
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	serverIsDomain := options.Handshake.ServerIsDomain()
 | |
| 	if options.WildcardSNI != option.ShadowTLSWildcardSNIOff {
 | |
| 		serverIsDomain = true
 | |
| 	}
 | |
| 	handshakeDialer, err := dialer.New(ctx, options.Handshake.DialerOptions, serverIsDomain)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	service, err := shadowtls.NewService(shadowtls.ServiceConfig{
 | |
| 		Version:  options.Version,
 | |
| 		Password: options.Password,
 | |
| 		Users: common.Map(options.Users, func(it option.ShadowTLSUser) shadowtls.User {
 | |
| 			return (shadowtls.User)(it)
 | |
| 		}),
 | |
| 		Handshake: shadowtls.HandshakeConfig{
 | |
| 			Server: options.Handshake.ServerOptions.Build(),
 | |
| 			Dialer: handshakeDialer,
 | |
| 		},
 | |
| 		HandshakeForServerName: handshakeForServerName,
 | |
| 		StrictMode:             options.StrictMode,
 | |
| 		WildcardSNI:            shadowtls.WildcardSNI(options.WildcardSNI),
 | |
| 		Handler:                (*inboundHandler)(inbound),
 | |
| 		Logger:                 logger,
 | |
| 	})
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	inbound.service = service
 | |
| 	inbound.listener = listener.New(listener.Options{
 | |
| 		Context:           ctx,
 | |
| 		Logger:            logger,
 | |
| 		Network:           []string{N.NetworkTCP},
 | |
| 		Listen:            options.ListenOptions,
 | |
| 		ConnectionHandler: inbound,
 | |
| 	})
 | |
| 	return inbound, nil
 | |
| }
 | |
| 
 | |
| func (h *Inbound) Start(stage adapter.StartStage) error {
 | |
| 	if stage != adapter.StartStateStart {
 | |
| 		return nil
 | |
| 	}
 | |
| 	return h.listener.Start()
 | |
| }
 | |
| 
 | |
| func (h *Inbound) Close() error {
 | |
| 	return h.listener.Close()
 | |
| }
 | |
| 
 | |
| func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
 | |
| 	err := h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, metadata.Source, metadata.Destination, onClose)
 | |
| 	N.CloseOnHandshakeFailure(conn, onClose, err)
 | |
| 	if err != nil {
 | |
| 		if E.IsClosedOrCanceled(err) {
 | |
| 			h.logger.DebugContext(ctx, "connection closed: ", err)
 | |
| 		} else {
 | |
| 			h.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", metadata.Source))
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| type inboundHandler Inbound
 | |
| 
 | |
| func (h *inboundHandler) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
 | |
| 	var metadata adapter.InboundContext
 | |
| 	metadata.Inbound = h.Tag()
 | |
| 	metadata.InboundType = h.Type()
 | |
| 	//nolint:staticcheck
 | |
| 	metadata.InboundDetour = h.listener.ListenOptions().Detour
 | |
| 	//nolint:staticcheck
 | |
| 	metadata.InboundOptions = h.listener.ListenOptions().InboundOptions
 | |
| 	metadata.Source = source
 | |
| 	metadata.Destination = destination
 | |
| 	if userName, _ := auth.UserFromContext[string](ctx); userName != "" {
 | |
| 		metadata.User = userName
 | |
| 		h.logger.InfoContext(ctx, "[", userName, "] inbound connection to ", metadata.Destination)
 | |
| 	} else {
 | |
| 		h.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
 | |
| 	}
 | |
| 	h.router.RouteConnectionEx(ctx, conn, metadata, onClose)
 | |
| }
 | 
![github-action[bot]](/assets/img/avatar_default.png)