diff options
Diffstat (limited to 'src/socket_wrapper.c')
| -rw-r--r-- | src/socket_wrapper.c | 80 |
1 files changed, 27 insertions, 53 deletions
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c index 2ea35a9..b442d28 100644 --- a/src/socket_wrapper.c +++ b/src/socket_wrapper.c @@ -3480,69 +3480,43 @@ ssize_t sendmsg(int s, const struct msghdr *omsg, int flags) static ssize_t swrap_readv(int s, const struct iovec *vector, int count) { + 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); - struct iovec v; + int rc; - if (!si) { + si = find_socket_info(s); + if (si == NULL) { return libc_readv(s, vector, count); } - if (!si->connected) { - errno = ENOTCONN; - return -1; - } + tmp.iov_base = NULL; + tmp.iov_len = 0; - if (si->type == SOCK_STREAM && count > 0) { - int i; - size_t len = 0; + ZERO_STRUCT(msg); + msg.msg_name = (struct sockaddr *)(void *)&ss; /* optional address */ + msg.msg_namelen = ss_len; /* size of address */ + msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */ + msg.msg_iovlen = count; /* # elements in msg_iov */ +#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL + msg.msg_control = NULL; /* ancillary data, see below */ + msg.msg_controllen = 0; /* ancillary data buffer len */ + msg.msg_flags = 0; /* flags on received message */ +#endif - for (i = 0; i < count; i++) { - size_t nlen; - nlen = len + vector[i].iov_len; - if (nlen > SOCKET_MAX_PACKET) { - break; - } - } - count = i; - if (count == 0) { - v = vector[0]; - v.iov_len = MIN(v.iov_len, SOCKET_MAX_PACKET); - vector = &v; - count = 1; - } + rc = swrap_recvmsg_before(s, si, &msg, &tmp); + if (rc == -1) { + return -1; } - ret = libc_readv(s, vector, count); - 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) { - uint8_t *buf; - off_t ofs = 0; - int i; - size_t remain = ret; + ret = libc_readv(s, msg.msg_iov, msg.msg_iovlen); - /* we capture it as one single packet */ - buf = (uint8_t *)malloc(ret); - if (!buf) { - /* we just not capture the packet */ - errno = 0; - return ret; - } - - for (i=0; i < count; i++) { - size_t this_time = MIN(remain, (size_t)vector[i].iov_len); - memcpy(buf + ofs, - vector[i].iov_base, - this_time); - ofs += this_time; - remain -= this_time; - } - - swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret); - free(buf); + rc = swrap_recvmsg_after(si, &msg, NULL, 0, ret); + if (rc != 0) { + return rc; } return ret; |
