...
1
2
3
4
5
6
7 package quic
8
9 import (
10 "context"
11 )
12
13
14
15
16
17
18
19
20
21 type localStreamLimits struct {
22 gate gate
23 max int64
24 opened int64
25 }
26
27 func (lim *localStreamLimits) init() {
28 lim.gate = newGate()
29 }
30
31
32 func (lim *localStreamLimits) open(ctx context.Context, c *Conn) (num int64, err error) {
33
34 if err := lim.gate.waitAndLock(ctx, c.testHooks); err != nil {
35 return 0, err
36 }
37 if lim.opened < 0 {
38 lim.gate.unlock(true)
39 return 0, errConnClosed
40 }
41 num = lim.opened
42 lim.opened++
43 lim.gate.unlock(lim.opened < lim.max)
44 return num, nil
45 }
46
47
48 func (lim *localStreamLimits) connHasClosed() {
49 lim.gate.lock()
50 lim.opened = -1
51 lim.gate.unlock(true)
52 }
53
54
55 func (lim *localStreamLimits) setMax(maxStreams int64) {
56 lim.gate.lock()
57 lim.max = max(lim.max, maxStreams)
58 lim.gate.unlock(lim.opened < lim.max)
59 }
60
61
62 type remoteStreamLimits struct {
63 max int64
64 opened int64
65 closed int64
66 maxOpen int64
67 sendMax sentVal
68 }
69
70 func (lim *remoteStreamLimits) init(maxOpen int64) {
71 lim.maxOpen = maxOpen
72 lim.max = min(maxOpen, implicitStreamLimit)
73 lim.opened = 0
74 }
75
76
77 func (lim *remoteStreamLimits) open(id streamID) error {
78 num := id.num()
79 if num >= lim.max {
80 return localTransportError{
81 code: errStreamLimit,
82 reason: "stream limit exceeded",
83 }
84 }
85 if num >= lim.opened {
86 lim.opened = num + 1
87 lim.maybeUpdateMax()
88 }
89 return nil
90 }
91
92
93 func (lim *remoteStreamLimits) close() {
94 lim.closed++
95 lim.maybeUpdateMax()
96 }
97
98
99 func (lim *remoteStreamLimits) maybeUpdateMax() {
100 newMax := min(
101
102 lim.closed+lim.maxOpen,
103
104 lim.opened+implicitStreamLimit,
105 )
106 avail := lim.max - lim.opened
107 if newMax > lim.max && (avail < 8 || newMax-lim.max >= 2*avail) {
108
109
110 lim.max = newMax
111 lim.sendMax.setUnsent()
112 }
113 }
114
115
116
117
118
119 func (lim *remoteStreamLimits) appendFrame(w *packetWriter, typ streamType, pnum packetNumber, pto bool) bool {
120 if lim.sendMax.shouldSendPTO(pto) {
121 if !w.appendMaxStreamsFrame(typ, lim.max) {
122 return false
123 }
124 lim.sendMax.setSent(pnum)
125 }
126 return true
127 }
128
View as plain text