summaryrefslogtreecommitdiff
path: root/socket/tcp-bsd.c
diff options
context:
space:
mode:
authorYouness Alaoui <youness.alaoui@collabora.co.uk>2011-01-18 17:25:43 -0500
committerYouness Alaoui <youness.alaoui@collabora.co.uk>2011-01-18 17:25:43 -0500
commit5619d893d232df1c306f08a166071d49f0ed0e46 (patch)
treef85380c4e6e49d22604a535d97f46de44785ca5e /socket/tcp-bsd.c
parentfa68cdd42e9e69010dd7cb874e7edba7369c06c0 (diff)
downloadlibnice-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.c15
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)) {