summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAnoop C S <anoopcs@redhat.com>2016-08-10 16:32:19 +0530
committerAndreas Schneider <asn@samba.org>2016-10-20 10:50:08 +0200
commit087f9aea821cceffd3ced15b576106cace8a2c9d (patch)
tree6be3cc15b8f6ba45cb3ca87d4d1736b1c189ac3c /src
parentf43d3835451a5271c4e5ec22f321a8120b40d1df (diff)
downloadsocket_wrapper-087f9aea821cceffd3ced15b576106cace8a2c9d.tar.gz
socket_wrapper-087f9aea821cceffd3ced15b576106cace8a2c9d.tar.xz
socket_wrapper-087f9aea821cceffd3ced15b576106cace8a2c9d.zip
swrap: Untangle socket_info_fd from socket_info structure.
This reverses the dependency of socket_info on socket_info_fd: Instead of maintaining the list of socket_info structures, and keeping a list of referencing fds (created by dup), we now maintain the list of fds with pointers to the corresponding socket_info structures, and count the references in the socket_info. This makes the treatment of the lists more obvious, especially seen in the removing part. This change is a preparatory step for implementing fd-passing in socket-wrapper. Pair-programmed-with: Michael Adam <obnox@samba.org> Signed-off-by: Anoop C S <anoopcs@redhat.com> Signed-off-by: Michael Adam <obnox@samba.org> Reviewed-by: Andreas Schneider <asn@samba.org>
Diffstat (limited to 'src')
-rw-r--r--src/socket_wrapper.c134
1 files changed, 76 insertions, 58 deletions
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c
index 6c4ae3b..5cb494c 100644
--- a/src/socket_wrapper.c
+++ b/src/socket_wrapper.c
@@ -233,11 +233,14 @@ struct swrap_address {
struct socket_info_fd {
struct socket_info_fd *prev, *next;
int fd;
+
+ /* Points to list of socket_info structures */
+ struct socket_info *si;
};
struct socket_info
{
- struct socket_info_fd *fds;
+ unsigned int refcount;
int family;
int type;
@@ -261,15 +264,14 @@ struct socket_info
unsigned long pck_snd;
unsigned long pck_rcv;
} io;
-
- struct socket_info *prev, *next;
};
/*
- * File descriptors are shared between threads so we should share socket
- * information too.
+ * While socket file descriptors are passed among different processes, the
+ * numerical value gets changed. So its better to store it locally to each
+ * process rather than including it within socket_info which will be shared.
*/
-struct socket_info *sockets;
+static struct socket_info_fd *socket_fds;
/* Function prototypes */
@@ -1359,26 +1361,34 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in
return 0;
}
-static struct socket_info *find_socket_info(int fd)
+static struct socket_info_fd *find_socket_info_fd(int fd)
{
- struct socket_info *i;
+ struct socket_info_fd *f;
- for (i = sockets; i; i = i->next) {
- struct socket_info_fd *f;
- for (f = i->fds; f; f = f->next) {
- if (f->fd == fd) {
- return i;
- }
+ for (f = socket_fds; f; f = f->next) {
+ if (f->fd == fd) {
+ return f;
}
}
return NULL;
}
+static struct socket_info *find_socket_info(int fd)
+{
+ struct socket_info_fd *fi = find_socket_info_fd(fd);
+
+ if (fi == NULL) {
+ return NULL;
+ }
+
+ return fi->si;
+}
+
#if 0 /* FIXME */
static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
{
- struct socket_info *s;
+ struct socket_info_fd *f;
/* first catch invalid input */
switch (sa->sa_family) {
@@ -1399,7 +1409,9 @@ static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
break;
}
- for (s = sockets; s != NULL; s = s->next) {
+ for (f = socket_fds; f; f = f->next) {
+ struct socket_info *s = f->si;
+
if (s->myname == NULL) {
continue;
}
@@ -1461,29 +1473,29 @@ static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
static void swrap_remove_stale(int fd)
{
- struct socket_info *si = find_socket_info(fd);
- struct socket_info_fd *fi;
+ struct socket_info_fd *fi = find_socket_info_fd(fd);
+ struct socket_info *si;
- if (si == NULL) {
+ if (fi == NULL) {
return;
}
- for (fi = si->fds; fi; fi = fi->next) {
- if (fi->fd == fd) {
- SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
- SWRAP_DLIST_REMOVE(si->fds, fi);
- free(fi);
- break;
- }
+ si = fi->si;
+
+ SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
+ SWRAP_DLIST_REMOVE(socket_fds, fi);
+ free(fi);
+
+ si->refcount--;
+
+ if (si->refcount > 0) {
+ return;
}
- if (si->fds == NULL) {
- SWRAP_DLIST_REMOVE(sockets, si);
- if (si->un_addr.sun_path[0] != '\0') {
- unlink(si->un_addr.sun_path);
- }
- free(si);
+ if (si->un_addr.sun_path[0] != '\0') {
+ unlink(si->un_addr.sun_path);
}
+ free(si);
}
static int sockaddr_convert_to_un(struct socket_info *si,
@@ -2504,10 +2516,11 @@ static int swrap_socket(int family, int type, int protocol)
return -1;
}
+ si->refcount = 1;
fi->fd = fd;
+ fi->si = si;
- SWRAP_DLIST_ADD(si->fds, fi);
- SWRAP_DLIST_ADD(sockets, si);
+ SWRAP_DLIST_ADD(socket_fds, fi);
SWRAP_LOG(SWRAP_LOG_TRACE,
"Created %s socket for protocol %s",
@@ -2729,8 +2742,10 @@ static int swrap_accept(int s,
};
memcpy(&child_si->myname.sa.ss, &in_my_addr.sa.ss, in_my_addr.sa_socklen);
- SWRAP_DLIST_ADD(child_si->fds, child_fi);
- SWRAP_DLIST_ADD(sockets, child_si);
+ child_si->refcount = 1;
+ child_fi->si = child_si;
+
+ SWRAP_DLIST_ADD(socket_fds, child_fi);
if (addr != NULL) {
swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
@@ -5078,29 +5093,26 @@ ssize_t writev(int s, const struct iovec *vector, int count)
static int swrap_close(int fd)
{
- struct socket_info *si = find_socket_info(fd);
- struct socket_info_fd *fi;
+ struct socket_info_fd *fi = find_socket_info_fd(fd);
+ struct socket_info *si = NULL;
int ret;
- if (!si) {
+ if (fi == NULL) {
return libc_close(fd);
}
- for (fi = si->fds; fi; fi = fi->next) {
- if (fi->fd == fd) {
- SWRAP_DLIST_REMOVE(si->fds, fi);
- free(fi);
- break;
- }
- }
+ si = fi->si;
+
+ SWRAP_DLIST_REMOVE(socket_fds, fi);
+ free(fi);
+
+ si->refcount--;
- if (si->fds) {
+ if (si->refcount > 0) {
/* there are still references left */
return libc_close(fd);
}
- SWRAP_DLIST_REMOVE(sockets, si);
-
if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
}
@@ -5154,10 +5166,13 @@ static int swrap_dup(int fd)
return -1;
}
+ si->refcount++;
+ fi->si = si;
+
/* Make sure we don't have an entry for the fd */
swrap_remove_stale(fi->fd);
- SWRAP_DLIST_ADD(si->fds, fi);
+ SWRAP_DLIST_ADD(socket_fds, fi);
return fi->fd;
}
@@ -5211,10 +5226,13 @@ static int swrap_dup2(int fd, int newfd)
return -1;
}
+ si->refcount++;
+ fi->si = si;
+
/* Make sure we don't have an entry for the fd */
swrap_remove_stale(fi->fd);
- SWRAP_DLIST_ADD(si->fds, fi);
+ SWRAP_DLIST_ADD(socket_fds, fi);
return fi->fd;
}
@@ -5256,10 +5274,13 @@ static int swrap_vfcntl(int fd, int cmd, va_list va)
return -1;
}
+ si->refcount++;
+ fi->si = si;
+
/* Make sure we don't have an entry for the fd */
swrap_remove_stale(fi->fd);
- SWRAP_DLIST_ADD(si->fds, fi);
+ SWRAP_DLIST_ADD(socket_fds, fi);
rc = fi->fd;
break;
@@ -5332,14 +5353,11 @@ int pledge(const char *promises, const char *paths[])
*/
void swrap_destructor(void)
{
- struct socket_info *s = sockets;
+ struct socket_info_fd *s = socket_fds;
while (s != NULL) {
- struct socket_info_fd *f = s->fds;
- if (f != NULL) {
- swrap_close(f->fd);
- }
- s = sockets;
+ swrap_close(s->fd);
+ s = socket_fds;
}
if (swrap.libc_handle != NULL) {