11#define MG_ENABLE_TCPIP 1
22#define MG_ENABLE_TCPIP_DRIVER_INIT 0
33
4- #include "mongoose.c"
4+ #include "mongoose.c" // order is important, this one first
55#include "driver_mock.c"
66
77static int s_num_tests = 0 ;
@@ -11,9 +11,9 @@ static int s_seg_sent = 0;
1111#ifdef NO_SLEEP_ABORT
1212#define ABORT () abort()
1313#else
14- #define ABORT () \
15- sleep(2); /* 2s, GH print reason */ \
16- abort ();
14+ #define ABORT () \
15+ sleep(2); /* 2s, GH print reason */ \
16+ abort ();
1717#endif
1818
1919#define ASSERT (expr ) \
@@ -48,18 +48,21 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) {
4848static void frag_recv_fn (struct mg_connection * c , int ev , void * ev_data ) {
4949 if (ev == MG_EV_ERROR ) {
5050 if (s_sent_fragment ) {
51- ASSERT (strcmp ((char * ) ev_data , "Received fragmented packet" ) == 0 );
51+ ASSERT (strcmp ((char * ) ev_data , "Received fragmented packet" ) == 0 );
5252 }
5353 }
5454 (void ) c , (void ) ev_data ;
5555}
5656
57+ // mock send to a non-existent peer using the listener connection
5758static void frag_send_fn (struct mg_connection * c , int ev , void * ev_data ) {
5859 static bool s_sent ;
59- static int s_seg_sizes [] = {416 , 416 , 368 };
60+ static int s_seg_sizes [] = {416 , 416 , 368 }; // based on len=1200 and MTU=500
6061 if (ev == MG_EV_POLL ) {
6162 if (!s_sent ) {
62- c -> send .len = 1200 ; // setting TCP payload size
63+ struct connstate * s = (struct connstate * ) (c + 1 );
64+ s -> dmss = 1500 ; // mock set some destination MSS way larger
65+ c -> send .len = 1200 ; // setting TCP payload size
6366 s_sent = true;
6467 }
6568 } else if (ev == MG_EV_WRITE ) {
@@ -88,7 +91,7 @@ static void test_poll(void) {
8891struct driver_data {
8992 char buf [DRIVER_BUF_SIZE ];
9093 size_t len ;
91- bool tx_ready ; // data can be read from tx
94+ bool tx_ready ; // data can be read from tx
9295};
9396
9497static struct driver_data s_driver_data ;
@@ -111,7 +114,7 @@ static size_t if_rx(void *buf, size_t len, struct mg_tcpip_if *ifp) {
111114 if (!driver_data -> len ) return 0 ;
112115 if (len > driver_data -> len ) len = driver_data -> len ;
113116 memcpy (buf , driver_data -> buf , len );
114- driver_data -> len = 0 ; // cleaning up the buffer
117+ driver_data -> len = 0 ; // cleaning up the buffer
115118 return len ;
116119}
117120
@@ -132,8 +135,8 @@ static void create_tcp_pkt(struct eth *e, struct ip *ip, uint32_t seq,
132135 memcpy (s_driver_data .buf , e , sizeof (* e ));
133136 memcpy (s_driver_data .buf + sizeof (* e ), ip , sizeof (* ip ));
134137 memcpy (s_driver_data .buf + sizeof (* e ) + sizeof (* ip ), & t , sizeof (struct tcp ));
135- s_driver_data .len = sizeof ( * e ) + sizeof ( * ip )
136- + sizeof (struct tcp ) + payload_len ;
138+ s_driver_data .len =
139+ sizeof ( * e ) + sizeof ( * ip ) + sizeof (struct tcp ) + payload_len ;
137140}
138141
139142static void init_tcp_handshake (struct eth * e , struct ip * ip , struct tcp * tcp ,
@@ -143,9 +146,9 @@ static void init_tcp_handshake(struct eth *e, struct ip *ip, struct tcp *tcp,
143146 mg_mgr_poll (mgr , 0 );
144147
145148 // SYN-ACK
146- while (!received_response (& s_driver_data )) mg_mgr_poll (mgr , 0 );
149+ while (!received_response (& s_driver_data )) mg_mgr_poll (mgr , 0 );
147150 tcp = (struct tcp * ) (s_driver_data .buf + sizeof (struct eth ) +
148- sizeof (struct ip ));
151+ sizeof (struct ip ));
149152 ASSERT ((tcp -> flags == (TH_SYN | TH_ACK )));
150153 ASSERT ((tcp -> ack == mg_htonl (1001 )));
151154
@@ -154,6 +157,9 @@ static void init_tcp_handshake(struct eth *e, struct ip *ip, struct tcp *tcp,
154157 mg_mgr_poll (mgr , 0 );
155158}
156159
160+ // NOTE: a 1-byte payload could be an erroneous Keep-Alive, keep length > 1 in
161+ // this operation, we're testing retransmissions and having len=1 won't work
162+
157163static void test_retransmit (void ) {
158164 struct mg_mgr mgr ;
159165 struct eth e ;
@@ -167,12 +173,13 @@ static void test_retransmit(void) {
167173 mg_mgr_init (& mgr );
168174 memset (& mif , 0 , sizeof (mif ));
169175 memset (& s_driver_data , 0 , sizeof (struct driver_data ));
170- driver .init = NULL , driver .tx = if_tx , driver .poll = if_poll , driver .rx = if_rx ;
176+ driver .init = NULL , driver .tx = if_tx , driver .poll = if_poll ,
177+ driver .rx = if_rx ;
171178 mif .driver = & driver ;
172179 mif .driver_data = & s_driver_data ;
173180 mg_tcpip_init (& mgr , & mif );
174181 mg_http_listen (& mgr , "http://0.0.0.0:0" , fn , NULL );
175- mgr .conns -> pfn = NULL ; // HTTP handler not needed
182+ mgr .conns -> pfn = NULL ; // HTTP handler not needed
176183 mg_mgr_poll (& mgr , 0 );
177184
178185 // setting the Ethernet header
@@ -189,20 +196,20 @@ static void test_retransmit(void) {
189196
190197 // packet with seq_no = 1001
191198 ip .len =
192- mg_htons (sizeof (struct ip ) + sizeof (struct tcp ) + /* TCP Payload */ 1 );
193- create_tcp_pkt (& e , & ip , 1001 , 1 , TH_PUSH | TH_ACK , 1 );
199+ mg_htons (sizeof (struct ip ) + sizeof (struct tcp ) + /* TCP Payload */ 2 );
200+ create_tcp_pkt (& e , & ip , 1001 , 1 , TH_PUSH | TH_ACK , 2 );
194201 mg_mgr_poll (& mgr , 0 );
195- while (!received_response (& s_driver_data )) mg_mgr_poll (& mgr , 0 );
202+ while (!received_response (& s_driver_data )) mg_mgr_poll (& mgr , 0 );
196203 t = (struct tcp * ) (s_driver_data .buf + sizeof (struct eth ) +
197204 sizeof (struct ip ));
198205 ASSERT ((t -> flags == TH_ACK ));
199- ASSERT ((t -> ack == mg_htonl (1002 ))); // OK
206+ ASSERT ((t -> ack == mg_htonl (1003 ))); // OK
200207
201208 // resend packet with seq_no = 1001 (e.g.: MIP ACK lost)
202- create_tcp_pkt (& e , & ip , 1001 , 1 , TH_PUSH | TH_ACK , 1 );
209+ create_tcp_pkt (& e , & ip , 1001 , 1 , TH_PUSH | TH_ACK , 2 );
203210 mg_mgr_poll (& mgr , 0 );
204211 start = mg_millis ();
205- while (!received_response (& s_driver_data )) {
212+ while (!received_response (& s_driver_data )) {
206213 mg_mgr_poll (& mgr , 0 );
207214 now = mg_millis () - start ;
208215 // we wait enough time for a reply
@@ -211,31 +218,31 @@ static void test_retransmit(void) {
211218 break ;
212219 }
213220 }
214- ASSERT ((!response_recv )); // replies should not be sent for duplicate packets
221+ ASSERT ((!response_recv )); // replies should not be sent for duplicate packets
215222
216- // packet with seq_no = 1002 got lost/delayed, send seq_no = 1003
217- create_tcp_pkt (& e , & ip , 1003 , 1 , TH_PUSH | TH_ACK , 1 );
223+ // packet with seq_no = 1003 got lost/delayed, send seq_no = 1005
224+ create_tcp_pkt (& e , & ip , 1005 , 1 , TH_PUSH | TH_ACK , 2 );
218225 mg_mgr_poll (& mgr , 0 );
219226 start = mg_millis ();
220- while (!received_response (& s_driver_data )) {
227+ while (!received_response (& s_driver_data )) {
221228 mg_mgr_poll (& mgr , 0 );
222229 now = mg_millis () - start ;
223230 if (now > 2 * MIP_TCP_ACK_MS )
224- ASSERT (0 ); // response should have been received by now
231+ ASSERT (0 ); // response should have been received by now
225232 }
226233 t = (struct tcp * ) (s_driver_data .buf + sizeof (struct eth ) +
227234 sizeof (struct ip ));
228235 ASSERT ((t -> flags == TH_ACK ));
229- ASSERT ((t -> ack == mg_htonl (1002 ))); // dup ACK
236+ ASSERT ((t -> ack == mg_htonl (1003 ))); // dup ACK
230237
231- // retransmitting packet with seq_no = 1002
232- create_tcp_pkt (& e , & ip , 1002 , 1 , TH_PUSH | TH_ACK , 1 );
238+ // retransmitting packet with seq_no = 1003
239+ create_tcp_pkt (& e , & ip , 1003 , 1 , TH_PUSH | TH_ACK , 2 );
233240 mg_mgr_poll (& mgr , 0 );
234- while (!received_response (& s_driver_data )) mg_mgr_poll (& mgr , 0 );
241+ while (!received_response (& s_driver_data )) mg_mgr_poll (& mgr , 0 );
235242 t = (struct tcp * ) (s_driver_data .buf + sizeof (struct eth ) +
236243 sizeof (struct ip ));
237244 ASSERT ((t -> flags == TH_ACK ));
238- ASSERT ((t -> ack == mg_htonl (1003 ))); // OK
245+ ASSERT ((t -> ack == mg_htonl (1005 ))); // OK
239246
240247 s_driver_data .len = 0 ;
241248 mg_mgr_free (& mgr );
@@ -252,7 +259,8 @@ static void test_frag_recv_path(void) {
252259 mg_mgr_init (& mgr );
253260 memset (& mif , 0 , sizeof (mif ));
254261 memset (& s_driver_data , 0 , sizeof (struct driver_data ));
255- driver .init = NULL , driver .tx = if_tx , driver .poll = if_poll , driver .rx = if_rx ;
262+ driver .init = NULL , driver .tx = if_tx , driver .poll = if_poll ,
263+ driver .rx = if_rx ;
256264 mif .driver = & driver ;
257265 mif .driver_data = & s_driver_data ;
258266 mg_tcpip_init (& mgr , & mif );
@@ -273,9 +281,8 @@ static void test_frag_recv_path(void) {
273281 init_tcp_handshake (& e , & ip , t , & mgr );
274282
275283 // send fragmented TCP packet
276- ip .len =
277- mg_htons (sizeof (struct ip ) + sizeof (struct tcp ) + 1000 );
278- ip .frag |= IP_MORE_FRAGS_MSK ; // setting More Fragments bit to 1
284+ ip .len = mg_htons (sizeof (struct ip ) + sizeof (struct tcp ) + 1000 );
285+ ip .frag |= IP_MORE_FRAGS_MSK ; // setting More Fragments bit to 1
279286 create_tcp_pkt (& e , & ip , 1001 , 1 , TH_PUSH | TH_ACK , 1000 );
280287 s_sent_fragment = true;
281288 mg_mgr_poll (& mgr , 0 );
@@ -292,15 +299,15 @@ static void test_frag_send_path(void) {
292299 mg_mgr_init (& mgr );
293300 memset (& mif , 0 , sizeof (mif ));
294301 memset (& s_driver_data , 0 , sizeof (struct driver_data ));
295- driver .init = NULL , driver .tx = if_tx , driver .poll = if_poll , driver .rx = if_rx ;
302+ driver .init = NULL , driver .tx = if_tx , driver .poll = if_poll ,
303+ driver .rx = if_rx ;
296304 mif .driver = & driver ;
297305 mif .driver_data = & s_driver_data ;
298306 mg_tcpip_init (& mgr , & mif );
299- mif .mtu = 500 ;
307+ mif .mtu = 500 ; // force ad hoc small MTU to fragment IP
300308 mg_http_listen (& mgr , "http://0.0.0.0:0" , frag_send_fn , NULL );
301309 mgr .conns -> pfn = NULL ;
302- for (int i = 0 ; i < 10 ; i ++ )
303- mg_mgr_poll (& mgr , 0 );
310+ for (int i = 0 ; i < 10 ; i ++ ) mg_mgr_poll (& mgr , 0 );
304311 ASSERT (s_seg_sent == 3 );
305312 s_driver_data .len = 0 ;
306313 mg_mgr_free (& mgr );
0 commit comments