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 |