From 184a9e1b70a49263834bd26c91b53875b5853e66 Mon Sep 17 00:00:00 2001 From: Mazet Laurent Date: Tue, 2 Sep 2025 19:29:46 +0200 Subject: [PATCH] add mono-directional sockets for udp connection --- ulvpn.c | 93 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 66 insertions(+), 27 deletions(-) diff --git a/ulvpn.c b/ulvpn.c index 112f397..243a1dd 100644 --- a/ulvpn.c +++ b/ulvpn.c @@ -38,8 +38,10 @@ char *version = "0.9"; char *devtun = "tun://tun0:1440"; char *loctun = "tun://10.2.0.1"; char *remtun = "tun://10.2.1.0"; -char *locudp = "udp://10.1.0.1:1234"; -char *remudp = "udp://10.1.0.2:1235"; +char *locudprx = "udp://10.1.0.1:1234"; +char *locudptx = NULL; +char *remudprx = "udp://10.1.0.2:1235"; +char *remudptx = NULL; char *cmlocblack = "lo://00:00:00:00:00:00/0829"; char *cmremblack = "lo://00:00:00:00:00:00/0839"; char *cmlocred = "lo://00:00:00:00:00:00/0809"; @@ -98,14 +100,22 @@ void sig_handler (int sig) void usage (void) { - printf ("usage: %s [-d devtun] [-h] [-l loctun] [-n mod] [-r remtun] [-t locudp] [-u remudp] [-v int] [-x url url] [-y url url] [-w]\n", progname); + printf ("usage: %s [-d devtun] [-h] [-l loctun] [-n mod] [-r remtun] [-t[r|t] locudp] [-u[r|t] remudp] [-v int] [-x url url] [-y url url] [-w]\n", progname); printf (" -d: dev tun (%s)\n", devtun); printf (" -h: help message\n"); printf (" -l: local tun (%s)\n", loctun); printf (" -n: desactivate module (tun,udp,red,black)\n"); printf (" -r: remote tun (%s)\n", remtun); - printf (" -t: local udp (%s)\n", locudp); - printf (" -u: remote udp (%s)\n", remudp); + if (locudprx != locudptx) { + printf (" -t[r|t]: local udp [rx|tx] (%s|%s)\n", locudprx, locudptx); + } else { + printf (" -t[r|t]: local udp [rx|tx] (%s)\n", locudprx); + } + if (remudprx != remudptx) { + printf (" -u[r|t]: remote udp [rx|tx] (%s|%s)\n", remudprx, remudptx); + } else { + printf (" -u[r|t]: remote udp [rx|tx] (%s)\n", remudprx); + } printf (" -v: program verbose level [%d..%d] (%d)\n", ERROR, TRACE, GET_VERBOSE_LEVEL (ulvpn)); printf (" -V: library verbose level [%d..%d] (%d)\n", ERROR, TRACE, GET_VERBOSE_LEVEL (mapec)); printf (" -x: black CM service (%s|%s)\n", cmlocblack, cmremblack); @@ -247,6 +257,8 @@ int depack_clear_data (uint8_t *buffer, int len, int maxlen) int main (int argc, char **argv) { + locudptx = locudprx; + remudptx = remudprx; /* get basename */ char *ptr = progname = argv[0]; @@ -266,6 +278,7 @@ int main (int argc, char **argv) return 1; } char c = arg[1]; + int way = 0; switch (c) { case 'd': arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; @@ -294,8 +307,8 @@ int main (int argc, char **argv) loctun = NULL; remtun = NULL; } else if (strcmp (arg, "udp") == 0) { - locudp = NULL; - remudp = NULL; + locudprx = locudptx = NULL; + remudprx = remudptx = NULL; } else if (strcmp (arg, "black") == 0) { cmlocblack = NULL; cmremblack = NULL; @@ -317,20 +330,30 @@ int main (int argc, char **argv) remtun = arg; break; case 't': - arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + way = (arg[2] == 'r') ? 1 : (arg[2] == 't') ? -1 : 0; + arg = (--argc > 0) ? *(++argv) : NULL; if (arg == NULL) { VERBOSE (ulvpn, ERROR, PRINTF ("%s: local udp not specified\n", progname)); return 1; } - locudp = arg; + switch (way) { + case 1: locudprx = arg; break; + case -1: locudptx = arg; break; + default: locudprx = locudptx = arg; break; + } break; case 'u': - arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + way = (arg[2] == 'r') ? 1 : (arg[2] == 't') ? -1 : 0; + arg = (--argc > 0) ? *(++argv) : NULL; if (arg == NULL) { VERBOSE (ulvpn, ERROR, PRINTF ("%s: remote udp not specified\n", progname)); return 1; } - remudp = arg; + switch (way) { + case 1: remudprx = arg; break; + case -1: remudptx = arg; break; + default: remudprx = remudptx = arg; break; + } break; case 'v': arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; @@ -382,11 +405,20 @@ int main (int argc, char **argv) VERBOSE (ulvpn, ERROR, PRINTF ("can't open communication for %s %s %s\n", devtun, loctun, remtun)); return -1; } - int udp_fd = -1; - if (((locudp) && (remudp)) && ((udp_fd = MAPEC_Connect (locudp, remudp, NULL)) < 0)) { - VERBOSE (ulvpn, ERROR, PRINTF ("can't open communication for %s %s\n", locudp, remudp)); + int udprx_fd = -1; + if (((locudprx) && (remudprx)) && ((udprx_fd = MAPEC_Connect (locudprx, remudprx, NULL)) < 0)) { + VERBOSE (ulvpn, ERROR, PRINTF ("can't open communication for %s %s %s\n", locudprx, remudprx, (locudprx == locudptx) ? "RX/TX" : "RX")); return -1; } + int udptx_fd = -1; + if (locudprx == locudptx) { + udptx_fd = udprx_fd; + } else { + if (((locudptx) && (remudptx)) && ((udptx_fd = MAPEC_Connect (locudptx, remudptx, NULL)) < 0)) { + VERBOSE (ulvpn, ERROR, PRINTF ("can't open communication for %s %s TX\n", locudptx, remudptx)); + return -1; + } + } /* init crypto module communication channels */ int rxblack_fd = (cmlocblack) ? MOREP_Connect (cmlocblack) : -1; @@ -405,7 +437,7 @@ int main (int argc, char **argv) return -1; } - VERBOSE (ulvpn, INFO, PRINTF ("fids: %d %d %d %d %d %d\n", tun_fd, udp_fd, rxblack_fd, txblack_fd, rxred_fd, txred_fd)); + VERBOSE (ulvpn, INFO, PRINTF ("fids: %d %d %d %d %d %d %d\n", tun_fd, udprx_fd, udptx_fd, rxblack_fd, txblack_fd, rxred_fd, txred_fd)); /* signals */ sigset_t mask; @@ -433,10 +465,10 @@ int main (int argc, char **argv) max_fd = tun_fd; } } - if (udp_fd >= 0) { - FD_SET (udp_fd, &readset); - if (max_fd < udp_fd) { - max_fd = udp_fd; + if (udprx_fd >= 0) { + FD_SET (udprx_fd, &readset); + if (max_fd < udprx_fd) { + max_fd = udprx_fd; } } if (rxblack_fd >= 0) { @@ -488,8 +520,8 @@ int main (int argc, char **argv) VERBOSE (ulvpn, DEBUG, PRINTF ("send %d bytes to CM red\n", txlen)); } } - } else if (udp_fd >= 0) { - int txlen = MAPEC_Send (udp_fd, buffer, rxlen); + } else if (udptx_fd >= 0) { + int txlen = MAPEC_Send (udptx_fd, buffer, rxlen); stat_udp_fd.tx++; if (txlen <= 0) { VERBOSE (ulvpn, WARNING, PRINTF ("error when sending to udp\n")); @@ -501,9 +533,9 @@ int main (int argc, char **argv) } } - } else if (FD_ISSET (udp_fd, &readset)) { + } else if (FD_ISSET (udprx_fd, &readset)) { uint8_t buffer[MAXPAYLOAD] = {0}; - int rxlen = MAPEC_Receive (udp_fd, buffer, sizeof (buffer)); + int rxlen = MAPEC_Receive (udprx_fd, buffer, sizeof (buffer)); stat_udp_fd.rx++; if (rxlen < 0) { VERBOSE (ulvpn, WARNING, PRINTF ("error when receiving from udp\n")); @@ -558,13 +590,13 @@ int main (int argc, char **argv) } if (msgtype == 0x01) { - if (udp_fd >= 0) { + if (udptx_fd >= 0) { int txlen = depack_encrypted_data (buffer, rxlen, sizeof (buffer)); if (txlen <= 0) { VERBOSE (ulvpn, WARNING, PRINTF ("error when depacking encrypted data\n")); } else { VERBOSE (ulvpn, DEBUG, PRINTF ("depacking %d bytes\n", txlen)); - txlen = MAPEC_Send (udp_fd, buffer, txlen); + txlen = MAPEC_Send (udptx_fd, buffer, txlen); stat_udp_fd.tx++; if (txlen <= 0) { VERBOSE (ulvpn, WARNING, PRINTF ("error when sending to udp\n")); @@ -633,7 +665,10 @@ int main (int argc, char **argv) /* cleaning */ close (tun_fd); - close (udp_fd); + close (udprx_fd); + if (udprx_fd != udptx_fd) { + close (udptx_fd); + } return rc; } @@ -655,7 +690,7 @@ int main (int argc, char **argv) /* test: ulvpn.exe -n 2>&1 | grep 'module not specified' */ /* test: ulvpn.exe -n foo 2>&1 | grep 'unknown module' */ /* test: ulvpn.exe -n tun -h | grep 'dev tun ((null))' */ -/* test: ulvpn.exe -n udp -h | grep 'local udp ((null))' */ +/* test: ulvpn.exe -n udp -h | fgrep 'local udp [rx|tx] ((null))' */ /* test: ulvpn.exe -n black -h | grep 'black CM service ((null)|(null))' */ /* test: ulvpn.exe -n red -h | grep 'red CM service ((null)|(null))' */ @@ -691,4 +726,8 @@ int main (int argc, char **argv) /* test: ulvpn.exe -v 5 -n black -n red -t udp://\*:1234 -u udp://localhost:1235 > ulvpn.log & pid=$!; sleep 1; echo TEST | nc -Nuq0 10.2.1.1 3000; kill -TRAP $pid; sleep 1; kill -HUP $pid; sleep 1; echo TEST | nc -Nuq0 10.2.1.1 3000; kill -TRAP $pid; sleep 1; kill -TERM $pid; grep 'tun: RX' ulvpn.log | wc -l | xargs test 2 -eq */ +/* test: ulvpn.exe -v 5 -n black -n red -tr udp://localhost:1234 -ur udp://localhost:1235 -tt udp://localhost:1236 -ut udp://localhost:1237 & pid1=$!; sleep 1; nc -ul 1237 > pcap & pid2=$!; sleep 1; echo | nc -Nuq0 10.2.1.1 3000; echo TEST | nc -Nuq0 10.2.1.1 3000; sleep 1; kill -TERM $pid1 $pid2; strings pcap | grep -q TEST */ +/* test: ulvpn.exe -v 5 -n black -n red -l tun://10.2.1.1 -r tun://10.2.0.0 -tr udp://localhost:1234 -ur udp://localhost:1235 -tt udp://localhost:1236 -ut udp://localhost:1237 & pid1=$!; sleep 1; nc -ul 3000 > text & pid2=$!; sleep 1; cat pcap | nc -4Nuq0 -p 1235 localhost 1234; sleep 1; kill -TERM $pid1 $pid2; test "$(cat text)" = TEST */ +/* test: rm -f pcap text */ + /* vim: set ts=4 sw=4 si et: */ -- 2.30.2