Subversion Repositories Kolibri OS

Rev

Rev 1281 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1281 Rev 1318
Line 6... Line 6...
6
;;  TCP.INC                                                        ;;
6
;;  TCP.INC                                                        ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;  Part of the tcp/ip network stack for KolibriOS                 ;;
8
;;  Part of the tcp/ip network stack for KolibriOS                 ;;
9
;;                                                                 ;;
9
;;                                                                 ;;
10
;;    Written by hidnplayr@kolibrios.org                           ;;
10
;;    Written by hidnplayr@kolibrios.org                           ;;
-
 
11
;;    Inspired by the TCP code of Mike Hibbit for MenuetOS         ;;
11
;;                                                                 ;;
12
;;                                                                 ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
13
;;          GNU GENERAL PUBLIC LICENSE                             ;;
13
;;             Version 2, June 1991                                ;;
14
;;             Version 2, June 1991                                ;;
14
;;                                                                 ;;
15
;;                                                                 ;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 16... Line 17...
16
 
17
 
Line 17... Line 18...
17
 
18
 
18
$Revision: 1281 $
19
$Revision: 1318 $
19
 
20
 
20
TCP_RETRIES		equ 5		; Number of times to resend a Packet
21
TCP_RETRIES		equ 5		; Number of times to resend a Packet
Line -... Line 22...
-
 
22
TCP_PACKET_TTL		equ 50		; resend if not replied to in 1/100 s
-
 
23
TCP_SOCKET_TTL		equ 10		; # of secs to wait before closing socket
Line 21... Line 24...
21
TCP_PACKET_TTL		equ 50		; resend if not replied to in 1/100 s
24
TCP_QUEUE_SIZE		equ 16
22
TCP_SOCKET_TTL		equ 10		; # of secs to wait before closing socket
25
 
23
TCP_QUEUE_SIZE		equ 16
26
TCP_MAX_ACKS		equ 16
24
 
27
 
Line 61... Line 64...
61
uglobal
64
uglobal
62
	TCP_PACKETS_TX		rd  MAX_IP
65
	TCP_PACKETS_TX		rd  MAX_IP
63
	TCP_PACKETS_RX		rd  MAX_IP
66
	TCP_PACKETS_RX		rd  MAX_IP
Line 64... Line 67...
64
 
67
 
65
	TCP_IN_QUEUE		rd  (tcp_in_queue_entry.size*TCP_QUEUE_SIZE+queue.data)/4
68
	TCP_IN_QUEUE		rd  (tcp_in_queue_entry.size*TCP_QUEUE_SIZE+queue.data)/4
66
	TCP_OUT_QUEUE		dd  ?
69
	TCP_OUT_QUEUE		dd  ?, ?
-
 
70
				rd  (tcp_out_queue_entry.size*TCP_QUEUE_SIZE)/4
-
 
71
 
-
 
72
	TCP_ACKS		dd  ?
67
				rd  (tcp_out_queue_entry.size*TCP_QUEUE_SIZE)/4
73
	TCP_ACK_LIST		rd  3*TCP_MAX_ACKS
Line 68... Line 74...
68
endg
74
endg
69
 
75
 
70
align 4
76
align 4
Line 71... Line 77...
71
iglobal
77
iglobal
72
stateHandler:
78
TCPstateHandler:
73
 
79
 
74
  dd  stateTCB_LISTEN
80
  dd  stateTCB_LISTEN
Line 112... Line 118...
112
; An empty slot is know by the fact that tcp_out_queue_entry.data_ptr (first dword of the slot) is set to 0
118
; An empty slot is know by the fact that tcp_out_queue_entry.data_ptr (first dword of the slot) is set to 0
113
; There are TCP_OUT_QUEUE_SIZE number of slots
119
; There are TCP_OUT_QUEUE_SIZE number of slots
Line 114... Line 120...
114
 
120
 
115
	xor	eax, eax
121
	xor	eax, eax
116
	mov	esi, TCP_OUT_QUEUE
122
	mov	esi, TCP_OUT_QUEUE
117
	mov	ecx, TCP_QUEUE_SIZE*tcp_out_queue_entry/4+1
123
	mov	ecx, TCP_QUEUE_SIZE*tcp_out_queue_entry/4+2+2+3*TCP_MAX_ACKS
Line 118... Line 124...
118
	rep	stosd
124
	rep	stosd
Line 191... Line 197...
191
TCP_send_queued:
197
TCP_send_queued:
Line 192... Line 198...
192
 
198
 
193
	cmp	[TCP_OUT_QUEUE], 0
199
	cmp	[TCP_OUT_QUEUE], 0
