Beispiel #1
0
void RunnerThread::run()
{
  //cout << "MarSystemThread: running" << endl;

  m_system->updControl("mrs_bool/active", true);

  while(!m_stop && m_ticks)
  {
    //cout << "tick" << endl;
    process_requests();

    m_system->tick();

    for (const auto & mapping : m_shared->controls)
      mapping.second->push();

    if (m_ticks > 0)
      --m_ticks;
  }

  m_system->updControl("mrs_bool/active", false);

  // make sure not to miss latest updates:
  process_requests();
}
Beispiel #2
0
int main(int argc,char **argv)
{
   int s,port;

   if (argc<2){
      printf("Usage: %s port\n",argv[0]);
      exit(1);
   }
   
   port=atoi(argv[1]);
   
   /* start server up */
   s = start_server(port);
   if (s>=0){
      printf("Server started on port %i\n",port);
      process_requests(s);
   }
   if (s==-1){
      printf("Port reserved or out-of-range\n");
      exit(1);
   }
   if (s==-2){
      printf("Error creating socket\n");
      exit(1);
   }

   fprintf(stderr,"udpft server exiting!\n");
   return(1);
}
Beispiel #3
0
int main(int argc, char *argv[])
{
	extern char *optarg;
	extern int optind;
	extern FILE *dbf;
	int opt;

	dbf = fopen("/dev/null", "w");

	if (!dbf) dbf = stderr;

	cgi_setup(WEB_ROOT);


	while ((opt = getopt(argc, argv,"s:")) != EOF) {
		switch (opt) {
		case 's':
			pstrcpy(servicesf,optarg);
			break;	  
		}
	}


	print_header();

	charset_initialise();

	if (load_config()) {
		cgi_load_variables(NULL);
		process_requests();
		show_services();
	}
	print_footer();
	return 0;
}
Beispiel #4
0
// *************************************************************************************************
// @fn          main
// @brief       Main routine
// @param       none
// @return      none
// *************************************************************************************************
int main(void)
{
#ifdef EMU
	emu_init();
#endif
	// Init MCU 
	init_application();

	// Assign initial value to global variables
	init_global_variables();

#ifdef CONFIG_TEST
	// Branch to welcome screen
	test_mode();
#else
	display_all_off();
#endif
	
	// Main control loop: wait in low power mode until some event needs to be processed
	while(1)
	{
		// When idle go to LPM3
    	idle_loop();

    	// Process wake-up events
    	if (button.all_flags || sys.all_flags) wakeup_event();
    	
    	// Process actions requested by logic modules
    	if (request.all_flags) process_requests();
    	
    	// Before going to LPM3, update display
    	if (display.all_flags) display_update();	
 	}	
}
Beispiel #5
0
/**
 * Get an IP address as a string.
 *
 * @param sa host address
 * @param salen length of host address in @a sa
 * @param do_resolve use #GNUNET_NO to return numeric hostname
 * @param timeout how long to try resolving
 * @param callback function to call with hostnames
 *        last callback is NULL when finished
 * @param cls closure for @a callback
 * @return handle that can be used to cancel the request
 */
struct GNUNET_RESOLVER_RequestHandle *
GNUNET_RESOLVER_hostname_get (const struct sockaddr *sa,
                              socklen_t salen,
                              int do_resolve,
                              struct GNUNET_TIME_Relative timeout,
                              GNUNET_RESOLVER_HostnameCallback callback,
                              void *cls)
{
    struct GNUNET_RESOLVER_RequestHandle *rh;
    size_t ip_len;
    const void *ip;

    check_config ();
    switch (sa->sa_family)
    {
    case AF_INET:
        GNUNET_assert (salen == sizeof (struct sockaddr_in));
        ip_len = sizeof (struct in_addr);
        ip = &((const struct sockaddr_in*)sa)->sin_addr;
        break;
    case AF_INET6:
        GNUNET_assert (salen == sizeof (struct sockaddr_in6));
        ip_len = sizeof (struct in6_addr);
        ip = &((const struct sockaddr_in6*)sa)->sin6_addr;
        break;
    default:
        GNUNET_break (0);
        return NULL;
    }
    rh = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_RequestHandle) + salen);
    rh->name_callback = callback;
    rh->cls = cls;
    rh->af = sa->sa_family;
    rh->timeout = GNUNET_TIME_relative_to_absolute (timeout);
    memcpy (&rh[1], ip, ip_len);
    rh->data_len = ip_len;
    rh->direction = GNUNET_YES;
    rh->received_response = GNUNET_NO;
    if (GNUNET_NO == do_resolve)
    {
        rh->task = GNUNET_SCHEDULER_add_now (&numeric_reverse, rh);
        return rh;
    }
    GNUNET_CONTAINER_DLL_insert_tail (req_head,
                                      req_tail,
                                      rh);
    rh->was_queued = GNUNET_YES;
    if (NULL != s_task)
    {
        GNUNET_SCHEDULER_cancel (s_task);
        s_task = NULL;
    }
    process_requests ();
    return rh;
}
void
accept_connection(SOCKET listen_fd) {

  struct sockaddr_storage peeraddr;
  netperf_socklen_t peeraddrlen;
#if defined(SO_KEEPALIVE)
  int on = 1;
#endif

  if (debug) {
    fprintf(where,
	    "%s: enter\n",
	    __FUNCTION__);
    fflush(where);
  }

  peeraddrlen = sizeof(peeraddr);

  /* while server_control is only used by the WIN32 path, but why
     bother ifdef'ing it?  and besides, do we *really* need knowledge
     of server_control in the WIN32 case? do we have to tell the
     child about *all* the listen endpoints? raj 2011-07-08 */
  server_control = listen_fd;

  if ((server_sock = accept(listen_fd,
			   (struct sockaddr *)&peeraddr,
			    &peeraddrlen)) == INVALID_SOCKET) {
    fprintf(where,
	    "%s: accept failure: %s (errno %d)\n",
	    __FUNCTION__,
	    strerror(errno),
	    errno);
    fflush(where);
    exit(1);
  }

#if defined(SO_KEEPALIVE)
  /* we are not terribly concerned if this does not work, it is merely
     duct tape added to belts and suspenders. raj 2011-07-08 */
  setsockopt(server_sock,
	     SOL_SOCKET,
	     SO_KEEPALIVE,
	     (const char *)&on,
	     sizeof(on));
#endif

  if (spawn_on_accept) {
    spawn_child();
    /* spawn_child() only returns when we are the parent */
    close(server_sock);
  }
  else {
    process_requests();
  }
}
Beispiel #7
0
/**
 * Convert a string to one or more IP addresses.
 *
 * @param hostname the hostname to resolve
 * @param af AF_INET or AF_INET6; use AF_UNSPEC for "any"
 * @param callback function to call with addresses
 * @param callback_cls closure for callback
 * @param timeout how long to try resolving
 * @return handle that can be used to cancel the request, NULL on error
 */
struct GNUNET_RESOLVER_RequestHandle *
GNUNET_RESOLVER_ip_get (const char *hostname, int af,
                        struct GNUNET_TIME_Relative timeout,
                        GNUNET_RESOLVER_AddressCallback callback,
                        void *callback_cls)
{
  struct GNUNET_RESOLVER_RequestHandle *rh;
  size_t slen;
  unsigned int i;
  struct in_addr v4;
  struct in6_addr v6;

  slen = strlen (hostname) + 1;
  if (slen + sizeof (struct GNUNET_RESOLVER_GetMessage) >=
      GNUNET_SERVER_MAX_MESSAGE_SIZE)
  {
    GNUNET_break (0);
    return NULL;
  }
  rh = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_RequestHandle) + slen);
  rh->af = af;
  rh->addr_callback = callback;
  rh->cls = callback_cls;
  memcpy (&rh[1], hostname, slen);
  rh->data_len = slen;
  rh->timeout = GNUNET_TIME_relative_to_absolute (timeout);
  rh->direction = GNUNET_NO;
  /* first, check if this is a numeric address */
  if (((1 == inet_pton (AF_INET, hostname, &v4)) &&
       ((af == AF_INET) || (af == AF_UNSPEC))) ||
      ((1 == inet_pton (AF_INET6, hostname, &v6)) &&
       ((af == AF_INET6) || (af == AF_UNSPEC))))
  {
    rh->task = GNUNET_SCHEDULER_add_now (&numeric_resolution, rh);
    return rh;
  }
  /* then, check if this is a loopback address */
  i = 0;
  while (loopback[i] != NULL)
    if (0 == strcasecmp (loopback[i++], hostname))
    {
      rh->task = GNUNET_SCHEDULER_add_now (&loopback_resolution, rh);
      return rh;
    }
  GNUNET_CONTAINER_DLL_insert_tail (req_head, req_tail, rh);
  rh->was_queued = GNUNET_YES;
  if (s_task != GNUNET_SCHEDULER_NO_TASK)
  {
    GNUNET_SCHEDULER_cancel (s_task);
    s_task = GNUNET_SCHEDULER_NO_TASK;
  }
  process_requests ();
  return rh;
}
Beispiel #8
0
int main(int argc, char ** argv)
{
    unsigned int thread_count;
    int result = cloudi_initialize_thread_count(&thread_count);
    assert(result == cloudi_success);
    assert(thread_count == 1);

    process_requests_t data = {0};

    process_requests(&data);

    return 0;
}
Beispiel #9
0
/**
 * Now try to reconnect to the resolver service.
 *
 * @param cls NULL
 * @param tc scheduler context
 */
