shadowsocks.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. // R.I.P Shadowsocks
  2. package shadowsocks
  3. import (
  4. "crypto/rand"
  5. "sync"
  6. "github.com/v2ray/v2ray-core/app"
  7. "github.com/v2ray/v2ray-core/common/alloc"
  8. "github.com/v2ray/v2ray-core/common/log"
  9. v2net "github.com/v2ray/v2ray-core/common/net"
  10. "github.com/v2ray/v2ray-core/proxy"
  11. "github.com/v2ray/v2ray-core/proxy/internal"
  12. "github.com/v2ray/v2ray-core/transport/hub"
  13. )
  14. type Shadowsocks struct {
  15. space app.Space
  16. config *Config
  17. port v2net.Port
  18. accepting bool
  19. tcpHub *hub.TCPHub
  20. udpHub *hub.UDPHub
  21. }
  22. func (this *Shadowsocks) Port() v2net.Port {
  23. return this.port
  24. }
  25. func (this *Shadowsocks) Close() {
  26. this.accepting = false
  27. this.tcpHub.Close()
  28. this.tcpHub = nil
  29. }
  30. func (this *Shadowsocks) Listen(port v2net.Port) error {
  31. if this.accepting {
  32. if this.port == port {
  33. return nil
  34. } else {
  35. return proxy.ErrorAlreadyListening
  36. }
  37. }
  38. this.accepting = true
  39. tcpHub, err := hub.ListenTCP(port, this.handleConnection)
  40. if err != nil {
  41. log.Error("Shadowsocks: Failed to listen TCP on port ", port, ": ", err)
  42. return err
  43. }
  44. this.tcpHub = tcpHub
  45. if this.config.UDP {
  46. udpHub, err := hub.ListenUDP(port, this.handlerUDPPayload)
  47. if err != nil {
  48. log.Error("Shadowsocks: Failed to listen UDP on port ", port, ": ", err)
  49. }
  50. this.udpHub = udpHub
  51. }
  52. return nil
  53. }
  54. func (this *Shadowsocks) handlerUDPPayload(payload *alloc.Buffer, dest v2net.Destination) {
  55. defer payload.Release()
  56. iv := payload.Value[:this.config.Cipher.IVSize()]
  57. key := this.config.Key
  58. payload.SliceFrom(this.config.Cipher.IVSize())
  59. reader, err := this.config.Cipher.NewDecodingStream(key, iv, payload)
  60. if err != nil {
  61. log.Error("Shadowsocks: Failed to create decoding stream: ", err)
  62. return
  63. }
  64. request, err := ReadRequest(reader)
  65. if err != nil {
  66. return
  67. }
  68. buffer, _ := v2net.ReadFrom(reader, nil)
  69. packet := v2net.NewPacket(v2net.TCPDestination(request.Address, request.Port), buffer, false)
  70. ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
  71. close(ray.InboundInput())
  72. for respChunk := range ray.InboundOutput() {
  73. response := alloc.NewBuffer().Slice(0, this.config.Cipher.IVSize())
  74. rand.Read(response.Value)
  75. writer, err := this.config.Cipher.NewEncodingStream(key, response.Value, response)
  76. if err != nil {
  77. log.Error("Shadowsocks: Failed to create encoding stream: ", err)
  78. return
  79. }
  80. switch {
  81. case request.Address.IsIPv4():
  82. writer.Write([]byte{AddrTypeIPv4})
  83. writer.Write(request.Address.IP())
  84. case request.Address.IsIPv6():
  85. writer.Write([]byte{AddrTypeIPv6})
  86. writer.Write(request.Address.IP())
  87. case request.Address.IsDomain():
  88. writer.Write([]byte{AddrTypeDomain, byte(len(request.Address.Domain()))})
  89. writer.Write([]byte(request.Address.Domain()))
  90. }
  91. writer.Write(request.Port.Bytes())
  92. writer.Write(respChunk.Value)
  93. respChunk.Release()
  94. this.udpHub.WriteTo(response.Value, dest)
  95. response.Release()
  96. }
  97. }
  98. func (this *Shadowsocks) handleConnection(conn *hub.TCPConn) {
  99. defer conn.Close()
  100. buffer := alloc.NewSmallBuffer()
  101. defer buffer.Release()
  102. _, err := v2net.ReadAllBytes(conn, buffer.Value[:this.config.Cipher.IVSize()])
  103. if err != nil {
  104. log.Error("Shadowsocks: Failed to read IV: ", err)
  105. return
  106. }
  107. iv := buffer.Value[:this.config.Cipher.IVSize()]
  108. key := this.config.Key
  109. reader, err := this.config.Cipher.NewDecodingStream(key, iv, conn)
  110. if err != nil {
  111. log.Error("Shadowsocks: Failed to create decoding stream: ", err)
  112. return
  113. }
  114. request, err := ReadRequest(reader)
  115. if err != nil {
  116. return
  117. }
  118. packet := v2net.NewPacket(v2net.TCPDestination(request.Address, request.Port), nil, true)
  119. ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
  120. var writeFinish sync.Mutex
  121. writeFinish.Lock()
  122. go func() {
  123. firstChunk := alloc.NewBuffer().Slice(0, this.config.Cipher.IVSize())
  124. defer firstChunk.Release()
  125. writer, err := this.config.Cipher.NewEncodingStream(key, firstChunk.Value, conn)
  126. if err != nil {
  127. log.Error("Shadowsocks: Failed to create encoding stream: ", err)
  128. return
  129. }
  130. if payload, ok := <-ray.InboundOutput(); ok {
  131. firstChunk.Append(payload.Value)
  132. payload.Release()
  133. writer.Write(firstChunk.Value)
  134. v2net.ChanToWriter(writer, ray.InboundOutput())
  135. }
  136. writeFinish.Unlock()
  137. }()
  138. v2net.ReaderToChan(ray.InboundInput(), reader)
  139. close(ray.InboundInput())
  140. writeFinish.Lock()
  141. }
  142. func init() {
  143. internal.MustRegisterInboundHandlerCreator("shadowsocks",
  144. func(space app.Space, rawConfig interface{}) (proxy.InboundHandler, error) {
  145. config := rawConfig.(*Config)
  146. return &Shadowsocks{
  147. space: space,
  148. config: config,
  149. }, nil
  150. })
  151. }