Subversion Repositories Kolibri OS

Rev

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