1 /*
2  * scamper_tbit.c
3  *
4  * Copyright (C) 2009-2010 Ben Stasiewicz
5  * Copyright (C) 2010-2011 The University of Waikato
6  * Copyright (C) 2012      Matthew Luckie
7  * Copyright (C) 2012,2015 The Regents of the University of California
8  * Copyright (C) 2021      Matthew Luckie
9  *
10  * Authors: Ben Stasiewicz, Matthew Luckie
11  *
12  * $Id: scamper_tbit.c,v 1.51 2021/08/29 08:55:39 mjl Exp $
13  *
14  * This file implements algorithms described in the tbit-1.0 source code,
15  * as well as the papers:
16  *
17  *  "On Inferring TCP Behaviour"
18  *      by Jitendra Padhye and Sally Floyd
19  *  "Measuring the Evolution of Transport Protocols in the Internet"
20  *      by Alberto Medina, Mark Allman, and Sally Floyd.
21  *
22  * This program is free software; you can redistribute it and/or modify
23  * it under the terms of the GNU General Public License as published by
24  * the Free Software Foundation, version 2.
25  *
26  * This program is distributed in the hope that it will be useful,
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29  * GNU General Public License for more details.
30  *
31  * You should have received a copy of the GNU General Public License
32  * along with this program; if not, write to the Free Software
33  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
34  *
35  */
36 
37 #ifdef HAVE_CONFIG_H
38 #include "config.h"
39 #endif
40 #include "internal.h"
41 
42 #include "scamper_addr.h"
43 #include "scamper_list.h"
44 #include "scamper_tbit.h"
45 #include "utils.h"
46 
47 typedef struct tqe
48 {
49   int                   off;
50   scamper_tbit_tcpqe_t *qe;
51 } tqe_t;
52 
53 struct scamper_tbit_tcpq
54 {
55   uint32_t   seq;
56   tqe_t    **tqes;
57   int        tqec;
58 };
59 
scamper_tbit_data_seqoff(uint32_t rcv_nxt,uint32_t seq)60 int scamper_tbit_data_seqoff(uint32_t rcv_nxt, uint32_t seq)
61 {
62   if(seq >= rcv_nxt)
63     return seq - rcv_nxt;
64   return TCP_MAX_SEQNUM - rcv_nxt + seq + 1;
65 }
66 
tqe_cmp(const tqe_t * a,const tqe_t * b)67 static int tqe_cmp(const tqe_t *a, const tqe_t *b)
68 {
69   if(a->off < b->off)         return -1;
70   if(a->off > b->off)         return  1;
71   if(a->qe->len < b->qe->len) return -1;
72   if(a->qe->len > b->qe->len) return  1;
73   return 0;
74 }
75 
scamper_tbit_fo_setcookie(scamper_tbit_t * tbit,uint8_t * cookie,uint8_t len)76 int scamper_tbit_fo_setcookie(scamper_tbit_t *tbit,uint8_t *cookie,uint8_t len)
77 {
78   if((tbit->fo_cookie = memdup(cookie, len)) == NULL)
79     return -1;
80   tbit->fo_cookielen = len;
81   return 0;
82 }
83 
scamper_tbit_fo_getcookie(scamper_tbit_t * tbit,uint8_t * c,uint8_t * l)84 int scamper_tbit_fo_getcookie(scamper_tbit_t *tbit, uint8_t *c, uint8_t *l)
85 {
86   uint8_t u8, v, iphlen, tcphlen, *pktptr;
87   scamper_tbit_pkt_t *pkt;
88   uint32_t i;
89 
90   for(i=0; i<tbit->pktc; i++)
91     {
92       pkt = tbit->pkts[i];
93       if(pkt->dir != SCAMPER_TBIT_PKT_DIR_RX)
94 	continue;
95 
96       v = (pkt->data[0] >> 4);
97       if(v == 4)
98 	{
99 	  iphlen = (pkt->data[0] & 0xf) * 4;
100 	  if(pkt->data[9] != IPPROTO_TCP)
101 	    continue;
102 	  if((bytes_ntohs(pkt->data+6) & 0x1fff) != 0)
103 	    continue;
104 	}
105       else if(v == 6)
106 	{
107 	  iphlen = 40;
108 	  u8 = pkt->data[6];
109 	  for(;;)
110 	    {
111 	      switch(u8)
112 		{
113 		case IPPROTO_HOPOPTS:
114 		case IPPROTO_DSTOPTS:
115 		case IPPROTO_ROUTING:
116 		  if(pkt->data[iphlen+1] == 0 ||
117 		     255 - iphlen <= (pkt->data[iphlen+1] * 8) + 8)
118 		    break;
119 		  u8 = pkt->data[iphlen+0];
120 		  iphlen += (pkt->data[iphlen+1] * 8) + 8;
121 		  continue;
122 
123 		case IPPROTO_FRAGMENT:
124 		  if(255 - iphlen <= 8)
125 		    break;
126 		  if((bytes_ntohs(pkt->data+iphlen+2) & 0xfff8) != 0)
127 		    break;
128 		  u8 = pkt->data[iphlen+0];
129 		  iphlen += 8;
130 		  continue;
131 		}
132 	      break;
133 	    }
134 	  if(u8 != IPPROTO_TCP)
135 	    continue;
136 	}
137       else continue;
138 
139       if((pkt->data[iphlen+13] & (TH_SYN|TH_ACK)) != (TH_SYN|TH_ACK))
140 	continue;
141 
142       tcphlen = ((pkt->data[iphlen+12] & 0xf0) >> 4) * 4;
143       u8 = 20;
144       while(u8 < tcphlen)
145 	{
146 	  pktptr = pkt->data + iphlen + u8;
147 	  if(pktptr[0] == 0)
148 	    break;
149 	  if(pktptr[1] == 1) {
150 	    u8++; continue;
151 	  }
152 
153 	  if(pktptr[1] == 0 || u8 + pktptr[1] > tcphlen)
154 	    break;
155 
156 	  if(pktptr[0] == 34 && pktptr[1] > 2 && pktptr[1] <= 18)
157 	    {
158 	      *l = pktptr[1] - 2;
159 	      memcpy(c, pktptr+2, *l);
160 	      return 1;
161 	    }
162 	  else if(pktptr[0] == 254  && pktptr[1] > 4 && pktptr[1] <= 20 &&
163 		  pktptr[2] == 0xF9 && pktptr[3] == 0x89)
164 	    {
165 	      *l = pktptr[1] - 4;
166 	      memcpy(c, pktptr+4, *l);
167 	      return 1;
168 	    }
169 	  u8 += pktptr[1];
170 	}
171     }
172 
173   return 0;
174 }
175 
scamper_tbit_tcpqe_free(scamper_tbit_tcpqe_t * qe,void (* ff)(void *))176 void scamper_tbit_tcpqe_free(scamper_tbit_tcpqe_t *qe, void (*ff)(void *))
177 {
178   if(qe == NULL) return;
179   if(ff != NULL && qe->data != NULL)
180     ff(qe->data);
181   free(qe);
182   return;
183 }
184 
185 /*
186  * scamper_tbit_tcpq_tail
187  *
188  * returns the sequence number at the tail of the tcpq, even if there
189  * are gaps in the tcpq.
190  */
scamper_tbit_tcpq_tail(const scamper_tbit_tcpq_t * tcpq)191 uint32_t scamper_tbit_tcpq_tail(const scamper_tbit_tcpq_t *tcpq)
192 {
193   uint32_t range = 0, edge, u32;
194   scamper_tbit_tcpqe_t *qe;
195   int i;
196 
197   for(i=0; i<tcpq->tqec; i++)
198     {
199       qe = tcpq->tqes[i]->qe;
200       edge = qe->seq + qe->len;
201       if((u32 = scamper_tbit_data_seqoff(tcpq->seq, edge)) > range)
202 	range = u32;
203     }
204 
205   return tcpq->seq + range;
206 }
207 
scamper_tbit_tcpq_alloc(uint32_t isn)208 scamper_tbit_tcpq_t *scamper_tbit_tcpq_alloc(uint32_t isn)
209 {
210   scamper_tbit_tcpq_t *q;
211   if((q = malloc_zero(sizeof(scamper_tbit_tcpq_t))) == NULL)
212     goto err;
213   q->seq = isn;
214   return q;
215  err:
216   scamper_tbit_tcpq_free(q, NULL);
217   return NULL;
218 }
219 
scamper_tbit_tcpq_flush(scamper_tbit_tcpq_t * q,void (* ff)(void *))220 void scamper_tbit_tcpq_flush(scamper_tbit_tcpq_t *q, void (*ff)(void *))
221 {
222   tqe_t *tqe;
223   int i;
224 
225   if(q->tqes == NULL)
226     return;
227 
228   for(i=0; i<q->tqec; i++)
229     {
230       tqe = q->tqes[i];
231       scamper_tbit_tcpqe_free(tqe->qe, ff);
232       free(tqe);
233     }
234   free(q->tqes);
235   q->tqes = NULL;
236   q->tqec = 0;
237   return;
238 }
239 
scamper_tbit_tcpq_free(scamper_tbit_tcpq_t * q,void (* ff)(void *))240 void scamper_tbit_tcpq_free(scamper_tbit_tcpq_t *q, void (*ff)(void *))
241 {
242   if(q == NULL)
243     return;
244   if(q->tqes != NULL)
245     scamper_tbit_tcpq_flush(q, ff);
246   free(q);
247   return;
248 }
249 
scamper_tbit_tcpq_seg(scamper_tbit_tcpq_t * q,uint32_t * seq,uint16_t * len)250 int scamper_tbit_tcpq_seg(scamper_tbit_tcpq_t *q, uint32_t *seq, uint16_t *len)
251 {
252   tqe_t *tqe;
253   assert(q->tqec >= 0);
254   if(q->tqec == 0)
255     return -1;
256   tqe = q->tqes[0];
257   assert(q->seq + tqe->off == tqe->qe->seq);
258   *seq = tqe->qe->seq;
259   *len = tqe->qe->len;
260   return 0;
261 }
262 
scamper_tbit_tcpq_pop(scamper_tbit_tcpq_t * q)263 scamper_tbit_tcpqe_t *scamper_tbit_tcpq_pop(scamper_tbit_tcpq_t *q)
264 {
265   scamper_tbit_tcpqe_t *qe;
266   uint16_t len;
267   tqe_t *tqe;
268   int i, off;
269 
270   if(q->tqec == 0)
271     return NULL;
272 
273   tqe = q->tqes[0];
274   qe = tqe->qe;
275   free(tqe);
276 
277   if(--q->tqec > 0)
278     memmove(q->tqes, q->tqes+1, sizeof(tqe_t *) * q->tqec);
279 
280   off = scamper_tbit_data_seqoff(q->seq, qe->seq);
281   if(off < 0 && off + qe->len <= 0)
282     return qe;
283 
284   len = qe->len + off;
285   for(i=0; i<q->tqec; i++)
286     q->tqes[i]->off -= len;
287   q->seq += len;
288 
289   return qe;
290 }
291 
scamper_tbit_tcpq_add(scamper_tbit_tcpq_t * q,uint32_t seq,uint8_t flags,uint16_t len,uint8_t * data)292 int scamper_tbit_tcpq_add(scamper_tbit_tcpq_t *q, uint32_t seq,
293 			  uint8_t flags, uint16_t len, uint8_t *data)
294 {
295   tqe_t *tqe;
296 
297   assert(scamper_tbit_data_inrange(q->seq, seq, len) != 0);
298   if((tqe = malloc_zero(sizeof(tqe_t))) == NULL)
299     goto err;
300   if((tqe->qe = malloc_zero(sizeof(scamper_tbit_tcpqe_t))) == NULL)
301     goto err;
302   tqe->off = scamper_tbit_data_seqoff(q->seq, seq);
303   tqe->qe->seq   = seq;
304   tqe->qe->flags = flags;
305   tqe->qe->len   = len;
306   tqe->qe->data  = data;
307   if(array_insert((void ***)&q->tqes,&q->tqec,tqe,(array_cmp_t)tqe_cmp) != 0)
308     goto err;
309   return 0;
310 
311  err:
312   if(tqe != NULL)
313     {
314       scamper_tbit_tcpqe_free(tqe->qe, NULL);
315       free(tqe);
316     }
317   return -1;
318 }
319 
scamper_tbit_tcpq_sack(scamper_tbit_tcpq_t * q,uint32_t * sack,int count)320 int scamper_tbit_tcpq_sack(scamper_tbit_tcpq_t *q, uint32_t *sack, int count)
321 {
322   uint32_t left, right;
323   scamper_tbit_tcpqe_t *qe;
324   int i, off, c = 0;
325 
326   assert(q->tqec >= 0);
327   if(q->tqec == 0)
328     return 0;
329 
330   qe = q->tqes[0]->qe;
331   if(qe->len == 0)
332     return 0;
333 
334   left = qe->seq;
335   right = qe->seq + qe->len;
336   assert(scamper_tbit_data_seqoff(q->seq, left) > 0);
337 
338   for(i=1; i<q->tqec && c < count; i++)
339     {
340       qe = q->tqes[i]->qe;
341       if(qe->len == 0)
342 	continue;
343       if((off = scamper_tbit_data_seqoff(right, qe->seq)) <= 0)
344 	{
345 	  off = abs(off);
346 	  if(qe->len > off)
347 	    right = right + qe->len - off;
348 	  continue;
349 	}
350 
351       sack[c*2]     = left;
352       sack[(c*2)+1] = right;
353       c++;
354 
355       left  = qe->seq;
356       right = qe->seq + qe->len;
357     }
358 
359   if(c < count)
360     {
361       sack[c*2]     = left;
362       sack[(c*2)+1] = right;
363       c++;
364     }
365 
366   return c;
367 }
368 
369 /*
370  * scamper_tbit_data_inrange:
371  *
372  * rcv_nxt <= beginning sequence number of segment < rcv_nxt + rcv_wnd OR
373  * rcv_nxt <= ending sequence number of segment < rcv_nxt + rcv_wnd
374  */
scamper_tbit_data_inrange(uint32_t rcv_nxt,uint32_t seq,uint16_t len)375 int scamper_tbit_data_inrange(uint32_t rcv_nxt, uint32_t seq, uint16_t len)
376 {
377   if((SEQ_LEQ(rcv_nxt, seq) && SEQ_LT(seq, rcv_nxt + 65535)) ||
378      (SEQ_LEQ(rcv_nxt, seq+len-1) && SEQ_LT(seq+len-1, rcv_nxt + 65535)))
379     return 1;
380   return 0;
381 }
382 
scamper_tbit_pkt_iplen(const scamper_tbit_pkt_t * pkt)383 int scamper_tbit_pkt_iplen(const scamper_tbit_pkt_t *pkt)
384 {
385   uint8_t v = pkt->data[0] >> 4;
386   int rc = -1;
387 
388   if(v == 4)
389     rc = bytes_ntohs(pkt->data+2);
390   else if(v == 6)
391     rc = bytes_ntohs(pkt->data+4) + 40;
392 
393   return rc;
394 }
395 
scamper_tbit_pkt_iph(const scamper_tbit_pkt_t * pkt,uint8_t * proto,uint8_t * iphlen,uint16_t * iplen)396 int scamper_tbit_pkt_iph(const scamper_tbit_pkt_t *pkt,
397 			 uint8_t *proto, uint8_t *iphlen, uint16_t *iplen)
398 {
399   uint8_t v = pkt->data[0] >> 4;
400 
401   if(v == 4)
402     {
403       *iphlen = (pkt->data[0] & 0xf) * 4;
404       *iplen = bytes_ntohs(pkt->data+2);
405       *proto = pkt->data[9];
406       return 0;
407     }
408 
409   if(v == 6)
410     {
411       *iphlen = 40;
412       *iplen = bytes_ntohs(pkt->data+4) + 40;
413       *proto = pkt->data[6];
414       for(;;)
415 	{
416 	  switch(*proto)
417 	    {
418 	    case IPPROTO_HOPOPTS:
419 	    case IPPROTO_DSTOPTS:
420 	    case IPPROTO_ROUTING:
421 	      if(pkt->data[(*iphlen)+1] == 0 ||
422 		 255 - *iphlen <= (pkt->data[(*iphlen)+1] * 8) + 8)
423 		return -1;
424 	      *proto = pkt->data[*iphlen];
425 	      *iphlen += (pkt->data[(*iphlen)+1] * 8) + 8;
426 	      continue;
427 	    case IPPROTO_FRAGMENT:
428 	      if(255 - *iphlen <= 8)
429 		return -1;
430 	      *proto = pkt->data[*iphlen];
431 	      if((bytes_ntohs(pkt->data+(*iphlen)+2) & 0xfff8) != 0) /* off */
432 		return -1;
433 	      if((pkt->data[(*iphlen)+3] & 0x1) != 0) /* mf */
434 		return -1;
435 	      *iphlen += 8;
436 	      continue;
437 	    }
438 	  break;
439 	}
440       return 0;
441     }
442 
443   return -1;
444 }
445 
scamper_tbit_pkt_tcpdatabytes(const scamper_tbit_pkt_t * pkt,uint16_t * bc)446 int scamper_tbit_pkt_tcpdatabytes(const scamper_tbit_pkt_t *pkt, uint16_t *bc)
447 {
448   uint8_t iphlen, tcphlen, proto;
449   uint16_t iplen;
450 
451   if(scamper_tbit_pkt_iph(pkt, &proto, &iphlen, &iplen) != 0)
452     return -1;
453   if(proto != IPPROTO_TCP)
454     return -1;
455   tcphlen = ((pkt->data[iphlen+12] & 0xf0) >> 4) * 4;
456   *bc = iplen - iphlen - tcphlen;
457   return 0;
458 }
459 
scamper_tbit_pkt_tcpack(const scamper_tbit_pkt_t * pkt,uint32_t * ack)460 int scamper_tbit_pkt_tcpack(const scamper_tbit_pkt_t *pkt, uint32_t *ack)
461 {
462   uint8_t iphlen, proto;
463   uint16_t iplen;
464   if(scamper_tbit_pkt_iph(pkt, &proto, &iphlen, &iplen) != 0)
465     return -1;
466   if(proto != IPPROTO_TCP || (pkt->data[iphlen+13] & TH_ACK) == 0)
467     return -1;
468   *ack = bytes_ntohl(pkt->data+iphlen+8);
469   return 0;
470 }
471 
scamper_tbit_icw_size(const scamper_tbit_t * tbit,uint32_t * icw_out)472 int scamper_tbit_icw_size(const scamper_tbit_t *tbit, uint32_t *icw_out)
473 {
474   const scamper_tbit_icw_t *icw = tbit->data;
475   const scamper_tbit_pkt_t *pkt;
476   scamper_tbit_tcpq_t *q = NULL;
477   uint32_t i, u32, seq, start_seq;
478   uint16_t iplen, datalen;
479   uint8_t proto, iphlen, tcphlen, flags, start_seq_c = 0;
480   int rc = -1;
481 
482   if(tbit->result != SCAMPER_TBIT_RESULT_ICW_SUCCESS ||
483      tbit->pktc < 1)
484     goto done;
485 
486   for(i=1; i<tbit->pktc; i++)
487     {
488       pkt = tbit->pkts[i];
489       if(pkt->dir == SCAMPER_TBIT_PKT_DIR_RX)
490 	break;
491     }
492   if(i == tbit->pktc ||
493      scamper_tbit_pkt_iph(pkt, &proto, &iphlen, &iplen) != 0 ||
494      proto != IPPROTO_TCP ||
495      (pkt->data[iphlen+13] & (TH_SYN|TH_ACK)) != (TH_SYN|TH_ACK))
496     goto done;
497 
498   start_seq = bytes_ntohl(pkt->data+iphlen+4) + icw->start_seq;
499   if((q = scamper_tbit_tcpq_alloc(start_seq)) == NULL)
500     goto done;
501 
502   for(i++; i<tbit->pktc; i++)
503     {
504       pkt = tbit->pkts[i];
505       if(pkt->dir != SCAMPER_TBIT_PKT_DIR_RX)
506 	continue;
507       if(scamper_tbit_pkt_iph(pkt, &proto, &iphlen, &iplen) != 0)
508 	break;
509       if(proto != IPPROTO_TCP)
510 	break;
511       seq     = bytes_ntohl(pkt->data+iphlen+4);
512       tcphlen = ((pkt->data[iphlen+12] & 0xf0) >> 4) * 4;
513       flags   = pkt->data[iphlen+13];
514 
515       if((datalen = iplen - iphlen - tcphlen) == 0 && (flags & TH_FIN) == 0)
516 	continue;
517       if(scamper_tbit_data_inrange(start_seq, seq, datalen) == 0)
518 	continue;
519 
520       if(seq == start_seq)
521 	{
522 	  start_seq_c++;
523 	  if(start_seq_c == 2)
524 	    {
525 	      u32 = scamper_tbit_tcpq_tail(q);
526 	      *icw_out = scamper_tbit_data_seqoff(start_seq, u32);
527 	      rc = 0;
528 	      break;
529 	    }
530 	}
531 
532       if(scamper_tbit_tcpq_add(q, seq, flags, datalen, NULL) != 0)
533 	break;
534     }
535 
536  done:
537   scamper_tbit_tcpq_free(q, NULL);
538   return rc;
539 }
540 
scamper_tbit_stats(const scamper_tbit_t * tbit,scamper_tbit_stats_t * stats)541 int scamper_tbit_stats(const scamper_tbit_t *tbit, scamper_tbit_stats_t *stats)
542 {
543   const scamper_tbit_pkt_t *pkt, *syn;
544   scamper_tbit_tcpq_t *q = NULL;
545   scamper_tbit_tcpqe_t *qe;
546   uint32_t rcv_nxt, seq;
547   uint16_t iplen, datalen, len;
548   uint8_t proto, iphlen, tcphlen, flags;
549   uint32_t i;
550   int off, seenfin = 0;
551 
552   memset(stats, 0, sizeof(scamper_tbit_stats_t));
553   if(tbit->pktc < 1)
554     return 0;
555 
556   /* to begin with, look for a SYN/ACK */
557   syn = tbit->pkts[0];
558   for(i=1; i<tbit->pktc; i++)
559     {
560       pkt = tbit->pkts[i];
561       if(pkt->dir == SCAMPER_TBIT_PKT_DIR_RX)
562 	break;
563     }
564   if(i == tbit->pktc)
565     return 0;
566 
567   if(scamper_tbit_pkt_iph(pkt, &proto, &iphlen, &iplen) != 0)
568     goto err;
569   if(proto != IPPROTO_TCP)
570     goto err;
571   if((pkt->data[iphlen+13] & (TH_SYN|TH_ACK)) != (TH_SYN|TH_ACK))
572     goto err;
573 
574   timeval_diff_tv(&stats->synack_rtt, &syn->tv, &pkt->tv);
575   rcv_nxt = bytes_ntohl(pkt->data+iphlen+4) + 1;
576 
577   if((q = scamper_tbit_tcpq_alloc(rcv_nxt)) == NULL)
578     goto err;
579 
580   for(i++; i<tbit->pktc; i++)
581     {
582       pkt = tbit->pkts[i];
583       if(pkt->dir != SCAMPER_TBIT_PKT_DIR_RX)
584 	continue;
585       if(scamper_tbit_pkt_iph(pkt, &proto, &iphlen, &iplen) != 0)
586 	goto err;
587       if(proto != IPPROTO_TCP)
588 	goto err;
589       seq     = bytes_ntohl(pkt->data+iphlen+4);
590       tcphlen = ((pkt->data[iphlen+12] & 0xf0) >> 4) * 4;
591       flags   = pkt->data[iphlen+13];
592       if((datalen = iplen - iphlen - tcphlen) == 0 && (flags & TH_FIN) == 0)
593 	continue;
594 
595       stats->rx_totalsize += (iplen - iphlen - tcphlen);
596 
597       /* skip over a packet out of range */
598       if(scamper_tbit_data_inrange(rcv_nxt, seq, datalen) == 0)
599 	continue;
600 
601       if(scamper_tbit_tcpq_add(q, seq, flags, datalen, NULL) != 0)
602 	goto err;
603 
604       while(scamper_tbit_tcpq_seg(q, &seq, &datalen) == 0)
605 	{
606 	  if(scamper_tbit_data_inrange(rcv_nxt, seq, datalen) == 0)
607 	    {
608 	      scamper_tbit_tcpqe_free(scamper_tbit_tcpq_pop(q), NULL);
609 	      continue;
610 	    }
611 
612 	  /* can't process this packet yet */
613 	  if((off = scamper_tbit_data_seqoff(rcv_nxt, seq)) > 0)
614 	    break;
615 
616 	  qe = scamper_tbit_tcpq_pop(q);
617 	  flags = qe->flags;
618 	  scamper_tbit_tcpqe_free(qe, NULL);
619 	  len = datalen + off;
620 	  rcv_nxt += len;
621 	  stats->rx_xfersize += len;
622 
623 	  if((flags & TH_FIN) != 0)
624 	    {
625 	      timeval_diff_tv(&stats->xfertime, &syn->tv, &pkt->tv);
626 	      seenfin = 1;
627 	    }
628 	}
629     }
630 
631   if(seenfin == 0)
632     goto err;
633 
634   scamper_tbit_tcpq_free(q, NULL);
635   return 0;
636 
637  err:
638   scamper_tbit_tcpq_free(q, NULL);
639   return -1;
640 }
641 
scamper_tbit_type2str(const scamper_tbit_t * tbit,char * buf,size_t len)642 char *scamper_tbit_type2str(const scamper_tbit_t *tbit, char *buf, size_t len)
643 {
644   static char *t[] = {
645     NULL,
646     "pmtud",
647     "ecn",
648     "null",
649     "sack-rcvr",
650     "icw",
651     "abc",
652     "blind-data",
653     "blind-rst",
654     "blind-syn",
655     "blind-fin",
656   };
657 
658   if(tbit->type >= sizeof(t) / sizeof(char *) || t[tbit->type] == NULL)
659     {
660       snprintf(buf, len, "%d", tbit->type);
661       return buf;
662     }
663 
664   return t[tbit->type];
665 }
666 
scamper_tbit_res2str(const scamper_tbit_t * tbit,char * buf,size_t len)667 char *scamper_tbit_res2str(const scamper_tbit_t *tbit, char *buf, size_t len)
668 {
669   static char *t[] = {
670     "none",                /* 0 */
671     "tcp-noconn",
672     "tcp-rst",
673     "tcp-error",
674     "sys-error",
675     "aborted",
676     "tcp-noconn-rst",
677     "halted",
678     "tcp-badopt",
679     "tcp-fin",
680     "tcp-zerowin",         /* 10 */
681     NULL,
682     NULL,
683     NULL,
684     NULL,
685     NULL,
686     NULL,
687     NULL,
688     NULL,
689     NULL,
690     "pmtud-noack",         /* 20 */
691     "pmtud-nodata",
692     "pmtud-toosmall",
693     "pmtud-nodf",
694     "pmtud-fail",
695     "pmtud-success",
696     "pmtud-cleardf",
697     NULL,
698     NULL,
699     NULL,
700     "ecn-success",         /* 30 */
701     "ecn-incapable",
702     "ecn-badsynack",
703     "ecn-noece",
704     "ecn-noack",
705     "ecn-nodata",
706     NULL,
707     NULL,
708     NULL,
709     NULL,
710     "null-success",        /* 40 */
711     "null-nodata",
712     NULL,
713     NULL,
714     NULL,
715     NULL,
716     NULL,
717     NULL,
718     NULL,
719     NULL,
720     "sack-incapable",      /* 50 */
721     "sack-rcvr-success",
722     "sack-rcvr-shifted",
723     "sack-rcvr-timeout",
724     "sack-rcvr-nosack",
725     NULL,
726     NULL,
727     NULL,
728     NULL,
729     NULL,
730     "icw-success",         /* 60 */
731     "icw-tooshort",
732     NULL,
733     NULL,
734     NULL,
735     NULL,
736     NULL,
737     NULL,
738     NULL,
739     NULL,
740     "abc-success",         /* 70 */
741     "abc-tooshort",
742     "abc-badicw",
743     NULL,
744     NULL,
745     NULL,
746     NULL,
747     NULL,
748     NULL,
749     NULL,
750     "blind-accepted",      /* 80 */
751     "blind-challenge",
752     "blind-ignored",
753     "blind-rst",
754     "blind-synnew",
755   };
756 
757   if(tbit->result >= sizeof(t) / sizeof(char *) || t[tbit->result] == NULL)
758     {
759       snprintf(buf, len, "%d", tbit->result);
760       return buf;
761     }
762 
763   return t[tbit->result];
764 }
765 
scamper_tbit_pkt_alloc(uint8_t dir,uint8_t * data,uint16_t len,struct timeval * tv)766 scamper_tbit_pkt_t *scamper_tbit_pkt_alloc(uint8_t dir, uint8_t *data,
767 					   uint16_t len, struct timeval *tv)
768 {
769   scamper_tbit_pkt_t *pkt;
770 
771   if((pkt = malloc_zero(sizeof(scamper_tbit_pkt_t))) == NULL)
772     goto err;
773 
774   pkt->dir = dir;
775   if(len != 0 && data != NULL)
776     {
777       if((pkt->data = memdup(data, len)) == NULL)
778 	goto err;
779       pkt->len = len;
780     }
781   if(tv != NULL) timeval_cpy(&pkt->tv, tv);
782   return pkt;
783 
784  err:
785   free(pkt);
786   return NULL;
787 }
788 
scamper_tbit_pkt_free(scamper_tbit_pkt_t * pkt)789 void scamper_tbit_pkt_free(scamper_tbit_pkt_t *pkt)
790 {
791   if(pkt == NULL)
792     return;
793   if(pkt->data != NULL) free(pkt->data);
794   free(pkt);
795   return;
796 }
797 
scamper_tbit_pkts_alloc(scamper_tbit_t * tbit,uint32_t count)798 int scamper_tbit_pkts_alloc(scamper_tbit_t *tbit, uint32_t count)
799 {
800   size_t size = count * sizeof(scamper_tbit_pkt_t *);
801   if((tbit->pkts = (scamper_tbit_pkt_t **)malloc_zero(size)) == NULL)
802     return -1;
803   return 0;
804 }
805 
scamper_tbit_record_pkt(scamper_tbit_t * tbit,scamper_tbit_pkt_t * pkt)806 int scamper_tbit_record_pkt(scamper_tbit_t *tbit, scamper_tbit_pkt_t *pkt)
807 {
808   size_t len = (tbit->pktc + 1) * sizeof(scamper_tbit_pkt_t *);
809 
810   /* Add a new element to the pkts array */
811   if(realloc_wrap((void**)&tbit->pkts, len) != 0)
812     return -1;
813 
814   tbit->pkts[tbit->pktc++] = pkt;
815   return 0;
816 }
817 
scamper_tbit_app_http_alloc(uint8_t type,char * host,char * file)818 scamper_tbit_app_http_t *scamper_tbit_app_http_alloc(uint8_t type,
819 						     char *host, char *file)
820 {
821   scamper_tbit_app_http_t *http;
822 
823   if((http = malloc_zero(sizeof(scamper_tbit_app_http_t))) == NULL ||
824      (host != NULL && (http->host = strdup(host)) == NULL) ||
825      (file != NULL && (http->file = strdup(file)) == NULL))
826     {
827       if(http == NULL) return NULL;
828       if(http->host != NULL) free(http->host);
829       if(http->file != NULL) free(http->file);
830       free(http);
831       return NULL;
832     }
833 
834   http->type = type;
835   return http;
836 }
837 
scamper_tbit_app_http_free(scamper_tbit_app_http_t * http)838 void scamper_tbit_app_http_free(scamper_tbit_app_http_t *http)
839 {
840   if(http == NULL)
841     return;
842   if(http->host != NULL) free(http->host);
843   if(http->file != NULL) free(http->file);
844   free(http);
845   return;
846 }
847 
scamper_tbit_app_bgp_alloc(void)848 scamper_tbit_app_bgp_t *scamper_tbit_app_bgp_alloc(void)
849 {
850   return malloc_zero(sizeof(scamper_tbit_app_bgp_t));
851 }
852 
scamper_tbit_app_bgp_free(scamper_tbit_app_bgp_t * bgp)853 void scamper_tbit_app_bgp_free(scamper_tbit_app_bgp_t *bgp)
854 {
855   if(bgp == NULL)
856     return;
857   free(bgp);
858   return;
859 }
860 
scamper_tbit_pmtud_alloc(void)861 scamper_tbit_pmtud_t *scamper_tbit_pmtud_alloc(void)
862 {
863   return malloc_zero(sizeof(scamper_tbit_pmtud_t));
864 }
865 
scamper_tbit_pmtud_free(scamper_tbit_pmtud_t * pmtud)866 void scamper_tbit_pmtud_free(scamper_tbit_pmtud_t *pmtud)
867 {
868   if(pmtud == NULL)
869     return;
870   if(pmtud->ptbsrc != NULL)
871     scamper_addr_free(pmtud->ptbsrc);
872   free(pmtud);
873   return;
874 }
875 
scamper_tbit_null_alloc(void)876 scamper_tbit_null_t *scamper_tbit_null_alloc(void)
877 {
878   return malloc_zero(sizeof(scamper_tbit_null_t));
879 }
880 
scamper_tbit_null_free(scamper_tbit_null_t * null)881 void scamper_tbit_null_free(scamper_tbit_null_t *null)
882 {
883   if(null == NULL)
884     return;
885   free(null);
886   return;
887 }
888 
scamper_tbit_icw_alloc(void)889 scamper_tbit_icw_t *scamper_tbit_icw_alloc(void)
890 {
891   return malloc_zero(sizeof(scamper_tbit_icw_t));
892 }
893 
scamper_tbit_icw_free(scamper_tbit_icw_t * icw)894 void scamper_tbit_icw_free(scamper_tbit_icw_t *icw)
895 {
896   free(icw);
897   return;
898 }
899 
scamper_tbit_blind_alloc(void)900 scamper_tbit_blind_t *scamper_tbit_blind_alloc(void)
901 {
902   return malloc_zero(sizeof(scamper_tbit_blind_t));
903 }
904 
scamper_tbit_blind_free(scamper_tbit_blind_t * blind)905 void scamper_tbit_blind_free(scamper_tbit_blind_t *blind)
906 {
907   if(blind == NULL)
908     return;
909   free(blind);
910   return;
911 }
912 
913 /* Free the tbit object. */
scamper_tbit_free(scamper_tbit_t * tbit)914 void scamper_tbit_free(scamper_tbit_t *tbit)
915 {
916   uint32_t i;
917 
918   if(tbit == NULL)
919     return;
920 
921   if(tbit->src != NULL)   scamper_addr_free(tbit->src);
922   if(tbit->dst != NULL)   scamper_addr_free(tbit->dst);
923   if(tbit->list != NULL)  scamper_list_free(tbit->list);
924   if(tbit->cycle != NULL) scamper_cycle_free(tbit->cycle);
925 
926   if(tbit->fo_cookie != NULL) free(tbit->fo_cookie);
927 
928   /* Free the recorded packets */
929   if(tbit->pkts != NULL)
930     {
931       for(i=0; i<tbit->pktc; i++)
932 	scamper_tbit_pkt_free(tbit->pkts[i]);
933       free(tbit->pkts);
934     }
935 
936   /* Free protocol specific data */
937   if(tbit->app_data != NULL)
938     {
939       if(tbit->app_proto == SCAMPER_TBIT_APP_HTTP)
940 	scamper_tbit_app_http_free(tbit->app_data);
941     }
942 
943   /* Free test-specific data */
944   if(tbit->data != NULL)
945     {
946       if(tbit->type == SCAMPER_TBIT_TYPE_PMTUD)
947 	scamper_tbit_pmtud_free(tbit->data);
948       else if(tbit->type == SCAMPER_TBIT_TYPE_NULL)
949 	scamper_tbit_null_free(tbit->data);
950       else if(tbit->type == SCAMPER_TBIT_TYPE_ICW)
951 	scamper_tbit_icw_free(tbit->data);
952       else if(tbit->type == SCAMPER_TBIT_TYPE_BLIND_RST ||
953 	      tbit->type == SCAMPER_TBIT_TYPE_BLIND_SYN ||
954 	      tbit->type == SCAMPER_TBIT_TYPE_BLIND_DATA ||
955 	      tbit->type == SCAMPER_TBIT_TYPE_BLIND_FIN)
956 	scamper_tbit_blind_free(tbit->data);
957     }
958 
959   free(tbit);
960   return;
961 }
962 
scamper_tbit_alloc(void)963 scamper_tbit_t *scamper_tbit_alloc(void)
964 {
965   return (scamper_tbit_t *)malloc_zero(sizeof(scamper_tbit_t));
966 }
967