[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-249-g3679e82

Stefan Metzmacher metze at samba.org
Sun Mar 8 16:23:45 GMT 2009


The branch, master has been updated
       via  3679e8243459f928b1a4d0998d47c6efdedd0301 (commit)
       via  f9156f6c77d9e87edc153b024a1d564b44eedd8f (commit)
       via  81e2633e41e9c8c1dddff7cc1122c7d6f28626bd (commit)
      from  dea9621680062b3726ad15cbec4a9d2cf7ce824e (commit)

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


- Log -----------------------------------------------------------------
commit 3679e8243459f928b1a4d0998d47c6efdedd0301
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sun Mar 8 17:20:18 2009 +0100

    socket_wrapper: downgrade ipv6 sockets to ipv4 is in connect() if the dest is ipv4
    
    We only do this if the socket isn't explicit bound yet.
    
    metze

commit f9156f6c77d9e87edc153b024a1d564b44eedd8f
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sun Mar 8 17:19:50 2009 +0100

    socket_wrapper: correctly handle connected dgram sockets
    
    metze

commit 81e2633e41e9c8c1dddff7cc1122c7d6f28626bd
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Mar 3 19:40:57 2009 +0100

    socket_wrapper: make it possible to bind to '::'
    
    metze

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

Summary of changes:
 lib/socket_wrapper/socket_wrapper.c |   48 ++++++++++++++++++++++++++++++----
 1 files changed, 42 insertions(+), 6 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c
index 8ad9e1d..733a332 100644
--- a/lib/socket_wrapper/socket_wrapper.c
+++ b/lib/socket_wrapper/socket_wrapper.c
@@ -202,6 +202,7 @@ struct socket_info
 	int bound;
 	int bcast;
 	int is_server;
+	int connected;
 
 	char *path;
 	char *tmp_path;
@@ -510,7 +511,9 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in
 
 		cmp = in->sin6_addr;
 		cmp.s6_addr[15] = 0;
-		if (IN6_ARE_ADDR_EQUAL(&swrap_ipv6, &cmp)) {
+		if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
+			iface = socket_wrapper_default_iface();
+		} else if (IN6_ARE_ADDR_EQUAL(&swrap_ipv6, &cmp)) {
 			iface = in->sin6_addr.s6_addr[15];
 		} else {
 			errno = EADDRNOTAVAIL;
@@ -1485,6 +1488,7 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
 	child_si->protocol = parent_si->protocol;
 	child_si->bound = 1;
 	child_si->is_server = 1;
+	child_si->connected = 1;
 
 	child_si->peername_len = len;
 	child_si->peername = sockaddr_dup(my_addr, len);
@@ -1532,8 +1536,10 @@ static int autobind_start;
 /* using sendto() or connect() on an unbound socket would give the
    recipient no way to reply, as unlike UDP and TCP, a unix domain
    socket can't auto-assign emphemeral port numbers, so we need to
-   assign it here */
-static int swrap_auto_bind(struct socket_info *si)
+   assign it here.
+   Note: this might change the family from ipv6 to ipv4
+*/
+static int swrap_auto_bind(struct socket_info *si, int family)
 {
 	struct sockaddr_un un_addr;
 	int i;
@@ -1551,7 +1557,7 @@ static int swrap_auto_bind(struct socket_info *si)
 
 	un_addr.sun_family = AF_UNIX;
 
-	switch (si->family) {
+	switch (family) {
 	case AF_INET: {
 		struct sockaddr_in in;
 
@@ -1580,6 +1586,11 @@ static int swrap_auto_bind(struct socket_info *si)
 	case AF_INET6: {
 		struct sockaddr_in6 in6;
 
+		if (si->family != family) {
+			errno = ENETUNREACH;
+			return -1;
+		}
+
 		switch (si->type) {
 		case SOCK_STREAM:
 			type = SOCKET_TYPE_CHAR_TCP_V6;
@@ -1630,6 +1641,7 @@ static int swrap_auto_bind(struct socket_info *si)
 		return -1;
 	}
 
+	si->family = family;
 	set_port(si->family, port, si->myname);
 
 	return 0;
@@ -1647,7 +1659,7 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad
 	}
 
 	if (si->bound == 0) {
-		ret = swrap_auto_bind(si);
+		ret = swrap_auto_bind(si, serv_addr->sa_family);
 		if (ret == -1) return -1;
 	}
 
@@ -1672,7 +1684,14 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad
 	if (ret == 0) {
 		si->peername_len = addrlen;
 		si->peername = sockaddr_dup(serv_addr, addrlen);
+		si->connected = 1;
+	}
 
+	if (si->type != SOCK_STREAM) {
+		return ret;
+	}
+
+	if (ret == 0) {
 		swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
 		swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
 	} else {
@@ -1801,11 +1820,18 @@ _PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct
 	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 (!from) {
+		from = (struct sockaddr *)&ss;
+		fromlen = &ss_len;
+	}
+
 	len = MIN(len, 1500);
 
 	/* irix 6.4 forgets to null terminate the sun_path string :-( */
@@ -1836,6 +1862,16 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, con
 		return real_sendto(s, buf, len, flags, to, tolen);
 	}
 
+	if (si->connected) {
+		if (to) {
+			errno = EISCONN;
+			return -1;
+		}
+
+		to = si->peername;
+		tolen = si->peername_len;
+	}
+
 	len = MIN(len, 1500);
 
 	switch (si->type) {
@@ -1844,7 +1880,7 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, con
 		break;
 	case SOCK_DGRAM:
 		if (si->bound == 0) {
-			ret = swrap_auto_bind(si);
+			ret = swrap_auto_bind(si, si->family);
 			if (ret == -1) return -1;
 		}
 		


-- 
Samba Shared Repository


More information about the samba-cvs mailing list