Tools/NetTest - TCP stack testing, going well
authorJohn Hodge <[email protected]>
Sun, 16 Mar 2014 09:09:21 +0000 (17:09 +0800)
committerJohn Hodge <[email protected]>
Sun, 16 Mar 2014 09:09:21 +0000 (17:09 +0800)
18 files changed:
Tools/NetTest/Makefile
Tools/NetTest/cmdline_backend.c [new file with mode: 0644]
Tools/NetTest/include/cmdline.h [new file with mode: 0644]
Tools/NetTest/include/nettest.h
Tools/NetTest/include/tcpserver.h [new file with mode: 0644]
Tools/NetTest/mode_cmdline.c
Tools/NetTest/tcpserver.c
Tools/NetTest_Runner/include/stack.h
Tools/NetTest_Runner/include/tcp.h
Tools/NetTest_Runner/include/test.h
Tools/NetTest_Runner/ip.c
Tools/NetTest_Runner/link.c
Tools/NetTest_Runner/stack.c
Tools/NetTest_Runner/tcp.c
Tools/NetTest_Runner/test_tcp.c
Tools/nativelib/logging.c
Tools/nativelib/threads.c
Tools/nativelib/threads_int.c

index c7118d2..f76c8b4 100644 (file)
@@ -18,9 +18,9 @@ K_OBJ += vfs/acls.o vfs/io.o vfs/fs/devfs.o
 # Modules
 MODULES := IPStack
 # Local kernel soruces (same as above, but located in same directory as Makefile)
-L_OBJ = vfs_shim.o nic.o tcpclient.o tcpserver.o helpers.o mode_cmdline.o
+L_OBJ = vfs_shim.o nic.o tcpclient.o tcpserver.o helpers.o cmdline_backend.o
 # Native Sources (compiled as usual)
-N_OBJ = main.o tap.o
+N_OBJ = main.o tap.o mode_cmdline.o
 
 # Compilation Options
 CFLAGS := -Wall -std=gnu99 -g -Werror -O0 -pthread
diff --git a/Tools/NetTest/cmdline_backend.c b/Tools/NetTest/cmdline_backend.c
new file mode 100644 (file)
index 0000000..f95895a
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ */
+#define DEBUG  1
+#include "cmdline.h"
+#include "tcpserver.h"
+#include <vfs_ext.h>
+#include <threads.h>
+#include <events.h>
+
+// === PROTOTYES ===
+void   Cmdline_Backend_Thread(void *unused);
+
+// === GLOBALS ===
+tThread        *gpCmdline_WorkerThread;
+tNetTest_TCPServer     *gpCmdline_TCPEchoServer;
+
+// === CODE ===
+void Cmdline_Backend_StartThread(void)
+{
+       ASSERT(!gpCmdline_WorkerThread);
+       gpCmdline_WorkerThread = Proc_SpawnWorker(Cmdline_Backend_Thread, NULL);
+}
+
+void Cmdline_Backend_Thread(void *unused)
+{
+       Threads_SetName("Cmdline Worker");
+       for( ;; )
+       {
+               fd_set  rfd, wfd, efd;
+                int    max = -1;
+               
+               FD_ZERO(&rfd);
+               
+               LOG("gpCmdline_TCPEchoServer = %p", gpCmdline_TCPEchoServer);
+               if(gpCmdline_TCPEchoServer)
+                       max = MAX(max, NetTest_TCPServer_FillSelect(gpCmdline_TCPEchoServer, &rfd));
+               
+               memcpy(&wfd, &rfd, sizeof(rfd));
+               memcpy(&efd, &rfd, sizeof(rfd));
+               
+               LOG("max = %i", max);
+               int rv = VFS_Select(max+1, &rfd, &wfd, &efd, NULL, THREAD_EVENT_USER1, true);
+               LOG("rv = %i", rv);
+               
+               if(gpCmdline_TCPEchoServer)
+                       NetTest_TCPServer_HandleSelect(gpCmdline_TCPEchoServer, &rfd, &wfd, &efd);
+       }
+}
+
+void Cmdline_Backend_StartEchoServer(int Port)
+{
+       if(gpCmdline_TCPEchoServer)
+       {
+               // Oops, two
+       }
+       else
+       {
+               gpCmdline_TCPEchoServer = NetTest_TCPServer_Create(Port);
+               Log_Debug("Cmdline", "Echo Server = %p", gpCmdline_TCPEchoServer);
+               Threads_PostEvent(gpCmdline_WorkerThread, THREAD_EVENT_USER1);
+       }
+}
diff --git a/Tools/NetTest/include/cmdline.h b/Tools/NetTest/include/cmdline.h
new file mode 100644 (file)
index 0000000..6c96e3f
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ */
+#ifndef _CMDLINE_H_
+#define _CMDLINE_H_
+
+extern void    Cmdline_Backend_StartThread(void);
+extern void    Cmdline_Backend_StartEchoServer(int Port);
+
+#endif
+
index 4705993..5edee29 100644 (file)
@@ -8,7 +8,9 @@
 #ifndef _NETTEST_H_
 #define _NETTEST_H_
 
