Rev 4296 | Rev 4344 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4296 | Rev 4339 | ||
---|---|---|---|
Line 76... | Line 76... | ||
76 | 76 | ||
77 | 77 | ||
- | 78 | ||
- | 79 | ||
- | 80 | align 4 |
|
- | 81 | proc TCP_process_input |
|
Line 78... | Line 82... | ||
78 | 82 | ||
79 | 83 | locals |
|
80 | align 4 |
84 | dataoffset dd ? |
81 | TCP_process_input: |
85 | endl |
Line 121... | Line 125... | ||
121 | pop edx ecx |
125 | pop edx ecx |
122 | jne .drop_no_socket |
126 | jne .drop_no_socket |
123 | .checksum_ok: |
127 | .checksum_ok: |
Line 124... | Line 128... | ||
124 | 128 | ||
- | 129 | ; Verify the data offset |
|
125 | ; Verify the data offset |
130 | 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) |
131 | and al, 0xf0 ; Calculate TCP segment header size (throwing away unused reserved bits in TCP header) |
127 | shr [edx + TCP_header.DataOffset], 2 |
132 | 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 |
133 | cmp al, sizeof.TCP_header ; Now see if it's at least the size of a standard TCP header |
- | 134 | jb .drop_no_socket ; If not, drop the packet |
|
Line 129... | Line -... | ||
129 | jb .drop_no_socket ; If not, drop the packet |
- | |
130 | 135 | mov [dataoffset], eax |
|
131 | movzx eax, [edx + TCP_header.DataOffset] |
136 | |
132 | sub ecx, eax ; substract TCP header size from total segment size |
137 | sub ecx, eax ; substract TCP header size from total segment size |
Line 133... | Line 138... | ||
133 | jb .drop_no_socket ; If total segment size is less then the advertised header size, drop packet |
138 | jb .drop_no_socket ; If total segment size is less then the advertised header size, drop packet |
Line 265... | Line 270... | ||
265 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_keepalive |
270 | or [ebx + TCP_SOCKET.timer_flags], timer_flag_keepalive |
Line 266... | Line 271... | ||
266 | 271 | ||
267 | ;-------------------- |
272 | ;-------------------- |
Line -... | Line 273... | ||
- | 273 | ; Process TCP options |
|
- | 274 | ||
- | 275 | ;;; FIXME: for LISTEN, options should be called after we determined route, we need it for MSS |
|
- | 276 | ;;; cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN ; no options when in listen state |
|
268 | ; Process TCP options |
277 | ;;; jz .not_uni_xfer ; also no header prediction |
Line 269... | Line 278... | ||
269 | 278 | ||
270 | push ecx |
279 | push ecx |
271 | 280 | ||
Line 272... | Line 281... | ||
272 | movzx ecx, [edx + TCP_header.DataOffset] |
281 | 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 | 282 | 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 |
283 | je .no_options |
Line 279... | Line 284... | ||
279 | ;;; cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN ; no options when in listen state |
284 | |
280 | ;;; jz .not_uni_xfer ; also no header prediction |
285 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Segment has options\n" |
Line 309... | Line 314... | ||
309 | jne .no_options ; error occured, ignore all options! |
314 | jne .no_options ; error occured, ignore all options! |
Line 310... | Line 315... | ||
310 | 315 | ||
311 | test [edx + TCP_header.Flags], TH_SYN |
316 | test [edx + TCP_header.Flags], TH_SYN |
Line -... | Line 317... | ||
- | 317 | jz @f |
|
312 | jz @f |
318 | |
313 | 319 | xor eax, eax |
|
314 | lodsw |
320 | lodsw |
315 | rol ax, 8 |
321 | rol ax, 8 |
316 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Maxseg=%u\n", ax |
322 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Maxseg=%u\n", eax |
317 | call TCP_mss |
323 | call TCP_mss |
Line 536... | Line 542... | ||
536 | 542 | ||
Line 537... | Line 543... | ||
537 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Header prediction: we are receiving %u bytes\n", ecx |
543 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Header prediction: we are receiving %u bytes\n", ecx |
Line 538... | Line 544... | ||
538 | 544 | ||
539 | add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Update sequence number with number of bytes we have copied |
545 | add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Update sequence number with number of bytes we have copied |
540 | 546 | ||
541 | movzx esi, [edx + TCP_header.DataOffset] |
547 | mov esi, [dataoffset] |
Line 542... | Line 548... | ||
542 | add esi, edx |
548 | add esi, edx |
Line 581... | Line 587... | ||
581 | je .SYN_SENT |
587 | je .SYN_SENT |
Line 582... | Line 588... | ||
582 | 588 | ||
583 | ;---------------------------- |
589 | ;---------------------------- |
Line 584... | Line 590... | ||
584 | ; trim any data not in window |
590 | ; trim any data not in window |
Line -... | Line 591... | ||
- | 591 | ||
585 | 592 | ; 1. Check for duplicate data at beginning of segment |
|
586 | ; check for duplicate data at beginning of segment (635) |
593 | |
587 | 594 | ; Calculate number of bytes we need to drop |
|
Line 588... | Line 595... | ||
588 | mov eax, [ebx + TCP_SOCKET.RCV_NXT] |
595 | mov eax, [ebx + TCP_SOCKET.RCV_NXT] |
Line 607... | Line 614... | ||
607 | and [edx + TCP_header.Flags], not (TH_URG) |
614 | and [edx + TCP_header.Flags], not (TH_URG) |
608 | .dup_syn: |
615 | .dup_syn: |
609 | dec eax |
616 | dec eax |
610 | .no_dup_syn: |
617 | .no_dup_syn: |
Line 611... | Line 618... | ||
611 | 618 | ||
612 | ; Check for entire duplicate segment (646) |
619 | ; 2. Check for entire duplicate segment |
613 | cmp eax, ecx ; eax holds number of bytes to drop, ecx is data size |
620 | cmp eax, ecx ; eax holds number of bytes to drop, ecx is data size |
614 | jb .duplicate |
621 | jb .duplicate |
615 | jnz @f |
622 | jnz @f |
616 | test [edx + TCP_header.Flags], TH_FIN |
623 | test [edx + TCP_header.Flags], TH_FIN |
Line 621... | Line 628... | ||
621 | ; At this point the FIN must be out of sequence or a duplicate, drop it |
628 | ; At this point the FIN must be out of sequence or a duplicate, drop it |
622 | and [edx + TCP_header.Flags], not TH_FIN |
629 | and [edx + TCP_header.Flags], not TH_FIN |
Line 623... | Line 630... | ||
623 | 630 | ||
624 | ; send an ACK and resynchronize and drop any data. |
631 | ; 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" |
632 | ; But keep on processing for RST or ACK |
627 | or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
633 | or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
- | 634 | mov eax, ecx |
|
628 | mov eax, ecx |
635 | |
Line 629... | Line 636... | ||
629 | ;TODO: update stats |
636 | ;;; TODO: update stats |
630 | 637 | ||
Line 631... | Line 638... | ||
631 | ;----------------------------------------------- |
638 | ;----------------------------------------------- |
- | 639 | ; Remove duplicate data and update urgent offset |
|
- | 640 | ||
- | 641 | .duplicate: |
|
632 | ; Remove duplicate data and update urgent offset |
642 | DEBUGF 1, "TCP_input: trimming duplicate data\n" |
633 | 643 | ||
634 | .duplicate: |
644 | ; Trim data from left side of window |
Line 635... | Line 645... | ||
635 | ;;; TODO: 677 |
645 | add [dataoffset], eax |
636 | add [edx + TCP_header.SequenceNumber], eax |
646 | add [edx + TCP_header.SequenceNumber], eax |
637 | sub ecx, eax |
647 | sub ecx, eax |
638 | 648 | ||
639 | sub [edx + TCP_header.UrgentPointer], ax |
649 | sub [edx + TCP_header.UrgentPointer], ax |
Line 640... | Line 650... | ||
640 | jg @f |
650 | jg @f |
641 | and [edx + TCP_header.Flags], not (TH_URG) |
651 | and [edx + TCP_header.Flags], not (TH_URG) |
Line 642... | Line 652... | ||
642 | mov [edx + TCP_header.UrgentPointer], 0 |
652 | mov [edx + TCP_header.UrgentPointer], 0 |
643 | @@: |
653 | @@: |
644 | 654 | ||
645 | ;-------------------------------------------------- |
655 | ;-------------------------------------------------- |
646 | ; Handle data that arrives after process terminates (687) |
656 | ; Handle data that arrives after process terminates |
647 | 657 | ||
648 | .no_duplicate: |
658 | .no_duplicate: |
Line 657... | Line 667... | ||
657 | call TCP_close |
667 | call TCP_close |
658 | ;;;TODO: update stats |
668 | ;;; TODO: update stats |
659 | jmp .respond_seg_reset |
669 | jmp .respond_seg_reset |
Line 660... | Line 670... | ||
660 | 670 | ||
661 | ;---------------------------------------- |
671 | ;---------------------------------------- |
Line 662... | Line 672... | ||
662 | ; Remove data beyond right edge of window (700-736) |
672 | ; Remove data beyond right edge of window |
663 | 673 | ||
664 | .not_terminated: |
674 | .not_terminated: |
665 | mov eax, [edx + TCP_header.SequenceNumber] |
675 | mov eax, [edx + TCP_header.SequenceNumber] |
Line 686... | Line 696... | ||
686 | mov eax, ebx |
696 | mov eax, ebx |
687 | call TCP_close |
697 | call TCP_close |
688 | jmp .findpcb ; FIXME: skip code for unscaling window, ... |
698 | jmp .findpcb ; FIXME: skip code for unscaling window, ... |
689 | .no_new_request: |
699 | .no_new_request: |
Line 690... | Line 700... | ||
690 | 700 | ||
691 | ; If window is closed can only take segments at window edge, and have to drop data and PUSH from |
701 | ; If window is closed, we can only take segments at window edge, and have to drop data and PUSH from |
Line 692... | Line 702... | ||
692 | ; incoming segments. Continue processing, but remember to ACK. Otherwise drop segment and ACK |
702 | ; incoming segments. Continue processing, but remember to ACK. Otherwise drop segment and ACK |
693 | 703 | ||
694 | cmp [ebx + TCP_SOCKET.RCV_WND], 0 |
704 | cmp [ebx + TCP_SOCKET.RCV_WND], 0 |
695 | jne .drop_after_ack |
705 | jne .drop_after_ack |
696 | mov eax, [edx + TCP_header.SequenceNumber] |
706 | mov esi, [edx + TCP_header.SequenceNumber] |
Line 697... | Line -... | ||
697 | cmp eax, [ebx + TCP_SOCKET.RCV_NXT] |
- | |
698 | jne .drop_after_ack |
707 | cmp esi, [ebx + TCP_SOCKET.RCV_NXT] |
699 | 708 | jne .drop_after_ack |
|
700 | DEBUGF DEBUG_NETWORK_VERBOSE, "690\n" |
- | |
701 | or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
709 | |
702 | ;;; TODO: update stats |
710 | or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
703 | jmp .no_excess_data |
- | |
704 | .dont_drop_all: |
- | |
705 | ;;; TODO: update stats |
711 | ;;; TODO: update stats |
- | 712 | .dont_drop_all: |
|
706 | ;;; TODO: 733 |
713 | ;;; TODO: update stats |
707 | 714 | DEBUGF 1, "Trimming %u bytes from the right of the window\n" |
|
Line 708... | Line 715... | ||
708 | sub ecx, eax |
715 | 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) |
716 | and [ebx + TCP_SOCKET.t_flags], not (TH_PUSH or TH_FIN) |
Line 710... | Line 717... | ||
710 | .no_excess_data: |
717 | .no_excess_data: |
711 | 718 | ||
712 | ;----------------- |
719 | ;----------------- |
713 | ; Record timestamp (737-746) |
720 | ; Record timestamp |
Line 1357... | Line 1364... | ||
1357 | 1364 | ||
Line 1358... | Line 1365... | ||
1358 | .trim_then_step6: |
1365 | .trim_then_step6: |
Line 1359... | Line 1366... | ||
1359 | 1366 | ||
- | 1367 | inc [edx + TCP_header.SequenceNumber] |
|
- | 1368 | ||
- | 1369 | ; Drop any received data that doesnt fit in the receive window. |
|
- | 1370 | cmp ecx, [ebx + TCP_SOCKET.RCV_WND] |
|
- | 1371 | jbe .dont_trim |
|
- | 1372 | ||
- | 1373 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: received data does not fit in window, trimming %u bytes\n", eax |
|
- | 1374 | mov ecx, [ebx + TCP_SOCKET.RCV_WND] |
|
- | 1375 | and [edx + TCP_header.Flags], not (TH_FIN) |
|
Line 1360... | Line 1376... | ||
1360 | inc [edx + TCP_header.SequenceNumber] |
1376 | ;;; TODO: update stats |
1361 | 1377 | ||
1362 | ;;; TODO: Drop any received data that follows receive window (590) |
1378 | .dont_trim: |
1363 | 1379 | ||
Line 1477... | Line 1493... | ||
1477 | 1493 | ||
1478 | ; Ok, lets do this.. Set delayed ACK flag and copy data into socket buffer |
1494 | ; Ok, lets do this.. Set delayed ACK flag and copy data into socket buffer |
Line 1479... | Line 1495... | ||
1479 | or [ebx + TCP_SOCKET.t_flags], TF_DELACK |
1495 | or [ebx + TCP_SOCKET.t_flags], TF_DELACK |
1480 | 1496 | ||
1481 | pusha |
1497 | pusha |
1482 | movzx esi, [edx + TCP_header.DataOffset] |
1498 | mov esi, [dataoffset] |
1483 | add esi, edx |
1499 | add esi, edx |
1484 | lea eax, [ebx + STREAM_SOCKET.rcv] |
1500 | lea eax, [ebx + STREAM_SOCKET.rcv] |
1485 | call SOCKET_ring_write ; Add the data to the socket buffer |
1501 | call SOCKET_ring_write ; Add the data to the socket buffer |
Line 1491... | Line 1507... | ||
1491 | call SOCKET_notify |
1507 | call SOCKET_notify |
Line 1492... | Line 1508... | ||
1492 | 1508 | ||
Line 1493... | Line 1509... | ||
1493 | jmp .data_done |
1509 | jmp .data_done |
1494 | - | ||
1495 | .out_of_order: |
1510 | |
- | 1511 | .out_of_order: |
|
Line 1496... | Line 1512... | ||
1496 | 1512 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP data is out of order!\nSequencenumber is %u, we expected %u.\n", \ |
|
Line 1497... | Line 1513... | ||
1497 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP data is out of order\n" |
1513 | [edx + TCP_header.SequenceNumber], [ebx + TCP_SOCKET.RCV_NXT] |
Line -... | Line 1514... | ||
- | 1514 | ||
1498 | 1515 | ; Uh-oh, some data is out of order, lets call TCP reassemble for help |
|
1499 | ; Uh-oh, some data is out of order, lets call TCP reassemble for help |
1516 | |
Line 1500... | Line 1517... | ||
1500 | 1517 | call TCP_reassemble |
|
Line 1501... | Line 1518... | ||
1501 | call TCP_reassemble |
1518 | |
Line 1701... | Line 1718... | ||
1701 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Drop (no socket)\n" |
1718 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Drop (no socket)\n" |
Line 1702... | Line 1719... | ||
1702 | 1719 | ||
1703 | call NET_packet_free |
1720 | call NET_packet_free |
1704 | add esp, 4 |
1721 | add esp, 4 |
- | 1722 | jmp .loop |
|
- | 1723 |