static void
reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  r_task = GNUNET_SCHEDULER_NO_TASK;
  if (NULL == req_head)
    return;                     /* no work pending */
  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
    return;
  LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to connect to DNS service\n");
  client = GNUNET_CLIENT_connect ("resolver", resolver_cfg);
  if (NULL == client)
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG, "Failed to connect, will try again later\n");
    reconnect ();
    return;
  }
  process_requests ();
}
Beispiel #10
0
int main(int argc, char ** argv)
{
    if (argc != 4)
    {
        printf("Usage: %s thread_count protocol buffer_size", argv[0]);
        return 1;
    }
    int const count = atoi(argv[1]);
    char const * const protocol = argv[2];
    int const buffer_size = atoi(argv[3]);

    assert(count == 1);

    process_requests_t data = {0, protocol, buffer_size};

    process_requests(&data);

    return 0;
}
Beispiel #11
0
int main(int argc, char *argv[]) {
    char *host = "localhost";
    char *port = "50000";

    int opt;
    while ((opt = getopt(argc, argv, "tuh:p:")) != -1) {
        switch (opt) {
        case 'h':
            host = optarg;
            break;
        case 'p':
            port = optarg;
            break;
        case '?':
            fprintf(stderr, "Unknown option: %c\n", optopt);
            exit(EXIT_FAILURE);
        default:
            fprintf(stderr, "Failed to parse command line arguments\n");
            exit(EXIT_FAILURE);
        }
    }

    if (optind != argc) {
        fprintf(stderr, "Some unexpected command line arguments are given\n");
        exit(EXIT_FAILURE);
    }

    int sockfd = create_socket(host, port);
    if (-1 == sockfd) {
        exit(EXIT_FAILURE);
    }

    process_requests(STDIN_FILENO, sockfd, STDOUT_FILENO);

    return 0;
}
/* the routine we call when we are going to spawn/fork/whatnot a child
   process from the parent netserver daemon. raj 2011-07-08 */
void
spawn_child() {

#if defined(HAVE_FORK)

  if (debug) {
    fprintf(where,
	    "%s: enter\n",
	    __FUNCTION__);
    fflush(where);
  }


  /* flush the usual suspects */
  fflush(stdin);
  fflush(stdout);
  fflush(stderr);
  fflush(where);

  signal(SIGCLD,SIG_IGN);

  switch (fork()) {
  case -1:
    fprintf(where,
	    "%s: fork() error %s (errno %d)\n",
	    __FUNCTION__,
	    strerror(errno),
	    errno);
    fflush(where);
    exit(1);

  case 0:
    /* we are the child, but not of inetd.  we don't know if we are
       the child of a daemonized parent or not, so we still need to
       worry about the standard file descriptors. raj 2011-07-11 */

    close_listens(listen_list);
    open_debug_file();

    child = 1;
    netperf_daemon = 0;
    process_requests();
    exit(0);
    break;

  default:
    /* we are the parent, not a great deal to do here, but we may
       want to reap some children */
#if !defined(HAVE_SETSID)
    /* Only call "waitpid()" if "setsid()" is not used. */
    while(waitpid(-1, NULL, WNOHANG) > 0) {
      if (debug) {
	fprintf(where,
		"%s: reaped a child process\n",
		__FUNCTION__);
      }
    }
#endif
    break;
  }

#elif defined(WIN32)

  BOOL b;
  char *cmdline;
  int cmdline_length;
  int cmd_index;
  PROCESS_INFORMATION pi;
  STARTUPINFO si;
  int i;

  if (debug) {
    fprintf(where,
	    "%s: enter\n",
	    __FUNCTION__);
    fflush(where);
  }


  /* create the cmdline array based on strlen(program) + 80 chars */
  cmdline_length = strlen(program) + 80;
  cmdline = malloc(cmdline_length + 1);  // +1 for trailing null

  memset(&si, 0 , sizeof(STARTUPINFO));
  si.cb = sizeof(STARTUPINFO);

  /* Pass the server_sock as stdin for the new process.  Hopefully
     this will continue to be created with the OBJ_INHERIT
     attribute. */
  si.hStdInput = (HANDLE)server_sock;
  si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
  si.dwFlags = STARTF_USESTDHANDLES;

  /* Build cmdline for child process */
  strcpy(cmdline, program);
  cmd_index = strlen(cmdline);
  if (verbosity > 1) {
    cmd_index += snprintf(&cmdline[cmd_index],
			  cmdline_length - cmd_index,
			  " -v %d",
			  verbosity);
  }
  for (i=0; i < debug; i++) {
    cmd_index += snprintf(&cmdline[cmd_index],
			  cmdline_length - cmd_index,
			  " -d");
  }
  cmd_index += snprintf(&cmdline[cmd_index],
			cmdline_length - cmd_index,
			" -I %x",
			(int)(UINT_PTR)server_sock);

  /* are these -i settings even necessary? the command line scanning
     does not seem to do anything with them */
  cmd_index += snprintf(&cmdline[cmd_index],
			cmdline_length - cmd_index,
			" -i %x",
			(int)(UINT_PTR)server_control);
  cmd_index += snprintf(&cmdline[cmd_index],
			cmdline_length - cmd_index,
			" -i %x",
			(int)(UINT_PTR)where);

  b = CreateProcess(NULL,    /* Application Name */
		    cmdline,
		    NULL,    /* Process security attributes */
		    NULL,    /* Thread security attributes */
		    TRUE,    /* Inherit handles */
		    0,       /* Creation flags
				PROCESS_QUERY_INFORMATION,  */
		    NULL,    /* Enviornment */
		    NULL,    /* Current directory */
		    &si,     /* StartupInfo */
		    &pi);
  if (!b)
    {
      perror("CreateProcessfailure: ");
      free(cmdline); /* even though we exit :) */
      exit(1);
    }

  /* We don't need the thread or process handles any more;
     let them go away on their own timeframe. */

  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);

  /* the caller/parent will close server_sock */

  free(cmdline);

#else

  fprintf(where,
	  "%s called on platform which cannot spawn children\n",
	  __FUNCTION__);
  fflush(where);
  exit(1);

