Subversion Repositories Kolibri OS

Rev

Rev 4388 | Rev 4850 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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