[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