diff options
author | Youness Alaoui <youness.alaoui@collabora.co.uk> | 2011-01-18 17:25:43 -0500 |
---|---|---|
committer | Youness Alaoui <youness.alaoui@collabora.co.uk> | 2011-01-18 17:25:43 -0500 |
commit | 5619d893d232df1c306f08a166071d49f0ed0e46 (patch) | |
tree | f85380c4e6e49d22604a535d97f46de44785ca5e /socket/tcp-bsd.c | |
parent | fa68cdd42e9e69010dd7cb874e7edba7369c06c0 (diff) | |
download | libnice-5619d893d232df1c306f08a166071d49f0ed0e46.tar.gz |
Fix a crash (Broken pipe) if we send to a TCP socket that had an error
Diffstat (limited to 'socket/tcp-bsd.c')
-rw-r--r-- | socket/tcp-bsd.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/socket/tcp-bsd.c b/socket/tcp-bsd.c index 8163753..c8a5c48 100644 --- a/socket/tcp-bsd.c +++ b/socket/tcp-bsd.c @@ -60,6 +60,7 @@ typedef struct { GMainContext *context; GIOChannel *io_channel; GSource *io_source; + gboolean error; } TcpPriv; struct to_be_sent { @@ -165,6 +166,7 @@ nice_tcp_bsd_socket_new (NiceAgent *agent, GMainContext *ctx, NiceAddress *addr) priv->agent = agent; priv->context = ctx; priv->server_addr = *addr; + priv->error = FALSE; sock->fileno = sockfd; sock->send = socket_send; @@ -204,12 +206,18 @@ socket_recv (NiceSocket *sock, NiceAddress *from, guint len, gchar *buf) TcpPriv *priv = sock->priv; int ret; + /* Don't try to access the socket if it had an error */ + if (priv->error) + return -1; + ret = recv (sock->fileno, buf, len, 0); /* recv returns 0 when the peer performed a shutdown.. we must return -1 here * so that the agent destroys the g_source */ - if (ret == 0) + if (ret == 0) { + priv->error = TRUE; return -1; + } if (ret < 0) { #ifdef G_OS_WIN32 @@ -237,6 +245,11 @@ socket_send (NiceSocket *sock, const NiceAddress *to, TcpPriv *priv = sock->priv; int ret; + /* Don't try to access the socket if it had an error, otherwise we risk a + crash with SIGPIPE (Broken pipe) */ + if (priv->error) + return -1; + /* First try to send the data, don't send it later if it can be sent now this way we avoid allocating memory on every send */ if (g_queue_is_empty (&priv->send_queue)) { |