From 442dc01c2b410071ff214a22f31adb25a62890b2 Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Tue, 7 Jul 2009 14:08:47 -0300 Subject: [PATCH] Allow set_driver to fail and handle this case. --- hcconn.c | 3 ++- hcconn.h | 4 ++-- hcconn_ssl.c | 10 +++++++--- pop.c | 3 ++- pop.h | 2 +- popproxy.c | 38 +++++++++++++++++++++++++++++++++----- 6 files changed, 47 insertions(+), 13 deletions(-) diff --git a/hcconn.c b/hcconn.c index 02f1572..0ba378a 100644 --- a/hcconn.c +++ b/hcconn.c @@ -132,7 +132,7 @@ hc_conn_watch (GIOChannel *channel, GIOCondition cond, gpointer data) return TRUE; } -void +int hc_conn_set_driver_channel (HCConn *conn, int fd) { struct channel_layer *layer = g_slice_new (struct channel_layer); @@ -148,6 +148,7 @@ hc_conn_set_driver_channel (HCConn *conn, int fd) if (conn->func) conn->func (conn, HC_EVENT_CONNECT, conn->data); fcntl (fd, F_SETFL, fcntl (fd, F_GETFL, 0) | O_NONBLOCK); + return 0; } diff --git a/hcconn.h b/hcconn.h index 89a9366..f5164ed 100644 --- a/hcconn.h +++ b/hcconn.h @@ -45,7 +45,7 @@ void hc_conn_write (HCConn *, char *, size_t); void hc_conn_close (HCConn *); void hc_conn_set_callback (HCConn *, HCClientFunc, gpointer); -void hc_conn_set_driver_channel (HCConn *, int); -void hc_conn_set_driver_ssl_client (HCConn *, HCConn *); +int hc_conn_set_driver_channel (HCConn *, int); +int hc_conn_set_driver_ssl_client (HCConn *, HCConn *); #endif diff --git a/hcconn_ssl.c b/hcconn_ssl.c index 0a4f885..264be27 100644 --- a/hcconn_ssl.c +++ b/hcconn_ssl.c @@ -185,11 +185,13 @@ hc_conn_ssl_watch (HCConn *conn, HCEvent event, gpointer data) } } -static void +static int hc_conn_set_driver_ssl (HCConn *conn, HCConn *lowconn, int server) { struct ssl_data *ssl; ssl = ssl_data_new (server); + if (ssl == NULL) + return -1; ssl->lowconn = lowconn; conn->layer = ssl; conn->read = hc_conn_ssl_read; @@ -197,9 +199,11 @@ hc_conn_set_driver_ssl (HCConn *conn, HCConn *lowconn, int server) conn->close = hc_conn_ssl_close; hc_conn_set_callback (lowconn, hc_conn_ssl_watch, conn); ssl_server_connect (conn); + return 0; } -void hc_conn_set_driver_ssl_client (HCConn *conn, HCConn *lowconn) +int +hc_conn_set_driver_ssl_client (HCConn *conn, HCConn *lowconn) { - hc_conn_set_driver_ssl (conn, lowconn, 0); + return hc_conn_set_driver_ssl (conn, lowconn, 0); } diff --git a/pop.c b/pop.c index 63ce258..02caf5a 100644 --- a/pop.c +++ b/pop.c @@ -165,7 +165,7 @@ pop_close (gpointer data) pop_destroy (pop); } -void +int hc_conn_set_driver_pop (HCConn *conn, HCConn *lowconn) { pop_t *pop; @@ -180,4 +180,5 @@ hc_conn_set_driver_pop (HCConn *conn, HCConn *lowconn) conn->close = pop_close; conn->layer = pop; hc_conn_set_callback (lowconn, pop_watch, conn); + return 0; } diff --git a/pop.h b/pop.h index 2c64621..a740f12 100644 --- a/pop.h +++ b/pop.h @@ -23,6 +23,6 @@ #include "hcconn.h" -void hc_conn_set_driver_pop (HCConn *, HCConn *); +int hc_conn_set_driver_pop (HCConn *, HCConn *); #endif diff --git a/popproxy.c b/popproxy.c index 03cc6d7..070738f 100644 --- a/popproxy.c +++ b/popproxy.c @@ -45,6 +45,7 @@ server_conn_new (char *server, char *port) int fd; HCConn *conn; HCConn *ssl_conn; + int r; fd = hc_tcp_connect (server, port); if (fd < 0) { @@ -53,8 +54,21 @@ server_conn_new (char *server, char *port) } conn = hc_conn_new (NULL, NULL); ssl_conn = hc_conn_new (NULL, NULL); - hc_conn_set_driver_channel (conn, fd); - hc_conn_set_driver_ssl_client (ssl_conn, conn); + r = hc_conn_set_driver_channel (conn, fd); + if (r != 0) + { + hc_conn_close (ssl_conn); + hc_conn_close (conn); + close (fd); + return NULL; + } + r = hc_conn_set_driver_ssl_client (ssl_conn, conn); + if (r != 0) + { + hc_conn_close (ssl_conn); + hc_conn_close (conn); + return NULL; + } return ssl_conn; } @@ -83,6 +97,7 @@ new_client (int fd, struct sockaddr *addr, socklen_t saddr, gpointer data) HCConn *pop_conn; HCConn *server_conn; struct pop_address *address = data; + int r; if (fd < 0) { g_critical ("Server has received an error event."); @@ -98,10 +113,23 @@ new_client (int fd, struct sockaddr *addr, socklen_t saddr, gpointer data) } conn = hc_conn_new (NULL, NULL); - hc_conn_set_driver_channel (conn, fd); + r = hc_conn_set_driver_channel (conn, fd); + if (r != 0) + { + hc_conn_close (server_conn); + hc_conn_close (conn); + close (fd); + return; + } pop_conn = hc_conn_new (NULL, NULL); - hc_conn_set_driver_pop (pop_conn, conn); - + r = hc_conn_set_driver_pop (pop_conn, conn); + if (r != 0) + { + hc_conn_close (server_conn); + hc_conn_close (pop_conn); + hc_conn_close (conn); + return; + } hc_conn_set_callback (pop_conn, push_other, server_conn); hc_conn_set_callback (server_conn, push_other, pop_conn); -- 2.20.1