#include <sys/socket.h>#include <sys/types.h>#include <arpa/inet.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <time.h>#include <string.h>#include <ctype.h>#include <netinet/in.h>#include <sys/wait.h>#include <signal.h>#include <poll.h>#define WAN_IPADDR "127.0.0.1" /* this will be our dummy server for now */#define WAN_PORT 3490 /* use the child forking example server */#define LAN_IPADDR INADDR_ANY /* auto bind to my IP */#define LAN_PORT 1111 /* change as necessary */#define MAX_DATA_LEN 100000 /* max bytes of data from data source */#define MAX_CLIENTS 10 /* how many clients can there be? */#define WAN 0#define LAN 1#define NFD 2 /* number of file descriptors to poll */char* ParseMessage(char* rawMessage) /* no specs on the actual translation yet, so just tolower()ing for now */{ char temp[MAX_DATA_LEN] = {0}; int i; for ( i=0; i < strlen(rawMessage); i++ ) { temp[i] = tolower(rawMessage[i]); } return temp;}int main(int argc, char *argv[]){ struct pollfd pfd[NFD]; //NFD-element array of polled file descriptors int fd_WAN, fd_LAN, tmp; //file descriptors for reading from WAN side, writing to LAN side int nsd[MAX_CLIENTS]={0}; //dynamically created file descriptors per client connection int err, slen, yes=1, c, n; //return vals, etc struct sockaddr_in saddr_lan, saddr_wan; //Internet socket address structures int clientnum=0; //keep track of how many clients char rawMessage[MAX_DATA_LEN+1]; //buffer for message, pre parsing char cookedMessage[MAX_DATA_LEN+1]; //buffer for message, post parsing //char testmsg[] = "THIS IS THE END OF THE WORLD AS WE KNOW IT"; //printf("%s\n", ParseMessage(testmsg)); /* Create descriptors, configure sockets */ //WAN side (as a client) //if ( (fd_WAN = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) if ( (fd_WAN = socket(AF_INET, SOCK_STREAM, O_NONBLOCK)) < 0 ) { fprintf(stderr,"Error creating WAN socket\n"); exit(-1); } memset(&saddr_wan, 0, sizeof(saddr_wan)); saddr_wan.sin_family = AF_INET; saddr_wan.sin_port = htons(WAN_PORT); //Set the remote (data server) IP address if ( inet_aton(WAN_IPADDR, &saddr_wan.sin_addr) <= 0 ) { printf("ERROR: Invalid remote IP address.\n"); exit(-1); } //LAN side (as a server) if ((fd_LAN = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } if (setsockopt(fd_LAN, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } saddr_lan.sin_family = AF_INET; // host byte order saddr_lan.sin_port = htons(LAN_PORT); // short, network byte order saddr_lan.sin_addr.s_addr = LAN_IPADDR; memset(saddr_lan.sin_zero, '\0', sizeof saddr_lan.sin_zero); if (bind(fd_LAN, (struct sockaddr *)&saddr_lan, sizeof saddr_lan) == -1) { perror("bind"); exit(1); } if (listen(fd_LAN, MAX_CLIENTS) == -1) { perror("listen"); exit(1); } /* Now connect to the data source */ if ( connect(fd_WAN, (struct sockaddr *) &saddr_wan, sizeof(saddr_wan) ) < 0 ) { printf("ERROR: Unable to connect()\n"); exit(-1); } /* Initialize poll structures */ pfd[WAN].fd = fd_WAN; pfd[WAN].events = POLLIN; pfd[WAN].revents = 0; pfd[LAN].fd = fd_LAN; pfd[LAN].events = POLLIN; pfd[LAN].revents = 0; memset(nsd, 0, sizeof(nsd)); /* Pass data through asynchronously */ while (1) { /* Continuously poll on both the WAN and LAN sides: */ /* When data is available on WAN side, slurp it down, translate it */ /* When a new LAN client connects, accept and add the fd to a local array */ err = poll(pfd, NFD, 0); if (err < 0) /* No new activity */ { perror("poll failed"); fprintf(stderr, "\r"); } else if (err > 0) /* There is activity */ { if (pfd[WAN].revents == POLLIN) /* new data */ { /* Read from socket, up to MAX_DATA_LEN bytes */ fprintf(stderr, "after POLLIN\n");//DEBUG while ( (n = read(fd_WAN, rawMessage, MAX_DATA_LEN)) > 0 ) { rawMessage[n] = 0; fprintf(stderr, "in while, after read");//DEBUG strncpy(cookedMessage, ParseMessage(rawMessage), MAX_DATA_LEN); for(c = 0; c < MAX_CLIENTS; c++) //for each client, dump cooked message { if (nsd[c] != 0) { if ( send(nsd[c],cookedMessage,strlen(cookedMessage),0) == -1 ) { perror("send"); //close(nsd[c]);//should I do this??? } } } } fprintf(stderr, "after while");//DEBUG if ( n < 0 ) { printf("ERROR: Couldn't read()\n"); exit(-1); } pfd[WAN].revents = 0; } if (pfd[LAN].revents == POLLIN) /* new client */ { slen = sizeof(saddr_lan); /* Add latest client to fd list */#if 0 if ( nsd[clientnum++] = accept(fd_LAN, (struct sockaddr *)&saddr_lan, &slen) == -1 ) { perror("accept"); //continue; } else { printf("DEBUG: clientnum = %d\n", clientnum); }#else tmp = accept(fd_LAN, (struct sockaddr *)&saddr_lan, &slen); if (tmp < 0) { perror("accept"); } else { for (c = 0; c < MAX_CLIENTS; c++) { if (nsd[c] == 0) { nsd[c] = tmp; break; } } if (c == MAX_CLIENTS) { fprintf(stderr, "No available client slots, closing connection\n"); close(tmp); } } #endif pfd[LAN].revents = 0; } } }//------END WHILE return 0;}//-----------------------------------------END MAIN