All pastes #955145 Raw Edit

broo.c

public c v1 · immutable
#955145 ·published 2008-03-24 12:09 UTC
rendered paste body
#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