-#include <stddef.h>
+#ifndef NULL
+# include <stddef.h>
+#endif
 
 extern int     NativeNic_AddDev(char *Desc);
 
@@ -25,6 +27,7 @@ extern void   NetTest_Suite_Netcat(const char *Addr, int Port);
 extern void    NetTest_Suite_Cmdline(void);
 
 extern int     Net_ParseAddress(const char *String, void *Addr);
+extern int     Net_OpenSocket(int AddrType, void *Addr, const char *Filename);
 extern int     Net_OpenSocket_TCPC(int AddrType, void *Addr, int Port);
 
 #endif
diff --git a/Tools/NetTest/include/tcpserver.h b/Tools/NetTest/include/tcpserver.h
new file mode 100644 (file)
index 0000000..9601f3f
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ */
+#ifndef _TCPSERVER_H_
+#define _TCPSERVER_H_
+
+#include <acess.h>
+#include <vfs_ext.h>
+
+typedef struct sNetTest_TCPServer      tNetTest_TCPServer;
+
+extern tNetTest_TCPServer      *NetTest_TCPServer_Create(int Port);
+extern void    NetTest_TCPServer_Close(tNetTest_TCPServer *Srv);
+extern int     NetTest_TCPServer_FillSelect(tNetTest_TCPServer *Srv, fd_set *fds);
+extern void    NetTest_TCPServer_HandleSelect(tNetTest_TCPServer *Srv, const fd_set *rfds, const fd_set *wfds, const fd_set *efds);
+
+#endif
+
index 5a17517..05a3933 100644 (file)
@@ -2,26 +2,40 @@
  */
 #include <nettest.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