Line -... Line 200...
-
 
200
	je	.exit
-
 
201
 
-
 
202
	mov	ebx, TCP_OUT_QUEUE+4
194
	je	.exit
203
	call	wait_mutex
195
 
204
 
196
	mov	eax, TCP_QUEUE_SIZE
205
	mov	eax, TCP_QUEUE_SIZE
Line 197... Line 206...
197
	mov	ecx, [TCP_OUT_QUEUE]
206
	mov	ecx, [TCP_OUT_QUEUE]
198
	mov	esi, TCP_OUT_QUEUE+4
207
	mov	esi, TCP_OUT_QUEUE+8
199
 
208
 
200
  .loop:
209
  .loop:
201
	cmp	[esi + tcp_out_queue_entry.data_ptr], 0
210
	cmp	[esi + tcp_out_queue_entry.data_ptr], 0
202
	jnz	.found_one
211
	jnz	.found_one
-
 
212
	add	esi, tcp_out_queue_entry.size
203
	add	esi, tcp_out_queue_entry.size
213
	loop	.loop
Line 204... Line 214...
204
	loop	.loop
214
  .exit:
205
  .exit:
215
	mov	[TCP_OUT_QUEUE+4], 0
206
	ret
216
	ret
-
 
217
 
-
 
218
  .found_one:
207
 
219
	dec	[esi + tcp_out_queue_entry.ttl]
208
  .found_one:
220
	jz	.send_it
209
	dec	[esi + tcp_out_queue_entry.ttl]
221
	cmp	[esi + tcp_out_queue_entry.data_ptr], -1
210
	jz	.send_it
222
	jz	.is_ack
211
  .find_next:
223
  .find_next:
212
	add	esi, tcp_out_queue_entry.size
224
	add	esi, tcp_out_queue_entry.size
-
 
225
	dec	eax
213
	dec	eax
226
	jz	.exit
Line 214... Line 227...
214
	jz	.exit
227
	test	ecx, ecx
215
	test	ecx, ecx
228
	jnz	.loop
216
	jnz	.loop
-
 
217
	ret
229
	mov	[TCP_OUT_QUEUE+4], 0
218
 
230
	ret
219
  .send_it:
231
 
220
	push	eax ecx esi
232
  .send_it:
221
 
233
	pusha
222
	mov	ebx, [esi + tcp_out_queue_entry.owner]
234
	mov	ebx, [esi + tcp_out_queue_entry.owner]
223
	push	[esi + tcp_out_queue_entry.data_size]
235
	pushd	[esi + tcp_out_queue_entry.data_size]
224
	push	[esi + tcp_out_queue_entry.data_ptr]
236
	pushd	[esi + tcp_out_queue_entry.data_ptr]
Line 225... Line 237...
225
	DEBUGF 1,"Now sending TCP packet %x, size: %u, owner: %x, sendproc %x\n", [esp], [esp+4], ebx, [esi + tcp_out_queue_entry.sendproc]
237
	DEBUGF 1,"Now sending TCP packet %x, size: %u, owner: %x, sendproc %x\n", [esp], [esp+4], ebx, [esi + tcp_out_queue_entry.sendproc]
226
	inc	[TCP_PACKETS_TX]
238
	inc	[TCP_PACKETS_TX]
Line 227... Line 239...
227
	call	[esi + tcp_out_queue_entry.sendproc]
239
	call	[esi + tcp_out_queue_entry.sendproc]
Line 239... Line 251...
239
	mov	[esi + tcp_out_queue_entry.data_ptr], 0
251
	mov	[esi + tcp_out_queue_entry.data_ptr], 0
240
	call	kernel_free
252
	call	kernel_free
241
	dec	[TCP_OUT_QUEUE]
253
	dec	[TCP_OUT_QUEUE]
242
	jmp	.find_next
254
	jmp	.find_next
Line -... Line 255...
-
 
255
 
-
 
256
  .is_ack:
-
 
257
	pusha
-
 
258
	mov	eax, [esi + tcp_out_queue_entry.socket]
-
 
259
	mov	ebx, [esi + tcp_out_queue_entry.owner]
-
 
260
	mov	ecx, [esi + tcp_out_queue_entry.size]
-
 
261
	call	TCP_send_ack
-
 
262
	popa
-
 
263
	mov	[esi + tcp_out_queue_entry.data_ptr], 0
-
 
264
	dec	[TCP_OUT_QUEUE]
-
 
265
	jmp	.find_next
Line 243... Line 266...
243
 
266
 
244
 
267
 
245
 
268
 
Line 264... Line 287...
264
 
