default.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. package outbound
  2. import (
  3. "context"
  4. "net"
  5. "net/netip"
  6. "os"
  7. "time"
  8. "github.com/sagernet/sing-box/adapter"
  9. C "github.com/sagernet/sing-box/constant"
  10. "github.com/sagernet/sing-dns"
  11. "github.com/sagernet/sing/common"
  12. "github.com/sagernet/sing/common/buf"
  13. "github.com/sagernet/sing/common/bufio"
  14. "github.com/sagernet/sing/common/canceler"
  15. E "github.com/sagernet/sing/common/exceptions"
  16. M "github.com/sagernet/sing/common/metadata"
  17. N "github.com/sagernet/sing/common/network"
  18. )
  19. func NewConnection(ctx context.Context, this N.Dialer, conn net.Conn, metadata adapter.InboundContext) error {
  20. defer conn.Close()
  21. ctx = adapter.WithContext(ctx, &metadata)
  22. var outConn net.Conn
  23. var err error
  24. if len(metadata.DestinationAddresses) > 0 {
  25. outConn, err = N.DialSerial(ctx, this, N.NetworkTCP, metadata.Destination, metadata.DestinationAddresses)
  26. } else {
  27. outConn, err = this.DialContext(ctx, N.NetworkTCP, metadata.Destination)
  28. }
  29. if err != nil {
  30. return N.ReportHandshakeFailure(conn, err)
  31. }
  32. err = N.ReportConnHandshakeSuccess(conn, outConn)
  33. if err != nil {
  34. outConn.Close()
  35. return err
  36. }
  37. return CopyEarlyConn(ctx, conn, outConn)
  38. }
  39. func NewDirectConnection(ctx context.Context, router adapter.Router, this N.Dialer, conn net.Conn, metadata adapter.InboundContext, domainStrategy dns.DomainStrategy) error {
  40. defer conn.Close()
  41. ctx = adapter.WithContext(ctx, &metadata)
  42. var outConn net.Conn
  43. var err error
  44. if len(metadata.DestinationAddresses) > 0 {
  45. outConn, err = N.DialSerial(ctx, this, N.NetworkTCP, metadata.Destination, metadata.DestinationAddresses)
  46. } else if metadata.Destination.IsFqdn() {
  47. var destinationAddresses []netip.Addr
  48. destinationAddresses, err = router.Lookup(ctx, metadata.Destination.Fqdn, domainStrategy)
  49. if err != nil {
  50. return N.ReportHandshakeFailure(conn, err)
  51. }
  52. outConn, err = N.DialSerial(ctx, this, N.NetworkTCP, metadata.Destination, destinationAddresses)
  53. } else {
  54. outConn, err = this.DialContext(ctx, N.NetworkTCP, metadata.Destination)
  55. }
  56. if err != nil {
  57. return N.ReportHandshakeFailure(conn, err)
  58. }
  59. err = N.ReportConnHandshakeSuccess(conn, outConn)
  60. if err != nil {
  61. outConn.Close()
  62. return err
  63. }
  64. return CopyEarlyConn(ctx, conn, outConn)
  65. }
  66. func NewPacketConnection(ctx context.Context, this N.Dialer, conn N.PacketConn, metadata adapter.InboundContext) error {
  67. defer conn.Close()
  68. ctx = adapter.WithContext(ctx, &metadata)
  69. var (
  70. outPacketConn net.PacketConn
  71. outConn net.Conn
  72. destinationAddress netip.Addr
  73. err error
  74. )
  75. if metadata.UDPConnect {
  76. if len(metadata.DestinationAddresses) > 0 {
  77. outConn, err = N.DialSerial(ctx, this, N.NetworkUDP, metadata.Destination, metadata.DestinationAddresses)
  78. } else {
  79. outConn, err = this.DialContext(ctx, N.NetworkUDP, metadata.Destination)
  80. }
  81. if err != nil {
  82. return N.ReportHandshakeFailure(conn, err)
  83. }
  84. outPacketConn = bufio.NewUnbindPacketConn(outConn)
  85. connRemoteAddr := M.AddrFromNet(outConn.RemoteAddr())
  86. if connRemoteAddr != metadata.Destination.Addr {
  87. destinationAddress = connRemoteAddr
  88. }
  89. } else {
  90. if len(metadata.DestinationAddresses) > 0 {
  91. outPacketConn, destinationAddress, err = N.ListenSerial(ctx, this, metadata.Destination, metadata.DestinationAddresses)
  92. } else {
  93. outPacketConn, err = this.ListenPacket(ctx, metadata.Destination)
  94. }
  95. if err != nil {
  96. return N.ReportHandshakeFailure(conn, err)
  97. }
  98. }
  99. err = N.ReportPacketConnHandshakeSuccess(conn, outPacketConn)
  100. if err != nil {
  101. outPacketConn.Close()
  102. return err
  103. }
  104. if destinationAddress.IsValid() {
  105. if metadata.Destination.IsFqdn() {
  106. if metadata.UDPDisableDomainUnmapping {
  107. outPacketConn = bufio.NewUnidirectionalNATPacketConn(bufio.NewPacketConn(outPacketConn), M.SocksaddrFrom(destinationAddress, metadata.Destination.Port), metadata.Destination)
  108. } else {
  109. outPacketConn = bufio.NewNATPacketConn(bufio.NewPacketConn(outPacketConn), M.SocksaddrFrom(destinationAddress, metadata.Destination.Port), metadata.Destination)
  110. }
  111. }
  112. if natConn, loaded := common.Cast[bufio.NATPacketConn](conn); loaded {
  113. natConn.UpdateDestination(destinationAddress)
  114. }
  115. }
  116. switch metadata.Protocol {
  117. case C.ProtocolSTUN:
  118. ctx, conn = canceler.NewPacketConn(ctx, conn, C.STUNTimeout)
  119. case C.ProtocolQUIC:
  120. ctx, conn = canceler.NewPacketConn(ctx, conn, C.QUICTimeout)
  121. case C.ProtocolDNS:
  122. ctx, conn = canceler.NewPacketConn(ctx, conn, C.DNSTimeout)
  123. }
  124. return bufio.CopyPacketConn(ctx, conn, bufio.NewPacketConn(outPacketConn))
  125. }
  126. func NewDirectPacketConnection(ctx context.Context, router adapter.Router, this N.Dialer, conn N.PacketConn, metadata adapter.InboundContext, domainStrategy dns.DomainStrategy) error {
  127. defer conn.Close()
  128. ctx = adapter.WithContext(ctx, &metadata)
  129. var (
  130. outPacketConn net.PacketConn
  131. outConn net.Conn
  132. destinationAddress netip.Addr
  133. err error
  134. )
  135. if metadata.UDPConnect {
  136. if len(metadata.DestinationAddresses) > 0 {
  137. outConn, err = N.DialSerial(ctx, this, N.NetworkUDP, metadata.Destination, metadata.DestinationAddresses)
  138. } else if metadata.Destination.IsFqdn() {
  139. var destinationAddresses []netip.Addr
  140. destinationAddresses, err = router.Lookup(ctx, metadata.Destination.Fqdn, domainStrategy)
  141. if err != nil {
  142. return N.ReportHandshakeFailure(conn, err)
  143. }
  144. outConn, err = N.DialSerial(ctx, this, N.NetworkUDP, metadata.Destination, destinationAddresses)
  145. } else {
  146. outConn, err = this.DialContext(ctx, N.NetworkUDP, metadata.Destination)
  147. }
  148. if err != nil {
  149. return N.ReportHandshakeFailure(conn, err)
  150. }
  151. connRemoteAddr := M.AddrFromNet(outConn.RemoteAddr())
  152. if connRemoteAddr != metadata.Destination.Addr {
  153. destinationAddress = connRemoteAddr
  154. }
  155. } else {
  156. if len(metadata.DestinationAddresses) > 0 {
  157. outPacketConn, destinationAddress, err = N.ListenSerial(ctx, this, metadata.Destination, metadata.DestinationAddresses)
  158. } else if metadata.Destination.IsFqdn() {
  159. var destinationAddresses []netip.Addr
  160. destinationAddresses, err = router.Lookup(ctx, metadata.Destination.Fqdn, domainStrategy)
  161. if err != nil {
  162. return N.ReportHandshakeFailure(conn, err)
  163. }
  164. outPacketConn, destinationAddress, err = N.ListenSerial(ctx, this, metadata.Destination, destinationAddresses)
  165. } else {
  166. outPacketConn, err = this.ListenPacket(ctx, metadata.Destination)
  167. }
  168. if err != nil {
  169. return N.ReportHandshakeFailure(conn, err)
  170. }
  171. }
  172. err = N.ReportPacketConnHandshakeSuccess(conn, outPacketConn)
  173. if err != nil {
  174. outPacketConn.Close()
  175. return err
  176. }
  177. if destinationAddress.IsValid() {
  178. if metadata.Destination.IsFqdn() {
  179. outPacketConn = bufio.NewNATPacketConn(bufio.NewPacketConn(outPacketConn), M.SocksaddrFrom(destinationAddress, metadata.Destination.Port), metadata.Destination)
  180. }
  181. if natConn, loaded := common.Cast[bufio.NATPacketConn](conn); loaded {
  182. natConn.UpdateDestination(destinationAddress)
  183. }
  184. }
  185. switch metadata.Protocol {
  186. case C.ProtocolSTUN:
  187. ctx, conn = canceler.NewPacketConn(ctx, conn, C.STUNTimeout)
  188. case C.ProtocolQUIC:
  189. ctx, conn = canceler.NewPacketConn(ctx, conn, C.QUICTimeout)
  190. case C.ProtocolDNS:
  191. ctx, conn = canceler.NewPacketConn(ctx, conn, C.DNSTimeout)
  192. }
  193. return bufio.CopyPacketConn(ctx, conn, bufio.NewPacketConn(outPacketConn))
  194. }
  195. func CopyEarlyConn(ctx context.Context, conn net.Conn, serverConn net.Conn) error {
  196. if cachedReader, isCached := conn.(N.CachedReader); isCached {
  197. payload := cachedReader.ReadCached()
  198. if payload != nil && !payload.IsEmpty() {
  199. _, err := serverConn.Write(payload.Bytes())
  200. payload.Release()
  201. if err != nil {
  202. serverConn.Close()
  203. return err
  204. }
  205. return bufio.CopyConn(ctx, conn, serverConn)
  206. }
  207. }
  208. if earlyConn, isEarlyConn := common.Cast[N.EarlyConn](serverConn); isEarlyConn && earlyConn.NeedHandshake() {
  209. payload := buf.NewPacket()
  210. err := conn.SetReadDeadline(time.Now().Add(C.ReadPayloadTimeout))
  211. if err != os.ErrInvalid {
  212. if err != nil {
  213. payload.Release()
  214. serverConn.Close()
  215. return err
  216. }
  217. _, err = payload.ReadOnceFrom(conn)
  218. if err != nil && !E.IsTimeout(err) {
  219. payload.Release()
  220. serverConn.Close()
  221. return E.Cause(err, "read payload")
  222. }
  223. err = conn.SetReadDeadline(time.Time{})
  224. if err != nil {
  225. payload.Release()
  226. serverConn.Close()
  227. return err
  228. }
  229. }
  230. _, err = serverConn.Write(payload.Bytes())
  231. payload.Release()
  232. if err != nil {
  233. serverConn.Close()
  234. return N.ReportHandshakeFailure(conn, err)
  235. }
  236. }
  237. return bufio.CopyConn(ctx, conn, serverConn)
  238. }