segment.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. package kcp
  2. import (
  3. "github.com/v2ray/v2ray-core/common/alloc"
  4. "github.com/v2ray/v2ray-core/common/serial"
  5. )
  6. type SegmentCommand byte
  7. const (
  8. SegmentCommandACK SegmentCommand = 0
  9. SegmentCommandData SegmentCommand = 1
  10. SegmentCommandTerminated SegmentCommand = 2
  11. )
  12. type SegmentOption byte
  13. const (
  14. SegmentOptionClose SegmentOption = 1
  15. )
  16. type ISegment interface {
  17. ByteSize() int
  18. Bytes([]byte) []byte
  19. }
  20. type DataSegment struct {
  21. Conv uint16
  22. Opt SegmentOption
  23. ReceivingWindow uint32
  24. Timestamp uint32
  25. Number uint32
  26. Unacknowledged uint32
  27. Data *alloc.Buffer
  28. timeout uint32
  29. ackSkipped uint32
  30. transmit uint32
  31. }
  32. func (this *DataSegment) Bytes(b []byte) []byte {
  33. b = serial.Uint16ToBytes(this.Conv, b)
  34. b = append(b, byte(SegmentCommandData), byte(this.Opt))
  35. b = serial.Uint32ToBytes(this.ReceivingWindow, b)
  36. b = serial.Uint32ToBytes(this.Timestamp, b)
  37. b = serial.Uint32ToBytes(this.Number, b)
  38. b = serial.Uint32ToBytes(this.Unacknowledged, b)
  39. b = serial.Uint16ToBytes(uint16(this.Data.Len()), b)
  40. b = append(b, this.Data.Value...)
  41. return b
  42. }
  43. func (this *DataSegment) ByteSize() int {
  44. return 2 + 1 + 1 + 4 + 4 + 4 + 4 + 2 + this.Data.Len()
  45. }
  46. type ACKSegment struct {
  47. Conv uint16
  48. Opt SegmentOption
  49. ReceivingWindow uint32
  50. Unacknowledged uint32
  51. Count byte
  52. NumberList []uint32
  53. TimestampList []uint32
  54. }
  55. func (this *ACKSegment) ByteSize() int {
  56. return 2 + 1 + 1 + 4 + 4 + 1 + len(this.NumberList)*4 + len(this.TimestampList)*4
  57. }
  58. func (this *ACKSegment) Bytes(b []byte) []byte {
  59. b = serial.Uint16ToBytes(this.Conv, b)
  60. b = append(b, byte(SegmentCommandACK), byte(this.Opt))
  61. b = serial.Uint32ToBytes(this.ReceivingWindow, b)
  62. b = serial.Uint32ToBytes(this.Unacknowledged, b)
  63. b = append(b, this.Count)
  64. for i := byte(0); i < this.Count; i++ {
  65. b = serial.Uint32ToBytes(this.NumberList[i], b)
  66. b = serial.Uint32ToBytes(this.TimestampList[i], b)
  67. }
  68. return b
  69. }
  70. type TerminationSegment struct {
  71. Conv uint16
  72. Opt SegmentOption
  73. }
  74. func (this *TerminationSegment) ByteSize() int {
  75. return 2 + 1 + 1
  76. }
  77. func (this *TerminationSegment) Bytes(b []byte) []byte {
  78. b = serial.Uint16ToBytes(this.Conv, b)
  79. b = append(b, byte(SegmentCommandTerminated), byte(this.Opt))
  80. return b
  81. }
  82. func ReadSegment(buf []byte) (ISegment, []byte) {
  83. if len(buf) <= 12 {
  84. return nil, nil
  85. }
  86. conv := serial.BytesToUint16(buf)
  87. buf = buf[2:]
  88. cmd := SegmentCommand(buf[0])
  89. opt := SegmentOption(buf[1])
  90. buf = buf[2:]
  91. if cmd == SegmentCommandData {
  92. seg := &DataSegment{
  93. Conv: conv,
  94. Opt: opt,
  95. }
  96. seg.ReceivingWindow = serial.BytesToUint32(buf)
  97. buf = buf[4:]
  98. seg.Timestamp = serial.BytesToUint32(buf)
  99. buf = buf[4:]
  100. seg.Number = serial.BytesToUint32(buf)
  101. buf = buf[4:]
  102. seg.Unacknowledged = serial.BytesToUint32(buf)
  103. buf = buf[4:]
  104. len := serial.BytesToUint16(buf)
  105. buf = buf[2:]
  106. seg.Data = alloc.NewSmallBuffer().Clear().Append(buf[:len])
  107. buf = buf[len:]
  108. return seg, buf
  109. }
  110. if cmd == SegmentCommandACK {
  111. seg := &ACKSegment{
  112. Conv: conv,
  113. Opt: opt,
  114. }
  115. seg.ReceivingWindow = serial.BytesToUint32(buf)
  116. buf = buf[4:]
  117. seg.Unacknowledged = serial.BytesToUint32(buf)
  118. buf = buf[4:]
  119. seg.Count = buf[0]
  120. buf = buf[1:]
  121. seg.NumberList = make([]uint32, 0, seg.Count)
  122. seg.TimestampList = make([]uint32, 0, seg.Count)
  123. for i := 0; i < int(seg.Count); i++ {
  124. seg.NumberList = append(seg.NumberList, serial.BytesToUint32(buf))
  125. seg.TimestampList = append(seg.TimestampList, serial.BytesToUint32(buf[4:]))
  126. buf = buf[8:]
  127. }
  128. return seg, buf
  129. }
  130. if cmd == SegmentCommandTerminated {
  131. return &TerminationSegment{
  132. Conv: conv,
  133. Opt: opt,
  134. }, buf
  135. }
  136. return nil, nil
  137. }