tor_multipath_voip/src/meas_lat.c

315 lines
8.4 KiB
C
Raw Normal View History

#include <stdlib.h>
#include <stdio.h>
2019-02-20 15:50:44 +00:00
#include <sys/timerfd.h>
#include <time.h>
#include <unistd.h>
2019-02-20 16:46:58 +00:00
#include <errno.h>
#include "evt_core.h"
2019-02-14 17:08:20 +00:00
#include "net_tools.h"
2019-03-11 14:17:15 +00:00
#include "socks5.h"
2019-02-20 15:50:44 +00:00
struct measure_conf {
uint64_t max_measure;
uint64_t payload_size;
char* payload;
2019-02-14 17:08:20 +00:00
uint64_t counter;
};
2019-02-20 15:50:44 +00:00
struct packet_header {
uint64_t counter;
struct timespec emit_time;
};
2019-03-05 15:13:08 +00:00
struct measure_conf* create_measure_conf(int max_mes, int plsize) {
2019-02-20 15:50:44 +00:00
struct measure_conf* mc = malloc(sizeof(struct measure_conf));
if (mc == NULL) {
perror("Malloc failed");
exit(EXIT_FAILURE);
}
mc->counter = 0;
2019-02-22 14:22:06 +00:00
mc->max_measure = max_mes;
mc->payload_size = plsize;
2019-02-20 15:50:44 +00:00
mc->payload = malloc(mc->payload_size);
if (mc->payload == NULL) {
perror("malloc failed");
exit(EXIT_FAILURE);
}
return mc;
}
2019-03-05 15:13:08 +00:00
void free_mesure_conf(void* v) {
struct measure_conf* mc = (struct measure_conf*)v;
free(mc->payload);
free(mc);
}
2019-03-05 15:21:25 +00:00
int on_udp_err(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
return 1;
}
2019-02-20 16:46:58 +00:00
int on_udp(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
2019-02-20 15:50:44 +00:00
ssize_t res;
int secs, nsecs;
uint64_t micro_sec;
struct timespec curr;
struct measure_conf* mc = fdinfo->other;
res = read(fdinfo->fd, mc->payload, mc->payload_size);
2019-02-20 16:46:58 +00:00
if (res == -1 && errno == EAGAIN) return 1;
2019-02-20 15:50:44 +00:00
if (res != mc->payload_size) {
perror("read error");
exit(EXIT_FAILURE);
}
struct packet_header* head = (struct packet_header*) mc->payload;
if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1){
perror("clock_gettime error");
exit(EXIT_FAILURE);
}
secs = curr.tv_sec - head->emit_time.tv_sec;
nsecs = curr.tv_nsec - head->emit_time.tv_nsec;
micro_sec = secs * 1000000 + nsecs / 1000;
printf("Packet %llu latency %luµs\n", (unsigned long long)head->counter, micro_sec);
if (head->counter >= mc->max_measure) {
printf("Measurement done\n");
exit(EXIT_SUCCESS);
}
2019-02-20 16:46:58 +00:00
return 0;
2019-02-14 17:08:20 +00:00
}
2019-02-20 16:46:58 +00:00
int on_timer(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
2019-02-20 15:50:44 +00:00
ssize_t s;
uint64_t ticks;
struct measure_conf* mc = fdinfo->other;
s = read(fdinfo->fd, &ticks, sizeof(uint64_t));
if (s != sizeof(uint64_t)) {
perror("Read error");
exit(EXIT_FAILURE);
}
if (ticks != 1) {
fprintf(stderr, "Has ticked %lu times, expected 1 time. This is a bug\n", ticks);
}
2019-02-22 14:22:06 +00:00
mc->counter++;
2019-02-20 15:50:44 +00:00
memset(mc->payload, 0, mc->payload_size);
struct packet_header* head = (struct packet_header*)mc->payload;
head->counter = mc->counter;
if (clock_gettime(CLOCK_MONOTONIC, &head->emit_time) == -1) {
perror("clock_gettime error");
exit(EXIT_FAILURE);
}
2019-03-11 14:17:15 +00:00
struct evt_core_fdinfo* tgtinfo = evt_core_get_first_from_cat (ctx, "udp-read");
if (tgtinfo == NULL) tgtinfo = evt_core_get_first_from_cat (ctx, "tcp-read");
if (tgtinfo == NULL) {
2019-03-05 15:13:08 +00:00
printf("No connection yet\n");
return 1;
}
2019-03-11 14:17:15 +00:00
s = send(tgtinfo->fd, mc->payload, mc->payload_size, 0);
2019-02-20 15:50:44 +00:00
if (s < 0) {
perror("Send error");
2019-03-05 15:13:08 +00:00
//exit(EXIT_FAILURE);
2019-02-20 15:50:44 +00:00
}
2019-02-20 16:46:58 +00:00
return 1;
2019-02-20 15:50:44 +00:00
}
void free_timer_conf(void* v) {
struct measure_conf* mc = v;
free(mc->payload);
free(mc);
2019-02-14 17:08:20 +00:00
}
2019-02-22 14:22:06 +00:00
void register_categories(struct evt_core_ctx* evts) {
2019-03-11 14:17:15 +00:00
struct evt_core_cat tcp_read = {
.app_ctx = NULL,
.free_app_ctx = NULL,
.cb = on_udp,
.err_cb = on_udp_err,
.name = "tcp-read",
.flags = EPOLLIN | EPOLLET,
.socklist = NULL
};
2019-02-14 17:08:20 +00:00
struct evt_core_cat udp_read = {
.app_ctx = NULL,
.free_app_ctx = NULL,
.cb = on_udp,
2019-03-05 15:21:25 +00:00
.err_cb = on_udp_err,
2019-02-14 17:08:20 +00:00
.name = "udp-read",
.flags = EPOLLIN | EPOLLET,
.socklist = NULL
};
struct evt_core_cat timer = {
2019-02-20 15:50:44 +00:00
.app_ctx = NULL,
2019-02-14 17:08:20 +00:00
.free_app_ctx = NULL,
.cb = on_timer,
2019-02-18 20:55:53 +00:00
.err_cb = NULL,
2019-02-14 17:08:20 +00:00
.name = "timer",
.flags = EPOLLIN | EPOLLET,
.socklist = NULL
};
2019-02-22 14:22:06 +00:00
evt_core_init(evts);
evt_core_add_cat (evts, &udp_read);
2019-03-11 14:17:15 +00:00
evt_core_add_cat (evts, &tcp_read);
2019-02-22 14:22:06 +00:00
evt_core_add_cat(evts, &timer);
2019-02-14 17:08:20 +00:00
printf("--- Categories registered\n");
2019-02-22 14:22:06 +00:00
}
2019-03-11 14:17:15 +00:00
int register_tor_socket(struct evt_core_ctx* evts, char* host, char* port, int count, int size) {
int socks5_sock = -1, err = 0;
2019-03-11 14:48:57 +00:00
for (int i = 120; i > 0; i--) {
2019-03-11 14:17:15 +00:00
sleep(2);
2019-03-11 14:48:57 +00:00
printf("Remaining try %d/120 to connect to %s:%s\n", i, host, port);
2019-03-11 14:17:15 +00:00
if (socks5_sock >= 0) {
close(socks5_sock);
socks5_sock = -1;
}
socks5_sock = create_tcp_client ("127.0.0.1", "9050");
err = socks5_handshake_syn (socks5_sock);
if (err < 0) continue;
err = socks5_handshake_ack (socks5_sock);
if (err < 0) continue;
err = socks5_connect_dns (socks5_sock, host, atoi(port));
if (err < 0) continue;
err = socks5_reply (socks5_sock);
if (err < 0) {
fprintf(stderr, "Socks5 error %s\n", socks5_rep(-err));
continue;
}
else break;
}
if (socks5_sock < 0 || err < 0) {
exit(EXIT_FAILURE);
}
char url[1024];
struct evt_core_cat cat = {0};
struct evt_core_fdinfo fdinfo = {0};
fdinfo.cat = &cat;
fdinfo.url = url;
fdinfo.fd = socks5_sock;
fdinfo.cat->name = "tcp-read";
fdinfo.other = create_measure_conf (count, size);
fdinfo.free_other = free_mesure_conf;
sprintf(fdinfo.url, "tcp:read:%s:%s", host, port);
evt_core_add_fd (evts, &fdinfo);
printf("--- Tor socket registered\n");
return fdinfo.fd;
}
2019-02-22 14:22:06 +00:00
int register_udp_socket(struct evt_core_ctx* evts, char* host, char* port, int count, int size) {
int udp_sock = create_udp_client (host, port);
2019-02-18 13:35:09 +00:00
char url[1024];
struct evt_core_cat cat = {0};
struct evt_core_fdinfo fdinfo = {0};
fdinfo.cat = &cat;
fdinfo.url = url;
fdinfo.fd = udp_sock;
fdinfo.cat->name = "udp-read";
2019-03-05 15:13:08 +00:00
fdinfo.other = create_measure_conf (count, size);
fdinfo.free_other = free_mesure_conf;
2019-02-22 14:22:06 +00:00
sprintf(fdinfo.url, "udp:read:%s:%s", host, port);
evt_core_add_fd (evts, &fdinfo);
2019-02-20 15:50:44 +00:00
printf("--- UDP socket registered\n");
2019-02-22 14:22:06 +00:00
return fdinfo.fd;
}
2019-02-20 15:50:44 +00:00
2019-02-22 14:22:06 +00:00
void register_timer(struct evt_core_ctx* evts, int udp, int interval, int count, int size) {
2019-02-20 15:50:44 +00:00
struct timespec now;
struct itimerspec timer_config;
2019-02-22 14:22:06 +00:00
char url[1024];
struct evt_core_cat cat = {0};
struct evt_core_fdinfo fdinfo = {0};
fdinfo.cat = &cat;
fdinfo.url = url;
2019-02-20 15:50:44 +00:00
if (clock_gettime(CLOCK_REALTIME, &now) == -1) {
perror("clock_gettime");
2019-02-22 14:22:06 +00:00
exit(EXIT_FAILURE);
2019-02-20 15:50:44 +00:00
}
2019-02-22 14:22:06 +00:00
uint64_t micro_sec = interval;
2019-02-20 15:50:44 +00:00
timer_config.it_value.tv_sec = now.tv_sec + 1;
timer_config.it_value.tv_nsec = now.tv_nsec;
timer_config.it_interval.tv_sec = micro_sec / 1000;
timer_config.it_interval.tv_nsec = micro_sec % 1000 * 1000000;
fdinfo.fd = timerfd_create(CLOCK_REALTIME, 0);
if (fdinfo.fd == -1) {
perror("Unable to timerfd_create");
2019-02-22 14:22:06 +00:00
exit(EXIT_FAILURE);
2019-02-20 15:50:44 +00:00
}
if (timerfd_settime (fdinfo.fd, TFD_TIMER_ABSTIME, &timer_config, NULL) == -1) {
perror("Unable to timerfd_time");
2019-02-22 14:22:06 +00:00
exit(EXIT_FAILURE);
2019-02-20 15:50:44 +00:00
}
fdinfo.cat->name = "timer";
2019-03-05 15:13:08 +00:00
fdinfo.other = create_measure_conf(count, size);
2019-02-20 15:50:44 +00:00
fdinfo.free_other = free_timer_conf;
2019-02-22 14:22:06 +00:00
sprintf(fdinfo.url, "timer:%d:%d", interval, count);
evt_core_add_fd (evts, &fdinfo);
2019-02-20 15:50:44 +00:00
printf("--- Timer registered\n");
2019-02-22 14:22:06 +00:00
}
int main(int argc, char** argv) {
2019-03-06 16:12:58 +00:00
setvbuf(stdout, NULL, _IONBF, 0);
2019-02-22 14:22:06 +00:00
printf("~ measlat ~\n");
int opt, udp_fd, count = 0, size = 0, interval = 0;
2019-03-11 14:17:15 +00:00
char *host = NULL, *port = NULL, *transport = NULL;
2019-02-22 14:22:06 +00:00
struct evt_core_ctx evts = {0};
// 1. Parse parameters
2019-03-11 14:17:15 +00:00
while ((opt = getopt(argc, argv, "h:p:c:s:i:t:")) != -1) {
2019-02-22 14:22:06 +00:00
switch(opt) {
2019-03-11 14:17:15 +00:00
case 'h': // host
2019-02-22 14:22:06 +00:00
host = optarg;
break;
2019-03-11 14:17:15 +00:00
case 'p': // port
2019-02-22 14:22:06 +00:00
port = optarg;
break;
2019-03-11 14:17:15 +00:00
case 't': // transport
transport = optarg;
break;
case 'c': // count
2019-02-22 14:22:06 +00:00
count = atoi(optarg);
break;
2019-03-11 14:17:15 +00:00
case 's': // size - payload in bytes
2019-02-22 14:22:06 +00:00
size = atoi(optarg);
break;
2019-03-11 14:17:15 +00:00
case 'i': // interval - every ms
2019-02-22 14:22:06 +00:00
interval = atoi(optarg);
break;
default:
goto usage;
}
}
// 2. Check and fix parameters
size_t header_size = sizeof(struct packet_header);
if (interval <= 0) interval = 1000;
if (count <= 0) count = 1;
if (size < header_size) size = header_size;
2019-03-11 14:17:15 +00:00
if (transport == NULL) transport = "udp";
2019-02-22 14:22:06 +00:00
if (host == NULL || port == NULL) goto usage;
// 3. Bind events
register_categories(&evts);
2019-03-11 14:17:15 +00:00
if (strcmp(transport, "udp") == 0) udp_fd = register_udp_socket(&evts, host, port, count, size);
else if (strcmp(transport, "tor") == 0) udp_fd = register_tor_socket(&evts, host, port, count, size);
2019-02-22 14:22:06 +00:00
register_timer(&evts, udp_fd, interval, count, size);
2019-02-20 15:50:44 +00:00
2019-02-22 14:22:06 +00:00
// 4. Run main loop
2019-02-20 15:50:44 +00:00
evt_core_loop(&evts);
return 0;
2019-02-22 14:22:06 +00:00
usage:
2019-03-11 14:17:15 +00:00
fprintf(stderr, "Usage: %s -h <host> -p <port> [-t <udp|tor>] [-c <count>] [-i <ms>] [-s <bytes>]\n", argv[0]);
2019-02-22 14:22:06 +00:00
exit(EXIT_FAILURE);
}