Esempio n. 1
0
def write_csv(path, data, compression):
    f = open_compressed_file('{}{}'.format(
        path, COMPRESSION_EXTENSIONS[compression]),
                             write=True)
    connections = []
    max_length = 0
    columns = 1
    for d in data:
        connections.append(data[d])
        columns = len(data[d])

        max_length = max(max_length, len(data[d][0]))

        for col in range(0, columns):
            f.write('{};'.format(d))
    f.write('\n')

    for i in range(max_length):
        for j in connections:
            if i < len(j[0]):
                for col in range(0, columns):
                    f.write('{};'.format(j[col][i]))
            else:
                for col in range(0, columns):
                    f.write(';')
        f.write('\n')
    f.close()
Esempio n. 2
0
def read_csv(path, columns_per_connection=2):
    output = {}
    file_path = find_file(path)

    if file_path is None:
        raise IOError('File not found {}'.format(path))

    f = open_compressed_file(file_path)

    first_line = f.readline().split(';')[:-1]
    for line in f:
        split = line.split(';')
        for i in range(0, len(first_line), columns_per_connection):
            if split[i] == '':
                continue

            try:
                index = int(first_line[i])
            except ValueError:
                index = first_line[i]

            if index not in output:
                output[index] = tuple(
                    [[] for _ in range(0, columns_per_connection)])
            for column in range(0, columns_per_connection):
                output[index][column].append(float(split[i + column]))
    f.close()
    return output
Esempio n. 3
0
def parse_buffer_backlog(path):
    output = {}
    paths = glob.glob(os.path.join(path, '*.{}*'.format(BUFFER_FILE_EXTENSION)))

    for i, file_path in enumerate(paths):
        output[i] = ([], [])
        f = open_compressed_file(file_path)
        for line in f:
            split = line.split(';')
            timestamp = parse_timestamp(split[0])
            size = split[1].replace('b\n', '')
            if 'K' in size:
                size = float(size.replace('K', '')) * 1000
            elif 'M' in size:
                size = float(size.replace('M', '')) * 1000000
            elif 'G' in size:
                size = float(size.replace('G', '')) * 1000000000
            output[i][0].append(timestamp)
            output[i][1].append(float(size) * 8)
        f.close()
    return output
Esempio n. 4
0
def parse_bbr_and_cwnd_values(path):
    bbr_values = {}
    cwnd_values = {}

    paths = glob.glob(os.path.join(path, '*.{}*'.format(FLOW_FILE_EXTENSION)))

    all_files = sorted(paths)

    for i, file_path in enumerate(all_files):

        bbr_values[i] = ([], [], [], [], [], [])
        cwnd_values[i] = ([], [], [])

        f = open_compressed_file(file_path)

        for line in f:
            split = map(lambda x: x.strip(), line.split(';'))

            timestamp = parse_timestamp(split[0])
            cwnd, ssthresh = 0, 0

            if split[1] != '':
                cwnd = int(split[1])
            if split[2] != '':
                ssthresh = int(split[2])

            cwnd_values[i][0].append(timestamp)
            cwnd_values[i][1].append(cwnd)
            cwnd_values[i][2].append(ssthresh)

            if split[3] != '':
                bbr = split[3].replace('bw:', '')\
                    .replace('mrtt:','')\
                    .replace('pacing_gain:', '')\
                    .replace('cwnd_gain:', '')
                bbr = bbr.split(',')

                if len(bbr) < 4:
                    pacing_gain = 0
                    cwnd_gain = 0
                else:
                    pacing_gain = float(bbr[2])
                    cwnd_gain = float(bbr[3])

                if 'Mbps' in bbr[0]:
                    bw = float(bbr[0].replace('Mbps', '')) * 1000000
                elif 'Kbps' in bbr[0]:
                    bw = float(bbr[0].replace('Kbps', '')) * 1000
                elif 'bps' in bbr[0]:
                    bw = float(bbr[0].replace('bps', ''))
                else:
                    bw = 0

                rtt = float(bbr[1])

                bbr_values[i][0].append(timestamp)
                bbr_values[i][1].append(bw)
                bbr_values[i][2].append(rtt)
                bbr_values[i][3].append(pacing_gain)
                bbr_values[i][4].append(cwnd_gain)
                bbr_values[i][5].append(bw * rtt / 1000)

        f.close()
    return bbr_values, cwnd_values
