shadowtls.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package inbound
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/binary"
  6. "io"
  7. "net"
  8. "github.com/sagernet/sing-box/adapter"
  9. "github.com/sagernet/sing-box/common/dialer"
  10. C "github.com/sagernet/sing-box/constant"
  11. "github.com/sagernet/sing-box/log"
  12. "github.com/sagernet/sing-box/option"
  13. E "github.com/sagernet/sing/common/exceptions"
  14. M "github.com/sagernet/sing/common/metadata"
  15. N "github.com/sagernet/sing/common/network"
  16. "github.com/sagernet/sing/common/task"
  17. )
  18. type ShadowTLS struct {
  19. myInboundAdapter
  20. handshakeDialer N.Dialer
  21. handshakeAddr M.Socksaddr
  22. }
  23. func NewShadowTLS(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowTLSInboundOptions) (*ShadowTLS, error) {
  24. inbound := &ShadowTLS{
  25. myInboundAdapter: myInboundAdapter{
  26. protocol: C.TypeShadowTLS,
  27. network: []string{N.NetworkTCP},
  28. ctx: ctx,
  29. router: router,
  30. logger: logger,
  31. tag: tag,
  32. listenOptions: options.ListenOptions,
  33. },
  34. handshakeDialer: dialer.New(router, options.Handshake.DialerOptions),
  35. handshakeAddr: options.Handshake.ServerOptions.Build(),
  36. }
  37. inbound.connHandler = inbound
  38. return inbound, nil
  39. }
  40. func (s *ShadowTLS) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
  41. handshakeConn, err := s.handshakeDialer.DialContext(ctx, N.NetworkTCP, s.handshakeAddr)
  42. if err != nil {
  43. return err
  44. }
  45. var handshake task.Group
  46. handshake.Append("client handshake", func(ctx context.Context) error {
  47. return s.copyUntilHandshakeFinished(handshakeConn, conn)
  48. })
  49. handshake.Append("server handshake", func(ctx context.Context) error {
  50. return s.copyUntilHandshakeFinished(conn, handshakeConn)
  51. })
  52. handshake.FastFail()
  53. err = handshake.Run(ctx)
  54. if err != nil {
  55. return err
  56. }
  57. return s.newConnection(ctx, conn, metadata)
  58. }
  59. func (s *ShadowTLS) copyUntilHandshakeFinished(dst io.Writer, src io.Reader) error {
  60. const handshake = 0x16
  61. const changeCipherSpec = 0x14
  62. var hasSeenChangeCipherSpec bool
  63. var tlsHdr [5]byte
  64. for {
  65. _, err := io.ReadFull(src, tlsHdr[:])
  66. if err != nil {
  67. return err
  68. }
  69. length := binary.BigEndian.Uint16(tlsHdr[3:])
  70. _, err = io.Copy(dst, io.MultiReader(bytes.NewReader(tlsHdr[:]), io.LimitReader(src, int64(length))))
  71. if err != nil {
  72. return err
  73. }
  74. if tlsHdr[0] != handshake {
  75. if tlsHdr[0] != changeCipherSpec {
  76. return E.New("unexpected tls frame type: ", tlsHdr[0])
  77. }
  78. if !hasSeenChangeCipherSpec {
  79. hasSeenChangeCipherSpec = true
  80. continue
  81. }
  82. }
  83. if hasSeenChangeCipherSpec {
  84. return nil
  85. }
  86. }
  87. }