shadowsocks.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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. tcpListener *hub.TCPHub
  20. }
  21. func (this *Shadowsocks) Port() v2net.Port {
  22. return this.port
  23. }
  24. func (this *Shadowsocks) Close() {
  25. this.accepting = false
  26. this.tcpListener.Close()
  27. this.tcpListener = nil
  28. }
  29. func (this *Shadowsocks) Listen(port v2net.Port) error {
  30. if this.accepting {
  31. if this.port == port {
  32. return nil
  33. } else {
  34. return proxy.ErrorAlreadyListening
  35. }
  36. }
  37. tcpListener, err := hub.ListenTCP(port, this.handleConnection)
  38. if err != nil {
  39. log.Error("Shadowsocks: Failed to listen on port ", port, ": ", err)
  40. return err
  41. }
  42. this.tcpListener = tcpListener
  43. this.accepting = true
  44. return nil
  45. }
  46. func (this *Shadowsocks) handleConnection(conn *hub.TCPConn) {
  47. defer conn.Close()
  48. buffer := alloc.NewSmallBuffer()
  49. defer buffer.Release()
  50. _, err := v2net.ReadAllBytes(conn, buffer.Value[:this.config.Cipher.IVSize()])
  51. if err != nil {
  52. log.Error("Shadowsocks: Failed to read IV: ", err)
  53. return
  54. }
  55. iv := buffer.Value[:this.config.Cipher.IVSize()]
  56. key := this.config.Key
  57. reader, err := this.config.Cipher.NewDecodingStream(key, iv, conn)
  58. if err != nil {
  59. log.Error("Shadowsocks: Failed to create decoding stream: ", err)
  60. return
  61. }
  62. request, err := ReadRequest(reader)
  63. if err != nil {
  64. return
  65. }
  66. packet := v2net.NewPacket(v2net.TCPDestination(request.Address, request.Port), nil, true)
  67. ray := this.space.PacketDispatcher().DispatchToOutbound(packet)
  68. respIv := make([]byte, this.config.Cipher.IVSize())
  69. rand.Read(respIv)
  70. writer, err := this.config.Cipher.NewEncodingStream(key, respIv, conn)
  71. if err != nil {
  72. log.Error("Shadowsocks: Failed to create encoding stream: ", err)
  73. return
  74. }
  75. var writeFinish sync.Mutex
  76. writeFinish.Lock()
  77. go func() {
  78. firstChunk := alloc.NewBuffer().Clear()
  79. defer firstChunk.Release()
  80. firstChunk.Append(respIv)
  81. if payload, ok := <-ray.InboundOutput(); ok {
  82. firstChunk.Append(payload.Value)
  83. payload.Release()
  84. writer.Write(firstChunk.Value)
  85. v2net.ChanToWriter(writer, ray.InboundOutput())
  86. }
  87. writeFinish.Unlock()
  88. }()
  89. v2net.ReaderToChan(ray.InboundInput(), reader)
  90. close(ray.InboundInput())
  91. writeFinish.Lock()
  92. }
  93. func init() {
  94. internal.MustRegisterInboundHandlerCreator("shadowsocks",
  95. func(space app.Space, rawConfig interface{}) (proxy.InboundHandler, error) {
  96. config := rawConfig.(*Config)
  97. return &Shadowsocks{
  98. space: space,
  99. config: config,
  100. }, nil
  101. })
  102. }