Rev 6474 | Rev 6909 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6474 | Rev 6476 | ||
---|---|---|---|
Line 12... | Line 12... | ||
12 | ;; GNU GENERAL PUBLIC LICENSE ;; |
12 | ;; GNU GENERAL PUBLIC LICENSE ;; |
13 | ;; Version 2, June 1991 ;; |
13 | ;; Version 2, June 1991 ;; |
14 | ;; ;; |
14 | ;; ;; |
15 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
15 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 16... | Line 16... | ||
16 | 16 | ||
- | 17 | $Revision: 6476 $ |
|
- | 18 | ||
Line 17... | Line 19... | ||
17 | $Revision: 6474 $ |
19 | TCP_BIT_SENDALOT = 1 shl 0 |
18 | 20 | ||
19 | ;-----------------------------------------------------------------; |
21 | ;-----------------------------------------------------------------; |
20 | ; ; |
22 | ; ; |
Line 62... | Line 64... | ||
62 | 64 | ||
63 | .not_idle: |
65 | .not_idle: |
64 | .again: |
66 | .again: |
Line -... | Line 67... | ||
- | 67 | mov [temp_bits], 0 |
|
- | 68 | ||
65 | mov [temp_bits], 0 |
69 | ; Calculate offset |
66 | 70 | ||
- | 71 | mov ebx, [eax + TCP_SOCKET.SND_NXT] |
|
- | 72 | sub ebx, [eax + TCP_SOCKET.SND_UNA] |
|
Line 67... | Line 73... | ||
67 | mov ebx, [eax + TCP_SOCKET.SND_NXT] ; calculate offset (71) |
73 | |
68 | sub ebx, [eax + TCP_SOCKET.SND_UNA] ; |
74 | ; Determine window |
69 | 75 | ||
70 | mov ecx, [eax + TCP_SOCKET.SND_WND] ; determine window |
76 | mov ecx, [eax + TCP_SOCKET.SND_WND] |
71 | cmp ecx, [eax + TCP_SOCKET.SND_CWND] ; |
77 | cmp ecx, [eax + TCP_SOCKET.SND_CWND] |
Line -... | Line 78... | ||
- | 78 | jb @f |
|
- | 79 | mov ecx, [eax + TCP_SOCKET.SND_CWND] |
|
72 | jb @f ; |
80 | @@: |
Line 73... | Line 81... | ||
73 | mov ecx, [eax + TCP_SOCKET.SND_CWND] ; |
81 | |
74 | @@: ; |
82 | ; get flags in dl |
Line 75... | Line 83... | ||
75 | 83 | ||
Line 103... | Line 111... | ||
103 | mov [eax + TCP_SOCKET.t_rxtshift], 0 |
111 | mov [eax + TCP_SOCKET.t_rxtshift], 0 |
Line 104... | Line 112... | ||
104 | 112 | ||
Line 105... | Line 113... | ||
105 | .no_force: |
113 | .no_force: |
106 | 114 | ||
Line 107... | Line 115... | ||
107 | ;-------------------------------- |
115 | ;-------------------------------- |
108 | ; Calculate how much data to send (106) |
116 | ; Calculate how much data to send |
109 | 117 | ||
110 | mov esi, [eax + STREAM_SOCKET.snd.size] |
118 | mov esi, [eax + STREAM_SOCKET.snd.size] |
111 | cmp esi, ecx |
119 | cmp esi, ecx |
112 | jb @f |
120 | jb @f |
Line 113... | Line 121... | ||
113 | mov esi, ecx |
121 | mov esi, ecx |
114 | @@: |
122 | @@: |
Line 115... | Line 123... | ||
115 | sub esi, ebx |
123 | sub esi, ebx |
116 | 124 | ||
Line 117... | Line 125... | ||
117 | ;------------------------ |
125 | ;------------------------ |
Line 118... | Line 126... | ||
118 | ; check for window shrink (107) |
126 | ; check for window shrink |
- | 127 | ||
119 | 128 | ; If FIN has been sent, but not ACKed, but we havent been called to retransmit, esi will be -1 |
|
Line 120... | Line 129... | ||
120 | ; If FIN has been set, but not ACKed, but we havent been called to retransmit, esi will be -1 |
129 | ; Otherwise, window shrank after we sent into it. |
- | 130 | ||
121 | ; Otherwise, window shrank after we sent into it. |
131 | jae .not_persist |
122 | 132 | ||
Line 123... | Line 133... | ||
123 | jae .not_persist |
133 | ; enter persist state |
- | 134 | ||
124 | 135 | xor esi, esi |
|
Line 125... | Line 136... | ||
125 | ; enter persist state |
136 | |
- | 137 | ; If window shrank to 0 |
|
126 | xor esi, esi |
138 | |
127 | 139 | test ecx, ecx |
|
128 | ; If window shrank to 0 |
140 | jnz @f |
Line 129... | Line 141... | ||
129 | test ecx, ecx |
141 | |
Line 130... | Line 142... | ||
130 | jnz @f |
142 | ; cancel pending retransmit |
Line 131... | Line 143... | ||
131 | 143 | ||
132 | ; cancel pending retransmit |
144 | and [eax + TCP_SOCKET.timer_flags], not timer_flag_retransmission |
Line 133... | Line 145... | ||
133 | and [eax + TCP_SOCKET.timer_flags], not timer_flag_retransmission |
145 | |
134 | 146 | ; pull SND_NXT back to (closed) window, We will enter persist state below. |
|
135 | ; pull SND_NXT back to (closed) window, We will enter persist state below. |
147 | |
136 | push [eax + TCP_SOCKET.SND_UNA] |
148 | push [eax + TCP_SOCKET.SND_UNA] |
137 | pop [eax + TCP_SOCKET.SND_NXT] |
149 | pop [eax + TCP_SOCKET.SND_NXT] |
Line 138... | Line 150... | ||
138 | @@: |
150 | @@: |
139 | 151 | ||
Line 140... | Line 152... | ||
140 | ; If window didn't close completely, just wait for an ACK |
152 | ; If window didn't close completely, just wait for an ACK |
141 | 153 | ||
142 | .not_persist: |
154 | .not_persist: |
143 | 155 | ||
144 | ;--------------------------- |
156 | ;--------------------------- |
145 | ; Send one segment at a time (124) |
157 | ; Send one segment at a time |
146 | 158 | ||
Line 147... | Line 159... | ||
147 | cmp esi, [eax + TCP_SOCKET.t_maxseg] |
159 | cmp esi, [eax + TCP_SOCKET.t_maxseg] |
148 | jbe @f |
160 | jbe @f |
Line 149... | Line 161... | ||
149 | mov esi, [eax + TCP_SOCKET.t_maxseg] |
161 | mov esi, [eax + TCP_SOCKET.t_maxseg] |
150 | or [temp_bits], TCP_BIT_SENDALOT |
162 | or [temp_bits], TCP_BIT_SENDALOT |
Line 151... | Line 163... | ||
151 | @@: |
163 | @@: |
152 | 164 | ||
Line 153... | Line 165... | ||
153 | ;-------------------------------------------- |
165 | ;-------------------------------------------- |
154 | ; Turn of FIN flag if send buffer not emptied (128) |
166 | ; Turn of FIN flag if send buffer not emptied |
Line 155... | Line 167... | ||
155 | 167 | ||
Line 201... | Line 213... | ||
201 | jb .send |
213 | jb .send |
Line 202... | Line 214... | ||
202 | 214 | ||
Line 203... | Line 215... | ||
203 | .len_zero: |
215 | .len_zero: |
204 | 216 | ||
Line 205... | Line 217... | ||
205 | ;---------------------------------------- |
217 | ;---------------------------------------- |
Line 206... | Line 218... | ||
206 | ; Check if a window update should be sent (154) |
218 | ; Check if a window update should be sent |
207 | 219 | ||
Line 225... | Line 237... | ||
225 | mov ebx, ecx |
237 | mov ebx, ecx |
226 | @@: |
238 | @@: |
227 | sub ebx, [eax + TCP_SOCKET.RCV_ADV] |
239 | sub ebx, [eax + TCP_SOCKET.RCV_ADV] |
228 | add ebx, [eax + TCP_SOCKET.RCV_NXT] |
240 | add ebx, [eax + TCP_SOCKET.RCV_NXT] |
Line -... | Line 241... | ||
- | 241 | ||
- | 242 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: we can increase window by %d bytes\n", ebx |
|
229 | 243 | ||
230 | mov edi, [eax + TCP_SOCKET.t_maxseg] |
244 | mov edi, [eax + TCP_SOCKET.t_maxseg] |
231 | shl edi, 1 |
- | |
232 | 245 | shl edi, 1 |
|
233 | cmp ebx, edi |
246 | cmp ebx, edi |
Line 234... | Line 247... | ||
234 | jae .send |
247 | jae .send |
235 | 248 | ||
236 | shl ebx, 1 |
249 | shl ebx, 1 |
Line 237... | Line 250... | ||
237 | ; cmp ebx, [eax + TCP_SOCKET.] ;;; TODO: check with receive buffer high water mark |
250 | ; cmp ebx, [eax + TCP_SOCKET.] ;;; TODO: check with receive buffer high water mark |
Line 238... | Line 251... | ||
238 | ; jae TCP_send |
251 | ; jae TCP_send |
239 | 252 | ||
- | 253 | .no_window: |
|
- | 254 | ||
Line 240... | Line 255... | ||
240 | .no_window: |
255 | ;-------------------------- |
241 | 256 | ; Should a segment be sent? |
|
Line 242... | Line 257... | ||
242 | ;-------------------------- |
257 | |
Line 250... | Line 265... | ||
250 | 265 | ||
251 | mov ebx, [eax + TCP_SOCKET.SND_UP] ; when urgent pointer is beyond start of send bufer |
266 | mov ebx, [eax + TCP_SOCKET.SND_UP] ; when urgent pointer is beyond start of send bufer |
252 | cmp ebx, [eax + TCP_SOCKET.SND_UNA] |
267 | cmp ebx, [eax + TCP_SOCKET.SND_UNA] |
Line -... | Line 268... | ||
- | 268 | ja .send |
|
- | 269 | ||
253 | ja .send |
270 | ; Do we need to send a FIN according to our state? |
254 | 271 | ||
Line 255... | Line 272... | ||
255 | test dl, TH_FIN |
272 | test dl, TH_FIN |
Line 256... | Line 273... | ||
256 | jz .enter_persist ; no reason to send, enter persist state |
273 | jz .enter_persist ; no reason to send, enter persist state |
257 | 274 | ||
Line -... | Line 275... | ||
- | 275 | ; Do so if we didnt do it already |
|
- | 276 | ||
258 | ; FIN was set, only send if not already sent, or on retransmit |
277 | test [eax + TCP_SOCKET.t_flags], TF_SENTFIN |
259 | 278 | jz .send |
|
260 | test [eax + TCP_SOCKET.t_flags], TF_SENTFIN |
279 | |
Line 261... | Line 280... | ||
261 | jz .send |
280 | ; Or when we need to retransmit the FIN |
262 | 281 | ||
Line 263... | Line 282... | ||
263 | mov ebx, [eax + TCP_SOCKET.SND_NXT] |
282 | mov ebx, [eax + TCP_SOCKET.SND_NXT] |
Line 264... | Line 283... | ||
264 | cmp ebx, [eax + TCP_SOCKET.SND_UNA] |
283 | cmp ebx, [eax + TCP_SOCKET.SND_UNA] |
265 | je .send |
284 | je .send |
Line 282... | Line 301... | ||
282 | mov [eax + TCP_SOCKET.t_rxtshift], 0 |
301 | mov [eax + TCP_SOCKET.t_rxtshift], 0 |
283 | call tcp_set_persist |
302 | call tcp_set_persist |
284 | @@: |
303 | @@: |
Line 285... | Line 304... | ||
285 | 304 | ||
286 | ;---------------------------- |
305 | ;---------------------------- |
Line 287... | Line 306... | ||
287 | ; No reason to send a segment (219) |
306 | ; No reason to send a segment |
Line 288... | Line 307... | ||
288 | 307 | ||
289 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: No reason to send a segment\n" |
308 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: No reason to send a segment\n" |
Line 298... | Line 317... | ||
298 | ret |
317 | ret |
Line 299... | Line 318... | ||
299 | 318 | ||
300 | 319 | ||
301 | ;----------------------------------------------- |
320 | ;----------------------------------------------- |
302 | ; |
321 | ; |
303 | ; Send a segment (222) |
322 | ; Send a segment |
304 | ; |
323 | ; |
305 | ; eax = socket pointer |
324 | ; eax = socket pointer |
306 | ; esi = data len |
325 | ; esi = data len |
Line 389... | Line 408... | ||
389 | ; edx = flags |
408 | ; edx = flags |
390 | ; edi = header size |
409 | ; edi = header size |
391 | ; esi = data len |
410 | ; esi = data len |
Line 392... | Line 411... | ||
392 | 411 | ||
393 | ;--------------------------------------------- |
412 | ;--------------------------------------------- |
Line 394... | Line 413... | ||
394 | ; check if we dont exceed the max segment size (270) |
413 | ; check if we dont exceed the max segment size |
395 | 414 | ||
396 | add esi, edi ; total TCP segment size |
415 | add esi, edi ; total TCP segment size |
Line 397... | Line 416... | ||
397 | cmp esi, [eax + TCP_SOCKET.t_maxseg] |
416 | cmp esi, [eax + TCP_SOCKET.t_maxseg] |
398 | jbe .no_overflow |
417 | jbe .no_overflow |
399 | 418 | ||
Line 400... | Line 419... | ||
400 | mov esi, [eax + TCP_SOCKET.t_maxseg] |
419 | mov esi, [eax + TCP_SOCKET.t_maxseg] |
- | 420 | or [temp_bits], TCP_BIT_SENDALOT |
|
401 | or [temp_bits], TCP_BIT_SENDALOT |
421 | .no_overflow: |
402 | .no_overflow: |
422 | |
Line 403... | Line 423... | ||
403 | 423 | ; Update stats |
|
404 | ; Update stats |
424 | |
Line 480... | Line 500... | ||
480 | 500 | ||
481 | ;----------------------------------------------------------------- |
501 | ;----------------------------------------------------------------- |
482 | ; Start by pushing all TCP header values in reverse order on stack |
502 | ; Start by pushing all TCP header values in reverse order on stack |
Line 483... | Line 503... | ||
483 | ; (essentially, creating the tcp header on the stack!) |
503 | ; (essentially, creating the tcp header on the stack!) |
484 | 504 | ||
485 | pushw 0 ; .UrgentPointer dw ? |
505 | pushw 0 ; UrgentPointer |
486 | pushw 0 ; .Checksum dw ? |
506 | pushw 0 ; Checksum |
487 | pushw bx ; .Window dw ? |
507 | pushw bx ; Window |
488 | shl edi, 2 ; .DataOffset db ? only 4 left-most bits |
508 | shl edi, 2 ; DataOffset |
489 | shl dx, 8 |
509 | shl dx, 8 |
490 | or dx, di ; .Flags db ? |
510 | or dx, di ; Flags |
Line 491... | Line 511... | ||
491 | pushw dx |
511 | pushw dx |
492 | shr edi, 2 ; .DataOffset db ? |
512 | shr edi, 2 ; DataOffset |
Line 493... | Line 513... | ||
493 | 513 | ||
494 | push [eax + TCP_SOCKET.RCV_NXT] ; .AckNumber dd ? |
514 | push [eax + TCP_SOCKET.RCV_NXT] ; AckNumber |
Line 495... | Line 515... | ||
495 | ntohd [esp] |
515 | ntohd [esp] |
496 | 516 | ||
Line 497... | Line 517... | ||
497 | push [eax + TCP_SOCKET.SND_NXT] ; .SequenceNumber dd ? |
517 | push [eax + TCP_SOCKET.SND_NXT] ; SequenceNumber |
Line 498... | Line 518... | ||
498 | ntohd [esp] |
518 | ntohd [esp] |
499 | 519 | ||
Line 556... | Line 576... | ||
556 | pop edi |
576 | pop edi |
557 | pop esi ; begin of data |
577 | pop esi ; begin of data |
558 | pop ecx ; full packet size |
578 | pop ecx ; full packet size |
559 | mov eax, [esp + 8] ; socket ptr |
579 | mov eax, [esp + 8] ; socket ptr |
Line 560... | Line 580... | ||
560 | 580 | ||
561 | ;---------------------------------- |
581 | ;---------------------------- |
Line 562... | Line 582... | ||
562 | ; initialize retransmit timer (400) |
582 | ; initialize retransmit timer |
Line 563... | Line 583... | ||
563 | 583 | ||
564 | ;TODO: check t_force and persist |
584 | ;TODO: check t_force and persist |
Line 582... | Line 602... | ||
582 | mov [eax + TCP_SOCKET.t_rtseq], edi |
602 | mov [eax + TCP_SOCKET.t_rtseq], edi |
583 | inc [TCPS_segstimed] |
603 | inc [TCPS_segstimed] |
584 | @@: |
604 | @@: |
Line 585... | Line 605... | ||
585 | 605 | ||
- | 606 | ; set retransmission timer if not already set, and not doing an ACK or keepalive probe |
|
586 | ; set retransmission timer if not already set, and not doing an ACK or keepalive probe |
607 | |
587 | test [eax + TCP_SOCKET.timer_flags], timer_flag_retransmission |
608 | test [eax + TCP_SOCKET.timer_flags], timer_flag_retransmission |
Line 588... | Line 609... | ||
588 | jnz .retransmit_set |
609 | jnz .retransmit_set |
589 | 610 | ||
Line 596... | Line 617... | ||
596 | 617 | ||
597 | test [eax + TCP_SOCKET.timer_flags], timer_flag_persist |
618 | test [eax + TCP_SOCKET.timer_flags], timer_flag_persist |
598 | jz .retransmit_set |
619 | jz .retransmit_set |
599 | and [eax + TCP_SOCKET.timer_flags], not timer_flag_persist |
620 | and [eax + TCP_SOCKET.timer_flags], not timer_flag_persist |
600 | mov [eax + TCP_SOCKET.t_rxtshift], 0 |
- | |
601 | 621 | mov [eax + TCP_SOCKET.t_rxtshift], 0 |
|
Line 602... | Line 622... | ||
602 | .retransmit_set: |
622 | .retransmit_set: |
603 | 623 | ||
Line 640... | Line 660... | ||
640 | jbe @f |
660 | jbe @f |
641 | mov [eax + TCP_SOCKET.RCV_ADV], ecx |
661 | mov [eax + TCP_SOCKET.RCV_ADV], ecx |
642 | @@: |
662 | @@: |
Line 643... | Line 663... | ||
643 | 663 | ||
- | 664 | ; update last ack sent |
|
644 | ; update last ack sent |
665 | |
645 | push [eax + TCP_SOCKET.RCV_NXT] |
666 | push [eax + TCP_SOCKET.RCV_NXT] |
Line 646... | Line 667... | ||
646 | pop [eax + TCP_SOCKET.last_ack_sent] |
667 | pop [eax + TCP_SOCKET.last_ack_sent] |
- | 668 | ||
647 | 669 | ; clear the ACK flags |
|
Line 648... | Line 670... | ||
648 | ; clear the ACK flags |
670 | |
649 | and [eax + TCP_SOCKET.t_flags], not (TF_ACKNOW + TF_DELACK) |
671 | and [eax + TCP_SOCKET.t_flags], not (TF_ACKNOW + TF_DELACK) |