287
 
Line 265... Line 288...
265
       DEBUGF 1,"TCP_Handler\n"
288
       DEBUGF 1,"TCP_Handler\n"
Line -... Line 289...
-
 
289
 
-
 
290
; TODO: validate checksum
266
 
291
 
267
; TODO: validate checksum
292
; Find a matching socket for received packet, all following expressions must be valid:
268
 
293
;
Line 269... Line 294...
269
; IP Packet TCP Destination Port = local Port
294
; IP Packet TCP Destination Port = local Port
Line 270... Line 295...
270
; IP Packet SA = Remote IP  OR = 0
295
; (IP Packet SA = Remote IP)  OR  (Remote IP = 0)
271
; IP Packet TCP Source Port = remote Port  OR = 0
296
; (IP Packet TCP Source Port = remote Port)  OR (remote Port = 0)
Line 316... Line 341...
316
 
341
 
317
;-------------------------------
342
;-------------------------------
Line 318... Line 343...
318
; ecx is size of tcp data
343
; ecx is size of tcp data
319
 
-
 
Line 320... Line 344...
320
; as a Packet has been received, update the TCB timer
344
 
321
	mov	[ebx +	SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.timer], TCP_SOCKET_TTL
345
; as a Packet has been received, update the TCB timer
322
 
346
 
Line 323... Line 347...
323
; If the received Packet has an ACK bit set, remove any Packets in the resend queue that this received Packet acknowledges
347
; If the received Packet has an ACK bit set, remove any Packets in the resend queue that this received Packet acknowledges
324
	test	[edx + TCP_Packet.Flags], TH_ACK
348
	test	[edx + TCP_Packet.Flags], TH_ACK
325
	jz	.no_ack 				 ; No ACK, so no data yet
349
	jz	.no_ack 				 ; No ACK, so no data yet
326
 
350
 
327
; Calculate ACK number
351
; Calculate ACK number, in intel byte order
328
	mov	edi, [edx + TCP_Packet.AckNumber]
-
 
Line 329... Line 352...
329
	bswap	edi
352
	mov	edi, [edx + TCP_Packet.AckNumber]
330
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.last_ack_number], edi
353
	bswap	edi
331
       DEBUGF 1,"Setting last_ack_number to %u\n", edi
354
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.last_ack_number], edi
Line -... Line 355...
-
 
355
	DEBUGF 1,"Setting last_ack_number to %u\n", edi
-
 
356
 
-
 
357
; Dequeue all acknowledged packets
-
 
358
	cmp	[TCP_OUT_QUEUE], 0		; first, check if any packets are queued at all
-
 
359
	je	.no_ack
332
	bswap	edi
360
 
333
 
361
	push	ebx
334
; Dequeue all acknowledged packets
362
	mov	ebx, TCP_OUT_QUEUE+4
335
	cmp	[TCP_OUT_QUEUE], 0		; first, check if any packets are queued at all
363
	call	wait_mutex
336
	je	.no_ack
364
	pop	ebx
337
 
365
 
338
	push	ecx
366
	push	ecx
Line 339... Line 367...
339
       DEBUGF 1,"Removing all queued packets with smaller ACK\n"
367
	DEBUGF 1,"Removing all queued packets with smaller ACK\n"
Line 357... Line 385...
357
	call	kernel_free
385
	call	kernel_free
Line 358... Line 386...
358
 
386
 
359
  .maybe_next:
387
  .maybe_next:
360
	add	esi, tcp_out_queue_entry.size
388
	add	esi, tcp_out_queue_entry.size
361
	loop	.loop
-
 
Line -... Line 389...
-
 
389
	loop	.loop
-
 
390
 
Line 362... Line 391...
362
	pop	ecx
391
	mov	[TCP_OUT_QUEUE+4], 0
363
 
392
	pop	ecx
364
 
393
 
Line 365... Line 394...
365
; Now call the correct handler, depending on the socket state
394
; Now call the correct handler, depending on the socket state
366
  .no_ack:
395
  .no_ack:
367
	mov	eax, [ebx +  SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state]
396
	mov	eax, [ebx +  SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state]
368
 
397
 
Line 369... Line -...
369
	cmp	eax, TCB_LISTEN
-
 
370
	jb	.dump
-
 
371
	cmp	eax, TCB_CLOSED
398
	cmp	eax, TCB_LISTEN
372
	ja	.dump
-
 
373
 
-
 
Line 374... Line 399...
374
	dec	eax
399
	jb	.dump
375
	shl	eax, 2
400
	cmp	eax, TCB_CLOSED
376
	add	eax, stateHandler
