Subversion Repositories Kolibri OS

Rev

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

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