[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Thu Sep 29 05:14:04 MDT 2011


The branch, master has been updated
       via  27195b3 socket_wrapper: correctly handle dup()/dup2() ref counting
       via  a110d05 socket_wrapper: pass down the fd explictly from the swrap_*() to the real_*() calls
      from  ea00f0e s3:smb2_server: SMB2_OP_CANCEL requests don't have to be signed

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 27195b3ac5970037445e8d05efb77b39cbfdd9ba
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Sep 28 23:09:49 2011 +0200

    socket_wrapper: correctly handle dup()/dup2() ref counting
    
    metze
    
    Autobuild-User: Stefan Metzmacher <metze at samba.org>
    Autobuild-Date: Thu Sep 29 13:13:56 CEST 2011 on sn-devel-104

commit a110d05f679e216fed7b1b1724ac17898024e834
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Sep 28 23:04:51 2011 +0200

    socket_wrapper: pass down the fd explictly from the swrap_*() to the real_*() calls
    
    metze

-----------------------------------------------------------------------

Summary of changes:
 lib/socket_wrapper/socket_wrapper.c |  187 +++++++++++++++++------------------
 1 files changed, 92 insertions(+), 95 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c
index ddfc74f..a54f50f 100644
--- a/lib/socket_wrapper/socket_wrapper.c
+++ b/lib/socket_wrapper/socket_wrapper.c
@@ -212,11 +212,14 @@ static size_t socket_length(int family)
 	return 0;
 }
 
