segment.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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 SegmentCommand byte
  9. const (
  10. SegmentCommandACK SegmentCommand = 0
  11. SegmentCommandData SegmentCommand = 1
  12. SegmentCommandTerminated SegmentCommand = 2
  13. SegmentCommandPing SegmentCommand = 3
  14. )
  15. type SegmentOption byte
  16. const (
  17. SegmentOptionClose SegmentOption = 1
  18. )
  19. type ISegment 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. Opt 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 (this *DataSegment) Bytes(b []byte) []byte {
  39. b = serial.Uint16ToBytes(this.Conv, b)
  40. b = append(b, byte(SegmentCommandData), byte(this.Opt))
  41. b = serial.Uint32ToBytes(this.Timestamp, b)
  42. b = serial.Uint32ToBytes(this.Number, b)
  43. b = serial.Uint32ToBytes(this.SendingNext, b)
  44. b = serial.Uint16ToBytes(uint16(this.Data.Len()), b)
  45. b = append(b, this.Data.Value...)
  46. return b
  47. }
  48. func (this *DataSegment) ByteSize() int {
  49. return 2 + 1 + 1 + 4 + 4 + 4 + 2 + this.Data.Len()
  50. }
  51. func (this *DataSegment) Release() {
  52. this.Data.Release()
  53. }
  54. type ACKSegment struct {
  55. Conv uint16
  56. Opt SegmentOption
  57. ReceivingWindow uint32
  58. ReceivingNext uint32
  59. Count byte
  60. NumberList []uint32
  61. TimestampList []uint32
  62. }
  63. func (this *ACKSegment) ByteSize() int {
  64. return 2 + 1 + 1 + 4 + 4 + 1 + int(this.Count)*4 + int(this.Count)*4
  65. }
  66. func (this *ACKSegment) Bytes(b []byte) []byte {
  67. b = serial.Uint16ToBytes(this.Conv, b)
  68. b = append(b, byte(SegmentCommandACK), byte(this.Opt))
  69. b = serial.Uint32ToBytes(this.ReceivingWindow, b)
  70. b = serial.Uint32ToBytes(this.ReceivingNext, b)
  71. b = append(b, this.Count)
  72. for i := byte(0); i < this.Count; i++ {
  73. b = serial.Uint32ToBytes(this.NumberList[i], b)
  74. b = serial.Uint32ToBytes(this.TimestampList[i], b)
  75. }
  76. return b
  77. }
  78. func (this *ACKSegment) Release() {}
  79. type CmdOnlySegment struct {
  80. Conv uint16
  81. Cmd SegmentCommand
  82. Opt SegmentOption
  83. SendingNext uint32
  84. ReceivinNext uint32
  85. }
  86. func (this *CmdOnlySegment) ByteSize() int {
  87. return 2 + 1 + 1 + 4 + 4
  88. }
  89. func (this *CmdOnlySegment) Bytes(b []byte) []byte {
  90. b = serial.Uint16ToBytes(this.Conv, b)
  91. b = append(b, byte(this.Cmd), byte(this.Opt))
  92. b = serial.Uint32ToBytes(this.SendingNext, b)
  93. b = serial.Uint32ToBytes(this.ReceivinNext, b)
  94. return b
  95. }
  96. func (this *CmdOnlySegment) Release() {}
  97. func ReadSegment(buf []byte) (ISegment, []byte) {
  98. if len(buf) <= 6 {
  99. return nil, nil
  100. }
  101. conv := serial.BytesToUint16(buf)
  102. buf = buf[2:]
  103. cmd := SegmentCommand(buf[0])
  104. opt := SegmentOption(buf[1])
  105. buf = buf[2:]
  106. if cmd == SegmentCommandData {
  107. seg := &DataSegment{
  108. Conv: conv,
  109. Opt: opt,
  110. }
  111. seg.Timestamp = serial.BytesToUint32(buf)
  112. buf = buf[4:]
  113. seg.Number = serial.BytesToUint32(buf)
  114. buf = buf[4:]
  115. seg.SendingNext = serial.BytesToUint32(buf)
  116. buf = buf[4:]
  117. len := serial.BytesToUint16(buf)
  118. buf = buf[2:]
  119. seg.Data = alloc.NewSmallBuffer().Clear().Append(buf[:len])
  120. buf = buf[len:]
  121. return seg, buf
  122. }
  123. if cmd == SegmentCommandACK {
  124. seg := &ACKSegment{
  125. Conv: conv,
  126. Opt: opt,
  127. }
  128. seg.ReceivingWindow = serial.BytesToUint32(buf)
  129. buf = buf[4:]
  130. seg.ReceivingNext = serial.BytesToUint32(buf)
  131. buf = buf[4:]
  132. seg.Count = buf[0]
  133. buf = buf[1:]
  134. seg.NumberList = make([]uint32, 0, seg.Count)
  135. seg.TimestampList = make([]uint32, 0, seg.Count)
  136. for i := 0; i < int(seg.Count); i++ {
  137. seg.NumberList = append(seg.NumberList, serial.BytesToUint32(buf))
  138. seg.TimestampList = append(seg.TimestampList, serial.BytesToUint32(buf[4:]))
  139. buf = buf[8:]
  140. }
  141. return seg, buf
  142. }
  143. seg := &CmdOnlySegment{
  144. Conv: conv,
  145. Cmd: cmd,
  146. Opt: opt,
  147. }
  148. seg.SendingNext = serial.BytesToUint32(buf)
  149. buf = buf[4:]
  150. seg.ReceivinNext = serial.BytesToUint32(buf)
  151. buf = buf[4:]
  152. return seg, buf
  153. }