2 * Acess2 Network Stack Tester
3 * - By John Hodge (thePowersGang)
6 * - Tests for the behavior of the "Transmission Control Protocol"
16 #define TEST_ASSERT_rx() TEST_ASSERT( rxlen = Net_Receive(0, sizeof(rxbuf), rxbuf, ERX_TIMEOUT) )
17 #define TEST_ASSERT_no_rx() TEST_ASSERT( Net_Receive(0, sizeof(rxbuf), rxbuf, NRX_TIMEOUT) == 0 )
19 bool Test_TCP_Basic(void)
21 TEST_SETNAME(__func__);
22 size_t rxlen, ofs, len;
24 const int ERX_TIMEOUT = 1000; // Expect RX timeout (timeout=failure)
25 const int NRX_TIMEOUT = 250; // Not expect RX timeout (timeout=success)
26 const int RETX_TIMEOUT = 1000; // OS PARAM - Retransmit timeout
27 const int LOST_TIMEOUT = 1000; // OS PARAM - Time before sending an ACK
28 const int DACK_TIMEOUT = 500; // OS PARAM - Timeout for delayed ACKs
29 const size_t DACK_BYTES = 4096; // OS PARAM - Threshold for delayed ACKs
33 .RAddr = BLOB(TEST_IP),
34 .LAddr = BLOB(HOST_IP),
42 const char testblob[] = "HelloWorld, this is some random testing data for TCP\xFF\x00\x66\x12\x12";
43 const size_t testblob_len = sizeof(testblob);
45 // 1. Test packets to closed port
48 // 1.1. Send SYN packet
49 TCP_SendC(&testconn, TCP_SYN, testblob_len, testblob);
51 testconn.LSeq += testblob_len;
52 // Expect RST,ACK with SEQ=0
54 TEST_ASSERT( TCP_Pkt_CheckC(rxlen, rxbuf, &ofs, &len, &testconn, TCP_RST|TCP_ACK) );
55 TEST_ASSERT_REL(ofs, ==, rxlen);
57 // 1.2. Send a SYN,ACK packet
58 testconn.RSeq = 12345;
59 TCP_SendC(&testconn, TCP_SYN|TCP_ACK, 0, NULL);
60 // Expect a TCP_RST with SEQ=ACK
62 TEST_ASSERT( TCP_Pkt_CheckC(rxlen, rxbuf, &ofs, &len, &testconn, TCP_RST) );
63 TEST_ASSERT_REL(ofs, ==, rxlen);
66 // 1.3. Send a RST packet
67 TCP_SendC(&testconn, TCP_RST, 0, NULL);
72 // 1.3. Send a RST,ACK packet
73 TCP_SendC(&testconn, TCP_RST|TCP_ACK, 0, NULL);
79 // 2. Establishing connection with a server
81 testconn.LPort = 11239;
82 Stack_SendCommand("tcp_echo_server %i", testconn.RPort);
87 TCP_SendC(&testconn, TCP_RST, 0, NULL);
91 TCP_SendC(&testconn, TCP_ACK, 0, NULL);
94 TEST_ASSERT( TCP_Pkt_CheckC(rxlen, rxbuf, &ofs, &len, &testconn, TCP_RST) );
95 TEST_ASSERT_REL(ofs, ==, rxlen);
97 // 2.3. Begin hanshake (SYN)
98 // TODO: Test "If the SYN bit is set, check the security."
99 TCP_SendC(&testconn, TCP_SYN, 0, NULL);
101 // - Expect SYN,ACK with ACK == SEQ+1
103 TCP_SkipCheck_Seq(true);
104 TEST_ASSERT( TCP_Pkt_CheckC(rxlen, rxbuf, &ofs, &len, &testconn, TCP_SYN|TCP_ACK) );
105 testconn.RSeq = TCP_Pkt_GetSeq(rxlen, rxbuf, testconn.AF) + 1;
107 // >>> STATE: SYN-RECEIVED
108 // TODO: Test other transitions from SYN-RECEIVED
110 // 2.4. Complete handshake, TCP ACK
111 TCP_SendC(&testconn, TCP_ACK, 0, NULL);
115 // >>> STATE: ESTABLISHED
118 TCP_SendC(&testconn, TCP_ACK|TCP_PSH, testblob_len, testblob);
119 testconn.LSeq += testblob_len;
121 // Expect echoed reponse with ACK
123 TEST_ASSERT( TCP_Pkt_CheckC(rxlen, rxbuf, &ofs, &len, &testconn, TCP_ACK|TCP_PSH) );
124 TEST_ASSERT_REL( len, ==, testblob_len );
125 TEST_ASSERT( memcmp(rxbuf + ofs, testblob, testblob_len) == 0 );
126 testconn.RSeq += testblob_len;
128 // Send something short
129 const char testblob2[] = "test blob two.";
130 const size_t testblob2_len = sizeof(testblob2);
131 TCP_SendC(&testconn, TCP_ACK|TCP_PSH, testblob2_len, testblob2);
132 testconn.LSeq += testblob2_len;
133 // Expect response with data and ACK
135 TEST_ASSERT( TCP_Pkt_CheckC(rxlen, rxbuf, &ofs, &len, &testconn, TCP_ACK|TCP_PSH) );
136 TEST_ASSERT_REL( len, ==, testblob2_len );
137 TEST_ASSERT( memcmp(rxbuf + ofs, testblob2, testblob2_len) == 0 );
139 // Wait for just under retransmit time, expecting nothing
141 TEST_ASSERT( 0 == Net_Receive(0, sizeof(rxbuf), rxbuf, RETX_TIMEOUT-100) );
142 // Now expect the previous message
144 TEST_ASSERT( TCP_Pkt_CheckC(rxlen, rxbuf, &ofs, &len, &testconn, TCP_ACK|TCP_PSH) );
145 TEST_ASSERT_REL( len, ==, testblob2_len );
146 TEST_ASSERT( memcmp(rxbuf + ofs, testblob2, testblob2_len) == 0 );
148 TEST_WARN("Not testing retransmit timer");
150 testconn.RSeq += testblob2_len;
152 // Send explicit acknowledgement
153 TCP_SendC(&testconn, TCP_ACK, 0, NULL);
156 // TODO: Test delayed ACKs (Timeout and data)
157 // > Requires inhibiting the server's echo response?
159 // === Test out-of-order packets ===
160 testconn.LSeq += testblob2_len; // raise sequence number
161 TCP_SendC(&testconn, TCP_ACK|TCP_PSH, testblob_len, testblob);
162 // - previous data has not been sent, expect no response for ()
163 // TODO: Should this ACK be delayed?
164 //TEST_ASSERT_no_rx();
165 // - Expect an ACK of the highest received packet
166 testconn.LSeq -= testblob2_len;
168 TEST_ASSERT( TCP_Pkt_CheckC(rxlen, rxbuf, &ofs, &len, &testconn, TCP_ACK) );
169 TEST_ASSERT_REL( len, ==, 0 );
170 // - Send missing data
171 TCP_SendC(&testconn, TCP_ACK, testblob2_len, testblob2);
172 testconn.LSeq += testblob_len+testblob2_len; // raise sequence number
173 // - Expect echo response with all sent data
175 TEST_ASSERT( TCP_Pkt_CheckC(rxlen, rxbuf, &ofs, &len, &testconn, TCP_ACK|TCP_PSH) );
176 TEST_ASSERT_REL( len, ==, testblob_len+testblob2_len );
177 TEST_ASSERT( memcmp(rxbuf + ofs, testblob2, testblob2_len) == 0 );
178 TEST_ASSERT( memcmp(rxbuf + ofs+testblob2_len, testblob, testblob_len) == 0 );
179 testconn.RSeq += len;
181 // 2.6. Close connection (TCP FIN)
182 TCP_SendC(&testconn, TCP_ACK|TCP_FIN, 0, NULL);
183 testconn.LSeq ++; // Empty = 1 byte
184 // Expect ACK? (Does acess do delayed ACKs here?)
186 TEST_ASSERT( TCP_Pkt_CheckC(rxlen, rxbuf, &ofs, &len, &testconn, TCP_ACK) );
187 TEST_ASSERT_REL( len, ==, 0 );
188 // >>> STATE: CLOSE WAIT
192 TEST_ASSERT( TCP_Pkt_CheckC(rxlen, rxbuf, &ofs, &len, &testconn, TCP_FIN) );
193 TEST_ASSERT_REL( len, ==, 0 );
195 // >>> STATE: LAST-ACK
197 // 2.7 Send ACK of FIN
198 TCP_SendC(&testconn, TCP_ACK, 0, NULL);
199 // Expect no response
207 bool Test_TCP_SYN_RECEIVED(void)
209 // 1. Get into SYN-RECEIVED
211 // 2. Send various non-ACK packets