Example #1
0
/**@internal
 * Main execution loop
 */
static void
main_loop(void)
{
	int result;
	pthread_t	tid;
	s_config *config = config_get_config();
	struct timespec wait_time;
	int msec;
	request *r;
	void **params;
	int* thread_serial_num_p;

	/* Set the time when nodogsplash started */
	if (!started_time) {
		debug(LOG_INFO, "Setting started_time");
		started_time = time(NULL);
	} else if (started_time < MINIMUM_STARTED_TIME) {
		debug(LOG_WARNING, "Detected possible clock skew - re-setting started_time");
		started_time = time(NULL);
	}

	/* If we don't have the Gateway IP address, get it. Exit on failure. */
	if (!config->gw_address) {
		debug(LOG_DEBUG, "Finding IP address of %s", config->gw_interface);
		if ((config->gw_address = get_iface_ip(config->gw_interface)) == NULL) {
			debug(LOG_ERR, "Could not get IP address information of %s, exiting...", config->gw_interface);
			exit(1);
		}
		if ((config->gw_mac = get_iface_mac(config->gw_interface)) == NULL) {
			debug(LOG_ERR, "Could not get MAC address information of %s, exiting...", config->gw_interface);
			exit(1);
		}
		debug(LOG_NOTICE, "Detected gateway %s at %s (%s)", config->gw_interface, config->gw_address, config->gw_mac);
	}

	/* Initializes the web server */
	if ((webserver = httpdCreate(config->gw_address, config->gw_port)) == NULL) {
		debug(LOG_ERR, "Could not create web server: %s", strerror(errno));
		exit(1);
	}
	debug(LOG_NOTICE, "Created web server on %s:%d", config->gw_address, config->gw_port);

	/* Set web root for server */
	debug(LOG_DEBUG, "Setting web root: %s",config->webroot);
	httpdSetFileBase(webserver,config->webroot);

	/* Add images files to server: any file in config->imagesdir can be served */
	debug(LOG_DEBUG, "Setting images subdir: %s",config->imagesdir);
	httpdAddWildcardContent(webserver,config->imagesdir,NULL,config->imagesdir);

	/* Add pages files to server: any file in config->pagesdir can be served */
	debug(LOG_DEBUG, "Setting pages subdir: %s",config->pagesdir);
	httpdAddWildcardContent(webserver,config->pagesdir,NULL,config->pagesdir);


	debug(LOG_DEBUG, "Registering callbacks to web server");

	httpdAddCContent(webserver, "/", "", 0, NULL, http_nodogsplash_callback_index);
	httpdAddCWildcardContent(webserver, config->authdir, NULL, http_nodogsplash_callback_auth);
	httpdAddCWildcardContent(webserver, config->denydir, NULL, http_nodogsplash_callback_deny);
	httpdAddC404Content(webserver, http_nodogsplash_callback_404);

	/* Reset the firewall (cleans it, in case we are restarting after nodogsplash crash) */

	fw_destroy();
	/* Then initialize it */
	debug(LOG_NOTICE, "Initializing firewall rules");
	if( fw_init() != 0 ) {
		debug(LOG_ERR, "Error initializing firewall rules! Cleaning up");
		fw_destroy();
		debug(LOG_ERR, "Exiting because of error initializing firewall rules");
		exit(1);
	}

	/* Start client statistics and timeout clean-up thread */
	result = pthread_create(&tid_client_check, NULL, (void *)thread_client_timeout_check, NULL);
	if (result != 0) {
		debug(LOG_ERR, "FATAL: Failed to create thread_client_timeout_check - exiting");
		termination_handler(0);
	}
	pthread_detach(tid_client_check);

	/* Start control thread */
	result = pthread_create(&tid, NULL, (void *)thread_ndsctl, (void *)safe_strdup(config->ndsctl_sock));
	if (result != 0) {
		debug(LOG_ERR, "FATAL: Failed to create thread_ndsctl - exiting");
		termination_handler(0);
	}
	pthread_detach(tid);

	/*
	 * Enter the httpd request handling loop
	 */
	debug(LOG_NOTICE, "Waiting for connections");
	while(1) {
		r = httpdGetConnection(webserver, NULL);

		/* We can't convert this to a switch because there might be
		 * values that are not -1, 0 or 1. */
		if (webserver->lastError == -1) {
			/* Interrupted system call */
			continue; /* continue loop from the top */
		} else if (webserver->lastError < -1) {
			/*
			 * FIXME
			 * An error occurred - should we abort?
			 * reboot the device ?
			 */
			debug(LOG_ERR, "FATAL: httpdGetConnection returned unexpected value %d, exiting.", webserver->lastError);
			termination_handler(0);
		} else if (r != NULL) {
			/* We got a connection */
			handle_http_request(webserver, r);
		} else {
			/* webserver->lastError should be 2 */
			/* XXX We failed an ACL.... No handling because
			 * we don't set any... */
		}
	}

	/* never reached */
}
Example #2
0
/**@internal
 * Main execution loop 
 */