401
	ja	.dump
377
 
402
 
Line 463... Line 488...
463
 
488
 
464
; Now, calculate the checksum
489
; Now, calculate the checksum
465
	xchg	cl, ch
490
	xchg	cl, ch
466
	pushw	cx
491
	pushw	cx
467
	xchg	cl, ch
-
 
468
;;        pushw   TCP_Packet.Data shl 8
492
	xchg	cl, ch
469
	pushw	IP_PROTO_TCP shl 8
493
	pushw	IP_PROTO_TCP shl 8
470
	pushd	[edi-4] ; destination address  ; TODO: fix this, IPv4 packet could have options..
494
	pushd	[edi-4] ; destination address           ; TODO: fix this, IPv4 packet could have options..
Line 471... Line 495...
471
	pushd	[edi-8] ; source address
495
	pushd	[edi-8] ; source address
472
 
-
 
473
	xor	edx, edx
496
 
474
;        mov     ecx, TCP_Packet.Data
497
	xor	edx, edx
475
	mov	esi, edi
498
	mov	esi, edi
476
	call	checksum_1
499
	call	checksum_1
477
	mov	ecx, 12
500
	mov	ecx, 12
Line 494... Line 517...
494
	je	.only_one				   ; send it only once
517
	je	.only_one				   ; send it only once
Line 495... Line 518...
495
 
518
 
496
	and	ecx, 0x0000ffff
519
	and	ecx, 0x0000ffff
497
	xchg	cl, ch
520
	xchg	cl, ch
498
	sub	cx, TCP_Packet.Data
-
 
Line -... Line 521...
-
 
521
	sub	cx, TCP_Packet.Data
499
	add_INET (edi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT)
522
 
Line 500... Line 523...
500
 
523
	add_INET (edi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT)     ; todo: this should only happen when packet was queued successful
Line 501... Line 524...
501
	mov	ecx, TCP_RETRIES
524
	mov	ecx, TCP_RETRIES
502
 
-
 
503
	jmp	.go_for_it
525
 
504
 
526
	jmp	.go_for_it
Line 505... Line 527...
505
  .only_one:
527
 
506
;        inc_INET (edi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT)
528
  .only_one:
Line 521... Line 543...
521
;  Queue a TCP packet for sending
543
;  Queue a TCP packet for sending
522
;
544
;
523
;  IN:  [esp] pointer to buffer
545
;  IN:  [esp] pointer to buffer
524
;       [esp + 4] size of buffer
546
;       [esp + 4] size of buffer
525
;       ebx = driver struct
547
;       ebx = driver struct
-
 
548
;       edx = sequence number of this packet in intel byte order
526
;       esi = sender proc
549
;       esi = sender proc
527
;       edx = sequence number of this packet in normal byte order
-
 
528
;       edi = socket number
550
;       edi = socket number
529
;       ecx = retries
-
 
-
 
551
 
530
;  OUT: /
552
;  OUT: /
531
;
553
;
532
;-----------------------------------------------------------------
554
;-----------------------------------------------------------------
533
align 4
555
align 4
534
TCP_queue:
556
TCP_queue:
Line 535... Line -...
535
 
-
 
536
	bswap	edx
557
 
537
	DEBUGF 1,"Adding packet to TCP queue, buffer: %x, size: %u, driver: %x, acknum: %u\n", [esp], [esp+4], ebx, edx
-
 
Line 538... Line 558...
538
	bswap	edx
558
	DEBUGF 1,"Adding packet to TCP queue, buffer: %x, size: %u, driver: %x, acknum: %u\n", [esp], [esp+4], ebx, edx
539
 
559
 
Line 540... Line 560...
540
	cmp	[TCP_OUT_QUEUE], TCP_QUEUE_SIZE
560
	cmp	[TCP_OUT_QUEUE], TCP_QUEUE_SIZE
541
	jge	.full
561
	jge	.full
542
 
562
 
-
 
563
	push	ebx
Line -... Line 564...
-
 
564
	mov	ebx, TCP_OUT_QUEUE+4
-
 
565
	call	wait_mutex
543
	push	ecx
566
	pop	ebx
544
	mov	ecx, TCP_QUEUE_SIZE
567
 
545
	mov	eax, TCP_OUT_QUEUE+4
568
	mov	ecx, TCP_QUEUE_SIZE
546
 
569
	mov	eax, TCP_OUT_QUEUE+8
547
  .loop:
570
  .loop:
Line -... Line 571...
-
 
571
	cmp	[eax + tcp_out_queue_entry.data_ptr], 0
