Rev 3908 | Rev 5201 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3908 | Rev 4423 | ||
---|---|---|---|
Line 76... | Line 76... | ||
76 | 76 | ||
77 | 77 | ||
- | 78 | ||
- | 79 | ||
- | 80 | align 4 |
|
- | 81 | proc TCP_process_input |
|
- | 82 | ||
- | 83 | locals |
|
Line 78... | Line 84... | ||
78 | 84 | dataoffset dd ? |
|
79 | 85 | timestamp dd ? |
|
80 | align 4 |
86 | temp_bits db ? |
81 | TCP_process_input: |
87 | endl |
Line 92... | Line 98... | ||
92 | 98 | ||
93 | .loop: |
99 | .loop: |
Line 94... | Line 100... | ||
94 | get_from_queue TCP_queue, TCP_QUEUE_SIZE, sizeof.TCP_queue_entry, .wait |
100 | get_from_queue TCP_queue, TCP_QUEUE_SIZE, sizeof.TCP_queue_entry, .wait |
- | 101 | ||
95 | 102 | push [esi + TCP_queue_entry.timestamp] |
|
Line 96... | Line 103... | ||
96 | push [esi + TCP_queue_entry.timestamp] |
103 | pop [timestamp] |
97 | push [esi + TCP_queue_entry.buffer_ptr] |
104 | push [esi + TCP_queue_entry.buffer_ptr] |
98 | 105 | ||
Line 107... | Line 114... | ||
107 | 114 | ||
108 | cmp ebx, LOOPBACK_DEVICE |
115 | cmp ebx, LOOPBACK_DEVICE |
Line 109... | Line 116... | ||
109 | je .checksum_ok |
116 | je .checksum_ok |
110 | 117 | ||
111 | ; re-calculate the checksum (if not already done by hw) |
118 | ; re-calculate the checksum (if not already done by hw) |
Line 112... | Line 119... | ||
112 | ; test [ebx + NET_DEVICE.hwacc], HWACC_TCP_IPv4_IN |
119 | test [ebx + NET_DEVICE.hwacc], NET_HWACC_TCP_IPv4_IN |
113 | ; jnz .checksum_ok |
120 | jnz .checksum_ok |
114 | 121 | ||
115 | push ecx esi |
122 | push ecx esi |
Line 121... | Line 128... | ||
121 | pop edx ecx |
128 | pop edx ecx |
122 | jne .drop_no_socket |
129 | jne .drop_no_socket |
123 | .checksum_ok: |
130 | .checksum_ok: |
Line 124... | Line 131... | ||
124 | 131 | ||
- | 132 | ; Verify the data offset |
|
125 | ; Verify the data offset |
133 | movzx eax, [edx + TCP_header.DataOffset] |
126 | and [edx + TCP_header.DataOffset], 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) |
127 | shr [edx + TCP_header.DataOffset], 2 |
135 | shr al, 2 |
128 | cmp [edx + TCP_header.DataOffset], 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 |
- | 137 | jb .drop_no_socket ; If not, drop the packet |
|
Line 129... | Line -... | ||
129 | jb .drop_no_socket ; If not, drop the packet |
- | |
130 | 138 | mov [dataoffset], eax |
|
131 | movzx eax, [edx + TCP_header.DataOffset] |
139 | |
132 | sub ecx, eax ; substract TCP header size from total segment size |
140 | sub ecx, eax ; substract TCP header size from total segment size |
Line 133... | Line 141... | ||
133 | jb .drop_no_socket ; If total segment size is less then the advertised header size, drop packet |
141 | jb .drop_no_socket ; If total segment size is less then the advertised header size, drop packet |
Line 209... | Line 217... | ||
209 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: socket locked\n" |
217 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: socket locked\n" |
Line 210... | Line 218... | ||
210 | 218 | ||
211 | ;--------------------------- |
219 | ;--------------------------- |
Line 212... | Line 220... | ||
212 | ; disable all temporary bits |
220 | ; disable all temporary bits |
Line 213... | Line 221... | ||
213 | 221 | ||
214 | mov [ebx + TCP_SOCKET.temp_bits], 0 |
222 | mov [temp_bits], 0 |
Line 215... | Line 223... | ||
215 | 223 | ||
Line 243... | Line 251... | ||
243 | test eax, eax |
251 | test eax, eax |
244 | jz .drop_no_socket |
252 | jz .drop_no_socket |
Line 245... | Line 253... | ||
245 | 253 | ||
Line 246... | Line 254... | ||
246 | mov ebx, eax |
254 | mov ebx, eax |
Line 247... | Line 255... | ||
247 | 255 | ||
248 | mov [ebx + TCP_SOCKET.temp_bits], TCP_BIT_DROPSOCKET ;;; FIXME: should we take over bits from previous socket? |
256 | mov [temp_bits], TCP_BIT_DROPSOCKET |
Line 249... | Line 257... | ||
249 | 257 | ||
Line 265... | Line 273... | ||
265 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_keepalive |
273 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_keepalive |
Line 266... | Line 274... | ||
266 | 274 | ||
267 | ;-------------------- |
275 | ;-------------------- |
Line -... | Line 276... | ||
- | 276 | ; Process TCP options |
|
- | 277 | ||
- | 278 | ;;; FIXME: for LISTEN, options should be called after we determined route, we need it for MSS |
|
- | 279 | ;;; cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN ; no options when in listen state |
|
268 | ; Process TCP options |
280 | ;;; jz .not_uni_xfer ; also no header prediction |
Line 269... | Line 281... | ||
269 | 281 | ||
270 | push ecx |
282 | push ecx |
271 | 283 | ||
Line 272... | Line 284... | ||
272 | movzx ecx, [edx + TCP_header.DataOffset] |
284 | mov ecx, [dataoffset] |
Line 273... | Line -... | ||
273 | cmp ecx, sizeof.TCP_header ; Does header contain any options? |
- | |
274 | je .no_options |
- | |
275 | - | ||
276 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Segment has options\n" |
- | |
277 | 285 | cmp ecx, sizeof.TCP_header ; Does header contain any options? |
|
278 | ;;; FIXME: for LISTEN, options should be called after we determined route, we need it for MSS |
286 | je .no_options |
Line 279... | Line 287... | ||
279 | ;;; cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN ; no options when in listen state |
287 | |
280 | ;;; jz .not_uni_xfer ; also no header prediction |
288 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Segment has options\n" |
Line 309... | Line 317... | ||
309 | jne .no_options ; error occured, ignore all options! |
317 | jne .no_options ; error occured, ignore all options! |
Line 310... | Line 318... | ||
310 | 318 | ||
311 | test [edx + TCP_header.Flags], TH_SYN |
319 | test [edx + TCP_header.Flags], TH_SYN |
Line -... | Line 320... | ||
- | 320 | jz @f |
|
312 | jz @f |
321 | |
313 | 322 | xor eax, eax |
|
314 | lodsw |
323 | lodsw |
315 | rol ax, 8 |
324 | rol ax, 8 |
316 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Maxseg=%u\n", ax |
325 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Maxseg=%u\n", eax |
317 | call TCP_mss |
326 | call TCP_mss |
Line 364... | Line 373... | ||
364 | jz @f |
373 | jz @f |
365 | or [ebx + TCP_SOCKET.t_flags], TF_RCVD_TSTMP |
374 | or [ebx + TCP_SOCKET.t_flags], TF_RCVD_TSTMP |
366 | @@: |
375 | @@: |
Line 367... | Line 376... | ||
367 | 376 | ||
- | 377 | lodsd |
|
368 | lodsd |
378 | bswap eax |
369 | mov [ebx + TCP_SOCKET.ts_val], eax |
379 | mov [ebx + TCP_SOCKET.ts_val], eax |
370 | lodsd ; timestamp echo reply |
380 | lodsd ; timestamp echo reply |
371 | mov [ebx + TCP_SOCKET.ts_ecr], eax |
381 | mov [ebx + TCP_SOCKET.ts_ecr], eax |
Line 372... | Line 382... | ||
372 | or [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP |
382 | or [temp_bits], TCP_BIT_TIMESTAMP |
Line 373... | Line 383... | ||
373 | 383 | ||
374 | ; Since we have a timestamp, lets do the paws test right away! |
384 | ; Since we have a timestamp, lets do the paws test right away! |
Line 375... | Line 385... | ||
375 | 385 | ||
376 | test [edx + TCP_header.Flags], TH_RST |
386 | test [edx + TCP_header.Flags], TH_RST |
377 | jnz .no_paws |
387 | jnz .no_paws |
378 | 388 | ||
379 | mov eax, [ebx + TCP_SOCKET.ts_recent] |
389 | mov eax, [ebx + TCP_SOCKET.ts_recent] |
Line 380... | Line 390... | ||
380 | test eax, eax |
390 | test eax, eax |
Line 381... | Line 391... | ||
381 | jz .no_paws |
391 | jz .no_paws |
382 | cmp eax, [ebx + TCP_SOCKET.ts_val] |
392 | cmp eax, [ebx + TCP_SOCKET.ts_val] |
Line 383... | Line 393... | ||
383 | jge .no_paws |
393 | jbe .no_paws |
384 | 394 | ||
385 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: PAWS: detected an old segment\n" |
395 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: PAWS: detected an old segment\n" |
Line 472... | Line 482... | ||
472 | call SOCKET_ring_free |
482 | call SOCKET_ring_free |
473 | popa |
483 | popa |
Line 474... | Line 484... | ||
474 | 484 | ||
Line 475... | Line 485... | ||
475 | ; Update RTT estimators |
485 | ; Update RTT estimators |
476 | 486 | ||
477 | test [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP |
487 | test [temp_bits], TCP_BIT_TIMESTAMP |
478 | jz .no_timestamp_rtt |
488 | jz .no_timestamp_rtt |
479 | mov eax, [esp + 4] ; timestamp when this segment was received |
489 | mov eax, [timestamp] |
480 | sub eax, [ebx + TCP_SOCKET.ts_ecr] |
490 | sub eax, [ebx + TCP_SOCKET.ts_ecr] |
481 | inc eax |
491 | inc eax |
Line 534... | Line 544... | ||
534 | 544 | ||
Line 535... | Line 545... | ||
535 | ; Complete processing of received data |
545 | ; Complete processing of received data |
Line 536... | Line -... | ||
536 | - | ||
537 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Header prediction: we are receiving %u bytes\n", ecx |
- | |
538 | 546 | ||
539 | add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Update sequence number with number of bytes we have copied |
547 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Header prediction: we are receiving %u bytes\n", ecx |
540 | 548 | ||
541 | movzx esi, [edx + TCP_header.DataOffset] |
549 | mov esi, [dataoffset] |
- | 550 | add esi, edx |
|
Line 542... | Line 551... | ||
542 | add esi, edx |
551 | lea eax, [ebx + STREAM_SOCKET.rcv] |
543 | lea eax, [ebx + STREAM_SOCKET.rcv] |
552 | call SOCKET_ring_write ; Add the data to the socket buffer |
Line 544... | Line 553... | ||
544 | call SOCKET_ring_write ; Add the data to the socket buffer |
553 | add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Update sequence number with number of bytes we have copied |
Line 556... | Line 565... | ||
556 | .not_uni_xfer: |
565 | .not_uni_xfer: |
Line 557... | Line 566... | ||
557 | 566 | ||
Line 558... | Line 567... | ||
558 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Header prediction failed\n" |
567 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Header prediction failed\n" |
559 | - | ||
560 | ; Calculate receive window size |
568 | |
561 | 569 | ; Calculate receive window size |
|
562 | push edx |
570 | push edx |
- | 571 | mov eax, SOCKET_MAXDATA |
|
563 | mov eax, SOCKETBUFFSIZE |
572 | sub eax, [ebx + STREAM_SOCKET.rcv.size] |
564 | sub eax, [ebx + STREAM_SOCKET.rcv.size] |
573 | DEBUGF DEBUG_NETWORK_VERBOSE, "Space in receive buffer=%d\n", eax |
- | 574 | mov edx, [ebx + TCP_SOCKET.RCV_ADV] |
|
565 | mov edx, [ebx + TCP_SOCKET.RCV_ADV] |
575 | sub edx, [ebx + TCP_SOCKET.RCV_NXT] |
566 | sub edx, [ebx + TCP_SOCKET.RCV_NXT] |
576 | DEBUGF DEBUG_NETWORK_VERBOSE, "Current advertised window=%d\n", edx |
567 | cmp eax, edx |
577 | cmp eax, edx |
568 | jg @f |
578 | jg @f |
569 | mov eax, edx |
579 | mov eax, edx |
Line 581... | Line 591... | ||
581 | je .SYN_SENT |
591 | je .SYN_SENT |
Line 582... | Line 592... | ||
582 | 592 | ||
583 | ;---------------------------- |
593 | ;---------------------------- |
Line 584... | Line 594... | ||
584 | ; trim any data not in window |
594 | ; trim any data not in window |
Line -... | Line 595... | ||
- | 595 | ||
585 | 596 | ; 1. Check for duplicate data at beginning of segment |
|
586 | ; check for duplicate data at beginning of segment (635) |
597 | |
587 | 598 | ; Calculate number of bytes we need to drop |
|
Line 588... | Line 599... | ||
588 | mov eax, [ebx + TCP_SOCKET.RCV_NXT] |
599 | mov eax, [ebx + TCP_SOCKET.RCV_NXT] |
Line 607... | Line 618... | ||
607 | and [edx + TCP_header.Flags], not (TH_URG) |
618 | and [edx + TCP_header.Flags], not (TH_URG) |
608 | .dup_syn: |
619 | .dup_syn: |
609 | dec eax |
620 | dec eax |
610 | .no_dup_syn: |
621 | .no_dup_syn: |
Line 611... | Line 622... | ||
611 | 622 | ||
612 | ; Check for entire duplicate segment (646) |
623 | ; 2. Check for entire duplicate segment |
613 | cmp eax, ecx ; eax holds number of bytes to drop, ecx is data size |
624 | cmp eax, ecx ; eax holds number of bytes to drop, ecx is data size |
614 | jb .duplicate |
625 | jb .duplicate |
615 | jnz @f |
626 | jnz @f |
616 | test [edx + TCP_header.Flags], TH_FIN |
627 | test [edx + TCP_header.Flags], TH_FIN |
Line 621... | Line 632... | ||
621 | ; At this point the FIN must be out of sequence or a duplicate, drop it |
632 | ; At this point the FIN must be out of sequence or a duplicate, drop it |
622 | and [edx + TCP_header.Flags], not TH_FIN |
633 | and [edx + TCP_header.Flags], not TH_FIN |
Line 623... | Line 634... | ||
623 | 634 | ||
624 | ; send an ACK and resynchronize and drop any data. |
635 | ; send an ACK and resynchronize and drop any data. |
625 | ; But keep on processing for RST or ACK |
- | |
626 | DEBUGF DEBUG_NETWORK_VERBOSE, "616\n" |
636 | ; But keep on processing for RST or ACK |
627 | or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
637 | or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
- | 638 | mov eax, ecx |
|
628 | mov eax, ecx |
639 | |
Line 629... | Line 640... | ||
629 | ;TODO: update stats |
640 | ;;; TODO: update stats |
630 | 641 | ||
Line 631... | Line 642... | ||
631 | ;----------------------------------------------- |
642 | ;----------------------------------------------- |
- | 643 | ; Remove duplicate data and update urgent offset |
|
- | 644 | ||
- | 645 | .duplicate: |
|
632 | ; Remove duplicate data and update urgent offset |
646 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: trimming duplicate data\n" |
633 | 647 | ||
634 | .duplicate: |
648 | ; Trim data from left side of window |
Line 635... | Line 649... | ||
635 | ;;; TODO: 677 |
649 | add [dataoffset], eax |
636 | add [edx + TCP_header.SequenceNumber], eax |
650 | add [edx + TCP_header.SequenceNumber], eax |
637 | sub ecx, eax |
651 | sub ecx, eax |
638 | 652 | ||
639 | sub [edx + TCP_header.UrgentPointer], ax |
653 | sub [edx + TCP_header.UrgentPointer], ax |
Line 640... | Line 654... | ||
640 | jg @f |
654 | jg @f |
641 | and [edx + TCP_header.Flags], not (TH_URG) |
655 | and [edx + TCP_header.Flags], not (TH_URG) |
Line 642... | Line 656... | ||
642 | mov [edx + TCP_header.UrgentPointer], 0 |
656 | mov [edx + TCP_header.UrgentPointer], 0 |
643 | @@: |
657 | @@: |
644 | 658 | ||
645 | ;-------------------------------------------------- |
659 | ;-------------------------------------------------- |
646 | ; Handle data that arrives after process terminates (687) |
660 | ; Handle data that arrives after process terminates |
647 | 661 | ||
648 | .no_duplicate: |
662 | .no_duplicate: |
Line 657... | Line 671... | ||
657 | call TCP_close |
671 | call TCP_close |
658 | ;;;TODO: update stats |
672 | ;;; TODO: update stats |
659 | jmp .respond_seg_reset |
673 | jmp .respond_seg_reset |
Line 660... | Line 674... | ||
660 | 674 | ||
661 | ;---------------------------------------- |
675 | ;---------------------------------------- |
Line 662... | Line 676... | ||
662 | ; Remove data beyond right edge of window (700-736) |
676 | ; Remove data beyond right edge of window |
663 | 677 | ||
664 | .not_terminated: |
678 | .not_terminated: |
665 | mov eax, [edx + TCP_header.SequenceNumber] |
679 | mov eax, [edx + TCP_header.SequenceNumber] |
Line 686... | Line 700... | ||
686 | mov eax, ebx |
700 | mov eax, ebx |
687 | call TCP_close |
701 | call TCP_close |
688 | jmp .findpcb ; FIXME: skip code for unscaling window, ... |
702 | jmp .findpcb ; FIXME: skip code for unscaling window, ... |
689 | .no_new_request: |
703 | .no_new_request: |
Line 690... | Line 704... | ||
690 | 704 | ||
691 | ; If window is closed can only take segments at window edge, and have to drop data and PUSH from |
705 | ; If window is closed, we can only take segments at window edge, and have to drop data and PUSH from |
Line 692... | Line 706... | ||
692 | ; incoming segments. Continue processing, but remember to ACK. Otherwise drop segment and ACK |
706 | ; incoming segments. Continue processing, but remember to ACK. Otherwise drop segment and ACK |
693 | 707 | ||
694 | cmp [ebx + TCP_SOCKET.RCV_WND], 0 |
708 | cmp [ebx + TCP_SOCKET.RCV_WND], 0 |
695 | jne .drop_after_ack |
709 | jne .drop_after_ack |
696 | mov eax, [edx + TCP_header.SequenceNumber] |
710 | mov esi, [edx + TCP_header.SequenceNumber] |
Line 697... | Line -... | ||
697 | cmp eax, [ebx + TCP_SOCKET.RCV_NXT] |
- | |
698 | jne .drop_after_ack |
711 | cmp esi, [ebx + TCP_SOCKET.RCV_NXT] |
699 | 712 | jne .drop_after_ack |
|
700 | DEBUGF DEBUG_NETWORK_VERBOSE, "690\n" |
- | |
701 | or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
713 | |
702 | ;;; TODO: update stats |
714 | or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
703 | jmp .no_excess_data |
715 | ;;; TODO: update stats |
704 | .dont_drop_all: |
- | |
705 | ;;; TODO: update stats |
716 | .dont_drop_all: |
706 | ;;; TODO: 733 |
717 | ;;; TODO: update stats |
707 | 718 | DEBUGF DEBUG_NETWORK_VERBOSE, "Trimming %u bytes from the right of the window\n" |
|
Line 708... | Line 719... | ||
708 | sub ecx, eax |
719 | sub ecx, eax ; remove data from the right side of window (decrease data length) |
709 | and [ebx + TCP_SOCKET.t_flags], not (TH_PUSH or TH_FIN) |
720 | and [edx + TCP_header.Flags], not (TH_PUSH or TH_FIN) |
Line 710... | Line 721... | ||
710 | .no_excess_data: |
721 | .no_excess_data: |
711 | 722 | ||
712 | ;----------------- |
723 | ;----------------- |
713 | ; Record timestamp (737-746) |
724 | ; Record timestamp |
714 | 725 | ||
715 | ; If last ACK falls within this segments sequence numbers, record its timestamp |
726 | ; If last ACK falls within this segments sequence numbers, record its timestamp |
716 | test [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP |
727 | test [temp_bits], TCP_BIT_TIMESTAMP |
Line 725... | Line 736... | ||
725 | sub eax, ecx |
736 | sub eax, ecx |
726 | jae .no_timestamp |
737 | jae .no_timestamp |
Line 727... | Line 738... | ||
727 | 738 | ||
Line 728... | Line 739... | ||
728 | DEBUGF DEBUG_NETWORK_VERBOSE, "Recording timestamp\n" |
739 | DEBUGF DEBUG_NETWORK_VERBOSE, "Recording timestamp\n" |
729 | 740 | ||
730 | mov eax, [esp + 4] ; tcp_now |
741 | mov eax, [timestamp] |
731 | mov [ebx + TCP_SOCKET.ts_recent_age], eax |
742 | mov [ebx + TCP_SOCKET.ts_recent_age], eax |
732 | mov eax, [ebx + TCP_SOCKET.ts_val] |
743 | mov eax, [ebx + TCP_SOCKET.ts_val] |
Line 880... | Line 891... | ||
880 | 891 | ||
Line 881... | Line 892... | ||
881 | push [ebx + TCP_SOCKET.SND_NXT] ; >>>> |
892 | push [ebx + TCP_SOCKET.SND_NXT] ; >>>> |
882 | 893 | ||
- | 894 | mov eax, [ebx + TCP_SOCKET.SND_WND] |
|
883 | mov eax, [ebx + TCP_SOCKET.SND_WND] |
895 | cmp eax, [ebx + TCP_SOCKET.SND_CWND] |
- | 896 | jbe @f |
|
884 | cmp eax, [ebx + TCP_SOCKET.SND_CWND] |
897 | mov eax, [ebx + TCP_SOCKET.SND_CWND] |
885 | cmova eax, [ebx + TCP_SOCKET.SND_CWND] |
898 | @@: |
886 | shr eax, 1 |
899 | shr eax, 1 |
887 | push edx |
900 | push edx |
888 | xor edx, edx |
901 | xor edx, edx |
Line 991... | Line 1004... | ||
991 | ;;; TODO: update stats |
1004 | ;;; TODO: update stats |
Line 992... | Line 1005... | ||
992 | 1005 | ||
Line 993... | Line 1006... | ||
993 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: acceptable ACK for %u bytes\n", edi |
1006 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: acceptable ACK for %u bytes\n", edi |
994 | 1007 | ||
Line 995... | Line 1008... | ||
995 | ;------------------------------------------ |
1008 | ;------------------------------------------ |
Line 996... | Line 1009... | ||
996 | ; RTT measurements and retransmission timer (912-926) |
1009 | ; RTT measurements and retransmission timer |
997 | 1010 | ||
998 | ; If we have a timestamp, update smoothed RTT |
1011 | ; If we have a timestamp, update smoothed RTT |
999 | 1012 | ||
1000 | test [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP |
1013 | test [temp_bits], TCP_BIT_TIMESTAMP |
1001 | jz .timestamp_not_present |
1014 | jz .timestamp_not_present |
1002 | mov eax, [esp+4] |
1015 | mov eax, [timestamp] |
Line 1026... | Line 1039... | ||
1026 | 1039 | ||
1027 | mov eax, [ebx + TCP_SOCKET.SND_MAX] |
1040 | mov eax, [ebx + TCP_SOCKET.SND_MAX] |
1028 | cmp eax, [edx + TCP_header.AckNumber] |
1041 | cmp eax, [edx + TCP_header.AckNumber] |
1029 | jne .more_data |
1042 | jne .more_data |
1030 | and [ebx + TCP_SOCKET.timer_flags], not timer_flag_retransmission |
1043 | and [ebx + TCP_SOCKET.timer_flags], not timer_flag_retransmission |
1031 | or [ebx + TCP_SOCKET.temp_bits], TCP_BIT_NEEDOUTPUT |
1044 | or [temp_bits], TCP_BIT_NEEDOUTPUT |
1032 | jmp .no_restart |
1045 | jmp .no_restart |
1033 | .more_data: |
1046 | .more_data: |
1034 | test [ebx + TCP_SOCKET.timer_flags], timer_flag_persist |
1047 | test [ebx + TCP_SOCKET.timer_flags], timer_flag_persist |
Line 1065... | Line 1078... | ||
1065 | mov eax, TCP_max_win |
1078 | mov eax, TCP_max_win |
1066 | shl eax, cl |
1079 | shl eax, cl |
1067 | pop ecx |
1080 | pop ecx |
Line 1068... | Line 1081... | ||
1068 | 1081 | ||
- | 1082 | cmp esi, eax |
|
1069 | cmp esi, eax |
1083 | jbe @f |
- | 1084 | mov esi, eax |
|
1070 | cmova esi, eax |
1085 | @@: |
Line 1071... | Line 1086... | ||
1071 | mov [ebx + TCP_SOCKET.SND_CWND], esi |
1086 | mov [ebx + TCP_SOCKET.SND_CWND], esi |
1072 | 1087 | ||
Line 1173... | Line 1188... | ||
1173 | push ebx |
1188 | push ebx |
1174 | lea ecx, [ebx + SOCKET.mutex] |
1189 | lea ecx, [ebx + SOCKET.mutex] |
1175 | call mutex_unlock |
1190 | call mutex_unlock |
1176 | pop ebx |
1191 | pop ebx |
Line 1177... | Line -... | ||
1177 | - | ||
1178 | push ebx |
1192 | |
1179 | mov eax, ebx |
1193 | mov eax, ebx |
1180 | call TCP_disconnect |
- | |
1181 | pop ebx |
- | |
1182 | 1194 | call TCP_close |
|
Line 1183... | Line 1195... | ||
1183 | jmp .destroy_new_socket |
1195 | jmp .drop_no_socket |
1184 | 1196 | ||
1185 | .ack_tw: |
1197 | .ack_tw: |
1186 | mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL |
1198 | mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL |
Line 1226... | Line 1238... | ||
1226 | 1238 | ||
1227 | TCP_sendseqinit ebx |
1239 | TCP_sendseqinit ebx |
Line 1228... | Line 1240... | ||
1228 | TCP_rcvseqinit ebx |
1240 | TCP_rcvseqinit ebx |
1229 | 1241 | ||
1230 | mov [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED |
1242 | mov [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED |
1231 | mov [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
1243 | or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
Line 1232... | Line 1244... | ||
1232 | mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval ;;;; macro |
1244 | mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval ;;;; macro |
1233 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_keepalive |
1245 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_keepalive |
Line 1234... | Line 1246... | ||
1234 | 1246 | ||
1235 | lea eax, [ebx + STREAM_SOCKET.snd] |
1247 | lea eax, [ebx + STREAM_SOCKET.snd] |
Line 1236... | Line 1248... | ||
1236 | call SOCKET_ring_create |
1248 | call SOCKET_ring_create |
Line 1237... | Line 1249... | ||
1237 | 1249 | ||
1238 | lea eax, [ebx + STREAM_SOCKET.rcv] |
1250 | lea eax, [ebx + STREAM_SOCKET.rcv] |
1239 | call SOCKET_ring_create |
1251 | call SOCKET_ring_create |
1240 | 1252 | ||
Line 1353... | Line 1365... | ||
1353 | 1365 | ||
Line 1354... | Line 1366... | ||
1354 | .trim_then_step6: |
1366 | .trim_then_step6: |
Line 1355... | Line 1367... | ||
1355 | 1367 | ||
- | 1368 | inc [edx + TCP_header.SequenceNumber] |
|
- | 1369 | ||
- | 1370 | ; Drop any received data that doesnt fit in the receive window. |
|
- | 1371 | cmp ecx, [ebx + TCP_SOCKET.RCV_WND] |
|
- | 1372 | jbe .dont_trim |
|
- | 1373 | ||
- | 1374 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: received data does not fit in window, trimming %u bytes\n", eax |
|
- | 1375 | mov ecx, [ebx + TCP_SOCKET.RCV_WND] |
|
- | 1376 | and [edx + TCP_header.Flags], not (TH_FIN) |
|
Line 1356... | Line 1377... | ||
1356 | inc [edx + TCP_header.SequenceNumber] |
1377 | ;;; TODO: update stats |
1357 | 1378 | ||
1358 | ;;; TODO: Drop any received data that follows receive window (590) |
1379 | .dont_trim: |
1359 | 1380 | ||
Line 1407... | Line 1428... | ||
1407 | pop [ebx + TCP_SOCKET.SND_WL1] |
1428 | pop [ebx + TCP_SOCKET.SND_WL1] |
Line 1408... | Line 1429... | ||
1408 | 1429 | ||
1409 | push [edx + TCP_header.AckNumber] |
1430 | push [edx + TCP_header.AckNumber] |
Line 1410... | Line 1431... | ||
1410 | pop [ebx + TCP_SOCKET.SND_WL2] |
1431 | pop [ebx + TCP_SOCKET.SND_WL2] |
Line 1411... | Line 1432... | ||
1411 | 1432 | ||
Line 1412... | Line 1433... | ||
1412 | or [ebx + TCP_SOCKET.temp_bits], TCP_BIT_NEEDOUTPUT |
1433 | or [temp_bits], TCP_BIT_NEEDOUTPUT |
1413 | 1434 | ||
Line 1473... | Line 1494... | ||
1473 | 1494 | ||
1474 | ; Ok, lets do this.. Set delayed ACK flag and copy data into socket buffer |
1495 | ; Ok, lets do this.. Set delayed ACK flag and copy data into socket buffer |
Line 1475... | Line 1496... | ||
1475 | or [ebx + TCP_SOCKET.t_flags], TF_DELACK |
1496 | or [ebx + TCP_SOCKET.t_flags], TF_DELACK |
1476 | 1497 | ||
1477 | pusha |
1498 | pusha |
1478 | movzx esi, [edx + TCP_header.DataOffset] |
1499 | mov esi, [dataoffset] |
1479 | add esi, edx |
1500 | add esi, edx |
1480 | lea eax, [ebx + STREAM_SOCKET.rcv] |
1501 | lea eax, [ebx + STREAM_SOCKET.rcv] |
1481 | call SOCKET_ring_write ; Add the data to the socket buffer |
1502 | call SOCKET_ring_write ; Add the data to the socket buffer |
Line 1487... | Line 1508... | ||
1487 | call SOCKET_notify |
1508 | call SOCKET_notify |
Line 1488... | Line 1509... | ||
1488 | 1509 | ||
Line 1489... | Line 1510... | ||
1489 | jmp .data_done |
1510 | jmp .data_done |
1490 | - | ||
1491 | .out_of_order: |
1511 | |
- | 1512 | .out_of_order: |
|
Line 1492... | Line 1513... | ||
1492 | 1513 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP data is out of order!\nSequencenumber is %u, we expected %u.\n", \ |
|
Line 1493... | Line 1514... | ||
1493 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP data is out of order\n" |
1514 | [edx + TCP_header.SequenceNumber], [ebx + TCP_SOCKET.RCV_NXT] |
Line -... | Line 1515... | ||
- | 1515 | ||
1494 | 1516 | ; Uh-oh, some data is out of order, lets call TCP reassemble for help |
|
1495 | ; Uh-oh, some data is out of order, lets call TCP reassemble for help |
1517 | |
1496 | - | ||
1497 | call TCP_reassemble |
1518 | call TCP_reassemble |
Line 1498... | Line 1519... | ||
1498 | 1519 | ||
1499 | DEBUGF DEBUG_NETWORK_VERBOSE, "1470\n" |
1520 | ; Generate ACK immediately, to let the other end know that a segment was received out of order, |
Line 1515... | Line 1536... | ||
1515 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: First FIN for this connection\n" |
1536 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: First FIN for this connection\n" |
Line 1516... | Line 1537... | ||
1516 | 1537 | ||
1517 | mov eax, ebx |
1538 | mov eax, ebx |
Line 1518... | Line 1539... | ||
1518 | call SOCKET_cant_recv_more |
1539 | call SOCKET_cant_recv_more |
1519 | 1540 | ||
Line 1520... | Line 1541... | ||
1520 | mov [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
1541 | or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
1521 | inc [ebx + TCP_SOCKET.RCV_NXT] |
1542 | inc [ebx + TCP_SOCKET.RCV_NXT] |
1522 | 1543 | ||
Line 1537... | Line 1558... | ||
1537 | dd .final_processing ; TCPS_LAST_ACK |
1558 | dd .final_processing ; TCPS_LAST_ACK |
1538 | dd .fin_wait2 ; TCPS_FIN_WAIT_2 |
1559 | dd .fin_wait2 ; TCPS_FIN_WAIT_2 |
1539 | dd .fin_timed ; TCPS_TIMED_WAIT |
1560 | dd .fin_timed ; TCPS_TIMED_WAIT |
Line 1540... | Line 1561... | ||
1540 | 1561 | ||
1541 | .fin_syn_est: |
- | |
1542 | 1562 | .fin_syn_est: |
|
1543 | mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT |
1563 | mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT |
Line 1544... | Line 1564... | ||
1544 | jmp .final_processing |
1564 | jmp .final_processing |
1545 | - | ||
1546 | .fin_wait1: |
1565 | |
1547 | 1566 | .fin_wait1: |
|
Line 1548... | Line 1567... | ||
1548 | mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSING |
1567 | mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSING |
1549 | jmp .final_processing |
- | |
1550 | 1568 | jmp .final_processing |
|
1551 | .fin_wait2: |
1569 | |
1552 | 1570 | .fin_wait2: |
|
1553 | mov [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT |
- | |
1554 | mov eax, ebx |
- | |
1555 | call TCP_cancel_timers |
1571 | mov [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT |
1556 | mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL |
- | |
Line 1557... | Line 1572... | ||
1557 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait |
1572 | mov eax, ebx |
1558 | call SOCKET_is_disconnected |
1573 | call TCP_cancel_timers |
1559 | jmp .final_processing |
1574 | call SOCKET_is_disconnected |
- | 1575 | ||
- | 1576 | .fin_timed: |
|
- | 1577 | mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL |
|
- | 1578 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait |
|
- | 1579 | ||
- | 1580 | ;----------------- |
|
- | 1581 | ; Final processing |
|
- | 1582 | ||
- | 1583 | .final_processing: |
|
- | 1584 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Final processing\n" |
|
- | 1585 | ||
- | 1586 | push ebx |
|
- | 1587 | lea ecx, [ebx + SOCKET.mutex] |
|
- | 1588 | call mutex_unlock |
|
- | 1589 | pop eax |
|
- | 1590 | ||
- | 1591 | test [temp_bits], TCP_BIT_NEEDOUTPUT |
|
- | 1592 | jnz .need_output |
|
- | 1593 | ||
- | 1594 | test [eax + TCP_SOCKET.t_flags], TF_ACKNOW |
|
- | 1595 | jz .dumpit |
|
- | 1596 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: ACK now!\n" |
|
- | 1597 | ||
- | 1598 | .need_output: |
|
- | 1599 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: need output\n" |
|
- | 1600 | call TCP_output |
|
- | 1601 | ||
1560 | 1602 | .dumpit: |
|
- | 1603 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: dumping\n" |
|
- | 1604 | ||
- | 1605 | call NET_packet_free |
|
- | 1606 | jmp .loop |
|
Line 1561... | Line 1607... | ||
1561 | .fin_timed: |
1607 | |
1562 | mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL |
1608 | |
Line 1596... | Line 1642... | ||
1596 | 1642 | ||
1597 | test [edx + TCP_header.Flags], TH_SYN |
1643 | test [edx + TCP_header.Flags], TH_SYN |
1598 | jnz .respond_syn |
1644 | jnz .respond_syn |
Line 1599... | Line -... | ||
1599 | jmp .dumpit |
- | |
1600 | - | ||
1601 | ;----------------- |
- | |
1602 | ; Final processing |
- | |
1603 | - | ||
1604 | .final_processing: |
- | |
1605 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Final processing\n" |
- | |
1606 | - | ||
1607 | push ebx |
- | |
1608 | lea ecx, [ebx + SOCKET.mutex] |
- | |
1609 | call mutex_unlock |
- | |
1610 | pop eax |
- | |
1611 | - | ||
1612 | test [eax + TCP_SOCKET.temp_bits], TCP_BIT_NEEDOUTPUT |
- | |
1613 | jnz .need_output |
- | |
1614 | - | ||
1615 | test [eax + TCP_SOCKET.t_flags], TF_ACKNOW |
- | |
1616 | jz .dumpit |
- | |
1617 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: ACK now!\n" |
- | |
1618 | - | ||
1619 | .need_output: |
- | |
1620 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: need output\n" |
- | |
1621 | call TCP_output |
- | |
1622 | - | ||
1623 | .dumpit: |
- | |
1624 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: dumping\n" |
- | |
1625 | - | ||
1626 | call NET_packet_free |
- | |
1627 | add esp, 4 |
- | |
1628 | jmp .loop |
1645 | jmp .dumpit |
1629 | 1646 | ||
Line 1630... | Line 1647... | ||
1630 | ;--------- |
1647 | ;--------- |
1631 | ; Respond |
1648 | ; Respond |
Line 1685... | Line 1702... | ||
1685 | lea ecx, [ebx + SOCKET.mutex] |
1702 | lea ecx, [ebx + SOCKET.mutex] |
1686 | call mutex_unlock |
1703 | call mutex_unlock |
1687 | popa |
1704 | popa |
Line 1688... | Line 1705... | ||
1688 | 1705 | ||
1689 | .destroy_new_socket: |
1706 | .destroy_new_socket: |
1690 | test [ebx + TCP_SOCKET.temp_bits], TCP_BIT_DROPSOCKET |
1707 | test [temp_bits], TCP_BIT_DROPSOCKET |
Line 1691... | Line 1708... | ||
1691 | jz .drop_no_socket |
1708 | jz .drop_no_socket |
1692 | 1709 | ||
Line 1693... | Line 1710... | ||
1693 | mov eax, ebx |
1710 | mov eax, ebx |
1694 | call SOCKET_free |
1711 | call SOCKET_free |
Line 1695... | Line 1712... | ||
1695 | 1712 | ||
1696 | .drop_no_socket: |
- | |
1697 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Drop (no socket)\n" |
1713 | .drop_no_socket: |
- | 1714 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Drop (no socket)\n" |
|
- | 1715 |