retransmission_queue.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. package quic
  2. import (
  3. "fmt"
  4. "github.com/Psiphon-Labs/quic-go/internal/protocol"
  5. "github.com/Psiphon-Labs/quic-go/internal/wire"
  6. )
  7. type retransmissionQueue struct {
  8. initial []wire.Frame
  9. initialCryptoData []*wire.CryptoFrame
  10. handshake []wire.Frame
  11. handshakeCryptoData []*wire.CryptoFrame
  12. appData []wire.Frame
  13. version protocol.VersionNumber
  14. }
  15. func newRetransmissionQueue(ver protocol.VersionNumber) *retransmissionQueue {
  16. return &retransmissionQueue{version: ver}
  17. }
  18. func (q *retransmissionQueue) AddInitial(f wire.Frame) {
  19. if cf, ok := f.(*wire.CryptoFrame); ok {
  20. q.initialCryptoData = append(q.initialCryptoData, cf)
  21. return
  22. }
  23. q.initial = append(q.initial, f)
  24. }
  25. func (q *retransmissionQueue) AddHandshake(f wire.Frame) {
  26. if cf, ok := f.(*wire.CryptoFrame); ok {
  27. q.handshakeCryptoData = append(q.handshakeCryptoData, cf)
  28. return
  29. }
  30. q.handshake = append(q.handshake, f)
  31. }
  32. func (q *retransmissionQueue) HasInitialData() bool {
  33. return len(q.initialCryptoData) > 0 || len(q.initial) > 0
  34. }
  35. func (q *retransmissionQueue) HasHandshakeData() bool {
  36. return len(q.handshakeCryptoData) > 0 || len(q.handshake) > 0
  37. }
  38. func (q *retransmissionQueue) HasAppData() bool {
  39. return len(q.appData) > 0
  40. }
  41. func (q *retransmissionQueue) AddAppData(f wire.Frame) {
  42. if _, ok := f.(*wire.StreamFrame); ok {
  43. panic("STREAM frames are handled with their respective streams.")
  44. }
  45. q.appData = append(q.appData, f)
  46. }
  47. func (q *retransmissionQueue) GetInitialFrame(maxLen protocol.ByteCount) wire.Frame {
  48. if len(q.initialCryptoData) > 0 {
  49. f := q.initialCryptoData[0]
  50. newFrame, needsSplit := f.MaybeSplitOffFrame(maxLen, q.version)
  51. if newFrame == nil && !needsSplit { // the whole frame fits
  52. q.initialCryptoData = q.initialCryptoData[1:]
  53. return f
  54. }
  55. if newFrame != nil { // frame was split. Leave the original frame in the queue.
  56. return newFrame
  57. }
  58. }
  59. if len(q.initial) == 0 {
  60. return nil
  61. }
  62. f := q.initial[0]
  63. if f.Length(q.version) > maxLen {
  64. return nil
  65. }
  66. q.initial = q.initial[1:]
  67. return f
  68. }
  69. func (q *retransmissionQueue) GetHandshakeFrame(maxLen protocol.ByteCount) wire.Frame {
  70. if len(q.handshakeCryptoData) > 0 {
  71. f := q.handshakeCryptoData[0]
  72. newFrame, needsSplit := f.MaybeSplitOffFrame(maxLen, q.version)
  73. if newFrame == nil && !needsSplit { // the whole frame fits
  74. q.handshakeCryptoData = q.handshakeCryptoData[1:]
  75. return f
  76. }
  77. if newFrame != nil { // frame was split. Leave the original frame in the queue.
  78. return newFrame
  79. }
  80. }
  81. if len(q.handshake) == 0 {
  82. return nil
  83. }
  84. f := q.handshake[0]
  85. if f.Length(q.version) > maxLen {
  86. return nil
  87. }
  88. q.handshake = q.handshake[1:]
  89. return f
  90. }
  91. func (q *retransmissionQueue) GetAppDataFrame(maxLen protocol.ByteCount) wire.Frame {
  92. if len(q.appData) == 0 {
  93. return nil
  94. }
  95. f := q.appData[0]
  96. if f.Length(q.version) > maxLen {
  97. return nil
  98. }
  99. q.appData = q.appData[1:]
  100. return f
  101. }
  102. func (q *retransmissionQueue) DropPackets(encLevel protocol.EncryptionLevel) {
  103. //nolint:exhaustive // Can only drop Initial and Handshake packet number space.
  104. switch encLevel {
  105. case protocol.EncryptionInitial:
  106. q.initial = nil
  107. q.initialCryptoData = nil
  108. case protocol.EncryptionHandshake:
  109. q.handshake = nil
  110. q.handshakeCryptoData = nil
  111. default:
  112. panic(fmt.Sprintf("unexpected encryption level: %s", encLevel))
  113. }
  114. }