github.com/xmplusdev/xmcore@v1.8.11-0.20240412132628-5518b55526af/proxy/shadowsocks_2022/inbound.go (about)

     1  package shadowsocks_2022
     2  
     3  import (
     4  	"context"
     5  
     6  	shadowsocks "github.com/sagernet/sing-shadowsocks"
     7  	"github.com/sagernet/sing-shadowsocks/shadowaead_2022"
     8  	C "github.com/sagernet/sing/common"
     9  	B "github.com/sagernet/sing/common/buf"
    10  	"github.com/sagernet/sing/common/bufio"
    11  	E "github.com/sagernet/sing/common/exceptions"
    12  	M "github.com/sagernet/sing/common/metadata"
    13  	N "github.com/sagernet/sing/common/network"
    14  	"github.com/xmplusdev/xmcore/common"
    15  	"github.com/xmplusdev/xmcore/common/buf"
    16  	"github.com/xmplusdev/xmcore/common/log"
    17  	"github.com/xmplusdev/xmcore/common/net"
    18  	"github.com/xmplusdev/xmcore/common/protocol"
    19  	"github.com/xmplusdev/xmcore/common/session"
    20  	"github.com/xmplusdev/xmcore/common/singbridge"
    21  	"github.com/xmplusdev/xmcore/features/routing"
    22  	"github.com/xmplusdev/xmcore/transport/internet/stat"
    23  )
    24  
    25  func init() {
    26  	common.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
    27  		return NewServer(ctx, config.(*ServerConfig))
    28  	}))
    29  }
    30  
    31  type Inbound struct {
    32  	networks []net.Network
    33  	service  shadowsocks.Service
    34  	email    string
    35  	level    int
    36  }
    37  
    38  func NewServer(ctx context.Context, config *ServerConfig) (*Inbound, error) {
    39  	networks := config.Network
    40  	if len(networks) == 0 {
    41  		networks = []net.Network{
    42  			net.Network_TCP,
    43  			net.Network_UDP,
    44  		}
    45  	}
    46  	inbound := &Inbound{
    47  		networks: networks,
    48  		email:    config.Email,
    49  		level:    int(config.Level),
    50  	}
    51  	if !C.Contains(shadowaead_2022.List, config.Method) {
    52  		return nil, newError("unsupported method ", config.Method)
    53  	}
    54  	service, err := shadowaead_2022.NewServiceWithPassword(config.Method, config.Key, 500, inbound, nil)
    55  	if err != nil {
    56  		return nil, newError("create service").Base(err)
    57  	}
    58  	inbound.service = service
    59  	return inbound, nil
    60  }
    61  
    62  func (i *Inbound) Network() []net.Network {
    63  	return i.networks
    64  }
    65  
    66  func (i *Inbound) Process(ctx context.Context, network net.Network, connection stat.Connection, dispatcher routing.Dispatcher) error {
    67  	inbound := session.InboundFromContext(ctx)
    68  	inbound.Name = "shadowsocks-2022"
    69  	inbound.SetCanSpliceCopy(3)
    70  
    71  	var metadata M.Metadata
    72  	if inbound.Source.IsValid() {
    73  		metadata.Source = M.ParseSocksaddr(inbound.Source.NetAddr())
    74  	}
    75  
    76  	ctx = session.ContextWithDispatcher(ctx, dispatcher)
    77  
    78  	if network == net.Network_TCP {
    79  		return singbridge.ReturnError(i.service.NewConnection(ctx, connection, metadata))
    80  	} else {
    81  		reader := buf.NewReader(connection)
    82  		pc := &natPacketConn{connection}
    83  		for {
    84  			mb, err := reader.ReadMultiBuffer()
    85  			if err != nil {
    86  				buf.ReleaseMulti(mb)
    87  				return singbridge.ReturnError(err)
    88  			}
    89  			for _, buffer := range mb {
    90  				packet := B.As(buffer.Bytes()).ToOwned()
    91  				buffer.Release()
    92  				err = i.service.NewPacket(ctx, pc, packet, metadata)
    93  				if err != nil {
    94  					packet.Release()
    95  					buf.ReleaseMulti(mb)
    96  					return err
    97  				}
    98  			}
    99  		}
   100  	}
   101  }
   102  
   103  func (i *Inbound) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
   104  	inbound := session.InboundFromContext(ctx)
   105  	inbound.User = &protocol.MemoryUser{
   106  		Email: i.email,
   107  		Level: uint32(i.level),
   108  	}
   109  	ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
   110  		From:   metadata.Source,
   111  		To:     metadata.Destination,
   112  		Status: log.AccessAccepted,
   113  		Email:  i.email,
   114  	})
   115  	newError("tunnelling request to tcp:", metadata.Destination).WriteToLog(session.ExportIDToError(ctx))
   116  	dispatcher := session.DispatcherFromContext(ctx)
   117  	link, err := dispatcher.Dispatch(ctx, singbridge.ToDestination(metadata.Destination, net.Network_TCP))
   118  	if err != nil {
   119  		return err
   120  	}
   121  	return singbridge.CopyConn(ctx, nil, link, conn)
   122  }
   123  
   124  func (i *Inbound) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
   125  	inbound := session.InboundFromContext(ctx)
   126  	inbound.User = &protocol.MemoryUser{
   127  		Email: i.email,
   128  		Level: uint32(i.level),
   129  	}
   130  	ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
   131  		From:   metadata.Source,
   132  		To:     metadata.Destination,
   133  		Status: log.AccessAccepted,
   134  		Email:  i.email,
   135  	})
   136  	newError("tunnelling request to udp:", metadata.Destination).WriteToLog(session.ExportIDToError(ctx))
   137  	dispatcher := session.DispatcherFromContext(ctx)
   138  	destination := singbridge.ToDestination(metadata.Destination, net.Network_UDP)
   139  	link, err := dispatcher.Dispatch(ctx, destination)
   140  	if err != nil {
   141  		return err
   142  	}
   143  	outConn := &singbridge.PacketConnWrapper{
   144  		Reader: link.Reader,
   145  		Writer: link.Writer,
   146  		Dest:   destination,
   147  	}
   148  	return bufio.CopyPacketConn(ctx, conn, outConn)
   149  }
   150  
   151  func (i *Inbound) NewError(ctx context.Context, err error) {
   152  	if E.IsClosed(err) {
   153  		return
   154  	}
   155  	newError(err).AtWarning().WriteToLog()
   156  }
   157  
   158  type natPacketConn struct {
   159  	net.Conn
   160  }
   161  
   162  func (c *natPacketConn) ReadPacket(buffer *B.Buffer) (addr M.Socksaddr, err error) {
   163  	_, err = buffer.ReadFrom(c)
   164  	return
   165  }
   166  
   167  func (c *natPacketConn) WritePacket(buffer *B.Buffer, addr M.Socksaddr) error {
   168  	_, err := buffer.WriteTo(c)
   169  	return err
   170  }