int main(void) { struct sockaddr_in saddr = { .sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_ANY), .sin_port = htons(513) }; socklen_t slen = sizeof(saddr); int fd, a; close(0); close(1); if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) err(1, "signal SIGCHLD"); if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) err(1, "signal SIGPIPE"); fd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (fd < 0) err(1, "socket"); a = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &a, sizeof(a))) err(1, "setsockopt"); if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr))) err(1, "bind"); if (listen(fd, 1)) err(1, "listen"); a = accept(fd, (struct sockaddr *)&saddr, &slen); if (a < 0) err(1, "accept"); handle_con(a); close(a); close(fd); return 0; }
/******************* * main() function *******************/ int main( int argc, char **argv ) { int force_load = FALSE; int sksize; char s[256]; struct sigaction sa; int res; int i; int act=-1; FILE *f; int allow; uint32_t adam; /* ** Parse command line parameters */ for( i=1; i<argc; i++ ) if( cmdln_arg_in(i,"-h","--help") ) { print_help(argv[0]); return 1; } else if( cmdln_arg_in(i,"-v","--version") ) { print_ver(); return 1; } else if( cmdln_arg_in(i,"-c","--config") ) strcpy(sz_cfgfile,argv[++i]); else if( cmdln_arg_in(i,"-f","--forceload") ) force_load = TRUE; else if( !strcmp(argv[i],"start") ) act = ACT_START; else if( !strcmp(argv[i],"shutdown") ) act = ACT_SHUTDOWN; else { fprintf(stderr,"Invalid argument: %s\n",argv[i]); return 2; } /* ** If mocks was run with no action parameter, output ** a short error message and exit. */ if( act<0 ) { fprintf(stderr,"Missing action\nSee %s -h for help\n",argv[0]); return 1; } /* ** Load and parse configuration file */ if( load_config() != ERR_NONE ) { fprintf(stderr,"Missing or bad configuration file.\n"); return 2; } /* ** Are we starting or shutting down? */ if( act==ACT_SHUTDOWN ) { printf("Shutting down "PROG_NAME" ... "); fflush(stdout); f = fopen(sz_pidfile,"r"); if( !f ) { printf("ERROR\n"); printf("\tPID file could not be opened "); printf("(maybe "PROG_NAME" is not running?)\n"); return 2; } if( fscanf(f,"%u",&res)<=0 ) { printf("ERROR\n"); printf("\tCould not read PID file\n"); return 2; } fclose(f); if( res<=0 ) { printf("ERROR\n"); printf("\tInvalid PID\n"); return 2; } if( kill(-res,SIGTERM)<0 ) { printf("ERROR\n"); printf("\tkill() failed\n"); return 2; } /* ** Give mocks some time to shut down cleanly and ** then kill it */ sleep(shutd_timeo); kill(-res,SIGKILL); printf("OK\n"); logstr(PROG_NAME" "PROG_VERSION" killed",NULL); return 0; } else { printf("Starting "PROG_NAME" ... "); fflush(stdout); } /* ** Check to see if a PID file already exists */ if( (f=fopen(sz_pidfile,"r"))!=NULL && !force_load ) { printf("\nAn instance of "PROG_NAME" might already be running.\n"); printf("Use %s -f to force execution\n",argv[0]); fclose(f); return 2; } /* ** Register signal handler for SIGCHILD and SIGTERM */ memset(&sa,0,sizeof(struct sigaction)); sa.sa_handler = handle_sig; sigaction(SIGTERM,&sa,0); sigaction(SIGCHLD,&sa,0); sigaction(SIGALRM,&sa,0); /* ** Start listening for client connections */ ad_socks.sa_family = AF_INET; *(ushort*)ad_socks.sa_data = htons(socks_port); res = open_serv_sock(&sk_socks,&ad_socks); if( res != ERR_NONE ) { printf("ERROR\n\t%s\n",sz_error[res]); return res; } /* ** SOCKS daemon successfully started */ printf("OK\n"); strcpy(s,PROG_NAME" "PROG_VERSION" started"); logstr(s,NULL); strcpy(s,"Listening on "); addr_to_ip(&ad_socks,s+strlen(s)); sprintf( s+strlen(s), ":%u", ntohs(((struct sockaddr_in*)&ad_socks)->sin_port) ); logstr(s,NULL); if( up_proxy ) { strcpy(s,"Relaying all traffic through "); sprintf( s+strlen(s),"%u.%u.%u.%u:%u", up_proxy->ip & 0xFF, (up_proxy->ip >> 8) & 0xFF, (up_proxy->ip >> 16) & 0xFF, up_proxy->ip >> 24, up_proxy->port ); logstr(s,NULL); } /* ** Now, remember we must act as a daemon, ** so let's fork() and detach. */ switch( fork() ) { case 0: setsid(); break; case -1: printf("ERROR\n\tfork() failed - cannot detach daemon\n"); exit(1); default: exit(0); } /* ** Create PID file */ f = fopen(sz_pidfile,"w"); if( !f ) logstr("WARNING: PID file could not be created!\n",NULL); else { fprintf(f,"%u",getpid()); fclose(f); } /* ** Entering the accept loop */ while( 1 ) { /* ** If we're already working with the maximum number of ** client connections, wake up every second to check ** if any connection closed and if not, ignore any other ** connection requests. */ if( con_cnt >= max_con_cnt ) { sleep(1); continue; } sksize = SOCK_SIZE; sk_client = accept( sk_socks,&ad_client,&sksize ); if( sk_client==-1 ) { if( errno!=EINTR ) logstr("Error: accept() failed",NULL); continue; } /* * Match the connection against our * client filter. */ allow = (filter_policy == FP_ALLOW); for( i=0; i<filter_except_cnt; i++ ) { memcpy(&adam,ad_client.sa_data+2,4); adam ^= filter_excepts[i]; adam &= htonl(0xFFFFFFFF << (32-filter_except_masks[i])); if( !adam ) { allow = !allow; break; } } if( !allow ) { logstr("Blocked by filter!",&ad_client); close(sk_client); continue; } switch( fork() ) { case 0: child = 1; close(sk_socks); logstr("Incoming connection",&ad_client); res = handle_con(); close(sk_client); exit(res); break; case -1: logstr("Could not accept connection (fork() error)",&ad_client); close(sk_client); break; default: if( ++con_cnt >= max_con_cnt ) { printf("Maximum daemon load reached: %d active connections", con_cnt); logstr(s,NULL); } close(sk_client); break; } /* end switch */ } /* end while */ close(sk_socks); return 0; }
int main(int argc, char *argv[]) { #ifdef FORK int pid; #endif unsigned int clilen; int sockfd, newsockfd, portno, on; struct sockaddr_in serv_addr, cli_addr; f=fopen("/root/ch3.log","a"); signal(SIGCHLD, handle_sig); if (argc < 2) { fprintf(stderr,"error: no port provided\n"); exit(1); } sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("error: opening socket"); on = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) error("error: set socket option"); memset((char *) &serv_addr, 0, sizeof(serv_addr)); portno = atoi(argv[1]); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("error: bind"); listen(sockfd,5); clilen = sizeof(cli_addr); while (1) { // printf("server: Listening to incoming connections...\n\n"); newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd < 0) error("error: accept"); printf("Handling new socket\n"); #ifdef FORK if(enable_fork){ pid = fork(); }else{ pid = 0; } if (pid < 0) error("error: fork"); if (pid == 0) { close(sockfd); #endif /* drop privileges */ handle_con(newsockfd); #ifdef FORK exit(0); } else close(newsockfd); #endif } return 0; /* we never get here */ }