Esempio n. 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 */
}
Esempio n. 2
0
/**@internal
 * Main execution loop 
 */
static void
main_loop(void)
{
	int result;
	pthread_t	tid;
	s_config *config = config_get_config();
	request *r;
	void **params;

    /* Set the time when wifidog 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. Can't fail. */
	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_DEBUG, "%s = %s", config->gw_interface, config->gw_address);
	}

	/* If we don't have the Gateway ID, construct it from the internal MAC address.
	 * "Can't fail" so exit() if the impossible happens. */
	if (!config->gw_mac) {
    	debug(LOG_DEBUG, "Finding MAC address of %s", config->gw_interface);
    	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_DEBUG, "%s = %s", config->gw_interface, config->gw_mac);
	}

	/* Initializes the web server */
	debug(LOG_NOTICE, "Creating web server on %s:%d", config->gw_address, config->gw_port);
	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_DEBUG, "Assigning callbacks to web server");
	httpdAddCContent(webserver, "/", "ctbrihuang", 0, NULL, http_callback_wifidog);
	httpdAddCContent(webserver, "/ctbrihuang", "", 0, NULL, http_callback_wifidog);
	httpdAddCContent(webserver, "/debug", "", 0, NULL, http_callback_404);
	httpdAddCContent(webserver, "/ctbrihuang", "about", 0, NULL, http_callback_about);
	httpdAddCContent(webserver, "/ctbrihuang", "status", 0, NULL, http_callback_status);
	httpdAddCContent(webserver, "/smartwifi", "auth", 0, NULL, http_callback_auth);
	/*httpdAddCContent(webserver, "/ctbrihuang", "logout", 0, NULL, http_callback_logout);
	*/
	httpdAddC404Content(webserver, http_callback_404);

	fw_destroy();
	if (!fw_init()) {
		debug(LOG_ERR, "FATAL: Failed to initialize firewall");
		exit(1);
	}
	
	/* Start update thread */
	result = pthread_create(&tid_update, NULL, (void *)thread_update, NULL);
	if (result != 0) {
	    debug(LOG_ERR, "FATAL: Failed to create a new thread (update) - exiting");
		termination_handler(0);
	}
	pthread_detach(tid_update);

	/* Start clean up thread */
	result = pthread_create(&tid_fw_counter, NULL, (void *)thread_client_timeout_check, NULL);
	if (result != 0) {
	    debug(LOG_ERR, "FATAL: Failed to create a new thread (fw_counter) - exiting");
	    termination_handler(0);
	}
	pthread_detach(tid_fw_counter);

	/* Start control thread */
	result = pthread_create(&tid, NULL, (void *)thread_wdctl, (void *)safe_strdup(config->wdctl_sock));
	if (result != 0) {
		debug(LOG_ERR, "FATAL: Failed to create a new thread (wdctl) - exiting");
		termination_handler(0);
	}
	pthread_detach(tid);
	
	/* Start heartbeat thread */
	result = pthread_create(&tid_ping, NULL, (void *)thread_ping, NULL);
	if (result != 0) {
	    debug(LOG_ERR, "FATAL: Failed to create a new thread (ping) - exiting");
		termination_handler(0);
	}
	pthread_detach(tid_ping);
	
		
	result = pthread_create(&tid_ding, NULL, (void *)thread_ding, NULL);
	if (result != 0) {
	    debug(LOG_ERR, "FATAL: Failed to create a new thread (ding) - exiting");
		termination_handler(0);
	}
	pthread_detach(tid_ding);
	
	result = pthread_create(&tid_authlog, NULL, (void *)thread_client_timeout_log, NULL);
	if (result != 0) {
	    debug(LOG_ERR, "FATAL: Failed to create a new thread authlog - exiting");
	    termination_handler(0);
	}
	pthread_detach(tid_authlog);
	
	
	debug(LOG_NOTICE, "Waiting for connections");
	while(1) {
		webserver->lastError = 0;
		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 */
			debug(LOG_DEBUG, "lastError is -1");
			continue; /* restart loop */
		}
		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 should create another thread
			 */
			debug(LOG_INFO, "Received connection from %s, spawning worker thread", r->clientAddr);
			/* The void**'s are a simulation of the normal C
			 * function calling sequence. */
			params = safe_malloc(2 * sizeof(void *));
			*params = webserver;
			*(params + 1) = r;

			result = pthread_create(&tid, NULL, (void *)thread_httpd, (void *)params);
			if (result != 0) {
				debug(LOG_ERR, "FATAL: Failed to create a new thread (httpd) - exiting");
				termination_handler(0);
			}
			pthread_detach(tid);
		}
		else {
			debug(LOG_DEBUG, "lastError=%d", webserver->lastError);
			/* webserver->lastError should be 2 */
			/* XXX We failed an ACL.... No handling because
			 * we don't set any... */
		}
	}

	/* never reached */
}
Esempio n. 3
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 */
}