41 unsigned char buf[CMSG_SPACE(
sizeof(payload_fd))];
42 std::memset(buf, 0,
sizeof(buf));
45 io.iov_base =
const_cast<char *
>(
message.c_str());
48 struct msghdr
msg = {0};
54 msg.msg_control = buf;
55 msg.msg_controllen =
sizeof(buf);
57 struct cmsghdr *cmsg = CMSG_FIRSTHDR(&
msg);
58 cmsg->cmsg_level = SOL_SOCKET;
59 cmsg->cmsg_type = SCM_RIGHTS;
60 cmsg->cmsg_len = CMSG_LEN(
sizeof(payload_fd));
62 std::memcpy(CMSG_DATA(cmsg), &payload_fd,
sizeof(payload_fd));
64 msg.msg_controllen = cmsg->cmsg_len;
68 const ssize_t status = ::sendmsg(sock_fd, &
msg, 0);
71 const int eno = errno;
74 else if (status !=
static_cast<ssize_t
>(
message.length()))
75 OPENVPN_THROW(xmit_fd_error,
"xmit_fd: unexpected send size");
80 const size_t buf_size,
83 struct msghdr
msg = {0};
85 std::unique_ptr<char[]> buf(
new char[buf_size]);
86 struct iovec io = {.iov_base = buf.get(), .iov_len = buf_size};
90 unsigned char c_buffer[256];
91 msg.msg_control = c_buffer;
92 msg.msg_controllen =
sizeof(c_buffer);
95 const ssize_t status = ::recvmsg(sock_fd, &
msg, 0);
98 const int eno = errno;
101 else if (status == 0)
103 else if (status >
static_cast<ssize_t
>(buf_size))
104 OPENVPN_THROW(xmit_fd_error,
"recv_fd: unexpectedly large message");
107 for (
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&
msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&
msg, cmsg))
109 if (cmsg->cmsg_len == CMSG_LEN(
sizeof(fd))
110 && cmsg->cmsg_level == SOL_SOCKET
111 && cmsg->cmsg_type == SCM_RIGHTS)
113 std::memcpy(&fd, CMSG_DATA(cmsg),
sizeof(fd));
116 message = std::string(buf.get(), status);