Esempio n. 5
0
def parse_pcap(path, delta_t):
    # Find correct .pcap files
    pcap1 = glob.glob(os.path.join(path, PCAP1 + '*'))[0]
    pcap2 = glob.glob(os.path.join(path, PCAP2 + '*'))[0]

    total_packets = len(list(dpkt.pcap.Reader(open_compressed_file(pcap1)))) + \
                    len(list(dpkt.pcap.Reader(open_compressed_file(pcap1))))
    print('  Found {} frames.'.format(colorize(total_packets, 'green')))
    processed_packets = 0

    f = open_compressed_file(pcap1)

    pcap = dpkt.pcap.Reader(f)

    connections = []
    active_connections = []

    round_trips = {}
    inflight = {}
    sending_rate = {}
    avg_rtt = {}

    inflight_seq = {}
    inflight_ack = {}

    sending_rate_data_size = {}

    inflight_avg = {}

    avg_rtt_samples = {}

    total_throughput = ([], [])
    total_sending_rate = ([], [])

    retransmissions = {}
    retransmission_counter = {}
    packet_counter = {}
    retransmissions_interval = {}
    total_retransmisions = ([], [], [])

    start_seq = {}

    t = 0

    ts_vals = {}
    seqs = {}

    start_ts = -1

    print('Connections:')
    for ts, buf in pcap:
        if start_ts < 0:
            start_ts = ts
            t = start_ts + delta_t

        processed_packets += 1
        if processed_packets % 500 == 0:
            print_progress(processed_packets, total_packets)

        eth = dpkt.ethernet.Ethernet(buf)
        ip = eth.data
        tcp = ip.data

        src_ip = socket.inet_ntoa(ip.src)
        dst_ip = socket.inet_ntoa(ip.dst)
        src_port = tcp.sport
        dst_port = tcp.dport

        # identify a connection always as (client port, server port)
        if src_port > dst_port:
            tcp_tuple = (src_ip, src_port, dst_ip, dst_port)
        else:
            tcp_tuple = (dst_ip, dst_port, src_ip, src_port)

        while ts >= t:

            total_sending_rate[0].append(t)
            total_sending_rate[1].append(0)

            total_retransmisions[0].append(t)
            total_retransmisions[1].append(0)
            total_retransmisions[2].append(0)

            for i, c in enumerate(connections):

                if c not in active_connections:
                    continue

                tp = float(sending_rate_data_size[i]) / delta_t
                sending_rate[i][0].append(t)
                sending_rate[i][1].append(tp)
                sending_rate_data_size[i] = 0

                total_sending_rate[1][-1] += tp

                retransmissions_interval[i][0].append(t)
                retransmissions_interval[i][1].append(
                    retransmission_counter[i])
                retransmissions_interval[i][2].append(packet_counter[i])
                total_retransmisions[1][-1] += retransmission_counter[i]
                total_retransmisions[2][-1] += packet_counter[i]
                retransmission_counter[i] = 0
                packet_counter[i] = 0

                inflight[i][0].append(t)
                if len(inflight_avg[i]) > 0:
                    inflight[i][1].append(
                        sum(inflight_avg[i]) / len(inflight_avg[i]))
                else:
                    inflight[i][1].append(0)
                inflight_avg[i] = []

                if len(avg_rtt_samples[i]) > 0:
                    avg_rt = sum(avg_rtt_samples[i]) / len(avg_rtt_samples[i])
                    avg_rtt[i][0].append(t)
                    avg_rtt[i][1].append(avg_rt)
                avg_rtt_samples[i] = []

            t += delta_t

        if tcp.flags & 0x02 and tcp_tuple not in connections:
            connections.append(tcp_tuple)
            active_connections.append(tcp_tuple)
            connection_index = connections.index(tcp_tuple)

            start_seq[connection_index] = tcp.seq

            round_trips[connection_index] = ([], [])
            inflight[connection_index] = ([], [])
            avg_rtt[connection_index] = ([], [])
            sending_rate[connection_index] = ([], [])

            ts_vals[connection_index] = ([], [])
            seqs[connection_index] = []

            inflight_seq[connection_index] = 0
            inflight_ack[connection_index] = 0

            inflight_avg[connection_index] = []

            sending_rate_data_size[connection_index] = 0

            avg_rtt_samples[connection_index] = []

            retransmissions[connection_index] = ([], )
            retransmission_counter[connection_index] = 0
            packet_counter[connection_index] = 0
            retransmissions_interval[connection_index] = ([], [], [])

            print('  [SYN] {}:{} -> {}:{}'.format(tcp_tuple[0], tcp_tuple[1],
                                                  tcp_tuple[2], tcp_tuple[3]))

        if tcp.flags & 0x01:
            if tcp_tuple in active_connections:
                active_connections.remove(tcp_tuple)
                print('  [FIN] {}:{} -> {}:{}'.format(tcp_tuple[0],
                                                      tcp_tuple[1],
                                                      tcp_tuple[2],
                                                      tcp_tuple[3]))
            continue

        connection_index = connections.index(tcp_tuple)

        ts_val = None
        ts_ecr = None

        options = dpkt.tcp.parse_opts(tcp.opts)
        for opt in options:
            if opt[0] == dpkt.tcp.TCP_OPT_TIMESTAMP:
                ts_val = reduce(lambda x, r: (x << 8) + r,
                                map(ord, opt[1][:4]))
                ts_ecr = reduce(lambda x, r: (x << 8) + r,
                                map(ord, opt[1][4:]))

        if src_port > dst_port:
            # client -> server
            tcp_seq = tcp.seq - start_seq[connection_index]
            if tcp_seq < 0:
                tcp_seq += 2**32

            packet_counter[connection_index] += 1

            inflight_seq[connection_index] = max(
                tcp_seq, inflight_seq[connection_index])
            sending_rate_data_size[connection_index] += ip.len * 8

            if tcp_seq in seqs[connection_index]:
                retransmissions[connection_index][0].append(ts)
                retransmission_counter[connection_index] += 1

            else:
                seqs[connection_index].append(tcp_seq)
                if ts_val is not None:
                    ts_vals[connection_index][0].append(ts)
                    ts_vals[connection_index][1].append(ts_val)

        else:
            # server -> client
            tcp_ack = tcp.ack - start_seq[connection_index]
            if tcp_ack < 0:
                tcp_ack += 2**32

            inflight_ack[connection_index] = max(
                tcp_ack, inflight_ack[connection_index])

            seqs[connection_index] = [
                x for x in seqs[connection_index] if x >= tcp_ack
            ]

            if ts_ecr in ts_vals[connection_index][1]:
                index = ts_vals[connection_index][1].index(ts_ecr)
                rtt = (ts - ts_vals[connection_index][0][index]) * 1000

                ts_vals[connection_index][0].pop(index)
                ts_vals[connection_index][1].pop(index)

                avg_rtt_samples[connection_index].append(rtt)

                round_trips[connection_index][0].append(ts)
                round_trips[connection_index][1].append(rtt)

        inflight_data = max(
            0, inflight_seq[connection_index] - inflight_ack[connection_index])
        inflight_avg[connection_index].append(inflight_data * 8)

    f.close()

    # Compute throughput after the bottleneck
    f = open_compressed_file(pcap2)

    pcap = dpkt.pcap.Reader(f)

    connections = []
    active_connections = []
    throughput = {}

    throughput_data_size = {}

    t = start_ts + delta_t

    for ts, buf in pcap:

        processed_packets += 1
        if processed_packets % 500 == 0:
            print_progress(processed_packets, total_packets)

        eth = dpkt.ethernet.Ethernet(buf)
        ip = eth.data
        tcp = ip.data

        src_ip = socket.inet_ntoa(ip.src)
        dst_ip = socket.inet_ntoa(ip.dst)
        src_port = tcp.sport
        dst_port = tcp.dport

        # identify a connection always as (client port, server port)
        if src_port > dst_port:
            tcp_tuple = (src_ip, src_port, dst_ip, dst_port)
        else:
            tcp_tuple = (dst_ip, dst_port, src_ip, src_port)

        while ts >= t:
            total_throughput[0].append(t)
            total_throughput[1].append(0)

            for i, c in enumerate(connections):
                if c not in active_connections:
                    continue
                tp = float(throughput_data_size[i]) / delta_t
                throughput[i][0].append(t)
                throughput[i][1].append(tp)
                total_throughput[1][-1] += tp
                throughput_data_size[i] = 0
            t += delta_t

        if tcp.flags & 0x02 and tcp_tuple not in connections:
            connections.append(tcp_tuple)
            active_connections.append(tcp_tuple)
            connection_index = connections.index(tcp_tuple)

            throughput[connection_index] = ([], [])
            throughput_data_size[connection_index] = 0

        if tcp.flags & 0x01:
            if tcp_tuple in active_connections:
                active_connections.remove(tcp_tuple)
            continue

        connection_index = connections.index(tcp_tuple)

        if src_port > dst_port:
            # client -> server
            throughput_data_size[connection_index] += ip.len * 8

    print('  100.00%')

    fairness_troughput = compute_fairness(throughput, delta_t)
    fairness_sending_rate = compute_fairness(sending_rate, delta_t)
    fairness = {
        'Throughtput': fairness_troughput,
        'Sending Rate': fairness_sending_rate
    }

    bbr_values, cwnd_values = parse_bbr_and_cwnd_values(path)
    bbr_total_values, sync_phases, sync_duration = compute_total_values(
        bbr_values)
    buffer_backlog = parse_buffer_backlog(path)

    data_info = DataInfo(sync_duration=sync_duration, sync_phases=sync_phases)

    throughput[len(throughput)] = total_throughput
    sending_rate[len(sending_rate)] = total_sending_rate
    retransmissions_interval[len(
        retransmissions_interval)] = total_retransmisions

    return PcapData(rtt=round_trips,
                    inflight=inflight,
                    throughput=throughput,
                    fairness=fairness,
                    avg_rtt=avg_rtt,
                    sending_rate=sending_rate,
                    bbr_values=bbr_values,
                    bbr_total_values=bbr_total_values,
                    cwnd_values=cwnd_values,
                    retransmissions=retransmissions,
                    retransmissions_interval=retransmissions_interval,
                    buffer_backlog=buffer_backlog,
                    data_info=data_info)