/* File: proxy.c Description: a general-purpose proxy optimized for a large number of concurrent connections. */ #include #include #include #include #include #include #include #include #include "config.h" #include "proxy_protos.h" extern char *optarg; extern int optind; static int sig; /* usage() */ static void usage ( void ); /* signal handler */ static void sighandler ( int signum ); /* main program */ int main ( int argc, char **argv ) { struct kevent ke; struct mdata *md; void (*ef)(struct kevent *, struct mdata * ); char ch; unsigned short sp = 0; unsigned short lp = 0; char lh[MAXPATHLEN]; char rh[MAXPATHLEN]; char lf[MAXPATHLEN]; struct timespec ts; int verbose = 0; /* get options */ memset(lh,0,sizeof(lh)); memset(rh,0,sizeof(rh)); memset(lf,0,sizeof(lf)); while ( (ch = getopt(argc,argv,"a:b:h:p:l:v")) != -1 ) { switch (ch) { case 'a': strncpy(lh,optarg,MAXPATHLEN-1); break; case 'b': lp = (unsigned short)strtoul(optarg,NULL,10); break; case 'h': strncpy(rh,optarg,MAXPATHLEN-1); break; case 'p': sp = (unsigned short)strtoul(optarg,NULL,10); break; case 'l': strncpy(lf,optarg,MAXPATHLEN-1); break; case 'v': verbose = 1; break; } } argc -= optind; argv += optind; /* usage() */ if ( !sp || !lh[0] || !lp || !rh[0] ) { usage(); exit(1); } fprintf(stderr,"Local host: %s\n", lh); fprintf(stderr,"Local port: %u\n", lp); fprintf(stderr,"Server host: %s\n", rh); fprintf(stderr,"Server port: %u\n", sp); /* set up signal handlers */ signal ( SIGINT, sighandler ); signal ( SIGTERM, sighandler ); signal ( SIGKILL, sighandler ); if ( fork() ) exit(0); /* allocate the main data structure */ if ( !(md = init_mdata(lh,lp,rh,sp,lf,verbose)) ) { perror("init_mdata"); exit(2); } /* set up the event queue, bind to the local port, and listen */ if ( !pay_attention(md) ) { perror("pay_attention"); deinit_mdata(md); exit(3); } /* enter the main event loop until a signal is received */ log_msg(md, "Entering event loop now"); /* 100 microsecond timeout */ ts.tv_sec = 0; ts.tv_nsec = 100000; while ( !sig ) { while ( kevent(md->kq,NULL,0,&ke,1,&ts) > 0 ) { md->events++; ef = ke.udata; ef(&ke,md); } md->iterations++; } /* print some info from this session */ print_stats(md); /* free allocated memory */ deinit_mdata(md); return 0; } static void usage ( void ) { fprintf(stderr,"Usage: %s -a -b -h -p [-l ] [-v]\n", PACKAGE); } /* signal handler, used for SIGINT, SIGTERM, SIGKILL */ static void sighandler ( int signum ) { sig = signum; }