[SCM] Socket Wrapper Repository - branch master updated
Andreas Schneider
asn at samba.org
Mon Jan 20 15:19:54 MST 2014
The branch, master has been updated
via 98a05e5 tests: Add sendmsg_recvmsg_fd test.
via c29f759 tests: Add test_echo_udp_sendmsg_recvmsg.
via ae88bf8 swrap: Implement recvmsg().
via 6d328a2 swrap: Fix DGRAM in swrap_recvmsg(before|after).
via 11b077a swrap: Use swrap_recvmsg_* in swrap_read().
via 7e5f1f5 swrap: Use swrap_recvmsg_* in swrap_recv().
via 35bcc16 swrap: Use swrap_recvmsg_* in swrap_recvfrom().
via e11fd61 swrap: Add swrap_recvmsg_after().
via 76ff3d4 swrap: Add swrap_recvmsg_before().
from e9de990 echo_srv: Add fd duplication and test it works.
http://gitweb.samba.org/?p=socket_wrapper.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 98a05e5b2ca9e3ac6ad22ae5c5bbb754ab8f6641
Author: Jakub Hrozek <jhrozek at redhat.com>
Date: Mon Jan 20 13:45:58 2014 +0100
tests: Add sendmsg_recvmsg_fd test.
commit c29f7596696ec67fdf9ad2c860362bd0fc1516ae
Author: Andreas Schneider <asn at samba.org>
Date: Mon Jan 20 18:36:47 2014 +0100
tests: Add test_echo_udp_sendmsg_recvmsg.
commit ae88bf8a6894df56f0be77610d47a0f3730c8804
Author: Andreas Schneider <asn at samba.org>
Date: Wed Jan 15 16:55:20 2014 +0100
swrap: Implement recvmsg().
commit 6d328a234f8e5557a2e6898aff4bc92ace4b8b01
Author: Andreas Schneider <asn at samba.org>
Date: Tue Dec 24 13:06:40 2013 +0100
swrap: Fix DGRAM in swrap_recvmsg(before|after).
commit 11b077a674fa146b2744f6cd4c5f947e7d1f531d
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Dec 24 11:37:29 2013 +0100
swrap: Use swrap_recvmsg_* in swrap_read().
commit 7e5f1f5abc66dff745cb4cc2bcf187189fa19d12
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Dec 24 11:35:16 2013 +0100
swrap: Use swrap_recvmsg_* in swrap_recv().
commit 35bcc16674140864e2816cb6a5a536afaed9e597
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Dec 24 11:31:50 2013 +0100
swrap: Use swrap_recvmsg_* in swrap_recvfrom().
commit e11fd61be098aed3ed2b16e6ed9fe12e6a8f2b13
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Dec 24 11:28:29 2013 +0100
swrap: Add swrap_recvmsg_after().
commit 76ff3d42b48c0d25d505496d3e90f50fe7d6f9db
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Dec 24 11:28:13 2013 +0100
swrap: Add swrap_recvmsg_before().
-----------------------------------------------------------------------
Summary of changes:
src/socket_wrapper.c | 349 ++++++++++++++++++--
tests/CMakeLists.txt | 4 +-
..._recvfrom.c => test_echo_udp_sendmsg_recvmsg.c} | 111 +++----
tests/test_sendmsg_recvmsg_fd.c | 116 +++++++
4 files changed, 487 insertions(+), 93 deletions(-)
copy tests/{test_echo_udp_sendto_recvfrom.c => test_echo_udp_sendmsg_recvmsg.c} (71%)
create mode 100644 tests/test_sendmsg_recvmsg_fd.c
Changeset truncated at 500 lines:
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c
index dc6ffb1..b85021a 100644
--- a/src/socket_wrapper.c
+++ b/src/socket_wrapper.c
@@ -313,6 +313,7 @@ struct swrap_libc_fns {
int flags,
struct sockaddr *src_addr,
socklen_t *addrlen);
+ int (*libc_recvmsg)(int sockfd, const struct msghdr *msg, int flags);
int (*libc_send)(int sockfd, const void *buf, size_t len, int flags);
int (*libc_sendmsg)(int sockfd, const struct msghdr *msg, int flags);
int (*libc_sendto)(int sockfd,
@@ -603,6 +604,13 @@ static int libc_recvfrom(int sockfd,
return swrap.fns.libc_recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
}
+static int libc_recvmsg(int sockfd, struct msghdr *msg, int flags)
+{
+ swrap_load_lib_function(SWRAP_LIBSOCKET, recvmsg);
+
+ return swrap.fns.libc_recvmsg(sockfd, msg, flags);
+}
+
static int libc_send(int sockfd, const void *buf, size_t len, int flags)
{
swrap_load_lib_function(SWRAP_LIBSOCKET, send);
@@ -2814,6 +2822,168 @@ static void swrap_sendmsg_after(struct socket_info *si,
errno = saved_errno;
}
+static int swrap_recvmsg_before(int fd,
+ struct socket_info *si,
+ struct msghdr *msg,
+ struct iovec *tmp_iov)
+{
+ size_t i, len = 0;
+ ssize_t ret;
+
+ (void)fd; /* unused */
+
+ switch (si->type) {
+ case SOCK_STREAM:
+ if (!si->connected) {
+ errno = ENOTCONN;
+ return -1;
+ }
+
+ if (msg->msg_iovlen == 0) {
+ break;
+ }
+
+ for (i=0; i < msg->msg_iovlen; i++) {
+ size_t nlen;
+ nlen = len + msg->msg_iov[i].iov_len;
+ if (nlen > SOCKET_MAX_PACKET) {
+ 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, SOCKET_MAX_PACKET);
+ msg->msg_iov = tmp_iov;
+ msg->msg_iovlen = 1;
+ }
+ break;
+
+ case SOCK_DGRAM:
+ if (msg->msg_name == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (msg->msg_iovlen == 0) {
+ break;
+ }
+
+ if (si->bound == 0) {
+ ret = swrap_auto_bind(fd, si, si->family);
+ if (ret == -1) {
+ return -1;
+ }
+ }
+ break;
+ default:
+ errno = EHOSTUNREACH;
+ return -1;
+ }
+
+ return 0;
+}
+
+static int swrap_recvmsg_after(struct socket_info *si,
+ struct msghdr *msg,
+ const struct sockaddr_un *un_addr,
+ socklen_t un_addrlen,
+ ssize_t ret)
+{
+ int saved_errno = errno;
+ size_t i;
+ uint8_t *buf;
+ off_t ofs = 0;
+ size_t avail = 0;
+ size_t remain;
+
+ /* to give better errors */
+ if (ret == -1 && saved_errno == ENOENT) {
+ saved_errno = EHOSTUNREACH;
+ }
+
+ for (i=0; i < msg->msg_iovlen; i++) {
+ avail += msg->msg_iov[i].iov_len;
+ }
+
+ if (avail == 0) {
+ errno = saved_errno;
+ return 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 -1;
+ }
+
+ 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;
+ }
+
+ switch (si->type) {
+ case SOCK_STREAM:
+ if (ret == -1 && saved_errno != EAGAIN && saved_errno != ENOBUFS) {
+ swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
+ } else if (ret == 0) { /* END OF FILE */
+ swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
+ } else if (ret > 0) {
+ swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
+ }
+ break;
+
+ case SOCK_DGRAM:
+ if (ret == -1) {
+ break;
+ }
+
+ if (un_addr != NULL) {
+ int rc;
+
+ rc = sockaddr_convert_from_un(si,
+ un_addr,
+ un_addrlen,
+ si->family,
+ msg->msg_name,
+ &msg->msg_namelen);
+ if (rc == -1) {
+ return -1;
+ }
+
+ swrap_dump_packet(si,
+ msg->msg_name,
+ SWRAP_RECVFROM,
+ buf,
+ ret);
+ } else {
+ swrap_dump_packet(si,
+ msg->msg_name,
+ SWRAP_RECV,
+ buf,
+ ret);
+ }
+
+ break;
+ }
+
+ free(buf);
+ errno = saved_errno;
+ return 0;
+}
+
/****************************************************************************
* RECVFROM
***************************************************************************/
@@ -2821,12 +2991,15 @@ static void swrap_sendmsg_after(struct socket_info *si,
static 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);
+ struct sockaddr_un from_addr;
+ socklen_t from_addrlen = sizeof(from_addr);
ssize_t ret;
struct socket_info *si = find_socket_info(s);
struct sockaddr_storage ss;
socklen_t ss_len = sizeof(ss);
+ struct msghdr msg;
+ struct iovec tmp;
+ int tret;
if (!si) {
return libc_recvfrom(s,
@@ -2837,32 +3010,55 @@ static ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags,
fromlen);
}
- if (!from) {
- from = (struct sockaddr *)(void *)&ss;
- fromlen = &ss_len;
+ if (from != NULL && fromlen != NULL) {
+ msg.msg_name = from; /* optional address */
+ msg.msg_namelen = *fromlen; /* size of address */
+ } else {
+ msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
+ msg.msg_namelen = ss_len; /* size of address */
}
- if (si->type == SOCK_STREAM) {
- len = MIN(len, SOCKET_MAX_PACKET);
+ tmp.iov_base = buf;
+ tmp.iov_len = len;
+
+ msg.msg_iov = &tmp; /* scatter/gather array */
+ msg.msg_iovlen = 1; /* # elements in msg_iov */
+ msg.msg_control = NULL; /* ancillary data, see below */
+ msg.msg_controllen = 0; /* ancillary data buffer len */
+ msg.msg_flags = 0; /* flags on received message */
+
+ tret = swrap_recvmsg_before(s, si, &msg, &tmp);
+ if (tret == -1) {
+ return -1;
}
+ buf = msg.msg_iov[0].iov_base;
+ len = msg.msg_iov[0].iov_len;
+
/* irix 6.4 forgets to null terminate the sun_path string :-( */
- memset(&un_addr, 0, sizeof(un_addr));
+ memset(&from_addr, 0, sizeof(from_addr));
ret = libc_recvfrom(s,
buf,
len,
flags,
- (struct sockaddr *)(void *)&un_addr,
- &un_addrlen);
- if (ret == -1)
+ (struct sockaddr *)(void *)&from_addr,
+ &from_addrlen);
+ if (ret == -1) {
return ret;
+ }
- if (sockaddr_convert_from_un(si, &un_addr, un_addrlen,
- si->family, from, fromlen) == -1) {
- return -1;
+ tret = swrap_recvmsg_after(si,
+ &msg,
+ &from_addr,
+ from_addrlen,
+ ret);
+ if (tret != 0) {
+ return tret;
}
- swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, ret);
+ if (from != NULL && fromlen != NULL) {
+ *fromlen = msg.msg_namelen;
+ }
return ret;
}
@@ -2968,24 +3164,44 @@ ssize_t sendto(int s, const void *buf, size_t len, int flags,
static ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
{
+ struct socket_info *si;
+ struct msghdr msg;
+ struct sockaddr_storage ss;
+ socklen_t ss_len = sizeof(ss);
+ struct iovec tmp;
ssize_t ret;
- struct socket_info *si = find_socket_info(s);
+ int tret;
- if (!si) {
+ si = find_socket_info(s);
+ if (si == NULL) {
return libc_recv(s, buf, len, flags);
}
- if (si->type == SOCK_STREAM) {
- len = MIN(len, SOCKET_MAX_PACKET);
+ tmp.iov_base = buf;
+ tmp.iov_len = len;
+
+ msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
+ msg.msg_namelen = ss_len; /* size of address */
+ msg.msg_iov = &tmp; /* scatter/gather array */
+ msg.msg_iovlen = 1; /* # elements in msg_iov */
+ msg.msg_control = NULL; /* ancillary data, see below */
+ msg.msg_controllen = 0; /* ancillary data buffer len */
+ msg.msg_flags = 0; /* flags on received message */
+
+ tret = swrap_recvmsg_before(s, si, &msg, &tmp);
+ if (tret == -1) {
+ SWRAP_LOG(SWRAP_LOG_ERROR, "swrap_recvmsg_before failed");
+ return -1;
}
+ buf = msg.msg_iov[0].iov_base;
+ len = msg.msg_iov[0].iov_len;
+
ret = libc_recv(s, buf, len, flags);
- if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
- swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
- } else if (ret == 0) { /* END OF FILE */
- swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
- } else if (ret > 0) {
- swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
+
+ tret = swrap_recvmsg_after(si, &msg, NULL, 0, ret);
+ if (tret != 0) {
+ return tret;
}
return ret;
@@ -3002,24 +3218,44 @@ ssize_t recv(int s, void *buf, size_t len, int flags)
static ssize_t swrap_read(int s, void *buf, size_t len)
{
+ struct socket_info *si;
+ struct msghdr msg;
+ struct iovec tmp;
+ struct sockaddr_storage ss;
+ socklen_t ss_len = sizeof(ss);
ssize_t ret;
- struct socket_info *si = find_socket_info(s);
+ int tret;
- if (!si) {
+ si = find_socket_info(s);
+ if (si == NULL) {
return libc_read(s, buf, len);
}
- if (si->type == SOCK_STREAM) {
- len = MIN(len, SOCKET_MAX_PACKET);
+ tmp.iov_base = buf;
+ tmp.iov_len = len;
+
+ msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */
+ msg.msg_namelen = ss_len; /* size of address */
+ msg.msg_iov = &tmp; /* scatter/gather array */
+ msg.msg_iovlen = 1; /* # elements in msg_iov */
+ msg.msg_control = NULL; /* ancillary data, see below */
+ msg.msg_controllen = 0; /* ancillary data buffer len */
+ msg.msg_flags = 0; /* flags on received message */
+
+ tret = swrap_recvmsg_before(s, si, &msg, &tmp);
+ if (tret == -1) {
+ SWRAP_LOG(SWRAP_LOG_ERROR, "swrap_recvmsg_before failed");
+ return -1;
}
+ buf = msg.msg_iov[0].iov_base;
+ len = msg.msg_iov[0].iov_len;
+
ret = libc_read(s, buf, len);
- if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
- swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
- } else if (ret == 0) { /* END OF FILE */
- swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
- } else if (ret > 0) {
- swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
+
+ tret = swrap_recvmsg_after(si, &msg, NULL, 0, ret);
+ if (tret != 0) {
+ return tret;
}
return ret;
@@ -3082,7 +3318,48 @@ ssize_t send(int s, const void *buf, size_t len, int flags)
* RECVMSG
***************************************************************************/
-/* TODO */
+static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
+{
+ struct sockaddr_un from_addr;
+ socklen_t from_addrlen = sizeof(from_addr);
+ struct socket_info *si;
+ struct msghdr msg;
+ struct iovec tmp;
+
+ ssize_t ret;
+ int rc;
+
+ si = find_socket_info(s);
+ if (si == NULL) {
+ return libc_recvmsg(s, omsg, flags);
+ }
+
+ rc = swrap_recvmsg_before(s, si, omsg, &tmp);
+ if (rc == -1) {
+ return -1;
+ }
+
+ msg = *omsg;
+ tmp.iov_base = msg.msg_iov;
+ tmp.iov_len = msg.msg_iovlen;
+
+ msg.msg_name = (struct sockaddr *)&from_addr;
+ msg.msg_namelen = from_addrlen;
+
+ ret = libc_recvmsg(s, &msg, flags);
+
+ rc = swrap_recvmsg_after(si, omsg, &from_addr, from_addrlen, ret);
+ if (rc != 0) {
+ return rc;
+ }
+
+ return ret;
+}
+
+ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
+{
+ return swrap_recvmsg(sockfd, msg, flags);
+}
/****************************************************************************
* SENDMSG
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 45db1db..c626c02 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -24,7 +24,9 @@ set(SWRAP_TESTS
test_echo_tcp_write_read
test_echo_tcp_writev_readv
test_echo_udp_sendto_recvfrom
- test_echo_udp_send_recv)
+ test_echo_udp_send_recv
+ test_echo_udp_sendmsg_recvmsg
+ test_sendmsg_recvmsg_fd)
foreach(_SWRAP_TEST ${SWRAP_TESTS})
add_cmocka_test(${_SWRAP_TEST} ${_SWRAP_TEST}.c ${TORTURE_LIBRARY})
diff --git a/tests/test_echo_udp_sendto_recvfrom.c b/tests/test_echo_udp_sendmsg_recvmsg.c
similarity index 71%
copy from tests/test_echo_udp_sendto_recvfrom.c
copy to tests/test_echo_udp_sendmsg_recvmsg.c
index b0ed24a..caabdb4 100644
--- a/tests/test_echo_udp_sendto_recvfrom.c
+++ b/tests/test_echo_udp_sendmsg_recvmsg.c
@@ -62,23 +62,39 @@ static void test_sendto_recvfrom_ipv4(void **state)
const char *a;
struct sockaddr_in srv_in;
socklen_t rlen = sizeof(srv_in);
+ struct msghdr s_msg;
+ struct msghdr r_msg;
+ struct iovec s_iov;
+ struct iovec r_iov;
snprintf(send_buf, sizeof(send_buf), "packet.%d", i);
- ret = sendto(s,
- send_buf,
- sizeof(send_buf),
- 0,
- (struct sockaddr *)(void *)&sin,
- slen);
+ ZERO_STRUCT(s_msg);
+
+ s_msg.msg_name = (struct sockaddr *)(void *)&sin;
+ s_msg.msg_namelen = slen;
+
+ s_iov.iov_base = send_buf;
+ s_iov.iov_len = sizeof(send_buf);
+
+ s_msg.msg_iov = &s_iov;
+ s_msg.msg_iovlen = 1;
+
+ ret = sendmsg(s, &s_msg, 0);
assert_int_not_equal(ret, -1);
- ret = recvfrom(s,
- recv_buf,
- sizeof(recv_buf),
- 0,
- (struct sockaddr *)&srv_in,
--
Socket Wrapper Repository
More information about the samba-cvs
mailing list