Beispiel #1
0
static int
addseg (tcptrace_context_t *context,
        tcb * ptcb,
	quadrant * pquad,
	seqnum thisseg_firstbyte,
	seglen len,
	Bool * pout_order)
{
    seqnum thisseg_lastbyte = thisseg_firstbyte + len - 1;
    segment *pseg;
    segment *pseg_new;
    int rexlen = 0;
    Bool split = FALSE;

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

    /* (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(context, thisseg_firstbyte, len);
	    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 */
		return (rexlen);
	    } else {
		/* overlap him, split myself in 2 */

		/* adjust new piece to mate with old piece */
		pseg_new->seq_lastbyte = pseg->seq_firstbyte - 1;

		/* pretend to be just the second half of this segment */
		pseg_new->seq_lastbyte = pseg->seq_firstbyte - 1;
		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;
	    if (!split) {
                /* must be a retransmission */
		rtt_retrans(context, ptcb, pseg);
            }

	    if (thisseg_lastbyte <= pseg->seq_lastbyte) {
		/* entirely contained within this sequence */
		rexlen += len;
		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;
	    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(context, thisseg_firstbyte, len);
    insert_seg_between (pquad, pseg_new, pquad->seglist_tail, NULL);

    return (rexlen);
}
Beispiel #2
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);
}