segment.go 4.7 KB

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