From a5b9350fd102ea7e4f003b82d54b91d994364433 Mon Sep 17 00:00:00 2001 From: Jan Vidar Krey Date: Wed, 10 Nov 2010 23:32:05 +0100 Subject: [PATCH] Work in progress. --- src/network/connection.c | 26 +++++++++++++++++++++++--- src/network/connection.h | 6 ++++++ src/tools/adcclient.c | 40 ++++++++++++++++++++++------------------ src/tools/adcclient.h | 1 + src/tools/admin.c | 3 ++- 5 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/network/connection.c b/src/network/connection.c index 3bf72c9..8853336 100644 --- a/src/network/connection.c +++ b/src/network/connection.c @@ -138,6 +138,23 @@ ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode #endif /* SSL_SUPPORT */ +int net_con_connect(struct net_connection* con, struct sockaddr* addr, size_t addr_len) +{ + int ret = net_connect(con->sd, (struct sockaddr*) addr, addr_len); + if (ret == 0 || (ret == -1 && net_error() == EISCONN)) + { + return 1; + } + else if (ret == -1 && (net_error() == EALREADY || net_error() == EINPROGRESS || net_error() == EWOULDBLOCK || net_error() == EINTR)) + { + return 0; + } + else + { + return -1; + } +} + ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len) { int ret; @@ -307,15 +324,18 @@ void net_con_callback(struct net_connection* con, int events) case tls_st_connected: LOG_PROTO("tls_st_connected, events=%s%s, ssl_flags=%s%s", (events & NET_EVENT_READ ? "R" : ""), (events & NET_EVENT_WRITE ? "W" : ""), con->flags & NET_WANT_SSL_READ ? "R" : "", con->flags & NET_WANT_SSL_WRITE ? "W" : ""); - if (events & NET_EVENT_WRITE && con->flags & NET_WANT_SSL_READ) + + // continue a SSL_read() that wants to write. + if (events & NET_EVENT_WRITE && con->flags & NET_WANT_SSL_WRITE) { - con->callback(con, events & NET_EVENT_READ, con->ptr); + con->callback(con, NET_EVENT_READ, con->ptr); return; } + // continue a SSL_write() that wants to read something. if (events & NET_EVENT_READ && con->flags & NET_WANT_SSL_WRITE) { - con->callback(con, events & NET_EVENT_READ, con->ptr); + con->callback(con, NET_EVENT_WRITE, con->ptr); return; } diff --git a/src/network/connection.h b/src/network/connection.h index ff69262..dc5c00b 100644 --- a/src/network/connection.h +++ b/src/network/connection.h @@ -75,6 +75,12 @@ extern ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len); */ extern ssize_t net_con_peek(struct net_connection* con, void* buf, size_t len); +/** + * Returns 1 if connected, 0 if net_con_connect needs to be called again, + * and -1 if an error occured. + */ +extern int net_con_connect(struct net_connection* con, struct sockaddr* addr, size_t addr_len); + /** * Set timeout for connetion. * diff --git a/src/tools/adcclient.c b/src/tools/adcclient.c index 93bb666..45969ee 100644 --- a/src/tools/adcclient.c +++ b/src/tools/adcclient.c @@ -376,13 +376,13 @@ int ADC_client_connect(struct ADC_client* client, const char* address) client->callback(client, ADC_CLIENT_CONNECTING, 0); } - - int ret = net_connect(net_con_get_sd(client->con), (struct sockaddr*) &client->addr, sizeof(struct sockaddr_in)); - if (ret == 0 || (ret == -1 && net_error() == EISCONN)) + + int ret = net_con_connect(client->con, (struct sockaddr*) &client->addr, sizeof(struct sockaddr_in)); + if (ret == 1) { ADC_client_on_connected(client); } - else if (ret == -1 && (net_error() == EALREADY || net_error() == EINPROGRESS || net_error() == EWOULDBLOCK || net_error() == EINTR)) + else if (ret == 0) { if (client->state != ps_conn) { @@ -400,10 +400,17 @@ int ADC_client_connect(struct ADC_client* client, const char* address) static void ADC_client_on_connected(struct ADC_client* client) { - net_con_update(client->con, NET_EVENT_READ); - client->callback(client, ADC_CLIENT_CONNECTED, 0); - ADC_client_send(client, ADC_HANDSHAKE); - ADC_client_set_state(client, ps_protocol); + if (client->ssl) + { + net_con_ssl_handshake(client->con, net_con_ssl_mode_client, NULL); + } + else + { + net_con_update(client->con, NET_EVENT_READ); + client->callback(client, ADC_CLIENT_CONNECTED, 0); + ADC_client_send(client, ADC_HANDSHAKE); + ADC_client_set_state(client, ps_protocol); + } } static void ADC_client_on_disconnected(struct ADC_client* client) @@ -432,8 +439,8 @@ static int ADC_client_parse_address(struct ADC_client* client, const char* arg) { char* split; int ssl = 0; - struct hostent* dns; - struct in_addr* addr; + struct hostent* dns = 0; + struct in_addr* addr = 0; if (!arg) return 0; @@ -445,12 +452,11 @@ static int ADC_client_parse_address(struct ADC_client* client, const char* arg) return 0; /* Check for ADC or ADCS */ - if (!strncmp(arg, "adc://", 6)) - ssl = 0; - else if (!strncmp(arg, "adcs://", 7)) - ssl = 1; - else - return 0; + if (!strncmp(arg, "adc://", 6)) ssl = 0; + else if (!strncmp(arg, "adcs://", 7)) ssl = 1; + else return 0; + + client->ssl = ssl; /* Split hostname and port (if possible) */ split = strrchr(client->hub_address + 6 + ssl, ':'); @@ -467,9 +473,7 @@ static int ADC_client_parse_address(struct ADC_client* client, const char* arg) /* Resolve IP address (FIXME: blocking call) */ dns = gethostbyname(client->hub_address + 6 + ssl); if (dns) - { addr = (struct in_addr*) dns->h_addr_list[0]; - } // Initialize the sockaddr struct. memset(&client->addr, 0, sizeof(client->addr)); diff --git a/src/tools/adcclient.h b/src/tools/adcclient.h index 3b49a3e..78c2442 100644 --- a/src/tools/adcclient.h +++ b/src/tools/adcclient.h @@ -105,6 +105,7 @@ struct ADC_client struct adc_message* info; char recvbuf[ADC_BUFSIZE]; char sendbuf[ADC_BUFSIZE]; + int ssl; adc_client_cb callback; size_t s_offset; size_t r_offset; diff --git a/src/tools/admin.c b/src/tools/admin.c index 225cbb2..e5aea64 100644 --- a/src/tools/admin.c +++ b/src/tools/admin.c @@ -82,7 +82,8 @@ int main(int argc, char** argv) while (running) { - net_backend_process(); + if (!net_backend_process()) + break; } ADC_client_destroy(&client);