protocol.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. package hysteria2
  2. import (
  3. "io"
  4. "math/rand"
  5. "github.com/apernet/quic-go/quicvarint"
  6. hyProtocol "github.com/v2fly/hysteria/core/v2/international/protocol"
  7. "github.com/v2fly/v2ray-core/v5/common/buf"
  8. "github.com/v2fly/v2ray-core/v5/common/net"
  9. hyTransport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2"
  10. )
  11. const (
  12. paddingChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  13. )
  14. // ConnWriter is TCP Connection Writer Wrapper
  15. type ConnWriter struct {
  16. io.Writer
  17. Target net.Destination
  18. TCPHeaderSent bool
  19. }
  20. // Write implements io.Writer
  21. func (c *ConnWriter) Write(p []byte) (n int, err error) {
  22. if !c.TCPHeaderSent {
  23. if err := c.writeTCPHeader(); err != nil {
  24. return 0, newError("failed to write request header").Base(err)
  25. }
  26. }
  27. return c.Writer.Write(p)
  28. }
  29. // WriteMultiBuffer implements buf.Writer
  30. func (c *ConnWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
  31. defer buf.ReleaseMulti(mb)
  32. for _, b := range mb {
  33. if !b.IsEmpty() {
  34. if _, err := c.Write(b.Bytes()); err != nil {
  35. return err
  36. }
  37. }
  38. }
  39. return nil
  40. }
  41. func (c *ConnWriter) WriteTCPHeader() error {
  42. if !c.TCPHeaderSent {
  43. if err := c.writeTCPHeader(); err != nil {
  44. return err
  45. }
  46. }
  47. return nil
  48. }
  49. func QuicLen(s int) int {
  50. return quicvarint.Len(uint64(s))
  51. }
  52. func (c *ConnWriter) writeTCPHeader() error {
  53. c.TCPHeaderSent = true
  54. paddingLen := 64 + rand.Intn(512-64)
  55. padding := make([]byte, paddingLen)
  56. for i := range padding {
  57. padding[i] = paddingChars[rand.Intn(len(paddingChars))]
  58. }
  59. addressAndPort := c.Target.NetAddr()
  60. addressLen := len(addressAndPort)
  61. if addressLen > hyProtocol.MaxAddressLength {
  62. return newError("address length too large: ", addressLen)
  63. }
  64. size := QuicLen(addressLen) + addressLen + QuicLen(paddingLen) + paddingLen
  65. buf := make([]byte, size)
  66. i := hyProtocol.VarintPut(buf, uint64(addressLen))
  67. i += copy(buf[i:], addressAndPort)
  68. i += hyProtocol.VarintPut(buf[i:], uint64(paddingLen))
  69. copy(buf[i:], padding)
  70. _, err := c.Writer.Write(buf)
  71. return err
  72. }
  73. // PacketWriter UDP Connection Writer Wrapper
  74. type PacketWriter struct {
  75. io.Writer
  76. HyConn *hyTransport.HyConn
  77. Target net.Destination
  78. }
  79. // WriteMultiBuffer implements buf.Writer
  80. func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
  81. for _, b := range mb {
  82. if b.IsEmpty() {
  83. continue
  84. }
  85. if _, err := w.writePacket(b.Bytes(), w.Target); err != nil {
  86. buf.ReleaseMulti(mb)
  87. return err
  88. }
  89. }
  90. return nil
  91. }
  92. // WriteMultiBufferWithMetadata writes udp packet with destination specified
  93. func (w *PacketWriter) WriteMultiBufferWithMetadata(mb buf.MultiBuffer, dest net.Destination) error {
  94. for _, b := range mb {
  95. if b.IsEmpty() {
  96. continue
  97. }
  98. if _, err := w.writePacket(b.Bytes(), dest); err != nil {
  99. buf.ReleaseMulti(mb)
  100. return err
  101. }
  102. }
  103. return nil
  104. }
  105. func (w *PacketWriter) WriteTo(payload []byte, addr net.Addr) (int, error) {
  106. dest := net.DestinationFromAddr(addr)
  107. return w.writePacket(payload, dest)
  108. }
  109. func (w *PacketWriter) writePacket(payload []byte, dest net.Destination) (int, error) {
  110. return w.HyConn.WritePacket(payload, dest)
  111. }
  112. // ConnReader is TCP Connection Reader Wrapper
  113. type ConnReader struct {
  114. io.Reader
  115. Target net.Destination
  116. }
  117. // Read implements io.Reader
  118. func (c *ConnReader) Read(p []byte) (int, error) {
  119. return c.Reader.Read(p)
  120. }
  121. // ReadMultiBuffer implements buf.Reader
  122. func (c *ConnReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
  123. b := buf.New()
  124. _, err := b.ReadFrom(c)
  125. if err != nil {
  126. return nil, err
  127. }
  128. return buf.MultiBuffer{b}, nil
  129. }
  130. // PacketPayload combines udp payload and destination
  131. type PacketPayload struct {
  132. Target net.Destination
  133. Buffer buf.MultiBuffer
  134. }
  135. // PacketReader is UDP Connection Reader Wrapper
  136. type PacketReader struct {
  137. io.Reader
  138. HyConn *hyTransport.HyConn
  139. }
  140. // ReadMultiBuffer implements buf.Reader
  141. func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
  142. p, err := r.ReadMultiBufferWithMetadata()
  143. if p != nil {
  144. return p.Buffer, err
  145. }
  146. return nil, err
  147. }
  148. // ReadMultiBufferWithMetadata reads udp packet with destination
  149. func (r *PacketReader) ReadMultiBufferWithMetadata() (*PacketPayload, error) {
  150. _, data, dest, err := r.HyConn.ReadPacket()
  151. if err != nil {
  152. return nil, err
  153. }
  154. b := buf.FromBytes(data)
  155. return &PacketPayload{Target: *dest, Buffer: buf.MultiBuffer{b}}, nil
  156. }
  157. type PacketConnectionReader struct {
  158. reader *PacketReader
  159. payload *PacketPayload
  160. }
  161. func (r *PacketConnectionReader) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
  162. if r.payload == nil || r.payload.Buffer.IsEmpty() {
  163. r.payload, err = r.reader.ReadMultiBufferWithMetadata()
  164. if err != nil {
  165. return
  166. }
  167. }
  168. addr = &net.UDPAddr{
  169. IP: r.payload.Target.Address.IP(),
  170. Port: int(r.payload.Target.Port),
  171. }
  172. r.payload.Buffer, n = buf.SplitFirstBytes(r.payload.Buffer, p)
  173. return
  174. }