Esempio n. 1
0
int main(int argc, char **argv) {
  struct timeval start, end;
  char *mem;
  double t, at, mb, tbytes;
  int64_t megs, iter, bytes, i, j, c, adjtime = 0;
  uint8_t b;
  uint32_t x;
  uint64_t llx;
  struct bigbit bbx;

  volatile uint8_t *m;
  volatile uint32_t *lm;
  volatile uint64_t *llm;
  volatile struct bigbit *bbm;

  setvbuf(stdout, (char *)NULL, _IONBF, 0);

  if (argc < 2) {
    fprintf(stderr, "usage: memspeed [-a] <megs of memory to allocate>\n");
    return 1;
  }
  i = 1;
  if (!strcmp(argv[i], "-a")) {
    adjtime = 1;
    i++;
  }

  megs = atoi(argv[i]);
  iter = 8192 / megs;
  mb = iter * megs;
  bytes = megs * 1024 * 1024;
  tbytes = (double)bytes * (double)iter;

  mem = malloc(bytes + 4);
  if (mem == NULL) {
    fprintf(stderr, "memspeed: memory allocation.\n");
    return 1;
  }

  /* init memory to reduce cache effects for inital test */
  printf("Initializing...");
  memset(mem, 0, bytes);
  if (adjtime) {
    gettimeofday(&start, NULL);
    for (i = 0; i < iter; i++)
      for (m = mem, j = bytes; j; j--) m++;
    gettimeofday(&end, NULL);
    at = time2double(start, end);
  }

  printf(
      "\r Tests iterate over %dMB, %d times for a simulated total of "
      "%.0fMB\n\n",
      megs, iter, mb);

//  goto three;

one:
  /* Test one: read bytes at a time. */
  printf("Test  1: reading bytes         : ");

  gettimeofday(&start, NULL);
  for (i = 0; i < iter; i++) {
    for (m = mem, j = bytes; j; j--) b = *m++;
  }
  gettimeofday(&end, NULL);
  t = time2double(start, end);
  if (adjtime) t -= at;

  printf("%5.2f seconds, %7.2f MB/s\n", t, mb / t);

two:
  /* Test two: write bytes at a time. */
  printf("Test  2: writing bytes         : ");

  gettimeofday(&start, NULL);
  for (i = 0; i < iter; i++) {
    for (m = mem, j = bytes; j; j--) *m++ = 0;
  }
  gettimeofday(&end, NULL);
  t = time2double(start, end);
  if (adjtime) t -= at;

  printf("%5.2f seconds, %7.2f MB/s\n", t, mb / t);

three:
  /* Test three: read 32 bit longs at a time. */
  printf("Test  3: reading %d bit longs  : ", sizeof(uint32_t) * 8);

  gettimeofday(&start, NULL);
  for (i = 0; i < iter; i++) {
    for (lm = (uint32_t *)mem, j = bytes / sizeof(uint32_t); j; j--) x = *lm++;
  }
  gettimeofday(&end, NULL);
  x++;
  t = time2double(start, end);
  if (adjtime) t -= (at / (double)sizeof(uint32_t));

  printf("%5.2f seconds, %7.2f MB/s\n", t, mb / t);

four:
  /* Test four: write 32 bit longs at a time. */
  printf("Test  4: writing %d bit longs  : ", sizeof(uint32_t) * 8);

  gettimeofday(&start, NULL);
  for (i = 0; i < iter; i++) {
    for (lm = (uint32_t *)mem, j = bytes / sizeof(uint32_t); j; j--)
      *lm++ = (uint32_t)0;
  }
  gettimeofday(&end, NULL);
  t = time2double(start, end);
  if (adjtime) t -= (at / (double)sizeof(uint32_t));

  printf("%5.2f seconds, %7.2f MB/s\n", t, mb / t);

five:
  /* Test five: read 64 bit longs at a time. */
  printf("Test  5: reading %d bit longs  : ", sizeof(uint64_t) * 8);

  gettimeofday(&start, NULL);
  for (i = 0; i < iter; i++) {
    for (llm = (uint64_t *)mem, j = bytes / sizeof(uint64_t); j; j--)
      llx = *llm++;
  }
  gettimeofday(&end, NULL);
  t = time2double(start, end);
  if (adjtime) t -= (at / (double)sizeof(uint64_t));

  printf("%5.2f seconds, %7.2f MB/s\n", t, mb / t);

six:
  /* Test six: write 64 bit longs at a time. */
  printf("Test  6: writing 64 bit longs  : ", sizeof(uint64_t) * 8);

  gettimeofday(&start, NULL);
  for (i = 0; i < iter; i++) {
    for (llm = (uint64_t *)mem, j = bytes / sizeof(uint64_t); j; j--)
      *llm++ = 0L;
  }
  gettimeofday(&end, NULL);
  t = time2double(start, end);
  if (adjtime) t -= (at / (double)sizeof(uint64_t));

  printf("%5.2f seconds, %7.2f MB/s\n", t, mb / t);

seven:
  /* Test seven: read 256 bit struct at a time. */
  printf("Test  7: reading %d bit struct: ", sizeof(struct bigbit) * 8);

  gettimeofday(&start, NULL);
  for (i = 0; i < iter; i++) {
    for (bbm = (struct bigbit *)mem, j = bytes / sizeof(struct bigbit); j; j--)
      bbx = *bbm++;
  }
  gettimeofday(&end, NULL);
  t = time2double(start, end);
  if (adjtime) t -= (at / (double)sizeof(struct bigbit));

  printf("%5.2f seconds, %7.2f MB/s\n", t, mb / t);

eight:
  /* Test eight: write 256 bit struct at a time. */
  printf("Test  8: writing %d bit struct: ", sizeof(struct bigbit) * 8);

  gettimeofday(&start, NULL);
  for (i = 0; i < iter; i++) {
    for (bbm = (struct bigbit *)mem, j = bytes / sizeof(struct bigbit); j; j--)
      *bbm++ = bbx;
  }
  gettimeofday(&end, NULL);
  t = time2double(start, end);
  if (adjtime) t -= (at / (double)sizeof(struct bigbit));

  printf("%5.2f seconds, %7.2f MB/s\n", t, mb / t);

nine:
  /* Test eight: read 256 bit struct with memcpy() */
  printf("Test  9: reading with memcpy() : ");

  gettimeofday(&start, NULL);
  for (i = 0; i < iter; i++) {
    for (bbm = (struct bigbit *)mem, j = bytes / sizeof(struct bigbit); j;
         j--, bbm++)
      memcpy((void *)&bbx, (void *)bbm, sizeof(bbx));
  }
  gettimeofday(&end, NULL);
  t = time2double(start, end);
  if (adjtime) t -= (at / (double)sizeof(struct bigbit));

  printf("%5.2f seconds, %7.2f MB/s\n", t, mb / t);

ten:
  /* Test nine: write with memset at a time. */
  printf("Test 10: writing with memset() : ");

  gettimeofday(&start, NULL);
  for (i = 0; i < iter; i++) {
    memset(mem, 0, bytes);
  }
  gettimeofday(&end, NULL);
  t = time2double(start, end);

  printf("%5.2f seconds, %7.2f MB/s\n", t, mb / t);

eleven:
  /* Test eight: copy with memcpy() */
  printf("Test 11: copying with memcpy() : ");

  x = bytes / 2;

  gettimeofday(&start, NULL);
  for (i = 0; i < iter; i++) {
    memcpy(mem + x, mem, x);
    memcpy(mem, mem + x, x);
  }
  gettimeofday(&end, NULL);
  t = time2double(start, end);

  printf("%5.2f seconds, %7.2f MB/s\n", t, mb / t);

  return 0;
}
Esempio n. 2
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);
}
Esempio n. 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++;
    }
}
Esempio n. 4
0
static int
addseg (tcb * ptcb,
        quadrant * pquad,
        seqnum thisseg_firstbyte, seglen len, Bool * pout_order,
        u_short this_ip_id)
{
  seqnum thisseg_lastbyte = thisseg_firstbyte + len - 1;
  segment *pseg;
  segment *pseg_new;
  int rexlen = 0;
  Bool split = FALSE;
  double recovery_time = 0;

  /* check each segment in the segment list */
  pseg = pquad->seglist_head;

  /* LM - all the segments are memorized in the seglist
     Here has been implemented the heuristic discussed in
     S. Jaiswal, G.Iannaccone, C. Diot, J.F. Kurose, D.Towsley
     Measurement and Classification of Out-of-Sequence Packets in a Tier-1 IP Backbone
     INFOCOM 2003 http://www.ieee-infocom.org/2003/technical_programs.htm
   */

  /* (optimize expected case, it just goes at the end) */
  if (pquad->seglist_tail &&
      (thisseg_firstbyte > pquad->seglist_tail->seq_lastbyte))
    pseg = NULL;
  for (; pseg != NULL; pseg = pseg->next)
    {

      if (thisseg_firstbyte > pseg->seq_lastbyte)
        {
          /* goes beyond this one */
          continue;
        }

      if (thisseg_firstbyte < pseg->seq_firstbyte)
        {
          /* starts BEFORE this recorded segment */

          /* if it also FINISHES before this segment, then it's */
          /* out of order (otherwise it's a resend the collapsed */
          /* multiple segments into one */
          if (thisseg_lastbyte < pseg->seq_lastbyte)
            *pout_order = TRUE;

          /* make a new segment record for it */
          pseg_new = create_seg (thisseg_firstbyte, len, this_ip_id);
          insert_seg_between (pquad, pseg_new, pseg->prev, pseg);

          /* see if we overlap the next segment in the list */
          if (thisseg_lastbyte <= pseg->seq_firstbyte)
            {
              /* we don't overlap, so we're done */
              // LM start
              rules_test (ptcb, pseg, len, pquad, this_ip_id, FALSE,
                          recovery_time);
              return (rexlen);
            }
          else
            {
              /* overlap him, split myself in 2 */
              //fprintf(fp_stdout, "split %lu %lu\n",
          //    len,  pseg_new->seq_lastbyte-pseg_new->seq_firstbyte);
              /* adjust new piece to mate with old piece */
              pseg_new->seq_lastbyte = pseg->seq_firstbyte - 1;

              // LM start
              rules_test (ptcb, pseg,
                          pseg_new->seq_lastbyte - pseg_new->seq_firstbyte,
                          pquad, this_ip_id, FALSE, recovery_time);

              /* pretend to be just the second half of this segment */
              thisseg_firstbyte = pseg->seq_firstbyte;
              len = thisseg_lastbyte - thisseg_firstbyte + 1;

              /* fall through */
            }
        }

      /* no ELSE, we might have fallen through */
      if (thisseg_firstbyte >= pseg->seq_firstbyte)
        {
          /* starts within this recorded sequence */
          ++pseg->retrans;
          recovery_time =
            time2double (current_time) - time2double (pseg->time);
          if (!split)
            rtt_retrans (ptcb, pseg);   /* must be a retransmission */
          if (thisseg_lastbyte <= pseg->seq_lastbyte)
            {
              /* entirely contained within this sequence */
              rexlen += len;
              // LM start
              rules_test (ptcb, pseg, len, pquad, this_ip_id, TRUE,
                          recovery_time);

              return (rexlen);
            }
          /* else */
          /* we extend beyond this sequence, split ourself in 2 */
          /* (pretend to be just the second half of this segment) */
          split = TRUE;
          rexlen += pseg->seq_lastbyte - thisseg_firstbyte + 1;
          thisseg_firstbyte = pseg->seq_lastbyte + 1;

          // LM start
          rules_test (ptcb, pseg, rexlen, pquad, this_ip_id, TRUE,
                      recovery_time);
          len = thisseg_lastbyte - thisseg_firstbyte + 1;
        }
    }
  /* if we got to the end, then it doesn't go BEFORE anybody, */
  /* tack it onto the end */

  pseg_new = create_seg (thisseg_firstbyte, len, this_ip_id);
  insert_seg_between (pquad, pseg_new, pquad->seglist_tail, NULL);

  /* MGM - management of the number of segments within this quadrant */

  if (pquad->no_of_segments > MAX_SEG_PER_QUAD)
    {
      /* free up the first segment in this quadrant */
      segment *tmp_pseg = pquad->seglist_head;

      /* rebuild the list */
      if (tmp_pseg->next != NULL)
        tmp_pseg->next->prev = tmp_pseg->prev;
      pquad->seglist_head = tmp_pseg->next;
      /* recall the initial segment byte */
      pquad->seglist_head->seq_firstbyte = tmp_pseg->seq_firstbyte;

      /* remove the segment */
      segment_release (tmp_pseg);
      pquad->no_of_segments--;
    }


  pseg_new->type_of_segment = IN_SEQUENCE;
  /* LM : This is an IN_SEQUENCE segment */
  if (internal_src && !internal_dst)
    {
      add_histo (tcp_anomalies_out, IN_SEQUENCE);
    }
  else if (!internal_src && internal_dst)
    {
      add_histo (tcp_anomalies_in, IN_SEQUENCE);
    }
#ifndef LOG_UNKNOWN
  else if (internal_src && internal_dst)
#else
  else
#endif
    {
      add_histo (tcp_anomalies_loc, IN_SEQUENCE);
    }

  if ((&(ptcb->ptp->c2s)) == ptcb)      //(dir == C2S)
    {
      add_histo (tcp_anomalies_c2s, IN_SEQUENCE);
    }
  else
    {
      add_histo (tcp_anomalies_s2c, IN_SEQUENCE);
    }
  return (rexlen);
}