Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/Tools/UDP_Proxy/udpproxy.c
Views: 1798
/*1UDP proxy code for connecting two UDP endpoints2Released under GNU GPLv33Author: Andrew Tridgell4*/5#define _GNU_SOURCE67#include <stdio.h>8#include <stdlib.h>9#include <string.h>10#include <time.h>11#include <errno.h>12#include <stdbool.h>13#include <sys/socket.h>14#include <netdb.h>15#include <unistd.h>16#include <stdlib.h>17#include <fcntl.h>18#include <sys/types.h>19#include <sys/time.h>20#include <arpa/inet.h>21#include <netinet/in.h>2223static bool verbose;24static int listen_port1, listen_port2;2526static double timestamp()27{28struct timeval tval;29gettimeofday(&tval,NULL);30return tval.tv_sec + (tval.tv_usec*1.0e-6);31}3233/*34open a socket of the specified type, port and address for incoming data35*/36int open_socket_in(int port)37{38struct sockaddr_in sock;39int res;40int one=1;4142memset(&sock,0,sizeof(sock));4344#ifdef HAVE_SOCK_SIN_LEN45sock.sin_len = sizeof(sock);46#endif47sock.sin_port = htons(port);48sock.sin_family = AF_INET;4950res = socket(AF_INET, SOCK_DGRAM, 0);51if (res == -1) {52fprintf(stderr, "socket failed\n"); return -1;53return -1;54}5556setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));5758if (bind(res, (struct sockaddr *)&sock, sizeof(sock)) < 0) {59return(-1);60}6162return res;63}6465static void main_loop(int sock1, int sock2)66{67unsigned char buf[10240];68bool have_conn1=false;69bool have_conn2=false;70double last_pkt1=0;71double last_pkt2=0;72int fdmax = (sock1>sock2?sock1:sock2)+1;73double last_stats = timestamp();74uint32_t bytes_in1=0;75uint32_t bytes_in2=0;7677while (1) {78fd_set fds;79int ret;80struct timeval tval;81double now = timestamp();8283if (verbose && now - last_stats > 1) {84double dt = now - last_stats;85printf("%u: %u bytes/sec %u: %u bytes/sec\n",86(unsigned)listen_port1, (unsigned)(bytes_in1/dt),87(unsigned)listen_port2, (unsigned)(bytes_in2/dt));88bytes_in1 = bytes_in2 = 0;89last_stats = now;90}9192if (have_conn1 && now - last_pkt1 > 10) {93break;94}95if (have_conn2 && now - last_pkt2 > 10) {96break;97}9899FD_ZERO(&fds);100FD_SET(sock1, &fds);101FD_SET(sock2, &fds);102103tval.tv_sec = 10;104tval.tv_usec = 0;105106ret = select(fdmax, &fds, NULL, NULL, &tval);107if (ret == -1 && errno == EINTR) continue;108if (ret <= 0) break;109110now = timestamp();111112if (FD_ISSET(sock1, &fds)) {113struct sockaddr_in from;114socklen_t fromlen = sizeof(from);115int n = recvfrom(sock1, buf, sizeof(buf), 0,116(struct sockaddr *)&from, &fromlen);117if (n <= 0) break;118119bytes_in1 += n;120121last_pkt1 = now;122if (!have_conn1) {123if (connect(sock1, (struct sockaddr *)&from, fromlen) != 0) {124break;125}126have_conn1 = true;127printf("have conn1\n");128}129if (have_conn2) {130if (send(sock2, buf, n, 0) != n) {131break;132}133}134}135136if (FD_ISSET(sock2, &fds)) {137struct sockaddr_in from;138socklen_t fromlen = sizeof(from);139int n = recvfrom(sock2, buf, sizeof(buf), 0,140(struct sockaddr *)&from, &fromlen);141if (n <= 0) break;142143bytes_in2 += n;144145last_pkt2 = now;146if (!have_conn2) {147if (connect(sock2, (struct sockaddr *)&from, fromlen) != 0) {148break;149}150have_conn2 = true;151printf("have conn2\n");152}153if (have_conn1) {154if (send(sock1, buf, n, 0) != n) {155break;156}157}158}159}160}161162int main(int argc, char *argv[])163{164int sock_in1, sock_in2;165166if (argc < 3) {167printf("Usage: udpproxy <port1> <port2>\n");168exit(1);169}170if (argc > 3) {171verbose = strcmp(argv[3],"-v") == 0;172printf("verbose=%u\n", (unsigned)verbose);173}174175while (true) {176listen_port1 = atoi(argv[1]);177listen_port2 = atoi(argv[2]);178179printf("Opening sockets %u %u\n", listen_port1, listen_port2);180sock_in1 = open_socket_in(listen_port1);181sock_in2 = open_socket_in(listen_port2);182if (sock_in1 == -1 || sock_in2 == -1) {183fprintf(stderr,"sock on ports %d or %d failed - %s\n",184listen_port1, listen_port2, strerror(errno));185exit(1);186}187188main_loop(sock_in1, sock_in2);189close(sock_in1);190close(sock_in2);191}192193return 0;194}195196197