Rev 4265 | Rev 5565 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4265 | Rev 4423 | ||
---|---|---|---|
Line 19... | Line 19... | ||
19 | ;----------------------------------------------------------------- |
19 | ;----------------------------------------------------------------- |
20 | ; |
20 | ; |
21 | ; TCP_output |
21 | ; TCP_output |
22 | ; |
22 | ; |
23 | ; IN: eax = socket pointer |
23 | ; IN: eax = socket pointer |
24 | ; |
- | |
25 | ; OUT: / |
24 | ; OUT: eax = 0 on success/errorcode |
26 | ; |
25 | ; |
27 | ;----------------------------------------------------------------- |
26 | ;----------------------------------------------------------------- |
28 | align 4 |
27 | align 4 |
29 | TCP_output: |
28 | proc TCP_output |
- | 29 | ||
- | 30 | locals |
|
- | 31 | temp_bits db ? |
|
- | 32 | endl |
|
Line 30... | Line 33... | ||
30 | 33 | ||
Line 31... | Line 34... | ||
31 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: socket=%x\n", eax |
34 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: socket=%x state=%u\n", eax, [eax + TCP_SOCKET.t_state] |
32 | 35 | ||
33 | push eax |
36 | push eax |
34 | lea ecx, [eax + SOCKET.mutex] |
37 | lea ecx, [eax + SOCKET.mutex] |
Line 55... | Line 58... | ||
55 | mov ebx, [eax + TCP_SOCKET.t_maxseg] |
58 | mov ebx, [eax + TCP_SOCKET.t_maxseg] |
56 | mov [eax + TCP_SOCKET.SND_CWND], ebx |
59 | mov [eax + TCP_SOCKET.SND_CWND], ebx |
Line 57... | Line 60... | ||
57 | 60 | ||
58 | .not_idle: |
61 | .not_idle: |
59 | .again: |
62 | .again: |
Line 60... | Line 63... | ||
60 | mov [eax + TCP_SOCKET.temp_bits], 0 |
63 | mov [temp_bits], 0 |
61 | 64 | ||
Line 62... | Line 65... | ||
62 | mov ebx, [eax + TCP_SOCKET.SND_NXT] ; calculate offset (71) |
65 | mov ebx, [eax + TCP_SOCKET.SND_NXT] ; calculate offset (71) |
Line 143... | Line 146... | ||
143 | 146 | ||
144 | cmp esi, [eax + TCP_SOCKET.t_maxseg] |
147 | cmp esi, [eax + TCP_SOCKET.t_maxseg] |
Line 145... | Line 148... | ||
145 | jbe @f |
148 | jbe @f |
146 | 149 | ||
147 | mov esi, [eax + TCP_SOCKET.t_maxseg] |
150 | mov esi, [eax + TCP_SOCKET.t_maxseg] |
Line 148... | Line 151... | ||
148 | or [eax + TCP_SOCKET.temp_bits], TCP_BIT_SENDALOT |
151 | or [temp_bits], TCP_BIT_SENDALOT |
149 | @@: |
152 | @@: |
Line 171... | Line 174... | ||
171 | 174 | ||
172 | test esi, esi |
175 | test esi, esi |
Line 173... | Line 176... | ||
173 | jz .len_zero |
176 | jz .len_zero |
174 | 177 | ||
Line 175... | Line 178... | ||
175 | cmp esi, [eax + TCP_SOCKET.t_maxseg] |
178 | cmp esi, [eax + TCP_SOCKET.t_maxseg] |
176 | je TCP_send |
179 | je .send |
177 | 180 | ||
Line 178... | Line 181... | ||
178 | add ebx, esi ; offset + length |
181 | add ebx, esi ; offset + length |
179 | cmp ebx, [eax + STREAM_SOCKET.snd.size] |
182 | cmp ebx, [eax + STREAM_SOCKET.snd.size] |
Line 180... | Line 183... | ||
180 | jb @f |
183 | jb @f |
181 | 184 | ||
182 | test [eax + TCP_SOCKET.t_flags], TF_NODELAY |
185 | test [eax + TCP_SOCKET.t_flags], TF_NODELAY |
183 | jnz TCP_send |
186 | jnz .send |
Line 184... | Line 187... | ||
184 | 187 | ||
185 | mov ebx, [eax + TCP_SOCKET.SND_MAX] |
188 | mov ebx, [eax + TCP_SOCKET.SND_MAX] |
Line 186... | Line 189... | ||
186 | cmp ebx, [eax + TCP_SOCKET.SND_UNA] |
189 | cmp ebx, [eax + TCP_SOCKET.SND_UNA] |
187 | je TCP_send |
190 | je .send |
188 | @@: |
191 | @@: |
189 | 192 | ||
Line 190... | Line 193... | ||
190 | test [eax + TCP_SOCKET.t_force], -1 ;;; |
193 | test [eax + TCP_SOCKET.t_force], -1 ;;; |
191 | jnz TCP_send |
194 | jnz .send |
192 | 195 | ||
Line 193... | Line 196... | ||
193 | mov ebx, [eax + TCP_SOCKET.max_sndwnd] |
196 | mov ebx, [eax + TCP_SOCKET.max_sndwnd] |
Line 194... | Line 197... | ||
194 | shr ebx, 1 |
197 | shr ebx, 1 |
195 | cmp esi, ebx |
198 | cmp esi, ebx |
Line 227... | Line 230... | ||
227 | add ebx, [eax + TCP_SOCKET.RCV_NXT] |
230 | add ebx, [eax + TCP_SOCKET.RCV_NXT] |
Line 228... | Line 231... | ||
228 | 231 | ||
229 | mov edi, [eax + TCP_SOCKET.t_maxseg] |
232 | mov edi, [eax + TCP_SOCKET.t_maxseg] |
Line 230... | Line 233... | ||
230 | shl edi, 1 |
233 | shl edi, 1 |
231 | 234 | ||
Line -... | Line 235... | ||
- | 235 | cmp ebx, edi |
|
232 | ; cmp ebx, edi |
236 | jae .send |
233 | ; jae TCP_send |
237 | |
Line 234... | Line 238... | ||
234 | 238 | shl ebx, 1 |
|
Line 235... | Line 239... | ||
235 | ; cmp ebx, [eax + TCP_SOCKET.] ;;; TODO: check with receive buffer high water mark |
239 | ; cmp ebx, [eax + TCP_SOCKET.] ;;; TODO: check with receive buffer high water mark |
236 | ; jae TCP_send |
240 | ; jae TCP_send |
Line 237... | Line -... | ||
237 | - | ||
238 | .no_window: |
- | |
239 | 241 | ||
240 | ;-------------------------- |
242 | .no_window: |
Line 241... | Line 243... | ||
241 | ; Should a segment be sent? (174) |
243 | |
242 | 244 | ;-------------------------- |
|
Line 243... | Line 245... | ||
243 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: 174\n" |
245 | ; Should a segment be sent? (174) |
244 | 246 | ||
245 | test [eax + TCP_SOCKET.t_flags], TF_ACKNOW ; we need to ACK |
247 | test [eax + TCP_SOCKET.t_flags], TF_ACKNOW ; we need to ACK |
Line 246... | Line 248... | ||
246 | jnz TCP_send |
248 | jnz .send |
247 | 249 | ||
Line 248... | Line 250... | ||
248 | test dl, TH_SYN + TH_RST ; we need to send a SYN or RST |
250 | test dl, TH_SYN + TH_RST ; we need to send a SYN or RST |
Line 249... | Line 251... | ||
249 | jnz TCP_send |
251 | jnz .send |
250 | 252 | ||
Line 251... | Line 253... | ||
251 | mov ebx, [eax + TCP_SOCKET.SND_UP] ; when urgent pointer is beyond start of send bufer |
253 | mov ebx, [eax + TCP_SOCKET.SND_UP] ; when urgent pointer is beyond start of send bufer |
252 | cmp ebx, [eax + TCP_SOCKET.SND_UNA] |
254 | cmp ebx, [eax + TCP_SOCKET.SND_UNA] |
253 | ja TCP_send |
255 | ja .send |
Line 254... | Line 256... | ||
254 | 256 | ||
255 | test dl, TH_FIN |
257 | test dl, TH_FIN |
Line 256... | Line 258... | ||
256 | jz .enter_persist ; no reason to send, enter persist state |
258 | jz .enter_persist ; no reason to send, enter persist state |
Line 296... | Line 298... | ||
296 | ; Fixme: returnvalue? |
298 | ; Fixme: returnvalue? |
Line 297... | Line 299... | ||
297 | 299 | ||
Line 298... | Line -... | ||
298 | ret |
- | |
299 | - | ||
300 | - | ||
301 | - | ||
302 | - | ||
303 | - | ||
304 | - | ||
305 | 300 | ret |
|
306 | 301 | ||
307 | 302 | ||
308 | ;----------------------------------------------- |
303 | ;----------------------------------------------- |
309 | ; |
304 | ; |
310 | ; Send a segment (222) |
305 | ; Send a segment (222) |
311 | ; |
306 | ; |
312 | ; eax = socket pointer |
307 | ; eax = socket pointer |
313 | ; esi = data len |
308 | ; esi = data len |
314 | ; dl = flags |
- | |
315 | ; |
309 | ; dl = flags |
Line 316... | Line 310... | ||
316 | ;----------------------------------------------- |
310 | ; |
Line 317... | Line 311... | ||
317 | align 4 |
311 | ;----------------------------------------------- |
318 | TCP_send: |
312 | .send: |
Line 404... | Line 398... | ||
404 | add esi, edi ; total TCP segment size |
398 | add esi, edi ; total TCP segment size |
405 | cmp esi, [eax + TCP_SOCKET.t_maxseg] |
399 | cmp esi, [eax + TCP_SOCKET.t_maxseg] |
406 | jbe .no_overflow |
400 | jbe .no_overflow |
Line 407... | Line 401... | ||
407 | 401 | ||
408 | mov esi, [eax + TCP_SOCKET.t_maxseg] |
402 | mov esi, [eax + TCP_SOCKET.t_maxseg] |
409 | or [eax + TCP_SOCKET.temp_bits], TCP_BIT_SENDALOT |
403 | or [temp_bits], TCP_BIT_SENDALOT |
Line -... | Line 404... | ||
- | 404 | .no_overflow: |
|
- | 405 | ||
- | 406 | ;---------------------------------------------------- |
|
- | 407 | ; Calculate the receive window. |
|
- | 408 | ; Dont shrink window, but avoid silly window syndrome |
|
- | 409 | ||
- | 410 | mov ebx, SOCKET_MAXDATA |
|
- | 411 | sub ebx, [eax + STREAM_SOCKET.rcv.size] |
|
- | 412 | ||
- | 413 | cmp ebx, SOCKET_MAXDATA/4 |
|
- | 414 | jae @f |
|
- | 415 | cmp ebx, [eax + TCP_SOCKET.t_maxseg] |
|
- | 416 | jae @f |
|
- | 417 | xor ebx, ebx |
|
- | 418 | @@: |
|
- | 419 | ||
- | 420 | cmp ebx, TCP_max_win |
|
- | 421 | jbe @f |
|
- | 422 | mov ebx, TCP_max_win |
|
- | 423 | @@: |
|
- | 424 | ||
- | 425 | mov ecx, [eax + TCP_SOCKET.RCV_ADV] |
|
- | 426 | sub ecx, [eax + TCP_SOCKET.RCV_NXT] |
|
- | 427 | cmp ebx, ecx |
|
- | 428 | ja @f |
|
- | 429 | mov ebx, ecx |
|
- | 430 | @@: |
|
- | 431 | ||
- | 432 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: window = %u\n", ebx |
|
- | 433 | ||
- | 434 | mov cl, [eax + TCP_SOCKET.RCV_SCALE] |
|
- | 435 | shr ebx, cl |
|
410 | .no_overflow: |
436 | xchg bl, bh |
411 | 437 | ||
412 | ;----------------------------------------------------------------- |
438 | ;----------------------------------------------------------------- |
Line 413... | Line 439... | ||
413 | ; Start by pushing all TCP header values in reverse order on stack |
439 | ; Start by pushing all TCP header values in reverse order on stack |
414 | ; (essentially, creating the tcp header on the stack!) |
440 | ; (essentially, creating the tcp header on the stack!) |
415 | 441 | ||
416 | pushw 0 ; .UrgentPointer dw ? |
442 | pushw 0 ; .UrgentPointer dw ? |
417 | pushw 0 ; .Checksum dw ? |
443 | pushw 0 ; .Checksum dw ? |
418 | pushw 0x00a0 ; .Window dw ? ;;;;;;; FIXME (370) |
444 | pushw bx ; .Window dw ? |
419 | shl edi, 2 ; .DataOffset db ? only 4 left-most bits |
445 | shl edi, 2 ; .DataOffset db ? only 4 left-most bits |
420 | shl dx, 8 |
446 | shl dx, 8 |
Line 532... | Line 558... | ||
532 | .retransmit_set: |
558 | .retransmit_set: |
Line 533... | Line 559... | ||
533 | 559 | ||
534 | ;-------------------- |
560 | ;-------------------- |
Line -... | Line 561... | ||
- | 561 | ; Create the checksum |
|
- | 562 | ||
- | 563 | xor dx, dx |
|
- | 564 | test [ebx + NET_DEVICE.hwacc], NET_HWACC_TCP_IPv4_OUT |
|
535 | ; Create the checksum |
565 | jnz .checksum_ok |
- | 566 | ||
- | 567 | TCP_checksum (eax + IP_SOCKET.LocalIP), (eax + IP_SOCKET.RemoteIP) |
|
536 | 568 | ||
Line 537... | Line 569... | ||
537 | TCP_checksum (eax + IP_SOCKET.LocalIP), (eax + IP_SOCKET.RemoteIP) |
569 | .checksum_ok: |
538 | mov [esi + TCP_header.Checksum], dx |
570 | mov [esi + TCP_header.Checksum], dx |
Line 564... | Line 596... | ||
564 | 596 | ||
565 | ; update last ack sent |
597 | ; update last ack sent |
566 | push [eax + TCP_SOCKET.RCV_NXT] |
598 | push [eax + TCP_SOCKET.RCV_NXT] |
Line 567... | Line 599... | ||
567 | pop [eax + TCP_SOCKET.last_ack_sent] |
599 | pop [eax + TCP_SOCKET.last_ack_sent] |
568 | 600 | ||
Line 569... | Line 601... | ||
569 | ; and flags |
601 | ; clear the ACK flags |
570 | and [eax + TCP_SOCKET.t_flags], not (TF_ACKNOW + TF_DELACK) |
602 | and [eax + TCP_SOCKET.t_flags], not (TF_ACKNOW + TF_DELACK) |
Line 580... | Line 612... | ||
580 | pop eax |
612 | pop eax |
Line 581... | Line 613... | ||
581 | 613 | ||
582 | ;----------------------------- |
614 | ;----------------------------- |
Line 583... | Line 615... | ||
583 | ; Check if we need more output |
615 | ; Check if we need more output |
584 | 616 | ||
Line 585... | Line 617... | ||
585 | test [eax + TCP_SOCKET.temp_bits], TCP_BIT_SENDALOT |
617 | test [temp_bits], TCP_BIT_SENDALOT |
Line 586... | Line 618... | ||
586 | jnz TCP_output.again |
618 | jnz TCP_output.again |
Line 620... | Line 652... | ||
620 | 652 | ||
621 | or eax, -2 |
653 | or eax, -2 |
Line 622... | Line -... | ||
622 | ret><><<> |
- | |
623 | - | ||
624 | - | ||
625 | 654 | ret |
|
626 | 655 |