diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/net-nonblock.c | 35 | ||||
-rw-r--r-- | src/core/network-openssl.c | 6 | ||||
-rw-r--r-- | src/core/network.c | 33 | ||||
-rw-r--r-- | src/core/network.h | 2 | ||||
-rw-r--r-- | src/core/servers.c | 45 |
5 files changed, 67 insertions, 54 deletions
diff --git a/src/core/net-nonblock.c b/src/core/net-nonblock.c index d6e767b6..94c53e74 100644 --- a/src/core/net-nonblock.c +++ b/src/core/net-nonblock.c @@ -35,41 +35,6 @@ typedef struct { int tag; } SIMPLE_THREAD_REC; -static int g_io_channel_write_block(GIOChannel *channel, void *data, int len) -{ - gsize ret; - int sent; - GIOStatus status; - - sent = 0; - do { - status = g_io_channel_write_chars(channel, (char *) data + sent, - len-sent, &ret, NULL); - sent += ret; - } while (sent < len && status != G_IO_STATUS_ERROR); - - return sent < len ? -1 : 0; -} - -static int g_io_channel_read_block(GIOChannel *channel, void *data, int len) -{ - time_t maxwait; - gsize ret; - int received; - GIOStatus status; - - maxwait = time(NULL)+2; - received = 0; - do { - status = g_io_channel_read_chars(channel, (char *) data + received, - len-received, &ret, NULL); - received += ret; - } while (received < len && time(NULL) < maxwait && - status != G_IO_STATUS_ERROR && status != G_IO_STATUS_EOF); - - return received < len ? -1 : 0; -} - /* nonblocking gethostbyname(), ip (IPADDR) + error (int, 0 = not error) is written to pipe when found PID of the resolver child is returned */ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, diff --git a/src/core/network-openssl.c b/src/core/network-openssl.c index 9fddf073..692c7e71 100644 --- a/src/core/network-openssl.c +++ b/src/core/network-openssl.c @@ -35,7 +35,8 @@ #include <openssl/err.h> /* OpenSSL 1.1.0 introduced some backward-incompatible changes to the api */ -#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \ + (!defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER < 0x2070000fL) /* The two functions below could be already defined if OPENSSL_API_COMPAT is * below the 1.1.0 version so let's do a clean start */ #undef X509_get_notBefore @@ -47,7 +48,8 @@ /* OpenSSL 1.1.0 also introduced some useful additions to the api */ #if (OPENSSL_VERSION_NUMBER >= 0x10002000L) -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined (LIBRESSL_VERSION_NUMBER) +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \ + (defined (LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL) static int X509_STORE_up_ref(X509_STORE *vfy) { int n; diff --git a/src/core/network.c b/src/core/network.c index d280b463..0e326e22 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -48,6 +48,39 @@ GIOChannel *g_io_channel_new(int handle) return chan; } +int g_io_channel_write_block(GIOChannel *channel, void *data, int len) +{ + gsize ret; + int sent; + GIOStatus status; + + sent = 0; + do { + status = g_io_channel_write_chars(channel, (char *) data + sent, len - sent, &ret, NULL); + sent += ret; + } while (sent < len && status != G_IO_STATUS_ERROR); + + return sent < len ? -1 : 0; +} + +int g_io_channel_read_block(GIOChannel *channel, void *data, int len) +{ + time_t maxwait; + gsize ret; + int received; + GIOStatus status; + + maxwait = time(NULL)+2; + received = 0; + do { + status = g_io_channel_read_chars(channel, (char *) data + received, len - received, &ret, NULL); + received += ret; + } while (received < len && time(NULL) < maxwait && + status != G_IO_STATUS_ERROR && status != G_IO_STATUS_EOF); + + return received < len ? -1 : 0; +} + IPADDR ip4_any = { AF_INET, #if defined(IN6ADDR_ANY_INIT) diff --git a/src/core/network.h b/src/core/network.h index e60f607f..30fd6aab 100644 --- a/src/core/network.h +++ b/src/core/network.h @@ -36,6 +36,8 @@ GIOChannel *g_io_channel_new(int handle); /* Returns 1 if IPADDRs are the same. */ /* Deprecated since it is unused. It will be deleted in a later release. */ int net_ip_compare(IPADDR *ip1, IPADDR *ip2) G_GNUC_DEPRECATED; +int g_io_channel_write_block(GIOChannel *channel, void *data, int len); +int g_io_channel_read_block(GIOChannel *channel, void *data, int len); int net_connect_ip_handle(const IPADDR *ip, int port, const IPADDR *my_ip); diff --git a/src/core/servers.c b/src/core/servers.c index b9faab81..11eccc53 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -460,8 +460,6 @@ static int server_remove_channels(SERVER_REC *server) void server_disconnect(SERVER_REC *server) { - int chans; - g_return_if_fail(IS_SERVER(server)); if (server->disconnected) @@ -480,21 +478,9 @@ void server_disconnect(SERVER_REC *server) server->disconnected = TRUE; signal_emit("server disconnected", 1, server); - /* close all channels */ - chans = server_remove_channels(server); - - if (server->handle != NULL) { - if (!chans || server->connection_lost) - net_sendbuffer_destroy(server->handle, TRUE); - else { - /* we were on some channels, try to let the server - disconnect so that our quit message is guaranteed - to get displayed */ - net_disconnect_later(net_sendbuffer_handle(server->handle)); - net_sendbuffer_destroy(server->handle, FALSE); - } - server->handle = NULL; - } + /* we used to destroy the handle here but it may be still in + use during signal processing, so destroy it on unref + instead */ if (server->readtag > 0) { g_source_remove(server->readtag); @@ -513,6 +499,8 @@ void server_ref(SERVER_REC *server) int server_unref(SERVER_REC *server) { + int chans; + g_return_val_if_fail(IS_SERVER(server), FALSE); if (--server->refcount > 0) @@ -524,6 +512,29 @@ int server_unref(SERVER_REC *server) return TRUE; } + /* close all channels */ + chans = server_remove_channels(server); + + /* since module initialisation uses server connected, only let + them know that the object got destroyed if the server was + disconnected */ + if (server->disconnected) { + signal_emit("server destroyed", 1, server); + } + + if (server->handle != NULL) { + if (!chans || server->connection_lost) + net_sendbuffer_destroy(server->handle, TRUE); + else { + /* we were on some channels, try to let the server + disconnect so that our quit message is guaranteed + to get displayed */ + net_disconnect_later(net_sendbuffer_handle(server->handle)); + net_sendbuffer_destroy(server->handle, FALSE); + } + server->handle = NULL; + } + MODULE_DATA_DEINIT(server); server_connect_unref(server->connrec); if (server->rawlog != NULL) rawlog_destroy(server->rawlog); |