Subversion Repositories Kolibri OS

Rev

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

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