Ejemplo n.º 1
0
Archivo: config.c Proyecto: indutny/bud
void bud_config_free(bud_config_t* config) {
  int i;

  /* Free all reload-dependent resources */
  bud_config_finalize(config);
  if (config->loop != NULL)
    uv_run(config->loop, UV_RUN_NOWAIT);

  for (i = 0; i < config->context_count + 1; i++)
    bud_context_free(&config->contexts[i]);
  free(config->contexts);
  config->contexts = NULL;

  bud_logger_free(config->logger);
  config->logger = NULL;

  bud_hashmap_iterate(&config->files.hashmap, bud_config_free_files, NULL);
  bud_hashmap_destroy(&config->files.hashmap);

  json_value_free(config->json);
  config->json = NULL;

  free(config->files.str);
  config->files.str = NULL;

  bud_config_trace_free(&config->trace);

  /* Free rest */
  free(config->workers);
  config->workers = NULL;

  free(config);
}
Ejemplo n.º 2
0
void bud_client_close_cb(uv_handle_t* handle) {
  bud_client_t* client;

  client = (bud_client_t*) handle->data;

  if (--client->destroy_waiting != 0)
    return;

  bud_trace_end(client);
  DBG_LN(&client->frontend, "close_cb");

  bud_client_side_destroy(&client->frontend);
  bud_client_side_destroy(&client->backend);

  if (client->ssl != NULL)
    SSL_free(client->ssl);
  if (client->sni_ctx.ctx != NULL)
    bud_context_free(&client->sni_ctx);
  if (client->sni_req != NULL)
    bud_http_request_cancel(client->sni_req);
  if (client->stapling_cache_req != NULL)
    bud_http_request_cancel(client->stapling_cache_req);
  if (client->stapling_req != NULL)
    bud_http_request_cancel(client->stapling_req);
  if (client->stapling_ocsp_resp != NULL)
    free(client->stapling_ocsp_resp);

  client->ssl = NULL;
  client->sni_req = NULL;
  client->stapling_cache_req = NULL;
  client->stapling_req = NULL;
  client->stapling_ocsp_resp = NULL;

  free(client);
}
Ejemplo n.º 3
0
void bud_config_destroy(bud_config_t* config) {
  int i;

  bud_config_finalize(config);
  if (config->loop != NULL)
    uv_run(config->loop, UV_RUN_NOWAIT);

  for (i = 0; i < config->context_count + 1; i++)
    bud_context_free(&config->contexts[i]);
  free(config->contexts);
  config->contexts = NULL;

  bud_logger_free(config->logger);
  config->logger = NULL;

  json_value_free(config->json);
  config->json = NULL;

  free(config->path);
  config->path = NULL;

  for (i = 0; i < config->backend_count; i++) {
    if (config->backend[i].revive_timer != NULL) {
      uv_close((uv_handle_t*) config->backend[i].revive_timer,
               (uv_close_cb) free);
      config->backend[i].revive_timer = NULL;
    }
  }
  free(config->backend);
  config->backend = NULL;
}
Ejemplo n.º 4
0
void bud_config_free(bud_config_t* config) {
  int i;

  bud_config_finalize(config);
  uv_run(config->loop, UV_RUN_ONCE);

  for (i = 0; i < config->context_count + 1; i++)
    bud_context_free(&config->contexts[i]);
  free(config->workers);
  config->workers = NULL;

  if (config->logger != NULL)
    bud_logger_free(config);
  config->logger = NULL;

  json_value_free(config->json);
  config->json = NULL;
  free(config);
}
Ejemplo n.º 5
0
Archivo: config.c Proyecto: indutny/bud
bud_error_t bud_config_init(bud_config_t* config) {
  bud_error_t err;
  int i;
  int r;

  /* Get addresses of frontend and backend */
  r = bud_config_str_to_addr(config->frontend.host,
                             config->frontend.port,
                             &config->frontend.addr);
  if (r != 0)
    return bud_error_num(kBudErrPton, r);

  for (i = 0; i < config->frontend.interface.count; i++) {
    bud_config_addr_t* addr;

    addr = &config->frontend.interface.list[i];
    r = bud_config_str_to_addr(addr->host, addr->port, &addr->addr);
    if (r != 0)
      return bud_error_num(kBudErrPton, r);
  }

  err = bud_config_format_proxyline(config);
  if (!bud_is_ok(err))
    return err;

  i = 0;

  config->balance_e = bud_config_balance_to_enum(config->balance);

  /* At least one backend should be present for non-SNI balancing */
  if (config->contexts[0].backend.count == 0 &&
      config->balance_e != kBudBalanceSNI) {
    err = bud_error(kBudErrNoBackend);
    goto fatal;
  }

  /* Get indexes for SSL_set_ex_data()/SSL_get_ex_data() */
  if (kBudSSLClientIndex == -1) {
    kBudSSLConfigIndex = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
    kBudSSLClientIndex = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
    kBudSSLSNIIndex = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
    kBudSSLTicketKeyIndex = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
    if (kBudSSLConfigIndex == -1 ||
        kBudSSLClientIndex == -1 ||
        kBudSSLSNIIndex == -1 ||
        kBudSSLTicketKeyIndex == -1) {
      err = bud_error(kBudErrNoSSLIndex);
      goto fatal;
    }
  }

#ifndef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
  if (config->context_count != 0) {
    err = bud_error(kBudErrSNINotSupported);
    goto fatal;
  }
#endif  /* !SSL_CTRL_SET_TLSEXT_SERVERNAME_CB */

  /* Allocate workers */
  if (!config->is_worker && config->worker_count != 0) {
    config->workers = calloc(config->worker_count, sizeof(*config->workers));
    if (config->workers == NULL) {
      err = bud_error_str(kBudErrNoMem, "workers");
      goto fatal;
    }
  }

  /* Initialize logger */
  config->logger = bud_logger_new(config, &err);
  if (!bud_is_ok(err))
    goto fatal;

  err = bud_config_init_tracing(&config->trace);
  if (!bud_is_ok(err))
    goto fatal;

  if (config->is_worker || config->worker_count == 0) {
    /* Connect to SNI server */
    if (config->sni.enabled) {
      config->sni.pool = bud_http_pool_new(config,
                                           config->sni.host,
                                           config->sni.port,
                                           &err);
      if (config->sni.pool == NULL)
        goto fatal;
    }

    /* Connect to OCSP Stapling server */
    if (config->stapling.enabled) {
      config->stapling.pool = bud_http_pool_new(config,
                                                config->stapling.host,
                                                config->stapling.port,
                                                &err);
      if (config->stapling.pool == NULL)
        goto fatal;
    }
  }

  /* Init all contexts */
  for (i = 0; i < config->context_count + 1; i++) {
    err = bud_context_init(config, &config->contexts[i]);
    if (!bud_is_ok(err))
      goto fatal;
  }

  return bud_ok();

fatal:
  /* Free all allocated contexts */
  do
    bud_context_free(&config->contexts[i--]);
  while (i >= 0);

  return err;
}
Ejemplo n.º 6
0
bud_error_t bud_config_init(bud_config_t* config) {
  int i;
  int r;
  bud_context_t* ctx;
  bud_error_t err;
  const char* cert_file;
  const char* key_file;
  BIO* cert_bio;

  i = 0;

  /* Get addresses of frontend and backend */
  r = bud_config_str_to_addr(config->frontend.host,
                             config->frontend.port,
                             &config->frontend.addr);
  if (r != 0) {
    err = bud_error_num(kBudErrPton, r);
    goto fatal;
  }

  r = bud_config_str_to_addr(config->backend.host,
                             config->backend.port,
                             &config->backend.addr);
  if (r != 0) {
    err = bud_error_num(kBudErrPton, r);
    goto fatal;
  }

  /* Get indexes for SSL_set_ex_data()/SSL_get_ex_data() */
  if (kBudSSLClientIndex == -1) {
    kBudSSLClientIndex = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
    kBudSSLSNIIndex = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
    if (kBudSSLClientIndex == -1 || kBudSSLSNIIndex == -1)
      goto fatal;
  }

#ifndef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
  if (config->context_count != 0) {
    err = bud_error(kBudErrSNINotSupported);
    goto fatal;
  }
#endif  /* !SSL_CTRL_SET_TLSEXT_SERVERNAME_CB */

  /* Allocate workers */
  if (!config->is_worker) {
    config->workers = calloc(config->worker_count, sizeof(*config->workers));
    if (config->workers == NULL) {
      err = bud_error_str(kBudErrNoMem, "workers");
      goto fatal;
    }
  }

  /* Initialize logger */
  err = bud_logger_new(config);
  if (!bud_is_ok(err))
    goto fatal;

  if (config->is_worker || config->worker_count == 0) {
    /* Connect to SNI server */
    if (config->sni.enabled) {
      config->sni.pool = bud_http_pool_new(config,
                                           config->sni.host,
                                           config->sni.port,
                                           &err);
      if (config->sni.pool == NULL)
        goto fatal;
    }

    /* Connect to OCSP Stapling server */
    if (config->stapling.enabled) {
      config->stapling.pool = bud_http_pool_new(config,
                                                config->stapling.host,
                                                config->stapling.port,
                                                &err);
      if (config->stapling.pool == NULL)
        goto fatal;
    }
  }

  /* Load all contexts */
  for (i = 0; i < config->context_count + 1; i++) {
    ctx = &config->contexts[i];

    err = bud_config_new_ssl_ctx(config, ctx);
    if (!bud_is_ok(err))
      goto fatal;

    /* Default context */
    if (i == 0) {
      cert_file = config->frontend.cert_file;
      key_file = config->frontend.key_file;
    } else {
      cert_file = ctx->cert_file;
      key_file = ctx->key_file;
    }

    cert_bio = BIO_new_file(cert_file, "r");
    if (cert_bio == NULL) {
      err = bud_error_str(kBudErrLoadCert, cert_file);
      goto fatal;
    }

    r = bud_context_use_certificate_chain(ctx, cert_bio);
    BIO_free_all(cert_bio);
    if (!r) {
      err = bud_error_str(kBudErrParseCert, cert_file);
      goto fatal;
    }

    if (!SSL_CTX_use_PrivateKey_file(ctx->ctx,
                                     key_file,
                                     SSL_FILETYPE_PEM)) {
      err = bud_error_str(kBudErrParseKey, key_file);
      goto fatal;
    }
  }

  return bud_ok();

fatal:
  /* Free all allocated contexts */
  do
    bud_context_free(&config->contexts[i--]);
  while (i >= 0);

  return err;
}