protocol.go 4.6 KB

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