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); }
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); }