outbound.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. package shadowsocks_2022
  2. import (
  3. "context"
  4. "runtime"
  5. "time"
  6. "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. M "github.com/sagernet/sing/common/metadata"
  12. N "github.com/sagernet/sing/common/network"
  13. "github.com/sagernet/sing/common/uot"
  14. "github.com/xtls/xray-core/common"
  15. "github.com/xtls/xray-core/common/buf"
  16. "github.com/xtls/xray-core/common/net"
  17. "github.com/xtls/xray-core/common/session"
  18. "github.com/xtls/xray-core/common/singbridge"
  19. "github.com/xtls/xray-core/transport"
  20. "github.com/xtls/xray-core/transport/internet"
  21. )
  22. func init() {
  23. common.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
  24. return NewClient(ctx, config.(*ClientConfig))
  25. }))
  26. }
  27. type Outbound struct {
  28. ctx context.Context
  29. server net.Destination
  30. method shadowsocks.Method
  31. uot bool
  32. }
  33. func NewClient(ctx context.Context, config *ClientConfig) (*Outbound, error) {
  34. o := &Outbound{
  35. ctx: ctx,
  36. server: net.Destination{
  37. Address: config.Address.AsAddress(),
  38. Port: net.Port(config.Port),
  39. Network: net.Network_TCP,
  40. },
  41. uot: config.UdpOverTcp,
  42. }
  43. if C.Contains(shadowaead_2022.List, config.Method) {
  44. if config.Key == "" {
  45. return nil, newError("missing psk")
  46. }
  47. method, err := shadowaead_2022.NewWithPassword(config.Method, config.Key)
  48. if err != nil {
  49. return nil, newError("create method").Base(err)
  50. }
  51. o.method = method
  52. } else {
  53. return nil, newError("unknown method ", config.Method)
  54. }
  55. return o, nil
  56. }
  57. func (o *Outbound) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {
  58. var inboundConn net.Conn
  59. inbound := session.InboundFromContext(ctx)
  60. if inbound != nil {
  61. inboundConn = inbound.Conn
  62. }
  63. outbound := session.OutboundFromContext(ctx)
  64. if outbound == nil || !outbound.Target.IsValid() {
  65. return newError("target not specified")
  66. }
  67. destination := outbound.Target
  68. network := destination.Network
  69. newError("tunneling request to ", destination, " via ", o.server.NetAddr()).WriteToLog(session.ExportIDToError(ctx))
  70. serverDestination := o.server
  71. if o.uot {
  72. serverDestination.Network = net.Network_TCP
  73. } else {
  74. serverDestination.Network = network
  75. }
  76. connection, err := dialer.Dial(ctx, serverDestination)
  77. if err != nil {
  78. return newError("failed to connect to server").Base(err)
  79. }
  80. if network == net.Network_TCP {
  81. serverConn := o.method.DialEarlyConn(connection, singbridge.ToSocksaddr(destination))
  82. var handshake bool
  83. if timeoutReader, isTimeoutReader := link.Reader.(buf.TimeoutReader); isTimeoutReader {
  84. mb, err := timeoutReader.ReadMultiBufferTimeout(time.Millisecond * 100)
  85. if err != nil && err != buf.ErrNotTimeoutReader && err != buf.ErrReadTimeout {
  86. return newError("read payload").Base(err)
  87. }
  88. _payload := B.StackNew()
  89. payload := C.Dup(_payload)
  90. defer payload.Release()
  91. for {
  92. payload.FullReset()
  93. nb, n := buf.SplitBytes(mb, payload.FreeBytes())
  94. if n > 0 {
  95. payload.Truncate(n)
  96. _, err = serverConn.Write(payload.Bytes())
  97. if err != nil {
  98. return newError("write payload").Base(err)
  99. }
  100. handshake = true
  101. }
  102. if nb.IsEmpty() {
  103. break
  104. } else {
  105. mb = nb
  106. }
  107. }
  108. runtime.KeepAlive(_payload)
  109. }
  110. if !handshake {
  111. _, err = serverConn.Write(nil)
  112. if err != nil {
  113. return newError("client handshake").Base(err)
  114. }
  115. }
  116. return singbridge.CopyConn(ctx, inboundConn, link, serverConn)
  117. } else {
  118. var packetConn N.PacketConn
  119. if pc, isPacketConn := inboundConn.(N.PacketConn); isPacketConn {
  120. packetConn = pc
  121. } else if nc, isNetPacket := inboundConn.(net.PacketConn); isNetPacket {
  122. packetConn = bufio.NewPacketConn(nc)
  123. } else {
  124. packetConn = &packetConnWrapper{
  125. Reader: link.Reader,
  126. Writer: link.Writer,
  127. Conn: inboundConn,
  128. Dest: destination,
  129. }
  130. }
  131. if o.uot {
  132. serverConn := o.method.DialEarlyConn(connection, M.Socksaddr{Fqdn: uot.UOTMagicAddress})
  133. return singbridge.ReturnError(bufio.CopyPacketConn(ctx, packetConn, uot.NewClientConn(serverConn)))
  134. } else {
  135. serverConn := o.method.DialPacketConn(connection)
  136. return singbridge.ReturnError(bufio.CopyPacketConn(ctx, packetConn, serverConn))
  137. }
  138. }
  139. }