#endif /* HAVE_FORK */
}
int _cdecl
main(int argc, char *argv[]) {

#ifdef WIN32
  WSADATA	wsa_data ;

  /* Initialize the winsock lib do we still want version 2.2? */
  if ( WSAStartup(MAKEWORD(2,2), &wsa_data) == SOCKET_ERROR ){
    printf("WSAStartup() failed : %lu\n", GetLastError()) ;
    return -1 ;
  }
#endif /* WIN32 */

  /* Save away the program name */
  program = (char *)malloc(strlen(argv[0]) + 1);
  if (program == NULL) {
    printf("malloc for program name failed!\n");
    return -1 ;
  }
  strcpy(program, argv[0]);

  init_netserver_globals();

  netlib_init();

  strncpy(local_host_name,"",sizeof(local_host_name));
  local_address_family = AF_UNSPEC;
  strncpy(listen_port,TEST_PORT,sizeof(listen_port));

  scan_netserver_args(argc, argv);

  check_if_inetd();

  if (child) {
    /* we are the child of either an inetd or parent netserver via
       spawning (Windows) rather than fork()ing. if we were fork()ed
       we would not be coming through this way. set_server_sock() must
       be called before open_debug_file() or there is a chance that
       we'll toast the descriptor when we do not wish it. */
    set_server_sock();
    open_debug_file();
    process_requests();
  }
  else if (daemon_parent) {
    /* we are the parent daemonized netserver
       process. accept_connections() will decide if we want to spawn a
       child process */
    accept_connections();
  }
  else {
    /* we are the top netserver process, so we have to create the
       listen endpoint(s) and decide if we want to daemonize */
    setup_listens(local_host_name,listen_port,local_address_family);
    if (want_daemonize) {
      daemonize();
    }
    accept_connections();
  }

  unlink_empty_debug_file();

#ifdef WIN32
  WSACleanup();
#endif

  return 0;

}
Beispiel #14
0
void set_up_server()
{ 
  struct  servent         *sp;            /* server entity           */
  struct sockaddr_in 	server;
  struct sockaddr_in 	peeraddr;

  int server_control;
  int peeraddr_len;
  int ppid,pid;
  
  server.sin_port = htons(listen_port_num);
  server.sin_addr.s_addr = INADDR_ANY;
  server.sin_family = AF_INET;
  
  printf("Starting netserver at port %d\n",listen_port_num);

  server_control = socket (AF_INET,SOCK_STREAM,0);
  if (server_control < 0)
    {
      perror("server_set_up: creating the socket");
      exit(1);
    }
  if (bind (server_control,
	    (struct sockaddr *)&server, 
	    sizeof(struct sockaddr_in)) == -1)
    {
      perror("server_set_up: binding the socket");
      exit (1);
    }
  if (listen (server_control,5) == -1)
    {
      perror("server_set_up: listening");
      exit(1);
    }
  
  /*
    setpgrp();
    */

  switch (fork())
    {
    case -1:  	
      perror("netperf server error");
      exit(1);
      
    case 0:	
      /* stdin/stderr should use fclose */
      fclose(stdin);
      fclose(stderr);
      setpgrp();

 /* some OS's have SIGCLD defined as SIGCHLD */
#ifndef SIGCLD
#define SIGCLD SIGCHLD
#endif /* SIGCLD */

      signal(SIGCLD, SIG_IGN);
      
      for (;;)
	{
	  peeraddr_len = sizeof(peeraddr);
	  if ((server_sock=accept(server_control,
				  (struct sockaddr *)&peeraddr,
				  &peeraddr_len)) == -1)
	    {
	      printf("server_control: accept failed\n");
	      exit(1);
	    }
	  signal(SIGCLD, SIG_IGN);
	  
	  switch (fork())
	    {
	    case -1:
	      /* something went wrong */
	      exit(1);
	    case 0:
	      /* we are the child process */
	      close(server_control);
	      process_requests();
	      exit(0);
	      break;
	    default:
	      /* we are the parent process */
	      close(server_sock);
	      /* we should try to "reap" some of our children. on some */
	      /* systems they are being left as defunct processes. we */
	      /* will call waitpid, looking for any child process, */
	      /* with the WNOHANG feature. when waitpid return a zero, */
	      /* we have reaped all the children there are to reap at */
	      /* the moment, so it is time to move on. raj 12/94 */
#ifndef DONT_WAIT
	      while(waitpid(-1, NULL, WNOHANG) > 0) { }
#endif /* DONT_WAIT */
	      break;
	    }
	} /*for*/
      break; /*case 0*/
      
    default: 
      exit (0);
      
    }
  
}
Beispiel #15
0
int _cdecl
main(int argc, char *argv[])
{

  int	c;
  int   not_inetd = 0;
#ifdef WIN32
  BOOL  child = FALSE;
#endif
  char arg1[BUFSIZ], arg2[BUFSIZ];
#ifndef PATH_MAX
#define PATH_MAX MAX_PATH
#endif
  char FileName[PATH_MAX];   /* for opening the debug log file */

  struct sockaddr name;
  netperf_socklen_t namelen = sizeof(name);
  

#ifdef WIN32
	WSADATA	wsa_data ;

	/* Initialize the winsock lib ( version 2.2 ) */
	if ( WSAStartup(MAKEWORD(2,2), &wsa_data) == SOCKET_ERROR ){
		printf("WSAStartup() failed : %d\n", GetLastError()) ;
		return 1 ;
	}
#endif /* WIN32 */

	/* Save away the program name */
	program = (char *)malloc(strlen(argv[0]) + 1);
	if (program == NULL) {
		printf("malloc(%d) failed!\n", strlen(argv[0]) + 1);
		return 1 ;
	}
	strcpy(program, argv[0]);

  netlib_init();
  
  /* Scan the command line to see if we are supposed to set-up our own */
  /* listen socket instead of relying on inetd. */

  /* first set a copy of initial values */
  strncpy(local_host_name,"0.0.0.0",sizeof(local_host_name));
  local_address_family = AF_UNSPEC;
  strncpy(listen_port,TEST_PORT,sizeof(listen_port));

  while ((c = getopt(argc, argv, SERVER_ARGS)) != EOF) {
    switch (c) {
    case '?':
    case 'h':
      print_netserver_usage();
      exit(1);
    case 'd':
      /* we want to set the debug file name sometime */
      debug++;
      break;
    case 'L':
      not_inetd = 1;
      break_args_explicit(optarg,arg1,arg2);
      if (arg1[0]) {
	strncpy(local_host_name,arg1,sizeof(local_host_name));
      }
      if (arg2[0]) {
	local_address_family = parse_address_family(arg2);
	/* if only the address family was set, we may need to set the
	   local_host_name accordingly. since our defaults are IPv4
	   this should only be necessary if we have IPv6 support raj
	   2005-02-07 */  
#if defined (AF_INET6)
	if (!arg1[0]) {
	  strncpy(local_host_name,"::0",sizeof(local_host_name));
	}
#endif
      }
      break;
    case 'n':
      shell_num_cpus = atoi(optarg);
      if (shell_num_cpus > MAXCPUS) {
	fprintf(stderr,
		"netserver: This version can only support %d CPUs. Please",
		MAXCPUS);
	fprintf(stderr,
		"           increase MAXCPUS in netlib.h and recompile.\n");
	fflush(stderr);
	exit(1);
      }
      break;
    case 'p':
      /* we want to open a listen socket at a */
      /* specified port number */
      strncpy(listen_port,optarg,sizeof(listen_port));
      not_inetd = 1;
      break;
    case '4':
      local_address_family = AF_INET;
      break;
    case '6':
#if defined(AF_INET6)
      local_address_family = AF_INET6;
      strncpy(local_host_name,"::0",sizeof(local_host_name));
#else
      local_address_family = AF_UNSPEC;
#endif
      break;
    case 'v':
      /* say how much to say */
      verbosity = atoi(optarg);
      break;
    case 'V':
      printf("Netperf version %s\n",NETPERF_VERSION);
      exit(0);
      break;
#ifdef WIN32
/*+*+SAF */
	case 'I':
		child = TRUE;
		/* This is the handle we expect to inherit. */
		/*+*+SAF server_sock = (HANDLE)atoi(optarg); */
		break;
	case 'i':
		/* This is a handle we should NOT inherit. */
		/*+*+SAF CloseHandle((HANDLE)atoi(optarg)); */
		break;
#endif

    }
  }

  /* +*+SAF I need a better way to find inherited handles I should close! */
  /* +*+SAF Use DuplicateHandle to force inheritable attribute (or reset it)? */

/*  unlink(DEBUG_LOG_FILE); */

  strcpy(FileName, DEBUG_LOG_FILE);
    
#ifndef WIN32
  snprintf(&FileName[strlen(FileName)], sizeof(FileName) - strlen(FileName), "_%d", getpid());
  if ((where = fopen(FileName, "w")) == NULL) {
    perror("netserver: debug file");
    exit(1);
  }
#else
  {
    
    if (child) {
      snprintf(&FileName[strlen(FileName)], sizeof(FileName) - strlen(FileName), "_%x", getpid());
    }
    
    /* Hopefully, by closing stdout & stderr, the subsequent
       fopen calls will get mapped to the correct std handles. */
    fclose(stdout);
    
    if ((where = fopen(FileName, "w")) == NULL) {
      perror("netserver: fopen of debug file as new stdout failed!");
      exit(1);
    }
    
    fclose(stderr);
    
    if ((where = fopen(FileName, "w")) == NULL) {
      fprintf(stdout, "fopen of debug file as new stderr failed!\n");
      exit(1);
    }
  }
#endif
 
#ifndef WIN32 
  chmod(DEBUG_LOG_FILE,0644);
#endif
  
#if WIN32
  if (child) {
	  server_sock = (SOCKET)GetStdHandle(STD_INPUT_HANDLE);
  }
#endif

  /* if we are not a child of an inetd or the like, then we should
   open a socket and hang listens off of it. otherwise, we should go
   straight into processing requests. the do_listen() routine will sit
   in an infinite loop accepting connections and forking child
   processes. the child processes will call process_requests */
  
  /* If fd 0 is not a socket then assume we're not being called */
  /* from inetd and start server socket on the default port. */
  /* this enhancement comes from [email protected] (Von Welch) */
  if (not_inetd) {
    /* the user specified a port number on the command line */
    set_up_server(local_host_name,listen_port,local_address_family);
  }
#ifdef WIN32
  /* OK, with Win2003 WinNT's POSIX subsystem is gone, and hence so is */
  /* fork.  But hopefully the kernel support will continue to exist */
  /* for some time.  We are not counting on the address space */
  /* copy_on_write support, since it isn't exposed except through the */
  /* NT native APIs (which are not public).  We will try to use the */
  /* InheritHandles flag in CreateProcess though since this is public */
  /* and is used for more than just POSIX so hopefully it won't go */
  /* away. */
  else if (TRUE) {
    if (child) {
      process_requests();
    } else {
      strncpy(listen_port,TEST_PORT,sizeof(listen_port));
      set_up_server(local_host_name,listen_port,local_address_family);
    }
  }
#endif
#if !defined(__VMS)
  else if (getsockname(0, &name, &namelen) == SOCKET_ERROR) {
    /* we may not be a child of inetd */
    if (errno == ENOTSOCK) {
      strncpy(listen_port,TEST_PORT,sizeof(listen_port));
      set_up_server(local_host_name,listen_port,local_address_family);
    }
  }
#endif /* !defined(__VMS) */
  else {
    /* we are probably a child of inetd, or are being invoked via the
       VMS auxilliarly server mechanism */
#if !defined(__VMS)
    server_sock = 0;
#else
    if ( (server_sock = socket(TCPIP$C_AUXS, SOCK_STREAM, 0)) == INVALID_SOCKET ) 
    { 
      perror("Failed to grab aux server socket" ); 
      exit(1); 
    } 
  
#endif /* !defined(__VMS) */
    process_requests();
  }
#ifdef WIN32
	/* Cleanup the winsock lib */
	WSACleanup();
#endif

  return(0);
}
int main(int argc, char **argv)
{
    int sock;
    uid_t own_u;
    gid_t own_g;
    char *rpath = NULL;
    char *sock_name = NULL;
    struct stat stbuf;
    int c, option_index;
#ifdef FS_IOC_GETVERSION
    int retval;
    struct statfs st_fs;
#endif

    prog_name = g_path_get_basename(argv[0]);

    is_daemon = true;
    sock = -1;
    own_u = own_g = -1;
    while (1) {
        option_index = 0;
        c = getopt_long(argc, argv, "p:nh?f:s:u:g:", helper_opts,
                        &option_index);
        if (c == -1) {
            break;
        }
        switch (c) {
        case 'p':
            rpath = g_strdup(optarg);
            break;
        case 'n':
            is_daemon = false;
            break;
        case 'f':
            sock = atoi(optarg);
            break;
        case 's':
            sock_name = g_strdup(optarg);
            break;
        case 'u':
            own_u = atoi(optarg);
            break;
        case 'g':
            own_g = atoi(optarg);
            break;
        case '?':
        case 'h':
        default:
            usage();
            exit(EXIT_FAILURE);
        }
    }

    /* Parameter validation */
    if ((sock_name == NULL && sock == -1) || rpath == NULL) {
        fprintf(stderr, "socket, socket descriptor or path not specified\n");
        usage();
        return -1;
    }

    if (sock_name && sock != -1) {
        fprintf(stderr, "both named socket and socket descriptor specified\n");
        usage();
        exit(EXIT_FAILURE);
    }

    if (sock_name && (own_u == -1 || own_g == -1)) {
        fprintf(stderr, "owner uid:gid not specified, ");
        fprintf(stderr,
                "owner uid:gid specifies who can access the socket file\n");
        usage();
        exit(EXIT_FAILURE);
    }

    if (lstat(rpath, &stbuf) < 0) {
        fprintf(stderr, "invalid path \"%s\" specified, %s\n",
                rpath, strerror(errno));
        exit(EXIT_FAILURE);
    }

    if (!S_ISDIR(stbuf.st_mode)) {
        fprintf(stderr, "specified path \"%s\" is not directory\n", rpath);
        exit(EXIT_FAILURE);
    }

    if (is_daemon) {
        if (daemon(0, 0) < 0) {
            fprintf(stderr, "daemon call failed\n");
            exit(EXIT_FAILURE);
        }
        openlog(PROGNAME, LOG_PID, LOG_DAEMON);
    }

    do_log(LOG_INFO, "Started\n");
    if (sock_name) {
        sock = proxy_socket(sock_name, own_u, own_g);
        if (sock < 0) {
            goto error;
        }
    }

    if (chroot(rpath) < 0) {
        do_perror("chroot");
        goto error;
    }
    if (chdir("/") < 0) {
        do_perror("chdir");
        goto error;
    }

    get_version = false;
#ifdef FS_IOC_GETVERSION
    /* check whether underlying FS support IOC_GETVERSION */
    retval = statfs("/", &st_fs);
    if (!retval) {
        switch (st_fs.f_type) {
        case EXT2_SUPER_MAGIC:
        case BTRFS_SUPER_MAGIC:
        case REISERFS_SUPER_MAGIC:
        case XFS_SUPER_MAGIC:
            get_version = true;
            break;
        }
    }
#endif

    umask(0);
    if (init_capabilities() < 0) {
        goto error;
    }

    process_requests(sock);
error:
    g_free(rpath);
    g_free(sock_name);
    do_log(LOG_INFO, "Done\n");
    closelog();
    return 0;
}
Beispiel #17
0
void loop(int server_s)
{
    FD_ZERO(BOA_READ);
    FD_ZERO(BOA_WRITE);

    max_fd = -1;

    while (1) {
        /* handle signals here */
        if (sighup_flag)
            sighup_run();
        if (sigchld_flag)
            sigchld_run();
        if (sigalrm_flag)
            sigalrm_run();

        if (sigterm_flag) {
            /* sigterm_flag:
             * 1. caught, unprocessed.
             * 2. caught, stage 1 processed
             */
            if (sigterm_flag == 1) {
                sigterm_stage1_run();
                BOA_FD_CLR(req, server_s, BOA_READ);
                close(server_s);
                /* make sure the server isn't in the block list */
                server_s = -1;
            }
            if (sigterm_flag == 2 && !request_ready && !request_block) {
                sigterm_stage2_run(); /* terminal */
            }
        } else {
            if (total_connections > max_connections) {
                /* FIXME: for poll we don't subtract 20. why? */
                BOA_FD_CLR(req, server_s, BOA_READ);
            } else {
                BOA_FD_SET(req, server_s, BOA_READ); /* server always set */
            }
        }
	if (isREBOOTASP == 1) {
			if(last_req_after_upgrade != req_after_upgrade){
					last_req_after_upgrade = req_after_upgrade;
			}
	}

        pending_requests = 0;
        /* max_fd is > 0 when something is blocked */

        if (max_fd) {
            struct timeval req_timeout; /* timeval for select */

            req_timeout.tv_sec = (request_ready ? 0 : default_timeout);
            req_timeout.tv_usec = 0l; /* reset timeout */

            if (select(max_fd + 1, BOA_READ,
                       BOA_WRITE, NULL,
                       (request_ready || request_block ?
                        &req_timeout : NULL)) == -1) {
                /* what is the appropriate thing to do here on EBADF */
                if (errno == EINTR) {
			//fprintf(stderr,"####%s:%d isFWUPGRADE=%d isREBOOTASP=%d###\n",  __FILE__, __LINE__ ,isFWUPGRADE , isREBOOTASP);
			//fprintf(stderr,"####%s:%d last_req_after_upgrade=%d req_after_upgrade=%d confirm_last_req=%d###\n",  __FILE__, __LINE__ ,last_req_after_upgrade , req_after_upgrade, confirm_last_req);
                	if (isFWUPGRADE !=0 && isREBOOTASP == 1 ) {
                		if (last_req_after_upgrade == req_after_upgrade)
              				confirm_last_req++;
                		if (confirm_last_req >3)
                			goto ToUpgrade;
                	} else if(isCFGUPGRADE ==2  && isREBOOTASP == 1 ) {
                		goto ToReboot;
                	}
                	else if (isFWUPGRADE ==0 && isREBOOTASP == 1) {
                		if (last_req_after_upgrade == req_after_upgrade)
              				confirm_last_req++;
                		if (confirm_last_req >3) {
                			isFWUPGRADE = 0;
                			isREBOOTASP = 0;
                			//isFAKEREBOOT = 0;
                			confirm_last_req=0;
              			}
                	}
                    continue;       /* while(1) */                
                }
                else if (errno != EBADF) {
                    DIE("select");
                }
            }
            /* FIXME: optimize for when select returns 0 (timeout).
             * Thus avoiding many operations in fdset_update
             * and others.
             */
            if (!sigterm_flag && FD_ISSET(server_s, BOA_READ)) {
                pending_requests = 1;
            }
            time(&current_time); /* for "new" requests if we've been in
            * select too long */
            /* if we skip this section (for example, if max_fd == 0),
             * then we aren't listening anyway, so we can't accept
             * new conns.  Don't worry about it.
             */
        }

        /* reset max_fd */
        max_fd = -1;

        if (request_block) {
            /* move selected req's from request_block to request_ready */
            fdset_update();
        }

        /* any blocked req's move from request_ready to request_block */
        if (pending_requests || request_ready) {
        	if (isFWUPGRADE !=0 && isREBOOTASP == 1 ){
        		req_after_upgrade++;
        	}else if(isFWUPGRADE ==0 && isREBOOTASP == 1){
        		req_after_upgrade++;
        	}
            process_requests(server_s);
            continue;
        }

ToUpgrade:
	 if (isFWUPGRADE !=0 && isREBOOTASP == 1 ) {
		char buffer[200];
		
		//fprintf(stderr,"\r\n [%s-%u] FirmwareUpgrade start",__FILE__,__LINE__);
		FirmwareUpgrade(firmware_data, firmware_len, 0, buffer);
		//fprintf(stderr,"\r\n [%s-%u] FirmwareUpgrade end",__FILE__,__LINE__);
		//system("echo 7 > /proc/gpio"); // disable system LED
		isFWUPGRADE=0;
		isREBOOTASP=0;
		//reboot_time = 5;
     		break;
     	}

ToReboot:
	 if(isCFGUPGRADE == 2 && isREBOOTASP ==1) {
	 	isCFGUPGRADE=0;
		isREBOOTASP=0;
		system("reboot");
		for(;;);
	 }
    }
}
Beispiel #18
0
void set_up_server()
{ 
  struct sockaddr_in 	server;
  struct sockaddr_in 	peeraddr;

  int server_control;
  int peeraddr_len;
  
  server.sin_port = htons(listen_port_num);
  server.sin_addr.s_addr = INADDR_ANY;
  server.sin_family = AF_INET;
  
  printf("Starting netserver at port %d\n",listen_port_num);

  server_control = socket (AF_INET,SOCK_STREAM,0);
#ifdef WIN32
  if (server_control == INVALID_SOCKET)
#else
  if (server_control < 0)
#endif /* WIN32 */
    {
      perror("server_set_up: creating the socket");
      exit(1);
    }
  if (bind (server_control,
	    (struct sockaddr *)&server, 
	    sizeof(struct sockaddr_in)) == -1)
    {
      perror("server_set_up: binding the socket");
      exit (1);
    }
  if (listen (server_control,5) == -1)
    {
      perror("server_set_up: listening");
      exit(1);
    }
  
  /*
    setpgrp();
    */

#if !defined(WIN32) && !defined(VXWORKS)
  switch (fork())
    {
    case -1:  	
      perror("netperf server error");
      exit(1);
      
    case 0:	
      /* stdin/stderr should use fclose */
      fclose(stdin);
      fclose(stderr);
 /* can I just use setsid on all systems? raj 4/96 */
#if defined(__NetBSD__) || defined(__bsdi__) || defined(sun) || defined(__FREEBSD__)
      setsid();
#else
      setpgrp();
#endif

 /* some OS's have SIGCLD defined as SIGCHLD */
#ifndef SIGCLD
#define SIGCLD SIGCHLD
#endif /* SIGCLD */

      signal(SIGCLD, SIG_IGN);
      
#endif /* WIN32 || VXWORKS*/

      for (;;)
	{
	  peeraddr_len = sizeof(peeraddr);
	  if ((server_sock=accept(server_control,
				  (struct sockaddr *)&peeraddr,
				  &peeraddr_len)) == -1)
	    {
	      printf("server_control: accept failed\n");
	      exit(1);
	    }
#if defined(WIN32) || defined(VXWORKS)
	/*
	 * Since we cannot fork this process , we cant fire any threads
	 * as they all share the same global data . So we better allow
	 * one request at at time 
	 */
	    process_requests() ;
	    close (server_sock); /* pavel 5-Feb-1998 */
	}
#else

	  signal(SIGCLD, SIG_IGN);
	  
	  switch (fork())
	    {
	    case -1:
	      /* something went wrong */
	      exit(1);
	    case 0:
	      /* we are the child process */
	      close(server_control);
	      process_requests();
	      exit(0);
	      break;
	    default:
	      /* we are the parent process */
	      close(server_sock);
	      /* we should try to "reap" some of our children. on some */
	      /* systems they are being left as defunct processes. we */
	      /* will call waitpid, looking for any child process, */
	      /* with the WNOHANG feature. when waitpid return a zero, */
	      /* we have reaped all the children there are to reap at */
	      /* the moment, so it is time to move on. raj 12/94 */
#ifndef DONT_WAIT
	      while(waitpid(-1, NULL, WNOHANG) > 0) { }
#endif /* DONT_WAIT */
	      break;
	    }
	} /*for*/
      break; /*case 0*/
      
    default: 
      exit (0);
      
    }
