vmessout.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. package vmess
  2. import (
  3. "crypto/md5"
  4. "crypto/rand"
  5. "io"
  6. mrand "math/rand"
  7. "net"
  8. "github.com/v2ray/v2ray-core"
  9. v2io "github.com/v2ray/v2ray-core/io"
  10. vmessio "github.com/v2ray/v2ray-core/io/vmess"
  11. v2net "github.com/v2ray/v2ray-core/net"
  12. )
  13. type VMessOutboundHandler struct {
  14. vPoint *core.VPoint
  15. dest v2net.VAddress
  16. }
  17. func NewVMessOutboundHandler(vp *core.VPoint, dest v2net.VAddress) *VMessOutboundHandler {
  18. handler := new(VMessOutboundHandler)
  19. handler.vPoint = vp
  20. handler.dest = dest
  21. return handler
  22. }
  23. func (handler *VMessOutboundHandler) pickVNext() (v2net.VAddress, core.VUser) {
  24. vNextLen := len(handler.vPoint.Config.VNextList)
  25. if vNextLen == 0 {
  26. panic("Zero vNext is configured.")
  27. }
  28. vNextIndex := mrand.Intn(vNextLen)
  29. vNext := handler.vPoint.Config.VNextList[vNextIndex]
  30. vNextUserLen := len(vNext.Users)
  31. if vNextUserLen == 0 {
  32. panic("Zero User account.")
  33. }
  34. vNextUserIndex := mrand.Intn(vNextUserLen)
  35. vNextUser := vNext.Users[vNextUserIndex]
  36. return vNext.Address, vNextUser
  37. }
  38. func (handler *VMessOutboundHandler) Start(ray core.OutboundVRay) error {
  39. vNextAddress, vNextUser := handler.pickVNext()
  40. request := new(vmessio.VMessRequest)
  41. request.Version = vmessio.Version
  42. request.UserId = vNextUser.Id
  43. rand.Read(request.RequestIV[:])
  44. rand.Read(request.RequestKey[:])
  45. rand.Read(request.ResponseHeader[:])
  46. request.Command = byte(0x01)
  47. request.Address = handler.dest
  48. conn, err := net.Dial("tcp", vNextAddress.String())
  49. if err != nil {
  50. return err
  51. }
  52. defer conn.Close()
  53. requestWriter := vmessio.NewVMessRequestWriter()
  54. requestWriter.Write(conn, request)
  55. requestKey := request.RequestKey[:]
  56. requestIV := request.RequestIV[:]
  57. responseKey := md5.Sum(requestKey)
  58. responseIV := md5.Sum(requestIV)
  59. encryptRequestWriter, err := v2io.NewAesEncryptWriter(requestKey, requestIV, conn)
  60. if err != nil {
  61. return err
  62. }
  63. responseReader, err := v2io.NewAesDecryptReader(responseKey[:], responseIV[:], conn)
  64. if err != nil {
  65. return err
  66. }
  67. input := ray.OutboundInput()
  68. output := ray.OutboundOutput()
  69. finish := make(chan bool, 2)
  70. go handler.dumpInput(encryptRequestWriter, input, finish)
  71. go handler.dumpOutput(responseReader, output, finish)
  72. handler.waitForFinish(finish)
  73. return nil
  74. }
  75. func (handler *VMessOutboundHandler) dumpOutput(reader io.Reader, output chan<- []byte, finish chan<- bool) {
  76. for {
  77. buffer := make([]byte, BufferSize)
  78. nBytes, err := reader.Read(buffer)
  79. if err == io.EOF {
  80. finish <- true
  81. break
  82. }
  83. output <- buffer[:nBytes]
  84. }
  85. }
  86. func (handler *VMessOutboundHandler) dumpInput(writer io.Writer, input <-chan []byte, finish chan<- bool) {
  87. for {
  88. buffer, open := <-input
  89. if !open {
  90. finish <- true
  91. break
  92. }
  93. writer.Write(buffer)
  94. }
  95. }
  96. func (handler *VMessOutboundHandler) waitForFinish(finish <-chan bool) {
  97. for i := 0; i < 2; i++ {
  98. <-finish
  99. }
  100. }
  101. type VMessOutboundHandlerFactory struct {
  102. }
  103. func (factory *VMessOutboundHandlerFactory) Create(vp *core.VPoint, destination v2net.VAddress) *VMessOutboundHandler {
  104. return NewVMessOutboundHandler(vp, destination)
  105. }