summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2013-12-24 11:28:29 +0100
committerAndreas Schneider <asn@samba.org>2014-01-20 16:48:38 +0100
commite11fd61be098aed3ed2b16e6ed9fe12e6a8f2b13 (patch)
tree3711683d50b64bce3f16ca8d41d0de09a15ed734
parent76ff3d42b48c0d25d505496d3e90f50fe7d6f9db (diff)
downloadsocket_wrapper-e11fd61be098aed3ed2b16e6ed9fe12e6a8f2b13.tar.gz
socket_wrapper-e11fd61be098aed3ed2b16e6ed9fe12e6a8f2b13.tar.xz
socket_wrapper-e11fd61be098aed3ed2b16e6ed9fe12e6a8f2b13.zip
swrap: Add swrap_recvmsg_after().
-rw-r--r--src/socket_wrapper.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c
index 360f150..a4f9799 100644
--- a/src/socket_wrapper.c
+++ b/src/socket_wrapper.c
@@ -2863,6 +2863,84 @@ static int swrap_recvmsg_before(int fd,
return 0;
}
+static int swrap_recvmsg_after(struct socket_info *si,
+ struct msghdr *msg,
+ const struct sockaddr_un *un_addr,
+ socklen_t un_addrlen,
+ struct sockaddr *from,
+ socklen_t *fromlen,
+ 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 (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;
+ }
+
+ swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, ret);
+
+ if (sockaddr_convert_from_un(si, un_addr, un_addrlen,
+ si->family, from, fromlen) == -1) {
+ return -1;
+ }
+
+ break;
+ }
+
+ free(buf);
+ errno = saved_errno;
+ return 0;
+}
+
/****************************************************************************
* RECVFROM
***************************************************************************/