Beispiel #19
0
void select_loop(int server_s)
{
    FD_ZERO(&block_read_fdset);
    FD_ZERO(&block_write_fdset);
    /* set server_s and req_timeout */
    req_timeout.tv_sec = (ka_timeout ? ka_timeout : REQUEST_TIMEOUT);
    req_timeout.tv_usec = 0l;   /* reset timeout */

    /* preset max_fd */
    max_fd = -1;

    while (1) {
        if (sighup_flag)
            sighup_run();

        if (sigchld_flag)
            sigchld_run();

        if (sigalrm_flag)
            sigalrm_run();

        if (sigterm_flag) {
            if (sigterm_flag == 1)
                sigterm_stage1_run(server_s);

            if (sigterm_flag == 2 /*&& !request_ready && !request_block*/) {
                sigterm_stage2_run();

            }
        }

        /* reset max_fd */
        max_fd = -1;

        if (request_block)
        {
            /* move selected req's from request_block to request_ready */
            //fprintf(stderr, "fdsetupdated\n");
            fdset_update();
        }

        /* any blocked req's move from request_ready to request_block */

        process_requests(server_s);

        if (!sigterm_flag && total_connections < (max_connections - 10)
#if  defined(TCSUPPORT_WEBSERVER_SSL)
                &&  http_mode != HTTPS_ONLY
#endif
           ) {
            BOA_FD_SET(server_s, &block_read_fdset);
        }

#if  defined(TCSUPPORT_WEBSERVER_SSL)
        if (!sigterm_flag  &&  total_connections < (max_connections - 10)  &&  http_mode != HTTP_ONLY)
        {
            BOA_FD_SET(server_ssl, &block_read_fdset);
        }
#endif

        req_timeout.tv_sec = (request_ready ? 0 :
                              (ka_timeout ? ka_timeout : REQUEST_TIMEOUT));

        req_timeout.tv_usec = 0l;   /* reset timeout */


        if (select(max_fd + 1, &block_read_fdset,
                   &block_write_fdset, NULL,
                   (request_ready || request_block ? &req_timeout : NULL)) == -1) {
            /* what is the appropriate thing to do here on EBADF */
            if (errno == EINTR)
            {
                continue;   /* while(1) */
            }
            else if (errno != EBADF) {
                DIE("select");
            }
        }

        time(&current_time);

        if (FD_ISSET(server_s, &block_read_fdset))
        {
            pending_requests = 1;
        }

#if  defined(TCSUPPORT_WEBSERVER_SSL)
        if (FD_ISSET(server_ssl, &block_read_fdset))
        {
            ssl_pending_requests = 1;
        }
#endif
    }
}
Beispiel #20
0
void loop(int server_s)
{
    struct pollfd pfd1[2][MAX_FD];
    short which = 0, other = 1, temp;
    int server_pfd, watch_server;

    pfds = pfd1[which];
    pfd_len = server_pfd = 0;
    watch_server = 1;

    while (1) {
        int timeout;

        time(&current_time);

        if (sighup_flag)
            sighup_run();
        if (sigchld_flag)
            sigchld_run();
        if (sigalrm_flag)
            sigalrm_run();

        if (sigterm_flag) {
            if (sigterm_flag == 1) {
                sigterm_stage1_run();
                close(server_s);
                server_s = -1;
                /* remove server_pfd */
                {
                    unsigned int i, j;

                    for(i = 0, j = 0;i < pfd_len;++i) {
                        if (i == (unsigned) server_pfd)
                            continue;
                        pfd1[other][j].fd = pfd1[which][j].fd;
                        pfd1[other][j].events = pfd1[which][j].events;
                        ++j;
                    }
                    pfd_len = j;
                    pfds = pfd1[other];
                    temp = other;
                    other = which;
                    which = temp;
                }
                watch_server = 0;
            }
            if (sigterm_flag == 2 && !request_ready && !request_block) {
                sigterm_stage2_run();
            }
        } else {
            if (total_connections < max_connections) {
                server_pfd = pfd_len++;
                pfds[server_pfd].fd = server_s;
                pfds[server_pfd].events = BOA_READ;
                watch_server = 1;
            } else {
                watch_server = 0;
            }
        }

        /* If there are any requests ready, the timeout is 0.
         * If not, and there are any requests blocking, the
         *  timeout is ka_timeout ? ka_timeout * 1000, otherwise
         *  REQUEST_TIMEOUT * 1000.
         * -1 means forever
         */
        pending_requests = 0;
        if (pfd_len) {
            timeout = (request_ready ? 0 :
                      (request_block ? default_timeout : -1));

            if (poll(pfds, pfd_len, timeout) == -1) {
                if (errno == EINTR)
                    continue;       /* while(1) */
            }
            if (!sigterm_flag && watch_server) {
                /*  */
                if (pfds[server_pfd].revents &
                  (POLLNVAL|POLLERR)) {
                    /* problem with the server socket, unexpected */
                    log_error("server pfd revent contains "
                      "POLLNVAL or POLLERR! Exiting.");
                    exit(1);
                } else if (pfds[server_pfd].revents & BOA_READ) {
                    pending_requests = 1;
                }
            }
            time(&current_time);
            /* if pfd_len is 0, we didn't poll, so the current time
             * should be up-to-date, and we *won't* be accepting anyway
             */
        }

        /* go through blocked and unblock them if possible */
        /* also resets pfd_len and pfd to known blocked */
        pfd_len = 0;
        if (request_block) {
            update_blocked(pfd1[other]);
        }

        /* swap pfd */
        pfds = pfd1[other];
        temp = other;
        other = which;
        which = temp;

        /* process any active requests */
        process_requests(server_s);
    }
}
Beispiel #21
0
/* process client requests */
int
srv_loop( const char* ipaddr, int port,
             const char* mcast_addr )
{
    int                 rc, maxfd, err, nrdy, i;
    fd_set              rset;
    struct timeval      tmout, idle_tmout, *ptmout = NULL;
    tmfd_t              *asock = NULL;
    size_t              n = 0, nasock = 0, max_nasock = LQ_BACKLOG;
    sigset_t            oset, bset;

    static const long IDLE_TMOUT_SEC = 30;

    assert( (port > 0) && mcast_addr && ipaddr );

    (void)tmfprintf( g_flog, "Server is starting up, max clients = [%u]\n",
                        g_uopt.max_clients );
    asock = calloc (max_nasock, sizeof(*asock));
    if (!asock) {
        mperror (g_flog, ENOMEM, "%s: calloc", __func__);
        return ERR_INTERNAL;
    }

    init_server_ctx( &g_srv, g_uopt.max_clients,
            (ipaddr[0] ? ipaddr : "0.0.0.0") , (uint16_t)port, mcast_addr );

    g_srv.rcv_tmout = (u_short)g_uopt.rcv_tmout;
    g_srv.snd_tmout = RLY_SOCK_TIMEOUT;

    /* NB: server socket is non-blocking! */
    if( 0 != (rc = setup_listener( ipaddr, port, &g_srv.lsockfd,
            g_uopt.lq_backlog )) ) {
        return rc;
    }

    sigemptyset (&bset);
    sigaddset (&bset, SIGINT);
    sigaddset (&bset, SIGQUIT);
    sigaddset (&bset, SIGCHLD);
    sigaddset (&bset, SIGTERM);

    (void) sigprocmask (SIG_BLOCK, &bset, &oset);

    TRACE( (void)tmfprintf( g_flog, "Entering server loop [%s]\n",
        SLOOP_TAG) );
    while (1) {
        FD_ZERO( &rset );
        FD_SET( g_srv.lsockfd, &rset );
        FD_SET( g_srv.cpipe[0], &rset );

        maxfd = (g_srv.lsockfd > g_srv.cpipe[0] ) ? g_srv.lsockfd : g_srv.cpipe[0];
        for (i = 0; (size_t)i < nasock; ++i) {
            assert (asock[i].fd >= 0);
            FD_SET (asock[i].fd, &rset);
            if (asock[i].fd > maxfd) maxfd = asock[i].fd;
        }

        /* if there are accepted sockets - apply specified time-out
         */
        tmout.tv_sec = g_uopt.ssel_tmout;
        tmout.tv_usec = 0;

        idle_tmout.tv_sec = IDLE_TMOUT_SEC;
        idle_tmout.tv_usec = 0;

        /* enforce *idle* select(2) timeout to alleviate signal contention */
        ptmout = ((nasock > 0) && (g_uopt.ssel_tmout > 0)) ? &tmout : &idle_tmout;

        TRACE( (void)tmfprintf( g_flog, "Waiting for input from [%ld] fd's, "
            "%s timeout\n", (long)(2 + nasock), (ptmout ? "with" : "NO")));

        if (ptmout && ptmout->tv_sec) {
            TRACE( (void)tmfprintf (g_flog, "select() timeout set to "
            "[%ld] seconds\n", ptmout->tv_sec) );
        }

        (void) sigprocmask (SIG_UNBLOCK, &bset, NULL);
        if( must_quit() ) {
            TRACE( (void)tmfputs( "Must quit now\n", g_flog ) );
            rc = 0; break;
        }

        nrdy = select (maxfd + 1, &rset, NULL, NULL, ptmout);
        err = errno;
        (void) sigprocmask (SIG_BLOCK, &bset, NULL);

        if( must_quit() ) {
            TRACE( (void)tmfputs( "Must quit now\n", g_flog ) );
            rc = 0; break;
        }
        wait_terminated( &g_srv );

        if( nrdy < 0 ) {
            if (EINTR == err) {
                TRACE( (void)tmfputs ("INTERRUPTED, yet "
                        "will continue.\n", g_flog)  );
                rc = 0; continue;
            }

            mperror( g_flog, err, "%s: select", __func__ );
            break;
        }

        TRACE( (void)tmfprintf (g_flog, "Got %ld requests\n", (long)nrdy) );
        if (0 == nrdy) {    /* time-out */
            tmout_requests (asock, &nasock);
            rc = 0; continue;
        }

        if( FD_ISSET(g_srv.cpipe[0], &rset) ) {
            (void) tpstat_read( &g_srv );
            if (--nrdy <= 0) continue;
        }

        if ((0 < nasock) &&
                 (0 < (nrdy - (FD_ISSET(g_srv.lsockfd, &rset) ? 1 : 0)))) {
            process_requests (asock, &nasock, &rset, &g_srv);
            /* n now contains # (yet) unprocessed accepted sockets */
        }

        if (FD_ISSET(g_srv.lsockfd, &rset)) {
            if (nasock >= max_nasock) {
                (void) tmfprintf (g_flog, "Cannot accept sockets beyond "
                    "the limit [%ld/%ld], skipping\n",
                    (long)nasock, (long)max_nasock);
            }
            else {
                n = max_nasock - nasock; /* append asock */
                accept_requests (g_srv.lsockfd, &(asock[nasock]), &n);
                nasock += n;
            }
        }
    } /* server loop */

    TRACE( (void)tmfprintf( g_flog, "Exited server loop [%s]\n", SLOOP_TAG) );

    for (i = 0; (size_t)i < nasock; ++i) {
        if (asock[i].fd > 0) (void) close (asock[i].fd);
    }
    free (asock);

    /* receive additional (blocked signals) */
    (void) sigprocmask (SIG_SETMASK, &oset, NULL);
    wait_terminated( &g_srv );
    terminate_all_clients( &g_srv );
    wait_all( &g_srv );

    if (0 != close( g_srv.lsockfd )) {
        mperror (g_flog, errno, "server socket close");
    }

    free_server_ctx( &g_srv );

    (void)tmfprintf( g_flog, "Server exits with rc=[%d]\n", rc );
    return rc;
}
Beispiel #22
0
void 
set_up_server(char hostname[], char port[], int af)
{ 

  struct addrinfo     hints;
  struct addrinfo     *local_res;
  struct addrinfo     *local_res_temp;

  struct sockaddr_storage     peeraddr;
  netperf_socklen_t                 peeraddr_len = sizeof(peeraddr);
  
  SOCKET server_control;
  int on=1;
  int count;
  int error;
  int not_listening;

#if !defined(WIN32) && !defined(MPE) && !defined(__VMS)
  FILE *rd_null_fp;    /* Used to redirect from "/dev/null". */
  FILE *wr_null_fp;    /* Used to redirect to   "/dev/null". */
#endif /* !WIN32 !MPE !__VMS */

  if (debug) {
    fprintf(stderr,
            "set_up_server called with host '%s' port '%s' remfam %d\n",
            hostname,
	    port,
            af);
    fflush(stderr);
  }

  memset(&hints,0,sizeof(hints));
  hints.ai_family = af;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_protocol = IPPROTO_TCP;
  hints.ai_flags = AI_PASSIVE;

  count = 0;
  do {
    error = getaddrinfo((char *)hostname,
                        (char *)port,
                        &hints,
                        &local_res);
    count += 1;
    if (error == EAI_AGAIN) {
      if (debug) {
        fprintf(stderr,"Sleeping on getaddrinfo EAI_AGAIN\n");
        fflush(stderr);
      }
      sleep(1);
    }
  } while ((error == EAI_AGAIN) && (count <= 5));

  if (error) {
    fprintf(stderr,
	    "set_up_server: could not resolve remote '%s' port '%s' af %d",
	    hostname,
	    port,
	    af);
    fprintf(stderr,"\n\tgetaddrinfo returned %d %s\n",
	    error,
	    gai_strerror(error));
    exit(-1);
  }

  if (debug) {
    dump_addrinfo(stderr, local_res, hostname, port, af);
  }

  not_listening = 1;
  local_res_temp = local_res;

  while((local_res_temp != NULL) && (not_listening)) {

    fprintf(stderr,
	    "Starting netserver at port %s\n",
	    port);

    server_control = socket(local_res_temp->ai_family,SOCK_STREAM,0);

    if (server_control == INVALID_SOCKET) {
      perror("set_up_server could not allocate a socket");
      exit(-1);
    }

    /* happiness and joy, keep going */
    if (setsockopt(server_control, 
		   SOL_SOCKET, 
		   SO_REUSEADDR, 
		   (char *)&on , 
		   sizeof(on)) == SOCKET_ERROR) {
      if (debug) {
	perror("warning: set_up_server could not set SO_REUSEADDR");
      }
    }
    /* still happy and joyful */

    if ((bind (server_control, 
	       local_res_temp->ai_addr, 
	       local_res_temp->ai_addrlen) != SOCKET_ERROR) &&
	(listen (server_control,5) != SOCKET_ERROR))  {
      not_listening = 0;
      break;
    }
    else {
      /* we consider a bind() or listen() failure a transient and try
	 the next address */
      if (debug) {
	perror("warning: set_up_server failed a bind or listen call\n");
      }
      local_res_temp = local_res_temp->ai_next;
      continue;
    }
  }

  if (not_listening) {
    fprintf(stderr,
	    "set_up_server could not establish a listen endpoint for %s port %s with family %s\n",
	    host_name,
	    port,
	    inet_ftos(af));
    fflush(stderr);
    exit(-1);
  }
  else {
    printf("Starting netserver at hostname %s port %s and family %s\n",
	   hostname,
	   port,
	   inet_ftos(af));
  }

  /*
    setpgrp();
    */

#if !defined(WIN32) && !defined(MPE) && !defined(__VMS)
  /* Flush the standard I/O file descriptors before forking. */
  fflush (stdin);
  fflush (stdout);
  fflush (stderr);
#if defined(HAVE_FORK)
  switch (fork())
#else
  switch (vfork())
#endif
    {
    case -1:  	
      perror("netperf server error");
      exit(1);
      
    case 0:	
      /* Redirect stdin from "/dev/null". */
      rd_null_fp = fopen ("/dev/null", "r");
      if (rd_null_fp == NULL)
      {
	perror ("netserver: opening for reading: /dev/null");
	exit   (1);
      }
      if (close (STDIN_FILENO) == -1)
      {
	perror ("netserver: closing stdin file descriptor");
	exit   (1);
      }
      if (dup (fileno (rd_null_fp)) == -1)
      {
	perror ("netserver: duplicate /dev/null read file descr. to stdin");
	exit   (1);
      }

      /* Redirect stdout to the debug write file descriptor. */
      if (close (STDOUT_FILENO) == -1)
      {
	perror ("netserver: closing stdout file descriptor");
	exit   (1);
      }
      if (dup (fileno (where))  == -1)
      {
	perror ("netserver: duplicate the debug write file descr. to stdout");
	exit   (1);
      }

      /* Redirect stderr to "/dev/null". */
      wr_null_fp = fopen ("/dev/null", "w");
      if (wr_null_fp == NULL)
      {
	perror ("netserver: opening for writing: /dev/null");
	exit   (1);
      }
      if (close (STDERR_FILENO) == -1)
      {
	perror ("netserver: closing stderr file descriptor");
	exit   (1);
      }
      if (dup (fileno (wr_null_fp))  == -1)
      {
	perror ("netserver: dupicate /dev/null write file descr. to stderr");
	exit   (1);
      }
 
#ifndef NO_SETSID
      setsid();
#else
      setpgrp();
#endif /* NO_SETSID */

 /* some OS's have SIGCLD defined as SIGCHLD */
#ifndef SIGCLD
#define SIGCLD SIGCHLD
#endif /* SIGCLD */

      signal(SIGCLD, SIG_IGN);
      
#endif /* !WIN32 !MPE !__VMS */

      for (;;)
	{
	  if ((server_sock=accept(server_control,
				  (struct sockaddr *)&peeraddr,
				  &peeraddr_len)) == INVALID_SOCKET)
	    {
	      printf("server_control: accept failed errno %d\n",errno);
	      exit(1);
	    }
#if defined(MPE) || defined(__VMS)
	  /*
	   * Since we cannot fork this process , we cant fire any threads
	   * as they all share the same global data . So we better allow
	   * one request at at time 
	   */
	  process_requests() ;
#elif WIN32
		{
			BOOL b;
			char cmdline[80];
			PROCESS_INFORMATION pi;
			STARTUPINFO si;
			int i;

			memset(&si, 0 , sizeof(STARTUPINFO));
			si.cb = sizeof(STARTUPINFO);

			/* Pass the server_sock as stdin for the new process. */
			/* Hopefully this will continue to be created with the OBJ_INHERIT attribute. */
			si.hStdInput = (HANDLE)server_sock;
			si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
			si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
			si.dwFlags = STARTF_USESTDHANDLES;

			/* Build cmdline for child process */
			strcpy(cmdline, program);
			if (verbosity > 1) {
				snprintf(&cmdline[strlen(cmdline)], sizeof(cmdline) - strlen(cmdline), " -v %d", verbosity);
			}
			for (i=0; i < debug; i++) {
				snprintf(&cmdline[strlen(cmdline)], sizeof(cmdline) - strlen(cmdline), " -d");
			}
			snprintf(&cmdline[strlen(cmdline)], sizeof(cmdline) - strlen(cmdline), " -I %x", (int)(UINT_PTR)server_sock);
			snprintf(&cmdline[strlen(cmdline)], sizeof(cmdline) - strlen(cmdline), " -i %x", (int)(UINT_PTR)server_control);
			snprintf(&cmdline[strlen(cmdline)], sizeof(cmdline) - strlen(cmdline), " -i %x", (int)(UINT_PTR)where);

			b = CreateProcess(NULL,	 /* Application Name */
					cmdline,
					NULL,    /* Process security attributes */
					NULL,    /* Thread security attributes */
					TRUE,    /* Inherit handles */
					0,	   /* Creation flags  PROCESS_QUERY_INFORMATION,  */
					NULL,    /* Enviornment */
					NULL,    /* Current directory */
					&si,	   /* StartupInfo */
					&pi);
			if (!b)
			{
				perror("CreateProcessfailure: ");
				exit(1);
			}

			/* We don't need the thread or process handles any more; let them */
			/* go away on their own timeframe. */

			CloseHandle(pi.hThread);
			CloseHandle(pi.hProcess);

			/* And close the server_sock since the child will own it. */

			close(server_sock);
		}
#else
      signal(SIGCLD, SIG_IGN);
#if defined(HAVE_FORK)
	  switch (fork())
#else
	  switch (vfork())
#endif
	    {
	    case -1:
	      /* something went wrong */
	      exit(1);
	    case 0:
	      /* we are the child process */
	      close(server_control);
	      process_requests();
	      exit(0);
	      break;
	    default:
	      /* we are the parent process */
	      close(server_sock);
	      /* we should try to "reap" some of our children. on some */
	      /* systems they are being left as defunct processes. we */
	      /* will call waitpid, looking for any child process, */
	      /* with the WNOHANG feature. when waitpid return a zero, */
	      /* we have reaped all the children there are to reap at */
	      /* the moment, so it is time to move on. raj 12/94 */
#ifndef DONT_WAIT
#ifdef NO_SETSID
	      /* Only call "waitpid()" if "setsid()" is not used. */
	      while(waitpid(-1, NULL, WNOHANG) > 0) { }
#endif /* NO_SETSID */
#endif /* DONT_WAIT */
	      break;
	    }
#endif /* !WIN32 !MPE !__VMS */  
	} /*for*/
#if !defined(WIN32) && !defined(MPE) && !defined(__VMS)
      break; /*case 0*/
      
    default: 
      exit (0);
      
    }
#endif /* !WIN32 !MPE !__VMS */  
}
Beispiel #23
0
void select_loop(int server_s)
{
    FD_ZERO(&block_read_fdset);
    FD_ZERO(&block_write_fdset);
    /* set server_s and req_timeout */
    req_timeout.tv_sec = (ka_timeout ? ka_timeout : REQUEST_TIMEOUT);
    req_timeout.tv_usec = 0l;   /* reset timeout */

    /* preset max_fd */
    max_fd = -1;

    while (1) {
        if (sighup_flag)
            sighup_run();
        if (sigchld_flag)
            sigchld_run();
        if (sigalrm_flag)
            sigalrm_run();

        if (sigterm_flag) {
            if (sigterm_flag == 1)
                sigterm_stage1_run(server_s);
            if (sigterm_flag == 2 && !request_ready && !request_block) {
                sigterm_stage2_run();
            }
        }

        /* reset max_fd */
        max_fd = -1;

        if (request_block)
            /* move selected req's from request_block to request_ready */
            fdset_update();

        /* any blocked req's move from request_ready to request_block */
        process_requests(server_s);

        if (!sigterm_flag && total_connections < (max_connections - 10)) {
            BOA_FD_SET(server_s, &block_read_fdset); /* server always set */
#ifdef SERVER_SSL
            if (do_sock < 2)
                BOA_FD_SET(server_ssl, &block_read_fdset); /* server always set */
#endif
        }

        req_timeout.tv_sec = (request_ready ? 0 :
                              (ka_timeout ? ka_timeout : REQUEST_TIMEOUT));
        req_timeout.tv_usec = 0l;   /* reset timeout */

        if (select(max_fd + 1, &block_read_fdset,
                   &block_write_fdset, NULL,
                   (request_ready || request_block ? &req_timeout : NULL)) == -1) {
            /* what is the appropriate thing to do here on EBADF */
            if (errno == EINTR)
                continue;   /* while(1) */
            else if (errno != EBADF) {
                DIE("select");
            }
        }

        time(&current_time);
        if (FD_ISSET(server_s, &block_read_fdset))
            pending_requests = 1;
    }
}
Beispiel #24
0
void loop(int server_s)
{
    FD_ZERO(BOA_READ);
    FD_ZERO(BOA_WRITE);

    max_fd = -1;

    while (1) {
        /* handle signals here */
        if (sighup_flag)
            sighup_run();
        if (sigchld_flag)
            sigchld_run();
        if (sigalrm_flag)
            sigalrm_run();

        if (sigterm_flag) {
            /* sigterm_flag:
             * 1. caught, unprocessed.
             * 2. caught, stage 1 processed
             */
            if (sigterm_flag == 1) {
                sigterm_stage1_run();
                BOA_FD_CLR(req, server_s, BOA_READ);
                close(server_s);
                /* make sure the server isn't in the block list */
                server_s = -1;
            }
            if (sigterm_flag == 2 && !request_ready && !request_block) {
                sigterm_stage2_run(); /* terminal */
            }
        } else {
            if (total_connections > max_connections) {
                /* FIXME: for poll we don't subtract 20. why? */
                BOA_FD_CLR(req, server_s, BOA_READ);
            } else {
                BOA_FD_SET(req, server_s, BOA_READ); /* server always set */
            }
        }

        pending_requests = 0;
        /* max_fd is > 0 when something is blocked */

        if (max_fd) {
            struct timeval req_timeout; /* timeval for select */

            req_timeout.tv_sec = (request_ready ? 0 : default_timeout);
            req_timeout.tv_usec = 0l; /* reset timeout */

            if (select(max_fd + 1, BOA_READ,
                       BOA_WRITE, NULL,
                       (request_ready || request_block ?
                        &req_timeout : NULL)) == -1) {
                /* what is the appropriate thing to do here on EBADF */
                if (errno == EINTR)
                    continue;       /* while(1) */
                else if (errno != EBADF) {
                    DIE("select");
                }
            }
            /* FIXME: optimize for when select returns 0 (timeout).
             * Thus avoiding many operations in fdset_update
             * and others.
             */
            if (!sigterm_flag && FD_ISSET(server_s, BOA_READ)) {
                pending_requests = 1;
            }
            time(&current_time); /* for "new" requests if we've been in
            * select too long */
            /* if we skip this section (for example, if max_fd == 0),
             * then we aren't listening anyway, so we can't accept
             * new conns.  Don't worry about it.
             */
        }

        /* reset max_fd */
        max_fd = -1;

        if (request_block) {
            /* move selected req's from request_block to request_ready */
            fdset_update();
        }

        /* any blocked req's move from request_ready to request_block */
        if (pending_requests || request_ready) {
            process_requests(server_s);
        }
    }
}
Beispiel #25
0
/**
 * Process response with a hostname for a DNS lookup.
 *
 * @param cls our "struct GNUNET_RESOLVER_RequestHandle" context
 * @param msg message with the hostname, NULL on error
 */
