Subversion Repositories Kolibri OS

Rev

Rev 2942 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1763 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2362 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved.    ;;
1763 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  Part of the tcp/ip network stack for KolibriOS                 ;;
7
;;                                                                 ;;
8
;;   Written by hidnplayr@kolibrios.org                            ;;
9
;;                                                                 ;;
10
;;    Based on the code of 4.4BSD                                  ;;
11
;;                                                                 ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
13
;;             Version 2, June 1991                                ;;
14
;;                                                                 ;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16
 
17
$Revision: 2946 $
18
 
1733 hidnplayr 19
;-----------------------------------------------------------------
20
;
21
; TCP_input:
22
;
23
;  IN:  [esp] = ptr to buffer
24
;       [esp+4] = buffer size
25
;       ebx = ptr to device struct
26
;       ecx = segment size
2310 hidnplayr 27
;       esi = ptr to TCP segment
2308 hidnplayr 28
;       edi = ptr to ipv4 source address, followed by ipv4 dest address
1733 hidnplayr 29
;
30
;  OUT: /
31
;
32
;-----------------------------------------------------------------
1830 hidnplayr 33
 
1733 hidnplayr 34
align 4
35
TCP_input:
36
 
2942 hidnplayr 37
        pushfd
38
        cli
39
 
2891 hidnplayr 40
        DEBUGF  1,"TCP_input: size=%u\n", ecx
1733 hidnplayr 41
 
2930 hidnplayr 42
; First, record the current time
2937 hidnplayr 43
        mov     eax, [timer_ticks]      ; in 1/100 seconds
2942 hidnplayr 44
        mov     [esp+8], eax
1733 hidnplayr 45
 
2930 hidnplayr 46
; then, re-calculate the checksum (if not already done by hw)
47
;        test    [ebx + NET_DEVICE.hwacc], HWACC_TCP_IPv4_IN
48
;        jnz     .checksum_ok
49
 
2390 hidnplayr 50
        push    ecx esi
51
        pushw   [esi + TCP_header.Checksum]
52
        mov     [esi + TCP_header.Checksum], 0
53
        TCP_checksum (edi), (edi+4)
2937 hidnplayr 54
        pop     cx                      ; previous checksum
2390 hidnplayr 55
        cmp     cx, dx
56
        pop     edx ecx
2600 hidnplayr 57
        jne     .drop_no_socket
2930 hidnplayr 58
  .checksum_ok:
1733 hidnplayr 59
 
2930 hidnplayr 60
; Verify the data offset
2390 hidnplayr 61
        and     [edx + TCP_header.DataOffset], 0xf0                     ; Calculate TCP segment header size (throwing away unused reserved bits in TCP header)
62
        shr     [edx + TCP_header.DataOffset], 2
63
        cmp     [edx + TCP_header.DataOffset], sizeof.TCP_header        ; Now see if it's at least the size of a standard TCP header
2600 hidnplayr 64
        jb      .drop_no_socket                                         ; If not, drop the packet
1733 hidnplayr 65
 
2390 hidnplayr 66
        movzx   eax, [edx + TCP_header.DataOffset]
67
        sub     ecx, eax                                                ; substract TCP header size from total segment size
2600 hidnplayr 68
        jb      .drop_no_socket                                         ; If total segment size is less then the advertised header size, drop packet
2891 hidnplayr 69
        DEBUGF  1,"TCP_input: %u bytes of data\n", ecx
1733 hidnplayr 70
 
71
;-------------------------------------------
72
; Convert Big-endian values to little endian
73
 
2390 hidnplayr 74
        ntohd   [edx + TCP_header.SequenceNumber]
75
        ntohd   [edx + TCP_header.AckNumber]
1733 hidnplayr 76
 
2390 hidnplayr 77
        ntohw   [edx + TCP_header.Window]
78
        ntohw   [edx + TCP_header.UrgentPointer]
79
        ntohw   [edx + TCP_header.SourcePort]
80
        ntohw   [edx + TCP_header.DestinationPort]
1733 hidnplayr 81
 
2930 hidnplayr 82
;------------------------
83
; Find the socket pointer
1733 hidnplayr 84
 
85
; IP Packet TCP Destination Port = local Port
86
; (IP Packet SenderAddress = Remote IP)  OR  (Remote IP = 0)
2309 hidnplayr 87
; (IP Packet TCP Source Port = remote Port) OR (remote Port = 0)
1733 hidnplayr 88
 
2937 hidnplayr 89
  .findpcb:
2390 hidnplayr 90
        mov     ebx, net_sockets
91
        mov     si, [edx + TCP_header.DestinationPort]
1733 hidnplayr 92
 
93
  .socket_loop:
2390 hidnplayr 94
        mov     ebx, [ebx + SOCKET.NextPtr]
95
        or      ebx, ebx
2600 hidnplayr 96
        jz      .drop_with_reset_no_socket
1733 hidnplayr 97
 
2390 hidnplayr 98
        cmp     [ebx + SOCKET.Domain], AF_INET4
99
        jne     .socket_loop
1733 hidnplayr 100
 
2390 hidnplayr 101
        cmp     [ebx + SOCKET.Protocol], IP_PROTO_TCP
102
        jne     .socket_loop
1733 hidnplayr 103
 
2390 hidnplayr 104
        cmp     [ebx + TCP_SOCKET.LocalPort], si
105
        jne     .socket_loop
1733 hidnplayr 106
 
2390 hidnplayr 107
        mov     eax, [ebx + IP_SOCKET.RemoteIP]
108
        cmp     eax, [edi]                              ; Ipv4 source addres
109
        je      @f
110
        test    eax, eax
111
        jnz     .socket_loop
1733 hidnplayr 112
       @@:
113
 
2390 hidnplayr 114
        mov     ax, [ebx + TCP_SOCKET.RemotePort]
115
        cmp     [edx + TCP_header.SourcePort], ax
116
        je      .found_socket
117
        test    ax, ax
118
        jnz     .socket_loop
119
  .found_socket:                                        ; ebx now contains the socketpointer
2891 hidnplayr 120
        DEBUGF  1,"TCP_input: socket ptr=%x state=%u flags=%x\n", ebx, [ebx + TCP_SOCKET.t_state], [edx + TCP_header.Flags]:2
1733 hidnplayr 121
 
2930 hidnplayr 122
;-------------
2890 hidnplayr 123
; update stats
2930 hidnplayr 124
 
2890 hidnplayr 125
        inc     [TCP_segments_rx]                       ; FIXME: correct interface?
1733 hidnplayr 126
 
127
;----------------------------
128
; Check if socket isnt closed
129
 
2390 hidnplayr 130
        cmp     [ebx + TCP_SOCKET.t_state], TCPS_CLOSED
2937 hidnplayr 131
        je      .drop_no_socket
1733 hidnplayr 132
 
133
;----------------
134
; Lock the socket
135
 
2402 hidnplayr 136
        pusha
137
        lea     ecx, [ebx + SOCKET.mutex]
138
        call    mutex_lock
139
        popa
1830 hidnplayr 140
 
2891 hidnplayr 141
        DEBUGF  1,"TCP_input: socket locked\n"
1733 hidnplayr 142
 
2937 hidnplayr 143
;---------------------------
144
; disable all temporary bits
2891 hidnplayr 145
 
2937 hidnplayr 146
        mov     [ebx + TCP_SOCKET.temp_bits], 0
2891 hidnplayr 147
 
1733 hidnplayr 148
;---------------------------------------
149
; unscale the window into a 32 bit value
150
 
2390 hidnplayr 151
        movzx   eax, [edx + TCP_header.Window]
152
        push    ecx
153
        mov     cl, [ebx + TCP_SOCKET.SND_SCALE]
154
        shl     eax, cl
155
        mov     dword [edx + TCP_header.Window], eax    ; word after window is checksum, we dont need checksum anymore
156
        pop     ecx
1733 hidnplayr 157
 
2930 hidnplayr 158
;---------------------------------------
159
; Are we accepting incoming connections?
1733 hidnplayr 160
 
2390 hidnplayr 161
        test    [ebx + SOCKET.options], SO_ACCEPTCON
2930 hidnplayr 162
        jnz     .accept_connection
1733 hidnplayr 163
 
164
;-------------------------------------
165
; Reset idle timer and keepalive timer
166
 
2390 hidnplayr 167
        mov     [ebx + TCP_SOCKET.t_idle], 0
168
        mov     [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval
1733 hidnplayr 169
 
170
;--------------------
171
; Process TCP options
172
 
2390 hidnplayr 173
        movzx   eax, [edx + TCP_header.DataOffset]
174
        cmp     eax, sizeof.TCP_header                  ; Does header contain any options?
175
        je      .no_options
1733 hidnplayr 176
 
2891 hidnplayr 177
        DEBUGF  1,"TCP_input: Segment has options\n"
1733 hidnplayr 178
 
2390 hidnplayr 179
        cmp     [ebx + TCP_SOCKET.t_state], TCPS_LISTEN ; no options when in listen state
180
        jz      .not_uni_xfer                           ; also no header prediction
1733 hidnplayr 181
 
2390 hidnplayr 182
        add     eax, edx
183
        lea     esi, [edx + sizeof.TCP_header]
1733 hidnplayr 184
 
185
  .opt_loop:
2390 hidnplayr 186
        cmp     esi, eax                        ; are we scanning outside of header?
187
        jae     .no_options
1733 hidnplayr 188
 
2390 hidnplayr 189
        cmp     byte [esi], TCP_OPT_EOL         ; end of option list?
190
        jz      .no_options
1733 hidnplayr 191
 
2390 hidnplayr 192
        cmp     byte [esi], TCP_OPT_NOP         ; nop ?
193
        jz      .opt_nop
1733 hidnplayr 194
 
2390 hidnplayr 195
        cmp     byte [esi], TCP_OPT_MAXSEG
196
        je      .opt_maxseg
1733 hidnplayr 197
 
2390 hidnplayr 198
        cmp     byte [esi], TCP_OPT_WINDOW
199
        je      .opt_window
1733 hidnplayr 200
 
2390 hidnplayr 201
        cmp     byte [esi], TCP_OPT_TIMESTAMP
202
        je      .opt_timestamp
1733 hidnplayr 203
 
2937 hidnplayr 204
        jmp     .no_options                     ; If we reach here, some unknown options were received, skip them all!
1733 hidnplayr 205
 
206
  .opt_nop:
2930 hidnplayr 207
        inc     esi
2390 hidnplayr 208
        jmp     .opt_loop
1733 hidnplayr 209
 
210
  .opt_maxseg:
2390 hidnplayr 211
        cmp     byte [esi+1], 4
2937 hidnplayr 212
        jne     .no_options                     ; error occured, ignore all options!
1733 hidnplayr 213
 
2390 hidnplayr 214
        test    [edx + TCP_header.Flags], TH_SYN
215
        jz      @f
1733 hidnplayr 216
 
2390 hidnplayr 217
        movzx   eax, word[esi+2]
218
        rol     ax, 8
2891 hidnplayr 219
        DEBUGF  1,"TCP_input: Maxseg=%u\n", ax
2390 hidnplayr 220
        mov     [ebx + TCP_SOCKET.t_maxseg], eax
1733 hidnplayr 221
 
222
       @@:
2930 hidnplayr 223
        add     esi, 4
2390 hidnplayr 224
        jmp     .opt_loop
1733 hidnplayr 225
 
226
 
227
  .opt_window:
2390 hidnplayr 228
        cmp     byte [esi+1], 3
229
        jne     .no_options
1733 hidnplayr 230
 
2390 hidnplayr 231
        test    [edx + TCP_header.Flags], TH_SYN
232
        jz      @f
1733 hidnplayr 233
 
2891 hidnplayr 234
        DEBUGF  1,"TCP_input: Got window option\n"
1733 hidnplayr 235
 
2390 hidnplayr 236
        ;;;;;
1733 hidnplayr 237
       @@:
2930 hidnplayr 238
        add     esi, 3
2390 hidnplayr 239
        jmp     .opt_loop
1733 hidnplayr 240
 
241
 
242
  .opt_timestamp:
2937 hidnplayr 243
        cmp     byte [esi+1], 10                ; length must be 10
2390 hidnplayr 244
        jne     .no_options
1733 hidnplayr 245
 
2891 hidnplayr 246
        DEBUGF  1,"TCP_input: Got timestamp option\n"
1733 hidnplayr 247
 
2937 hidnplayr 248
        push    dword [esi + 2]                 ; timestamp
249
        pop     [ebx + TCP_SOCKET.ts_val]
250
        push    dword [esi + 6]                 ; timestamp echo reply
2930 hidnplayr 251
        pop     [ebx + TCP_SOCKET.ts_ecr]
2937 hidnplayr 252
        or      [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP
2930 hidnplayr 253
 
2946 hidnplayr 254
        ; Since we have a timestamp, lets do the paws test right away!
255
 
256
        test    [edx + TCP_header.Flags], TH_RST
257
        jnz     .no_paws
258
 
259
        mov     eax, [ebx + TCP_SOCKET.ts_recent]
260
        test    eax, eax
261
        jz      .no_paws
262
        cmp     eax, [ebx + TCP_SOCKET.ts_val]
263
        jge     .no_paws
264
 
265
        DEBUGF  1,"TCP_input: PAWS: detected an old segment\n"
266
 
267
        mov     eax, [esp+4+4]                          ; tcp_now
268
        sub     eax, [ebx + TCP_SOCKET.ts_recent_age]
269
        cmp     eax, TCP_PAWS_IDLE
270
        jle     .dropafterack                           ; TODO: update stats
271
 
272
        mov     [ebx + TCP_SOCKET.ts_recent], 0         ; timestamp was invalid, fix it.
273
  .no_paws:
274
 
2390 hidnplayr 275
        add     esi, 10
276
        jmp     .opt_loop
1733 hidnplayr 277
 
278
  .no_options:
279
 
280
;-----------------------------------------------------------------------
281
; Time to do some header prediction (Original Principle by Van Jacobson)
282
 
283
; There are two common cases for an uni-directional data transfer.
284
;
285
; General rule: the packets has no control flags, is in-sequence,
286
;   window width didnt change and we're not retransmitting.
287
;
288
; Second rules:
289
;  -  If the length is 0 and the ACK moved forward, we're the sender side of the transfer.
290
;      In this case we'll free the ACK'ed data and notify higher levels that we have free space in buffer
291
;
292
;  -  If the length is not 0 and the ACK didn't move, we're the receiver side of the transfer.
293
;      If the packets are in order (data queue is empty), add the data to the socket buffer and request a delayed ACK
294
 
2390 hidnplayr 295
        cmp     [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED
296
        jnz     .not_uni_xfer
1733 hidnplayr 297
 
2390 hidnplayr 298
        test    [edx + TCP_header.Flags], TH_SYN + TH_FIN + TH_RST + TH_URG
299
        jnz     .not_uni_xfer
1733 hidnplayr 300
 
2390 hidnplayr 301
        test    [edx + TCP_header.Flags], TH_ACK
302
        jz      .not_uni_xfer
1733 hidnplayr 303
 
2390 hidnplayr 304
        mov     eax, [edx + TCP_header.SequenceNumber]
305
        cmp     eax, [ebx + TCP_SOCKET.RCV_NXT]
306
        jne     .not_uni_xfer
1733 hidnplayr 307
 
2390 hidnplayr 308
        mov     eax, dword [edx + TCP_header.Window]
309
        cmp     eax, [ebx + TCP_SOCKET.SND_WND]
310
        jne     .not_uni_xfer
1733 hidnplayr 311
 
2390 hidnplayr 312
        mov     eax, [ebx + TCP_SOCKET.SND_NXT]
313
        cmp     eax, [ebx + TCP_SOCKET.SND_MAX]
314
        jne     .not_uni_xfer
1733 hidnplayr 315
 
316
;---------------------------------------
317
; check if we are sender in the uni-xfer
318
 
319
; If the following 4 conditions are all true, this segment is a pure ACK.
320
;
321
; - The segment contains no data.
2390 hidnplayr 322
        test    ecx, ecx
323
        jnz     .not_sender
1733 hidnplayr 324
 
325
; - The congestion window is greater than or equal to the current send window.
326
;     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.
2390 hidnplayr 327
        mov     eax, [ebx + TCP_SOCKET.SND_CWND]
328
        cmp     eax, [ebx + TCP_SOCKET.SND_WND]
329
        jb      .not_uni_xfer
1733 hidnplayr 330
 
331
; - The acknowledgment field in the segment is less than or equal to the maximum sequence number sent.
2390 hidnplayr 332
        mov     eax, [edx + TCP_header.AckNumber]
333
        cmp     eax, [ebx + TCP_SOCKET.SND_MAX]
334
        ja      .not_uni_xfer
1733 hidnplayr 335
 
336
; - The acknowledgment field in the segment is greater than the largest unacknowledged sequence number.
2390 hidnplayr 337
        sub     eax, [ebx + TCP_SOCKET.SND_UNA]
338
        jbe     .not_uni_xfer
1733 hidnplayr 339
 
2891 hidnplayr 340
        DEBUGF  1,"TCP_input: Header prediction: we are sender\n"
1733 hidnplayr 341
 
342
;---------------------------------
343
; Packet is a pure ACK, process it
344
 
345
; Delete acknowledged bytes from send buffer
2390 hidnplayr 346
        pusha
347
        mov     ecx, eax
348
        lea     eax, [ebx + STREAM_SOCKET.snd]
349
        call    SOCKET_ring_free
350
        popa
1733 hidnplayr 351
 
2930 hidnplayr 352
; Update RTT estimators
353
 
2937 hidnplayr 354
        test    [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP
355
        jz      .no_timestamp_rtt
2942 hidnplayr 356
        mov     eax, [esp + 4+4]                         ; timestamp when this segment was received
2937 hidnplayr 357
        sub     eax, [ebx + TCP_SOCKET.ts_ecr]
358
        inc     eax
359
        call    TCP_xmit_timer
360
        jmp     .rtt_done
2930 hidnplayr 361
 
2937 hidnplayr 362
  .no_timestamp_rtt:
363
        cmp     [ebx + TCP_SOCKET.t_rtt], 0
364
        je      .rtt_done
365
        mov     eax, [edx + TCP_header.AckNumber]
366
        cmp     eax, [ebx + TCP_SOCKET.t_rtseq]
367
        jbe     .rtt_done
368
        mov     eax, [ebx + TCP_SOCKET.t_rtt]
369
        call    TCP_xmit_timer
2930 hidnplayr 370
 
2937 hidnplayr 371
  .rtt_done:
372
 
1733 hidnplayr 373
; update window pointers
2390 hidnplayr 374
        mov     eax, [edx + TCP_header.AckNumber]
375
        mov     [ebx + TCP_SOCKET.SND_UNA], eax
1733 hidnplayr 376
 
377
; Stop retransmit timer
2390 hidnplayr 378
        mov     [ebx + TCP_SOCKET.timer_retransmission], 0
1733 hidnplayr 379
 
380
; Awaken waiting processes
2402 hidnplayr 381
        pusha
382
        lea     ecx, [ebx + SOCKET.mutex]
383
        call    mutex_unlock
384
        popa
385
 
2390 hidnplayr 386
        mov     eax, ebx
387
        call    SOCKET_notify_owner
1733 hidnplayr 388
 
1763 hidnplayr 389
; Generate more output
2390 hidnplayr 390
        call    TCP_output
1733 hidnplayr 391
 
2937 hidnplayr 392
        jmp     .drop_no_socket
1763 hidnplayr 393
 
1733 hidnplayr 394
;-------------------------------------------------
395
; maybe we are the receiver in the uni-xfer then..
396
 
397
  .not_sender:
398
; - The amount of data in the segment is greater than 0 (data count is in ecx)
399
 
400
; - The acknowledgment field equals the largest unacknowledged sequence number. This means no data is acknowledged by this segment.
2390 hidnplayr 401
        mov     eax, [edx + TCP_header.AckNumber]
402
        cmp     eax, [ebx + TCP_SOCKET.SND_UNA]
403
        jne     .not_uni_xfer
1733 hidnplayr 404
 
405
; - The reassembly list of out-of-order segments for the connection is empty (seg_next equals tp).
406
 
407
;;; TODO
408
 
2930 hidnplayr 409
;       jnz     .not_uni_xfer
1733 hidnplayr 410
 
411
; Complete processing of received data
412
 
2891 hidnplayr 413
        DEBUGF  1,"TCP_input: Header prediction: we are receiving %u bytes\n", ecx
1733 hidnplayr 414
 
2390 hidnplayr 415
        add     [ebx + TCP_SOCKET.RCV_NXT], ecx         ; Update sequence number with number of bytes we have copied
1763 hidnplayr 416
 
2390 hidnplayr 417
        movzx   esi, [edx + TCP_header.DataOffset]
418
        add     esi, edx
419
        lea     eax, [ebx + STREAM_SOCKET.rcv]
420
        call    SOCKET_ring_write                       ; Add the data to the socket buffer
1733 hidnplayr 421
 
2390 hidnplayr 422
        mov     eax, ebx
423
        call    SOCKET_notify_owner
1733 hidnplayr 424
 
2390 hidnplayr 425
        or      [ebx + TCP_SOCKET.t_flags], TF_DELACK   ; Set delayed ack flag
1733 hidnplayr 426
 
2390 hidnplayr 427
        jmp     .drop
1733 hidnplayr 428
 
429
 
430
 
431
 
432
 
433
 
434
;--------------------------------------------------
435
; Header prediction failed, do it the slow way
436
 
437
  .not_uni_xfer:
438
 
2891 hidnplayr 439
        DEBUGF  1,"TCP_input: Header prediction failed\n"
1733 hidnplayr 440
 
441
; Calculate receive window size
442
 
2942 hidnplayr 443
        push    edx
2937 hidnplayr 444
        mov     eax, SOCKETBUFFSIZE
445
        sub     eax, [ebx + STREAM_SOCKET.rcv.size]
446
        mov     edx, [ebx + TCP_SOCKET.RCV_ADV]
447
        sub     edx, [ebx + TCP_SOCKET.RCV_NXT]
448
        cmp     eax, edx
2942 hidnplayr 449
        jg      @f
2937 hidnplayr 450
        mov     eax, edx
451
       @@:
2942 hidnplayr 452
        DEBUGF  1,"Receive window size=%d\n", ax
2937 hidnplayr 453
        mov     [ebx + TCP_SOCKET.RCV_WND], ax
2942 hidnplayr 454
        pop     edx
1733 hidnplayr 455
 
2937 hidnplayr 456
; If listen or Syn sent, go to that specific code right away
457
 
2390 hidnplayr 458
        cmp     [ebx + TCP_SOCKET.t_state], TCPS_LISTEN
459
        je      .LISTEN
1733 hidnplayr 460
 
2390 hidnplayr 461
        cmp     [ebx + TCP_SOCKET.t_state], TCPS_SYN_SENT
462
        je      .SYN_SENT
1733 hidnplayr 463
 
2891 hidnplayr 464
        DEBUGF  1,"TCP_input: state is not listen or syn_sent\n"
1733 hidnplayr 465
 
466
;----------------------------
467
; trim any data not in window
468
 
469
; check for duplicate data at beginning of segment
470
 
2390 hidnplayr 471
        mov     eax, [ebx + TCP_SOCKET.RCV_NXT]
472
        sub     eax, [edx + TCP_header.SequenceNumber]
2942 hidnplayr 473
        jle     .no_duplicate
1733 hidnplayr 474
 
2891 hidnplayr 475
        DEBUGF  1,"TCP_input: %u bytes duplicate data!\n", eax
1763 hidnplayr 476
 
2390 hidnplayr 477
        test    [edx + TCP_header.Flags], TH_SYN
478
        jz      .no_dup_syn
1733 hidnplayr 479
 
2942 hidnplayr 480
        DEBUGF  1,"TCP_input: got duplicate syn\n"
1733 hidnplayr 481
 
2390 hidnplayr 482
        and     [edx + TCP_header.Flags], not (TH_SYN)
483
        inc     [edx + TCP_header.SequenceNumber]
1733 hidnplayr 484
 
2390 hidnplayr 485
        cmp     [edx + TCP_header.UrgentPointer], 1
486
        jbe     @f
487
        dec     [edx + TCP_header.UrgentPointer]
488
        jmp     .dup_syn
1733 hidnplayr 489
       @@:
2390 hidnplayr 490
        and     [edx + TCP_header.Flags], not (TH_URG)
1838 hidnplayr 491
  .dup_syn:
2390 hidnplayr 492
        dec     eax
1763 hidnplayr 493
  .no_dup_syn:
1733 hidnplayr 494
 
2937 hidnplayr 495
; Check for entire duplicate segment
496
        cmp     eax, ecx                ; eax holds number of bytes to drop, ecx is data size
497
        jb      .duplicate
498
        jnz     @f
2390 hidnplayr 499
        test    [edx + TCP_header.Flags], TH_FIN
2937 hidnplayr 500
        jnz     .duplicate
501
       @@:
1733 hidnplayr 502
 
2937 hidnplayr 503
; Any valid FIN must be to the left of the window.
504
; At this point the FIN must be out of sequence or a duplicate, drop it
2390 hidnplayr 505
        and     [edx + TCP_header.Flags], not TH_FIN
2937 hidnplayr 506
 
507
; send an ACK and resynchronize and drop any data.
508
; But keep on processing for RST or ACK
2390 hidnplayr 509
        or      [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
2937 hidnplayr 510
        mov     eax, ecx
511
;TODO: update stats
1733 hidnplayr 512
 
513
;-----------------------------------------------
514
; Remove duplicate data and update urgent offset
515
 
2937 hidnplayr 516
  .duplicate:
517
;;; TODO: 677
2390 hidnplayr 518
        add     [edx + TCP_header.SequenceNumber], eax
2937 hidnplayr 519
        sub     ecx, eax
1733 hidnplayr 520
 
2390 hidnplayr 521
        sub     [edx + TCP_header.UrgentPointer], ax
2942 hidnplayr 522
        jg      @f
2390 hidnplayr 523
        and     [edx + TCP_header.Flags], not (TH_URG)
524
        mov     [edx + TCP_header.UrgentPointer], 0
1733 hidnplayr 525
       @@:
526
 
527
;--------------------------------------------------
528
; Handle data that arrives after process terminates
529
 
2937 hidnplayr 530
  .no_duplicate:
2390 hidnplayr 531
        cmp     [ebx + SOCKET.PID], 0
2937 hidnplayr 532
        jne     .not_terminated
2390 hidnplayr 533
        cmp     [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT
2937 hidnplayr 534
        jbe     .not_terminated
2390 hidnplayr 535
        test    ecx, ecx
2937 hidnplayr 536
        jz      .not_terminated
1733 hidnplayr 537
 
2937 hidnplayr 538
        mov     eax, ebx
539
        call    TCP_close
540
;;;TODO: update stats
2390 hidnplayr 541
        jmp     .drop_with_reset
1733 hidnplayr 542
 
543
;----------------------------------------
2937 hidnplayr 544
; Remove data beyond right edge of window (700-736)
1733 hidnplayr 545
 
2937 hidnplayr 546
  .not_terminated:
2390 hidnplayr 547
        mov     eax, [edx + TCP_header.SequenceNumber]
548
        add     eax, ecx
549
        sub     eax, [ebx + TCP_SOCKET.RCV_NXT]
2937 hidnplayr 550
        sub     ax, [ebx + TCP_SOCKET.RCV_WND]          ; eax now holds the number of bytes to drop
2942 hidnplayr 551
        jle     .no_excess_data
1733 hidnplayr 552
 
2942 hidnplayr 553
        DEBUGF  1,"%d bytes beyond right edge of window\n", eax
554
 
1733 hidnplayr 555
;;; TODO: update stats
2390 hidnplayr 556
        cmp     eax, ecx
2942 hidnplayr 557
        jl      .dont_drop_all
2937 hidnplayr 558
; If a new connection request is received while in TIME_WAIT, drop the old connection and start over,
559
; if the sequence numbers are above the previous ones
1733 hidnplayr 560
 
2937 hidnplayr 561
        test    [edx + TCP_header.Flags], TH_SYN
562
        jz      .no_new_request
563
        cmp     [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT
564
        jne     .no_new_request
2942 hidnplayr 565
;        mov     edx, [ebx + TCP_SOCKET.RCV_NXT]
566
;        cmp     edx, [edx + TCP_header.SequenceNumber]
567
;        add     edx, 64000      ; TCP_ISSINCR   FIXME
2937 hidnplayr 568
        mov     eax, ebx
569
        call    TCP_close
570
        jmp     .findpcb        ; FIXME: skip code for unscaling window, ...
571
  .no_new_request:
1733 hidnplayr 572
 
2937 hidnplayr 573
; If window is closed can only take segments at window edge, and have to drop data and PUSH from
574
; incoming segments. Continue processing, but remember to ACK. Otherwise drop segment and ACK
575
 
576
        cmp     [ebx + TCP_SOCKET.RCV_WND], 0
577
        jne     .drop_after_ack
578
        mov     eax, [edx + TCP_header.SequenceNumber]
579
        cmp     eax, [ebx + TCP_SOCKET.RCV_NXT]
580
        jne     .drop_after_ack
581
 
582
        or      [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
583
;;; TODO: update stats
584
        jmp     .no_excess_data
1733 hidnplayr 585
  .dont_drop_all:
2937 hidnplayr 586
;;; TODO: update stats
587
;;; TODO: 733
588
        sub     ecx, eax
589
        and     [ebx + TCP_SOCKET.t_flags], not (TH_PUSH or TH_FIN)
1733 hidnplayr 590
  .no_excess_data:
591
 
592
;-----------------
2937 hidnplayr 593
; Record timestamp (737-746) TODO
1733 hidnplayr 594
 
2937 hidnplayr 595
; If last ACK falls within this segments sequence numbers, record its timestamp
596
        test    [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP
597
        jz      .no_timestamp
598
        mov     eax, [ebx + TCP_SOCKET.last_ack_sent]
599
        sub     eax, [edx + TCP_header.SequenceNumber]
600
        jb      .no_timestamp
601
        test    [ebx + TCP_header.Flags], TH_SYN or TH_FIN      ; syn and fin occupy one byte
602
        jz      @f
603
        dec     eax
604
       @@:
605
        sub     eax, ecx
606
        jae     .no_timestamp
1733 hidnplayr 607
 
2942 hidnplayr 608
        mov     eax, [esp + 4+4]                                  ; tcp_now
2937 hidnplayr 609
        mov     [ebx + TCP_SOCKET.ts_recent_age], eax
610
        mov     eax, [ebx + TCP_SOCKET.ts_val]
611
        mov     [ebx + TCP_SOCKET.ts_recent], eax
612
  .no_timestamp:
1733 hidnplayr 613
 
614
;------------------
615
; Process RST flags
616
 
2390 hidnplayr 617
        test    [edx + TCP_header.Flags], TH_RST
2891 hidnplayr 618
        jz      .no_rst
1733 hidnplayr 619
 
2891 hidnplayr 620
        DEBUGF  1,"TCP_input: Got an RST flag\n"
1733 hidnplayr 621
 
2390 hidnplayr 622
        mov     eax, [ebx + TCP_SOCKET.t_state]
623
        shl     eax, 2
624
        jmp     dword [eax + .rst_sw_list]
1733 hidnplayr 625
 
626
  .rst_sw_list:
2891 hidnplayr 627
        dd      .no_rst         ; TCPS_CLOSED
628
        dd      .no_rst         ; TCPS_LISTEN
629
        dd      .no_rst         ; TCPS_SYN_SENT
630
        dd      .econnrefused   ; TCPS_SYN_RECEIVED
631
        dd      .econnreset     ; TCPS_ESTABLISHED
632
        dd      .econnreset     ; TCPS_CLOSE_WAIT
633
        dd      .econnreset     ; TCPS_FIN_WAIT_1
634
        dd      .rst_close      ; TCPS_CLOSING
635
        dd      .rst_close      ; TCPS_LAST_ACK
636
        dd      .econnreset     ; TCPS_FIN_WAIT_2
637
        dd      .rst_close      ; TCPS_TIMED_WAIT
1733 hidnplayr 638
 
639
  .econnrefused:
2891 hidnplayr 640
        DEBUGF  1,"TCP_input: Connection refused\n"
1733 hidnplayr 641
 
2390 hidnplayr 642
        mov     [ebx + SOCKET.errorcode], ECONNREFUSED
643
        jmp     .close
1733 hidnplayr 644
 
645
  .econnreset:
2891 hidnplayr 646
        DEBUGF  1,"TCP_input: Connection reset\n"
1733 hidnplayr 647
 
2390 hidnplayr 648
        mov     [ebx + SOCKET.errorcode], ECONNRESET
1733 hidnplayr 649
 
2882 hidnplayr 650
  .close:
2891 hidnplayr 651
        DEBUGF  1,"TCP_input: Closing connection\n"
1733 hidnplayr 652
 
2390 hidnplayr 653
        mov     [ebx + TCP_SOCKET.t_state], TCPS_CLOSED
2937 hidnplayr 654
;;; TODO: update stats (tcp drops)
2390 hidnplayr 655
        mov     eax, ebx
656
        call    TCP_close
657
        jmp     .drop
1733 hidnplayr 658
 
659
  .rst_close:
2891 hidnplayr 660
        DEBUGF  1,"TCP_input: Closing with reset\n"
1733 hidnplayr 661
 
2390 hidnplayr 662
        mov     eax, ebx
663
        call    TCP_close
664
        jmp     .drop
1733 hidnplayr 665
 
2891 hidnplayr 666
  .no_rst:
1733 hidnplayr 667
 
668
;--------------------------------------
669
; handle SYN-full and ACK-less segments
670
 
2390 hidnplayr 671
        test    [edx + TCP_header.Flags], TH_SYN
2937 hidnplayr 672
        jz      .not_syn_full
1733 hidnplayr 673
 
2390 hidnplayr 674
        mov     eax, ebx
675
        mov     ebx, ECONNRESET
676
        call    TCP_drop
677
        jmp     .drop_with_reset
2937 hidnplayr 678
  .not_syn_full:
1733 hidnplayr 679
 
680
;---------------
681
; ACK processing
682
 
2891 hidnplayr 683
        test    [edx + TCP_header.Flags], TH_ACK
684
        jz      .drop
685
 
2390 hidnplayr 686
        cmp     [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED
2937 hidnplayr 687
        jb      .ack_processed                                  ; states: closed, listen, syn_sent
688
        ja      .no_syn_rcv                                     ; established, fin_wait_1, fin_wait_2, close_wait, closing, last_ack, time_wait
1733 hidnplayr 689
 
2891 hidnplayr 690
        DEBUGF  1,"TCP_input: state=syn_received\n"
1733 hidnplayr 691
 
2390 hidnplayr 692
        mov     eax, [edx + TCP_header.AckNumber]
693
        cmp     [ebx + TCP_SOCKET.SND_UNA], eax
694
        ja      .drop_with_reset
695
        cmp     eax, [ebx + TCP_SOCKET.SND_MAX]
696
        ja      .drop_with_reset
1733 hidnplayr 697
 
2309 hidnplayr 698
;;; TODO: update stats
699
 
2390 hidnplayr 700
        mov     eax, ebx
701
        call    SOCKET_is_connected
702
        mov     [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED
1831 hidnplayr 703
 
704
; Do window scaling?
705
 
2390 hidnplayr 706
        test    [ebx + TCP_SOCKET.t_flags], TF_RCVD_SCALE
707
        jz      @f
708
        test    [ebx + TCP_SOCKET.t_flags], TF_REQ_SCALE
709
        jz      @f
1831 hidnplayr 710
 
2390 hidnplayr 711
        push    word [ebx + TCP_SOCKET.requested_s_scale]       ; Set send and receive scale factors to the received values
712
        pop     word [ebx + TCP_SOCKET.SND_SCALE]
1831 hidnplayr 713
       @@:
714
 
2891 hidnplayr 715
;;; TODO: call TCP_reassemble
1831 hidnplayr 716
 
2390 hidnplayr 717
        mov     eax, [edx + TCP_header.SequenceNumber]
718
        dec     eax
719
        mov     [ebx + TCP_SOCKET.SND_WL1], eax
1831 hidnplayr 720
 
1733 hidnplayr 721
  .no_syn_rcv:
722
 
2937 hidnplayr 723
;-------------------------
724
; check for duplicate ACKs
1733 hidnplayr 725
 
2390 hidnplayr 726
        mov     eax, [edx + TCP_header.AckNumber]
727
        cmp     eax, [ebx + TCP_SOCKET.SND_UNA]
728
        ja      .not_dup_ack
1733 hidnplayr 729
 
2390 hidnplayr 730
        test    ecx, ecx
731
        jnz     .reset_dupacks
1733 hidnplayr 732
 
2390 hidnplayr 733
        mov     eax, dword [edx + TCP_header.Window]
734
        cmp     eax, [ebx + TCP_SOCKET.SND_WND]
735
        jne     .reset_dupacks
1733 hidnplayr 736
 
2891 hidnplayr 737
        DEBUGF  1,"TCP_input: Processing duplicate ACK\n"
1733 hidnplayr 738
 
2937 hidnplayr 739
; If we have outstanidn data, other than a window probe, this is a completely duplicate ACK
740
; (window info didnt change) The ACK is the biggest we've seen and we've seen exactly our rexmt threshold of them,
741
; assume a packet has been dropped and retransmit it. Kludge snd_nxt & the congestion window so we send only this one packet.
1733 hidnplayr 742
 
2937 hidnplayr 743
        cmp     [ebx + TCP_SOCKET.timer_retransmission], 0 ;;;;  FIXME
744
        jg      @f
745
 
2390 hidnplayr 746
        mov     eax, [edx + TCP_header.AckNumber]
747
        cmp     eax, [ebx + TCP_SOCKET.SND_UNA]
748
        je      .dup_ack
1763 hidnplayr 749
 
750
       @@:
2390 hidnplayr 751
        mov     [ebx + TCP_SOCKET.t_dupacks], 0
752
        jmp     .not_dup_ack
1763 hidnplayr 753
 
754
  .dup_ack:
2390 hidnplayr 755
        inc     [ebx + TCP_SOCKET.t_dupacks]
756
        cmp     [ebx + TCP_SOCKET.t_dupacks], TCP_re_xmit_thresh
757
        jne     .no_re_xmit
1763 hidnplayr 758
 
2390 hidnplayr 759
        push    [ebx + TCP_SOCKET.SND_NXT]              ; >>>>
1763 hidnplayr 760
 
2390 hidnplayr 761
        mov     eax, [ebx + TCP_SOCKET.SND_WND]
762
        cmp     eax, [ebx + TCP_SOCKET.SND_CWND]
2866 hidnplayr 763
        cmova   eax, [ebx + TCP_SOCKET.SND_CWND]
2390 hidnplayr 764
        shr     eax, 1
765
        push    edx
766
        xor     edx, edx
767
        div     [ebx + TCP_SOCKET.t_maxseg]
768
        cmp     eax, 2
2937 hidnplayr 769
        ja      @f
770
        xor     eax, eax
771
        mov     al, 2
1763 hidnplayr 772
       @@:
2390 hidnplayr 773
        mul     [ebx + TCP_SOCKET.t_maxseg]
774
        pop     edx
775
        mov     [ebx + TCP_SOCKET.SND_SSTHRESH], eax
1763 hidnplayr 776
 
2390 hidnplayr 777
        mov     [ebx + TCP_SOCKET.timer_retransmission], 0      ; turn off retransmission timer
778
        mov     [ebx + TCP_SOCKET.t_rtt], 0
779
        mov     eax, [edx + TCP_header.AckNumber]
780
        mov     [ebx + TCP_SOCKET.SND_NXT], eax
781
        mov     eax, [ebx + TCP_SOCKET.t_maxseg]
782
        mov     [ebx + TCP_SOCKET.SND_CWND], eax
1763 hidnplayr 783
 
2390 hidnplayr 784
        mov     eax, ebx
785
        call    TCP_output                                      ; retransmit missing segment
1763 hidnplayr 786
 
2390 hidnplayr 787
        push    edx
788
        xor     edx, edx
789
        mov     eax, [ebx + TCP_SOCKET.t_maxseg]
790
        mul     [ebx + TCP_SOCKET.t_dupacks]
791
        pop     edx
792
        add     eax, [ebx + TCP_SOCKET.SND_SSTHRESH]
793
        mov     [ebx + TCP_SOCKET.SND_CWND], eax
1763 hidnplayr 794
 
2390 hidnplayr 795
        pop     eax                                     ; <<<<
796
        cmp     eax, [ebx + TCP_SOCKET.SND_NXT]
797
        jb      @f
798
        mov     [ebx + TCP_SOCKET.SND_NXT], eax
1763 hidnplayr 799
       @@:
800
 
2390 hidnplayr 801
        jmp     .drop
1733 hidnplayr 802
 
803
 
1763 hidnplayr 804
  .no_re_xmit:
2390 hidnplayr 805
        jbe     .not_dup_ack
1733 hidnplayr 806
 
2891 hidnplayr 807
        DEBUGF  1,"TCP_input: Increasing congestion window\n"
1733 hidnplayr 808
 
2390 hidnplayr 809
        mov     eax, [ebx + TCP_SOCKET.t_maxseg]
810
        add     [ebx + TCP_SOCKET.SND_CWND], eax
1733 hidnplayr 811
 
2390 hidnplayr 812
        mov     eax, ebx
813
        call    TCP_output
1733 hidnplayr 814
 
2390 hidnplayr 815
        jmp     .drop
1733 hidnplayr 816
 
817
 
1763 hidnplayr 818
  .not_dup_ack:
819
 
1733 hidnplayr 820
;-------------------------------------------------
821
; If the congestion window was inflated to account
822
; for the other side's cached packets, retract it
823
 
2390 hidnplayr 824
        mov     eax, [ebx + TCP_SOCKET.SND_SSTHRESH]
825
        cmp     eax, [ebx + TCP_SOCKET.SND_CWND]
826
        ja      @f
827
        cmp     [ebx + TCP_SOCKET.t_dupacks], TCP_re_xmit_thresh
828
        jbe     @f
829
        mov     [ebx + TCP_SOCKET.SND_CWND], eax
1763 hidnplayr 830
       @@:
1733 hidnplayr 831
 
2390 hidnplayr 832
        mov     [ebx + TCP_SOCKET.t_dupacks], 0
1733 hidnplayr 833
 
2390 hidnplayr 834
        mov     eax, [edx + TCP_header.AckNumber]
835
        cmp     eax, [ebx + TCP_SOCKET.SND_MAX]
836
        jbe     @f
1733 hidnplayr 837
 
2390 hidnplayr 838
        ;;; TODO: update stats
839
        jmp     .drop_after_ack
1733 hidnplayr 840
 
1763 hidnplayr 841
       @@:
1733 hidnplayr 842
 
2390 hidnplayr 843
        mov     edi, [edx + TCP_header.AckNumber]
844
        sub     edi, [ebx + TCP_SOCKET.SND_UNA]         ; now we got the number of acked bytes in edi
1733 hidnplayr 845
 
2390 hidnplayr 846
        ;;; TODO: update stats
1733 hidnplayr 847
 
2891 hidnplayr 848
        DEBUGF  1,"TCP_input: acceptable ACK for %u bytes\n", edi
1763 hidnplayr 849
 
1733 hidnplayr 850
;------------------------------------------
2937 hidnplayr 851
; RTT measurements and retransmission timer  (912-926)
1733 hidnplayr 852
 
2937 hidnplayr 853
; If we have a timestamp, update smoothed RTT
1733 hidnplayr 854
 
2937 hidnplayr 855
        test    [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP
856
        jne     .timestamp_not_present
2942 hidnplayr 857
        mov     eax, [esp+4+4]
2937 hidnplayr 858
        sub     eax, [ebx + TCP_SOCKET.ts_ecr]
859
        inc     eax
860
        call    TCP_xmit_timer
861
        jmp     .rtt_done_
1733 hidnplayr 862
 
2937 hidnplayr 863
; If no timestamp but transmit timer is running and timed sequence number was acked,
864
; update smoothed RTT. Since we now have an RTT measurement, cancel the timer backoff
865
; (Phil Karn's retransmit algo)
866
; Recompute the initial retransmit timer
867
 
868
  .timestamp_not_present:
869
        mov     eax, [edx + TCP_header.AckNumber]
870
        cmp     eax, [ebx + TCP_SOCKET.t_rtseq]
871
        jbe     .rtt_done_
872
        mov     eax, [ebx + TCP_SOCKET.t_rtt]
873
        test    eax, eax
874
        jz      .rtt_done_
875
        call    TCP_xmit_timer
876
 
877
  .rtt_done_:
878
 
879
; If all outstanding data is acked, stop retransmit timer and remember to restart (more output or persist)
880
; If there is more data to be acked, restart retransmit timer, using current (possible backed-off) value.
881
 
2390 hidnplayr 882
        mov     eax, [ebx + TCP_SOCKET.SND_MAX]
883
        cmp     eax, [edx + TCP_header.AckNumber]
2937 hidnplayr 884
        jne     .more_data
885
        mov     [ebx + TCP_SOCKET.timer_retransmission], 0
886
        or      [ebx + TCP_SOCKET.temp_bits], TCP_BIT_NEEDOUTPUT
887
        jmp     .no_restart
888
  .more_data:
889
        cmp     [ebx + TCP_SOCKET.timer_persist], 0
890
        jne     .no_restart
2891 hidnplayr 891
 
2937 hidnplayr 892
        mov     eax, [ebx + TCP_SOCKET.t_rxtcur]
893
        mov     [ebx + TCP_SOCKET.timer_retransmission], ax
1733 hidnplayr 894
 
2937 hidnplayr 895
  .no_restart:
896
 
897
 
1733 hidnplayr 898
;-------------------------------------------
899
; Open congestion window in response to ACKs
900
 
2390 hidnplayr 901
        mov     esi, [ebx + TCP_SOCKET.SND_CWND]
902
        mov     eax, [ebx + TCP_SOCKET.t_maxseg]
1733 hidnplayr 903
 
2390 hidnplayr 904
        cmp     esi, [ebx + TCP_SOCKET.SND_SSTHRESH]
905
        jbe     @f
906
        push    edx
907
        push    eax
908
        mul     eax
909
        div     esi
910
        pop     edx
911
        shr     edx, 3
912
        add     eax, edx
913
        pop     edx
1763 hidnplayr 914
       @@:
1733 hidnplayr 915
 
2390 hidnplayr 916
        add     esi, eax
1733 hidnplayr 917
 
2390 hidnplayr 918
        push    ecx
919
        mov     cl, [ebx + TCP_SOCKET.SND_SCALE]
920
        mov     eax, TCP_max_win
921
        shl     eax, cl
922
        pop     ecx
1733 hidnplayr 923
 
2390 hidnplayr 924
        cmp     esi, eax
2866 hidnplayr 925
        cmova   esi, eax
2390 hidnplayr 926
        mov     [ebx + TCP_SOCKET.SND_CWND], esi
1733 hidnplayr 927
 
2891 hidnplayr 928
;------------------------------------------
929
; Remove acknowledged data from send buffer
1733 hidnplayr 930
 
2891 hidnplayr 931
        cmp     edi, [ebx + STREAM_SOCKET.snd.size]
932
        jbe     .finiacked
1733 hidnplayr 933
 
2891 hidnplayr 934
        push    ecx edx ebx
935
        mov     ecx, [ebx + STREAM_SOCKET.snd.size]
936
        lea     eax, [ebx + STREAM_SOCKET.snd]
937
        sub     [ebx + TCP_SOCKET.SND_WND], ecx
938
        call    SOCKET_ring_free
939
        pop     ebx edx ecx
1733 hidnplayr 940
 
2891 hidnplayr 941
        DEBUGF  1,"TCP_input: our FIN is acked\n"
942
        stc
1763 hidnplayr 943
 
2891 hidnplayr 944
        jmp     .wakeup
1763 hidnplayr 945
 
2891 hidnplayr 946
  .finiacked:
1763 hidnplayr 947
 
2390 hidnplayr 948
        push    ecx edx ebx
949
        mov     ecx, edi
950
        lea     eax, [ebx + STREAM_SOCKET.snd]
951
        call    SOCKET_ring_free
952
        pop     ebx
953
        sub     [ebx + TCP_SOCKET.SND_WND], ecx
954
        pop     edx ecx
1733 hidnplayr 955
 
2891 hidnplayr 956
        DEBUGF  1,"TCP_input: our FIN is not acked\n"
957
        clc
958
 
959
;----------------------------------------
1733 hidnplayr 960
; Wake up process waiting on send buffer
961
 
2891 hidnplayr 962
  .wakeup:
963
 
964
        pushf
2390 hidnplayr 965
        mov     eax, ebx
966
        call    SOCKET_notify_owner
1733 hidnplayr 967
 
1831 hidnplayr 968
; Update TCPS
1733 hidnplayr 969
 
2390 hidnplayr 970
        mov     eax, [edx + TCP_header.AckNumber]
971
        mov     [ebx + TCP_SOCKET.SND_UNA], eax
972
        cmp     eax, [ebx + TCP_SOCKET.SND_NXT]
973
        jb      @f
974
        mov     [ebx + TCP_SOCKET.SND_NXT], eax
1733 hidnplayr 975
       @@:
976
 
2891 hidnplayr 977
        popf
1733 hidnplayr 978
 
979
; General ACK handling complete
980
; Now do the state-specific ones
981
 
2390 hidnplayr 982
        mov     eax, [ebx + TCP_SOCKET.t_state]
983
        jmp     dword [eax*4 + .ACK_sw_list]
1733 hidnplayr 984
 
985
  .ACK_sw_list:
2891 hidnplayr 986
        dd      .ack_processed  ; TCPS_CLOSED
987
        dd      .ack_processed  ; TCPS_LISTEN
988
        dd      .ack_processed  ; TCPS_SYN_SENT
989
        dd      .ack_processed  ; TCPS_SYN_RECEIVED
990
        dd      .ack_processed  ; TCPS_ESTABLISHED
991
        dd      .ack_processed  ; TCPS_CLOSE_WAIT
992
        dd      .ack_fw1        ; TCPS_FIN_WAIT_1
993
        dd      .ack_c          ; TCPS_CLOSING
994
        dd      .ack_la         ; TCPS_LAST_ACK
995
        dd      .ack_processed  ; TCPS_FIN_WAIT_2
996
        dd      .ack_tw         ; TCPS_TIMED_WAIT
1733 hidnplayr 997
 
998
 
1772 hidnplayr 999
  .ack_fw1:
2891 hidnplayr 1000
        jnc     .ack_processed
1733 hidnplayr 1001
 
2390 hidnplayr 1002
        test    [ebx + SOCKET.state], SS_CANTRCVMORE
1003
        jnz     @f
1004
        mov     eax, ebx
1005
        call    SOCKET_is_disconnected
2937 hidnplayr 1006
        mov     [ebx + TCP_SOCKET.timer_timed_wait], TCP_time_max_idle
1772 hidnplayr 1007
       @@:
2390 hidnplayr 1008
        mov     [ebx + TCP_SOCKET.t_state], TCPS_FIN_WAIT_2
1009
        jmp     .ack_processed
1733 hidnplayr 1010
 
1772 hidnplayr 1011
  .ack_c:
2891 hidnplayr 1012
        jnc     .ack_processed
1772 hidnplayr 1013
 
2390 hidnplayr 1014
        mov     [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT
1015
        mov     eax, ebx
1016
        call    TCP_cancel_timers
1017
        mov     [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL
1018
        mov     eax, ebx
1019
        call    SOCKET_is_disconnected
1020
        jmp     .ack_processed
1733 hidnplayr 1021
 
1772 hidnplayr 1022
  .ack_la:
2891 hidnplayr 1023
        jnc     .ack_processed
1733 hidnplayr 1024
 
2390 hidnplayr 1025
        mov     eax, ebx
2882 hidnplayr 1026
        call    TCP_disconnect
2390 hidnplayr 1027
        jmp     .drop
1733 hidnplayr 1028
 
1772 hidnplayr 1029
  .ack_tw:
2390 hidnplayr 1030
        mov     [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL
1031
        jmp     .drop_after_ack
1733 hidnplayr 1032
 
2930 hidnplayr 1033
  .reset_dupacks:               ; We got a new ACK, reset duplicate ACK counter
1034
        mov     [ebx + TCP_SOCKET.t_dupacks], 0
1035
        jmp     .ack_processed
1733 hidnplayr 1036
 
1772 hidnplayr 1037
 
1733 hidnplayr 1038
 
2930 hidnplayr 1039
;-------------
1040
; Passive Open
1733 hidnplayr 1041
 
2930 hidnplayr 1042
align 4
1043
 
1044
  .accept_connection:
1045
 
1046
        DEBUGF  1,"TCP_input: Accepting new connection\n"
1047
 
1048
        pusha
1049
        lea     ecx, [ebx + SOCKET.mutex]
1050
        call    mutex_unlock
1051
        popa
1052
 
1053
        push    ecx edx esi edi         ;;;
1054
        call    SOCKET_fork
1055
        pop     edi esi edx ecx
1056
 
1057
        test    eax, eax
1058
        jz      .drop
1059
 
2937 hidnplayr 1060
        mov     [eax + TCP_SOCKET.temp_bits], TCP_BIT_DROPSOCKET        ;;; FIXME: should we take over bits from previous socket?
1061
 
2930 hidnplayr 1062
        push    dword [edi + 4]                         ; Ipv4 destination addres
1063
        pop     [eax + IP_SOCKET.LocalIP]
1064
 
1065
        push    [edx + TCP_header.DestinationPort]
1066
        pop     [eax + TCP_SOCKET.LocalPort]
1067
 
1068
        mov     [eax + TCP_SOCKET.t_state], TCPS_LISTEN
1069
        mov     ebx, eax
1070
 
1071
  .LISTEN:
1072
 
1073
        DEBUGF  1,"TCP_input: state=listen\n"
1074
 
2937 hidnplayr 1075
        test    [edx + TCP_header.Flags], TH_RST
2930 hidnplayr 1076
        jnz     .drop
1077
 
1078
        test    [edx + TCP_header.Flags], TH_ACK
1079
        jnz     .drop_with_reset
1080
 
1081
        test    [edx + TCP_header.Flags], TH_SYN
1082
        jz      .drop
1083
 
1084
;;; TODO: check if it's a broadcast or multicast, and drop if so
1085
 
1086
        push    dword [edi]                             ; Ipv4 source addres
1087
        pop     [ebx + IP_SOCKET.RemoteIP]
1088
 
1089
        push    [edx + TCP_header.SourcePort]
1090
        pop     [ebx + TCP_SOCKET.RemotePort]
1091
 
1092
        push    [edx + TCP_header.SequenceNumber]
1093
        pop     [ebx + TCP_SOCKET.IRS]
1094
 
1095
        mov     eax, [TCP_sequence_num]
1096
        add     [TCP_sequence_num], 64000 / 2
1097
        mov     [ebx + TCP_SOCKET.ISS], eax
1098
        mov     [ebx + TCP_SOCKET.SND_NXT], eax
1099
 
1100
        TCP_sendseqinit ebx
1101
        TCP_rcvseqinit ebx
1102
 
1103
        mov     [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED
1104
        mov     [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
1105
        mov     [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval  ;;;; macro
1106
 
1107
        lea     eax, [ebx + STREAM_SOCKET.snd]
1108
        call    SOCKET_ring_create
1109
 
1110
        lea     eax, [ebx + STREAM_SOCKET.rcv]
1111
        call    SOCKET_ring_create
1112
 
2937 hidnplayr 1113
        and     [ebx + TCP_SOCKET.temp_bits], not TCP_BIT_DROPSOCKET
1114
 
2930 hidnplayr 1115
;;;        call    SOCKET_notify_owner
1116
 
1117
        jmp     .trim_then_step6
1118
 
1119
 
1120
 
1121
 
1122
 
1123
 
1124
 
1125
 
1126
 
1127
 
1128
;------------
1129
; Active Open
1130
 
1131
align 4
2937 hidnplayr 1132
  .SYN_SENT:
2930 hidnplayr 1133
 
1134
        DEBUGF  1,"TCP_input: state=syn_sent\n"
1135
 
1136
        test    [edx + TCP_header.Flags], TH_ACK
1137
        jz      @f
1138
 
1139
        mov     eax, [edx + TCP_header.AckNumber]
1140
        cmp     eax, [ebx + TCP_SOCKET.ISS]
1141
        jbe     .drop_with_reset
1142
 
1143
        cmp     eax, [ebx + TCP_SOCKET.SND_MAX]
1144
        ja      .drop_with_reset
1145
       @@:
1146
 
1147
        test    [edx + TCP_header.Flags], TH_RST
1148
        jz      @f
1149
 
1150
        test    [edx + TCP_header.Flags], TH_ACK
1151
        jz      .drop
1152
 
1153
        mov     eax, ebx
1154
        mov     ebx, ECONNREFUSED
1155
        call    TCP_drop
1156
 
1157
        jmp     .drop
1158
       @@:
1159
 
1160
        test    [edx + TCP_header.Flags], TH_SYN
1161
        jz      .drop
1162
 
1163
; at this point, segment seems to be valid
1164
 
1165
        test    [edx + TCP_header.Flags], TH_ACK
1166
        jz      .no_syn_ack
1167
 
1168
; now, process received SYN in response to an active open
1169
 
1170
        mov     eax, [edx + TCP_header.AckNumber]
1171
        mov     [ebx + TCP_SOCKET.SND_UNA], eax
1172
        cmp     eax, [ebx + TCP_SOCKET.SND_NXT]
1173
        jbe     @f
1174
        mov     [ebx + TCP_SOCKET.SND_NXT], eax
1175
       @@:
1176
 
1177
  .no_syn_ack:
1178
        mov     [ebx + TCP_SOCKET.timer_retransmission], 0      ; disable retransmission
1179
 
1180
        push    [edx + TCP_header.SequenceNumber]
1181
        pop     [ebx + TCP_SOCKET.IRS]
1182
 
1183
        TCP_rcvseqinit ebx
1184
 
1185
        or      [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
1186
 
1187
        mov     eax, [ebx + TCP_SOCKET.SND_UNA]
1188
        cmp     eax, [ebx + TCP_SOCKET.ISS]
1189
        jbe     .simultaneous_open
1190
 
1191
        test    [edx + TCP_header.Flags], TH_ACK
1192
        jz      .simultaneous_open
1193
 
1194
        DEBUGF  1,"TCP_input: active open\n"
1195
 
1196
;;; TODO: update stats
1197
 
1198
; set socket state to connected
1199
        mov     [ebx + SOCKET.state], SS_ISCONNECTED
1200
        mov     [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED
1201
 
2937 hidnplayr 1202
; Do window scaling on this connection ?
1203
        mov     eax, [ebx + TCP_SOCKET.t_flags]
1204
        and     eax, TF_REQ_SCALE or TF_RCVD_SCALE
1205
        cmp     eax, TF_REQ_SCALE or TF_RCVD_SCALE
1206
        jne     .no_scaling
2930 hidnplayr 1207
 
2937 hidnplayr 1208
        mov     ax, word [ebx + TCP_SOCKET.requested_s_scale]
1209
        mov     word [ebx + TCP_SOCKET.SND_SCALE], ax
1210
  .no_scaling:
2930 hidnplayr 1211
 
2937 hidnplayr 1212
;;; TODO: reassemble packets queue
1213
 
1214
        mov     eax, [ebx + TCP_SOCKET.t_rtt]
1215
        test    eax, eax
1216
        je      .trim_then_step6
1217
        call    TCP_xmit_timer
2930 hidnplayr 1218
        jmp     .trim_then_step6
1219
 
1220
  .simultaneous_open:
1221
 
1222
        DEBUGF  1,"TCP_input: simultaneous open\n"
1223
; We have received a syn but no ACK, so we are having a simultaneous open..
1224
        mov     [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED
1225
 
1226
;-------------------------------------
1227
; Common processing for receipt of SYN
1228
 
1229
  .trim_then_step6:
1230
 
1231
        inc     [edx + TCP_header.SequenceNumber]
1232
 
1233
;;; TODO: Drop any received data that follows receive window (590)
1234
 
1235
        mov     eax, [edx + TCP_header.SequenceNumber]
1236
        mov     [ebx + TCP_SOCKET.RCV_UP], eax
1237
        dec     eax
1238
        mov     [ebx + TCP_SOCKET.SND_WL1], eax
1239
 
1240
 
1241
 
2390 hidnplayr 1242
  .ack_processed:       ; (step 6)
1733 hidnplayr 1243
 
2891 hidnplayr 1244
        DEBUGF  1,"TCP_input: ACK processed\n"
1733 hidnplayr 1245
 
1246
;----------------------------------------------
1247
; check if we need to update window information
1248
 
2390 hidnplayr 1249
        test    [edx + TCP_header.Flags], TH_ACK
1250
        jz      .no_window_update
1733 hidnplayr 1251
 
2390 hidnplayr 1252
        mov     eax, [ebx + TCP_SOCKET.SND_WL1]
1253
        cmp     eax, [edx + TCP_header.SequenceNumber]
1254
        jb      .update_window
1255
        ja      @f
1733 hidnplayr 1256
 
2390 hidnplayr 1257
        mov     eax, [ebx + TCP_SOCKET.SND_WL2]
1258
        cmp     eax, [edx + TCP_header.AckNumber]
1259
        jb      .update_window
1260
        ja      .no_window_update
1733 hidnplayr 1261
       @@:
1262
 
2390 hidnplayr 1263
        mov     eax, [ebx + TCP_SOCKET.SND_WL2]
1264
        cmp     eax, [edx + TCP_header.AckNumber]
1265
        jne     .no_window_update
1733 hidnplayr 1266
 
2390 hidnplayr 1267
        mov     eax, dword [edx + TCP_header.Window]
1268
        cmp     eax, [ebx + TCP_SOCKET.SND_WND]
1269
        jbe     .no_window_update
1733 hidnplayr 1270
 
1271
  .update_window:
1272
 
2612 hidnplayr 1273
;;; TODO: Keep track of pure window updates
1733 hidnplayr 1274
 
2390 hidnplayr 1275
        mov     eax, dword [edx + TCP_header.Window]
1276
        cmp     eax, [ebx + TCP_SOCKET.max_sndwnd]
1277
        jbe     @f
1278
        mov     [ebx + TCP_SOCKET.max_sndwnd], eax
1733 hidnplayr 1279
       @@:
2390 hidnplayr 1280
        mov     [ebx + TCP_SOCKET.SND_WND], eax
1733 hidnplayr 1281
 
2891 hidnplayr 1282
        DEBUGF  1,"TCP_input: Updating window to %u\n", eax
2612 hidnplayr 1283
 
2390 hidnplayr 1284
        push    [edx + TCP_header.SequenceNumber]
1285
        pop     [ebx + TCP_SOCKET.SND_WL1]
1733 hidnplayr 1286
 
2390 hidnplayr 1287
        push    [edx + TCP_header.AckNumber]
1288
        pop     [ebx + TCP_SOCKET.SND_WL2]
1733 hidnplayr 1289
 
2937 hidnplayr 1290
        or      [ebx + TCP_SOCKET.temp_bits], TCP_BIT_NEEDOUTPUT
1733 hidnplayr 1291
 
1292
  .no_window_update:
1293
 
1294
 
1295
 
1296
 
1297
 
1298
 
1299
 
1300
;-----------------
1301
; process URG flag
1302
 
2390 hidnplayr 1303
        test    [edx + TCP_header.Flags], TH_URG
1304
        jz      .not_urgent
1733 hidnplayr 1305
 
2390 hidnplayr 1306
        cmp     [edx + TCP_header.UrgentPointer], 0
1307
        jz      .not_urgent
1733 hidnplayr 1308
 
2390 hidnplayr 1309
        cmp     [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT
1310
        je      .not_urgent
1733 hidnplayr 1311
 
1312
; Ignore bogus urgent offsets
1313
 
2390 hidnplayr 1314
        ;;; 1040-1050
1733 hidnplayr 1315
 
2390 hidnplayr 1316
        movzx   eax, [edx + TCP_header.UrgentPointer]
1317
        add     eax, [ebx + STREAM_SOCKET.rcv.size]
1318
        cmp     eax, SOCKET_MAXDATA
1319
        jbe     .not_urgent
1733 hidnplayr 1320
 
2390 hidnplayr 1321
        mov     [edx + TCP_header.UrgentPointer], 0
1322
        and     [edx + TCP_header.Flags], not (TH_URG)
1323
        jmp     .do_data
1733 hidnplayr 1324
 
1325
  .not_urgent:
1326
 
1327
; processing of received urgent pointer
1328
 
2390 hidnplayr 1329
        ;;; TODO (1051-1093)
1733 hidnplayr 1330
 
1331
 
2891 hidnplayr 1332
;---------------------------------------
1333
; process the data in the segment (1094)
1733 hidnplayr 1334
 
1335
  .do_data:
1336
 
2891 hidnplayr 1337
        cmp     [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT
1338
        jae     .final_processing
1733 hidnplayr 1339
 
2390 hidnplayr 1340
        test    [edx + TCP_header.Flags], TH_FIN
2891 hidnplayr 1341
        jnz     @f
1733 hidnplayr 1342
 
2390 hidnplayr 1343
        test    ecx, ecx
2891 hidnplayr 1344
        jnz     .final_processing
1345
       @@:
1733 hidnplayr 1346
 
2891 hidnplayr 1347
;        call    TCP_reassemble        ;;; TODO
1733 hidnplayr 1348
 
1349
;---------------
1350
; FIN processing
1351
 
2891 hidnplayr 1352
        test    [edx + TCP_header.Flags], TH_FIN
2930 hidnplayr 1353
        jz      .final_processing
1733 hidnplayr 1354
 
2891 hidnplayr 1355
        DEBUGF  1,"TCP_input: Processing FIN\n"
1733 hidnplayr 1356
 
2891 hidnplayr 1357
        cmp     [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT
1358
        jae     .not_first_fin
1774 hidnplayr 1359
 
2891 hidnplayr 1360
        DEBUGF  1,"TCP_input: First FIN for this connection\n"
1774 hidnplayr 1361
 
2390 hidnplayr 1362
        mov     eax, ebx
1363
        call    SOCKET_cant_recv_more
1774 hidnplayr 1364
 
2390 hidnplayr 1365
        mov     [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
1366
        inc     [ebx + TCP_SOCKET.RCV_NXT]
1774 hidnplayr 1367
 
1368
  .not_first_fin:
2390 hidnplayr 1369
        mov     eax, [ebx + TCP_SOCKET.t_state]
1370
        shl     eax, 2
1371
        jmp     dword [eax + .FIN_sw_list]
1733 hidnplayr 1372
 
1373
  .FIN_sw_list:
2937 hidnplayr 1374
        dd      .final_processing       ; TCPS_CLOSED
1375
        dd      .final_processing       ; TCPS_LISTEN
1376
        dd      .final_processing       ; TCPS_SYN_SENT
1377
        dd      .fin_syn_est            ; TCPS_SYN_RECEIVED
1378
        dd      .fin_syn_est            ; TCPS_ESTABLISHED
1379
        dd      .final_processing       ; TCPS_CLOSE_WAIT
1380
        dd      .fin_wait1              ; TCPS_FIN_WAIT_1
1381
        dd      .final_processing       ; TCPS_CLOSING
1382
        dd      .final_processing       ; TCPS_LAST_ACK
1383
        dd      .fin_wait2              ; TCPS_FIN_WAIT_2
1384
        dd      .fin_timed              ; TCPS_TIMED_WAIT
1733 hidnplayr 1385
 
1386
  .fin_syn_est:
1387
 
2390 hidnplayr 1388
        mov     [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT
2930 hidnplayr 1389
        jmp     .final_processing
1733 hidnplayr 1390
 
1391
  .fin_wait1:
1392
 
2390 hidnplayr 1393
        mov     [ebx + TCP_SOCKET.t_state], TCPS_CLOSING
2930 hidnplayr 1394
        jmp     .final_processing
1733 hidnplayr 1395
 
1396
  .fin_wait2:
1397
 
2390 hidnplayr 1398
        mov     [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT
1399
        mov     eax, ebx
1400
        call    TCP_cancel_timers
1401
        mov     [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL
1402
        call    SOCKET_is_disconnected
2930 hidnplayr 1403
        jmp     .final_processing
1733 hidnplayr 1404
 
1405
  .fin_timed:
2390 hidnplayr 1406
        mov     [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL
2930 hidnplayr 1407
        jmp     .final_processing
1733 hidnplayr 1408
 
1409
 
2930 hidnplayr 1410
  .drop_after_ack:
1411
        DEBUGF  1,"TCP_input: Drop after ACK\n"
1733 hidnplayr 1412
 
2930 hidnplayr 1413
        push    edx ebx
2891 hidnplayr 1414
        lea     ecx, [ebx + SOCKET.mutex]
1415
        call    mutex_unlock
2930 hidnplayr 1416
        pop     eax edx
2891 hidnplayr 1417
 
2930 hidnplayr 1418
        test    [edx + TCP_header.Flags], TH_RST
1419
        jnz     .dumpit
1733 hidnplayr 1420
 
2930 hidnplayr 1421
        or      [eax + TCP_SOCKET.t_flags], TF_ACKNOW
1422
        jmp     .need_output
2891 hidnplayr 1423
 
1733 hidnplayr 1424
 
2891 hidnplayr 1425
 
2930 hidnplayr 1426
  .drop_with_reset:
1427
        DEBUGF  1,"TCP_input: Drop with reset\n"
1428
 
1429
        push    ebx edx
2402 hidnplayr 1430
        lea     ecx, [ebx + SOCKET.mutex]
1431
        call    mutex_unlock
2930 hidnplayr 1432
        pop     edx ebx
1733 hidnplayr 1433
 
2930 hidnplayr 1434
        test    [edx + TCP_header.Flags], TH_RST
1435
        jnz     .dumpit
1733 hidnplayr 1436
 
2930 hidnplayr 1437
        ;;; if its a multicast/broadcast, also drop
1733 hidnplayr 1438
 
2930 hidnplayr 1439
        test    [edx + TCP_header.Flags], TH_ACK
1440
        jnz     .respond_ack
1733 hidnplayr 1441
 
2930 hidnplayr 1442
        test    [edx + TCP_header.Flags], TH_SYN
1443
        jnz     .respond_syn
1444
        jmp     .dumpit
1733 hidnplayr 1445
 
2930 hidnplayr 1446
;-----------------
1447
; Final processing
1733 hidnplayr 1448
 
2930 hidnplayr 1449
  .final_processing:
1450
        DEBUGF  1,"TCP_input: Final processing\n"
1733 hidnplayr 1451
 
2930 hidnplayr 1452
        push    ebx
1453
        lea     ecx, [ebx + SOCKET.mutex]
1454
        call    mutex_unlock
1455
        pop     eax
1733 hidnplayr 1456
 
2937 hidnplayr 1457
        test    [eax + TCP_SOCKET.temp_bits], TCP_BIT_NEEDOUTPUT
1458
        jnz     .need_output
1733 hidnplayr 1459
 
2930 hidnplayr 1460
        test    [eax + TCP_SOCKET.t_flags], TF_ACKNOW
1461
        jz      .dumpit
1462
        DEBUGF  1,"TCP_input: ACK now!\n"
1733 hidnplayr 1463
 
2930 hidnplayr 1464
  .need_output:
1465
        call    TCP_output
1733 hidnplayr 1466
 
2930 hidnplayr 1467
  .dumpit:
1468
        DEBUGF  1,"TCP_input: dumping\n"
1733 hidnplayr 1469
 
2942 hidnplayr 1470
        popf
2390 hidnplayr 1471
        call    kernel_free
1472
        add     esp, 4
2942 hidnplayr 1473
 
2390 hidnplayr 1474
        ret
1733 hidnplayr 1475
 
1476
 
1477
  .respond_ack:
2390 hidnplayr 1478
        push    ebx
1479
        mov     cl, TH_RST
1480
        call    TCP_respond_socket
1481
        pop     ebx
1482
        jmp     .destroy_new_socket
1733 hidnplayr 1483
 
1484
 
1485
  .respond_syn:
2390 hidnplayr 1486
        push    ebx
1487
        mov     cl, TH_RST + TH_ACK
1488
        call    TCP_respond_socket
1489
        pop     ebx
1490
        jmp     .destroy_new_socket
1733 hidnplayr 1491
 
1492
 
1493
 
1494
;-----
1495
; Drop
1496
 
2930 hidnplayr 1497
  .drop:
1733 hidnplayr 1498
 
2937 hidnplayr 1499
        DEBUGF  1,"TCP_input: Dropping packet\n"
1500
 
2402 hidnplayr 1501
        pusha
1502
        lea     ecx, [ebx + SOCKET.mutex]
1503
        call    mutex_unlock
1504
        popa
1733 hidnplayr 1505
 
2937 hidnplayr 1506
  .destroy_new_socket:
1733 hidnplayr 1507
 
2937 hidnplayr 1508
        test    [ebx + TCP_SOCKET.temp_bits], TCP_BIT_DROPSOCKET
1509
        jz      .drop_no_socket
1733 hidnplayr 1510
 
2937 hidnplayr 1511
        mov     eax, ebx
1512
        call    SOCKET_free
1733 hidnplayr 1513
 
2930 hidnplayr 1514
  .drop_no_socket:
1515
        DEBUGF  1,"TCP_input: Drop (no socket)\n"
1516
 
2942 hidnplayr 1517
        popf
2390 hidnplayr 1518
        call    kernel_free
1519
        add     esp, 4
2942 hidnplayr 1520
 
2600 hidnplayr 1521
        ret
1522
 
2930 hidnplayr 1523
  .drop_with_reset_no_socket:
2600 hidnplayr 1524
 
2891 hidnplayr 1525
        DEBUGF  1,"TCP_input: Drop with reset (no socket)\n"
2600 hidnplayr 1526
 
1527
        test    [edx + TCP_header.Flags], TH_RST
1528
        jnz     .drop_no_socket
1529
 
1530
        ;;; if its a multicast/broadcast, also drop
1531
 
1532
        test    [edx + TCP_header.Flags], TH_ACK
1533
        jnz     .respond_seg_ack
1534
 
1535
        test    [edx + TCP_header.Flags], TH_SYN
1536
        jnz     .respond_seg_syn
1537
 
2930 hidnplayr 1538
        jmp     .drop_no_socket
2600 hidnplayr 1539
 
1540
  .respond_seg_ack:
1541
 
1542
        mov     cl, TH_RST
1543
        call    TCP_respond_segment
1544
        jmp     .drop_no_socket
1545
 
1546
  .respond_seg_syn:
1547
 
1548
        mov     cl, TH_RST + TH_ACK
1549
        call    TCP_respond_segment
1550
        jmp     .drop_no_socket