segment.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. package kcp
  2. import (
  3. "sync"
  4. "github.com/v2ray/v2ray-core/common"
  5. "github.com/v2ray/v2ray-core/common/alloc"
  6. _ "github.com/v2ray/v2ray-core/common/log"
  7. "github.com/v2ray/v2ray-core/common/serial"
  8. )
  9. var (
  10. dataSegmentPool = &sync.Pool{
  11. New: func() interface{} { return new(DataSegment) },
  12. }
  13. ackSegmentPool = &sync.Pool{
  14. New: func() interface{} { return new(AckSegment) },
  15. }
  16. cmdSegmentPool = &sync.Pool{
  17. New: func() interface{} { return new(CmdOnlySegment) },
  18. }
  19. )
  20. type SegmentCommand byte
  21. const (
  22. SegmentCommandACK SegmentCommand = 0
  23. SegmentCommandData SegmentCommand = 1
  24. SegmentCommandTerminated SegmentCommand = 2
  25. SegmentCommandPing SegmentCommand = 3
  26. )
  27. type SegmentOption byte
  28. const (
  29. SegmentOptionClose SegmentOption = 1
  30. )
  31. type Segment interface {
  32. common.Releasable
  33. ByteSize() int
  34. Bytes([]byte) []byte
  35. }
  36. const (
  37. DataSegmentOverhead = 18
  38. )
  39. type DataSegment struct {
  40. Conv uint16
  41. Opt SegmentOption
  42. Timestamp uint32
  43. Number uint32
  44. SendingNext uint32
  45. Data *alloc.Buffer
  46. timeout uint32
  47. ackSkipped uint32
  48. transmit uint32
  49. }
  50. func NewDataSegment() *DataSegment {
  51. return dataSegmentPool.Get().(*DataSegment)
  52. }
  53. func (this *DataSegment) Bytes(b []byte) []byte {
  54. b = serial.Uint16ToBytes(this.Conv, b)
  55. b = append(b, byte(SegmentCommandData), byte(this.Opt))
  56. b = serial.Uint32ToBytes(this.Timestamp, b)
  57. b = serial.Uint32ToBytes(this.Number, b)
  58. b = serial.Uint32ToBytes(this.SendingNext, b)
  59. b = serial.Uint16ToBytes(uint16(this.Data.Len()), b)
  60. b = append(b, this.Data.Value...)
  61. return b
  62. }
  63. func (this *DataSegment) ByteSize() int {
  64. return 2 + 1 + 1 + 4 + 4 + 4 + 2 + this.Data.Len()
  65. }
  66. func (this *DataSegment) Release() {
  67. this.Data.Release()
  68. this.Data = nil
  69. this.Opt = 0
  70. this.timeout = 0
  71. this.ackSkipped = 0
  72. this.transmit = 0
  73. dataSegmentPool.Put(this)
  74. }
  75. type AckSegment struct {
  76. Conv uint16
  77. Opt SegmentOption
  78. ReceivingWindow uint32
  79. ReceivingNext uint32
  80. Count byte
  81. NumberList []uint32
  82. TimestampList []uint32
  83. }
  84. func NewAckSegment() *AckSegment {
  85. seg := ackSegmentPool.Get().(*AckSegment)
  86. if seg.NumberList == nil {
  87. seg.NumberList = make([]uint32, 0, 128)
  88. }
  89. if seg.TimestampList == nil {
  90. seg.TimestampList = make([]uint32, 0, 128)
  91. }
  92. return seg
  93. }
  94. func (this *AckSegment) PutNumber(number uint32, timestamp uint32) {
  95. this.Count++
  96. this.NumberList = append(this.NumberList, number)
  97. this.TimestampList = append(this.TimestampList, timestamp)
  98. }
  99. func (this *AckSegment) IsFull() bool {
  100. return this.Count == 128
  101. }
  102. func (this *AckSegment) ByteSize() int {
  103. return 2 + 1 + 1 + 4 + 4 + 1 + int(this.Count)*4 + int(this.Count)*4
  104. }
  105. func (this *AckSegment) Bytes(b []byte) []byte {
  106. b = serial.Uint16ToBytes(this.Conv, b)
  107. b = append(b, byte(SegmentCommandACK), byte(this.Opt))
  108. b = serial.Uint32ToBytes(this.ReceivingWindow, b)
  109. b = serial.Uint32ToBytes(this.ReceivingNext, b)
  110. b = append(b, this.Count)
  111. for i := byte(0); i < this.Count; i++ {
  112. b = serial.Uint32ToBytes(this.NumberList[i], b)
  113. b = serial.Uint32ToBytes(this.TimestampList[i], b)
  114. }
  115. return b
  116. }
  117. func (this *AckSegment) Release() {
  118. this.Opt = 0
  119. this.Count = 0
  120. this.NumberList = this.NumberList[:0]
  121. this.TimestampList = this.TimestampList[:0]
  122. ackSegmentPool.Put(this)
  123. }
  124. type CmdOnlySegment struct {
  125. Conv uint16
  126. Cmd SegmentCommand
  127. Opt SegmentOption
  128. SendingNext uint32
  129. ReceivinNext uint32
  130. }
  131. func NewCmdOnlySegment() *CmdOnlySegment {
  132. return cmdSegmentPool.Get().(*CmdOnlySegment)
  133. }
  134. func (this *CmdOnlySegment) ByteSize() int {
  135. return 2 + 1 + 1 + 4 + 4
  136. }
  137. func (this *CmdOnlySegment) Bytes(b []byte) []byte {
  138. b = serial.Uint16ToBytes(this.Conv, b)
  139. b = append(b, byte(this.Cmd), byte(this.Opt))
  140. b = serial.Uint32ToBytes(this.SendingNext, b)
  141. b = serial.Uint32ToBytes(this.ReceivinNext, b)
  142. return b
  143. }
  144. func (this *CmdOnlySegment) Release() {
  145. this.Opt = 0
  146. cmdSegmentPool.Put(this)
  147. }
  148. func ReadSegment(buf []byte) (Segment, []byte) {
  149. if len(buf) <= 4 {
  150. return nil, nil
  151. }
  152. conv := serial.BytesToUint16(buf)
  153. buf = buf[2:]
  154. cmd := SegmentCommand(buf[0])
  155. opt := SegmentOption(buf[1])
  156. buf = buf[2:]
  157. if cmd == SegmentCommandData {
  158. seg := NewDataSegment()
  159. seg.Conv = conv
  160. seg.Opt = opt
  161. if len(buf) < 16 {
  162. return nil, nil
  163. }
  164. seg.Timestamp = serial.BytesToUint32(buf)
  165. buf = buf[4:]
  166. seg.Number = serial.BytesToUint32(buf)
  167. buf = buf[4:]
  168. seg.SendingNext = serial.BytesToUint32(buf)
  169. buf = buf[4:]
  170. dataLen := int(serial.BytesToUint16(buf))
  171. buf = buf[2:]
  172. if len(buf) < dataLen {
  173. return nil, nil
  174. }
  175. seg.Data = alloc.NewSmallBuffer().Clear().Append(buf[:dataLen])
  176. buf = buf[dataLen:]
  177. return seg, buf
  178. }
  179. if cmd == SegmentCommandACK {
  180. seg := NewAckSegment()
  181. seg.Conv = conv
  182. seg.Opt = opt
  183. if len(buf) < 9 {
  184. return nil, nil
  185. }
  186. seg.ReceivingWindow = serial.BytesToUint32(buf)
  187. buf = buf[4:]
  188. seg.ReceivingNext = serial.BytesToUint32(buf)
  189. buf = buf[4:]
  190. seg.Count = buf[0]
  191. buf = buf[1:]
  192. if len(buf) < int(seg.Count)*8 {
  193. return nil, nil
  194. }
  195. for i := 0; i < int(seg.Count); i++ {
  196. seg.NumberList = append(seg.NumberList, serial.BytesToUint32(buf))
  197. seg.TimestampList = append(seg.TimestampList, serial.BytesToUint32(buf[4:]))
  198. buf = buf[8:]
  199. }
  200. return seg, buf
  201. }
  202. seg := NewCmdOnlySegment()
  203. seg.Conv = conv
  204. seg.Cmd = cmd
  205. seg.Opt = opt
  206. if len(buf) < 8 {
  207. return nil, nil
  208. }
  209. seg.SendingNext = serial.BytesToUint32(buf)
  210. buf = buf[4:]
  211. seg.ReceivinNext = serial.BytesToUint32(buf)
  212. buf = buf[4:]
  213. return seg, buf
  214. }