added udp jitter/packet count calculation
This commit is contained in:
parent
71a7ccf6d3
commit
f4ca73a1b1
123
src/iperf_api.c
123
src/iperf_api.c
@ -300,10 +300,14 @@ int iperf_tcp_recv(struct iperf_stream *sp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int iperf_udp_recv(struct iperf_stream *sp)
|
int iperf_udp_recv(struct iperf_stream *sp)
|
||||||
{ int result, message;
|
{
|
||||||
char ch;
|
int result, message;
|
||||||
int size = sp->settings->blksize;
|
int size = sp->settings->blksize;
|
||||||
|
double transit = 0, d = 0;
|
||||||
char *buf = (char *) malloc(size);
|
char *buf = (char *) malloc(size);
|
||||||
|
struct udp_datagram *udp = (struct udp_datagram *) buf;
|
||||||
|
struct timeval arrival_time;
|
||||||
|
|
||||||
if(!buf)
|
if(!buf)
|
||||||
{
|
{
|
||||||
perror("malloc: unable to allocate receive buffer");
|
perror("malloc: unable to allocate receive buffer");
|
||||||
@ -311,26 +315,39 @@ int iperf_udp_recv(struct iperf_stream *sp)
|
|||||||
|
|
||||||
do{
|
do{
|
||||||
result = recv(sp->socket, buf, size, 0);
|
result = recv(sp->socket, buf, size, 0);
|
||||||
|
|
||||||
} while (result == -1 && errno == EINTR);
|
} while (result == -1 && errno == EINTR);
|
||||||
|
|
||||||
//interprete the type of message in packet
|
//interprete the type of message in packet
|
||||||
if(result > 0)
|
if(result > 0)
|
||||||
{
|
{
|
||||||
ch = buf[0];
|
message = udp->state;
|
||||||
message = (int) ch;
|
}
|
||||||
|
|
||||||
|
if(message != STREAM_END && (sp->stream_id == udp->stream_id))
|
||||||
|
{
|
||||||
|
sp->result->bytes_received+= result;
|
||||||
|
//if((sp->packet_count + 1) == udp->packet_count)
|
||||||
|
sp->packet_count++;
|
||||||
|
|
||||||
|
//jitter measurement
|
||||||
|
if(gettimeofday(&arrival_time, NULL) < 0) {
|
||||||
|
perror("gettimeofday");
|
||||||
|
}
|
||||||
|
|
||||||
|
transit = timeval_diff(&udp->sent_time, &arrival_time);
|
||||||
|
d = transit - sp->prev_transit;
|
||||||
|
if(d < 0)
|
||||||
|
d = -d;
|
||||||
|
sp->prev_transit = transit;
|
||||||
|
sp->jitter += (d - sp->jitter)/ 16.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(message == 3 || message == 9 || message == 8)
|
if(message == 3 || message == 9 || message == 8)
|
||||||
{
|
|
||||||
printf("Recieved %d from client\n", message);
|
printf("Recieved %d from client\n", message);
|
||||||
}
|
|
||||||
|
|
||||||
if(message != STREAM_END)
|
|
||||||
sp->result->bytes_received+= result;
|
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
return message;
|
return message;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,7 +399,8 @@ int iperf_tcp_send(struct iperf_stream *sp)
|
|||||||
|
|
||||||
result = send(sp->socket, buf, size , 0);
|
result = send(sp->socket, buf, size , 0);
|
||||||
|
|
||||||
sp->result->bytes_sent+= size;
|
if(buf[0] != STREAM_END)
|
||||||
|
sp->result->bytes_sent+= size;
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
return result;
|
return result;
|
||||||
@ -390,7 +408,7 @@ int iperf_tcp_send(struct iperf_stream *sp)
|
|||||||
|
|
||||||
int iperf_udp_send(struct iperf_stream *sp)
|
int iperf_udp_send(struct iperf_stream *sp)
|
||||||
{
|
{
|
||||||
int result = 0, i;
|
int result = 0;
|
||||||
struct timeval before, after;
|
struct timeval before, after;
|
||||||
int64_t adjustus, dtargus;
|
int64_t adjustus, dtargus;
|
||||||
|
|
||||||
@ -399,6 +417,9 @@ int iperf_udp_send(struct iperf_stream *sp)
|
|||||||
{
|
{
|
||||||
int size = sp->settings->blksize;
|
int size = sp->settings->blksize;
|
||||||
char *buf = (char *) malloc(size);
|
char *buf = (char *) malloc(size);
|
||||||
|
// this is for udp packet/jitter/lost packet measurements
|
||||||
|
struct udp_datagram *udp = (struct udp_datagram *) buf;
|
||||||
|
|
||||||
if(!buf)
|
if(!buf)
|
||||||
{
|
{
|
||||||
perror("malloc: unable to allocate transmit buffer");
|
perror("malloc: unable to allocate transmit buffer");
|
||||||
@ -408,31 +429,37 @@ int iperf_udp_send(struct iperf_stream *sp)
|
|||||||
dtargus /= sp->settings->rate;
|
dtargus /= sp->settings->rate;
|
||||||
|
|
||||||
assert(dtargus != 0);
|
assert(dtargus != 0);
|
||||||
|
|
||||||
|
// record the packet sent time
|
||||||
|
if(gettimeofday(&udp->sent_time, 0) < 0)
|
||||||
|
perror("gettimeofday");
|
||||||
|
|
||||||
switch(sp->settings->state)
|
switch(sp->settings->state)
|
||||||
{
|
{
|
||||||
case STREAM_BEGIN:
|
case STREAM_BEGIN:
|
||||||
buf[0]= STREAM_BEGIN;
|
udp->state = STREAM_BEGIN;
|
||||||
for(i=1; i < size; i++)
|
udp->stream_id = (int)sp;
|
||||||
buf[i] = i % 37;
|
udp->packet_count = (sp->packet_count)++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STREAM_END:
|
case STREAM_END:
|
||||||
buf[0]= STREAM_END;
|
udp->state = STREAM_END;
|
||||||
|
udp->stream_id = (int) sp;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RESULT_REQUEST:
|
case RESULT_REQUEST:
|
||||||
buf[0]= RESULT_REQUEST;
|
udp->state = RESULT_REQUEST;
|
||||||
|
udp->stream_id = (int) sp;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ALL_STREAMS_END:
|
case ALL_STREAMS_END:
|
||||||
buf[0]= ALL_STREAMS_END;
|
udp->state = ALL_STREAMS_END;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
buf[0]= 0;
|
udp->state = 0;
|
||||||
for(i=1; i < size; i++)
|
udp->stream_id = (int)sp;
|
||||||
buf[i] = i % 37;
|
udp->packet_count = sp->packet_count++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,6 +493,7 @@ int iperf_udp_send(struct iperf_stream *sp)
|
|||||||
// RESET THE TIMER
|
// RESET THE TIMER
|
||||||
update_timer(sp->send_timer, 0, dtargus);
|
update_timer(sp->send_timer, 0, dtargus);
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
||||||
} // timer_expired_micro
|
} // timer_expired_micro
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -556,7 +584,7 @@ void iperf_init_test(struct iperf_test *test)
|
|||||||
FD_SET(s, &test->write_set);
|
FD_SET(s, &test->write_set);
|
||||||
|
|
||||||
for(i = 0; i < test->num_streams; i++)
|
for(i = 0; i < test->num_streams; i++)
|
||||||
{
|
{
|
||||||
s = netdial(test->protocol, test->server_hostname, test->server_port);
|
s = netdial(test->protocol, test->server_hostname, test->server_port);
|
||||||
|
|
||||||
if(s < 0)
|
if(s < 0)
|
||||||
@ -582,6 +610,7 @@ void iperf_init_test(struct iperf_test *test)
|
|||||||
|
|
||||||
if(test->default_settings->state != RESULT_REQUEST)
|
if(test->default_settings->state != RESULT_REQUEST)
|
||||||
connect_msg(sp);
|
connect_msg(sp);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -653,7 +682,7 @@ void *iperf_stats_callback(struct iperf_test *test)
|
|||||||
|
|
||||||
char *iperf_reporter_callback(struct iperf_test *test)
|
char *iperf_reporter_callback(struct iperf_test *test)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0, total_packets = 0;
|
||||||
char ubuf[UNIT_LEN];
|
char ubuf[UNIT_LEN];
|
||||||
char nbuf[UNIT_LEN];
|
char nbuf[UNIT_LEN];
|
||||||
struct iperf_stream *sp = test->streams;
|
struct iperf_stream *sp = test->streams;
|
||||||
@ -722,10 +751,12 @@ char *iperf_reporter_callback(struct iperf_test *test)
|
|||||||
{
|
{
|
||||||
if(test->role == 'c')
|
if(test->role == 'c')
|
||||||
bytes+= sp->result->bytes_sent;
|
bytes+= sp->result->bytes_sent;
|
||||||
else
|
else
|
||||||
{
|
bytes+= sp->result->bytes_received;
|
||||||
bytes+= sp->result->bytes_received;
|
|
||||||
}
|
if(test->protocol == Pudp)
|
||||||
|
total_packets+= sp->packet_count;
|
||||||
|
|
||||||
|
|
||||||
if(test->protocol == Ptcp)
|
if(test->protocol == Ptcp)
|
||||||
{
|
{
|
||||||
@ -761,7 +792,7 @@ char *iperf_reporter_callback(struct iperf_test *test)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf(message, report_bw_jitter_loss_format, sp->socket, start_time,
|
sprintf(message, report_bw_jitter_loss_format, sp->socket, start_time,
|
||||||
end_time, ubuf, nbuf, 0.0, 0, 0, 0.0);
|
end_time, ubuf, nbuf, sp->jitter * 1000, 0, sp->packet_count, 0.0);
|
||||||
strcat(message_final, message);
|
strcat(message_final, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -784,7 +815,7 @@ char *iperf_reporter_callback(struct iperf_test *test)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf(message, report_sum_bw_jitter_loss_format, start_time, end_time, ubuf, nbuf, 0.0, 0, 0, 0.0);
|
sprintf(message, report_sum_bw_jitter_loss_format, start_time, end_time, ubuf, nbuf,sp->jitter, 0, total_packets, 0.0);
|
||||||
strcat(message_final, message);
|
strcat(message_final, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -855,11 +886,16 @@ struct iperf_stream *iperf_new_stream(struct iperf_test *testp)
|
|||||||
|
|
||||||
sp->socket = -1;
|
sp->socket = -1;
|
||||||
|
|
||||||
|
sp->packet_count =0;
|
||||||
|
sp->stream_id = (int)sp;
|
||||||
|
sp->jitter = 0.0;
|
||||||
|
sp->prev_transit = 0.0;
|
||||||
|
|
||||||
sp->result->bytes_received = 0;
|
sp->result->bytes_received = 0;
|
||||||
sp->result->bytes_sent = 0;
|
sp->result->bytes_sent = 0;
|
||||||
gettimeofday(&sp->result->start_time, NULL);
|
gettimeofday(&sp->result->start_time, NULL);
|
||||||
|
|
||||||
sp->settings->state = STREAM_BEGIN;
|
sp->settings->state = STREAM_BEGIN;
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -906,6 +942,7 @@ int iperf_udp_accept(struct iperf_test *test)
|
|||||||
int sz;
|
int sz;
|
||||||
|
|
||||||
buf = (char *) malloc(test->default_settings->blksize);
|
buf = (char *) malloc(test->default_settings->blksize);
|
||||||
|
struct udp_datagram *udp = (struct udp_datagram *) buf;
|
||||||
len = sizeof sa_peer;
|
len = sizeof sa_peer;
|
||||||
|
|
||||||
sz = recvfrom(test->listener_sock_udp, buf, test->default_settings->blksize, 0, (struct sockaddr *) &sa_peer, &len);
|
sz = recvfrom(test->listener_sock_udp, buf, test->default_settings->blksize, 0, (struct sockaddr *) &sa_peer, &len);
|
||||||
@ -927,12 +964,12 @@ int iperf_udp_accept(struct iperf_test *test)
|
|||||||
|
|
||||||
iperf_init_stream(sp, test);
|
iperf_init_stream(sp, test);
|
||||||
sp->result->bytes_received+= sz;
|
sp->result->bytes_received+= sz;
|
||||||
iperf_add_stream(test, sp);
|
iperf_add_stream(test, sp);
|
||||||
|
|
||||||
|
|
||||||
test->listener_sock_udp = netannounce(Pudp, NULL, test->server_port);
|
test->listener_sock_udp = netannounce(Pudp, NULL, test->server_port);
|
||||||
if(test->listener_sock_udp < 0)
|
if(test->listener_sock_udp < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
||||||
FD_SET(test->listener_sock_udp, &test->read_set);
|
FD_SET(test->listener_sock_udp, &test->read_set);
|
||||||
test->max_fd = (test->max_fd < test->listener_sock_udp) ? test->listener_sock_udp : test->max_fd;
|
test->max_fd = (test->max_fd < test->listener_sock_udp) ? test->listener_sock_udp : test->max_fd;
|
||||||
@ -940,9 +977,13 @@ int iperf_udp_accept(struct iperf_test *test)
|
|||||||
if(test->default_settings->state != RESULT_REQUEST)
|
if(test->default_settings->state != RESULT_REQUEST)
|
||||||
connect_msg(sp);
|
connect_msg(sp);
|
||||||
|
|
||||||
free(buf);
|
printf("1st UDP data packet for socket %d has arrived \n", sp->socket);
|
||||||
return 0;
|
sp->stream_id = udp->stream_id;
|
||||||
|
sp->packet_count++;
|
||||||
|
printf("Stream id = %d\tudp_id = %d\tcount = %d\n", sp->stream_id, udp->stream_id, sp->packet_count);
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int iperf_tcp_accept(struct iperf_test *test)
|
int iperf_tcp_accept(struct iperf_test *test)
|
||||||
@ -1100,7 +1141,7 @@ void iperf_run_server(struct iperf_test *test)
|
|||||||
else if(result >0)
|
else if(result >0)
|
||||||
{
|
{
|
||||||
// Accept a new TCP connection
|
// Accept a new TCP connection
|
||||||
if (FD_ISSET(test->listener_sock_tcp, &test->temp_set) )
|
if (FD_ISSET(test->listener_sock_tcp, &test->temp_set))
|
||||||
{
|
{
|
||||||
test->protocol = Ptcp;
|
test->protocol = Ptcp;
|
||||||
test->default_settings->blksize = DEFAULT_TCP_BLKSIZE;
|
test->default_settings->blksize = DEFAULT_TCP_BLKSIZE;
|
||||||
@ -1255,7 +1296,7 @@ void iperf_run_client(struct iperf_test *test)
|
|||||||
if(FD_ISSET(sp->socket, &test->write_set))
|
if(FD_ISSET(sp->socket, &test->write_set))
|
||||||
{
|
{
|
||||||
result+= sp->snd(sp);
|
result+= sp->snd(sp);
|
||||||
|
|
||||||
if(sp->next==NULL)
|
if(sp->next==NULL)
|
||||||
break;
|
break;
|
||||||
sp=sp->next;
|
sp=sp->next;
|
||||||
@ -1306,8 +1347,8 @@ void iperf_run_client(struct iperf_test *test)
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
sp = np;
|
sp = np;
|
||||||
sp->settings->state = STREAM_END;
|
sp->settings->state = STREAM_END;
|
||||||
sp->snd(sp);
|
sp->snd(sp);
|
||||||
np = sp->next;
|
np = sp->next;
|
||||||
} while (np);
|
} while (np);
|
||||||
|
|
||||||
|
@ -4,8 +4,7 @@ struct iperf_interval_results
|
|||||||
{
|
{
|
||||||
iperf_size_t bytes_transferred;
|
iperf_size_t bytes_transferred;
|
||||||
int interval_duration;
|
int interval_duration;
|
||||||
struct iperf_interval_results *next;
|
struct iperf_interval_results *next;
|
||||||
|
|
||||||
void * custom_data;
|
void * custom_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -35,7 +34,7 @@ struct iperf_settings
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct iperf_stream
|
struct iperf_stream
|
||||||
{
|
{
|
||||||
/* configurable members */
|
/* configurable members */
|
||||||
int local_port; // local port
|
int local_port; // local port
|
||||||
int remote_port; // remote machine port
|
int remote_port; // remote machine port
|
||||||
@ -43,11 +42,15 @@ struct iperf_stream
|
|||||||
int protocol; // protocol- TCP/UDP
|
int protocol; // protocol- TCP/UDP
|
||||||
|
|
||||||
/* non configurable members */
|
/* non configurable members */
|
||||||
struct iperf_stream_result *result; //structure pointer to result
|
struct iperf_stream_result *result; //structure pointer to result
|
||||||
|
int socket; // socket
|
||||||
|
struct timer *send_timer;
|
||||||
|
|
||||||
int socket; // socket
|
/* for udp measurements - Need to change the members */
|
||||||
|
int packet_count;
|
||||||
struct timer *send_timer;
|
int stream_id; // stream identity
|
||||||
|
double jitter;
|
||||||
|
double prev_transit;
|
||||||
|
|
||||||
struct sockaddr_storage local_addr;
|
struct sockaddr_storage local_addr;
|
||||||
struct sockaddr_storage remote_addr;
|
struct sockaddr_storage remote_addr;
|
||||||
@ -101,6 +104,19 @@ struct iperf_test
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct udp_datagram
|
||||||
|
{
|
||||||
|
int state;
|
||||||
|
int stream_id;
|
||||||
|
int packet_count;
|
||||||
|
struct timeval sent_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void add_interval_list(struct iperf_stream_result *rp, struct iperf_interval_results temp);
|
||||||
|
void display_interval_list(struct iperf_stream_result *rp);
|
||||||
|
void send_result_to_client(struct iperf_stream *sp);
|
||||||
|
void receive_result_from_server(struct iperf_test *test);
|
||||||
int getsock_tcp_mss( int inSock );
|
int getsock_tcp_mss( int inSock );
|
||||||
int set_socket_options(struct iperf_stream *sp, struct iperf_test *test);
|
int set_socket_options(struct iperf_stream *sp, struct iperf_test *test);
|
||||||
void connect_msg(struct iperf_stream *sp);
|
void connect_msg(struct iperf_stream *sp);
|
||||||
|
@ -24,7 +24,8 @@ timeval_to_double(struct timeval *tv)
|
|||||||
double
|
double
|
||||||
timeval_diff(struct timeval *tv0, struct timeval *tv1)
|
timeval_diff(struct timeval *tv0, struct timeval *tv1)
|
||||||
{
|
{
|
||||||
return timeval_to_double(tv1) - timeval_to_double(tv0);
|
//return timeval_to_double(tv1) - timeval_to_double(tv0);
|
||||||
|
return (tv1->tv_sec - tv0->tv_sec) + abs(tv1->tv_usec - tv0->tv_usec) / 1000000.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -43,7 +44,7 @@ timer_expired(struct timer *tp)
|
|||||||
current+= now.tv_sec * 1000000 ;
|
current+= now.tv_sec * 1000000 ;
|
||||||
current+= now.tv_usec;
|
current+= now.tv_usec;
|
||||||
|
|
||||||
diff = end - current;
|
diff = end - current;
|
||||||
|
|
||||||
return diff <= 0;
|
return diff <= 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user