548
	cmp	[eax + tcp_out_queue_entry.data_ptr], 0
572
	je	.found_it
549
	je	.found_it
573
	add	eax, tcp_out_queue_entry.size
550
	add	eax, tcp_out_queue_entry.size
-
 
551
	loop	.loop
-
 
552
 
574
	loop	.loop
553
  .full:			; silently discard the packet
575
 
Line 554... Line 576...
554
	DEBUGF 1,"TCP queue is full!\n"
576
	add	esp, 4
Line 555... Line 577...
555
 
577
  .full:			; silently discard the packet
Line 556... Line 578...
556
	add	esp, 4
578
	DEBUGF 1,"TCP queue is full!\n"
557
	call	kernel_free
579
	call	kernel_free
558
	add	esp, 4
580
	add	esp, 4
559
 
581
 
560
	ret
582
	ret
561
 
583
 
562
  .found_it:			; eax points to empty queue entry
584
  .found_it:			; eax points to empty queue entry
563
 
585
 
Line 564... Line 586...
564
	pop	[eax + tcp_out_queue_entry.retries]
586
	mov	[eax + tcp_out_queue_entry.retries], TCP_RETRIES
Line 565... Line 587...
565
	pop	[eax + tcp_out_queue_entry.data_ptr]
587
	pop	[eax + tcp_out_queue_entry.data_ptr]
-
 
588
	pop	[eax + tcp_out_queue_entry.data_size]
566
	pop	[eax + tcp_out_queue_entry.data_size]
589
	mov	[eax + tcp_out_queue_entry.ttl], 1			; send immediately
-
 
590
	mov	[eax + tcp_out_queue_entry.owner], ebx
-
 
591
	mov	[eax + tcp_out_queue_entry.sendproc], esi
Line 567... Line 592...
567
	mov	[eax + tcp_out_queue_entry.ttl], 1			; send immediately
592
	mov	[eax + tcp_out_queue_entry.seq_num], edx
Line -... Line 593...
-
 
593
	mov	[eax + tcp_out_queue_entry.socket], edi
-
 
594
 
-
 
595
	inc	[TCP_OUT_QUEUE]
-
 
596
 
-
 
597
	sub	eax, TCP_OUT_QUEUE+8
-
 
598
	shr	eax, 5
-
 
599
	DEBUGF 1,"Added to queue in pos %u, total queued packets: %u\n", eax, [TCP_OUT_QUEUE+8]
-
 
600
 
-
 
601
	mov	[TCP_OUT_QUEUE+4], 0
-
 
602
 
-
 
603
	ret
-
 
604
 
-
 
605
 
-
 
606
;-----------------------------------------------------------------
-
 
607
;
-
 
608
;  IN:  ebx = socket
-
 
609
;       ecx = ack number
-
 
610
;
-
 
611
;  OUT: /
-
 
612
;
-
 
613
;-----------------------------------------------------------------
-
 
614
align 4
-
 
615
TCP_queue_ack:
-
 
616
 
-
 
617
	DEBUGF 1,"Adding ACK to TCP queue, socket: %x, acknum: %u\n", ebx, ecx
-
 
618
 
-
 
619
	cmp	[TCP_OUT_QUEUE], TCP_QUEUE_SIZE
-
 
620
	jge	.full
-
 
621
 
-
 
622
	push	ebx ecx
-
 
623
	mov	ebx, TCP_OUT_QUEUE+4
-
 
624
	call	wait_mutex
-
 
625
 
-
 
626
	mov	ecx, TCP_QUEUE_SIZE
-
 
627
	mov	eax, TCP_OUT_QUEUE+8
-
 
628
  .loop:
-
 
629
	cmp	[eax + tcp_out_queue_entry.data_ptr], 0
-
 
630
	je	.found_it
-
 
631
	add	eax, tcp_out_queue_entry.size
-
 
632
	loop	.loop
-
 
633
 
-
 
634
	add	esp, 8
-
 
635
  .full:			; silently discard the packet
-
 
636
	DEBUGF 1,"TCP queue is full!\n"
-
 
637
	ret
-
 
638
 
-
 
639
  .found_it:			; eax points to empty queue entry
-
 
640
 
-
 
641
	pop	[eax + tcp_out_queue_entry.data_size]			; ACK number
-
 
642
	mov	[eax + tcp_out_queue_entry.data_ptr], -1		; ACK packet
-
 
643
	pop	[eax + tcp_out_queue_entry.socket]
-
 
644
	mov	[eax + tcp_out_queue_entry.retries], 1
-
 
645
	mov	[eax + tcp_out_queue_entry.ttl], 20			; 200 ms
-
 
646
 
-
 
647
	inc	[TCP_OUT_QUEUE]
-
 
648
 
-
 
649
	sub	eax, TCP_OUT_QUEUE+8
-
 
650
	shr	eax, 5
-
 
651
	DEBUGF 1,"Added to queue in pos %u, total queued packets: %u\n", eax, [TCP_OUT_QUEUE+8]
-
 
652
 
-
 
653
	mov	[TCP_OUT_QUEUE+4], 0
-
 
654
 
-
 
655
	ret
-
 
656
 
-
 
657
 
-
 
658
; IN: eax = socket pointer
-
 
659
;     ebx = device structure
-
 
660
;     ecx = ack number
-
 
661
 
-
 
662
align 4
-
 
663
TCP_send_ack:
-
 
664
 
-
 
665
	DEBUGF 1,"Creating TCP ACK packet, socket: %x, acknum: %x\n", eax, ecx
-
 
666
 
-
 
667
	push	ecx eax
-
 
668
 
-
 
669
	mov	di , IP_PROTO_TCP
-
 
670
	mov	ecx, TCP_Packet.Data
-
 
671
; Create an IPv4 Packet of the correct size
-
 
672
	mov	ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP]
-
 
673
	mov	eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP]
-
 
674
 
-
 
675
	call	IPv4_create_packet
-
 
676
	cmp	edi, -1
-
 
677
	je	.fail
-
 
678
 
-
 
679
	pop	ecx
-
 
680
 
-
 
681
; fill in tcp sequence number
-
 
682
	push	[ecx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
-
 
683
	pop	[edi + TCP_Packet.SequenceNumber]
-
 
684
 
-
 
685
; Fill in local and remote ports
-
 
686
	push	dword [ecx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort]
-
 
687
	pop	dword [edi + TCP_Packet.SourcePort]
-
 
688
 
-
 
689
; Acknumber
-
 
690
	pop	[edi + TCP_Packet.AckNumber]
-
 
691
 
-
 
692
; Fill  in other tcp options
-
 
693
	mov	[edi + TCP_Packet.Flags], TH_ACK
-
 
694
	mov	[edi + TCP_Packet.Window], 0x0005	   ; 1280 bytes
-
 
695
	mov	[edi + TCP_Packet.UrgentPointer], 0
-
 
696
	mov	[edi + TCP_Packet.DataOffset], 0x50
-
 
697
	mov	[edi + TCP_Packet.Checksum], 0
-
 
698
 
-
 
699
; Push pointer to and size of total packet (needed for send procedure)
-
 
700
	push	edx eax esi
-
 
701
 
-
 
702
; Now, calculate the checksum
-
 
703
	pushw	TCP_Packet.Data shl 8
-
 
704
	pushw	IP_PROTO_TCP shl 8
-
 
705
	pushd	[edi-4] ; destination address           ; TODO: fix this, IPv4 packet could have options..
-
 
706
	pushd	[edi-8] ; source address
-
 
707
 
-
 
708
	xor	edx, edx
-
 
709
	mov	ecx, 12
-
 
710
	mov	esi, esp
-
 
711
	call	checksum_1
-
 
712
	call	checksum_2
-
 
713
	mov	[edi + TCP_Packet.Checksum], dx
-
 
714
	add	esp, 12 				; remove the pseudoheader from stack
-
 
715
 
-
 
716
	pop	eax
-
 
717
	call	eax
-
 
718
	call	kernel_free
-
 
719
	add	esp, 4 ; pop (balance stack)
-
 
720
	ret
-
 
721
 
-
 
722
  .fail:
-
 
723
	add	esp, 8
-
 
724
	ret
-
 
725
 
-
 
726
 
-
 
727
 
-
 
728
 
-
 
729
;-----------------------------------------------------------------
-
 
730
;
-
 
731
; Remove all queued TCP packets for a specified socket
-
 
732
;
-
 
733
; IN: eax = socket number
-
 
734
; OUT: /
-
 
735
;
-
 
736
; destoys esi and ecx
-
 
737
;
-
 
738
;-----------------------------------------------------------------
-
 
739
 
-
 
740
align 4
-
 
741
TCP_remove_socket:
-
 
742
 
-
 
743
	cmp	[TCP_OUT_QUEUE], 0
-
 
744
	je	.skip
-
 
745
 
-
 
746
	mov	ebx, TCP_OUT_QUEUE+4
-
 
747
	call	wait_mutex
-
 
748
 
-
 
749
	mov	eax, TCP_QUEUE_SIZE
-
 
750
	mov	ecx, [TCP_OUT_QUEUE]
-
 
751
	mov	esi, TCP_OUT_QUEUE+8
-
 
752
 
-
 
753
  .loop:
-
 
754
	cmp	[esi + tcp_out_queue_entry.data_ptr], 0
-
 
755
	jz	.maybenext
-
 
756
	cmp	[esi + tcp_out_queue_entry.socket], eax
-
 
757
	jnz	.maybenext
-
 
758
 
-
 
759
	push	[esi + tcp_out_queue_entry.data_ptr]
Line 568... Line 760...
568
	mov	[eax + tcp_out_queue_entry.owner], ebx
760
	mov	[esi + tcp_out_queue_entry.data_ptr], 0
Line 735... Line 927...
735
  .exit:
927
  .exit:
736
	mov	[ebx + SOCKET_head.lock], 0
928
	mov	[ebx + SOCKET_head.lock], 0
737
	ret
929
	ret
Line -... Line 930...
-
 
930
 
-
 
931
 
-
 
932
if 0
-
 
933
 
-
 
934
 
-
 
935
align 4
-
 
936
stateTCB_ESTABLISHED:
-
 
937
 
-
 
938
	DEBUGF	1,"TCBStateHandler: Established\n"
-
 
939
 
-
 
940
	mov	eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
-
 
941
	bswap	eax
-
 
942
	DEBUGF	1,"RCV_NXT is set to:%u\n", eax
-
 
943
	bswap	eax
-
 
944
	cmp	eax, [edx + TCP_Packet.SequenceNumber]
-
 
945
	jne	.exit					;;;;;;
-
 
946
 
-
 
947
; check if we received an ACK
-
 
948
	test	[edx + TCP_Packet.Flags], TH_ACK
-
 
949
	jz	.no_ack
-
 
950
 
-
 
951
	mov	ax, [edx + TCP_Packet.Window]
-
 
952
	xchg	al, ah
-
 
953
	cmp	ax, 1024
-
 
954
	ja	@f
-
 
955
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 1
-
 
956
      @@:
-
 
957
  .no_ack:
-
 
958
 
-
 
959
; Now, see if we received any data
-
 
960
	test	ecx, ecx
-
 
961
	jz	.nodata
-
 
962
 
-
 
963
; Calculate next sequencenumber
-
 
964
	add_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT)