-
+struct socket_info_fd {
+	struct socket_info_fd *prev, *next;
+	int fd;
+};
 
 struct socket_info
 {
-	int fd;
+	struct socket_info_fd *fds;
 
 	int family;
 	int type;
@@ -585,8 +588,12 @@ static struct socket_info *find_socket_info(int fd)
 {
 	struct socket_info *i;
 	for (i = sockets; i; i = i->next) {
-		if (i->fd == fd) 
-			return i;
+		struct socket_info_fd *f;
+		for (f = i->fds; f; f = f->next) {
+			if (f->fd == fd) {
+				return i;
+			}
+		}
 	}
 
 	return NULL;
@@ -1405,6 +1412,7 @@ static void swrap_dump_packet(struct socket_info *si,
 _PUBLIC_ int swrap_socket(int family, int type, int protocol)
 {
 	struct socket_info *si;
+	struct socket_info_fd *fi;
 	int fd;
 	int real_type = type;
 #ifdef SOCK_CLOEXEC
@@ -1466,6 +1474,10 @@ _PUBLIC_ int swrap_socket(int family, int type, int protocol)
 	if (fd == -1) return -1;
 
 	si = (struct socket_info *)calloc(1, sizeof(struct socket_info));
+	if (si == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
 
 	si->family = family;
 
@@ -1473,16 +1485,26 @@ _PUBLIC_ int swrap_socket(int family, int type, int protocol)
 	 * the type, not the flags */
 	si->type = real_type;
 	si->protocol = protocol;
-	si->fd = fd;
 
+	fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
+	if (fi == NULL) {
+		free(si);
+		errno = ENOMEM;
+		return -1;
+	}
+
+	fi->fd = fd;
+
+	SWRAP_DLIST_ADD(si->fds, fi);
 	SWRAP_DLIST_ADD(sockets, si);
 
-	return si->fd;
+	return fd;
 }
 
 _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
 {
 	struct socket_info *parent_si, *child_si;
+	struct socket_info_fd *child_fi;
 	int fd;
 	struct sockaddr_un un_addr;
 	socklen_t un_addrlen = sizeof(un_addr);
@@ -1535,7 +1557,19 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
 	child_si = (struct socket_info *)malloc(sizeof(struct socket_info));
 	memset(child_si, 0, sizeof(*child_si));
 
-	child_si->fd = fd;
+	child_fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
+	if (child_fi == NULL) {
+		free(child_si);
+		free(my_addr);
+		close(fd);
+		errno = ENOMEM;
+		return -1;
+	}
+
+	child_fi->fd = fd;
+
+	SWRAP_DLIST_ADD(child_si->fds, child_fi);
+
 	child_si->family = parent_si->family;
 	child_si->type = parent_si->type;
 	child_si->protocol = parent_si->protocol;
@@ -1557,6 +1591,7 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
 	ret = real_getsockname(fd, (struct sockaddr *)(void *)&un_my_addr,
 			       &un_my_addrlen);
 	if (ret == -1) {
+		free(child_fi);
 		free(child_si);
 		close(fd);
 		return ret;
@@ -1566,6 +1601,7 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
 	ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen,
 				       child_si->family, my_addr, &len);
 	if (ret == -1) {
+		free(child_fi);
 		free(child_si);
 		free(my_addr);
 		close(fd);
@@ -1594,7 +1630,7 @@ static int autobind_start;
    assign it here.
    Note: this might change the family from ipv6 to ipv4
 */
-static int swrap_auto_bind(struct socket_info *si, int family)
+static int swrap_auto_bind(int fd, struct socket_info *si, int family)
 {
 	struct sockaddr_un un_addr;
 	int i;
@@ -1683,7 +1719,7 @@ static int swrap_auto_bind(struct socket_info *si, int family)
 			 type, socket_wrapper_default_iface(), port);
 		if (stat(un_addr.sun_path, &st) == 0) continue;
 
-		ret = real_bind(si->fd, (struct sockaddr *)(void *)&un_addr,
+		ret = real_bind(fd, (struct sockaddr *)(void *)&un_addr,
 				sizeof(un_addr));
 		if (ret == -1) return ret;
 
@@ -1716,7 +1752,7 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad
 	}
 
 	if (si->bound == 0) {
-		ret = swrap_auto_bind(si, serv_addr->sa_family);
+		ret = swrap_auto_bind(s, si, serv_addr->sa_family);
 		if (ret == -1) return -1;
 	}
 
@@ -1906,7 +1942,8 @@ _PUBLIC_ int swrap_ioctl(int s, int r, void *p)
 	return ret;
 }
 
-static ssize_t swrap_sendmsg_before(struct socket_info *si,
+static ssize_t swrap_sendmsg_before(int fd,
+				    struct socket_info *si,
 				    struct msghdr *msg,
 				    struct iovec *tmp_iov,
 				    struct sockaddr_un *tmp_un,
@@ -1991,7 +2028,7 @@ static ssize_t swrap_sendmsg_before(struct socket_info *si,
 		}
 
 		if (si->bound == 0) {
-			ret = swrap_auto_bind(si, si->family);
+			ret = swrap_auto_bind(fd, si, si->family);
 			if (ret == -1) return -1;
 		}
 
@@ -2003,7 +2040,7 @@ static ssize_t swrap_sendmsg_before(struct socket_info *si,
 					     tmp_un, 0, NULL);
 		if (ret == -1) return -1;
 
-		ret = real_connect(si->fd, (struct sockaddr *)(void *)tmp_un,
+		ret = real_connect(fd, (struct sockaddr *)(void *)tmp_un,
 				   sizeof(*tmp_un));
 
 		/* to give better errors */
@@ -2168,7 +2205,7 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, con
 	msg.msg_flags = 0;             /* flags on received message */
 #endif
 
-	ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
+	ret = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
 	if (ret == -1) return -1;
 
 	buf = msg.msg_iov[0].iov_base;
@@ -2289,7 +2326,7 @@ _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
 	msg.msg_flags = 0;             /* flags on received message */
 #endif
 
-	ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
+	ret = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
 	if (ret == -1) return -1;
 
 	buf = msg.msg_iov[0].iov_base;
@@ -2332,7 +2369,7 @@ _PUBLIC_ ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
 	msg.msg_flags = omsg->msg_flags;           /* flags on received message */
 #endif
 
-	ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
+	ret = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
 	if (ret == -1) return -1;
 
 	if (bcast) {
@@ -2493,7 +2530,7 @@ int swrap_writev(int s, const struct iovec *vector, size_t count)
 	msg.msg_flags = 0;             /* flags on received message */
 #endif
 
-	ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
+	ret = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
 	if (ret == -1) return -1;
 
 	ret = real_writev(s, msg.msg_iov, msg.msg_iovlen);
@@ -2506,12 +2543,26 @@ int swrap_writev(int s, const struct iovec *vector, size_t count)
 _PUBLIC_ int swrap_close(int fd)
 {
 	struct socket_info *si = find_socket_info(fd);
+	struct socket_info_fd *fi;
 	int ret;
 
 	if (!si) {
 		return real_close(fd);
 	}
 
+	for (fi = si->fds; fi; fi = fi->next) {
+		if (fi->fd == fd) {
+			SWRAP_DLIST_REMOVE(si->fds, fi);
+			free(fi);
+			break;
+		}
+	}
+
+	if (si->fds) {
+		/* there are still references left */
+		return real_close(fd);
+	}
+
 	SWRAP_DLIST_REMOVE(sockets, si);
 
 	if (si->myname && si->peername) {
@@ -2538,8 +2589,8 @@ _PUBLIC_ int swrap_close(int fd)
 
 _PUBLIC_ int swrap_dup(int fd)
 {
-	struct socket_info *si, *si2;
-	int fd2;
+	struct socket_info *si;
+	struct socket_info_fd *fi;
 
 	si = find_socket_info(fd);
 
@@ -2547,55 +2598,28 @@ _PUBLIC_ int swrap_dup(int fd)
 		return real_dup(fd);
 	}
 
-	if (si->tmp_path) {
-		/* we would need reference counting to handle this */
-		errno = EINVAL;
-		return -1;
-	}
-
-	fd2 = real_dup(fd);
-	if (fd2 == -1) {
-		return -1;
-	}
-
-	si2 = (struct socket_info *)malloc(sizeof(struct socket_info));
-	if (si2 == NULL) {
-		real_close(fd2);
+	fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
+	if (fi == NULL) {
 		errno = ENOMEM;
 		return -1;
 	}
 
-	/* copy the whole structure, then duplicate pointer elements */
-	*si2 = *si;
-
-	si2->fd = fd2;
-
-	if (si2->myname) {
-		si2->myname = sockaddr_dup(si2->myname, si2->myname_len);
-		if (si2->myname == NULL) {
-			real_close(fd2);
-			errno = ENOMEM;
-			return -1;
-		}
-	}
-
-	if (si2->peername) {
-		si2->peername = sockaddr_dup(si2->peername, si2->peername_len);
-		if (si2->peername == NULL) {
-			real_close(fd2);
-			errno = ENOMEM;
-			return -1;
-		}
+	fi->fd = real_dup(fd);
+	if (fi->fd == -1) {
+		int saved_errno = errno;
+		free(fi);
+		errno = saved_errno;
+		return -1;
 	}
 
-	SWRAP_DLIST_ADD(sockets, si2);
-	return fd2;
+	SWRAP_DLIST_ADD(si->fds, fi);
+	return fi->fd;
 }
 
 _PUBLIC_ int swrap_dup2(int fd, int newfd)
 {
-	struct socket_info *si, *si2;
-	int fd2;
+	struct socket_info *si;
+	struct socket_info_fd *fi;
 
 	si = find_socket_info(fd);
 
@@ -2603,53 +2627,26 @@ _PUBLIC_ int swrap_dup2(int fd, int newfd)
 		return real_dup2(fd, newfd);
 	}
 
-	if (si->tmp_path) {
-		/* we would need reference counting to handle this */
-		errno = EINVAL;
-		return -1;
-	}
-
 	if (find_socket_info(newfd)) {
 		/* dup2() does an implicit close of newfd, which we
 		 * need to emulate */
 		swrap_close(newfd);
 	}
 
-	fd2 = real_dup2(fd, newfd);
-	if (fd2 == -1) {
-		return -1;
-	}
-
-	si2 = (struct socket_info *)malloc(sizeof(struct socket_info));
-	if (si2 == NULL) {
-		real_close(fd2);
+	fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
+	if (fi == NULL) {
 		errno = ENOMEM;
 		return -1;
 	}
 
-	/* copy the whole structure, then duplicate pointer elements */
-	*si2 = *si;
-
-	si2->fd = fd2;
-
-	if (si2->myname) {
-		si2->myname = sockaddr_dup(si2->myname, si2->myname_len);
-		if (si2->myname == NULL) {
-			real_close(fd2);
-			errno = ENOMEM;
-			return -1;
-		}
-	}
-
-	if (si2->peername) {
-		si2->peername = sockaddr_dup(si2->peername, si2->peername_len);
-		if (si2->peername == NULL) {
-			real_close(fd2);
-			errno = ENOMEM;
-			return -1;
-		}
+	fi->fd = real_dup2(fd, newfd);
+	if (fi->fd == -1) {
+		int saved_errno = errno;
+		free(fi);
+		errno = saved_errno;
+		return -1;
 	}
 
-	SWRAP_DLIST_ADD(sockets, si2);
-	return fd2;
+	SWRAP_DLIST_ADD(si->fds, fi);
+	return fi->fd;
 }


-- 
Samba Shared Repository


More information about the samba-cvs mailing list