示例#1
0
//--------------------------------------------------------------------
void Stat(Double *p, Int n, Statistics *s)
{

// Statistics: min, max, ave, var

   s->ave = Mean(p,n);
   s->dev = Stdev(p,n);

   //qsort((void*)p, n, sizeof(Double),(int(*)(void*,void*))Cmp_Double);
   qsort((void*)p, n, sizeof(Double), Cmp_Double);

   s->min = p[0];
   s->max = p[n-1];

} // end Statistics
示例#2
0
文件: output.c 项目: blitz/tcptrace
void
PrintTrace(
    tcp_pair *ptp)
{
    double etime;
    u_long etime_secs;
    u_long etime_usecs;
    double etime_data1;
    double etime_data2;
    tcb *pab = &ptp->a2b;
    tcb *pba = &ptp->b2a;
    char *host1 = pab->host_letter;
    char *host2 = pba->host_letter;
    char bufl[40],bufr[40];
   
    /* counters to use for seq. space wrap around calculations
     */
    u_llong stream_length_pab=0, stream_length_pba=0;
    u_long pab_last, pba_last;

   /* Reset the counter for each connection */
   sv_print_count = 1; /* The first field (conn_#) gets printed in trace.c */
   

    /* calculate elapsed time */
    etime = elapsed(ptp->first_time,ptp->last_time);
    etime_secs = etime / 1000000.0;
    etime_usecs = 1000000 * (etime/1000000.0 - (double)etime_secs);

    /* Check if comma-separated-values or tab-separated-values
     * has been requested.
     */ 
   if(csv || tsv || (sv != NULL)) {
       fprintf(stdout,"%s%s%s%s%s%s%s%s",
	       ptp->a_hostname, sp, ptp->b_hostname, sp,
	       ptp->a_portname, sp, ptp->b_portname, sp);
       sv_print_count += 4;
       /* Print the start and end times. In other words,
	* print the time of the first and the last packet
	*/ 
       fprintf(stdout,"%ld.%ld %s %ld.%ld %s",
	       (long)ptp->first_time.tv_sec, (long)ptp->first_time.tv_usec, sp,
	       (long)ptp->last_time.tv_sec, (long)ptp->last_time.tv_usec, sp);
       sv_print_count += 2;      
    }
    else {
       fprintf(stdout,"\thost %-4s      %s\n",
	       (snprintf(bufl,sizeof(bufl),"%s:", host1),bufl), ptp->a_endpoint);
       fprintf(stdout,"\thost %-4s      %s\n",
	       (snprintf(bufl,sizeof(bufl),"%s:", host2),bufl), ptp->b_endpoint);
       fprintf(stdout,"\tcomplete conn: %s",
	       ConnReset(ptp)?"RESET":(
				       ConnComplete(ptp)?"yes":"no"));
       if (ConnComplete(ptp))
	 fprintf(stdout,"\n");
       else
	 fprintf(stdout,"\t(SYNs: %u)  (FINs: %u)\n",
		 SynCount(ptp), FinCount(ptp));
       
       fprintf(stdout,"\tfirst packet:  %s\n", ts2ascii(&ptp->first_time));
       fprintf(stdout,"\tlast packet:   %s\n", ts2ascii(&ptp->last_time));
       
       fprintf(stdout,"\telapsed time:  %s\n", elapsed2str(etime));
       
       fprintf(stdout,"\ttotal packets: %" FS_ULL "\n", ptp->packets);
       
       fprintf(stdout,"\tfilename:      %s\n", ptp->filename);
       
       fprintf(stdout,"   %s->%s:			      %s->%s:\n",
	       host1,host2,host2,host1);
    }
   
    StatLineI("total packets","", pab->packets, pba->packets);
    if (pab->reset_count || pba->reset_count || csv || tsv || (sv != NULL))
	StatLineI("resets sent","", pab->reset_count, pba->reset_count);
    StatLineI("ack pkts sent","", pab->ack_pkts, pba->ack_pkts);
    StatLineI("pure acks sent","", pab->pureack_pkts, pba->pureack_pkts);
    StatLineI("sack pkts sent","", pab->num_sacks, pba->num_sacks);
    StatLineI("dsack pkts sent","", pab->num_dsacks, pba->num_dsacks);
    StatLineI("max sack blks/ack","", pab->max_sack_blocks, pba->max_sack_blocks);
    StatLineI("unique bytes sent","",
	      pab->unique_bytes, pba->unique_bytes);
    StatLineI("actual data pkts","", pab->data_pkts, pba->data_pkts);
    StatLineI("actual data bytes","", pab->data_bytes, pba->data_bytes);
    StatLineI("rexmt data pkts","", pab->rexmit_pkts, pba->rexmit_pkts);
    StatLineI("rexmt data bytes","",
	      pab->rexmit_bytes, pba->rexmit_bytes);
    StatLineI("zwnd probe pkts","", 
		  pab->num_zwnd_probes, pba->num_zwnd_probes);
    StatLineI("zwnd probe bytes","",
	      pab->zwnd_probe_bytes, pba->zwnd_probe_bytes);
    StatLineI("outoforder pkts","",
	      pab->out_order_pkts, pba->out_order_pkts);
    StatLineI("pushed data pkts","", pab->data_pkts_push, pba->data_pkts_push);
    StatLineP("SYN/FIN pkts sent","","%s",
	      (snprintf(bufl,sizeof(bufl),"%d/%d",
		       pab->syn_count, pab->fin_count),bufl),
	      (snprintf(bufr,sizeof(bufr),"%d/%d",
		       pba->syn_count, pba->fin_count),bufr));
    if (pab->f1323_ws || pba->f1323_ws || pab->f1323_ts || pba->f1323_ts || csv || tsv || (sv != NULL)) {
	StatLineP("req 1323 ws/ts","","%s",
		  (snprintf(bufl,sizeof(bufl),"%c/%c",
		      pab->f1323_ws?'Y':'N',pab->f1323_ts?'Y':'N'),bufl),
		  (snprintf(bufr,sizeof(bufr),"%c/%c",
		      pba->f1323_ws?'Y':'N',pba->f1323_ts?'Y':'N'),bufr));
    }
    if (pab->f1323_ws || pba->f1323_ws || csv || tsv || (sv != NULL)) {
	StatLineI("adv wind scale","",
		  (u_long)pab->window_scale, (u_long)pba->window_scale);
    }
    if (pab->fsack_req || pba->fsack_req || csv || tsv || (sv != NULL)) {
	StatLineP("req sack","","%s",
		  pab->fsack_req?"Y":"N",
		  pba->fsack_req?"Y":"N");
	StatLineI("sacks sent","",
		  pab->sacks_sent,
		  pba->sacks_sent);
    }
    StatLineI("urgent data pkts", "pkts",
	      pab->urg_data_pkts,
	      pba->urg_data_pkts);
    StatLineI("urgent data bytes", "bytes",
	      pab->urg_data_bytes,
	      pba->urg_data_bytes);
    StatLineI("mss requested","bytes", pab->mss, pba->mss);
    StatLineI("max segm size","bytes",
	      pab->max_seg_size,
	      pba->max_seg_size);
    StatLineI("min segm size","bytes",
	      pab->min_seg_size,
	      pba->min_seg_size);
    StatLineI("avg segm size","bytes",
	      (int)((double)pab->data_bytes / ((double)pab->data_pkts+.001)),
	      (int)((double)pba->data_bytes / ((double)pba->data_pkts+.001)));
    StatLineI("max win adv","bytes", pab->win_max, pba->win_max);
    StatLineI("min win adv","bytes", pab->win_min, pba->win_min);
    StatLineI("zero win adv","times",
	      pab->win_zero_ct, pba->win_zero_ct);
    // Average window advertisement is calculated only for window scaled pkts
    // if we have seen this connection using window scaling.
    // Otherwise, it is just the regular way of dividing the sum of 
    // all window advertisements by the total number of packets.
     
    if (pab->window_stats_updated_for_scaling &&
	pba->window_stats_updated_for_scaling)
	  StatLineI("avg win adv","bytes",
		    pab->win_scaled_pkts==0?0:
		    (pab->win_tot/pab->win_scaled_pkts),
		    pba->win_scaled_pkts==0?0:
		    (pba->win_tot/pba->win_scaled_pkts));
    else
	  StatLineI("avg win adv","bytes",
		    pab->packets==0?0:pab->win_tot/pab->packets,
		    pba->packets==0?0:pba->win_tot/pba->packets);
    if (print_owin) {
	StatLineI("max owin","bytes", pab->owin_max, pba->owin_max);
	StatLineI("min non-zero owin","bytes", pab->owin_min, pba->owin_min);
	StatLineI("avg owin","bytes",
		  pab->owin_count==0?0:pab->owin_tot/pab->owin_count,
		  pba->owin_count==0?0:pba->owin_tot/pba->owin_count);
	if (etime == 0.0) {
		StatLineP("wavg owin", "", "%s", "NA", "NA");	
	}
	else {
		StatLineI("wavg owin","bytes", 
			  (u_llong)(pab->owin_wavg/((double)etime/1000000)), 
		  	  (u_llong)(pba->owin_wavg/((double)etime/1000000)));
   	} 
    }
    StatLineI("initial window","bytes",
	      pab->initialwin_bytes, pba->initialwin_bytes);
    StatLineI("initial window","pkts",
	      pab->initialwin_segs, pba->initialwin_segs);

    /* compare to theoretical length of the stream (not just what
       we saw) using the SYN and FIN
     * Seq. Space wrap around calculations:
     * Calculate stream length using last_seq_num seen, first_seq_num
     * seen and wrap_count.
     * first_seq_num = syn
     * If reset_set, last_seq_num = latest_seq
     *          else last_seq_num = fin
     */
    
    pab_last = (pab->reset_count>0)?pab->latest_seq:pab->fin;
    
    pba_last = (pba->reset_count>0)?pba->latest_seq:pba->fin;
    
    /* calculating stream length for direction pab */
    if ((pab->syn_count > 0) && (pab->fin_count > 0)) {
	if (pab->seq_wrap_count > 0) {
	    if (pab_last > pab->syn) {
		stream_length_pab = pab_last + (MAX_32 * pab->seq_wrap_count) - pab->syn - 1;
	    }
	    else {
		stream_length_pab = pab_last + (MAX_32 * (pab->seq_wrap_count+1)) - pab->syn - 1;
	    }
	}
	else {
	    if (pab_last > pab->syn) {
		stream_length_pab = pab_last - pab->syn - 1;
	    }
	    else {
		stream_length_pab = MAX_32 + pab_last - pab->syn - 1;
	    }
	}
    }

    /* calculating stream length for direction pba */
    if ((pba->syn_count > 0) && (pba->fin_count > 0)) {
	if (pba->seq_wrap_count > 0) {
	    if (pba_last > pba->syn) {
		stream_length_pba = pba_last + (MAX_32 * pba->seq_wrap_count) - pba->syn - 1;
	    }
	    else {
		stream_length_pba = pba_last + (MAX_32 * (pba->seq_wrap_count+1)) - pba->syn - 1;
	    }
	}
	else {
	    if (pba_last > pba->syn) {
		stream_length_pba = pba_last - pba->syn - 1;
	    }
	    else {
		stream_length_pba = MAX_32 + pba_last - pba->syn - 1;
	    }
	}
    }

    /* print out values */
    if ((pab->fin_count > 0) && (pab->syn_count > 0)) {
	char *format = "%8" FS_ULL;
	StatLineFieldL("ttl stream length", "bytes", format, stream_length_pab, 0);
    }
    else {
	StatLineField("ttl stream length", "", "%s", (u_long)"NA", 0);
    }
    if ((pba->fin_count > 0) && (pba->syn_count > 0)) {
	char *format = "%8" FS_ULL;
	StatLineFieldL("ttl stream length", "bytes", format, stream_length_pba, 1);
    }
    else {
	StatLineField("ttl stream length", "", "%s", (u_long)"NA", 1);
    }

    if ((pab->fin_count > 0) && (pab->syn_count > 0)) {
	char *format = "%8" FS_ULL;
	StatLineFieldL("missed data", "bytes", format, (stream_length_pab - pab->unique_bytes), 0);
    }
    else {
	StatLineField("missed data", "", "%s", (u_long)"NA", 0);
    }
    if ((pba->fin_count > 0) && (pba->syn_count > 0)) {
	char *format = "%8" FS_ULL;
	StatLineFieldL("missed data", "bytes", format, (stream_length_pba - pba->unique_bytes), 1);
    }
    else {
	StatLineField("missed data", "", "%s", (u_long)"NA", 1);
    }
    
    /* tell how much data was NOT captured in the files */
    StatLineI("truncated data","bytes",
	      pab->trunc_bytes, pba->trunc_bytes);
    StatLineI("truncated packets","pkts",
	      pab->trunc_segs, pba->trunc_segs);

    /* stats on just the data */
    etime_data1 = elapsed(pab->first_data_time,
			  pab->last_data_time); /* in usecs */
    etime_data2 = elapsed(pba->first_data_time,
			  pba->last_data_time); /* in usecs */
    /* fix from Rob Austein */
    StatLineF("data xmit time","secs","%7.3f",
	      etime_data1 / 1000000.0,
	      etime_data2 / 1000000.0);
    StatLineP("idletime max","ms","%s",
	      ZERO_TIME(&pab->last_time)?"NA":
	      (snprintf(bufl,sizeof(bufl),"%8.1f",(double)pab->idle_max/1000.0),bufl),
	      ZERO_TIME(&pba->last_time)?"NA":
	      (snprintf(bufr,sizeof(bufr),"%8.1f",(double)pba->idle_max/1000.0),bufr));

    if ((pab->num_hardware_dups != 0) || (pba->num_hardware_dups != 0)  || csv || tsv || (sv != NULL)) {
	StatLineI("hardware dups","segs",
		  pab->num_hardware_dups, pba->num_hardware_dups);

        if(!(csv || tsv || (sv != NULL)))       
	  fprintf(stdout,
		  "       ** WARNING: presence of hardware duplicates makes these figures suspect!\n");
    }

    /* do the throughput calcs */
    etime /= 1000000.0;  /* convert to seconds */
    if (etime == 0.0)
	StatLineP("throughput","","%s","NA","NA");
    else
	StatLineF("throughput","Bps","%8.0f",
		  (double) (pab->unique_bytes) / etime,
		  (double) (pba->unique_bytes) / etime);

    if (print_rtt) {
        if(!(csv || tsv || (sv != NULL)))
	  fprintf(stdout,"\n");
	StatLineI("RTT samples","", pab->rtt_count, pba->rtt_count);
	StatLineF("RTT min","ms","%8.1f",
		  (double)pab->rtt_min/1000.0,
		  (double)pba->rtt_min/1000.0);
	StatLineF("RTT max","ms","%8.1f",
		  (double)pab->rtt_max/1000.0,
		  (double)pba->rtt_max/1000.0);
	StatLineF("RTT avg","ms","%8.1f",
		  Average(pab->rtt_sum, pab->rtt_count) / 1000.0,
		  Average(pba->rtt_sum, pba->rtt_count) / 1000.0);
	StatLineF("RTT stdev","ms","%8.1f",
		  Stdev(pab->rtt_sum, pab->rtt_sum2, pab->rtt_count) / 1000.0,
		  Stdev(pba->rtt_sum, pba->rtt_sum2, pba->rtt_count) / 1000.0);
        if(!(csv || tsv || (sv != NULL)))
	  fprintf(stdout,"\n");
	StatLineF("RTT from 3WHS","ms","%8.1f",
		  (double)pab->rtt_3WHS/1000.0,
		  (double)pba->rtt_3WHS/1000.0);
        if(!(csv || tsv || (sv != NULL)))
	  fprintf(stdout,"\n");
	StatLineI("RTT full_sz smpls","", 
		  pab->rtt_full_count, pba->rtt_full_count);
	StatLineF("RTT full_sz min","ms","%8.1f",
		  (double)pab->rtt_full_min/1000.0,
		  (double)pba->rtt_full_min/1000.0);
	StatLineF("RTT full_sz max","ms","%8.1f",
		  (double)pab->rtt_full_max/1000.0,
		  (double)pba->rtt_full_max/1000.0);
	StatLineF("RTT full_sz avg","ms","%8.1f",
		  Average(pab->rtt_full_sum, pab->rtt_full_count) / 1000.0,
		  Average(pba->rtt_full_sum, pba->rtt_full_count) / 1000.0);
	StatLineF("RTT full_sz stdev","ms","%8.1f",
		  Stdev(pab->rtt_full_sum, pab->rtt_full_sum2, pab->rtt_full_count) / 1000.0,
		  Stdev(pba->rtt_full_sum, pba->rtt_full_sum2, pba->rtt_full_count) / 1000.0);
        if(!(csv || tsv || (sv != NULL)))
	  fprintf(stdout,"\n");
	StatLineI("post-loss acks","",
		  pab->rtt_nosample, pba->rtt_nosample);
	if (pab->rtt_amback || pba->rtt_amback || csv || tsv || (sv != NULL)) {
	   if(!(csv || tsv || (sv != NULL)))
	     fprintf(stdout, "\
\t  For the following 5 RTT statistics, only ACKs for\n\
\t  multiply-transmitted segments (ambiguous ACKs) were\n\
\t  considered.  Times are taken from the last instance\n\
\t  of a segment.\n\
");
	    StatLineI("ambiguous acks","",
		      pab->rtt_amback, pba->rtt_amback);
	    StatLineF("RTT min (last)","ms","%8.1f",
		      (double)pab->rtt_min_last/1000.0,
		      (double)pba->rtt_min_last/1000.0);
	    StatLineF("RTT max (last)","ms","%8.1f",
		      (double)pab->rtt_max_last/1000.0,
		      (double)pba->rtt_max_last/1000.0);
	    StatLineF("RTT avg (last)","ms","%8.1f",
		      Average(pab->rtt_sum_last, pab->rtt_count_last) / 1000.0,
		      Average(pba->rtt_sum_last, pba->rtt_count_last) / 1000.0);
	    StatLineF("RTT sdv (last)","ms","%8.1f",
		      Stdev(pab->rtt_sum_last, pab->rtt_sum2_last, pab->rtt_count_last) / 1000.0,
		      Stdev(pba->rtt_sum_last, pba->rtt_sum2_last, pba->rtt_count_last) / 1000.0);

	}
	StatLineI("segs cum acked","",
		  pab->rtt_cumack, pba->rtt_cumack);
	StatLineI("duplicate acks","",
		  pab->rtt_dupack, pba->rtt_dupack);
	StatLineI("triple dupacks","",
		  pab->rtt_triple_dupack, pba->rtt_triple_dupack);
	if (debug)
	    StatLineI("unknown acks:","",
		      pab->rtt_unkack, pba->rtt_unkack);
	StatLineI("max # retrans","",
		  pab->retr_max, pba->retr_max);
	StatLineF("min retr time","ms","%8.1f",
		  (double)((double)pab->retr_min_tm/1000.0),
		  (double)((double)pba->retr_min_tm/1000.0));
	StatLineF("max retr time","ms","%8.1f",
		  (double)((double)pab->retr_max_tm/1000.0),
		  (double)((double)pba->retr_max_tm/1000.0));
	StatLineF("avg retr time","ms","%8.1f",
		  Average(pab->retr_tm_sum, pab->retr_tm_count) / 1000.0,
		  Average(pba->retr_tm_sum, pba->retr_tm_count) / 1000.0);
	StatLineF("sdv retr time","ms","%8.1f",
		  Stdev(pab->retr_tm_sum, pab->retr_tm_sum2,
			pab->retr_tm_count) / 1000.0,
		  Stdev(pba->retr_tm_sum, pba->retr_tm_sum2,
			pba->retr_tm_count) / 1000.0);
    }
   
   if(csv || tsv || (sv != NULL)) {
      printf("\n");
      /* Error checking: print an error message if the count of printed fields
       * doesn't correspond to the actual fields expected.
       */
      if(sv_print_count != sv_expected_count) {
	fprintf(stderr, "output.c: Count of printed fields does not correspond to count of header fields for long output with comma/tab/<SP>-separated values.\n");
	fprintf(stderr,"sv_print_count=%u, sv_expected_count=%u\n",
		sv_print_count, sv_expected_count);
	exit(-1);
      }
   }
}
示例#3
0
void
rules_test (tcb * thisdir, segment * pseg, seglen len, quadrant * pquad,
            u_short this_ip_id, Bool pkt_already_seen, double recovery_time)
{
  double DeltaT2, RTO, Mean_RTT, RTT_min;
  char type_of_segment =
    real_rules_test (thisdir, pseg, len, pquad, this_ip_id, pkt_already_seen,
                     &recovery_time);
  tcb *otherdir;
  int dir, num_acked;
#ifdef LOG_OOO
  extern FILE *fp_dup_ooo_log;
#endif

  if (pkt_already_seen)
    {
      pseg->type_of_segment = type_of_segment;
      num_acked = (pseg->prev != NULL) ? pseg->prev->acked : 0;
    }
  else
    {
      pseg->prev->type_of_segment = type_of_segment;
      num_acked = (pseg->prev->prev != NULL) ? pseg->prev->prev->acked : 0;
    }
  /* LM added */

  dir = (&(thisdir->ptp->c2s)) == thisdir;
  otherdir = (dir == C2S) ? &(thisdir->ptp->s2c) : &(thisdir->ptp->c2s);

  DeltaT2 =
    time2double (current_time) - time2double (pquad->seglist_tail->time);

  Mean_RTT =
    Average (thisdir->rtt_sum,
             thisdir->rtt_count) + Average (otherdir->rtt_sum,
                                            otherdir->rtt_count);
  RTO =
    Mean_RTT +
    4 *
    (Stdev
     (thisdir->rtt_sum + otherdir->rtt_sum,
      thisdir->rtt_sum2 + otherdir->rtt_sum2,
      thisdir->rtt_count + otherdir->rtt_count));

  RTT_min = (double) (thisdir->rtt_min + otherdir->rtt_min);

#ifdef LOG_OOO
  if (type_of_segment != 0)
    {
      wfprintf (fp_dup_ooo_log, "T: %f ",
               (elapsed (first_packet, current_time) / 1000.0));
      if (dir == C2S)
        {
          wfprintf (fp_dup_ooo_log, "%s %s ",
                   HostName (thisdir->ptp->addr_pair.a_address),
                   ServiceName (thisdir->ptp->addr_pair.a_port));
          wfprintf (fp_dup_ooo_log, "%s %s ",
                   HostName (thisdir->ptp->addr_pair.b_address),
                   ServiceName (thisdir->ptp->addr_pair.b_port));
        }
      else
        {
          wfprintf (fp_dup_ooo_log, "%s %s ",
                   HostName (thisdir->ptp->addr_pair.b_address),
                   ServiceName (thisdir->ptp->addr_pair.b_port));
          wfprintf (fp_dup_ooo_log, "%s %s ",
                   HostName (thisdir->ptp->addr_pair.a_address),
                   ServiceName (thisdir->ptp->addr_pair.a_port));
        }

      wfprintf (fp_dup_ooo_log,
               "%lu %lu %d %d %u %d %u %d %lf %lf %lu %lf %lf %lf %d",
               thisdir->data_pkts,
               thisdir->data_bytes,
               (type_of_segment & 15),
               thisdir->fsack_req && otherdir->fsack_req,
               thisdir->mss,
               (dir == C2S),
               (internal_dst),
               thisdir->initialwin_bytes,
               recovery_time / 1000.0,
               DeltaT2 / 1000.0,
               len, RTO / 1000.0, RTT_min / 1000.0, Mean_RTT / 1000.0,
               num_acked);
      wfprintf (fp_dup_ooo_log, " %f %f %f %f\n", thisdir->srtt / 1000.0,
               thisdir->rttvar / 1000.0, otherdir->srtt / 1000.0,
               otherdir->rttvar / 1000.0);
    }

#endif

  if (internal_src && !internal_dst)
    {
      add_histo (tcp_anomalies_out, aggregateType (type_of_segment));
    }
  else if (!internal_src && internal_dst)
    {
      add_histo (tcp_anomalies_in, aggregateType (type_of_segment));
    }
#ifndef LOG_UNKNOWN
  else if (internal_src && internal_dst)
#else
  else
#endif
    {
      add_histo (tcp_anomalies_loc, aggregateType (type_of_segment));
    }
  if (dir == C2S)
    {
      add_histo (tcp_anomalies_c2s, aggregateType (type_of_segment));
    }
  else
    {
      add_histo (tcp_anomalies_s2c, aggregateType (type_of_segment));
    }

/* just keep the main classification  and discard bit larger than
   BATCH_CLASSIFICATION*/
  switch (type_of_segment & (BATCH_CLASSIFICATION - 1))
    {
    case IN_SEQUENCE:
      /* just ignore them */
      break;
    case RETRANSMISSION_RTO:
      thisdir->rtx_RTO++;
      break;
    case RETRANSMISSION_FR:
      thisdir->rtx_FR++;
      break;
    case REORDERING:
      thisdir->reordering++;
      break;
    case NETWORK_DUPLICATE:
      thisdir->net_dup++;
      break;
    case FLOW_CONTROL:
      thisdir->flow_control++;
      break;
    case UNNECESSARY_RETRANSMISSION_FR:
      thisdir->unnecessary_rtx_FR++;
      break;
    case UNNECESSARY_RETRANSMISSION_RTO:
      thisdir->unnecessary_rtx_RTO++;
      break;
    default:
      thisdir->unknown++;
    }
}
示例#4
0
 /* LM start - Rule number one
  ** R1.a IP_id_new not equal to IP_id_old
  ** R1.b this_seg_time-prev_seg_time >
  ** R1.c number of acks > 3 (or max number permitted)
  ** DeltaT1: Time between current segment and the last segment before a ooo
  ** DeltaT2: Time between current segment and the received segment with the maximum sequence number
  */
