Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 207 lines (190 sloc) 4.823 kb
fe6cc71 updated copyright
Petar Maymounkov authored
1 // Copyright 2011 GoDCCP Authors. All rights reserved.
edf3b43 bug fixes
Petar Maymounkov authored
2 // Use of this source code is governed by a
3 // license that can be found in the LICENSE file.
4
5 package dccp
6
658dc7b fix bug in ccconst
Petar Maymounkov authored
7 import (
8 "log"
9 "time"
10 )
edf3b43 bug fixes
Petar Maymounkov authored
11
12 func (c *Conn) gotoLISTEN() {
13 c.AssertLocked()
14 c.socket.SetServer(true)
15 c.socket.SetState(LISTEN)
cde143f Petar Maymounkov fixups
authored
16 c.logState()
edf3b43 bug fixes
Petar Maymounkov authored
17 go func() {
18 time.Sleep(REQUEST_BACKOFF_MAX)
19 c.Lock()
20 state := c.socket.GetState()
21 c.Unlock()
22 if state != LISTEN {
23 return
24 }
25 c.abortQuietly()
26 }()
27 }
28
c27a2a9 separated congestion control into sender and receiver side
Petar Maymounkov authored
29 const RESPOND_TIMEOUT = 30e9 // Timeout in RESPOND state, 30 sec in nanoseconds
30
9fa434c improvements and bug fixes + new notes
Petar Maymounkov authored
31 func (c *Conn) gotoRESPOND(hServiceCode uint32, hSeqNo int64) {
32 c.AssertLocked()
33 c.socket.SetState(RESPOND)
cde143f Petar Maymounkov fixups
authored
34 c.logState()
9fa434c improvements and bug fixes + new notes
Petar Maymounkov authored
35 iss := c.socket.ChooseISS()
36 c.socket.SetGAR(iss)
37 c.socket.SetISR(hSeqNo)
38 c.socket.SetGSR(hSeqNo)
39 // TODO: To be more prudent, set service code only if it is currently 0,
40 // otherwise check that h.ServiceCode matches socket service code
41 c.socket.SetServiceCode(hServiceCode)
c27a2a9 separated congestion control into sender and receiver side
Petar Maymounkov authored
42
43 go func() {
44 time.Sleep(RESPOND_TIMEOUT)
45 c.Lock()
46 state := c.socket.GetState()
47 c.Unlock()
48 if state == RESPOND {
49 c.abortQuietly()
50 }
51 }()
9fa434c improvements and bug fixes + new notes
Petar Maymounkov authored
52 }
53
edf3b43 bug fixes
Petar Maymounkov authored
54 const (
55 REQUEST_BACKOFF_FIRST = 1e9 // Initial re-send period for client Request resends is 1 sec, in nanoseconds
56 REQUEST_BACKOFF_MAX = 120e9 // Request re-sends quit after 2 mins, in nanoseconds
57 REQUEST_BACKOFF_FREQ = 10e9 // Back-off Request resend every 10 secs, in nanoseconds
58 )
59
60 func (c *Conn) gotoREQUEST(serviceCode uint32) {
61 c.AssertLocked()
62 c.socket.SetServer(false)
63 c.socket.SetState(REQUEST)
cde143f Petar Maymounkov fixups
authored
64 c.logState()
edf3b43 bug fixes
Petar Maymounkov authored
65 c.socket.SetServiceCode(serviceCode)
66 iss := c.socket.ChooseISS()
67 c.socket.SetGAR(iss)
68 c.inject(c.generateRequest(serviceCode))
69
70 // Resend Request using exponential backoff, if no response
71 go func() {
72 b := newBackOff(REQUEST_BACKOFF_FIRST, REQUEST_BACKOFF_MAX, REQUEST_BACKOFF_FREQ)
73 for {
044bbb7 Petar Maymounkov verified backoff works properly
authored
74 err, _ := b.Sleep()
edf3b43 bug fixes
Petar Maymounkov authored
75 c.Lock()
76 state := c.socket.GetState()
77 c.Unlock()
78 if state != REQUEST {
79 break
80 }
81 // If the back-off timer has reached maximum wait, quit trying
82 if err != nil {
83 c.abort()
84 break
85 }
86 c.Lock()
658dc7b fix bug in ccconst
Petar Maymounkov authored
87 log.Printf("resend Request\n")
edf3b43 bug fixes
Petar Maymounkov authored
88 c.inject(c.generateRequest(serviceCode))
89 c.Unlock()
90 }
91 }()
92 }
93
9fa434c improvements and bug fixes + new notes
Petar Maymounkov authored
94 const (
95 PARTOPEN_BACKOFF_FIRST = 200e6 // 200 miliseconds in nanoseconds, Section 8.1.5
96 PARTOPEN_BACKOFF_MAX = 4 * MSL // 8 mins in nanoseconds, Section 8.1.5
97 )
98
99 func (c *Conn) gotoPARTOPEN() {
100 c.AssertLocked()
101 c.socket.SetState(PARTOPEN)
cde143f Petar Maymounkov fixups
authored
102 c.logState()
b15a4e3 congestion control is active only during OPEN and PARTOPEN
Petar Maymounkov authored
103 c.scc.Open()
104 c.rcc.Open()
45c62e4 Petar Maymounkov refine logging framework
authored
105 c.logEvent("CCID open")
6577934 bug fixes in readLoop -> writeLoop dialog
Petar Maymounkov authored
106 c.inject(nil) // Unblocks the writeLoop select, so it can see the state change
9fa434c improvements and bug fixes + new notes
Petar Maymounkov authored
107
108 // Start PARTOPEN timer, according to Section 8.1.5
109 go func() {
110 b := newBackOff(PARTOPEN_BACKOFF_FIRST, PARTOPEN_BACKOFF_MAX, PARTOPEN_BACKOFF_FIRST)
044bbb7 Petar Maymounkov verified backoff works properly
authored
111 c.CLog.Logf("conn", "Event", "PARTOPEN backoff %d start", time.Nanoseconds())
9fa434c improvements and bug fixes + new notes
Petar Maymounkov authored
112 for {
044bbb7 Petar Maymounkov verified backoff works properly
authored
113 err, btm := b.Sleep()
9fa434c improvements and bug fixes + new notes
Petar Maymounkov authored
114 c.Lock()
115 state := c.socket.GetState()
116 c.Unlock()
117 if state != PARTOPEN {
044bbb7 Petar Maymounkov verified backoff works properly
authored
118 c.CLog.Logf("conn", "Event", "PARTOPEN backoff EXIT via state change %d", btm)
9fa434c improvements and bug fixes + new notes
Petar Maymounkov authored
119 break
120 }
121 // If the back-off timer has reached maximum wait. End the connection.
122 if err != nil {
123 c.abort()
124 break
125 }
044bbb7 Petar Maymounkov verified backoff works properly
authored
126 c.CLog.Logf("conn", "Event", "PARTOPEN backoff %d", btm)
9fa434c improvements and bug fixes + new notes
Petar Maymounkov authored
127 c.Lock()
128 c.inject(c.generateAck())
d5b1c07 fix
Petar Maymounkov authored
129 // XXX: This is a deviation from the RFC. The Sync packet necessitates a
130 // SyncAck response, which moves the client from PARTOPEN to OPEN in the
131 // lack of DataAck packets sent from the server to the client.
132 c.inject(c.generateSync())
9fa434c improvements and bug fixes + new notes
Petar Maymounkov authored
133 c.Unlock()
134 }
135 }()
136 }
137
6577934 bug fixes in readLoop -> writeLoop dialog
Petar Maymounkov authored
138 func (c *Conn) gotoOPEN(hSeqNo int64) {
139 c.AssertLocked()
140 c.socket.SetOSR(hSeqNo)
141 c.socket.SetState(OPEN)
cde143f Petar Maymounkov fixups
authored
142 c.logState()
b15a4e3 congestion control is active only during OPEN and PARTOPEN
Petar Maymounkov authored
143 c.scc.Open()
144 c.rcc.Open()
6577934 bug fixes in readLoop -> writeLoop dialog
Petar Maymounkov authored
145 c.inject(nil) // Unblocks the writeLoop select, so it can see the state change
146 }
147
edf3b43 bug fixes
Petar Maymounkov authored
148 func (c *Conn) gotoTIMEWAIT() {
149 c.AssertLocked()
658dc7b fix bug in ccconst
Petar Maymounkov authored
150 c.teardownUser()
edf3b43 bug fixes
Petar Maymounkov authored
151 c.socket.SetState(TIMEWAIT)
cde143f Petar Maymounkov fixups
authored
152 c.logState()
b15a4e3 congestion control is active only during OPEN and PARTOPEN
Petar Maymounkov authored
153 c.scc.Close()
154 c.rcc.Close()
45c62e4 Petar Maymounkov refine logging framework
authored
155 c.logEvent("CCID close ->TIMEWAIT")
edf3b43 bug fixes
Petar Maymounkov authored
156 go func() {
157 time.Sleep(2 * MSL)
158 c.abortQuietly()
159 }()
160 }
161
162 func (c *Conn) gotoCLOSING() {
163 c.AssertLocked()
658dc7b fix bug in ccconst
Petar Maymounkov authored
164 c.teardownUser()
edf3b43 bug fixes
Petar Maymounkov authored
165 c.socket.SetState(CLOSING)
cde143f Petar Maymounkov fixups
authored
166 c.logState()
b15a4e3 congestion control is active only during OPEN and PARTOPEN
Petar Maymounkov authored
167 c.scc.Close()
168 c.rcc.Close()
45c62e4 Petar Maymounkov refine logging framework
authored
169 c.logEvent("CCID close ->CLOSING")
edf3b43 bug fixes
Petar Maymounkov authored
170 go func() {
171 c.Lock()
172 rtt := c.socket.GetRTT()
173 c.Unlock()
174 b := newBackOff(2*rtt, CLOSING_BACKOFF_MAX, CLOSING_BACKOFF_FREQ)
175 for {
044bbb7 Petar Maymounkov verified backoff works properly
authored
176 err, _ := b.Sleep()
edf3b43 bug fixes
Petar Maymounkov authored
177 c.Lock()
178 state := c.socket.GetState()
179 c.Unlock()
180 if state != CLOSING {
181 break
182 }
183 if err != nil {
184 c.Lock()
185 c.gotoTIMEWAIT()
186 c.Unlock()
187 break
188 }
189 c.Lock()
190 c.inject(c.generateClose())
191 c.Unlock()
192 }
193 }()
194 }
6577934 bug fixes in readLoop -> writeLoop dialog
Petar Maymounkov authored
195
2acc115 finalized congestion control interfaces
Petar Maymounkov authored
196 // gotoCLOSED MUST be idempotent
6577934 bug fixes in readLoop -> writeLoop dialog
Petar Maymounkov authored
197 func (c *Conn) gotoCLOSED() {
198 c.AssertLocked()
199 c.socket.SetState(CLOSED)
cde143f Petar Maymounkov fixups
authored
200 c.logState()
2acc115 finalized congestion control interfaces
Petar Maymounkov authored
201 c.teardownUser()
202 c.teardownWriteLoop()
b15a4e3 congestion control is active only during OPEN and PARTOPEN
Petar Maymounkov authored
203 c.scc.Close()
204 c.rcc.Close()
45c62e4 Petar Maymounkov refine logging framework
authored
205 c.logEvent("CCID close ->CLOSED")
6577934 bug fixes in readLoop -> writeLoop dialog
Petar Maymounkov authored
206 }
Something went wrong with that request. Please try again.