Subversion Repositories Kolibri OS

Rev

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