From c14545104d42bea6232db2f00106b432f32b31e4 Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Sun, 22 Nov 2009 17:25:31 +0000 Subject: [PATCH] changes in Net Branch: further development of TCP code git-svn-id: svn://kolibrios.org@1281 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/branches/net/network/socket.inc | 49 ++++++---------- kernel/branches/net/network/tcp.inc | 80 ++++++++++++++++++-------- 2 files changed, 74 insertions(+), 55 deletions(-) diff --git a/kernel/branches/net/network/socket.inc b/kernel/branches/net/network/socket.inc index a5f8ca03c6..85a3d5f2c5 100644 --- a/kernel/branches/net/network/socket.inc +++ b/kernel/branches/net/network/socket.inc @@ -334,6 +334,8 @@ socket_connect: .tcp: ; TODO: set sequence number to random value + lea ebx, [eax + SOCKET_head.lock] + call wait_mutex ; fill in remote port and IP @@ -518,35 +520,16 @@ socket_close: cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_SENT je .destroy_tcb - ; Now construct the response, and queue for sending by IP - - mov bl, TH_FIN - xor ecx, ecx - call TCP_send - - ; increament SND.NXT in socket - lea esi, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] - inc_INET esi - - ; Get the socket state - cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED - je .fin_wait_1 - cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED - je .fin_wait_1 - - ; assume CLOSE WAIT - ; Send a fin, then enter last-ack state - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LAST_ACK - jmp .send - - .fin_wait_1: ; Send a fin, then enter finwait2 state mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_FIN_WAIT_1 - .send: + mov bl, TH_FIN + xor ecx, ecx +; call TCP_send ;;;;; + .destroy_tcb: stdcall net_socket_free, eax @@ -571,32 +554,34 @@ socket_close: align 4 socket_recv: - DEBUGF 1,"Socket_receive: socknum: %u bufferaddress: %x, length: %u, flags: %x\n",ecx,edx,esi,edi + DEBUGF 1,"Socket_receive: socknum: %u bufaddr: %x, buflength: %u, flags: %x\n",ecx,edx,esi,edi stdcall net_socket_num_to_addr, ecx ; get real socket address or eax, eax jz s_error + mov ebx, esi + DEBUGF 1,"Socket pointer: %x\n", eax - get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, s_error + get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, s_error ; destroys esi and ecx - mov edi, edx + mov edi, edx ; addr to buffer mov ecx, [esi + socket_queue_entry.data_size] DEBUGF 1,"Got %u bytes of data\n", ecx - cmp ecx, edx + cmp ecx, ebx jle .large_enough DEBUGF 1,"Buffer too small...\n" jmp s_error .large_enough: - push [esi + socket_queue_entry.data_ptr] + push [esi + socket_queue_entry.data_ptr] ; save the buffer addr so we can clear it later mov esi, [esi + socket_queue_entry.offset] - add esi, [esp] + add esi, [esp] ; calculate the real data offset DEBUGF 1,"Source buffer: %x, real addr: %x\n", [esp], esi - mov dword[esp+32+4], ecx ; return number of bytes copied + mov dword[esp+32+4], ecx ; return number of bytes copied shr ecx, 1 jnc .nb @@ -609,7 +594,7 @@ socket_recv: rep movsd .nd: - call kernel_free + call kernel_free ; todo: check if ALL applications had the chance to receive data ret @@ -696,7 +681,7 @@ socket_send: mov ecx, esi mov esi, edx - xor bl , bl + mov bl, TH_PUSH + TH_ACK call TCP_send diff --git a/kernel/branches/net/network/tcp.inc b/kernel/branches/net/network/tcp.inc index 8fac7e047c..c22036adbe 100644 --- a/kernel/branches/net/network/tcp.inc +++ b/kernel/branches/net/network/tcp.inc @@ -41,7 +41,7 @@ ends struct tcp_in_queue_entry .data_ptr dd ? .data_size dd ? - .offset dd ? + .offset dd ? ; TODO: replace this in code by absolute address isntead of relative offset .size: ends @@ -238,6 +238,7 @@ TCP_send_queued: push [esi + tcp_out_queue_entry.data_ptr] mov [esi + tcp_out_queue_entry.data_ptr], 0 call kernel_free + dec [TCP_OUT_QUEUE] jmp .find_next @@ -391,7 +392,7 @@ TCP_handler : ; ; IN: eax = socket pointer ; bl = flags -; ecx = number of bytes to send, may be set to 0 +; ecx = number of bytes to send, may be set to 0 (single ACK) ; esi = pointer to data ; ;----------------------------------------------------------------- @@ -403,7 +404,7 @@ TCP_send: mov di , IP_PROTO_TCP add ecx, TCP_Packet.Data - push bx eax esi + push ecx bx eax esi ; Create an IPv4 Packet of the correct size mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP] mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP] @@ -436,7 +437,6 @@ TCP_send: ; fill in tcp sequence number push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] pop [edi + TCP_Packet.SequenceNumber] - inc_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT) ;;;;;;;; ; Fill in local and remote ports push dword [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort] @@ -454,37 +454,61 @@ TCP_send: mov [edi + TCP_Packet.DataOffset], 0x50 mov [edi + TCP_Packet.Checksum], 0 +; Get size of total packet back in ecx + pop ecx ; Push pointer to and size of total packet (needed for send procedure) push edx eax - ; push socket number (for TCP_add_to_queue) push esi -; Now, calculate the checksum ; TODO: calculate correct checksum for packets with data - pushw TCP_Packet.Data shl 8 +; Now, calculate the checksum + xchg cl, ch + pushw cx + xchg cl, ch +;; pushw TCP_Packet.Data shl 8 pushw IP_PROTO_TCP shl 8 pushd [edi-4] ; destination address ; TODO: fix this, IPv4 packet could have options.. pushd [edi-8] ; source address xor edx, edx - mov ecx, TCP_Packet.Data +; mov ecx, TCP_Packet.Data mov esi, edi call checksum_1 mov ecx, 12 mov esi, esp call checksum_1 - add esp, 12 ; remove the pseudoheader from stack ; and store it in TCP header call checksum_2 mov [edi + TCP_Packet.Checksum], dx + add esp, 10 ; remove the pseudoheader from stack -; At last send the packet! DEBUGF 1,"Sending TCP Packet to device %x\n", ebx mov edx, [edi + TCP_Packet.SequenceNumber] bswap edx mov esi, [ebx + ETH_DEVICE.transmit] + + pop cx ; get the length from packet, back from pseudoheader pop edi - jmp TCP_queue + + cmp cx, TCP_Packet.Data shl 8 ; if the packet has no data + je .only_one ; send it only once + + and ecx, 0x0000ffff + xchg cl, ch + sub cx, TCP_Packet.Data + add_INET (edi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT) + + mov ecx, TCP_RETRIES + + jmp .go_for_it + + .only_one: +; inc_INET (edi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT) + mov ecx, 1 + .go_for_it: + + mov [edi + SOCKET_head.lock], 0 + jmp TCP_queue ; At last send the packet! .fail: add esp, 2+4 @@ -502,6 +526,7 @@ TCP_send: ; esi = sender proc ; edx = sequence number of this packet in normal byte order ; edi = socket number +; ecx = retries ; OUT: / ; ;----------------------------------------------------------------- @@ -515,6 +540,7 @@ TCP_queue: cmp [TCP_OUT_QUEUE], TCP_QUEUE_SIZE jge .full + push ecx mov ecx, TCP_QUEUE_SIZE mov eax, TCP_OUT_QUEUE+4 @@ -527,6 +553,7 @@ TCP_queue: .full: ; silently discard the packet DEBUGF 1,"TCP queue is full!\n" + add esp, 4 call kernel_free add esp, 4 @@ -534,10 +561,10 @@ TCP_queue: .found_it: ; eax points to empty queue entry + pop [eax + tcp_out_queue_entry.retries] pop [eax + tcp_out_queue_entry.data_ptr] pop [eax + tcp_out_queue_entry.data_size] mov [eax + tcp_out_queue_entry.ttl], 1 ; send immediately - mov [eax + tcp_out_queue_entry.retries], TCP_RETRIES mov [eax + tcp_out_queue_entry.owner], ebx mov [eax + tcp_out_queue_entry.sendproc], esi mov [eax + tcp_out_queue_entry.seq_num], edx @@ -724,13 +751,13 @@ stateTCB_ESTABLISHED: jne .exit ; Calculate next sequencenumber - test ecx, ecx - jnz @f - inc ecx - @@: +;; test ecx, ecx +;; jnz @f +;; inc ecx +;; @@: add_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT) - test [edx + TCP_Packet.Flags], TH_FIN + test [edx + TCP_Packet.Flags], TH_FIN + TH_RST ;;; jnz .fin .check_ack: @@ -752,7 +779,7 @@ stateTCB_ESTABLISHED: ; Now, see if we received any data test ecx, ecx - jz .ack + jz .exit DEBUGF 1,"Got %u bytes data!\n", ecx ; calculate header length @@ -760,14 +787,21 @@ stateTCB_ESTABLISHED: and eax, 11110000b shr eax, 2 DEBUGF 1,"TCP header size: %u\n", eax - add edx, eax + add edx, eax ; now edx points to data + add esp, 4 - pop esi + pop esi ; pointer to buffer add esp, 4 + sub edx, esi - mov edi, edx - mov eax, ebx - jmp socket_internal_receiver ; Place the data from packet into socket + mov edi, edx ; offset + mov eax, ebx ; socket ptr + + call socket_internal_receiver ; Place the data from packet into socket + + lea ebx, [eax + SOCKET_head.lock] ;;;;; + call wait_mutex ;;;;; + mov ebx, eax ;;;; .ack: mov eax, ebx