Subversion Repositories Kolibri OS

Rev

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

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