All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

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