Ejemplo n.º 1
0
static int pklua_socket_server_accepted_cb(int sockfd, void* void_data) {
  pk_log(PK_LOG_LUA_DEBUG,
         "pklua_socket_server_accepted_cb(%d, %p)", sockfd, void_data);
  pklua_socket_server_cb_data* data = (pklua_socket_server_cb_data*) void_data;
  pkb_add_job(&(data->pkm->blocking_jobs), PK_ACCEPT_LUA, sockfd, void_data);
  return 0;
}
Ejemplo n.º 2
0
void pkb_stop_blockers(struct pk_manager *pkm)
{
  int i;
  pkb_add_job(&(pkm->blocking_jobs), PK_QUIT, 0, NULL);
  for (i = 0; i < MAX_BLOCKING_THREADS; i++) {
    if (pkm->blocking_threads[i] != NULL) {
      pthread_join(pkm->blocking_threads[i]->thread, NULL);
#if HAVE_LUA
      pklua_close_lua(pkm->blocking_threads[i]->lua);
#endif
      free(pkm->blocking_threads[i]);
      pkm->blocking_threads[i] = NULL;
    }
  }
}
Ejemplo n.º 3
0
void* pkb_run_blocker(void *void_pkblocker)
{
  time_t last_check_world = 0;
  time_t last_check_tunnels = 0;
  struct pk_job job;
  struct pk_blocker* this = (struct pk_blocker*) void_pkblocker;
  struct pk_manager* pkm = this->manager;

#if HAVE_LUA
  /* Initialize Lua state for this thread/blocker. */
  if (pkm->lua != NULL) {
    this->lua = pklua_unlock_lua(pklua_get_locked_lua(pkm));
  }
#endif

  pk_log(PK_LOG_MANAGER_DEBUG, "Started blocking thread.");
  PK_HOOK(PK_HOOK_START_BLOCKER, 0, this, pkm);

  while (1) {
    pkb_get_job(&(pkm->blocking_jobs), &job);
    switch (job.job) {
      case PK_NO_JOB:
        break;
      case PK_CHECK_WORLD:
        if (time(0) >= last_check_world + pkm->housekeeping_interval_min) {
          pkm_reconfig_start((struct pk_manager*) job.ptr_data);
          if (PK_HOOK(PK_HOOK_CHECK_WORLD, 0, this, pkm)) {
            pkb_check_world((struct pk_manager*) job.ptr_data);
            pkb_check_tunnels((struct pk_manager*) job.ptr_data);
            last_check_world = last_check_tunnels = time(0);
            PK_HOOK(PK_HOOK_CHECK_WORLD, 1, this, pkm);
          }
          pkm_reconfig_stop((struct pk_manager*) job.ptr_data);
        }
        break;
      case PK_CHECK_FRONTENDS:
        if (time(0) >= last_check_tunnels + pkm->housekeeping_interval_min) {
          pkm_reconfig_start((struct pk_manager*) job.ptr_data);
          if (PK_HOOK(PK_HOOK_CHECK_TUNNELS, 0, this, pkm)) {
            pkb_check_tunnels((struct pk_manager*) job.ptr_data);
            last_check_tunnels = time(0);
            PK_HOOK(PK_HOOK_CHECK_TUNNELS, 1, this, pkm);
          }
          pkm_reconfig_stop((struct pk_manager*) job.ptr_data);
        }
        break;
      case PK_ACCEPT_LUA:
#if HAVE_LUA
        pklua_socket_server_accepted(this->lua, job.int_data, job.ptr_data);
#endif
        break;
      case PK_ACCEPT_FE:
        /* FIXME: Do something more useful here */
        if (PKS_fail(PKS_close(job.int_data))) { };
        break;
      case PK_QUIT:
        /* Put the job back in the queue, in case there are many workers */
        pkb_add_job(&(pkm->blocking_jobs), PK_QUIT, 0, NULL);
        pk_log(PK_LOG_MANAGER_DEBUG, "Exiting blocking thread.");
        return NULL;
    }
  }
}
Ejemplo n.º 4
0
static int _pkr_process_readable(struct incoming_conn_state* ics)
{
  char peeked[PEEK_BYTES+1];
  int bytes;
  int result = PARSE_UNDECIDED;

  PK_TRACE_FUNCTION;

  /* We have data! Peek at it to find out what it is... */
  bytes = PKS_peek(ics->pkb->conn.sockfd, peeked, PEEK_BYTES);
  if (bytes == 0) {
    /* Connection closed already */
    result = PARSE_FAILED;
  }
  else if (bytes < 0) {
    pk_log(PK_LOG_MANAGER_DEBUG,
           "_pkr_process_readable(%d): peek failed %d=%s!",
           ics->pkb->conn.sockfd, errno, strerror(errno));
    if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) {
      result = PARSE_WANT_MORE_DATA;
    }
    else {
      result = PARSE_FAILED;
    }
  }
  else {
    peeked[bytes] = '\0';
  }

  if (!result) result = _pkr_parse_ssltls(peeked, bytes, ics);
  if (!result) result = _pkr_parse_http(peeked, bytes, ics);

  /* No result yet? Do we have enough data? */
  if (!result) {
    if (bytes > 4) {
      result = PARSE_FAILED;
    }
    else {
      result = PARSE_WANT_MORE_DATA;
    }
  }

  ics->parse_state = result;
  pk_log(PK_LOG_MANAGER_DEBUG,
         "_pkr_process_readable(%d): result=%d, bytes=%d",
         ics->pkb->conn.sockfd, result, bytes);

  if ((result == PARSE_WANT_MORE_DATA) || (result == PARSE_MATCH_SLOW)) {
    /* Parsers found something or we still need more data.
     * Punt to another thread for further processing. */
    pkb_add_job(&(ics->pkm->blocking_jobs), PK_RELAY_INCOMING, result, ics);
  }
  else if (result == PARSE_MATCH_FAST) {
    /* Parsers found something. Process now. */
    pkr_relay_incoming(result, ics);
  }
  else {
    /* result == PARSE_FAILED */
    _pkr_close(ics, 0, "No tunnel found");
  }

  PK_CHECK_MEMORY_CANARIES;

  return result;
}