diff options
| author | Stefan Metzmacher <metze@samba.org> | 2013-12-24 11:28:29 +0100 |
|---|---|---|
| committer | Andreas Schneider <asn@samba.org> | 2014-01-20 16:48:38 +0100 |
| commit | e11fd61be098aed3ed2b16e6ed9fe12e6a8f2b13 (patch) | |
| tree | 3711683d50b64bce3f16ca8d41d0de09a15ed734 /src | |
| parent | 76ff3d42b48c0d25d505496d3e90f50fe7d6f9db (diff) | |
| download | socket_wrapper-e11fd61be098aed3ed2b16e6ed9fe12e6a8f2b13.tar.gz socket_wrapper-e11fd61be098aed3ed2b16e6ed9fe12e6a8f2b13.tar.xz socket_wrapper-e11fd61be098aed3ed2b16e6ed9fe12e6a8f2b13.zip | |
swrap: Add swrap_recvmsg_after().
Diffstat (limited to 'src')
| -rw-r--r-- | src/socket_wrapper.c | 78 |
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 ***************************************************************************/ |
