github.com/xraypb/xray-core@v1.6.6/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)
    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  
    68  	var metadata M.Metadata
    69  	if inbound.Source.IsValid() {
    70  		metadata.Source = M.ParseSocksaddr(inbound.Source.NetAddr())
    71  	}
    72  
    73  	ctx = session.ContextWithDispatcher(ctx, dispatcher)
    74  
    75  	if network == net.Network_TCP {
    76  		return returnError(i.service.NewConnection(ctx, connection, metadata))
    77  	} else {
    78  		reader := buf.NewReader(connection)
    79  		pc := &natPacketConn{connection}
    80  		for {
    81  			mb, err := reader.ReadMultiBuffer()
    82  			if err != nil {
    83  				buf.ReleaseMulti(mb)
    84  				return returnError(err)
    85  			}
    86  			for _, buffer := range mb {
    87  				packet := B.As(buffer.Bytes()).ToOwned()
    88  				err = i.service.NewPacket(ctx, pc, packet, metadata)
    89  				if err != nil {
    90  					packet.Release()
    91  					buf.ReleaseMulti(mb)
    92  					return err
    93  				}
    94  				buffer.Release()
    95  			}
    96  		}
    97  	}
    98  }
    99  
   100  func (i *Inbound) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
   101  	inbound := session.InboundFromContext(ctx)
   102  	inbound.User = &protocol.MemoryUser{
   103  		Email: i.email,
   104  		Level: uint32(i.level),
   105  	}
   106  	ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
   107  		From:   metadata.Source,
   108  		To:     metadata.Destination,
   109  		Status: log.AccessAccepted,
   110  		Email:  i.email,
   111  	})
   112  	newError("tunnelling request to tcp:", metadata.Destination).WriteToLog(session.ExportIDToError(ctx))
   113  	dispatcher := session.DispatcherFromContext(ctx)
   114  	link, err := dispatcher.Dispatch(ctx, toDestination(metadata.Destination, net.Network_TCP))
   115  	if err != nil {
   116  		return err
   117  	}
   118  	outConn := &pipeConnWrapper{
   119  		&buf.BufferedReader{Reader: link.Reader},
   120  		link.Writer,
   121  		conn,
   122  	}
   123  	return bufio.CopyConn(ctx, conn, outConn)
   124  }
   125  
   126  func (i *Inbound) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
   127  	inbound := session.InboundFromContext(ctx)
   128  	inbound.User = &protocol.MemoryUser{
   129  		Email: i.email,
   130  		Level: uint32(i.level),
   131  	}
   132  	ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
   133  		From:   metadata.Source,
   134  		To:     metadata.Destination,
   135  		Status: log.AccessAccepted,
   136  		Email:  i.email,
   137  	})
   138  	newError("tunnelling request to udp:", metadata.Destination).WriteToLog(session.ExportIDToError(ctx))
   139  	dispatcher := session.DispatcherFromContext(ctx)
   140  	destination := toDestination(metadata.Destination, net.Network_UDP)
   141  	link, err := dispatcher.Dispatch(ctx, destination)
   142  	if err != nil {
   143  		return err
   144  	}
   145  	outConn := &packetConnWrapper{
   146  		Reader: link.Reader,
   147  		Writer: link.Writer,
   148  		Dest:   destination,
   149  	}
   150  	return bufio.CopyPacketConn(ctx, conn, outConn)
   151  }
   152  
   153  func (i *Inbound) NewError(ctx context.Context, err error) {
   154  	if E.IsClosed(err) {
   155  		return
   156  	}
   157  	newError(err).AtWarning().WriteToLog()
   158  }
   159  
   160  type natPacketConn struct {
   161  	net.Conn
   162  }
   163  
   164  func (c *natPacketConn) ReadPacket(buffer *B.Buffer) (addr M.Socksaddr, err error) {
   165  	_, err = buffer.ReadFrom(c)
   166  	return
   167  }
   168  
   169  func (c *natPacketConn) WritePacket(buffer *B.Buffer, addr M.Socksaddr) error {
   170  	_, err := buffer.WriteTo(c)
   171  	return err
   172  }