-
 
965
 
-
 
966
	push	edx
-
 
967
	DEBUGF	1,"Got %u bytes data!\n", ecx
-
 
968
; calculate header length
-
 
969
	movzx	eax, [edx + TCP_Packet.DataOffset]
-
 
970
	and	eax, 11110000b
-
 
971
	shr	eax, 2
-
 
972
	DEBUGF	1,"TCP header size: %u\n", eax
-
 
973
	add	edx, eax	; now edx points to data
-
 
974
 
-
 
975
	add	esp, 4
-
 
976
	pop	esi		; pointer to buffer
-
 
977
	add	esp, 4
-
 
978
 
-
 
979
	sub	edx, esi
-
 
980
	mov	edi, edx	; offset
-
 
981
	mov	eax, ebx	; socket ptr
-
 
982
 
-
 
983
	call	socket_internal_receiver	; Place the data from packet into socket
-
 
984
 
-
 
985
;        lea     ebx, [eax + SOCKET_head.lock]
-
 
986
;        call    wait_mutex
-
 
987
	mov	ebx, eax
-
 
988
	pop	edx
-
 
989
 
-
 
990
	test	[edx + TCP_Packet.Flags], TH_FIN + TH_RST
-
 
991
	jz	.ack
-
 
992
 
-
 
993
  .nodata:
-
 
994
	test	[edx + TCP_Packet.Flags], TH_FIN + TH_RST
-
 
995
	jz	.exit
-
 
996
 
-
 
997
; Send an ACK to that fin, and enter closewait state
-
 
998
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSE_WAIT
-
 
999
; Remove all resend entries from the queue
-
 
1000
	mov	eax, ebx
-
 
1001
	call	TCP_remove_socket
-
 
1002
 
-
 
1003
  .ack:
-
 
1004
	push	ebx
-
 
1005
	mov	ecx, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
-
 
1006
	call	TCP_queue_ack
-
 
1007
	pop	ebx
-
 
1008
 
-
 
1009
  .exit:
-
 
1010
	mov	[ebx + SOCKET_head.lock], 0
-
 
1011
	ret
-
 
1012
 
-
 
1013
 
Line 738... Line 1014...
738
 
1014
end if
739
 
1015
 
Line 740... Line 1016...
740
 
1016
 
Line 749... Line 1025...
749
	bswap	eax
