#include #include #include #include #include #include #include #include #include #include // Source <--> Muxer <--> Multiple Target int main(int argc, char* argv[]) { int ret, flags; int listener, sender, ep; int PORT_ENDP=29000, PORT_UR_BEGIN=29100, PORT_UR_SIZE=10; while((ret = getopt(argc, argv, "hl:t:s:")) != -1) { switch(ret) { case 'l': PORT_ENDP=atoi(optarg); break; case 't': PORT_UR_BEGIN=atoi(optarg); break; case 's': PORT_UR_SIZE=atoi(optarg); break; case 'h': default: fprintf(stderr, "Usage: %s -l ListenPort -t TargetPort -s TargetRange\n", argv[0]); exit(1); } } fprintf(stderr, "listening on %d, sending to [%d,%d)\n", PORT_ENDP, PORT_UR_BEGIN, PORT_UR_BEGIN+PORT_UR_SIZE); listener = socket(AF_INET, SOCK_DGRAM, 0); struct sockaddr_in saddr; memset(&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = INADDR_ANY; saddr.sin_port = htons(PORT_ENDP); ret = bind(listener, (const struct sockaddr*)&saddr, sizeof(saddr)); if (ret < 0) { perror("bind"); exit(1); } sender = socket(AF_INET, SOCK_DGRAM, 0); // Set to non-blocking flags = fcntl(listener, F_GETFL, 0); if (flags < 0) { perror("fcntl"); exit(1); } flags |= O_NONBLOCK; fcntl(listener, F_SETFL, flags); flags = fcntl(sender, F_GETFL, 0); if (flags < 0) { perror("fcntl"); exit(1); } flags |= O_NONBLOCK; fcntl(sender, F_SETFL, flags); ep = epoll_create(1024); struct epoll_event ev1; ev1.events = EPOLLIN | EPOLLET; ev1.data.fd = listener; struct epoll_event ev2; ev2.events = EPOLLIN | EPOLLET; ev2.data.fd = sender; epoll_ctl(ep, EPOLL_CTL_ADD, listener, &ev1); epoll_ctl(ep, EPOLL_CTL_ADD, sender, &ev2); struct epoll_event events[1024]; struct sockaddr_in* addrTargets = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in) * PORT_UR_SIZE); memset(addrTargets, 0, sizeof(struct sockaddr_in) * PORT_UR_SIZE); for(int i=0; i 0) { sendto(sender, buffer, nsize, 0, (const struct sockaddr*)(addrTargets + rrOffset), sizeof(struct sockaddr_in)); if (++rrOffset >= PORT_UR_SIZE) { rrOffset = 0; } } if (nsize < 0 && errno != EAGAIN) { perror("recvfrom: "); } } else if (events[i].data.fd == sender) { int nsize; while((nsize = recvfrom(sender, buffer, sizeof(buffer), 0, NULL, NULL)) > 0) { sendto(listener, buffer, nsize, 0, (const struct sockaddr*)&addrFrom, sizeof(struct sockaddr_in)); } if (nsize < 0 && errno != EAGAIN) { perror("recvfrom: "); } } } } }