tor_multipath_voip/src/udp_echo.c

110 lines
2.8 KiB
C
Raw Normal View History

2019-02-22 15:01:22 +00:00
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include "evt_core.h"
#include "net_tools.h"
2019-09-23 15:00:02 +00:00
#include "measure.h"
struct udpecho_ctx {
struct measure_conf mc;
uint8_t is_measlat;
};
2019-02-22 15:01:22 +00:00
int on_udp(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
ssize_t nread, nwritten;
struct sockaddr_in addr;
socklen_t addrlen = sizeof(addr);
2019-09-23 15:00:02 +00:00
struct udpecho_ctx *uctx = fdinfo->cat->app_ctx;
2019-02-22 15:01:22 +00:00
2019-09-23 15:00:02 +00:00
nread = recvfrom(fdinfo->fd, uctx->mc.payload, uctx->mc.payload_size, MSG_TRUNC, (struct sockaddr*)&addr, &addrlen);
2019-02-22 15:01:22 +00:00
if (nread == -1 && errno == EAGAIN) return 1; // Read done
2019-09-23 15:00:02 +00:00
if (nread <= 0 || nread > uctx->mc.payload_size) {
fprintf(stderr, "Message is either truncated or an error occured. nread=%ld, expected=%ld\n", nread, uctx->mc.payload_size);
2019-02-22 15:01:22 +00:00
perror("read errno");
exit(EXIT_FAILURE);
}
2019-09-23 15:00:02 +00:00
if (uctx->is_measlat) measure_parse (nread, &uctx->mc);
nwritten = sendto(fdinfo->fd, uctx->mc.payload, nread, 0, (struct sockaddr*)&addr, addrlen);
2019-02-22 15:01:22 +00:00
// @FIXME don't support EAGAIN on write. Could be intended, you don't think so?
if (nwritten != nread) {
fprintf(stderr, "Didn't write the same number of bytes as read. nread=%ld, nwritten=%ld\n", nread, nwritten);
perror("write errno");
exit(EXIT_FAILURE);
}
return 0;
}
int main(int argc, char** argv) {
2019-03-06 16:12:58 +00:00
setvbuf(stdout, NULL, _IONBF, 0);
2019-02-22 15:01:22 +00:00
printf("~ udpecho ~\n");
2019-09-23 15:00:02 +00:00
struct udpecho_ctx uctx = {0};
2019-02-22 15:01:22 +00:00
int opt, udp_sock, verbose = 0;
2019-04-18 12:34:38 +00:00
char *port = NULL, *bindhost = NULL;
2019-02-22 15:01:22 +00:00
struct evt_core_ctx evts = {0};
2019-09-24 13:37:12 +00:00
uctx.mc.is_server = 1;
2019-09-23 15:00:02 +00:00
uctx.mc.payload_size = 1500;
2019-02-22 15:01:22 +00:00
// 1. Parse parameters
2019-09-23 15:00:02 +00:00
while ((opt = getopt(argc, argv, "b:p:vms:")) != -1) {
2019-02-22 15:01:22 +00:00
switch(opt) {
case 'v':
2019-04-01 12:16:41 +00:00
verbose++;
2019-02-22 15:01:22 +00:00
break;
case 'p':
port = optarg;
break;
2019-04-18 12:34:38 +00:00
case 'b':
bindhost = optarg;
break;
2019-09-23 15:00:02 +00:00
case 'm':
uctx.is_measlat = 1;
break;
case 's':
uctx.mc.payload_size = atoi(optarg);
break;
2019-02-22 15:01:22 +00:00
default:
goto usage;
}
}
2019-04-18 12:34:38 +00:00
if (bindhost == NULL) bindhost = "127.0.0.1";
2019-09-23 15:00:02 +00:00
measure_prepare (&uctx.mc);
2019-02-22 15:01:22 +00:00
// 2. Register category
struct evt_core_cat udp_read = {
2019-09-23 15:00:02 +00:00
.app_ctx = &uctx,
2019-02-22 15:01:22 +00:00
.free_app_ctx = NULL,
.cb = on_udp,
.err_cb = NULL,
.name = "udp-read",
.flags = EPOLLIN | EPOLLET,
.socklist = NULL
};
2019-04-01 12:16:41 +00:00
evt_core_init(&evts, verbose);
2019-02-22 15:01:22 +00:00
evt_core_add_cat(&evts, &udp_read);
// 3. Register UDP socket
2019-04-18 12:34:38 +00:00
udp_sock = create_udp_server (bindhost, port);
2019-02-22 15:01:22 +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;
sprintf(url, "udp:rw:127.0.0.1:%s", port);
fdinfo.cat->name = "udp-read";
evt_core_add_fd(&evts, &fdinfo);
// 4. Start main loop
evt_core_loop (&evts);
return 0;
usage:
2019-04-18 12:34:38 +00:00
fprintf(stderr, "Usage: %s -p <port> [-v] [-b ip]\n", argv[0]);
2019-02-22 15:01:22 +00:00
}