summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/net-nonblock.c35
-rw-r--r--src/core/network-openssl.c6
-rw-r--r--src/core/network.c33
-rw-r--r--src/core/network.h2
-rw-r--r--src/core/servers.c45
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);