mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
Add support for sendmsg() in socket_wrapper
This is required because the deferred connect code skips the connect() until sending the packet, but unless we catch this call, the connect() never happens. Andrew Bartlett
This commit is contained in:
parent
714acfac01
commit
8603985575
@ -118,6 +118,7 @@
|
||||
#define real_setsockopt setsockopt
|
||||
#define real_recvfrom recvfrom
|
||||
#define real_sendto sendto
|
||||
#define real_sendmsg sendmsg
|
||||
#define real_ioctl ioctl
|
||||
#define real_recv recv
|
||||
#define real_send send
|
||||
@ -2064,6 +2065,76 @@ _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
|
||||
return ret;
|
||||
}
|
||||
|
||||
_PUBLIC_ ssize_t swrap_sendmsg(int s, const struct msghdr *msg, int flags)
|
||||
{
|
||||
int ret;
|
||||
uint8_t *buf;
|
||||
off_t ofs = 0;
|
||||
size_t i;
|
||||
size_t remain;
|
||||
|
||||
struct socket_info *si = find_socket_info(s);
|
||||
|
||||
if (!si) {
|
||||
return real_sendmsg(s, msg, flags);
|
||||
}
|
||||
|
||||
if (si->defer_connect) {
|
||||
struct sockaddr_un un_addr;
|
||||
int bcast = 0;
|
||||
|
||||
if (si->bound == 0) {
|
||||
ret = swrap_auto_bind(si, si->family);
|
||||
if (ret == -1) return -1;
|
||||
}
|
||||
|
||||
ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
|
||||
&un_addr, 0, &bcast);
|
||||
if (ret == -1) return -1;
|
||||
|
||||
ret = real_connect(s, (struct sockaddr *)&un_addr,
|
||||
sizeof(un_addr));
|
||||
|
||||
/* to give better errors */
|
||||
if (ret == -1 && errno == ENOENT) {
|
||||
errno = EHOSTUNREACH;
|
||||
}
|
||||
|
||||
if (ret == -1) {
|
||||
return ret;
|
||||
}
|
||||
si->defer_connect = 0;
|
||||
}
|
||||
|
||||
ret = real_sendmsg(s, msg, flags);
|
||||
remain = ret;
|
||||
|
||||
/* 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 < 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;
|
||||
}
|
||||
|
||||
swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret);
|
||||
free(buf);
|
||||
if (ret == -1) {
|
||||
swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int swrap_readv(int s, const struct iovec *vector, size_t count)
|
||||
{
|
||||
int ret;
|
||||
|
@ -49,6 +49,7 @@ int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *opt
|
||||
int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen);
|
||||
ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);
|
||||
ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);
|
||||
ssize_t swrap_sendmsg(int s, const struct msghdr *msg, int flags);
|
||||
int swrap_ioctl(int s, int req, void *ptr);
|
||||
ssize_t swrap_recv(int s, void *buf, size_t len, int flags);
|
||||
ssize_t swrap_send(int s, const void *buf, size_t len, int flags);
|
||||
@ -108,6 +109,11 @@ int swrap_close(int);
|
||||
#endif
|
||||
#define sendto(s,buf,len,flags,to,tolen) swrap_sendto(s,buf,len,flags,to,tolen)
|
||||
|
||||
#ifdef sendmsg
|
||||
#undef sendmsg
|
||||
#endif
|
||||
#define sendmsg(s,msg,flags) swrap_sendmsg(s,msg,flags)
|
||||
|
||||
#ifdef ioctl
|
||||
#undef ioctl
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user