1025
	bswap	eax
750
	cmp	eax, [edx + TCP_Packet.SequenceNumber]
1026
	cmp	eax, [edx + TCP_Packet.SequenceNumber]
751
	jne	.exit
1027
	jne	.exit
Line 752... Line 1028...
752
 
1028
 
753
; Calculate next sequencenumber
-
 
754
;;        test    ecx, ecx
-
 
755
;;        jnz     @f
-
 
756
;;        inc     ecx
-
 
757
;;       @@:
1029
; Calculate next sequencenumber
Line 758... Line 1030...
758
	add_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT)
1030
	add_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT)
759
 
1031
 
Line 760... Line 1032...
760
	test	[edx + TCP_Packet.Flags], TH_FIN + TH_RST ;;;
1032
	test	[edx + TCP_Packet.Flags], TH_FIN + TH_RST
761
	jnz	.fin
1033
	jnz	.fin
762
 
1034
 
Line 797... Line 1069...
797
	mov	edi, edx	; offset
1069
	mov	edi, edx	; offset
798
	mov	eax, ebx	; socket ptr
1070
	mov	eax, ebx	; socket ptr
Line 799... Line 1071...
799
 
1071
 
Line 800... Line 1072...
800
	call	socket_internal_receiver	; Place the data from packet into socket
1072
	call	socket_internal_receiver	; Place the data from packet into socket
801
 
1073
 
802
	lea	ebx, [eax + SOCKET_head.lock]  ;;;;;
1074
	lea	ebx, [eax + SOCKET_head.lock]
Line 803... Line 1075...
803
	call	wait_mutex			 ;;;;;
1075
	call	wait_mutex
804
	mov	ebx, eax			   ;;;;
1076
	mov	ebx, eax
805
 
1077
 
806
  .ack:
1078
  .ack:
Line 812... Line 1084...
812
	pop	ebx
1084
	pop	ebx
813
  .exit:
1085
  .exit:
814
	mov	[ebx + SOCKET_head.lock], 0
1086
	mov	[ebx + SOCKET_head.lock], 0
815
	ret
1087
	ret
Line 816... Line 1088...
816
 
1088
 
817
  .fin:
1089
  .fin:        ; we received a FIN or RESET
818
; Remove all resend entries from the queue
1090
; Remove all resend entries from the queue
819
	mov	ecx, TCP_QUEUE_SIZE
1091
	mov	ecx, TCP_QUEUE_SIZE
Line 820... Line 1092...
820
	mov	esi, TCP_OUT_QUEUE+4
1092
	mov	esi, TCP_OUT_QUEUE+4
Line 835... Line 1107...
835
  .maybe_next:
1107
  .maybe_next:
836
	add	esi, tcp_out_queue_entry.size
1108
	add	esi, tcp_out_queue_entry.size
837
	loop	.removeloop
1109
	loop	.removeloop
Line 838... Line 1110...
838
 
1110
 
839
; Send an ACK to that fin, and enter closewait state
1111
; Send an ACK to that fin, and enter closewait state
840
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSE_WAIT
1112
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSING
Line 841... Line -...
841
	jmp	.check_ack
-
 
842
 
1113
	jmp	.check_ack
843
 
1114
 
Line 844... Line 1115...
844
 
1115
 
Line 862... Line 1133...
862
	cmp	al, TH_FIN
1133
	cmp	al, TH_FIN
863
	je	@f
1134
	je	@f
864
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT
1135
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT
Line 865... Line 1136...
865
 
1136
 
866
    @@:
-
 
867
 
-
 
868
;        lea     esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
-
 
869
;        inc_INET esi
-
 
870
 
1137
    @@:
871
	; Send an ACK
1138
	; Send an ACK
872
	mov	eax, ebx
1139
	mov	eax, ebx
873
	mov	bl, TH_ACK
1140
	mov	bl, TH_ACK
874
	push	eax
1141
	push	eax
Line 891... Line 1158...
891
	jz	.exit
1158
	jz	.exit
Line 892... Line 1159...
892
 
1159
 
893
	; Change state, as we have a fin
1160
	; Change state, as we have a fin
Line 894... Line -...
894
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT
-
 
895
 
-
 
896
	lea	esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
-
 
897
	inc_INET esi
-
 
898
 
-
 
899
	mov	[ebx + SOCKET_head.lock], 0
1161
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT
900
 
1162
 
901
	; Send an ACK
1163
	; Send an ACK
902
	mov	eax, ebx
1164
	mov	eax, ebx
903
	mov	bl, TH_ACK
1165
	mov	bl, TH_ACK