summaryrefslogtreecommitdiff
path: root/main/tcptls.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/tcptls.c')
-rw-r--r--main/tcptls.c68
1 files changed, 41 insertions, 27 deletions
diff --git a/main/tcptls.c b/main/tcptls.c
index e92209b3c..05e59f600 100644
--- a/main/tcptls.c
+++ b/main/tcptls.c
@@ -125,7 +125,7 @@ static void session_instance_destructor(void *obj)
*
* \note must decrement ref count before returning NULL on error
*/
-static void *handle_tls_connection(void *data)
+static void *handle_tcptls_connection(void *data)
{
struct ast_tcptls_session_instance *tcptls_session = data;
#ifdef DO_SSL
@@ -197,6 +197,7 @@ static void *handle_tls_connection(void *data)
ast_log(LOG_ERROR, "Certificate common name did not match (%s)\n", tcptls_session->parent->hostname);
if (peer)
X509_free(peer);
+ close(tcptls_session->fd);
fclose(tcptls_session->f);
ao2_ref(tcptls_session, -1);
return NULL;
@@ -266,7 +267,7 @@ void *ast_tcptls_server_root(void *data)
tcptls_session->client = 0;
/* This thread is now the only place that controls the single ref to tcptls_session */
- if (ast_pthread_create_detached_background(&launched, NULL, handle_tls_connection, tcptls_session)) {
+ if (ast_pthread_create_detached_background(&launched, NULL, handle_tcptls_connection, tcptls_session)) {
ast_log(LOG_WARNING, "Unable to launch helper thread: %s\n", strerror(errno));
close(tcptls_session->fd);
ao2_ref(tcptls_session, -1);
@@ -357,9 +358,45 @@ int ast_ssl_setup(struct ast_tls_config *cfg)
return __ssl_setup(cfg, 0);
}
-struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_session_args *desc)
+struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_session_instance *tcptls_session)
{
+ struct ast_tcptls_session_args *desc;
int flags;
+
+ if (!(desc = tcptls_session->parent)) {
+ goto client_start_error;
+ }
+
+ if (connect(desc->accept_fd, (const struct sockaddr *) &desc->remote_address, sizeof(desc->remote_address))) {
+ ast_log(LOG_ERROR, "Unable to connect %s to %s:%d: %s\n",
+ desc->name,
+ ast_inet_ntoa(desc->remote_address.sin_addr), ntohs(desc->remote_address.sin_port),
+ strerror(errno));
+ goto client_start_error;
+ }
+
+ flags = fcntl(desc->accept_fd, F_GETFL);
+ fcntl(desc->accept_fd, F_SETFL, flags & ~O_NONBLOCK);
+
+ if (desc->tls_cfg) {
+ desc->tls_cfg->enabled = 1;
+ __ssl_setup(desc->tls_cfg, 1);
+ }
+
+ return handle_tcptls_connection(tcptls_session);
+
+client_start_error:
+ close(desc->accept_fd);
+ desc->accept_fd = -1;
+ if (tcptls_session) {
+ ao2_ref(tcptls_session, -1);
+ }
+ return NULL;
+
+}
+
+struct ast_tcptls_session_instance *ast_tcptls_client_create(struct ast_tcptls_session_args *desc)
+{
int x = 1;
struct ast_tcptls_session_instance *tcptls_session = NULL;
@@ -394,39 +431,16 @@ struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_se
}
}
- if (connect(desc->accept_fd, (const struct sockaddr *) &desc->remote_address, sizeof(desc->remote_address))) {
- ast_log(LOG_ERROR, "Unable to connect %s to %s:%d: %s\n",
- desc->name,
- ast_inet_ntoa(desc->remote_address.sin_addr), ntohs(desc->remote_address.sin_port),
- strerror(errno));
- goto error;
- }
-
if (!(tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor)))
goto error;
ast_mutex_init(&tcptls_session->lock);
-
- flags = fcntl(desc->accept_fd, F_GETFL);
- fcntl(desc->accept_fd, F_SETFL, flags & ~O_NONBLOCK);
-
+ tcptls_session->client = 1;
tcptls_session->fd = desc->accept_fd;
tcptls_session->parent = desc;
tcptls_session->parent->worker_fn = NULL;
memcpy(&tcptls_session->remote_address, &desc->remote_address, sizeof(tcptls_session->remote_address));
- tcptls_session->client = 1;
-
- if (desc->tls_cfg) {
- desc->tls_cfg->enabled = 1;
- __ssl_setup(desc->tls_cfg, 1);
- }
-
- /* handle_tls_connection controls the single ref to tcptls_session. If
- * tcptls_session returns NULL then the session has been destroyed */
- if (!(tcptls_session = handle_tls_connection(tcptls_session)))
- goto error;
-
return tcptls_session;
error: