aboutsummaryrefslogtreecommitdiffstats
path: root/src/stream.c
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2016-11-26 14:51:45 +0100
committerHarald Welte <laforge@gnumonks.org>2017-04-14 11:06:09 +0200
commit719d1a38c67afb5e896d35bccb2cc3f922872ec8 (patch)
treec943ef810b7d73283ba0cebb802b2b0f128e8569 /src/stream.c
parenta7d7dd220cd8a94ca6ee341620f0cd40815ec3b7 (diff)
osmo_stream_srv_fd_cb(): don't leak socket FDs on errors
So far we seem to assume that the accept_cb does all handling of socket fd cleanup. However, there are cases where there is no accept_cb set, the accept_cb returns error, or an earlier sctp_sock_activate_events() or the activation of non-blocking mode fails. For those cases, close the socket and return an error code. Fixes: CID#57915 Change-Id: I3a3ce9194ab7ca5c1921fc79c2a1c9e10a552cf0
Diffstat (limited to 'src/stream.c')
-rw-r--r--src/stream.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/src/stream.c b/src/stream.c
index 591cd06..653f26b 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -529,6 +529,7 @@ struct osmo_stream_srv_link {
static int osmo_stream_srv_fd_cb(struct osmo_fd *ofd, unsigned int what)
{
int ret;
+ int sock_fd;
struct sockaddr_in sa;
socklen_t sa_len = sizeof(sa);
struct osmo_stream_srv_link *link = ofd->data;
@@ -541,17 +542,33 @@ static int osmo_stream_srv_fd_cb(struct osmo_fd *ofd, unsigned int what)
}
LOGP(DLINP, LOGL_DEBUG, "accept()ed new link from %s to port %u\n",
inet_ntoa(sa.sin_addr), link->port);
+ sock_fd = ret;
- if (link->proto == IPPROTO_SCTP)
- sctp_sock_activate_events(ret);
+ if (link->proto == IPPROTO_SCTP) {
+ ret = sctp_sock_activate_events(sock_fd);
+ if (ret < 0)
+ goto error_close_socket;
+ }
- if (link->flags & OSMO_STREAM_SRV_F_NODELAY)
- setsockopt_nodelay(ret, link->proto, 1);
+ if (link->flags & OSMO_STREAM_SRV_F_NODELAY) {
+ ret = setsockopt_nodelay(ret, link->proto, 1);
+ if (ret < 0)
+ goto error_close_socket;
+ }
- if (link->accept_cb)
- link->accept_cb(link, ret);
+ if (!link->accept_cb) {
+ ret = -ENOTSUP;
+ goto error_close_socket;
+ }
+ ret = link->accept_cb(link, sock_fd);
+ if (ret)
+ goto error_close_socket;
return 0;
+
+error_close_socket:
+ close(sock_fd);
+ return ret;
}
/*! \brief Create an Osmocom Stream Server Link