+#include "cmdline.h"
 
 // === CODE ===
 void NetTest_Suite_Cmdline(void)
 {
        char line[BUFSIZ];
+       Cmdline_Backend_StartThread();
        while( fgets(line, sizeof(line)-1, stdin) )
        {
-               const char *cmd = strtok(line, " ");
+               const char *const sep = " \n\r";
+               const char *cmd = strtok(line, sep);
                if(!cmd)
                        continue;
                if( strcmp(cmd, "exit") == 0 ) {
                        return ;
                }
-               else if( strcmp(cmd, "request") == 0 ) {
-                       //const char *addr = strtok(NULL, " ");
+               else if( strcmp(cmd, "tcp_echo_server") == 0 ) {
+                       const char *port_str = strtok(NULL, sep);
+                       char *end;
+                       int port = strtol(port_str, &end, 0);
+                       if(*end != '\0') {
+                               fprintf(stderr, "ERROR: Port number '%s' not valid\n", port_str);
+                               continue ;
+                       }
                        
+                       Cmdline_Backend_StartEchoServer(port);
+                       // TODO: Allow stopping of the server?
                }
                else {
                        fprintf(stderr, "ERROR: Unknown command '%s'\n", cmd);
                }
        }
+       
+       // TODO: Tear down backend?
 }
index e69de29..d38b442 100644 (file)
@@ -0,0 +1,92 @@
+/*
+ * Acess2 Networking Test Suite (NetTest)
+ * - By John Hodge (thePowersGang)
+ *
+ * tcpserver.c
+ * - TCP Client tester
+ */
+#include <vfs.h>
+#include <vfs_ext.h>
+#include <nettest.h>
+#include "tcpserver.h"
+
+#define MAX_CLIENTS    4
+
+struct sNetTest_TCPServer
+{
+        int    ServerFD;
+        int    nClients;
+       struct sClient {
+                int    FD;
+       } Clients[MAX_CLIENTS];
+};
+
+// === CODE ===
+tNetTest_TCPServer *NetTest_TCPServer_Create(int Port)
+{
+       tNetTest_TCPServer *ret;
+       ret = calloc(sizeof(*ret), 1);
+       ret->ServerFD = VFS_Open("/Devices/ip/1/tcps", VFS_OPENFLAG_READ);
+       ASSERT(ret->ServerFD >= 0);
+       VFS_IOCtl(ret->ServerFD, 4, &Port);
+       return ret;
+}
+
+void NetTest_TCPServer_Close(tNetTest_TCPServer *Srv)
+{
+       VFS_Close(Srv->ServerFD);
+       for( int i = 0; i < Srv->nClients; i ++ )
+       {
+               struct sClient  *client = &Srv->Clients[i];
+               VFS_Close(client->FD);
+       }
+       free(Srv);
+}
+
+int NetTest_TCPServer_FillSelect(tNetTest_TCPServer *Srv, fd_set *fds)
+{
+       ASSERT(Srv->ServerFD >= 0);
+        int    max = -1;
+       
+       if( Srv->nClients == MAX_CLIENTS ) {
+               max = Srv->ServerFD;
+               FD_SET(Srv->ServerFD, fds);
+       }
+       for( int i = 0; i < Srv->nClients; i ++ )
+       {
+                int    fd = Srv->Clients[i].FD;
+               if( fd > max )  max = fd;
+               FD_SET(fd, fds);
+       }
+       return max;
+}
+
+void NetTest_TCPServer_HandleSelect(tNetTest_TCPServer *Srv, const fd_set *rfds, const fd_set *wfds, const fd_set *efds)
+{
+       if( FD_ISSET(Srv->ServerFD, rfds) )
+       {
+               // New connection!
+               ASSERT(Srv->nClients != MAX_CLIENTS);
+               struct sClient *client = &Srv->Clients[Srv->nClients++];
+               client->FD = VFS_OpenChild(Srv->ServerFD, "", VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE);
+       }
+
+       for( int i = 0; i < Srv->nClients; i ++ )
+       {
+               struct sClient  *client = &Srv->Clients[i];
+               if( FD_ISSET(client->FD, rfds) )
+               {
+                       // RX'd data on client
+               }
+               
+               if( FD_ISSET(client->FD, efds) )
+               {
+                       // Drop client
+                       VFS_Close(client->FD);
+                       memmove(client, client+1, (Srv->nClients-i-1) * sizeof(*client));
+                       Srv->nClients --;
+                       i --;   // counteract i++
+               }
+       }
+}
+
index 40c92d6..7ac2083 100644 (file)
@@ -15,7 +15,7 @@ extern void   Stack_AddArg(const char *Fmt, ...);
 extern int     Stack_Start(const char *Subcommand);
 extern void    Stack_Kill(void);
 
-extern int     Stack_SendCommand(const char *CommandString);
+extern int     Stack_SendCommand(const char *CommandString, ...);
 
 #endif
 
index a96d921..effc3ad 100644 (file)
 #define TCP_FIN        0x01
 #define TCP_SYN        0x02
 #define TCP_RST        0x04
+#define TCP_PSH        0x08
+#define TCP_ACK        0x10
+#define TCP_URG        0x20
 
 extern void    TCP_Send(int IF, int AF, const void *IP, short sport, short dport, uint32_t seq, uint32_t ack, uint8_t flags, uint16_t window, size_t data_len, const void *data);
-extern bool    TCP_Pkt_Check(size_t len, const void *data, size_t *ofs, int AF, const void *IP, short sport, short dport, uint8_t flags);
+
+
+// The following skip the next check of each field
+extern void    TCP_SkipCheck_Seq(bool Skip);
+
+extern bool    TCP_Pkt_Check(size_t len, const void *data, size_t *ofs, int AF, const void *IP, short sport, short dport, uint32_t seq, uint32_t ack, uint8_t flags);
+
+// - Get a field from a previously validated packet
+extern uint32_t        TCP_Pkt_GetSeq(size_t len, const void *data, int AF);
 
 #endif
 
index 7a32586..3559faf 100644 (file)
@@ -5,7 +5,7 @@
 
 #define TEST_SETNAME(name)     test_setname(name)
 #define TEST_ASSERT(cnd)       do{if(!(cnd)) {test_assertion_fail(__FILE__,__LINE__,"%s",#cnd);return false;}}while(0)
-#define TEST_ASSERT_REL(a,r,b) do{long long a_val=(a),b_val=(b);if(!(a_val r b_val)) {test_assertion_fail(__FILE__,__LINE__,"%s(0x%llx)%s%s(%llx)",#a,a_val,#r,#b,b_val);return false;}}while(0)
+#define TEST_ASSERT_REL(a,r,b) do{long long a_val=(a),b_val=(b);if(!(a_val r b_val)) {test_assertion_fail(__FILE__,__LINE__,"%s(0x%llx)%s%s(0x%llx)",#a,a_val,#r,#b,b_val);return false;}}while(0)
 #define TEST_WARN(msg...)      test_message(__FILE__,__LINE__,msg)
 
 extern void    test_setname(const char *name);
index bebcf73..628fdbe 100644 (file)
@@ -94,8 +94,19 @@ bool IP_Pkt_Check(size_t len, const void *data, size_t *ofs_out, int AF, const v
                tIPv4Hdr hdr;
                memcpy(&hdr, (const uint8_t*)data + ofs, sizeof(hdr));
                TEST_ASSERT_REL(hdr.VerLen >> 4, ==, 4);
+               TEST_ASSERT_REL(IP_Checksum(IP_CHECKSUM_START, sizeof(hdr), &hdr), ==, 0);
+               
+               TEST_ASSERT_REL(ntohs(hdr.TotalLength), <=, len - ofs);
+               TEST_ASSERT_REL(ntohs(hdr.FragmentInfo), ==, 0);
+               
+               TEST_ASSERT_REL(hdr.TTL, >, 1); // >1 because there's no intervening hops
+               TEST_ASSERT_REL(hdr.Protocol, ==, proto);
+
+               TEST_ASSERT( memcmp(hdr.SrcAddr, Src, 4) == 0 );
+               TEST_ASSERT( memcmp(hdr.DstAddr, Dst, 4) == 0 );
        
-               return false;
+               *ofs_out = ofs + (hdr.VerLen & 0xF) * 4;
+               return true;
        }
        else {
                TEST_WARN("Invalid AF(%i) in IP_Pkt_Check", AF);
index 53dfde5..96fddaf 100644 (file)
@@ -38,8 +38,8 @@ bool Link_Pkt_Check(size_t len, const void *data, size_t *ofs_out,
        const uint8_t   *data8 = data;
        TEST_ASSERT_REL(len, >=, 6+6+2);
 
-       if(Src) TEST_ASSERT( memcmp(data8+0, Src, 6) == 0 );
-       if(Dst) TEST_ASSERT( memcmp(data8+6, Dst, 6) == 0 );
+       if(Dst) TEST_ASSERT( memcmp(data8+0, Dst, 6) == 0 );
+       if(Src) TEST_ASSERT( memcmp(data8+6, Src, 6) == 0 );
        
        TEST_ASSERT_REL( ntohs(*(uint16_t*)(data8+12)), ==, Proto );
 
index c359d84..65f8352 100644 (file)
@@ -123,9 +123,18 @@ void Stack_Kill(void)
        }
 }
 
-int Stack_SendCommand(const char *CommandString)
+int Stack_SendCommand(const char *Fmt, ...)
 {
-       write(giStack_InFD, CommandString, strlen(CommandString));
+       va_list args;
+       va_start(args, Fmt);
+       size_t len = vsnprintf(NULL, 0, Fmt, args);
+       va_end(args);
+       char command[len+1];
+       va_start(args, Fmt);
+       vsnprintf(command, len+1, Fmt, args);
+       va_end(args);
+       
+       write(giStack_InFD, command, len);
        write(giStack_InFD, "\n", 1);
        return 0;
 }
index 56c5571..0bf0a67 100644 (file)
@@ -19,6 +19,23 @@ typedef struct {
 } __attribute__((packed)) tTCPHeader;
 
 // === CODE ===
+uint16_t TCP_int_GetPseudoHeader(int AF, const void *SrcAddr, const void *DstAddr, uint8_t pctl, size_t Len)
+{
+       if( AF == 4 ) {
+               uint8_t phdr[12];
+               memcpy(phdr+0, SrcAddr, 4);
+               memcpy(phdr+4, DstAddr, 4);
+               phdr[8] = 0;
+               phdr[9] = pctl;
+               *(uint16_t*)(phdr+10) = htons(Len);
+               return IP_Checksum(IP_CHECKSUM_START, 12, phdr);
+       }
+       else {
+               TEST_WARN("TCP unknown AF %i", AF);
+               return 0;
+       }
+}
+
 void TCP_Send(int IF, int AF, const void *IP, short sport, short dport,
        uint32_t seq, uint32_t ack, uint8_t flags, uint16_t window,
        size_t data_len, const void *data
@@ -29,13 +46,14 @@ void TCP_Send(int IF, int AF, const void *IP, short sport, short dport,
        hdr.DPort = htons(dport);
        hdr.Seq = htonl(seq);
        hdr.Ack = htonl(ack);
-       hdr.DataOfs = sizeof(hdr)/4;
+       hdr.DataOfs = (sizeof(hdr)/4) << 4;
        hdr.Flags = flags;
        hdr.Window = htons(window);
        hdr.Checksum = htons(0);
        hdr.UrgPtr = htons(0);
 
-       uint16_t        checksum = IP_CHECKSUM_START;
+       uint16_t        checksum;
+       checksum = TCP_int_GetPseudoHeader(AF, BLOB(HOST_IP), IP, IPPROTO_TCP, sizeof(hdr)+data_len);
        checksum = IP_Checksum(checksum, sizeof(hdr), &hdr);
        checksum = IP_Checksum(checksum, data_len, data);
        hdr.Checksum = htons( checksum );
@@ -45,30 +63,56 @@ void TCP_Send(int IF, int AF, const void *IP, short sport, short dport,
        IP_Send(IF, AF, BLOB(HOST_IP), IP, IPPROTO_TCP, 2, buflens, bufs);
 }
 
-bool TCP_Pkt_Check(size_t len, const void *data, size_t *out_ofs, int AF, const void *IP, short sport, short dport,
-       uint8_t flags)
+struct {
+       bool    Seq;
+       bool    Ack;
+       bool    SPort;
+}      gTCP_Skips;
+
+void TCP_SkipCheck_Seq(bool Skip) {
+       gTCP_Skips.Seq = Skip;
+}
+
+bool TCP_Pkt_Check(size_t len, const void *data, size_t *out_ofs,
+       int AF, const void *IP, short sport, short dport,
+       uint32_t seq, uint32_t ack, uint8_t flags)
 {
        size_t  ofs;
        if( !IP_Pkt_Check(len, data, &ofs, AF, IP, BLOB(HOST_IP), IPPROTO_TCP) )
                return false;
+       // TODO: IP has its own length field, use that?
        
        tTCPHeader      hdr;
        TEST_ASSERT_REL(len - ofs, >=, sizeof(hdr));    
        memcpy(&hdr, (char*)data + ofs, sizeof(hdr));
        
-       TEST_ASSERT_REL( ntohs(hdr.SPort), ==, sport );
+       TEST_ASSERT_REL( hdr.DataOfs >> 4, >=, sizeof(hdr)/4 );
+       if( !gTCP_Skips.SPort ) TEST_ASSERT_REL( ntohs(hdr.SPort), ==, sport );
        TEST_ASSERT_REL( ntohs(hdr.DPort), ==, dport );
-       // TODO: Checks on Seq/Ack
+       if( !gTCP_Skips.Seq )   TEST_ASSERT_REL( ntohl(hdr.Seq), ==, seq );
+       if( !gTCP_Skips.Ack )   TEST_ASSERT_REL( ntohl(hdr.Ack), ==, ack );
        TEST_ASSERT_REL( hdr.Flags, ==, flags);
 
        uint16_t        real_cksum = htons(hdr.Checksum);
        hdr.Checksum = 0;
-       uint16_t        calc_cksum = IP_CHECKSUM_START;
+       uint16_t        calc_cksum;
+       calc_cksum = TCP_int_GetPseudoHeader(AF, IP, BLOB(HOST_IP), IPPROTO_TCP, len-ofs);
        calc_cksum = IP_Checksum(calc_cksum, sizeof(hdr), &hdr);
        calc_cksum = IP_Checksum(calc_cksum, len - ofs - sizeof(hdr), (char*)data+ofs+sizeof(hdr));
        TEST_ASSERT_REL( real_cksum, ==, calc_cksum );
-       
+
+       memset(&gTCP_Skips, 0, sizeof(gTCP_Skips));
+
        *out_ofs = ofs + sizeof(hdr);
        return true;
 }
 
+uint32_t TCP_Pkt_GetSeq(size_t len, const void *data, int AF) {
+       size_t  ofs;
+       IP_Pkt_Check(len, data, &ofs, AF, NULL, NULL, IPPROTO_TCP);
+       
+       tTCPHeader      hdr;
+       memcpy(&hdr, (char*)data + ofs, sizeof(hdr));
+       return ntohl(hdr.Seq);
+}
+
index a19c85b..32f79c0 100644 (file)
@@ -7,20 +7,90 @@
 #include "arp.h"
 #include "tcp.h"
 
+#define TEST_ASSERT_rx()       TEST_ASSERT( rxlen = Net_Receive(0, sizeof(rxbuf), rxbuf, ERX_TIMEOUT) )
+#define TEST_ASSERT_no_rx()    TEST_ASSERT( Net_Receive(0, sizeof(rxbuf), rxbuf, NRX_TIMEOUT) == 0 )
+
 bool Test_TCP_Basic(void)
 {
        TEST_SETNAME(__func__);
        size_t  rxlen, ofs;
        char rxbuf[MTU];
+       const int       ERX_TIMEOUT = 1000;     // Expect RX timeout (timeout=failure)
+       const int       NRX_TIMEOUT = 1000;     // Not expect RX timeout (timeout=success)
+       
+       const char testblob[] = "HelloWorld, this is some random testing data for TCP\xFF\x00\x66\x12\x12";
+       const size_t    testblob_len = sizeof(testblob);
        
-       // 1. Test connection to closed port
+       // 1. Test packets to closed port
+       // > RFC793 Pg.65
+       const uint16_t  our_window = 0x1000;
        uint32_t        seq_tx = 0x1000;
-       uint32_t        seq_exp = 0;
-       TCP_Send(0, 4, BLOB(TEST_IP), 1234, 80, seq_tx, seq_exp, TCP_SYN, 0x1000, 0, NULL);
+       uint32_t        seq_exp = 0x33456;
+       
+       // 1.1. Send SYN packet
+       TCP_Send(0, 4, BLOB(TEST_IP), 1234, 80, seq_tx, seq_exp, TCP_SYN, 0x1000, testblob_len, testblob);
+       // Expect a TCP_RST|TCP_ACK with SEQ=0,ACK=SEQ+LEN
+       TEST_ASSERT( rxlen = Net_Receive(0, sizeof(rxbuf), rxbuf, ERX_TIMEOUT) );
+       TEST_ASSERT( TCP_Pkt_Check(rxlen, rxbuf, &ofs, 4, BLOB(TEST_IP), 80, 1234,
+               0, seq_tx+testblob_len, TCP_RST|TCP_ACK) );
+       TEST_ASSERT_REL(ofs, ==, rxlen);
        
-       TEST_ASSERT( rxlen = Net_Receive(0, sizeof(rxbuf), rxbuf, 1000) );
-       TEST_ASSERT( TCP_Pkt_Check(rxlen, rxbuf, &ofs, 4, BLOB(TEST_IP), 80, 1234, TCP_RST) );
+       // 1.2. Send a SYN,ACK packet
+       TCP_Send(0, 4, BLOB(TEST_IP), 1234, 80, seq_tx, seq_exp, TCP_SYN|TCP_ACK, 0x1000, 0, NULL);
+       // Expect a TCP_RST with SEQ=ACK
+       TEST_ASSERT( rxlen = Net_Receive(0, sizeof(rxbuf), rxbuf, ERX_TIMEOUT) );
+       TEST_ASSERT( TCP_Pkt_Check(rxlen, rxbuf, &ofs, 4, BLOB(TEST_IP), 80, 1234, seq_exp, seq_tx+0, TCP_RST) );
        TEST_ASSERT_REL(ofs, ==, rxlen);
        
+       // 1.3. Send a RST packet
+       TCP_Send(0, 4, BLOB(TEST_IP), 1234, 80, seq_tx, seq_exp, TCP_RST, 0x1000, 0, NULL);
+       // Expect nothing
+       TEST_ASSERT( Net_Receive(0, sizeof(rxbuf), rxbuf, NRX_TIMEOUT) == 0 );
+       
+       // 1.3. Send a RST,ACK packet
+       TCP_Send(0, 4, BLOB(TEST_IP), 1234, 80, seq_tx, seq_exp, TCP_RST|TCP_ACK, 0x1000, 0, NULL);
+       // Expect nothing
+       TEST_ASSERT_no_rx();
+
+       
+       // 2. Establishing connection with a server
+       const int server_port = 1024;
+       const int local_port = 11234;
+       Stack_SendCommand("tcp_echo_server %i", server_port);
+
+       // >>> STATE: LISTEN
+
+       // 2.1. Send RST
+       TCP_Send(0, 4, BLOB(TEST_IP), local_port, server_port, seq_tx, seq_exp, TCP_RST, our_window, 0, NULL);
+       // - Expect nothing
+       TEST_ASSERT_no_rx();
+       // 2.2. Send ACK
+       TCP_Send(0, 4, BLOB(TEST_IP), local_port, server_port, seq_tx, seq_exp, TCP_ACK, our_window, 0, NULL);
+       // - Expect RST
+       TEST_ASSERT_rx();
+       TEST_ASSERT( TCP_Pkt_Check(rxlen, rxbuf, &ofs, 4, BLOB(TEST_IP), 80, 1234, seq_exp, seq_tx+0, TCP_RST) );
+
+       // 2.3. Begin hanshake (SYN)
+       // TODO: "If the SYN bit is set, check the security."
+       TCP_Send(0, 4, BLOB(TEST_IP), local_port, server_port, seq_tx, 0, TCP_SYN, our_window, 0, NULL);
+       // - Expect SYN,ACK with ACK == SEQ+1
+       TEST_ASSERT_rx();
+       TCP_SkipCheck_Seq(true);
+       TEST_ASSERT( TCP_Pkt_Check(rxlen, rxbuf, &ofs, 4, BLOB(TEST_IP), server_port, local_port,
+               0, seq_tx+1, TCP_SYN|TCP_ACK) );
+       seq_exp = TCP_Pkt_GetSeq(rxlen, rxbuf, 4);
+
+       // >>> STATE: SYN-RECEIVED
+       // TODO: Test other transitions from SYN-RECEIVED
+               
+       // 2.4. Complete handshake, TCP ACK
+       TCP_Send(0,4,BLOB(TEST_IP), local_port, server_port, seq_tx, seq_exp, TCP_ACK, our_window, 0, NULL);
+       // - Expect nothing
+       TEST_ASSERT( Net_Receive(0, sizeof(rxbuf), rxbuf, NRX_TIMEOUT) == 0 );
+
+       // >>> STATE: ESTABLISHED
+       
+       // 2.5. Send data
+       
        return true;
 }
index e9925ac..292b8a5 100644 (file)
@@ -110,9 +110,9 @@ void Debug_HexDump(const char *Prefix, const void *Data, size_t Length)
 
 void Debug_TraceEnter(const char *Function, const char *Format, ...)
 {
-       const char *Ident = "Trace";
        LOG_LOCK_ACQUIRE();
-       LOGHDR("37","T");
+       //const char *Ident = "Trace";
+       //LOGHDR("37","T");
        for( int i = 0; i < giDebug_TraceLevel; i ++ )
                fprintf(stderr, " ");
        fprintf(stderr, "%s: (", Function);
@@ -171,9 +171,9 @@ void Debug_TraceEnter(const char *Function, const char *Format, ...)
 
 void Debug_TraceLog(const char *Function, const char *Format, ...)
 {
-       const char *Ident = "Trace";
        LOG_LOCK_ACQUIRE();
-       LOGHDR("37","T");
+       //const char *Ident = "Trace";
+       //LOGHDR("37","T");
        
        for( int i = 0; i < giDebug_TraceLevel; i ++ )
                fprintf(stderr, " ");
@@ -195,9 +195,9 @@ void Debug_TraceLeave(const char *Function, char Type, ...)
                Log_Error("Debug", "Function %s called LEAVE without ENTER", Function);
        }
        
-       const char *Ident = "Trace";
        LOG_LOCK_ACQUIRE();
-       LOGHDR("37","T");
+       //const char *Ident = "Trace";
+       //LOGHDR("37","T");
        
        va_list args;
        va_start(args, Type);
index cc508fb..93db6c3 100644 (file)
@@ -5,6 +5,7 @@
  * threads.c
  * - Threads handling
  */
+#define DEBUG  1
 #include <acess.h>
 #include <threads.h>
 #include <threads_int.h>
@@ -84,6 +85,7 @@ void Threads_AddActive(tThread *Thread)
 {
        Thread->Status = THREAD_STAT_ACTIVE;
        // Increment state-change semaphore
+       LOG("Waking %p(%i %s)", Thread, Thread->TID, Thread->ThreadName);
        Threads_int_SemSignal(Thread->WaitSemaphore);
 }
 
@@ -149,6 +151,7 @@ void Threads_int_WaitForStatusEnd(enum eThreadStatus Status)
                        Log_Warning("Threads", "Thread %p(%i %s) rescheduled while in %s state",
                                us, us->TID, us->ThreadName, casTHREAD_STAT[Status]);
        }
+       LOG("%p(%i %s) Awake", us, us->TID, us->ThreadName);
 }
 
 int Threads_int_Sleep(enum eThreadStatus Status, void *Ptr, int Num, tThread **ListHead, tThread **ListTail, tShortSpinlock *Lock)
index 8ab9b34..87c60b1 100644 (file)
@@ -8,6 +8,7 @@
  * POSIX Mutex/Semaphore management
  * Wait state
  */
+#define DEBUG  1
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdint.h>
@@ -109,9 +110,12 @@ void Threads_int_SemWaitAll(tThreadIntSem *Sem)
        if( Threads_int_ThreadingEnabled() )
        {
                // TODO: Handle multiples
+               LOG("Waiting on %p", Sem);
                sem_wait( (void*)Sem );
-               while( sem_trywait((void*)Sem) )
+               LOG("Wait 1 done, cleaning up");
+               while( sem_trywait((void*)Sem) == 0 )
                        ;
+               LOG("Wait over");
        }
        else
        {

UCC git Repository :: git.ucc.asn.au