예제 #1
0
/* Insertion sort of the packet in the buffer using its seqnum */
void insert_descending_order(struct tcp_buf *tcp_buffer, struct ofpbuf *pkt){
    int i, index;
    uint32_t seq_buf, seq_new;

    index = 0;
    if(tcp_buffer->inserted_items == 0){
        tcp_buffer->buffer[0] = pkt;
    }
    else{
        seq_buf = get_tcp_seq(tcp_buffer->buffer[index]);
        seq_new = get_tcp_seq(pkt);
        // Find the correct position for the item
        while((seq_new <= seq_buf) && (index<tcp_buffer->inserted_items)){
            index++;
            if(seq_new == seq_buf){
                tcp_buffer->expected_seqnum = get_next_seqnum(tcp_buffer, seq_new, pkt, false);
            } 
            if(tcp_buffer->buffer[index]){
                seq_buf = get_tcp_seq(tcp_buffer->buffer[index]);
            }
        }
        // Shift the elements to the right
        for(i=tcp_buffer->inserted_items;i>index;i--){
            tcp_buffer->buffer[i] = tcp_buffer->buffer[i-1];
        }
        tcp_buffer->buffer[index] = pkt;
    }

    tcp_buffer->inserted_items++;
    tcp_buffer->consecutive_buffering_events++;
}
예제 #2
0
void Packet::print()
{
   uint32_t tsval, tsecr;
   char sip_str[INET_ADDRSTRLEN];
   char dip_str[INET_ADDRSTRLEN];

   inet_ntop(AF_INET, &ip_hdr->ip_src.s_addr, sip_str, INET_ADDRSTRLEN);
   inet_ntop(AF_INET, &ip_hdr->ip_dst.s_addr, dip_str, INET_ADDRSTRLEN);

   get_tcp_ts(&tsval,&tsecr);
   switch(get_ip_protocol()) 
   {
      case IPPROTO_TCP:
	 std::cout << "TCP packet: "
	      << "[" << get_ts().tv_sec << "." << std::setw(9) << std::setfill('0') << get_ts().tv_nsec << "] ["
	      << sip_str << ":" << get_tcp_sport() << "->"
	      << dip_str << ":" << get_tcp_dport() << "] "
	      << "[S:" << get_tcp_seq() << "] "
	      << "[A:" << get_tcp_ack() << "] "
	      << "[L:" << get_tcp_payload_len() << "] "
	      << "[M:" << get_tcp_mss() << "] "
	      << "[TV:" << tsval << "] "
	      << "[TE:" << tsecr << "]"
	      << std::endl << std::flush;
	 break;
      case IPPROTO_ICMP:
	 std::cout << "ICMP packet: ["
	      << sip_str << "->"
	      << dip_str << "] " 
	      << "[TTL:" << get_ip_ttl() << "]"
	      << std::endl << std::flush;
	 break;
      default:
	 std::cout << "Unknown packet!" << std::endl << std::flush;
	 break;
   }
}
예제 #3
0
int get_packet_list(struct ofpbuf *out_packets[], struct ofpbuf * packet, uint32_t flow_id, uint32_t in_port){

    struct tcp_buf * tcp_buf;    
    uint8_t tcp_flags;
    struct tcp_header *tcp;
    uint32_t seq;
    int i, out_packets_count;
    uint32_t seq_work;
    struct ofpbuf * buf_pkt;
    int removed_items;


    // Getting the buffer for the flow, or creating a new one if 
    // not existing
    tcp_buf = get_tcp_buf(flow_id);

    tcp = ofpbuf_l4(packet);
    tcp_flags = TCP_FLAGS(tcp->tcp_ctl);    
    seq = get_tcp_seq(packet);

    out_packets_count = 0;


    if (tcp_flags & TCP_SYN){
        tcp_buf->expected_seqnum = seq+1;
        VLOG_INFO("[SYN packet] sequence: %" PRIu32 " expected: %" PRIu32 " in_port: %"PRIu32 "  size: %d",
            seq, tcp_buf->expected_seqnum, in_port, tcp_buf->inserted_items);
        out_packets[out_packets_count] = packet;
        out_packets_count++;
    }
    else if(tcp_buf->fin_state){
        delete_tcp_buf(tcp_buf);
        out_packets[out_packets_count] = packet;
        out_packets_count++;
    }
    // Retransmission or packets which come without a SYN or after a FIN
    // Just send out
    else if(tcp_buf->expected_seqnum == -1){
        out_packets[out_packets_count] = packet;
        out_packets_count++;
    }
    // Sending out and checking if the the gap in the reordering buffer has been filled
    else if(seq <= tcp_buf->expected_seqnum){
        VLOG_INFO("[sending in order packet] seq: %"PRIu32 " expected: %" PRIu32 " in_port: %"PRIu32 " size: %d",
            seq, tcp_buf->expected_seqnum, in_port, tcp_buf->inserted_items);

        out_packets[out_packets_count] = packet;
        out_packets_count++;
        tcp_buf->consecutive_buffering_events = 0;

        // Increasing sequence only if it matches
        if(seq == tcp_buf->expected_seqnum){
            tcp_buf->expected_seqnum = get_next_seqnum(tcp_buf, tcp_buf->expected_seqnum, packet, false);
        }

        // Check if there are packets waiting to be sent
        removed_items = 0;
        for(i=tcp_buf->inserted_items-1;i>= 0;i--){
            seq_work = get_tcp_seq(tcp_buf->buffer[i]);

            if(seq_work <= tcp_buf->expected_seqnum){
                VLOG_INFO("[sending out from buffer] sequence: %" PRIu32 " expected: %" PRIu32 " size: %d",
                    seq_work, tcp_buf->expected_seqnum, tcp_buf->inserted_items - removed_items);
                removed_items++;            
                out_packets[out_packets_count] = tcp_buf->buffer[i];
                out_packets_count++;
                if(seq_work == tcp_buf->expected_seqnum){
                    tcp_buf->expected_seqnum = get_next_seqnum(tcp_buf, tcp_buf->expected_seqnum, tcp_buf->buffer[i], false);
                }
            }
        }
        tcp_buf->inserted_items = tcp_buf->inserted_items - removed_items;
    }
    // Buffer not full yet, buffering the packet
    else if(tcp_buf->inserted_items<TCP_BUF_SIZE && tcp_buf->consecutive_buffering_events < CONSECUTIVE_BUFFERING_TREESHOLD){
        VLOG_INFO("[buffering] sequence: %"PRIu32 " expected: %" PRIu32 " in_port: %"PRIu32 " size: %d",
            seq, tcp_buf->expected_seqnum, in_port, tcp_buf->inserted_items);
        buf_pkt = ofpbuf_clone(packet);
        insert_descending_order(tcp_buf, buf_pkt);
    }
    // Buffer full or loss event detecte
    else{
        VLOG_WARN("!! -- Empty Buffer Event -- !!");
        if(tcp_buf->consecutive_buffering_events >= CONSECUTIVE_BUFFERING_TREESHOLD)
            syslog(LOG_INFO, "!! -- Because of an apparent loss -- !!");

        seq_work = get_tcp_seq(tcp_buf->buffer[tcp_buf->inserted_items-1]);

        // If incoming packet has the smallest sequence
        if(seq<seq_work){
            VLOG_INFO("[resetting buffer] sequence: %" PRIu32, seq);
            out_packets[out_packets_count] = packet;
            out_packets_count++;
        }
        // If a packet in the buffer has the smallest sequence
        else{
            VLOG_INFO("[resetting] sequence: %" PRIu32, get_tcp_seq(tcp_buf->buffer[tcp_buf->inserted_items-1]));
            out_packets[out_packets_count] = tcp_buf->buffer[tcp_buf->inserted_items-1];
            out_packets_count++;
            tcp_buf->inserted_items--;
            buf_pkt = ofpbuf_clone(packet);
            insert_descending_order(tcp_buf, buf_pkt);
        }

        // Completely empty the buffer
        for(i=tcp_buf->inserted_items-1;i>= 0;i--){
            seq_work = get_tcp_seq(tcp_buf->buffer[i]);
            VLOG_INFO("resetting %" PRIu32, seq_work);
            get_next_seqnum(tcp_buf, seq_work, tcp_buf->buffer[i], false);
            out_packets[out_packets_count] = tcp_buf->buffer[i];
            out_packets_count++;

            // Adjusting seqnum
            if(i==0){
                tcp_buf->expected_seqnum = get_next_seqnum(tcp_buf, seq_work, tcp_buf->buffer[i], false);
            }
        }

        tcp_buf->inserted_items=0;

        if(tcp_buf->consecutive_buffering_events >= CONSECUTIVE_BUFFERING_TREESHOLD){
            tcp_buf->expected_seqnum = get_next_seqnum(tcp_buf, tcp_buf->expected_seqnum, packet, true);
        }
    }

    return out_packets_count;
}