static void
handle_response (void *cls, const struct GNUNET_MessageHeader *msg)
{
  struct GNUNET_RESOLVER_RequestHandle *rh = cls;
  uint16_t size;

  LOG (GNUNET_ERROR_TYPE_DEBUG, "Receiving response from DNS service\n");
  if (msg == NULL)
  {
    char buf[INET6_ADDRSTRLEN];

    if (NULL != rh->name_callback)
      LOG (GNUNET_ERROR_TYPE_INFO,
           _("Timeout trying to resolve IP address `%s'.\n"),
           inet_ntop (rh->af, (const void *) &rh[1], buf, sizeof(buf)));
    else
      LOG (GNUNET_ERROR_TYPE_INFO,
           _("Timeout trying to resolve hostname `%s'.\n"),
           (const char *) &rh[1]);
    /* check if request was canceled */
    if (rh->was_transmitted != GNUNET_SYSERR)
    {
      if (NULL != rh->name_callback)
      {
        /* no reverse lookup was successful, return ip as string */
        if (rh->received_response == GNUNET_NO)
          rh->name_callback (rh->cls,
                             no_resolve (rh->af,
					 &rh[1],
                                         rh->data_len));
        /* at least one reverse lookup was successful */
        else
          rh->name_callback (rh->cls, NULL);
      }
      if (NULL != rh->addr_callback)
        rh->addr_callback (rh->cls, NULL, 0);
    }
    GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh);
    GNUNET_free (rh);
    GNUNET_CLIENT_disconnect (client);
    client = NULL;
    reconnect ();
    return;
  }
  if (GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE != ntohs (msg->type))
  {
    GNUNET_break (0);
    GNUNET_CLIENT_disconnect (client);
    client = NULL;
    reconnect ();
    return;
  }
  size = ntohs (msg->size);
  /* message contains not data, just header */
  if (size == sizeof (struct GNUNET_MessageHeader))
  {
    /* check if request was canceled */
    if (rh->was_transmitted != GNUNET_SYSERR)
    {
      if (NULL != rh->name_callback)
        rh->name_callback (rh->cls, NULL);
      if (NULL != rh->addr_callback)
        rh->addr_callback (rh->cls, NULL, 0);
    }
    GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh);
    GNUNET_free (rh);
    process_requests ();
    return;
  }
  /* return reverse lookup results to caller */
  if (NULL != rh->name_callback)
  {
    const char *hostname;

    hostname = (const char *) &msg[1];
    if (hostname[size - sizeof (struct GNUNET_MessageHeader) - 1] != '\0')
    {
      GNUNET_break (0);
      if (rh->was_transmitted != GNUNET_SYSERR)
        rh->name_callback (rh->cls, NULL);
      GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh);
      GNUNET_free (rh);
      GNUNET_CLIENT_disconnect (client);
      client = NULL;
      reconnect ();
      return;
    }
    LOG (GNUNET_ERROR_TYPE_DEBUG, "Resolver returns `%s' for IP `%s'.\n",
         hostname, GNUNET_a2s ((const void *) &rh[1], rh->data_len));
    if (rh->was_transmitted != GNUNET_SYSERR)
      rh->name_callback (rh->cls, hostname);
    rh->received_response = GNUNET_YES;
    GNUNET_CLIENT_receive (client, &handle_response, rh,
                           GNUNET_TIME_absolute_get_remaining (rh->timeout));
  }
  /* return lookup results to caller */
  if (NULL != rh->addr_callback)
  {
    struct sockaddr_in v4;
    struct sockaddr_in6 v6;
    const struct sockaddr *sa;
    socklen_t salen;
    const void *ip;
    size_t ip_len;

    ip = &msg[1];
    ip_len = size - sizeof (struct GNUNET_MessageHeader);
    if (ip_len == sizeof (struct in_addr))
    {
      memset (&v4, 0, sizeof (v4));
      v4.sin_family = AF_INET;
      v4.sin_addr = *(struct in_addr*) ip;
#if HAVE_SOCKADDR_IN_SIN_LEN
      v4.sin_len = sizeof (v4);
#endif
      salen = sizeof (v4);
      sa = (const struct sockaddr *) &v4;
    }
    else if (ip_len == sizeof (struct in6_addr))
    {
      memset (&v6, 0, sizeof (v6));
      v6.sin6_family = AF_INET6;
      v6.sin6_addr = *(struct in6_addr*) ip;
#if HAVE_SOCKADDR_IN_SIN_LEN
      v6.sin6_len = sizeof (v6);
#endif
      salen = sizeof (v6);
      sa = (const struct sockaddr *) &v6;
    }
    else
    {
      GNUNET_break (0);
      if (rh->was_transmitted != GNUNET_SYSERR)
        rh->addr_callback (rh->cls, NULL, 0);
      GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh);
      GNUNET_free (rh);
      GNUNET_CLIENT_disconnect (client);
      client = NULL;
      reconnect ();
      return;
    }
    rh->addr_callback (rh->cls, sa, salen);
    GNUNET_CLIENT_receive (client, &handle_response, rh,
                           GNUNET_TIME_absolute_get_remaining (rh->timeout));
  }
}