Subversion Repositories Kolibri OS

Rev

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

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