static void
main_loop(void) {

  int result;
  pthread_t	tid;
  s_config *config = config_get_config();
  struct timespec wait_time;
  int msec;
  request *r;
  void **params;
  FILE *fh;
  int* thread_serial_num_p;

  /* Set the time when nodogsplash started */
  if (!started_time) {
    debug(LOG_INFO, "Setting started_time");
    started_time = time(NULL);
  }
  else if (started_time < MINIMUM_STARTED_TIME) {
    debug(LOG_WARNING, "Detected possible clock skew - re-setting started_time");
    started_time = time(NULL);
  }

  /* If we don't have the Gateway IP address, get it. Exit on failure. */
  if (!config->gw_address) {
    debug(LOG_DEBUG, "Finding IP address of %s", config->gw_interface);
    if ((config->gw_address = get_iface_ip(config->gw_interface)) == NULL) {
      debug(LOG_ERR, "Could not get IP address information of %s, exiting...", config->gw_interface);
      exit(1);
    }
    debug(LOG_NOTICE, "Detected gateway %s at %s", config->gw_interface, config->gw_address);
  }

  /* Initializes the web server */
  if ((webserver = httpdCreate(config->gw_address, config->gw_port)) == NULL) {
    debug(LOG_ERR, "Could not create web server: %s", strerror(errno));
    exit(1);
  }
  debug(LOG_NOTICE, "Created web server on %s:%d", config->gw_address, config->gw_port);

  /* Set web root for server */
  debug(LOG_DEBUG, "Setting web root: %s",config->webroot);
  httpdSetFileBase(webserver,config->webroot);

  /* Add images files to server: any file in config->imagesdir can be served */
  debug(LOG_DEBUG, "Setting images subdir: %s",config->imagesdir);
  httpdAddWildcardContent(webserver,config->imagesdir,NULL,config->imagesdir);

  /* Add pages files to server: any file in config->pagesdir can be served */
  debug(LOG_DEBUG, "Setting pages subdir: %s",config->pagesdir);
  httpdAddWildcardContent(webserver,config->pagesdir,NULL,config->pagesdir);


  debug(LOG_DEBUG, "Registering callbacks to web server");
	
  httpdAddCContent(webserver, "/", "", 0, NULL, http_nodogsplash_callback_index);
  httpdAddCWildcardContent(webserver, config->authdir, NULL, http_nodogsplash_callback_auth);
  httpdAddCWildcardContent(webserver, config->denydir, NULL, http_nodogsplash_callback_deny);
  httpdAddC404Content(webserver, http_nodogsplash_callback_404);

  /* Reset the firewall (cleans it, in case we are restarting after nodogsplash crash) */
  
  fw_destroy();
  /* Then initialize it */
  debug(LOG_NOTICE, "Initializing firewall rules");
  if( fw_init() != 0 ) {
    debug(LOG_ERR, "Error initializing firewall rules! Cleaning up");
    fw_destroy();
    debug(LOG_ERR, "Exiting because of error initializing firewall rules");
    exit(1);
  }

  /* Start client statistics and timeout clean-up thread */
  result = pthread_create(&tid_client_check, NULL, (void *)thread_client_timeout_check, NULL);
  if (result != 0) {
    debug(LOG_ERR, "FATAL: Failed to create thread_client_timeout_check - exiting");
    termination_handler(0);
  }
  pthread_detach(tid_client_check);

  /* Start control thread */
  result = pthread_create(&tid, NULL, (void *)thread_ndsctl, (void *)safe_strdup(config->ndsctl_sock));
  if (result != 0) {
    debug(LOG_ERR, "FATAL: Failed to create thread_ndsctl - exiting");
    termination_handler(0);
  }
  pthread_detach(tid);
	
  /*
   * Enter the httpd request handling loop
   */
  debug(LOG_NOTICE, "Waiting for connections");
  created_httpd_threads = 0;
  current_httpd_threads = 0;
  while(1) {
    r = httpdGetConnection(webserver, NULL);

    /* We can't convert this to a switch because there might be
     * values that are not -1, 0 or 1. */
    if (webserver->lastError == -1) {
      /* Interrupted system call */
      continue; /* continue loop from the top */
    }
    else if (webserver->lastError < -1) {
      /*
       * FIXME
       * An error occurred - should we abort?
       * reboot the device ?
       */
      debug(LOG_ERR, "FATAL: httpdGetConnection returned unexpected value %d, exiting.", webserver->lastError);
      termination_handler(0);
    }
    else if (r != NULL) {
      /*
       * We got a connection
       *
       * We create another thread to handle the request,
       * possibly sleeping first if there are too many already
       */
      debug(LOG_DEBUG,"%d current httpd threads.", current_httpd_threads);
      if(config->decongest_httpd_threads && current_httpd_threads >= config->httpd_thread_threshold) {
	msec = current_httpd_threads * config->httpd_thread_delay_ms;
	wait_time.tv_sec = msec / 1000;
	wait_time.tv_nsec = (msec % 1000) * 1000000;
	debug(LOG_INFO, "Httpd thread creation delayed %ld sec %ld nanosec for congestion.",
	      wait_time.tv_sec, wait_time.tv_nsec);
	nanosleep(&wait_time,NULL);
      }
      thread_serial_num_p = (int*) malloc(sizeof(int)); /* thread_httpd() must free */
      *thread_serial_num_p = created_httpd_threads;
      debug(LOG_INFO, "Creating httpd request thread %d for %s", *thread_serial_num_p, r->clientAddr);
      /* The void**'s are a simulation of the normal C
       * function calling sequence. */
      params = safe_malloc(3 * sizeof(void *)); /* thread_httpd() must free */
      *params = webserver;
      *(params + 1) = r;
      *(params + 2) = thread_serial_num_p;
      created_httpd_threads++;
      result = pthread_create(&tid, NULL, (void *)thread_httpd, (void *)params);
      if (result != 0) {
	debug(LOG_ERR, "FATAL: pthread_create failed to create httpd request thread - exiting...");
	termination_handler(0);
      }
      pthread_detach(tid);
    }
    else {
      /* webserver->lastError should be 2 */
      /* XXX We failed an ACL.... No handling because
       * we don't set any... */
    }
  }

  /* never reached */
}