Created
June 25, 2013 21:29
-
-
Save vi/5862606 to your computer and use it in GitHub Desktop.
UDP relay - for implementing other programs working with UDP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <unistd.h> | |
| #include <stdlib.h> | |
| #include <sys/types.h> | |
| #include <string.h> | |
| #ifndef WIN32 | |
| #include <netdb.h> | |
| #include <sys/socket.h> | |
| #include <sys/select.h> | |
| #include <netinet/in.h> | |
| #else | |
| #define WINVER 0x0501 | |
| #include <winsock2.h> | |
| #include <windows.h> | |
| #include <ws2tcpip.h> | |
| #include <fcntl.h> | |
| #endif | |
| #include <errno.h> | |
| #include <signal.h> | |
| #include <sys/time.h> | |
| #define BUFSIZE 4096 | |
| int s_recv = -1; | |
| int s_send = -1; | |
| int start = 0; | |
| int end = 0; | |
| unsigned char buf[BUFSIZE]; | |
| int main(int argc, char* argv[]) { | |
| if (argc<5 || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-?")) { | |
| fprintf (stderr, | |
| "Usage:\n" | |
| "\tudprelay recv_host recv_port send_host send_port" | |
| "\tCreated by Vitaly \"_Vi\" Shukela\n" | |
| ); | |
| return 1; | |
| } | |
| struct addrinfo hints; | |
| struct addrinfo *recv_addr; | |
| struct addrinfo *send_addr; | |
| memset(&hints, 0, sizeof(struct addrinfo)); | |
| hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ | |
| hints.ai_flags = AI_PASSIVE; | |
| char* recv_host = argv[1]; | |
| char* recv_port = argv[2]; | |
| char* send_host = argv[3]; | |
| char* send_port = argv[4]; | |
| if (!strcmp(recv_host, "NULL")) recv_host=NULL; | |
| if (!strcmp(recv_port, "NULL")) recv_port=NULL; | |
| if (!strcmp(send_host, "NULL")) send_host=NULL; | |
| if (!strcmp(send_port, "NULL")) send_port=NULL; | |
| int gai_error; | |
| gai_error=getaddrinfo(recv_host,recv_port, &hints, &recv_addr); | |
| if (gai_error) { fprintf(stderr, "getaddrinfo 1: %s\n",gai_strerror(gai_error)); return 4; } | |
| if (!recv_addr) { fprintf(stderr, "getaddrinfo returned no addresses\n"); return 6; } | |
| if (recv_addr->ai_next) { | |
| fprintf(stderr, "Warning: using only one of addresses retuned by getaddrinfo\n"); | |
| } | |
| hints.ai_flags &= !AI_PASSIVE; | |
| gai_error=getaddrinfo(send_host, send_port, &hints, &send_addr); | |
| if (gai_error) { fprintf(stderr, "getaddrinfo 2: %s\n",gai_strerror(gai_error)); return 13; } | |
| if (!send_addr) { fprintf(stderr, "getaddrinfo 2 returned no addresses\n"); return 15; } | |
| if (send_addr->ai_next) { | |
| fprintf(stderr, "Warning: using only one of addresses retuned by getaddrinfo 2\n"); | |
| } | |
| s_recv = socket(recv_addr->ai_family, recv_addr->ai_socktype, recv_addr->ai_protocol); | |
| if (s_recv == -1) { perror("socket"); return 7; } | |
| { | |
| int one = 1; | |
| setsockopt(s_recv, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); | |
| } | |
| if (bind(s_recv, recv_addr->ai_addr, recv_addr->ai_addrlen)) { perror("bind"); return 5; } | |
| s_send = socket(send_addr->ai_family, send_addr->ai_socktype, send_addr->ai_protocol); | |
| if (s_send == -1) { perror("socket 2"); return 12; } | |
| //char should_be_enough[1024]; | |
| struct sockaddr peeraddr ; | |
| socklen_t peeraddrlen = sizeof peeraddr; | |
| for (;;) { | |
| fd_set rfds; | |
| FD_ZERO(&rfds); | |
| int maxfd = 0; | |
| FD_SET(s_recv, &rfds); | |
| FD_SET(s_send, &rfds); | |
| if (s_recv >= maxfd) maxfd = s_recv+1; | |
| if (s_send >= maxfd) maxfd = s_send+1; | |
| struct timeval *timeout = NULL; | |
| struct timeval tv; | |
| int select_ret = select(maxfd, &rfds, NULL, NULL, timeout); | |
| if (select_ret==-1) { | |
| if (errno==EAGAIN || errno==EINTR) continue; | |
| perror("select"); | |
| return 91; | |
| } | |
| if (FD_ISSET(s_recv, &rfds)) { | |
| int ret = recvfrom(s_recv, buf, BUFSIZE, 0, &peeraddr, &peeraddrlen); | |
| sendto(s_send, buf, ret, 0, send_addr->ai_addr, send_addr->ai_addrlen); | |
| } | |
| if (FD_ISSET(s_send, &rfds)) { | |
| int ret = recv(s_send, buf, BUFSIZE, 0); | |
| sendto(s_recv, buf, ret, 0, &peeraddr, peeraddrlen); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment