shadowtls.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package inbound
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/binary"
  6. "io"
  7. "net"
  8. "os"
  9. "github.com/sagernet/sing-box/adapter"
  10. "github.com/sagernet/sing-box/common/dialer"
  11. C "github.com/sagernet/sing-box/constant"
  12. "github.com/sagernet/sing-box/log"
  13. "github.com/sagernet/sing-box/option"
  14. "github.com/sagernet/sing-box/transport/shadowtls"
  15. "github.com/sagernet/sing/common"
  16. "github.com/sagernet/sing/common/buf"
  17. "github.com/sagernet/sing/common/bufio"
  18. E "github.com/sagernet/sing/common/exceptions"
  19. M "github.com/sagernet/sing/common/metadata"
  20. N "github.com/sagernet/sing/common/network"
  21. "github.com/sagernet/sing/common/task"
  22. )
  23. type ShadowTLS struct {
  24. myInboundAdapter
  25. handshakeDialer N.Dialer
  26. handshakeAddr M.Socksaddr
  27. v2 bool
  28. password string
  29. fallbackAfter int
  30. }
  31. func NewShadowTLS(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowTLSInboundOptions) (*ShadowTLS, error) {
  32. inbound := &ShadowTLS{
  33. myInboundAdapter: myInboundAdapter{
  34. protocol: C.TypeShadowTLS,
  35. network: []string{N.NetworkTCP},
  36. ctx: ctx,
  37. router: router,
  38. logger: logger,
  39. tag: tag,
  40. listenOptions: options.ListenOptions,
  41. },
  42. handshakeDialer: dialer.New(router, options.Handshake.DialerOptions),
  43. handshakeAddr: options.Handshake.ServerOptions.Build(),
  44. password: options.Password,
  45. }
  46. switch options.Version {
  47. case 0:
  48. fallthrough
  49. case 1:
  50. case 2:
  51. inbound.v2 = true
  52. if options.FallbackAfter == nil {
  53. inbound.fallbackAfter = 2
  54. } else {
  55. inbound.fallbackAfter = *options.FallbackAfter
  56. }
  57. default:
  58. return nil, E.New("unknown shadowtls protocol version: ", options.Version)
  59. }
  60. inbound.connHandler = inbound
  61. return inbound, nil
  62. }
  63. func (s *ShadowTLS) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
  64. handshakeConn, err := s.handshakeDialer.DialContext(ctx, N.NetworkTCP, s.handshakeAddr)
  65. if err != nil {
  66. return err
  67. }
  68. if !s.v2 {
  69. var handshake task.Group
  70. handshake.Append("client handshake", func(ctx context.Context) error {
  71. return s.copyUntilHandshakeFinished(handshakeConn, conn)
  72. })
  73. handshake.Append("server handshake", func(ctx context.Context) error {
  74. return s.copyUntilHandshakeFinished(conn, handshakeConn)
  75. })
  76. handshake.FastFail()
  77. handshake.Cleanup(func() {
  78. handshakeConn.Close()
  79. })
  80. err = handshake.Run(ctx)
  81. if err != nil {
  82. return err
  83. }
  84. return s.newConnection(ctx, conn, metadata)
  85. } else {
  86. hashConn := shadowtls.NewHashWriteConn(conn, s.password)
  87. go bufio.Copy(hashConn, handshakeConn)
  88. var request *buf.Buffer
  89. request, err = s.copyUntilHandshakeFinishedV2(ctx, handshakeConn, conn, hashConn, s.fallbackAfter)
  90. if err == nil {
  91. handshakeConn.Close()
  92. return s.newConnection(ctx, bufio.NewCachedConn(shadowtls.NewConn(conn), request), metadata)
  93. } else if err == os.ErrPermission {
  94. s.logger.WarnContext(ctx, "fallback connection")
  95. hashConn.Fallback()
  96. return common.Error(bufio.Copy(handshakeConn, conn))
  97. } else {
  98. return err
  99. }
  100. }
  101. }
  102. func (s *ShadowTLS) copyUntilHandshakeFinished(dst io.Writer, src io.Reader) error {
  103. const handshake = 0x16
  104. const changeCipherSpec = 0x14
  105. var hasSeenChangeCipherSpec bool
  106. var tlsHdr [5]byte
  107. for {
  108. _, err := io.ReadFull(src, tlsHdr[:])
  109. if err != nil {
  110. return err
  111. }
  112. length := binary.BigEndian.Uint16(tlsHdr[3:])
  113. _, err = io.Copy(dst, io.MultiReader(bytes.NewReader(tlsHdr[:]), io.LimitReader(src, int64(length))))
  114. if err != nil {
  115. return err
  116. }
  117. if tlsHdr[0] != handshake {
  118. if tlsHdr[0] != changeCipherSpec {
  119. return E.New("unexpected tls frame type: ", tlsHdr[0])
  120. }
  121. if !hasSeenChangeCipherSpec {
  122. hasSeenChangeCipherSpec = true
  123. continue
  124. }
  125. }
  126. if hasSeenChangeCipherSpec {
  127. return nil
  128. }
  129. }
  130. }
  131. func (s *ShadowTLS) copyUntilHandshakeFinishedV2(ctx context.Context, dst net.Conn, src io.Reader, hash *shadowtls.HashWriteConn, fallbackAfter int) (*buf.Buffer, error) {
  132. const applicationData = 0x17
  133. var tlsHdr [5]byte
  134. var applicationDataCount int
  135. for {
  136. _, err := io.ReadFull(src, tlsHdr[:])
  137. if err != nil {
  138. return nil, err
  139. }
  140. length := binary.BigEndian.Uint16(tlsHdr[3:])
  141. if tlsHdr[0] == applicationData {
  142. data := buf.NewSize(int(length))
  143. _, err = data.ReadFullFrom(src, int(length))
  144. if err != nil {
  145. data.Release()
  146. return nil, err
  147. }
  148. if hash.HasContent() && length >= 8 {
  149. checksum := hash.Sum()
  150. if bytes.Equal(data.To(8), checksum) {
  151. s.logger.TraceContext(ctx, "match current hashcode")
  152. data.Advance(8)
  153. return data, nil
  154. } else if hash.LastSum() != nil && bytes.Equal(data.To(8), hash.LastSum()) {
  155. s.logger.TraceContext(ctx, "match last hashcode")
  156. data.Advance(8)
  157. return data, nil
  158. }
  159. }
  160. _, err = io.Copy(dst, io.MultiReader(bytes.NewReader(tlsHdr[:]), data))
  161. data.Release()
  162. applicationDataCount++
  163. } else {
  164. _, err = io.Copy(dst, io.MultiReader(bytes.NewReader(tlsHdr[:]), io.LimitReader(src, int64(length))))
  165. }
  166. if err != nil {
  167. return nil, err
  168. }
  169. if applicationDataCount > fallbackAfter {
  170. return nil, os.ErrPermission
  171. }
  172. }
  173. }