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); }
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); }
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; }
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); }
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; }
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; }