From db559618341e2bd17b244041749f19d27876087a Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Mon, 24 Jan 2011 22:01:54 +0000 Subject: [PATCH] More updates to TCP code of new stack. git-svn-id: svn://kolibrios.org@1763 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/branches/net/network/socket.inc | 26 +-- kernel/branches/net/network/stack.inc | 34 ++- kernel/branches/net/network/tcp.inc | 6 +- kernel/branches/net/network/tcp_input.inc | 228 ++++++++++++++++----- kernel/branches/net/network/tcp_output.inc | 18 ++ kernel/branches/net/network/tcp_subr.inc | 17 +- kernel/branches/net/network/tcp_timer.inc | 17 ++ 7 files changed, 255 insertions(+), 91 deletions(-) diff --git a/kernel/branches/net/network/socket.inc b/kernel/branches/net/network/socket.inc index 829e0563ad..2f6020375c 100644 --- a/kernel/branches/net/network/socket.inc +++ b/kernel/branches/net/network/socket.inc @@ -1,10 +1,8 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; -;; SOCKET.INC ;; -;; ;; ;; Written by hidnplayr@kolibrios.org, ;; ;; and Clevermouse. ;; ;; ;; @@ -45,12 +43,8 @@ end virtual virtual at SOCKET.end IP_SOCKET: - - .LocalIP dd ? - rd 3 ; for IPv6 addresses - - .RemoteIP dd ? - rd 3 ; for IPv6 addresses + .LocalIP rd 4 + .RemoteIP rd 4 .end: end virtual @@ -788,6 +782,9 @@ SOCKET_send: call SOCKET_num_to_ptr jz s_error + mov ecx, esi + mov esi, edx + jmp [eax + SOCKET.snd_proc] @@ -796,9 +793,6 @@ SOCKET_send_udp: DEBUGF 1,"SOCKET_send: UDP\n" - mov ecx, esi - mov esi, edx - call UDP_output mov dword [esp+32], 0 @@ -811,8 +805,6 @@ SOCKET_send_tcp: DEBUGF 1,"SOCKET_send: TCP\n" push eax - mov ecx, esi - mov esi, edx add eax, STREAM_SOCKET.snd call SOCKET_ring_write pop eax @@ -828,12 +820,9 @@ SOCKET_send_ip: DEBUGF 1,"type: IP\n" - mov ecx, esi - mov esi, edx - call IPv4_output_raw - mov dword [esp+32], eax + mov [esp+32], eax ret align 4 @@ -841,7 +830,6 @@ SOCKET_send_icmp: DEBUGF 1,"SOCKET_send: ICMP\n" - mov ecx, esi call ICMP_output_raw mov dword [esp+32], 0 diff --git a/kernel/branches/net/network/stack.inc b/kernel/branches/net/network/stack.inc index e94f86fd3c..eba49ac10d 100644 --- a/kernel/branches/net/network/stack.inc +++ b/kernel/branches/net/network/stack.inc @@ -1,16 +1,20 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; STACK.INC ;; ;; ;; -;; BASIC TCP/IP stack for KolibriOS ;; +;; TCP/IP stack for KolibriOS ;; ;; ;; ;; Written by hidnplayr@kolibrios.org ;; ;; ;; -;; based on the work of Mike Hibbett, mikeh@oceanfree.net ;; -;; but also Paolo Franchetti ;; +;; Some parts of code are based on the work of: ;; +;; Mike Hibbett (menuetos network stack) ;; +;; Eugen Brasoveanu (solar os network stack and drivers) ;; +;; mike.dld (kolibrios socket code) ;; +;; ;; +;; TCP part is based on 4.4BSD ;; ;; ;; ;; GNU GENERAL PUBLIC LICENSE ;; ;; Version 2, June 1991 ;; @@ -19,19 +23,18 @@ $Revision$ -__DEBUG_LEVEL_OLD__ equ __DEBUG_LEVEL__ - -__DEBUG_LEVEL__ equ 1 ; this sets the debug level for network part of kernel +__DEBUG_LEVEL_OLD__ equ __DEBUG_LEVEL__ ; use seperate debug level for network part of kernel +__DEBUG_LEVEL__ equ 1 uglobal - net_10ms dd ? - net_tmr_count dw ? + net_10ms dd ? + net_tmr_count dw ? endg MAX_NET_DEVICES equ 16 -MIN_EPHEMERAL_PORT equ 49152 -MAX_EPHEMERAL_PORT equ 61000 +MIN_EPHEMERAL_PORT equ 49152 +MAX_EPHEMERAL_PORT equ 61000 ; Ethernet protocol numbers ETHER_ARP equ 0x0608 @@ -43,13 +46,6 @@ ETHER_PPP_SESSION equ 0x6488 AF_UNSPEC equ 0 AF_UNIX equ 1 AF_INET4 equ 2 -;AF_AX25 equ 3 -;AF_IPX equ 4 -;AF_APPLETALK equ 5 -;AF_NETROM equ 6 -;AF_BRIDGE equ 7 -;AF_AAL5 equ 8 -;AF_X25 equ 9 AF_INET6 equ 10 ; Internet protocol numbers @@ -100,7 +96,7 @@ virtual at 0 .packets_tx dd ? ; .packets_rx dd ? ; -; .chksum dd ? ; bitmask stating available checksum routines on hardware +; .hwacc dd ? ; bitmask stating available hardware accelerations (offload engines) .end: diff --git a/kernel/branches/net/network/tcp.inc b/kernel/branches/net/network/tcp.inc index 30ba72f0d7..b8554e3f08 100644 --- a/kernel/branches/net/network/tcp.inc +++ b/kernel/branches/net/network/tcp.inc @@ -1,10 +1,8 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; -;; TCP.INC ;; -;; ;; ;; Part of the tcp/ip network stack for KolibriOS ;; ;; ;; ;; Written by hidnplayr@kolibrios.org ;; @@ -77,6 +75,8 @@ TCP_max_keepcnt equ 8 ; max keepalive probes TCP_max_winshift equ 14 TCP_max_win equ 65535 +TCP_re_xmit_thresh equ 3 + struct TCP_segment .SourcePort dw ? .DestinationPort dw ? diff --git a/kernel/branches/net/network/tcp_input.inc b/kernel/branches/net/network/tcp_input.inc index 4e69ede312..363823d03d 100644 --- a/kernel/branches/net/network/tcp_input.inc +++ b/kernel/branches/net/network/tcp_input.inc @@ -1,3 +1,21 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; Part of the tcp/ip network stack for KolibriOS ;; +;; ;; +;; Written by hidnplayr@kolibrios.org ;; +;; ;; +;; Based on the code of 4.4BSD ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + ;----------------------------------------------------------------- ; ; TCP_input: @@ -339,8 +357,9 @@ TCP_input: ; Update RTT estimators -; Delete acknowledged bytes from send buffer +;;; TODO +; Delete acknowledged bytes from send buffer pusha mov ecx, eax lea eax, [ebx + STREAM_SOCKET.snd] @@ -349,22 +368,20 @@ TCP_input: ; update window pointers mov eax, [edx + TCP_segment.AckNumber] - dec eax - mov [ebx + TCP_SOCKET.SND_WL1], eax + mov [ebx + TCP_SOCKET.SND_UNA], eax ; Stop retransmit timer mov [ebx + TCP_SOCKET.timer_ack], 0 ; Awaken waiting processes + mov [ebx + SOCKET.lock], 0 mov eax, ebx call SOCKET_notify_owner -;; Generate more output FIXME -;; mov eax, ebx -;; call TCP_output -;; -;; jmp .drop - jmp .ack_processed +; Generate more output + call TCP_output + + jmp .drop_not_locked ;------------------------------------------------- ; maybe we are the receiver in the uni-xfer then.. @@ -387,16 +404,15 @@ TCP_input: DEBUGF 1,"header prediction: we are receiver\nreceiving %u bytes of data\n", ecx - pusha + add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Update sequence number with number of bytes we have copied + add esi, edx lea eax, [ebx + STREAM_SOCKET.rcv] call SOCKET_ring_write ; Add the data to the socket buffer mov eax, ebx call SOCKET_notify_owner - popa - add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Update sequence number with number of bytes we have copied or [ebx + TCP_SOCKET.t_flags], TF_DELACK ; Set delayed ack flag jmp .drop @@ -415,7 +431,7 @@ TCP_input: ; Calculate receive window size -;;;; +;;;; TODO: 444 cmp [ebx + TCP_SOCKET.t_state], TCB_LISTEN je .LISTEN @@ -540,7 +556,7 @@ align 4 TCP_rcvseqinit ebx - mov [ebx + TCP_SOCKET.t_flags], TF_ACKNOW + or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW mov eax, [ebx + TCP_SOCKET.SND_UNA] cmp eax, [ebx + TCP_SOCKET.ISS] @@ -608,7 +624,7 @@ align 4 ; First, check if timestamp is present -;;;; TODO +;;;; TODO 602 ; Then, check if at least some bytes of data are within window @@ -628,10 +644,12 @@ align 4 mov eax, [ebx + TCP_SOCKET.RCV_NXT] sub eax, [edx + TCP_segment.SequenceNumber] - jz .no_duplicate + jle .no_duplicate + + DEBUGF 1,"Uh oh.. %x bytes of duplicate data!\n", eax test [edx + TCP_segment.Flags], TH_SYN - jz .no_drop + jz .no_dup_syn ; remove duplicate syn @@ -643,13 +661,13 @@ align 4 dec [edx + TCP_segment.UrgentPointer] - jmp .no_drop + jmp .no_dup_syn @@: and [edx + TCP_segment.Flags], not (TH_URG) dec eax jz .no_duplicate - .no_drop: + .no_dup_syn: DEBUGF 1,"Going to drop %u out of %u bytes\n", eax, ecx @@ -828,14 +846,15 @@ align 4 jmp .drop + + + + + + .rst_skip: - - - - - ;-------------------------------------- ; handle SYN-full and ACK-less segments @@ -857,7 +876,6 @@ align 4 - ;--------------- ; ACK processing @@ -876,39 +894,125 @@ align 4 cmp eax, [ebx + TCP_SOCKET.SND_UNA] jg .not_dup_ack - DEBUGF 1,"Duplicate ACK\n" - test ecx, ecx - jnz .ack_processed + jnz .reset_dupacks mov eax, dword [edx + TCP_segment.Window] cmp eax, [ebx + TCP_SOCKET.SND_WND] - jne .ack_processed + jne .reset_dupacks -; Process the duplicate ACK + DEBUGF 1,"Processing a duplicate ACK..\n" - ;;;;; 833 - 878 + cmp [ebx + TCP_SOCKET.timer_retransmission], 10000 ;;;; + jg @f + + mov eax, [edx + TCP_segment.AckNumber] + cmp eax, [ebx + TCP_SOCKET.SND_UNA] + je .dup_ack + + @@: + mov [ebx + TCP_SOCKET.t_dupacks], 0 + jmp .not_dup_ack + + .dup_ack: + inc [ebx + TCP_SOCKET.t_dupacks] + cmp [ebx + TCP_SOCKET.t_dupacks], TCP_re_xmit_thresh + jne .no_re_xmit + + push [ebx + TCP_SOCKET.SND_NXT] ; >>>> + + mov eax, [ebx + TCP_SOCKET.SND_WND] + cmp eax, [ebx + TCP_SOCKET.SND_CWND] + cmovg eax, [ebx + TCP_SOCKET.SND_CWND] + shr eax, 1 + push edx + xor edx, edx + div [ebx + TCP_SOCKET.t_maxseg] + cmp eax, 2 + jge @f + mov ax, 2 + @@: + mul [ebx + TCP_SOCKET.t_maxseg] + pop edx + mov [ebx + TCP_SOCKET.SND_SSTHRESH], eax + + mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; turn off retransmission timer + mov [ebx + TCP_SOCKET.t_rtt], 0 + mov eax, [edx + TCP_segment.AckNumber] + mov [ebx + TCP_SOCKET.SND_NXT], eax + mov eax, [ebx + TCP_SOCKET.t_maxseg] + mov [ebx + TCP_SOCKET.SND_CWND], eax + + mov eax, ebx + call TCP_output ; retransmit missing segment + + push edx + xor edx, edx + mov eax, [ebx + TCP_SOCKET.t_maxseg] + mul [ebx + TCP_SOCKET.t_dupacks] + pop edx + add eax, [ebx + TCP_SOCKET.SND_SSTHRESH] + mov [ebx + TCP_SOCKET.SND_CWND], eax + + pop eax ; <<<< + cmp eax, [ebx + TCP_SOCKET.SND_NXT] + jl @f + mov [ebx + TCP_SOCKET.SND_NXT], eax + @@: -;;; call TCP_output jmp .drop + + .no_re_xmit: + jle .not_dup_ack + + DEBUGF 1,"Increasing congestion window\n" + + mov eax, [ebx + TCP_SOCKET.t_maxseg] + add [ebx + TCP_SOCKET.SND_CWND], eax + + mov eax, ebx + call TCP_output + + jmp .drop + + + + + + .not_dup_ack: - DEBUGF 1,"new ACK\n" - - - - - - - ;------------------------------------------------- ; If the congestion window was inflated to account ; for the other side's cached packets, retract it - ;;;; 888 - 902 + mov eax, [ebx + TCP_SOCKET.SND_SSTHRESH] + cmp eax, [ebx + TCP_SOCKET.SND_CWND] + jg @f + cmp [ebx + TCP_SOCKET.t_dupacks], TCP_re_xmit_thresh + jle @f + mov [ebx + TCP_SOCKET.SND_CWND], eax + @@: + + mov [ebx + TCP_SOCKET.t_dupacks], 0 + + mov eax, [edx + TCP_segment.AckNumber] + cmp eax, [ebx + TCP_SOCKET.SND_MAX] + jle @f + + ;;; TODO: update stats + jmp .drop_after_ack + + @@: + + mov edi, [edx + TCP_segment.AckNumber] + sub edi, [ebx + TCP_SOCKET.SND_UNA] ; now we got the number of acked bytes in esi + + ;;; TODO: update stats + DEBUGF 1,"We have an acceptable ACK of %x bytes\n", esi @@ -918,7 +1022,7 @@ align 4 ;------------------------------------------ ; RTT measurements and retransmission timer - ;;;;; 903 - 926 + ;;;;; 912 - 926 mov [ebx + TCP_SOCKET.timer_retransmission], 0 @@ -937,8 +1041,32 @@ align 4 ;------------------------------------------- ; Open congestion window in response to ACKs - ;;;; + mov esi, [ebx + TCP_SOCKET.SND_CWND] + mov eax, [ebx + TCP_SOCKET.t_maxseg] + cmp esi, [ebx + TCP_SOCKET.SND_SSTHRESH] + jle @f + push edx + push eax + mul eax + div esi + pop edx + shr edx, 3 + add eax, edx + pop edx + @@: + + add esi, eax + + push ecx + mov cl, [ebx + TCP_SOCKET.SND_SCALE] + mov eax, TCP_max_win + shl eax, cl + pop ecx + + cmp esi, eax + cmovg esi, eax + mov [ebx + TCP_SOCKET.SND_CWND], esi @@ -949,13 +1077,13 @@ align 4 ;------------------------------------------ ; Remove acknowledged data from send buffer - pusha - mov ecx, [edx + TCP_segment.AckNumber] - sub ecx, [ebx + TCP_SOCKET.SND_UNA] ; ecx now holds number of bytes acked - + push ecx edx ebx + mov ecx, edi lea eax, [ebx + STREAM_SOCKET.snd] call SOCKET_ring_free - popa + pop ebx + sub [ebx + TCP_SOCKET.SND_WND], ecx + pop edx ecx ; Wake up process waiting on send buffer @@ -977,6 +1105,7 @@ align 4 + ; General ACK handling complete ; Now do the state-specific ones @@ -1016,8 +1145,9 @@ align 4 + .reset_dupacks: ; We got a new ACK, reset duplicate ACK counter -align 4 + mov [ebx + TCP_SOCKET.t_dupacks], 0 .ack_processed: ; (step 6) diff --git a/kernel/branches/net/network/tcp_output.inc b/kernel/branches/net/network/tcp_output.inc index d7804f8616..60fe3bad7c 100644 --- a/kernel/branches/net/network/tcp_output.inc +++ b/kernel/branches/net/network/tcp_output.inc @@ -1,3 +1,21 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; Part of the tcp/ip network stack for KolibriOS ;; +;; ;; +;; Written by hidnplayr@kolibrios.org ;; +;; ;; +;; Based on the code of 4.4BSD ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + ;----------------------------------------------------------------- ; ; TCP_output diff --git a/kernel/branches/net/network/tcp_subr.inc b/kernel/branches/net/network/tcp_subr.inc index e350889400..80aefb891b 100644 --- a/kernel/branches/net/network/tcp_subr.inc +++ b/kernel/branches/net/network/tcp_subr.inc @@ -1,5 +1,20 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; Part of the tcp/ip network stack for KolibriOS ;; +;; ;; +;; Written by hidnplayr@kolibrios.org ;; +;; ;; +;; Based on the code of 4.4BSD ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - +$Revision$ macro TCP_checksum IP1, IP2 { diff --git a/kernel/branches/net/network/tcp_timer.inc b/kernel/branches/net/network/tcp_timer.inc index 8ce9c2ef99..acd1c90e8e 100644 --- a/kernel/branches/net/network/tcp_timer.inc +++ b/kernel/branches/net/network/tcp_timer.inc @@ -1,3 +1,20 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; Part of the tcp/ip network stack for KolibriOS ;; +;; ;; +;; Written by hidnplayr@kolibrios.org ;; +;; ;; +;; Based on the code of 4.4BSD ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ ;---------------------- ; 160 ms timer