[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Thu Mar 3 15:44:02 MST 2011


The branch, master has been updated
       via  a5d5457 socket_wrapper: use swrap_sendmsg_before()/after() in swrap_writev()
       via  e831376 socket_wrapper: use swrap_sendmsg_before()/after() in swrap_sendmsg()
       via  4a736f0 socket_wrapper: use swrap_sendmsg_before()/after() in swrap_send()
       via  a2db6b4 socket_wrapper: use swrap_sendmsg_before()/after() in swrap_sendto()
       via  8c6d7d7 socket_wrapper: add swrap_sendmsg_before/after helper functions
       via  c9ae810 socket_wrapper: replace recvmsg() correctly
       via  ec028b5 socket_wrapper: readv() should only work on connected sockets
       via  7bdc3db socket_wrapper: move swrap_ioctl() above the send*/recv* functions
       via  0ad8d45 socket_wrapper: fix compiler warnings
       via  e3c0d66 socket_wrapper: don't allow connect() to the broadcast address
      from  7b139a4 s3: Use dom_sid_string_buf in sid_to_fstring

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


- Log -----------------------------------------------------------------
commit a5d54579ea949f4cd7c975c3f5d0006a90777735
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sat Oct 30 16:23:49 2010 +0200

    socket_wrapper: use swrap_sendmsg_before()/after() in swrap_writev()
    
    metze
    
    Autobuild-User: Stefan Metzmacher <metze at samba.org>
    Autobuild-Date: Thu Mar  3 23:43:39 CET 2011 on sn-devel-104

commit e831376f914d729b9ff3f39c5841846359c712aa
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sat Oct 30 16:23:49 2010 +0200

    socket_wrapper: use swrap_sendmsg_before()/after() in swrap_sendmsg()
    
    This also adds the same logic for broadcast as in swrap_sendto()
    for SOCK_DGRAM.
    
    metze

commit 4a736f0fbe58fabf6c0a0650cbc38882cb0446ab
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sat Oct 30 16:23:49 2010 +0200

    socket_wrapper: use swrap_sendmsg_before()/after() in swrap_send()
    
    metze

commit a2db6b4dba2650c582aa4572276d96dac521a3d8
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sat Oct 30 16:23:49 2010 +0200

    socket_wrapper: use swrap_sendmsg_before()/after() in swrap_sendto()
    
    metze

commit 8c6d7d7b2797c051885e12e3cdf3da158cf4fe25
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sat Oct 30 16:08:49 2010 +0200

    socket_wrapper: add swrap_sendmsg_before/after helper functions
    
    Currently have almost the same logic in swrap_send(), swrap_sendto(),
    swrap_writev() and swrap_sendmsg(), this helper functions
    let combine all the logic in 2 places.
    
    metze

commit c9ae8102099ed66c776c79e88f1a582f3e213fbc
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 3 15:37:17 2011 +0100

    socket_wrapper: replace recvmsg() correctly
    
    metze

commit ec028b555bbca84e1f949c6632099f8407c0d695
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sat Oct 30 16:28:23 2010 +0200

    socket_wrapper: readv() should only work on connected sockets
    
    metze

commit 7bdc3db9ea5380eeee8d975b3579dcf673a0eafa
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sat Oct 30 16:19:33 2010 +0200

    socket_wrapper: move swrap_ioctl() above the send*/recv* functions
    
    metze

commit 0ad8d459c6f47a0d70c8af2b19e6585a38f34cb4
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Mar 2 20:46:45 2011 +0100

    socket_wrapper: fix compiler warnings
    
    metze

commit e3c0d6611087184b37399df2bf04053c60c9f043
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sat Oct 30 16:07:31 2010 +0200

    socket_wrapper: don't allow connect() to the broadcast address
    
    This will simplify other code later.
    
    metze

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

Summary of changes:
 lib/socket_wrapper/socket_wrapper.c |  655 +++++++++++++++++++++--------------
 lib/socket_wrapper/socket_wrapper.h |    6 +
 2 files changed, 398 insertions(+), 263 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c
index 563c3a8..02cce3f 100644
--- a/lib/socket_wrapper/socket_wrapper.c
+++ b/lib/socket_wrapper/socket_wrapper.c
@@ -296,7 +296,7 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, sock
 	switch(type) {
 	case SOCKET_TYPE_CHAR_TCP:
 	case SOCKET_TYPE_CHAR_UDP: {
-		struct sockaddr_in *in2 = (struct sockaddr_in *)in;
+		struct sockaddr_in *in2 = (struct sockaddr_in *)(void *)in;
 
 		if ((*len) < sizeof(*in2)) {
 		    errno = EINVAL;
@@ -314,7 +314,7 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, sock
 #ifdef HAVE_IPV6
 	case SOCKET_TYPE_CHAR_TCP_V6:
 	case SOCKET_TYPE_CHAR_UDP_V6: {
-		struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)in;
+		struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)(void *)in;
 
 		if ((*len) < sizeof(*in2)) {
 			errno = EINVAL;
@@ -352,7 +352,7 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i
 	switch (inaddr->sa_family) {
 	case AF_INET: {
 		const struct sockaddr_in *in = 
-		    (const struct sockaddr_in *)inaddr;
+		    (const struct sockaddr_in *)(const void *)inaddr;
 		unsigned int addr = ntohl(in->sin_addr.s_addr);
 		char u_type = '\0';
 		char b_type = '\0';
@@ -395,8 +395,8 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i
 #ifdef HAVE_IPV6
 	case AF_INET6: {
 		const struct sockaddr_in6 *in = 
-		    (const struct sockaddr_in6 *)inaddr;
-		struct in6_addr cmp;
+		    (const struct sockaddr_in6 *)(const void *)inaddr;
+		struct in6_addr cmp1, cmp2;
 
 		switch (si->type) {
 		case SOCK_STREAM:
@@ -411,9 +411,10 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i
 
 		prt = ntohs(in->sin6_port);
 
-		cmp = in->sin6_addr;
-		cmp.s6_addr[15] = 0;
-		if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp)) {
+		cmp1 = *swrap_ipv6();
+		cmp2 = in->sin6_addr;
+		cmp2.s6_addr[15] = 0;
+		if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
 			iface = in->sin6_addr.s6_addr[15];
 		} else {
 			errno = ENETUNREACH;
@@ -460,7 +461,7 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in
 	switch (si->family) {
 	case AF_INET: {
 		const struct sockaddr_in *in = 
-		    (const struct sockaddr_in *)inaddr;
+		    (const struct sockaddr_in *)(const void *)inaddr;
 		unsigned int addr = ntohl(in->sin_addr.s_addr);
 		char u_type = '\0';
 		char d_type = '\0';
@@ -511,8 +512,8 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in
 #ifdef HAVE_IPV6
 	case AF_INET6: {
 		const struct sockaddr_in6 *in = 
-		    (const struct sockaddr_in6 *)inaddr;
-		struct in6_addr cmp;
+		    (const struct sockaddr_in6 *)(const void *)inaddr;
+		struct in6_addr cmp1, cmp2;
 
 		switch (si->type) {
 		case SOCK_STREAM:
@@ -527,11 +528,12 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in
 
 		prt = ntohs(in->sin6_port);
 
-		cmp = in->sin6_addr;
-		cmp.s6_addr[15] = 0;
+		cmp1 = *swrap_ipv6();
+		cmp2 = in->sin6_addr;
+		cmp2.s6_addr[15] = 0;
 		if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
 			iface = socket_wrapper_default_iface();
-		} else if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp)) {
+		} else if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
 			iface = in->sin6_addr.s6_addr[15];
 		} else {
 			errno = EADDRNOTAVAIL;
@@ -1504,7 +1506,7 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
 	memset(&un_addr, 0, sizeof(un_addr));
 	memset(&un_my_addr, 0, sizeof(un_my_addr));
 
-	ret = real_accept(s, (struct sockaddr *)&un_addr, &un_addrlen);
+	ret = real_accept(s, (struct sockaddr *)(void *)&un_addr, &un_addrlen);
 	if (ret == -1) {
 		free(my_addr);
 		return ret;
@@ -1542,7 +1544,8 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
 	    *addrlen = 0;
 	}
 
-	ret = real_getsockname(fd, (struct sockaddr *)&un_my_addr, &un_my_addrlen);
+	ret = real_getsockname(fd, (struct sockaddr *)(void *)&un_my_addr,
+			       &un_my_addrlen);
 	if (ret == -1) {
 		free(child_si);
 		close(fd);
@@ -1670,7 +1673,8 @@ 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 *)&un_addr, sizeof(un_addr));
+		ret = real_bind(si->fd, (struct sockaddr *)(void *)&un_addr,
+				sizeof(un_addr));
 		if (ret == -1) return ret;
 
 		si->tmp_path = strdup(un_addr.sun_path);
@@ -1695,6 +1699,7 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad
 	int ret;
 	struct sockaddr_un un_addr;
 	struct socket_info *si = find_socket_info(s);
+	int bcast = 0;
 
 	if (!si) {
 		return real_connect(s, serv_addr, addrlen);
@@ -1710,16 +1715,22 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad
 		return -1;
 	}
 
-	ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr, 0, NULL);
+	ret = sockaddr_convert_to_un(si, serv_addr,
+				     addrlen, &un_addr, 0, &bcast);
 	if (ret == -1) return -1;
 
+	if (bcast) {
+		errno = ENETUNREACH;
+		return -1;
+	}
+
 	if (si->type == SOCK_DGRAM) {
 		si->defer_connect = 1;
 		ret = 0;
 	} else {
 		swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
 
-		ret = real_connect(s, (struct sockaddr *)&un_addr,
+		ret = real_connect(s, (struct sockaddr *)(void *)&un_addr,
 				   sizeof(struct sockaddr_un));
 	}
 
@@ -1755,12 +1766,12 @@ _PUBLIC_ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
 	si->myname_len = addrlen;
 	si->myname = sockaddr_dup(myaddr, addrlen);
 
-	ret = sockaddr_convert_to_un(si, (const struct sockaddr *)myaddr, addrlen, &un_addr, 1, &si->bcast);
+	ret = sockaddr_convert_to_un(si, myaddr, addrlen, &un_addr, 1, &si->bcast);
 	if (ret == -1) return -1;
 
 	unlink(un_addr.sun_path);
 
-	ret = real_bind(s, (struct sockaddr *)&un_addr,
+	ret = real_bind(s, (struct sockaddr *)(void *)&un_addr,
 			sizeof(struct sockaddr_un));
 
 	if (ret == 0) {
@@ -1859,180 +1870,325 @@ _PUBLIC_ int swrap_setsockopt(int s, int  level,  int  optname,  const  void  *o
 	}
 }
 
-_PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
+_PUBLIC_ int swrap_ioctl(int s, int r, void *p)
 {
-	struct sockaddr_un un_addr;
-	socklen_t un_addrlen = sizeof(un_addr);
 	int ret;
 	struct socket_info *si = find_socket_info(s);
-	struct sockaddr_storage ss;
-	socklen_t ss_len = sizeof(ss);
+	int value;
 
 	if (!si) {
-		return real_recvfrom(s, buf, len, flags, from, fromlen);
-	}
-
-	if (!from) {
-		from = (struct sockaddr *)&ss;
-		fromlen = &ss_len;
-	}
-
-	if (si->type == SOCK_STREAM) {
-		/* cut down to 1500 byte packets for stream sockets,
-		 * which makes it easier to format PCAP capture files
-		 * (as the caller will simply continue from here) */
-		len = MIN(len, 1500);
+		return real_ioctl(s, r, p);
 	}
 
-	/* irix 6.4 forgets to null terminate the sun_path string :-( */
-	memset(&un_addr, 0, sizeof(un_addr));
-	ret = real_recvfrom(s, buf, len, flags, (struct sockaddr *)&un_addr, &un_addrlen);
-	if (ret == -1) 
-		return ret;
+	ret = real_ioctl(s, r, p);
 
-	if (sockaddr_convert_from_un(si, &un_addr, un_addrlen,
-				     si->family, from, fromlen) == -1) {
-		return -1;
+	switch (r) {
+	case FIONREAD:
+		value = *((int *)p);
+		if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
+			swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
+		} else if (value == 0) { /* END OF FILE */
+			swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
+		}
+		break;
 	}
 
-	swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, ret);
-
 	return ret;
 }
 
-
-_PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
+static ssize_t swrap_sendmsg_before(struct socket_info *si,
+				    struct msghdr *msg,
+				    struct iovec *tmp_iov,
+				    struct sockaddr_un *tmp_un,
+				    const struct sockaddr_un **to_un,
+				    const struct sockaddr **to,
+				    int *bcast)
 {
-	struct sockaddr_un un_addr;
-	int ret;
-	struct socket_info *si = find_socket_info(s);
-	int bcast = 0;
+	size_t i, len = 0;
+	ssize_t ret;
 
-	if (!si) {
-		return real_sendto(s, buf, len, flags, to, tolen);
+	if (to_un) {
+		*to_un = NULL;
+	}
+	if (to) {
+		*to = NULL;
+	}
+	if (bcast) {
+		*bcast = 0;
 	}
 
-	if (si->connected) {
-		if (to) {
-			errno = EISCONN;
+	switch (si->type) {
+	case SOCK_STREAM:
+		if (!si->connected) {
+			errno = ENOTCONN;
 			return -1;
 		}
 
-		to = si->peername;
-		tolen = si->peername_len;
-	}
+		if (msg->msg_iovlen == 0) {
+			break;
+		}
 
-	switch (si->type) {
-	case SOCK_STREAM:
-		/* cut down to 1500 byte packets for stream sockets,
+		/*
+		 * cut down to 1500 byte packets for stream sockets,
 		 * which makes it easier to format PCAP capture files
-		 * (as the caller will simply continue from here) */
-		len = MIN(len, 1500);
+		 * (as the caller will simply continue from here)
+		 */
 
-		ret = real_send(s, buf, len, flags);
+		for (i=0; i < msg->msg_iovlen; i++) {
+			size_t nlen;
+			nlen = len + msg->msg_iov[i].iov_len;
+			if (nlen > 1500) {
+				break;
+			}
+		}
+		msg->msg_iovlen = i;
+		if (msg->msg_iovlen == 0) {
+			*tmp_iov = msg->msg_iov[0];
+			tmp_iov->iov_len = MIN(tmp_iov->iov_len, 1500);
+			msg->msg_iov = tmp_iov;
+			msg->msg_iovlen = 1;
+		}
 		break;
+
 	case SOCK_DGRAM:
+		if (si->connected) {
+			if (msg->msg_name) {
+				errno = EISCONN;
+				return -1;
+			}
+		} else {
+			const struct sockaddr *msg_name;
+			msg_name = (const struct sockaddr *)msg->msg_name;
+
+			if (msg_name == NULL) {
+				errno = ENOTCONN;
+				return -1;
+			}
+
+
+			ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
+						     tmp_un, 0, bcast);
+			if (ret == -1) return -1;
+
+			if (to_un) {
+				*to_un = tmp_un;
+			}
+			if (to) {
+				*to = msg_name;
+			}
+			msg->msg_name = tmp_un;
+			msg->msg_namelen = sizeof(*tmp_un);
+		}
+
 		if (si->bound == 0) {
 			ret = swrap_auto_bind(si, si->family);
 			if (ret == -1) return -1;
 		}
 
-		ret = sockaddr_convert_to_un(si, to, tolen, &un_addr, 0, &bcast);
+		if (!si->defer_connect) {
+			break;
+		}
+
+		ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
+					     tmp_un, 0, NULL);
 		if (ret == -1) return -1;
 
-		if (bcast) {
-			struct stat st;
-			unsigned int iface;
-			unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
-			char type;
+		ret = real_connect(si->fd, (struct sockaddr *)(void *)tmp_un,
+				   sizeof(*tmp_un));
 
-			type = SOCKET_TYPE_CHAR_UDP;
+		/* to give better errors */
+		if (ret == -1 && errno == ENOENT) {
+			errno = EHOSTUNREACH;
+		}
 
-			for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
-				snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT, 
-					 socket_wrapper_dir(), type, iface, prt);
-				if (stat(un_addr.sun_path, &st) != 0) continue;
+		if (ret == -1) {
+			return ret;
+		}
 
-				/* ignore the any errors in broadcast sends */
-				real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr));
-			}
+		si->defer_connect = 0;
+		break;
+	default:
+		errno = EHOSTUNREACH;
+		return -1;
+	}
 
-			swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
+	return 0;
+}
 
-			return len;
-		}
+static void swrap_sendmsg_after(struct socket_info *si,
+				struct msghdr *msg,
+				const struct sockaddr *to,
+				ssize_t ret)
+{
+	int saved_errno = errno;
+	size_t i, len = 0;
+	uint8_t *buf;
+	off_t ofs = 0;
+	size_t avail = 0;
+	size_t remain;
 
-		if (si->defer_connect) {
-			ret = real_connect(s, (struct sockaddr *)&un_addr,
-					   sizeof(un_addr));
+	/* to give better errors */
+	if (ret == -1 && saved_errno == ENOENT) {
+		saved_errno = EHOSTUNREACH;
+	}
 
-			/* to give better errors */
-			if (ret == -1 && errno == ENOENT) {
-				errno = EHOSTUNREACH;
-			}
+	for (i=0; i < msg->msg_iovlen; i++) {
+		avail += msg->msg_iov[i].iov_len;
+	}
 
-			if (ret == -1) {
-				return ret;
-			}
-			si->defer_connect = 0;
+	if (ret == -1) {
+		remain = MIN(80, avail);
+	} else {
+		remain = ret;
+	}
+
+	/* we capture it as one single packet */
+	buf = (uint8_t *)malloc(remain);
+	if (!buf) {
+		/* we just not capture the packet */
+		errno = saved_errno;
+		return;
+	}
+
+	for (i=0; i < msg->msg_iovlen; i++) {
+		size_t this_time = MIN(remain, msg->msg_iov[i].iov_len);
+		memcpy(buf + ofs,
+		       msg->msg_iov[i].iov_base,
+		       this_time);
+		ofs += this_time;
+		remain -= this_time;
+	}
+	len = ofs;
+
+	switch (si->type) {
+	case SOCK_STREAM:
+		if (ret == -1) {
+			swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
+			swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
+		} else {
+			swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
 		}
+		break;
 
-		/* Man page for Linux says:
-		 * "the error EISONN may be returned when they are not NULL and 0"
-		 * But in practice it's not on x86/amd64, but on other unix it is
-		 * (ie. freebsd)
-		 * So if we are already connected we send NULL/0
-		 */
+	case SOCK_DGRAM:
 		if (si->connected) {
-			ret = real_sendto(s, buf, len, flags, NULL, 0);
+			to = si->peername;
+		}
+		if (ret == -1) {
+			swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
+			swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
 		} else {
-			ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr));
+			swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
 		}
 		break;
-	default:
-		ret = -1;
-		errno = EHOSTUNREACH;
-		break;
 	}
 
-	/* to give better errors */
-	if (ret == -1 && errno == ENOENT) {
-		errno = EHOSTUNREACH;
+	free(buf);
+	errno = saved_errno;
+}
+
+_PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
+{
+	struct sockaddr_un un_addr;
+	socklen_t un_addrlen = sizeof(un_addr);
+	int ret;
+	struct socket_info *si = find_socket_info(s);
+	struct sockaddr_storage ss;
+	socklen_t ss_len = sizeof(ss);
+
+	if (!si) {
+		return real_recvfrom(s, buf, len, flags, from, fromlen);
 	}
 
-	if (ret == -1) {
-		swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
-		swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
-	} else {
-		swrap_dump_packet(si, to, SWRAP_SENDTO, buf, ret);
+	if (!from) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list