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