char
real_rules_test (tcb * thisdir, segment * pseg, seglen len, quadrant * pquad,
                 u_short this_ip_id, Bool pkt_already_seen,
                 double *recovery_time)
{
  double RTO, RTT, Mean_RTT;
  int Rule1a, Rule1b, Rule1d;
  int Rule2b, Rule2c;
  int RuleProbing;
  tcb *otherdir;
  char prev_tos;
  int validRTT;

  int dir = (&(thisdir->ptp->c2s) == thisdir);

  otherdir = (dir == C2S) ? &(thisdir->ptp->s2c) : &(thisdir->ptp->c2s);
  Mean_RTT =
    Average (thisdir->rtt_sum,
             thisdir->rtt_count) + Average (otherdir->rtt_sum,
                                            otherdir->rtt_count);
  RTO =
    Mean_RTT +
    4 *
    (Stdev
     (thisdir->rtt_sum + otherdir->rtt_sum,
      thisdir->rtt_sum2 + otherdir->rtt_sum2,
      thisdir->rtt_count + otherdir->rtt_count));
  RTT = (double) (thisdir->rtt_min + otherdir->rtt_min);
  validRTT = (thisdir->rtt_count != 0 && otherdir->rtt_count != 0);

  if (RTO < RTO_MIN)
    RTO = RTO_MIN;
  if (RTT < RTT_MIN)
    RTT = RTT_MIN;

  if (!pkt_already_seen)        /* if pkt_already_seen then *recovery_time is passed otherwise it is set below */
    *recovery_time =
      (pseg->prev->prev !=
       NULL) ? time2double (current_time) -
      time2double (pseg->prev->prev->time) : -1.0;
  /* take the previous packet classification */

  if (pseg->prev != NULL)
    {
      if (pkt_already_seen)
        prev_tos = pseg->prev->type_of_segment;
      else
        prev_tos =
          (pseg->prev->prev !=
           NULL) ? pseg->prev->prev->type_of_segment : IN_SEQUENCE;
    }
  else
    prev_tos = IN_SEQUENCE;

  if (!validRTT)
    {
      RTT = INITIAL_RTT_MIN;
      RTO = INITIAL_RTO;
      /* if *recovery_time is -1 then this is the first packet and use next segment as recovery time */
      if (*recovery_time == -1.0)
        *recovery_time =
          time2double (current_time) - time2double (pseg->time);
    }

  Rule1a = (pseg->ip_id != this_ip_id);
  Rule1b = (*recovery_time > RTO);
  Rule1d = (*recovery_time < Mean_RTT);
  if (pkt_already_seen)
    Rule2b = (pseg->prev != NULL) ? (pseg->prev->acked > 3
                                     && *recovery_time < RTO) : 0;
  else
    Rule2b = (pseg->prev->prev != NULL) ? (pseg->prev->prev->acked > 3
                                           && *recovery_time < RTO) : 0;

  Rule2c = (time2double (current_time) - time2double (pseg->time) < RTT);

  RuleProbing = ((len == 1) && (otherdir->win_curr == 0)
                 && (thisdir->syn_count != 0) && (otherdir->syn_count != 0));

  if (RuleProbing)
    return FLOW_CONTROL;
  if (Rule1d && prev_tos != IN_SEQUENCE)
    return (prev_tos | BATCH_CLASSIFICATION);   /* Old Classification with the first bit is 1 */


  if (!pseg->acked)
    {
      if (pkt_already_seen)
        {
          if (!Rule1a)
            return CLASSIFICATION (NETWORK_DUPLICATE);
          if (Rule1a && (Rule1b || Rule2b))
            return CLASSIFICATION (Rule2b ? RETRANSMISSION_FR :
                                   RETRANSMISSION_RTO);
          if (Rule1d)
            return
              CLASSIFICATION (DUPLICATE_WITH_RC_LESS_THAN_RTT_NOT_3DUP_ACK);
          if (!Rule1b)
            return
              CLASSIFICATION
              (DUPLICATE_WITH_RC_LESS_THAN_RTO_AND_GREATER_THAN_RTT_NOT_3DUP_ACK);
          return CLASSIFICATION (UNKNOWN);
        }

      if (Rule1b || Rule2b)
        return CLASSIFICATION (Rule2b ? RETRANSMISSION_FR :
                               RETRANSMISSION_RTO);
      if (Rule2c)
        return CLASSIFICATION (REORDERING);
      if (Rule1d)
        return CLASSIFICATION (OOO_WITH_RC_LESS_THAN_RTT_NOT_3DUP_ACK);
      if (!Rule1b)
        return
          CLASSIFICATION
          (OOO_WITH_RC_LESS_THAN_RTO_AND_GREATER_THAN_RTT_NOT_3DUP_ACK);
      return CLASSIFICATION (UNKNOWN);

    }

  if (!Rule1a)
    return CLASSIFICATION (NETWORK_DUPLICATE);
  if ((Rule1b || Rule2b))
    return CLASSIFICATION (Rule2b ? UNNECESSARY_RETRANSMISSION_FR :
                           UNNECESSARY_RETRANSMISSION_RTO);
  if (Rule1d)
    return
      CLASSIFICATION
      (UNNECESSARY_RETRANSMISSION_WITH_RC_LESS_THAN_RTT_NOT_3DUP_ACK);
  if (!Rule1b)
    return
      CLASSIFICATION
      (UNNECESSARY_RETRANSMISSION_WITH_RC_LESS_THAN_RTO_AND_GREATER_THAN_RTT_NOT_3DUP_ACK);
  return CLASSIFICATION (UNKNOWN);
}