socket: add support for sending and receiving descriptors
Add support for the SCM_RIGHTS control message used in communication with the privops helper.
This commit is contained in:
parent
c4d6f98bed
commit
f231efb811
2 changed files with 30 additions and 4 deletions
31
socket.c
31
socket.c
|
@ -630,12 +630,15 @@ init_message_nonaddress(SCK_Message *message)
|
||||||
message->timestamp.if_index = INVALID_IF_INDEX;
|
message->timestamp.if_index = INVALID_IF_INDEX;
|
||||||
message->timestamp.l2_length = 0;
|
message->timestamp.l2_length = 0;
|
||||||
message->timestamp.tx_flags = 0;
|
message->timestamp.tx_flags = 0;
|
||||||
|
|
||||||
|
message->descriptor = INVALID_SOCK_FD;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
process_header(struct msghdr *msg, unsigned int msg_length, int sock_fd, SCK_Message *message)
|
process_header(struct msghdr *msg, unsigned int msg_length, int sock_fd, int flags,
|
||||||
|
SCK_Message *message)
|
||||||
{
|
{
|
||||||
struct cmsghdr *cmsg;
|
struct cmsghdr *cmsg;
|
||||||
|
|
||||||
|
@ -773,6 +776,18 @@ process_header(struct msghdr *msg, unsigned int msg_length, int sock_fd, SCK_Mes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
|
||||||
|
if (!(flags & SCK_FLAG_MSG_DESCRIPTOR) || cmsg->cmsg_len != CMSG_LEN(sizeof (int))) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
DEBUG_LOG("Unexpected SCM_RIGHTS");
|
||||||
|
for (i = 0; CMSG_LEN((i + 1) * sizeof (int)) <= cmsg->cmsg_len; i++)
|
||||||
|
close(((int *)CMSG_DATA(cmsg))[i]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
message->descriptor = *(int *)CMSG_DATA(cmsg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -823,7 +838,7 @@ receive_messages(int sock_fd, SCK_Message *messages, int max_messages, int flags
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
hdr = ARR_GetElement(recv_headers, i);
|
hdr = ARR_GetElement(recv_headers, i);
|
||||||
if (!process_header(&hdr->msg_hdr, hdr->msg_len, sock_fd, &messages[i]))
|
if (!process_header(&hdr->msg_hdr, hdr->msg_len, sock_fd, flags, &messages[i]))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
log_message(sock_fd, 1, &messages[i],
|
log_message(sock_fd, 1, &messages[i],
|
||||||
|
@ -876,8 +891,6 @@ send_message(int sock_fd, SCK_Message *message, int flags)
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct iovec iov;
|
struct iovec iov;
|
||||||
|
|
||||||
assert(flags == 0);
|
|
||||||
|
|
||||||
switch (message->addr_type) {
|
switch (message->addr_type) {
|
||||||
case SCK_ADDR_UNSPEC:
|
case SCK_ADDR_UNSPEC:
|
||||||
saddr_len = 0;
|
saddr_len = 0;
|
||||||
|
@ -974,6 +987,16 @@ send_message(int sock_fd, SCK_Message *message, int flags)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (flags & SCK_FLAG_MSG_DESCRIPTOR) {
|
||||||
|
int *fd;
|
||||||
|
|
||||||
|
fd = add_control_message(&msg, SOL_SOCKET, SCM_RIGHTS, sizeof (*fd), sizeof (cmsg_buf));
|
||||||
|
if (!fd)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*fd = message->descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
/* This is apparently required on some systems */
|
/* This is apparently required on some systems */
|
||||||
if (msg.msg_controllen == 0)
|
if (msg.msg_controllen == 0)
|
||||||
msg.msg_control = NULL;
|
msg.msg_control = NULL;
|
||||||
|
|
3
socket.h
3
socket.h
|
@ -38,6 +38,7 @@
|
||||||
|
|
||||||
/* Flags for receiving and sending messages */
|
/* Flags for receiving and sending messages */
|
||||||
#define SCK_FLAG_MSG_ERRQUEUE 1
|
#define SCK_FLAG_MSG_ERRQUEUE 1
|
||||||
|
#define SCK_FLAG_MSG_DESCRIPTOR 2
|
||||||
|
|
||||||
/* Maximum number of received messages */
|
/* Maximum number of received messages */
|
||||||
#define SCK_MAX_RECV_MESSAGES 4
|
#define SCK_MAX_RECV_MESSAGES 4
|
||||||
|
@ -70,6 +71,8 @@ typedef struct {
|
||||||
int l2_length;
|
int l2_length;
|
||||||
int tx_flags;
|
int tx_flags;
|
||||||
} timestamp;
|
} timestamp;
|
||||||
|
|
||||||
|
int descriptor;
|
||||||
} SCK_Message;
|
} SCK_Message;
|
||||||
|
|
||||||
/* Initialisation function */
|
/* Initialisation function */
|
||||||
|
|
Loading…
Reference in a new issue