Commit 3b01fa98 authored by Jonathon Duerig's avatar Jonathon Duerig

Fixed a time-calculation bug in the monitor. Added bandwidth and base-rtt...

Fixed a time-calculation bug in the monitor. Added bandwidth and base-rtt calculations based on TCP-vegas. Miscellaneous cleanups.
parent de2f2638
......@@ -241,6 +241,8 @@ def send_destinations(conn, packet_list):
prev_time = packet_list[0][3]
for packet in packet_list:
ip = ip_to_int(emulated_to_real[packet[0]])
if prev_time == 0.0:
prev_time = packet[3]
delta = int((packet[3] - prev_time) * 1000)
if packet[3] == 0:
delta = 0
......
sh instrument.sh ../iperf -i 0.5 -c elab1 -t 30
#sh instrument.sh ../iperf -c elab1 -t 30
......@@ -261,9 +261,11 @@ int insert_fake(unsigned long ip, unsigned short port)
delays[index]=0;
last_delays[index]=0;
delay_count[index]=0;
delay_records[index].head = NULL;
delay_records[index].tail = NULL;
delay_records[index].sample_number = 0;
max_throughput[index] = 0;
base_rtt[index] = LONG_MAX;
// delay_records[index].head = NULL;
// delay_records[index].tail = NULL;
// delay_records[index].sample_number = 0;
result = index;
}
return result;
......@@ -336,7 +338,9 @@ void reconnect_receiver(int index)
last_loss_rates[index]=0;
delays[index]=0;
last_delays[index]=0;
remove_delay_samples(index);
max_throughput[index] = 0;
base_rtt[index] = LONG_MAX;
// remove_delay_samples(index);
}
void reset_receive_records(int index, unsigned long ip,
......
......@@ -46,6 +46,9 @@ FILE *loss_log;
ThroughputAckState throughput[CONCURRENT_RECEIVERS];
unsigned long max_throughput[CONCURRENT_RECEIVERS];
unsigned long base_rtt[CONCURRENT_RECEIVERS];
// Returns true if sequence is between the firstUnknown and the
// nextSequence. Takes account of wraparound.
int throughputInWindow(ThroughputAckState * state, unsigned int sequence)
......@@ -349,25 +352,18 @@ u_int16_t handle_IP(u_char *args, const struct pcap_pkthdr* pkthdr, const u_char
source_port = htons(tp->source);
dest_port = htons(tp->dest);
// path_id = search_rcvdb(ip_dst);
// If there is a fake entry, the stub_port entry will be the
// destination port requested by the command line.
// debug_addr.s_addr = ip_src;
// printf("ip_src: %s ", inet_ntoa(debug_addr));
// debug_addr.s_addr = ip_dst;
// printf("ip_dst: %s, dest_port: %d, source_port: %d\n",
// inet_ntoa(debug_addr), dest_port, source_port);
path_id = find_by_stub_port(ip_dst, dest_port);
// printf("outgoing path_id: %d\n", path_id);
if (path_id == -1 || rcvdb[path_id].source_port != 0
|| rcvdb[path_id].dest_port != 0)
if (flag_standalone)
{
// If this is standalone mode, the stub_port entry will be the
// destination port requested by the command line.
path_id = find_by_stub_port(ip_dst, dest_port);
}
else
{
// I contacted the receiver. Therefore, my port is unique and
// the receiver's port is fixed. The destination is the
// receiver, therefore my port is the one that is of interest.
path_id = find_by_stub_port(ip_dst, source_port);
// printf("stub path_id (outgoing): %d\n", path_id);
}
if (path_id != -1) { //a monitored outgoing packet
//ignore the pure outgoing ack
......@@ -417,22 +413,20 @@ u_int16_t handle_IP(u_char *args, const struct pcap_pkthdr* pkthdr, const u_char
}
} else {
// path_id = search_rcvdb(ip_src);
// If there is a fake entry, and the packet is incoming, then
// the source_port will be the remote port requested on the
// command line.
path_id = find_by_stub_port(ip_src, source_port);
// printf("incoming path_id: %d\n", path_id);
if (path_id == -1 || rcvdb[path_id].source_port != 0
|| rcvdb[path_id].dest_port != 0)
if (flag_standalone)
{
// If this is standalone mode, and the packet is incoming,
// then the source_port will be the remote port requested on
// the command line.
path_id = find_by_stub_port(ip_src, source_port);
}
else
{
// I contacted the receiver, so my port is unique and their
// port is the same every time. This means that if a packet is
// coming from them, the destination port is the one of
// interest.
path_id = find_by_stub_port(ip_src, dest_port);
// printf("stub path_id (incoming): %d\n", path_id);
}
if (path_id != -1) { //a monitored incoming packet
if (ack_bit == 1) { //has an acknowledgement
......@@ -445,16 +439,53 @@ u_int16_t handle_IP(u_char *args, const struct pcap_pkthdr* pkthdr, const u_char
if (flag_resend) { //if the ack is triggered by a resend, skip the delay calculation.
flag_resend = 0;
} else { //calculate the delay
int delay = 0;
int delay = 0;
int bandwidth = 0;
int goodput = 0;
struct tcp_info info;
msecs = floor((pkthdr->ts.tv_usec-sniff_rcvdb[path_id].records[record_id].captime.tv_usec)/1000.0+0.5);
delay = (pkthdr->ts.tv_sec-sniff_rcvdb[path_id].records[record_id].captime.tv_sec)*1000 + msecs;
if (delay != 0)
{
delays[path_id] += delay;
(delay_count[path_id])++;
append_delay_sample(path_id, delay, &(pkthdr->ts));
if (delay < base_rtt[path_id])
{
base_rtt[path_id] = delay;
}
if (is_live && delay_count[path_id] > 0)
{
int info_size = sizeof(info);
int error = getsockopt(rcvdb[path_id].sockfd,
SOL_TCP, TCP_INFO, &info,
&info_size);
if (error == -1)
{
perror("getsockopt() TCP_INFO");
clean_exit(1);
}
bandwidth = (info.tcpi_snd_cwnd * info.tcpi_snd_mss)
/ base_rtt[path_id];
if (bandwidth > max_throughput[path_id])
{
max_throughput[path_id] = bandwidth;
}
goodput = throughputTick(&throughput[path_id]);
logWrite(DELAY_DETAIL, NULL, "Goodput: %d", goodput);
logWrite(DELAY_DETAIL, NULL, "Throughput: %lu", bandwidth);
logWrite(DELAY_DETAIL, NULL, "Congestion Window Size: %lu",
info.tcpi_snd_cwnd);
logWrite(DELAY_DETAIL, NULL, "Sending MSS: %lu",
info.tcpi_snd_mss);
logWrite(DELAY_DETAIL, NULL, "Base RTT: %lu",
base_rtt[path_id]);
}
// append_delay_sample(path_id, delay, &(pkthdr->ts));
logWrite(DELAY_DETAIL, &(pkthdr->ts),
"Delay: %lu, Sum: %lu, Count: %lu", delay,
delays[path_id], delay_count[path_id]);
}
}
pop_sniff_rcvdb(path_id, (unsigned long)(ack_seq-1)); //advance the sniff window base
} //ack in rcvdb
} //has ack
......@@ -526,7 +557,7 @@ u_int16_t handle_ethernet (u_char *args,const struct pcap_pkthdr* pkthdr,const u
return ether_type;
}
void init_pcap(int to_ms, unsigned short port, char * device, int is_live) {
void init_pcap(int to_ms, unsigned short port, char * device) {
char errbuf[PCAP_ERRBUF_SIZE];
if (flag_debug) {
......
......@@ -108,6 +108,7 @@ typedef struct {
} delay_record;
extern short flag_debug;
extern short flag_standalone;
extern int pcapfd;
extern int maxfd;
extern connection snddb[CONCURRENT_SENDERS];
......@@ -119,10 +120,13 @@ extern unsigned long delay_count[CONCURRENT_RECEIVERS];
extern loss_record loss_records[CONCURRENT_RECEIVERS]; //loss is calculated at the sender side
extern unsigned long last_loss_rates[CONCURRENT_RECEIVERS]; //loss per billion
extern delay_record delay_records[CONCURRENT_RECEIVERS]; //delay is calculated at the sender side
extern int is_live;
extern unsigned long max_throughput[CONCURRENT_RECEIVERS];
extern unsigned long base_rtt[CONCURRENT_RECEIVERS];
extern void sniff(void);
extern void init_pcap(int to_ms, unsigned short port, char * device,
int is_live);
extern void init_pcap(int to_ms, unsigned short port, char * device);
extern void append_delay_sample(int path_id, long sample_value,
struct timeval const * timestamp);
extern void remove_delay_samples(int path_id);
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment