Rev 6413 | Rev 6710 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6413 | Rev 6476 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;; Part of the TCP/IP network stack for KolibriOS ;; |
6 | ;; Part of the TCP/IP network stack for KolibriOS ;; |
7 | ;; ;; |
7 | ;; ;; |
8 | ;; Written by hidnplayr@kolibrios.org ;; |
8 | ;; Written by hidnplayr@kolibrios.org ;; |
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 | ||
- | 19 | TCP_BIT_NEEDOUTPUT = 1 shl 0 |
|
- | 20 | TCP_BIT_TIMESTAMP = 1 shl 1 |
|
- | 21 | TCP_BIT_DROPSOCKET = 1 shl 2 |
|
Line 17... | Line 22... | ||
17 | $Revision: 6413 $ |
22 | TCP_BIT_FIN_IS_ACKED = 1 shl 3 |
18 | 23 | ||
19 | ;-----------------------------------------------------------------; |
24 | ;-----------------------------------------------------------------; |
20 | ; ; |
25 | ; ; |
Line 63... | Line 68... | ||
63 | add esp, sizeof.TCP_queue_entry - 4 |
68 | add esp, sizeof.TCP_queue_entry - 4 |
64 | call net_buff_free |
69 | call net_buff_free |
65 | ret |
70 | ret |
Line -... | Line 71... | ||
- | 71 | ||
- | 72 | ||
- | 73 | ;-----------------------------------------------------------------; |
|
- | 74 | ; ; |
|
- | 75 | ; TCP_process_input: Process segments from the incoming TCP queue.; |
|
- | 76 | ; ; |
|
66 | - | ||
- | 77 | ; IN: / ; |
|
- | 78 | ; OUT: / ; |
|
67 | 79 | ; ; |
|
68 | 80 | ;-----------------------------------------------------------------; |
|
Line 69... | Line 81... | ||
69 | align 4 |
81 | align 4 |
70 | proc tcp_process_input |
82 | proc tcp_process_input |
Line 99... | Line 111... | ||
99 | 111 | ||
Line 100... | Line 112... | ||
100 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: size=%u time=%d\n", ecx, [timer_ticks] |
112 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: size=%u time=%d\n", ecx, [timer_ticks] |
Line 101... | Line 113... | ||
101 | 113 | ||
102 | mov edx, esi |
- | |
Line 103... | Line -... | ||
103 | - | ||
104 | cmp ebx, LOOPBACK_DEVICE |
114 | mov edx, esi |
105 | je .checksum_ok |
115 | |
Line 106... | Line 116... | ||
106 | 116 | ; Verify the checksum (if not already done by hw) |
|
107 | ; re-calculate the checksum (if not already done by hw) |
117 | |
Line 117... | Line 127... | ||
117 | pop edx ecx |
127 | pop edx ecx |
118 | jne .drop_no_socket |
128 | jne .drop_no_socket |
119 | .checksum_ok: |
129 | .checksum_ok: |
Line 120... | Line 130... | ||
120 | 130 | ||
- | 131 | ; Verify the data offset |
|
121 | ; Verify the data offset |
132 | |
122 | movzx eax, [edx + TCP_header.DataOffset] |
133 | movzx eax, [edx + TCP_header.DataOffset] |
123 | and al, 0xf0 ; Calculate TCP segment header size (throwing away unused reserved bits in TCP header) |
134 | and al, 0xf0 ; Calculate TCP segment header size (throwing away unused reserved bits in TCP header) |
124 | shr al, 2 |
135 | shr al, 2 |
125 | cmp al, sizeof.TCP_header ; Now see if it's at least the size of a standard TCP header |
136 | cmp al, sizeof.TCP_header ; Now see if it's at least the size of a standard TCP header |
Line 137... | Line 148... | ||
137 | ntohd [edx + TCP_header.AckNumber] |
148 | ntohd [edx + TCP_header.AckNumber] |
Line 138... | Line 149... | ||
138 | 149 | ||
139 | ntohw [edx + TCP_header.Window] |
150 | ntohw [edx + TCP_header.Window] |
Line 140... | Line 151... | ||
140 | ntohw [edx + TCP_header.UrgentPointer] |
151 | ntohw [edx + TCP_header.UrgentPointer] |
- | 152 | ||
141 | 153 | ;----------------------------------------------------------------------------------- |
|
- | 154 | ; |
|
- | 155 | ; Find the socket pointer |
|
Line 142... | Line 156... | ||
142 | ;------------------------ |
156 | ; |
143 | ; Find the socket pointer |
157 | ;----------------------------------------------------------------------------------- |
144 | 158 | ||
Line 218... | Line 232... | ||
218 | mov cl, [ebx + TCP_SOCKET.SND_SCALE] |
232 | mov cl, [ebx + TCP_SOCKET.SND_SCALE] |
219 | shl eax, cl |
233 | shl eax, cl |
220 | mov dword [edx + TCP_header.Window], eax ; word after window is checksum, we dont need checksum anymore |
234 | mov dword[edx + TCP_header.Window], eax ; word after window is checksum, we dont need checksum anymore |
221 | pop ecx |
235 | pop ecx |
Line 222... | Line 236... | ||
222 | 236 | ||
- | 237 | ;----------------------------------------------------------------------------------- |
|
223 | ;--------------------------------------- |
238 | ; |
- | 239 | ; Accept incoming connections |
|
- | 240 | ; |
|
Line 224... | Line 241... | ||
224 | ; Are we accepting incoming connections? |
241 | ;----------------------------------------------------------------------------------- |
225 | 242 | ||
Line 226... | Line 243... | ||
226 | test [ebx + SOCKET.options], SO_ACCEPTCON |
243 | test [ebx + SOCKET.options], SO_ACCEPTCON |
Line -... | Line 244... | ||
- | 244 | jz .no_accept |
|
- | 245 | ||
227 | jz .no_accept |
246 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Accepting new connection\n" |
228 | 247 | ||
229 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Accepting new connection\n" |
248 | ; Unlock current socket |
230 | 249 | ||
Line -... | Line 250... | ||
- | 250 | pusha |
|
- | 251 | lea ecx, [ebx + SOCKET.mutex] |
|
231 | pusha |
252 | call mutex_unlock |
232 | lea ecx, [ebx + SOCKET.mutex] |
253 | popa |
233 | call mutex_unlock |
254 | |
Line 234... | Line 255... | ||
234 | popa |
255 | ; Fork it |
235 | 256 | ||
Line -... | Line 257... | ||
- | 257 | push ecx edx esi edi |
|
- | 258 | call socket_fork |
|
236 | push ecx edx esi edi |
259 | pop edi esi edx ecx |
Line 237... | Line 260... | ||
237 | call socket_fork |
260 | |
Line 238... | Line 261... | ||
238 | pop edi esi edx ecx |
261 | test eax, eax |
Line 259... | Line 282... | ||
259 | 282 | ||
260 | mov [ebx + TCP_SOCKET.t_idle], 0 |
283 | mov [ebx + TCP_SOCKET.t_idle], 0 |
261 | mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_idle |
284 | mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_idle |
Line 262... | Line 285... | ||
262 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_keepalive |
285 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_keepalive |
- | 286 | ||
263 | 287 | ;----------------------------------------------------------------------------------- |
|
- | 288 | ; |
|
- | 289 | ; Process TCP options |
|
Line 264... | Line 290... | ||
264 | ;-------------------- |
290 | ; |
265 | ; Process TCP options |
291 | ;----------------------------------------------------------------------------------- |
266 | 292 | ||
Line 393... | Line 419... | ||
393 | mov [ebx + TCP_SOCKET.ts_recent], 0 ; timestamp was invalid, fix it. |
419 | mov [ebx + TCP_SOCKET.ts_recent], 0 ; timestamp was invalid, fix it. |
394 | .no_paws: |
420 | .no_paws: |
395 | jmp .opt_loop |
421 | jmp .opt_loop |
Line 396... | Line 422... | ||
396 | 422 | ||
397 | .paws_drop: |
423 | .paws_drop: |
398 | inc [TCPS_rcvduppack] ; update stats |
424 | inc [TCPS_rcvduppack] |
399 | add [TCPS_rcvdupbyte], ecx |
425 | add [TCPS_rcvdupbyte], ecx |
400 | inc [TCPS_pawsdrop] |
426 | inc [TCPS_pawsdrop] |
Line 401... | Line 427... | ||
401 | jmp .drop_after_ack |
427 | jmp .drop_after_ack |
Line 402... | Line 428... | ||
402 | 428 | ||
Line 403... | Line 429... | ||
403 | .no_options: |
429 | .no_options: |
- | 430 | ||
- | 431 | pop ecx |
|
- | 432 | ||
404 | 433 | ;----------------------------------------------------------------------------------- |
|
Line 405... | Line 434... | ||
405 | pop ecx |
434 | ; |
406 | 435 | ; Header prediction |
|
407 | ;----------------------------------------------------------------------- |
436 | ; |
408 | ; Time to do some header prediction (Original Principle by Van Jacobson) |
437 | ;----------------------------------------------------------------------------------- |
409 | 438 | ||
410 | ; There are two common cases for an uni-directional data transfer. |
439 | ; According to Van Jacobson, there are two common cases for an uni-directional data transfer. |
Line 444... | Line 473... | ||
444 | ; check if we are sender in the uni-xfer |
473 | ; check if we are sender in the uni-xfer |
Line 445... | Line 474... | ||
445 | 474 | ||
446 | ; If the following 4 conditions are all true, this segment is a pure ACK. |
475 | ; If the following 4 conditions are all true, this segment is a pure ACK. |
447 | ; |
476 | ; |
- | 477 | ; - The segment contains no data. |
|
448 | ; - The segment contains no data. |
478 | |
449 | test ecx, ecx |
479 | test ecx, ecx |
Line 450... | Line 480... | ||
450 | jnz .not_sender |
480 | jnz .not_sender |
451 | 481 | ||
- | 482 | ; - The congestion window is greater than or equal to the current send window. |
|
452 | ; - The congestion window is greater than or equal to the current send window. |
483 | ; This test is true only if the window is fully open, that is, the connection is not in the middle of slow start or congestion avoidance. |
453 | ; This test is true only if the window is fully open, that is, the connection is not in the middle of slow start or congestion avoidance. |
484 | |
454 | mov eax, [ebx + TCP_SOCKET.SND_CWND] |
485 | mov eax, [ebx + TCP_SOCKET.SND_CWND] |
Line 455... | Line 486... | ||
455 | cmp eax, [ebx + TCP_SOCKET.SND_WND] |
486 | cmp eax, [ebx + TCP_SOCKET.SND_WND] |
- | 487 | jb .not_uni_xfer |
|
456 | jb .not_uni_xfer |
488 | |
457 | 489 | ; - The acknowledgment field in the segment is less than or equal to the maximum sequence number sent. |
|
458 | ; - The acknowledgment field in the segment is less than or equal to the maximum sequence number sent. |
490 | |
Line 459... | Line 491... | ||
459 | mov eax, [edx + TCP_header.AckNumber] |
491 | mov eax, [edx + TCP_header.AckNumber] |
- | 492 | cmp eax, [ebx + TCP_SOCKET.SND_MAX] |
|
460 | cmp eax, [ebx + TCP_SOCKET.SND_MAX] |
493 | ja .not_uni_xfer |
461 | ja .not_uni_xfer |
494 | |
Line 462... | Line 495... | ||
462 | 495 | ; - The acknowledgment field in the segment is greater than the largest unacknowledged sequence number. |
|
Line 463... | Line 496... | ||
463 | ; - The acknowledgment field in the segment is greater than the largest unacknowledged sequence number. |
496 | |
464 | sub eax, [ebx + TCP_SOCKET.SND_UNA] |
497 | sub eax, [ebx + TCP_SOCKET.SND_UNA] |
Line -... | Line 498... | ||
- | 498 | jbe .not_uni_xfer |
|
- | 499 | ||
- | 500 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Header prediction: we are sender\n" |
|
- | 501 | ||
- | 502 | ;--------------------------------- |
|
465 | jbe .not_uni_xfer |
503 | ; Packet is a pure ACK, process it |
- | 504 | ||
466 | 505 | inc [TCPS_predack] |
|
467 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Header prediction: we are sender\n" |
506 | |
468 | 507 | inc [TCPS_rcvackpack] |
|
469 | ;--------------------------------- |
508 | add [TCPS_rcvackbyte], eax |
470 | ; Packet is a pure ACK, process it |
509 | |
Line 495... | Line 534... | ||
495 | mov eax, [ebx + TCP_SOCKET.t_rtt] |
534 | mov eax, [ebx + TCP_SOCKET.t_rtt] |
496 | call tcp_xmit_timer |
535 | call tcp_xmit_timer |
497 | .rtt_done: |
536 | .rtt_done: |
Line 498... | Line 537... | ||
498 | 537 | ||
- | 538 | ; update window pointers |
|
499 | ; update window pointers |
539 | |
500 | mov eax, [edx + TCP_header.AckNumber] |
540 | mov eax, [edx + TCP_header.AckNumber] |
Line 501... | Line 541... | ||
501 | mov [ebx + TCP_SOCKET.SND_UNA], eax |
541 | mov [ebx + TCP_SOCKET.SND_UNA], eax |
- | 542 | ||
502 | 543 | ; Stop retransmit timer |
|
Line 503... | Line 544... | ||
503 | ; Stop retransmit timer |
544 | |
- | 545 | and [ebx + TCP_SOCKET.timer_flags], not timer_flag_retransmission |
|
504 | and [ebx + TCP_SOCKET.timer_flags], not timer_flag_retransmission |
546 | |
505 | 547 | ; Unlock the socket |
|
506 | ; Unlock the socket |
548 | |
507 | pusha |
549 | pusha |
Line 508... | Line 550... | ||
508 | lea ecx, [ebx + SOCKET.mutex] |
550 | lea ecx, [ebx + SOCKET.mutex] |
- | 551 | call mutex_unlock |
|
509 | call mutex_unlock |
552 | popa |
510 | popa |
553 | |
Line 511... | Line 554... | ||
511 | 554 | ; Awaken waiting processes |
|
- | 555 | ||
512 | ; Awaken waiting processes |
556 | mov eax, ebx |
Line 513... | Line 557... | ||
513 | mov eax, ebx |
557 | call socket_notify |
Line 514... | Line 558... | ||
514 | call socket_notify |
558 | |
515 | 559 | ; Generate more output |
|
Line 516... | Line 560... | ||
516 | ; Generate more output |
560 | |
517 | call tcp_output |
- | |
Line -... | Line 561... | ||
- | 561 | call tcp_output |
|
518 | 562 | ||
- | 563 | jmp .drop_no_socket |
|
519 | jmp .drop_no_socket |
564 | |
520 | 565 | ;------------------------------------------------- |
|
521 | ;------------------------------------------------- |
566 | ; maybe we are the receiver in the uni-xfer then.. |
Line 522... | Line 567... | ||
522 | ; maybe we are the receiver in the uni-xfer then.. |
567 | |
- | 568 | .not_sender: |
|
523 | 569 | ||
524 | .not_sender: |
570 | ; - The amount of data in the segment is greater than 0 (data count is in ecx) |
Line 525... | Line 571... | ||
525 | ; - The amount of data in the segment is greater than 0 (data count is in ecx) |
571 | ; - The acknowledgment field equals the largest unacknowledged sequence number. This means no data is acknowledged by this segment. |
Line 548... | Line 594... | ||
548 | 594 | ||
Line 549... | Line 595... | ||
549 | or [ebx + TCP_SOCKET.t_flags], TF_DELACK ; Set delayed ack flag |
595 | or [ebx + TCP_SOCKET.t_flags], TF_DELACK ; Set delayed ack flag |
Line 550... | Line -... | ||
550 | - | ||
551 | jmp .drop |
- | |
Line -... | Line 596... | ||
- | 596 | ||
- | 597 | jmp .drop |
|
552 | 598 | ||
- | 599 | ||
- | 600 | ;----------------------------------------------------------------------------------- |
|
Line -... | Line 601... | ||
- | 601 | ; |
|
553 | ;-------------------------------------------------- |
602 | ; TCP segment processing, the slow way |
Line 554... | Line 603... | ||
554 | ; Header prediction failed, do it the slow way |
603 | ; |
- | 604 | ;----------------------------------------------------------------------------------- |
|
555 | 605 | ||
556 | .not_uni_xfer: |
606 | .not_uni_xfer: |
557 | 607 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Header prediction failed\n" |
|
558 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Header prediction failed\n" |
608 | |
559 | 609 | ; Calculate receive window size |
|
Line 574... | Line 624... | ||
574 | pop edx |
624 | pop edx |
Line 575... | Line 625... | ||
575 | 625 | ||
Line 576... | Line 626... | ||
576 | ; If we are in listen or syn_sent state, go to that specific code right away |
626 | ; If we are in listen or syn_sent state, go to that specific code right away |
577 | 627 | ||
Line 578... | Line 628... | ||
578 | cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN |
628 | cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN |
579 | je .LISTEN |
629 | je .state_listen |
Line 580... | Line 630... | ||
580 | 630 | ||
- | 631 | cmp [ebx + TCP_SOCKET.t_state], TCPS_SYN_SENT |
|
581 | cmp [ebx + TCP_SOCKET.t_state], TCPS_SYN_SENT |
632 | je .state_syn_sent |
- | 633 | ||
- | 634 | ;----------------------------------------------------------------------------------- |
|
Line -... | Line 635... | ||
- | 635 | ; |
|
582 | je .SYN_SENT |
636 | ; Trim any data not in window |
Line 583... | Line 637... | ||
583 | 637 | ; |
|
- | 638 | ;----------------------------------------------------------------------------------- |
|
584 | ;---------------------------- |
639 | |
585 | ; trim any data not in window |
640 | ;------------------------------------------------- |
586 | 641 | ; Check for duplicate data at beginning of segment |
|
Line 587... | Line 642... | ||
587 | ; 1. Check for duplicate data at beginning of segment |
642 | |
Line -... | Line 643... | ||
- | 643 | ; Calculate number of bytes we need to drop |
|
- | 644 | ||
588 | 645 | mov eax, [ebx + TCP_SOCKET.RCV_NXT] |
|
589 | ; Calculate number of bytes we need to drop |
646 | sub eax, [edx + TCP_header.SequenceNumber] |
Line 590... | Line 647... | ||
590 | mov eax, [ebx + TCP_SOCKET.RCV_NXT] |
647 | jle .no_duplicate |
Line 609... | Line 666... | ||
609 | and [edx + TCP_header.Flags], not (TH_URG) |
666 | and [edx + TCP_header.Flags], not (TH_URG) |
610 | .dup_syn: |
667 | .dup_syn: |
611 | dec eax |
668 | dec eax |
612 | .no_dup_syn: |
669 | .no_dup_syn: |
Line -... | Line 670... | ||
- | 670 | ||
613 | 671 | ;----------------------------------- |
|
- | 672 | ; Check for entire duplicate segment |
|
614 | ; 2. Check for entire duplicate segment |
673 | |
615 | cmp eax, ecx ; eax holds number of bytes to drop, ecx is data size |
674 | cmp eax, ecx ; eax holds number of bytes to drop, ecx is data size |
616 | jb .duplicate |
675 | jb .no_complete_dup |
617 | jnz @f |
676 | jnz @f |
618 | test [edx + TCP_header.Flags], TH_FIN |
677 | test [edx + TCP_header.Flags], TH_FIN |
619 | jnz .duplicate |
678 | jnz .no_complete_dup |
Line 620... | Line 679... | ||
620 | @@: |
679 | @@: |
621 | 680 | ||
- | 681 | ; Any valid FIN must be to the left of the window. |
|
622 | ; Any valid FIN must be to the left of the window. |
682 | ; At this point the FIN must be out of sequence or a duplicate, drop it |
Line 623... | Line 683... | ||
623 | ; At this point the FIN must be out of sequence or a duplicate, drop it |
683 | |
624 | and [edx + TCP_header.Flags], not TH_FIN |
684 | and [edx + TCP_header.Flags], not TH_FIN |
- | 685 | ||
625 | 686 | ; send an ACK to resynchronize and drop any data. |
|
626 | ; send an ACK and resynchronize and drop any data. |
687 | ; But keep on processing for RST or ACK |
Line -... | Line 688... | ||
- | 688 | ||
- | 689 | or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
|
- | 690 | mov eax, ecx |
|
- | 691 | ||
627 | ; But keep on processing for RST or ACK |
692 | inc [TCPS_rcvduppack] |
628 | or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
- | |
- | 693 | add [TCPS_rcvdupbyte], eax |
|
629 | mov eax, ecx |
694 | jmp .dup_processed |
Line 630... | Line 695... | ||
630 | 695 | .no_complete_dup: |
|
631 | inc [TCPS_rcvpartduppack] |
696 | inc [TCPS_rcvpartduppack] |
Line 632... | Line -... | ||
632 | - | ||
633 | ;;; TODO: update stats |
697 | add [TCPS_rcvpartdupbyte], eax |
Line 634... | Line 698... | ||
634 | 698 | .dup_processed: |
|
- | 699 | ||
635 | ;----------------------------------------------- |
700 | ;----------------------------------------------- |
636 | ; Remove duplicate data and update urgent offset |
701 | ; Remove duplicate data and update urgent offset |
637 | 702 | ||
Line 638... | Line 703... | ||
638 | .duplicate: |
703 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: trimming duplicate data\n" |
639 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: trimming duplicate data\n" |
704 | |
640 | 705 | ; Trim data from left side of window |
|
641 | ; Trim data from left side of window |
706 | |
642 | add [dataoffset], eax |
707 | add [dataoffset], eax |
- | 708 | add [edx + TCP_header.SequenceNumber], eax |
|
Line 643... | Line 709... | ||
643 | add [edx + TCP_header.SequenceNumber], eax |
709 | sub ecx, eax |
644 | sub ecx, eax |
710 | |
Line 645... | Line -... | ||
645 | - | ||
646 | sub [edx + TCP_header.UrgentPointer], ax |
711 | sub [edx + TCP_header.UrgentPointer], ax |
647 | jg @f |
712 | jg @f |
648 | and [edx + TCP_header.Flags], not (TH_URG) |
713 | and [edx + TCP_header.Flags], not (TH_URG) |
649 | mov [edx + TCP_header.UrgentPointer], 0 |
714 | mov [edx + TCP_header.UrgentPointer], 0 |
650 | @@: |
715 | @@: |
Line 662... | Line 727... | ||
662 | 727 | ||
663 | mov eax, ebx |
728 | mov eax, ebx |
664 | call tcp_close |
729 | call tcp_close |
665 | inc [TCPS_rcvafterclose] |
730 | inc [TCPS_rcvafterclose] |
- | 731 | jmp .respond_seg_reset |
|
Line 666... | Line 732... | ||
666 | jmp .respond_seg_reset |
732 | .not_terminated: |
667 | 733 | ||
Line 668... | Line -... | ||
668 | ;---------------------------------------- |
- | |
669 | ; Remove data beyond right edge of window |
734 | ;---------------------------------------- |
670 | 735 | ; Remove data beyond right edge of window |
|
671 | .not_terminated: |
736 | |
672 | mov eax, [edx + TCP_header.SequenceNumber] |
737 | mov eax, [edx + TCP_header.SequenceNumber] |
673 | add eax, ecx |
738 | add eax, ecx |
Line 674... | Line 739... | ||
674 | sub eax, [ebx + TCP_SOCKET.RCV_NXT] |
739 | sub eax, [ebx + TCP_SOCKET.RCV_NXT] |
Line 675... | Line 740... | ||
675 | sub eax, [ebx + TCP_SOCKET.RCV_WND] ; eax now holds the number of bytes to drop |
740 | sub eax, [ebx + TCP_SOCKET.RCV_WND] ; eax now holds the number of bytes to drop |
- | 741 | jle .no_excess_data |
|
676 | jle .no_excess_data |
742 | |
677 | 743 | DEBUGF DEBUG_NETWORK_VERBOSE, "%d bytes beyond right edge of window\n", eax |
|
- | 744 | ||
- | 745 | inc [TCPS_rcvpackafterwin] |
|
- | 746 | ||
- | 747 | cmp eax, ecx |
|
678 | DEBUGF DEBUG_NETWORK_VERBOSE, "%d bytes beyond right edge of window\n", eax |
748 | jl .dont_drop_all |
679 | 749 | ||
Line 680... | Line 750... | ||
680 | ;;; TODO: update stats |
750 | add [TCPS_rcvbyteafterwin], ecx |
681 | cmp eax, ecx |
751 | |
682 | jl .dont_drop_all |
752 | ;---------------------------------------------------------------------------------------------------- |
683 | ; If a new connection request is received while in TIME_WAIT, drop the old connection and start over, |
753 | ; If a new connection request is received while in TIME_WAIT, drop the old connection and start over, |
684 | ; if the sequence numbers are above the previous ones |
754 | ; if the sequence numbers are above the previous ones |
685 | 755 | ||
686 | test [edx + TCP_header.Flags], TH_SYN |
756 | test [edx + TCP_header.Flags], TH_SYN |
687 | jz .no_new_request |
757 | jz .no_new_request |
Line 703... | Line 773... | ||
703 | mov esi, [edx + TCP_header.SequenceNumber] |
773 | mov esi, [edx + TCP_header.SequenceNumber] |
704 | cmp esi, [ebx + TCP_SOCKET.RCV_NXT] |
774 | cmp esi, [ebx + TCP_SOCKET.RCV_NXT] |
705 | jne .drop_after_ack |
775 | jne .drop_after_ack |
Line 706... | Line 776... | ||
706 | 776 | ||
707 | or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
777 | or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
708 | ;;; TODO: update stats |
778 | inc [TCPS_rcvwinprobe] |
709 | .dont_drop_all: |
779 | .dont_drop_all: |
710 | ;;; TODO: update stats |
780 | add [TCPS_rcvbyteafterwin], eax |
- | 781 | DEBUGF DEBUG_NETWORK_VERBOSE, "Trimming %u bytes from the right of the window\n" |
|
711 | DEBUGF DEBUG_NETWORK_VERBOSE, "Trimming %u bytes from the right of the window\n" |
782 | |
- | 783 | ; remove data from the right side of window (decrease data length) |
|
- | 784 | ||
712 | sub ecx, eax ; remove data from the right side of window (decrease data length) |
785 | sub ecx, eax |
713 | and [edx + TCP_header.Flags], not (TH_PUSH or TH_FIN) |
786 | and [edx + TCP_header.Flags], not (TH_PUSH or TH_FIN) |
Line 714... | Line 787... | ||
714 | .no_excess_data: |
787 | .no_excess_data: |
- | 788 | ||
715 | 789 | ;----------------------------------------------------------------------------------- |
|
- | 790 | ; |
|
- | 791 | ; Record timestamp |
|
Line 716... | Line 792... | ||
716 | ;----------------- |
792 | ; |
- | 793 | ;----------------------------------------------------------------------------------- |
|
717 | ; Record timestamp |
794 | |
718 | 795 | ; If last ACK falls within this segments sequence numbers, record its timestamp |
|
719 | ; If last ACK falls within this segments sequence numbers, record its timestamp |
796 | |
720 | test [temp_bits], TCP_BIT_TIMESTAMP |
797 | test [temp_bits], TCP_BIT_TIMESTAMP |
721 | jz .no_timestamp |
798 | jz .no_timestamp |
722 | mov eax, [ebx + TCP_SOCKET.last_ack_sent] |
799 | mov eax, [ebx + TCP_SOCKET.last_ack_sent] |
723 | sub eax, [edx + TCP_header.SequenceNumber] |
800 | sub eax, [edx + TCP_header.SequenceNumber] |
724 | jb .no_timestamp |
801 | jb .no_timestamp |
725 | test [ebx + TCP_header.Flags], TH_SYN or TH_FIN ; syn and fin occupy one byte |
802 | test [edx + TCP_header.Flags], TH_SYN or TH_FIN ; SYN and FIN occupy one byte |
726 | jz @f |
803 | jz @f |
727 | dec eax |
804 | dec eax |
Line 735... | Line 812... | ||
735 | mov [ebx + TCP_SOCKET.ts_recent_age], eax |
812 | mov [ebx + TCP_SOCKET.ts_recent_age], eax |
736 | mov eax, [ebx + TCP_SOCKET.ts_val] |
813 | mov eax, [ebx + TCP_SOCKET.ts_val] |
737 | mov [ebx + TCP_SOCKET.ts_recent], eax |
814 | mov [ebx + TCP_SOCKET.ts_recent], eax |
738 | .no_timestamp: |
815 | .no_timestamp: |
Line 739... | Line 816... | ||
739 | 816 | ||
- | 817 | ;----------------------------------------------------------------------------------- |
|
740 | ;------------------ |
818 | ; |
- | 819 | ; Process RST flag |
|
- | 820 | ; |
|
Line 741... | Line 821... | ||
741 | ; Process RST flags |
821 | ;----------------------------------------------------------------------------------- |
742 | 822 | ||
Line 743... | Line 823... | ||
743 | test [edx + TCP_header.Flags], TH_RST |
823 | test [edx + TCP_header.Flags], TH_RST |
Line 744... | Line 824... | ||
744 | jz .no_rst |
824 | jz .no_rst |
745 | 825 | ||
746 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Got an RST flag\n" |
826 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Got an RST flag\n" |
Line -... | Line 827... | ||
- | 827 | ||
747 | 828 | mov eax, [ebx + TCP_SOCKET.t_state] |
|
748 | mov eax, [ebx + TCP_SOCKET.t_state] |
829 | shl eax, 2 |
749 | shl eax, 2 |
830 | jmp dword [eax + .rst_sw_list] |
750 | jmp dword [eax + .rst_sw_list] |
831 | |
751 | 832 | ;----------------------------------------------------------------------------------- |
|
Line 758... | Line 839... | ||
758 | dd .econnreset ; TCPS_CLOSE_WAIT |
839 | dd .econnreset ; TCPS_CLOSE_WAIT |
759 | dd .econnreset ; TCPS_FIN_WAIT_1 |
840 | dd .econnreset ; TCPS_FIN_WAIT_1 |
760 | dd .rst_close ; TCPS_CLOSING |
841 | dd .rst_close ; TCPS_CLOSING |
761 | dd .rst_close ; TCPS_LAST_ACK |
842 | dd .rst_close ; TCPS_LAST_ACK |
762 | dd .econnreset ; TCPS_FIN_WAIT_2 |
843 | dd .econnreset ; TCPS_FIN_WAIT_2 |
763 | dd .rst_close ; TCPS_TIMED_WAIT |
844 | dd .rst_close ; TCPS_TIME_WAIT |
Line -... | Line 845... | ||
- | 845 | ||
764 | 846 | ;----------------------------------------------------------------------------------- |
|
765 | .econnrefused: |
847 | .econnrefused: |
766 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Connection refused\n" |
- | |
767 | 848 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Connection refused\n" |
|
768 | mov [ebx + SOCKET.errorcode], ECONNREFUSED |
849 | mov [ebx + SOCKET.errorcode], ECONNREFUSED |
Line -... | Line 850... | ||
- | 850 | jmp .close |
|
769 | jmp .close |
851 | |
770 | 852 | ;----------------------------------------------------------------------------------- |
|
771 | .econnreset: |
- | |
772 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Connection reset\n" |
853 | .econnreset: |
773 | - | ||
774 | mov [ebx + SOCKET.errorcode], ECONNRESET |
854 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Connection reset\n" |
775 | 855 | mov [ebx + SOCKET.errorcode], ECONNRESET |
|
776 | .close: |
- | |
777 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Closing connection\n" |
856 | .close: |
778 | 857 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Closing connection\n" |
|
- | 858 | mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSED |
|
- | 859 | inc [TCPS_drops] |
|
779 | mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSED |
860 | |
780 | ;;; TODO: update stats (tcp drops) |
861 | |
781 | mov eax, ebx |
862 | mov eax, ebx |
Line -... | Line 863... | ||
- | 863 | call tcp_close |
|
782 | call tcp_close |
864 | jmp .drop_no_socket |
783 | jmp .drop_no_socket |
865 | |
Line 784... | Line 866... | ||
784 | 866 | ;----------------------------------------------------------------------------------- |
|
785 | .rst_close: |
867 | .rst_close: |
786 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Closing with reset\n" |
868 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Closing with reset\n" |
Line -... | Line 869... | ||
- | 869 | ||
787 | 870 | mov eax, ebx |
|
Line 788... | Line 871... | ||
788 | mov eax, ebx |
871 | call tcp_close |
- | 872 | jmp .drop_no_socket |
|
789 | call tcp_close |
873 | |
- | 874 | ;----------------------------------------------------------------------------------- |
|
- | 875 | .no_rst: |
|
- | 876 | ||
- | 877 | ;----------------------------------------------------------------------------------- |
|
Line 790... | Line 878... | ||
790 | jmp .drop_no_socket |
878 | ; |
791 | 879 | ; Handle SYN-full and ACK-less segments |
|
Line 792... | Line 880... | ||
792 | .no_rst: |
880 | ; |
793 | 881 | ;----------------------------------------------------------------------------------- |
|
794 | ;-------------------------------------- |
882 | |
795 | ; handle SYN-full and ACK-less segments |
883 | ; If a SYN is in the window, then this is an error so we send an RST and drop the connection |
796 | 884 | ||
Line 797... | Line -... | ||
797 | test [edx + TCP_header.Flags], TH_SYN |
- | |
798 | jz .not_syn_full |
885 | test [edx + TCP_header.Flags], TH_SYN |
Line 799... | Line 886... | ||
799 | 886 | jz .not_syn_full |
|
800 | mov eax, ebx |
887 | |
Line -... | Line 888... | ||
- | 888 | mov eax, ebx |
|
- | 889 | mov ebx, ECONNRESET |
|
- | 890 | call tcp_drop |
|
- | 891 | jmp .drop_with_reset |
|
- | 892 | .not_syn_full: |
|
- | 893 | ||
801 | mov ebx, ECONNRESET |
894 | ; If ACK bit is off, we drop the segment and return |
802 | call tcp_drop |
895 | |
803 | jmp .drop_with_reset |
896 | test [edx + TCP_header.Flags], TH_ACK |
Line 804... | Line 897... | ||
804 | .not_syn_full: |
897 | jz .drop |
Line 819... | Line 912... | ||
819 | cmp [ebx + TCP_SOCKET.SND_UNA], eax |
912 | cmp [ebx + TCP_SOCKET.SND_UNA], eax |
820 | ja .drop_with_reset |
913 | ja .drop_with_reset |
821 | cmp eax, [ebx + TCP_SOCKET.SND_MAX] |
914 | cmp eax, [ebx + TCP_SOCKET.SND_MAX] |
822 | ja .drop_with_reset |
915 | ja .drop_with_reset |
Line 823... | Line 916... | ||
823 | 916 | ||
Line 824... | Line 917... | ||
824 | ;;; TODO: update stats |
917 | inc [TCPS_connects] |
825 | 918 | ||
826 | mov eax, ebx |
919 | mov eax, ebx |
Line 841... | Line 934... | ||
841 | call tcp_reassemble |
934 | call tcp_reassemble |
Line 842... | Line 935... | ||
842 | 935 | ||
843 | mov eax, [edx + TCP_header.SequenceNumber] |
936 | mov eax, [edx + TCP_header.SequenceNumber] |
844 | dec eax |
937 | dec eax |
845 | mov [ebx + TCP_SOCKET.SND_WL1], eax |
- | |
846 | 938 | mov [ebx + TCP_SOCKET.SND_WL1], eax |
|
Line -... | Line 939... | ||
- | 939 | .no_syn_rcv: |
|
- | 940 | ||
- | 941 | ;----------------------------------------------------------------------------------- |
|
- | 942 | ; |
|
- | 943 | ; ACK processing for SYN_RECEIVED state and higher |
|
- | 944 | ; |
|
847 | .no_syn_rcv: |
945 | ;----------------------------------------------------------------------------------- |
848 | 946 | ||
Line 849... | Line 947... | ||
849 | ;------------------------- |
947 | ;------------------------- |
850 | ; check for duplicate ACKs |
948 | ; Check for duplicate ACKs |
851 | 949 | ||
Line 852... | Line 950... | ||
852 | mov eax, [edx + TCP_header.AckNumber] |
950 | mov eax, [edx + TCP_header.AckNumber] |
853 | cmp eax, [ebx + TCP_SOCKET.SND_UNA] |
951 | cmp eax, [ebx + TCP_SOCKET.SND_UNA] |
Line 854... | Line 952... | ||
854 | ja .not_dup_ack |
952 | ja .dup_ack_complete |
855 | 953 | ||
856 | test ecx, ecx |
954 | test ecx, ecx |
Line -... | Line 955... | ||
- | 955 | jnz .reset_dupacks |
|
857 | jnz .reset_dupacks |
956 | |
Line 858... | Line 957... | ||
858 | 957 | mov eax, dword[edx + TCP_header.Window] |
|
859 | mov eax, dword [edx + TCP_header.Window] |
958 | cmp eax, [ebx + TCP_SOCKET.SND_WND] |
860 | cmp eax, [ebx + TCP_SOCKET.SND_WND] |
959 | jne .reset_dupacks |
Line 861... | Line 960... | ||
861 | jne .reset_dupacks |
960 | |
862 | 961 | inc [TCPS_rcvdupack] |
|
Line 863... | Line 962... | ||
863 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Processing duplicate ACK\n" |
962 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Processing duplicate ACK\n" |
864 | 963 | ||
865 | ; If we have outstanding data, other than a window probe, this is a completely duplicate ACK |
964 | ; If we have outstanding data, other than a window probe, this is a completely duplicate ACK |
Line 866... | Line -... | ||
866 | ; (window info didnt change) The ACK is the biggest we've seen and we've seen exactly our rexmt threshold of them, |
- | |
867 | ; assume a packet has been dropped and retransmit it. Kludge snd_nxt & the congestion window so we send only this one packet. |
965 | ; (window info didnt change) The ACK is the biggest we've seen and we've seen exactly our rexmt threshold of them, |
868 | 966 | ; assume a packet has been dropped and retransmit it. Kludge snd_nxt & the congestion window so we send only this one packet. |
|
Line 869... | Line -... | ||
869 | test [ebx + TCP_SOCKET.timer_flags], timer_flag_retransmission |
- | |
870 | jz @f |
967 | |
871 | 968 | test [ebx + TCP_SOCKET.timer_flags], timer_flag_retransmission |
|
- | 969 | jz .reset_dupacks |
|
872 | mov eax, [edx + TCP_header.AckNumber] |
970 | |
- | 971 | mov eax, [edx + TCP_header.AckNumber] |
|
- | 972 | cmp eax, [ebx + TCP_SOCKET.SND_UNA] |
|
Line 873... | Line 973... | ||
873 | cmp eax, [ebx + TCP_SOCKET.SND_UNA] |
973 | jne .reset_dupacks |
Line 874... | Line 974... | ||
874 | je .dup_ack |
974 | |
875 | 975 | ; Increment dupplicat ACK counter |
|
Line 908... | Line 1008... | ||
908 | mov [ebx + TCP_SOCKET.SND_NXT], eax |
1008 | mov [ebx + TCP_SOCKET.SND_NXT], eax |
909 | mov eax, [ebx + TCP_SOCKET.t_maxseg] |
1009 | mov eax, [ebx + TCP_SOCKET.t_maxseg] |
910 | mov [ebx + TCP_SOCKET.SND_CWND], eax |
1010 | mov [ebx + TCP_SOCKET.SND_CWND], eax |
Line 911... | Line 1011... | ||
911 | 1011 | ||
- | 1012 | ; Unlock the socket |
|
912 | ; Unlock the socket |
1013 | |
913 | push ebx |
1014 | push ebx |
914 | lea ecx, [ebx + SOCKET.mutex] |
1015 | lea ecx, [ebx + SOCKET.mutex] |
Line 915... | Line 1016... | ||
915 | call mutex_unlock |
1016 | call mutex_unlock |
- | 1017 | ||
916 | 1018 | ; retransmit missing segment |
|
917 | ; retransmit missing segment |
1019 | |
Line 918... | Line 1020... | ||
918 | mov eax, [esp] |
1020 | mov eax, [esp] |
- | 1021 | call tcp_output |
|
919 | call tcp_output |
1022 | |
920 | 1023 | ; Lock the socket again |
|
921 | ; Lock the socket again |
1024 | |
922 | mov ecx, [esp] |
1025 | mov ecx, [esp] |
Line 923... | Line 1026... | ||
923 | add ecx, SOCKET.mutex |
1026 | add ecx, SOCKET.mutex |
- | 1027 | call mutex_lock |
|
924 | call mutex_lock |
1028 | pop ebx |
925 | pop ebx |
1029 | |
926 | 1030 | ; Continue processing |
|
927 | ; Continue processing |
1031 | |
928 | xor edx, edx |
1032 | xor edx, edx |
Line 934... | Line 1038... | ||
934 | pop eax ; <<<< |
1038 | pop eax ; <<<< |
935 | cmp eax, [ebx + TCP_SOCKET.SND_NXT] |
1039 | cmp eax, [ebx + TCP_SOCKET.SND_NXT] |
936 | jb @f |
1040 | jb @f |
937 | mov [ebx + TCP_SOCKET.SND_NXT], eax |
1041 | mov [ebx + TCP_SOCKET.SND_NXT], eax |
938 | @@: |
1042 | @@: |
939 | - | ||
940 | jmp .drop |
1043 | jmp .drop |
Line 941... | Line -... | ||
941 | - | ||
942 | 1044 | ||
943 | .no_re_xmit: |
- | |
944 | jbe .not_dup_ack |
- | |
945 | 1045 | .another_lost: |
|
Line 946... | Line 1046... | ||
946 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Increasing congestion window\n" |
1046 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Increasing congestion window\n" |
947 | 1047 | ||
Line 948... | Line 1048... | ||
948 | mov eax, [ebx + TCP_SOCKET.t_maxseg] |
1048 | mov eax, [ebx + TCP_SOCKET.t_maxseg] |
- | 1049 | add [ebx + TCP_SOCKET.SND_CWND], eax |
|
949 | add [ebx + TCP_SOCKET.SND_CWND], eax |
1050 | |
950 | 1051 | ; Unlock the socket |
|
951 | ; Unlock the socket |
1052 | |
Line 952... | Line 1053... | ||
952 | push ebx |
1053 | push ebx |
- | 1054 | lea ecx, [ebx + SOCKET.mutex] |
|
953 | lea ecx, [ebx + SOCKET.mutex] |
1055 | call mutex_unlock |
954 | call mutex_unlock |
1056 | |
Line 955... | Line 1057... | ||
955 | 1057 | ; retransmit missing segment, again |
|
- | 1058 | ||
956 | ; retransmit missing segment |
1059 | mov eax, [esp] |
957 | mov eax, [esp] |
1060 | call tcp_output |
958 | call tcp_output |
1061 | |
959 | 1062 | ; Lock the socket again |
|
Line -... | Line 1063... | ||
- | 1063 | ||
- | 1064 | mov ecx, [esp] |
|
960 | ; Lock the socket again |
1065 | add ecx, SOCKET.mutex |
Line -... | Line 1066... | ||
- | 1066 | call mutex_lock |
|
- | 1067 | pop ebx |
|
- | 1068 | ||
Line 961... | Line 1069... | ||
961 | mov ecx, [esp] |
1069 | ; And drop the incoming segment |
Line 962... | Line 1070... | ||
962 | add ecx, SOCKET.mutex |
1070 | |
963 | call mutex_lock |
1071 | jmp .drop |
964 | pop ebx |
1072 | |
Line 993... | Line 1101... | ||
993 | sub edi, [ebx + TCP_SOCKET.SND_UNA] ; now we got the number of acked bytes in edi |
1101 | sub edi, [ebx + TCP_SOCKET.SND_UNA] ; now we got the number of acked bytes in edi |
994 | inc [TCPS_rcvackpack] |
1102 | inc [TCPS_rcvackpack] |
995 | add [TCPS_rcvackbyte], edi |
1103 | add [TCPS_rcvackbyte], edi |
996 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: acceptable ACK for %u bytes\n", edi |
1104 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: acceptable ACK for %u bytes\n", edi |
Line 997... | Line 1105... | ||
997 | 1105 | ||
- | 1106 | ;----------------------------------------------------------------------------------- |
|
998 | ;------------------------------------------ |
1107 | ; |
- | 1108 | ; RTT measurements and retransmission timer |
|
- | 1109 | ; |
|
Line 999... | Line 1110... | ||
999 | ; RTT measurements and retransmission timer |
1110 | ;----------------------------------------------------------------------------------- |
Line 1000... | Line 1111... | ||
1000 | 1111 | ||
1001 | ; If we have a timestamp, update smoothed RTT |
1112 | ; If we have a timestamp, update smoothed RTT |
Line 1019... | Line 1130... | ||
1019 | jbe .rtt_done_ |
1130 | jbe .rtt_done_ |
1020 | mov eax, [ebx + TCP_SOCKET.t_rtt] |
1131 | mov eax, [ebx + TCP_SOCKET.t_rtt] |
1021 | test eax, eax |
1132 | test eax, eax |
1022 | jz .rtt_done_ |
1133 | jz .rtt_done_ |
1023 | call tcp_xmit_timer |
1134 | call tcp_xmit_timer |
1024 | - | ||
1025 | .rtt_done_: |
1135 | .rtt_done_: |
Line 1026... | Line 1136... | ||
1026 | 1136 | ||
1027 | ; If all outstanding data is acked, stop retransmit timer and remember to restart (more output or persist) |
1137 | ; If all outstanding data is acked, stop retransmit timer and remember to restart (more output or persist) |
Line 1040... | Line 1150... | ||
1040 | mov eax, [ebx + TCP_SOCKET.t_rxtcur] |
1150 | mov eax, [ebx + TCP_SOCKET.t_rxtcur] |
1041 | mov [ebx + TCP_SOCKET.timer_retransmission], eax |
1151 | mov [ebx + TCP_SOCKET.timer_retransmission], eax |
1042 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_retransmission |
1152 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_retransmission |
1043 | .no_restart: |
1153 | .no_restart: |
Line -... | Line 1154... | ||
- | 1154 | ||
1044 | 1155 | ;----------------------------------------------------------------------------------- |
|
1045 | - | ||
1046 | ;------------------------------------------- |
1156 | ; |
- | 1157 | ; Open congestion window in response to ACKs |
|
- | 1158 | ; |
|
- | 1159 | ;----------------------------------------------------------------------------------- |
|
- | 1160 | ||
- | 1161 | ; If the window gives us less then sstresh packets in flight, open exponentially. |
|
Line 1047... | Line 1162... | ||
1047 | ; Open congestion window in response to ACKs |
1162 | ; Otherwise, open lineary |
1048 | 1163 | ||
1049 | mov esi, [ebx + TCP_SOCKET.SND_CWND] |
- | |
1050 | mov eax, [ebx + TCP_SOCKET.t_maxseg] |
1164 | mov esi, [ebx + TCP_SOCKET.SND_CWND] |
1051 | 1165 | mov eax, [ebx + TCP_SOCKET.t_maxseg] |
|
1052 | cmp esi, [ebx + TCP_SOCKET.SND_SSTHRESH] |
1166 | cmp esi, [ebx + TCP_SOCKET.SND_SSTHRESH] |
1053 | jbe @f |
1167 | jbe @f |
1054 | push edx |
1168 | push edx |
1055 | push eax |
1169 | push eax |
1056 | mul eax |
1170 | mul eax ; t_maxseg*t_maxseg |
1057 | div esi |
1171 | div esi ; t_maxseg*t_maxseg/snd_cwnd |
1058 | pop edx |
1172 | pop edx ; t_maxseg |
1059 | shr edx, 3 |
1173 | shr edx, 3 ; t_maxseg/8 |
1060 | add eax, edx |
1174 | add eax, edx ; t_maxseg*t_maxseg/snd_cwnd + t_maxseg/8 |
1061 | pop edx |
- | |
1062 | @@: |
1175 | pop edx |
Line 1063... | Line 1176... | ||
1063 | 1176 | @@: |
|
1064 | add esi, eax |
1177 | add esi, eax |
1065 | 1178 | ||
Line 1073... | Line 1186... | ||
1073 | jbe @f |
1186 | jbe @f |
1074 | mov esi, eax |
1187 | mov esi, eax |
1075 | @@: |
1188 | @@: |
1076 | mov [ebx + TCP_SOCKET.SND_CWND], esi |
1189 | mov [ebx + TCP_SOCKET.SND_CWND], esi |
Line 1077... | Line 1190... | ||
1077 | 1190 | ||
- | 1191 | ;----------------------------------------------------------------------------------- |
|
1078 | ;------------------------------------------ |
1192 | ; |
- | 1193 | ; Remove acknowledged data from send buffer |
|
- | 1194 | ; |
|
- | 1195 | ;----------------------------------------------------------------------------------- |
|
- | 1196 | ||
- | 1197 | ; If the number of bytes acknowledged exceeds the number of bytes on the send buffer, |
|
- | 1198 | ; snd_wnd is decremented by the number of bytes in the send buffer and TCP knows |
|
Line 1079... | Line 1199... | ||
1079 | ; Remove acknowledged data from send buffer |
1199 | ; that its FIN has been ACKed. (FIN occupies 1 byte in the sequence number space) |
1080 | 1200 | ||
- | 1201 | cmp edi, [ebx + STREAM_SOCKET.snd.size] |
|
- | 1202 | jbe .no_fin_ack |
|
Line 1081... | Line 1203... | ||
1081 | cmp edi, [ebx + STREAM_SOCKET.snd.size] |
1203 | |
1082 | jbe .finiacked |
1204 | ; Drop all data in output buffer |
1083 | - | ||
1084 | push ecx edx ebx |
1205 | |
- | 1206 | push ecx edx ebx |
|
1085 | mov ecx, [ebx + STREAM_SOCKET.snd.size] |
1207 | mov ecx, [ebx + STREAM_SOCKET.snd.size] |
1086 | lea eax, [ebx + STREAM_SOCKET.snd] |
1208 | sub [ebx + TCP_SOCKET.SND_WND], ecx |
Line 1087... | Line 1209... | ||
1087 | sub [ebx + TCP_SOCKET.SND_WND], ecx |
1209 | lea eax, [ebx + STREAM_SOCKET.snd] |
1088 | call socket_ring_free |
1210 | call socket_ring_free |
1089 | pop ebx edx ecx |
1211 | pop ebx edx ecx |
- | 1212 | ||
Line 1090... | Line 1213... | ||
1090 | 1213 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: our FIN is acked\n" |
|
Line 1091... | Line 1214... | ||
1091 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: our FIN is acked\n" |
1214 | or [temp_bits], TCP_BIT_FIN_IS_ACKED |
1092 | or [temp_bits], TCP_BIT_FIN_IS_ACKED |
1215 | jmp .ack_complete |
1093 | jmp .wakeup |
1216 | .no_fin_ack: |
1094 | 1217 | ||
1095 | .finiacked: |
1218 | ; Drop acknowledged data |
1096 | 1219 | ||
1097 | push ecx edx ebx |
1220 | push ecx edx ebx |
- | 1221 | mov ecx, edi |
|
Line 1098... | Line 1222... | ||
1098 | mov ecx, edi |
1222 | lea eax, [ebx + STREAM_SOCKET.snd] |
1099 | lea eax, [ebx + STREAM_SOCKET.snd] |
1223 | call socket_ring_free |
1100 | call socket_ring_free |
- | |
1101 | pop ebx |
1224 | pop ebx |
- | 1225 | sub [ebx + TCP_SOCKET.SND_WND], ecx |
|
- | 1226 | pop edx ecx |
|
Line 1102... | Line -... | ||
1102 | sub [ebx + TCP_SOCKET.SND_WND], ecx |
- | |
1103 | pop edx ecx |
1227 | .ack_complete: |
1104 | 1228 | ||
Line 1105... | Line 1229... | ||
1105 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: our FIN is not acked\n" |
1229 | ;----------------------------------------------------------------------------------- |
- | 1230 | ; |
|
1106 | 1231 | ; Wake up process waiting on send buffer |
|
1107 | ;---------------------------------------- |
1232 | ; |
1108 | ; Wake up process waiting on send buffer |
1233 | ;----------------------------------------------------------------------------------- |
1109 | 1234 | ||
1110 | .wakeup: |
1235 | mov eax, ebx |
1111 | mov eax, ebx |
1236 | call socket_notify |
Line 1112... | Line 1237... | ||
1112 | call socket_notify |
1237 | |
- | 1238 | ; Update TCPS |
|
1113 | 1239 | ||
- | 1240 | mov eax, [edx + TCP_header.AckNumber] |
|
1114 | ; Update TCPS |
1241 | mov [ebx + TCP_SOCKET.SND_UNA], eax |
Line 1115... | Line 1242... | ||
1115 | mov eax, [edx + TCP_header.AckNumber] |
1242 | cmp eax, [ebx + TCP_SOCKET.SND_NXT] |
1116 | mov [ebx + TCP_SOCKET.SND_UNA], eax |
1243 | jb @f |
Line 1117... | Line 1244... | ||
1117 | cmp eax, [ebx + TCP_SOCKET.SND_NXT] |
1244 | mov [ebx + TCP_SOCKET.SND_NXT], eax |
1118 | jb @f |
1245 | @@: |
1119 | mov [ebx + TCP_SOCKET.SND_NXT], eax |
1246 | |
1120 | @@: |
1247 | ;----------------------------------------------------------------------------------- |
1121 | 1248 | ; |
|
1122 | ; General ACK handling complete |
1249 | ; State specific ACK handeling |
Line 1137... | Line 1264... | ||
1137 | dd .ack_c ; TCPS_CLOSING |
1264 | dd .ack_c ; TCPS_CLOSING |
1138 | dd .ack_la ; TCPS_LAST_ACK |
1265 | dd .ack_la ; TCPS_LAST_ACK |
1139 | dd .ack_processed ; TCPS_FIN_WAIT_2 |
1266 | dd .ack_processed ; TCPS_FIN_WAIT_2 |
1140 | dd .ack_tw ; TCPS_TIMED_WAIT |
1267 | dd .ack_tw ; TCPS_TIMED_WAIT |
Line 1141... | Line -... | ||
1141 | - | ||
- | 1268 | ||
1142 | 1269 | ;----------------------------------------------------------------------------------- |
|
- | 1270 | .ack_fw1: |
|
- | 1271 | ; If our FIN is now acked, enter FIN_WAIT_2 |
|
1143 | .ack_fw1: |
1272 | |
1144 | test [temp_bits], TCP_BIT_FIN_IS_ACKED |
1273 | test [temp_bits], TCP_BIT_FIN_IS_ACKED |
Line -... | Line 1274... | ||
- | 1274 | jz .ack_processed |
|
- | 1275 | ||
- | 1276 | ; If we can't receive any more data, then closing user can proceed. |
|
- | 1277 | ; Starting the timer is contrary to the specification, but if we dont get a FIN, |
|
1145 | jz .ack_processed |
1278 | ; we'll hang forever. |
1146 | 1279 | ||
1147 | test [ebx + SOCKET.state], SS_CANTRCVMORE |
1280 | test [ebx + SOCKET.state], SS_CANTRCVMORE |
1148 | jnz @f |
1281 | jnz @f |
1149 | mov eax, ebx |
1282 | mov eax, ebx |
1150 | call socket_is_disconnected |
1283 | call socket_is_disconnected |
1151 | mov [ebx + TCP_SOCKET.timer_timed_wait], TCP_time_max_idle |
1284 | mov [ebx + TCP_SOCKET.timer_timed_wait], TCP_time_max_idle |
1152 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait |
1285 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait |
1153 | @@: |
1286 | @@: |
Line -... | Line 1287... | ||
- | 1287 | mov [ebx + TCP_SOCKET.t_state], TCPS_FIN_WAIT_2 |
|
1154 | mov [ebx + TCP_SOCKET.t_state], TCPS_FIN_WAIT_2 |
1288 | jmp .ack_processed |
- | 1289 | ||
- | 1290 | ;----------------------------------------------------------------------------------- |
|
1155 | jmp .ack_processed |
1291 | .ack_c: |
1156 | 1292 | ; Enter the TIME_WAIT state if our FIN is acked in CLOSED state. |
|
Line 1157... | Line 1293... | ||
1157 | .ack_c: |
1293 | |
1158 | test [temp_bits], TCP_BIT_FIN_IS_ACKED |
1294 | test [temp_bits], TCP_BIT_FIN_IS_ACKED |
1159 | jz .ack_processed |
1295 | jz .ack_processed |
1160 | 1296 | ||
1161 | mov [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT |
1297 | mov [ebx + TCP_SOCKET.t_state], TCPS_TIME_WAIT |
1162 | mov eax, ebx |
1298 | mov eax, ebx |
1163 | call tcp_cancel_timers |
1299 | call tcp_cancel_timers |
1164 | mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL |
1300 | mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL |
Line -... | Line 1301... | ||
- | 1301 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait |
|
1165 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait |
1302 | mov eax, ebx |
- | 1303 | call socket_is_disconnected |
|
- | 1304 | jmp .ack_processed |
|
- | 1305 | ||
1166 | mov eax, ebx |
1306 | ;----------------------------------------------------------------------------------- |
1167 | call socket_is_disconnected |
1307 | .ack_la: |
Line 1168... | Line 1308... | ||
1168 | jmp .ack_processed |
1308 | ; In LAST_ACK state, we may still be waiting for data to drain and/or to be acked. |
1169 | 1309 | ; If our FIN is acked however, enter CLOSED state and return. |
|
1170 | .ack_la: |
1310 | |
1171 | test [temp_bits], TCP_BIT_FIN_IS_ACKED |
1311 | test [temp_bits], TCP_BIT_FIN_IS_ACKED |
Line 1172... | Line -... | ||
1172 | jz .ack_processed |
- | |
1173 | 1312 | jz .ack_processed |
|
1174 | push ebx |
1313 | |
Line -... | Line 1314... | ||
- | 1314 | push ebx |
|
1175 | lea ecx, [ebx + SOCKET.mutex] |
1315 | lea ecx, [ebx + SOCKET.mutex] |
- | 1316 | call mutex_unlock |
|
- | 1317 | pop eax |
|
- | 1318 | ||
1176 | call mutex_unlock |
1319 | call tcp_close |
1177 | pop ebx |
1320 | jmp .drop_no_socket |
1178 | 1321 | ||
Line 1179... | Line 1322... | ||
1179 | mov eax, ebx |
1322 | ;----------------------------------------------------------------------------------- |
1180 | call tcp_close |
- | |
1181 | jmp .drop_no_socket |
- | |
1182 | 1323 | .ack_tw: |
|
1183 | .ack_tw: |
- | |
1184 | mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL |
1324 | ; In TIME_WAIT state the only thing that should arrive is a retransmission of the remote FIN. |
1185 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait |
1325 | ; Acknowledge it and restart the FINACK timer |
1186 | jmp .drop_after_ack |
- | |
1187 | - | ||
- | 1326 | ||
Line -... | Line 1327... | ||
- | 1327 | mov [ebx + TCP_SOCKET.timer_timed_wait], 2*TCP_time_MSL |
|
1188 | .reset_dupacks: ; We got a new ACK, reset duplicate ACK counter |
1328 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_2msl |
Line 1189... | Line 1329... | ||
1189 | mov [ebx + TCP_SOCKET.t_dupacks], 0 |
1329 | jmp .drop_after_ack |
1190 | jmp .ack_processed |
1330 | |
Line 1204... | Line 1344... | ||
1204 | jnz .drop_with_reset |
1344 | jnz .drop_with_reset |
Line 1205... | Line 1345... | ||
1205 | 1345 | ||
1206 | test [edx + TCP_header.Flags], TH_SYN |
1346 | test [edx + TCP_header.Flags], TH_SYN |
Line 1207... | Line 1347... | ||
1207 | jz .drop |
1347 | jz .drop |
Line 1208... | Line 1348... | ||
1208 | 1348 | ||
Line -... | Line 1349... | ||
- | 1349 | inc [TCPS_accepts] |
|
- | 1350 | ||
- | 1351 | ;;; TODO: check if it's a broadcast or multicast, and drop if so |
|
1209 | inc [TCPS_accepts] ; update stats |
1352 | |
1210 | 1353 | ;------------------------------------------- |
|
Line 1211... | Line 1354... | ||
1211 | ;;; TODO: check if it's a broadcast or multicast, and drop if so |
1354 | ; Processing of SYN received in LISTEN state |
1212 | 1355 | ||
Line 1213... | Line 1356... | ||
1213 | push [edi + IPv4_header.SourceAddress] |
1356 | push [edi + IPv4_header.SourceAddress] |
1214 | pop [ebx + IP_SOCKET.RemoteIP] |
1357 | pop [ebx + IP_SOCKET.RemoteIP] |
Line 1215... | Line 1358... | ||
1215 | 1358 | ||
1216 | push [edx + TCP_header.SourcePort] |
1359 | push [edx + TCP_header.SourcePort] |
1217 | pop [ebx + TCP_SOCKET.RemotePort] |
1360 | pop [ebx + TCP_SOCKET.RemotePort] |
1218 | 1361 | ||
Line 1219... | Line 1362... | ||
1219 | push [edx + TCP_header.SequenceNumber] |
1362 | push [edx + TCP_header.SequenceNumber] |
1220 | pop [ebx + TCP_SOCKET.IRS] |
1363 | pop [ebx + TCP_SOCKET.IRS] |
Line 1249... | Line 1392... | ||
1249 | call socket_notify |
1392 | call socket_notify |
1250 | popa |
1393 | popa |
Line 1251... | Line 1394... | ||
1251 | 1394 | ||
Line -... | Line 1395... | ||
- | 1395 | jmp .trim |
|
1252 | jmp .trim |
1396 | |
1253 | 1397 | ;----------------------------------------------------------------------------------- |
|
1254 | ;------------ |
1398 | ; |
1255 | ; Active Open |
- | |
1256 | - | ||
- | 1399 | ; Completion of active open? |
|
Line -... | Line 1400... | ||
- | 1400 | ; |
|
1257 | align 4 |
1401 | ;----------------------------------------------------------------------------------- |
Line 1258... | Line 1402... | ||
1258 | .SYN_SENT: |
1402 | |
1259 | 1403 | .state_syn_sent: |
|
Line 1277... | Line 1421... | ||
1277 | jz .drop |
1421 | jz .drop |
Line 1278... | Line 1422... | ||
1278 | 1422 | ||
1279 | mov eax, ebx |
1423 | mov eax, ebx |
1280 | mov ebx, ECONNREFUSED |
1424 | mov ebx, ECONNREFUSED |
1281 | call tcp_drop |
- | |
1282 | 1425 | call tcp_drop |
|
1283 | jmp .drop |
1426 | jmp .drop |
Line -... | Line 1427... | ||
- | 1427 | @@: |
|
- | 1428 | ||
- | 1429 | ;----------------------------------------------------------------------------------- |
|
- | 1430 | ; |
|
- | 1431 | ; Process received SYN in response to an active open |
|
- | 1432 | ; |
|
1284 | @@: |
1433 | ;----------------------------------------------------------------------------------- |
1285 | 1434 | ||
Line 1286... | Line -... | ||
1286 | test [edx + TCP_header.Flags], TH_SYN |
- | |
1287 | jz .drop |
- | |
1288 | 1435 | test [edx + TCP_header.Flags], TH_SYN |
|
1289 | ; at this point, segment seems to be valid |
1436 | jz .drop |
1290 | - | ||
1291 | test [edx + TCP_header.Flags], TH_ACK |
- | |
Line 1292... | Line 1437... | ||
1292 | jz .no_syn_ack |
1437 | |
1293 | 1438 | test [edx + TCP_header.Flags], TH_ACK |
|
1294 | ; now, process received SYN in response to an active open |
1439 | jz @f |
1295 | 1440 | ||
1296 | mov eax, [edx + TCP_header.AckNumber] |
1441 | mov eax, [edx + TCP_header.AckNumber] |
1297 | mov [ebx + TCP_SOCKET.SND_UNA], eax |
- | |
Line 1298... | Line -... | ||
1298 | cmp eax, [ebx + TCP_SOCKET.SND_NXT] |
- | |
1299 | jbe @f |
1442 | mov [ebx + TCP_SOCKET.SND_UNA], eax |
- | 1443 | cmp eax, [ebx + TCP_SOCKET.SND_NXT] |
|
Line 1300... | Line 1444... | ||
1300 | mov [ebx + TCP_SOCKET.SND_NXT], eax |
1444 | jbe @f |
1301 | @@: |
1445 | mov [ebx + TCP_SOCKET.SND_NXT], eax |
Line 1302... | Line 1446... | ||
1302 | 1446 | ||
Line 1317... | Line 1461... | ||
1317 | test [edx + TCP_header.Flags], TH_ACK |
1461 | test [edx + TCP_header.Flags], TH_ACK |
1318 | jz .simultaneous_open |
1462 | jz .simultaneous_open |
Line 1319... | Line 1463... | ||
1319 | 1463 | ||
Line 1320... | Line 1464... | ||
1320 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: active open\n" |
1464 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: active open\n" |
Line 1321... | Line 1465... | ||
1321 | 1465 | ||
- | 1466 | inc [TCPS_connects] |
|
1322 | ;;; TODO: update stats |
1467 | |
1323 | 1468 | ; set socket state to connected |
|
1324 | ; set socket state to connected |
1469 | |
1325 | push eax |
1470 | push eax |
1326 | mov eax, ebx |
1471 | mov eax, ebx |
Line 1327... | Line 1472... | ||
1327 | call socket_is_connected |
1472 | call socket_is_connected |
- | 1473 | pop eax |
|
1328 | pop eax |
1474 | mov [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED |
1329 | mov [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED |
1475 | |
1330 | 1476 | ; Do window scaling on this connection ? |
|
1331 | ; Do window scaling on this connection ? |
1477 | |
Line 1338... | Line 1484... | ||
1338 | mov word[ebx + TCP_SOCKET.SND_SCALE], ax |
1484 | mov word[ebx + TCP_SOCKET.SND_SCALE], ax |
1339 | .no_scaling: |
1485 | .no_scaling: |
Line 1340... | Line 1486... | ||
1340 | 1486 | ||
Line -... | Line 1487... | ||
- | 1487 | ;;; TODO: reassemble packets queue |
|
- | 1488 | ||
- | 1489 | ; If we didnt have time to re-transmit the SYN, |
|
1341 | ;;; TODO: reassemble packets queue |
1490 | ; Use its rtt as our initial srtt & rtt var. |
1342 | 1491 | ||
1343 | mov eax, [ebx + TCP_SOCKET.t_rtt] |
1492 | mov eax, [ebx + TCP_SOCKET.t_rtt] |
1344 | test eax, eax |
1493 | test eax, eax |
1345 | je .trim |
1494 | je .trim |
Line -... | Line 1495... | ||
- | 1495 | call tcp_xmit_timer |
|
- | 1496 | jmp .trim |
|
1346 | call tcp_xmit_timer |
1497 | |
- | 1498 | ;----------------------------------------------------------------------------------- |
|
- | 1499 | ; |
|
Line -... | Line 1500... | ||
- | 1500 | ; Simultaneous open (We have received a SYN but no ACK) |
|
1347 | jmp .trim |
1501 | ; |
1348 | - | ||
1349 | .simultaneous_open: |
1502 | ;----------------------------------------------------------------------------------- |
Line 1350... | Line 1503... | ||
1350 | 1503 | ||
- | 1504 | .simultaneous_open: |
|
1351 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: simultaneous open\n" |
1505 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: simultaneous open\n" |
- | 1506 | mov [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED |
|
- | 1507 | ||
Line 1352... | Line 1508... | ||
1352 | ; We have received a syn but no ACK, so we are having a simultaneous open.. |
1508 | ;----------------------------------------------------------------------------------- |
- | 1509 | ; |
|
- | 1510 | ; Common processing for receipt of SYN |
|
- | 1511 | ; |
|
1353 | mov [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED |
1512 | ;----------------------------------------------------------------------------------- |
Line 1354... | Line 1513... | ||
1354 | 1513 | ||
- | 1514 | .trim: |
|
1355 | ;------------------------------------- |
1515 | ; Advance sequence number to correspond to first data byte. |
1356 | ; Common processing for receipt of SYN |
1516 | ; If data, trim to stay within window, dropping FIN if necessary |
Line 1357... | Line 1517... | ||
1357 | 1517 | ||
- | 1518 | inc [edx + TCP_header.SequenceNumber] |
|
1358 | .trim: |
1519 | |
- | 1520 | ; Drop any received data that doesnt fit in the receive window. |
|
- | 1521 | ||
1359 | inc [edx + TCP_header.SequenceNumber] |
1522 | cmp ecx, [ebx + TCP_SOCKET.RCV_WND] |
1360 | 1523 | jbe .dont_trim |
|
Line 1361... | Line 1524... | ||
1361 | ; Drop any received data that doesnt fit in the receive window. |
1524 | |
1362 | cmp ecx, [ebx + TCP_SOCKET.RCV_WND] |
1525 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: received data does not fit in window, trimming %u bytes\n", eax |
1363 | jbe .dont_trim |
1526 | inc [TCPS_rcvpackafterwin] |
1364 | 1527 | sub ecx, [ebx + TCP_SOCKET.RCV_WND] |
|
1365 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: received data does not fit in window, trimming %u bytes\n", eax |
1528 | add [TCPS_rcvbyteafterwin], ecx |
Line -... | Line 1529... | ||
- | 1529 | ||
- | 1530 | and [edx + TCP_header.Flags], not (TH_FIN) |
|
- | 1531 | mov ecx, [ebx + TCP_SOCKET.RCV_WND] |
|
- | 1532 | ||
- | 1533 | .dont_trim: |
|
- | 1534 | mov eax, [edx + TCP_header.SequenceNumber] |
|
1366 | mov ecx, [ebx + TCP_SOCKET.RCV_WND] |
1535 | mov [ebx + TCP_SOCKET.RCV_UP], eax |
1367 | and [edx + TCP_header.Flags], not (TH_FIN) |
1536 | dec eax |
Line 1368... | Line -... | ||
1368 | ;;; TODO: update stats |
- | |
1369 | 1537 | mov [ebx + TCP_SOCKET.SND_WL1], eax |
|
Line 1370... | Line 1538... | ||
1370 | .dont_trim: |
1538 | |
1371 | mov eax, [edx + TCP_header.SequenceNumber] |
1539 | ;----------------------------------------------------------------------------------- |
Line -... | Line 1540... | ||
- | 1540 | ; |
|
- | 1541 | ; Update window information (step 6 in RFC793) |
|
1372 | mov [ebx + TCP_SOCKET.RCV_UP], eax |
1542 | ; |
1373 | dec eax |
1543 | ;----------------------------------------------------------------------------------- |
1374 | mov [ebx + TCP_SOCKET.SND_WL1], eax |
1544 | |
1375 | 1545 | .ack_processed: |
|
Line -... | Line 1546... | ||
- | 1546 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: ACK processed\n" |
|
- | 1547 | ||
1376 | .ack_processed: |
1548 | ; dont look at window if no ACK |
1377 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: ACK processed\n" |
1549 | |
1378 | 1550 | test [edx + TCP_header.Flags], TH_ACK |
|
1379 | ;---------------------------------------------- |
- | |
1380 | ; check if we need to update window information |
1551 | jz .no_window_update |
Line -... | Line 1552... | ||
- | 1552 | ||
- | 1553 | ; Does the segment contain new data? |
|
- | 1554 | ||
- | 1555 | mov eax, [ebx + TCP_SOCKET.SND_WL1] |
|
- | 1556 | cmp eax, [edx + TCP_header.SequenceNumber] |
|
- | 1557 | jb .update_window |
|
1381 | 1558 | ja @f |
|
1382 | test [edx + TCP_header.Flags], TH_ACK |
1559 | |
1383 | jz .no_window_update |
1560 | ; No new data but a new ACK ? |
Line 1384... | Line -... | ||
1384 | - | ||
Line 1385... | Line 1561... | ||
1385 | mov eax, [ebx + TCP_SOCKET.SND_WL1] |
1561 | |
- | 1562 | mov eax, [ebx + TCP_SOCKET.SND_WL2] |
|
- | 1563 | cmp eax, [edx + TCP_header.AckNumber] |
|
- | 1564 | jb .update_window |
|
- | 1565 | @@: |
|
- | 1566 | ||
- | 1567 | ; No new data or ACK but advertised window is larger then current window? |
|
- | 1568 | ||
- | 1569 | mov eax, [ebx + TCP_SOCKET.SND_WL2] |
|
- | 1570 | cmp eax, [edx + TCP_header.AckNumber] |
|
- | 1571 | jne .no_window_update |
|
- | 1572 | ||
Line 1386... | Line 1573... | ||
1386 | cmp eax, [edx + TCP_header.SequenceNumber] |
1573 | mov eax, dword[edx + TCP_header.Window] |
- | 1574 | cmp eax, [ebx + TCP_SOCKET.SND_WND] |
|
1387 | jb .update_window |
1575 | jbe .no_window_update |
1388 | ja @f |
1576 | |
1389 | 1577 | ||
1390 | mov eax, [ebx + TCP_SOCKET.SND_WL2] |
1578 | ; Keep track of pure window updates |
1391 | cmp eax, [edx + TCP_header.AckNumber] |
- | |
Line 1392... | Line 1579... | ||
1392 | jb .update_window |
1579 | .update_window: |
Line 1393... | Line 1580... | ||
1393 | ja .no_window_update |
1580 | test ecx, ecx |
1394 | @@: |
1581 | jnz @f |
Line 1395... | Line 1582... | ||
1395 | 1582 | mov eax, [ebx + TCP_SOCKET.SND_WL2] |
|
1396 | mov eax, dword [edx + TCP_header.Window] |
1583 | cmp eax, [edx + TCP_header.AckNumber] |
Line 1397... | Line 1584... | ||
1397 | cmp eax, [ebx + TCP_SOCKET.SND_WND] |
1584 | jne @f |
1398 | jbe .no_window_update |
- | |
1399 | 1585 | mov eax, dword[edx + TCP_header.Window] |
|
Line 1400... | Line 1586... | ||
1400 | .update_window: |
1586 | cmp eax, [ebx + TCP_SOCKET.SND_WND] |
- | 1587 | jbe @f |
|
1401 | 1588 | inc [TCPS_rcvwinupd] |
|
- | 1589 | @@: |
|
- | 1590 | ||
Line 1402... | Line 1591... | ||
1402 | ;;; TODO: update stats (Keep track of pure window updates) |
1591 | mov eax, dword[edx + TCP_header.Window] |
1403 | 1592 | mov [ebx + TCP_SOCKET.SND_WND], eax |
|
Line 1404... | Line 1593... | ||
1404 | mov eax, dword [edx + TCP_header.Window] |
1593 | cmp eax, [ebx + TCP_SOCKET.max_sndwnd] |
1405 | cmp eax, [ebx + TCP_SOCKET.max_sndwnd] |
1594 | jbe @f |
Line 1406... | Line 1595... | ||
1406 | jbe @f |
1595 | mov [ebx + TCP_SOCKET.max_sndwnd], eax |
1407 | mov [ebx + TCP_SOCKET.max_sndwnd], eax |
1596 | @@: |
Line 1408... | Line 1597... | ||
1408 | @@: |
1597 | |
Line 1409... | Line 1598... | ||
1409 | mov [ebx + TCP_SOCKET.SND_WND], eax |
1598 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Updating window to %u\n", eax |
Line 1447... | Line 1636... | ||
1447 | 1636 | ||
Line 1448... | Line 1637... | ||
1448 | ; processing of received urgent pointer |
1637 | ; processing of received urgent pointer |
Line -... | Line 1638... | ||
- | 1638 | ||
- | 1639 | ;;; TODO (1051-1093) |
|
- | 1640 | ||
1449 | 1641 | ;----------------------------------------------------------------------------------- |
|
1450 | ;;; TODO (1051-1093) |
1642 | ; |
1451 | - | ||
Line 1452... | Line 1643... | ||
1452 | 1643 | ; Process the data |
|
1453 | ;--------------------------------------- |
- | |
1454 | ; process the data in the segment (1094) |
1644 | ; |
1455 | 1645 | ;----------------------------------------------------------------------------------- |
|
Line 1456... | Line 1646... | ||
1456 | .do_data: |
1646 | |
1457 | 1647 | .do_data: |
|
Line 1458... | Line 1648... | ||
1458 | cmp [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT |
1648 | cmp [ebx + TCP_SOCKET.t_state], TCPS_TIME_WAIT |
1459 | jae .final_processing |
1649 | jae .final_processing |
1460 | 1650 | ||
Line 1461... | Line 1651... | ||
1461 | test [edx + TCP_header.Flags], TH_FIN |
1651 | test [edx + TCP_header.Flags], TH_FIN |
- | 1652 | jnz @f |
|
1462 | jnz @f |
1653 | |
1463 | 1654 | test ecx, ecx |
|
1464 | test ecx, ecx |
1655 | jz .final_processing |
Line 1465... | Line 1656... | ||
1465 | jz .final_processing |
1656 | @@: |
- | 1657 | ||
1466 | @@: |
1658 | ; The segment is in order? |
1467 | 1659 | ||
Line 1468... | Line 1660... | ||
1468 | ; The segment is in order? |
1660 | mov eax, [edx + TCP_header.SequenceNumber] |
- | 1661 | cmp eax, [ebx + TCP_SOCKET.RCV_NXT] |
|
1469 | mov eax, [edx + TCP_header.SequenceNumber] |
1662 | jne .out_of_order |
1470 | cmp eax, [ebx + TCP_SOCKET.RCV_NXT] |
1663 | |
Line 1471... | Line 1664... | ||
1471 | jne .out_of_order |
1664 | ; The reassembly queue is empty? |
- | 1665 | ||
1472 | 1666 | cmp [ebx + TCP_SOCKET.seg_next], 0 |
|
Line 1473... | Line 1667... | ||
1473 | ; The reassembly queue is empty? |
1667 | jne .out_of_order |
1474 | cmp [ebx + TCP_SOCKET.seg_next], 0 |
1668 | |
1475 | jne .out_of_order |
1669 | ; The connection is established? |
Line 1488... | Line 1682... | ||
1488 | call socket_ring_write ; Add the data to the socket buffer |
1682 | call socket_ring_write ; Add the data to the socket buffer |
1489 | add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Update sequence number with number of bytes we have copied |
1683 | add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Update sequence number with number of bytes we have copied |
1490 | popa |
1684 | popa |
Line 1491... | Line 1685... | ||
1491 | 1685 | ||
- | 1686 | ; Wake up the sleeping process |
|
1492 | ; Wake up the sleeping process |
1687 | |
1493 | mov eax, ebx |
1688 | mov eax, ebx |
Line 1494... | Line 1689... | ||
1494 | call socket_notify |
1689 | call socket_notify |
Line 1503... | Line 1698... | ||
1503 | 1698 | ||
Line 1504... | Line 1699... | ||
1504 | call tcp_reassemble |
1699 | call tcp_reassemble |
1505 | 1700 | ||
- | 1701 | ; Generate ACK immediately, to let the other end know that a segment was received out of order, |
|
1506 | ; Generate ACK immediately, to let the other end know that a segment was received out of order, |
1702 | ; and to tell it what sequence number is expected. This aids the fast-retransmit algorithm. |
1507 | ; and to tell it what sequence number is expected. This aids the fast-retransmit algorithm. |
1703 | |
Line 1508... | Line 1704... | ||
1508 | or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
1704 | or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
- | 1705 | .data_done: |
|
1509 | .data_done: |
1706 | |
- | 1707 | ;----------------------------------------------------------------------------------- |
|
- | 1708 | ; |
|
Line 1510... | Line 1709... | ||
1510 | 1709 | ; Process FIN |
|
1511 | ;--------------- |
1710 | ; |
Line 1512... | Line 1711... | ||
1512 | ; FIN processing |
1711 | ;----------------------------------------------------------------------------------- |
Line 1513... | Line 1712... | ||
1513 | 1712 | ||
1514 | test [edx + TCP_header.Flags], TH_FIN |
1713 | test [edx + TCP_header.Flags], TH_FIN |
Line 1515... | Line 1714... | ||
1515 | jz .final_processing |
1714 | jz .final_processing |
Line 1516... | Line 1715... | ||
1516 | 1715 | ||
Line 1527... | Line 1726... | ||
1527 | or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
1726 | or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
1528 | inc [ebx + TCP_SOCKET.RCV_NXT] |
1727 | inc [ebx + TCP_SOCKET.RCV_NXT] |
Line 1529... | Line 1728... | ||
1529 | 1728 | ||
1530 | .not_first_fin: |
1729 | .not_first_fin: |
1531 | mov eax, [ebx + TCP_SOCKET.t_state] |
- | |
1532 | shl eax, 2 |
1730 | mov eax, [ebx + TCP_SOCKET.t_state] |
Line 1533... | Line 1731... | ||
1533 | jmp dword [eax + .FIN_sw_list] |
1731 | jmp dword[.fin_sw_list+eax*4] |
1534 | 1732 | ||
1535 | .FIN_sw_list: |
1733 | .fin_sw_list: |
1536 | dd .final_processing ; TCPS_CLOSED |
1734 | dd .final_processing ; TCPS_CLOSED |
1537 | dd .final_processing ; TCPS_LISTEN |
1735 | dd .final_processing ; TCPS_LISTEN |
1538 | dd .final_processing ; TCPS_SYN_SENT |
1736 | dd .final_processing ; TCPS_SYN_SENT |
Line 1543... | Line 1741... | ||
1543 | dd .final_processing ; TCPS_CLOSING |
1741 | dd .final_processing ; TCPS_CLOSING |
1544 | dd .final_processing ; TCPS_LAST_ACK |
1742 | dd .final_processing ; TCPS_LAST_ACK |
1545 | dd .fin_wait2 ; TCPS_FIN_WAIT_2 |
1743 | dd .fin_wait2 ; TCPS_FIN_WAIT_2 |
1546 | dd .fin_timed ; TCPS_TIMED_WAIT |
1744 | dd .fin_timed ; TCPS_TIMED_WAIT |
Line -... | Line 1745... | ||
- | 1745 | ||
1547 | 1746 | ;----------------------------------------------------------------------------------- |
|
- | 1747 | .fin_syn_est: |
|
- | 1748 | ; In SYN_RECEIVED and ESTABLISHED state, enter the CLOSE_WAIT state |
|
1548 | .fin_syn_est: |
1749 | |
1549 | mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT |
1750 | mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT |
Line -... | Line 1751... | ||
- | 1751 | jmp .final_processing |
|
1550 | jmp .final_processing |
1752 | |
- | 1753 | ;----------------------------------------------------------------------------------- |
|
- | 1754 | .fin_wait1: |
|
1551 | 1755 | ; From FIN_WAIT_1 state, enter CLOSING state (our FIN has not been ACKed) |
|
1552 | .fin_wait1: |
1756 | |
Line -... | Line 1757... | ||
- | 1757 | mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSING |
|
1553 | mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSING |
1758 | jmp .final_processing |
- | 1759 | ||
- | 1760 | ;----------------------------------------------------------------------------------- |
|
1554 | jmp .final_processing |
1761 | .fin_wait2: |
1555 | 1762 | ; From FIN_WAIT_2 state, enter TIME_WAIT state and start the timer |
|
1556 | .fin_wait2: |
1763 | |
1557 | mov [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT |
1764 | mov [ebx + TCP_SOCKET.t_state], TCPS_TIME_WAIT |
Line -... | Line 1765... | ||
- | 1765 | mov eax, ebx |
|
1558 | mov eax, ebx |
1766 | call tcp_cancel_timers |
- | 1767 | call socket_is_disconnected |
|
1559 | call tcp_cancel_timers |
1768 | |
1560 | call socket_is_disconnected |
1769 | ;----------------------------------------------------------------------------------- |
Line 1561... | Line 1770... | ||
1561 | 1770 | .fin_timed: |
|
- | 1771 | ; (re)start the 2 MSL timer |
|
1562 | .fin_timed: |
1772 | mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL |
- | 1773 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait |
|
- | 1774 | ||
Line 1563... | Line 1775... | ||
1563 | mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL |
1775 | ;----------------------------------------------------------------------------------- |
1564 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait |
1776 | ; |
Line 1565... | Line 1777... | ||
1565 | 1777 | ; Finally, drop the segment |
|
Line 1589... | Line 1801... | ||
1589 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: dumping\n" |
1801 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: dumping\n" |
Line 1590... | Line 1802... | ||
1590 | 1802 | ||
1591 | call net_buff_free |
1803 | call net_buff_free |
Line -... | Line 1804... | ||
- | 1804 | jmp .loop |
|
- | 1805 | ||
- | 1806 | ;----------------------------------------------------------------------------------- |
|
- | 1807 | ; |
|
- | 1808 | ; Drop segment, reply with an RST segment when needed |
|
Line 1592... | Line 1809... | ||
1592 | jmp .loop |
1809 | ; |
1593 | - | ||
1594 | - | ||
1595 | ;----------------- |
- | |
1596 | ; Drop the segment |
1810 | ;----------------------------------------------------------------------------------- |
1597 | 1811 | ||
Line 1598... | Line 1812... | ||
1598 | 1812 | ;----------------------------------------------------------------------------------- |
|
1599 | .drop_after_ack: |
1813 | .drop_after_ack: |
Line 1608... | Line 1822... | ||
1608 | jnz .done |
1822 | jnz .done |
Line 1609... | Line 1823... | ||
1609 | 1823 | ||
1610 | or [eax + TCP_SOCKET.t_flags], TF_ACKNOW |
1824 | or [eax + TCP_SOCKET.t_flags], TF_ACKNOW |
Line -... | Line 1825... | ||
- | 1825 | jmp .need_output |
|
1611 | jmp .need_output |
1826 | |
1612 | 1827 | ;----------------------------------------------------------------------------------- |
|
Line 1613... | Line 1828... | ||
1613 | .drop_with_reset: |
1828 | .drop_with_reset: |
1614 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Drop with reset\n" |
1829 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Drop with reset\n" |
Line 1628... | Line 1843... | ||
1628 | 1843 | ||
1629 | test [edx + TCP_header.Flags], TH_SYN |
1844 | test [edx + TCP_header.Flags], TH_SYN |
1630 | jnz .respond_syn |
1845 | jnz .respond_syn |
Line 1631... | Line -... | ||
1631 | jmp .done |
- | |
1632 | - | ||
1633 | ;--------- |
- | |
1634 | ; Respond |
1846 | jmp .done |
1635 | 1847 | ||
1636 | .respond_ack: |
1848 | .respond_ack: |
1637 | push ebx |
1849 | push ebx |
1638 | mov cl, TH_RST |
1850 | mov cl, TH_RST |