Example #1
0
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;
}
Example #2
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;
}
Example #3
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 */

}