mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
Socket: sending filedescriptors over UNIX sockets
This commit is contained in:
parent
62bca8e882
commit
d0425e8a54
@ -74,6 +74,9 @@ typedef struct birdsock {
|
|||||||
uint lifindex; /* local interface that received the datagram */
|
uint lifindex; /* local interface that received the datagram */
|
||||||
/* laddr and lifindex are valid only if SKF_LADDR_RX flag is set to request it */
|
/* laddr and lifindex are valid only if SKF_LADDR_RX flag is set to request it */
|
||||||
|
|
||||||
|
/* Filedescriptors to send/receive (UNIX) */
|
||||||
|
int rxfd, txfd;
|
||||||
|
|
||||||
int af; /* System-dependend adress family (e.g. AF_INET) */
|
int af; /* System-dependend adress family (e.g. AF_INET) */
|
||||||
int fd; /* System-dependent data */
|
int fd; /* System-dependent data */
|
||||||
int index; /* Index in poll buffer */
|
int index; /* Index in poll buffer */
|
||||||
@ -143,6 +146,9 @@ extern int sk_priority_control; /* Suggested priority for control traffic, shou
|
|||||||
#define SKF_HDRINCL 0x400 /* Used internally */
|
#define SKF_HDRINCL 0x400 /* Used internally */
|
||||||
#define SKF_PKTINFO 0x800 /* Used internally */
|
#define SKF_PKTINFO 0x800 /* Used internally */
|
||||||
|
|
||||||
|
#define SKF_FD_RX 0x1000 /* Allow receiving filedescriptors (unix sockets) */
|
||||||
|
#define SKF_FD_TX 0x2000 /* Allow sending filedescriptors (unix sockets) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Socket types SA SP DA DP IF TTL SendTo (?=may, -=must not, *=must)
|
* Socket types SA SP DA DP IF TTL SendTo (?=may, -=must not, *=must)
|
||||||
*/
|
*/
|
||||||
@ -157,6 +163,7 @@ extern int sk_priority_control; /* Suggested priority for control traffic, shou
|
|||||||
#define SK_UNIX 9
|
#define SK_UNIX 9
|
||||||
#define SK_SSH_ACTIVE 10 /* - - * * - ? - DA = host */
|
#define SK_SSH_ACTIVE 10 /* - - * * - ? - DA = host */
|
||||||
#define SK_SSH 11
|
#define SK_SSH 11
|
||||||
|
#define SK_UNIX_MSG 12 /* Like SK_UNIX but using sendmsg and recvmsg */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Socket subtypes
|
* Socket subtypes
|
||||||
|
@ -300,6 +300,43 @@ sk_prepare_cmsgs6(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
|
|||||||
msg->msg_controllen = controllen;
|
msg->msg_controllen = controllen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UNIX packet control messages
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CMSGU_SPACE_FD CMSG_SPACE(sizeof (int))
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
sk_prepare_cmsgs_unix(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
|
||||||
|
{
|
||||||
|
if (s->txfd < 0)
|
||||||
|
{
|
||||||
|
msg->msg_control = NULL;
|
||||||
|
msg->msg_controllen = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg->msg_control = cbuf;
|
||||||
|
msg->msg_controllen = cbuflen;
|
||||||
|
|
||||||
|
struct cmsghdr *cm = CMSG_FIRSTHDR(msg);
|
||||||
|
cm->cmsg_level = SOL_SOCKET;
|
||||||
|
cm->cmsg_type = SCM_RIGHTS;
|
||||||
|
cm->cmsg_len = CMSG_LEN(sizeof s->txfd);
|
||||||
|
memcpy(CMSG_DATA(cm), &s->txfd, sizeof s->txfd);
|
||||||
|
|
||||||
|
msg->msg_controllen = CMSGU_SPACE_FD;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
sk_process_cmsg_unix_fd(sock *s, struct cmsghdr *cm)
|
||||||
|
{
|
||||||
|
if (cm->cmsg_type == SCM_RIGHTS)
|
||||||
|
memcpy(&s->rxfd, CMSG_DATA(cm), sizeof s->rxfd);
|
||||||
|
else
|
||||||
|
s->rxfd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Miscellaneous socket syscalls
|
* Miscellaneous socket syscalls
|
||||||
@ -1420,14 +1457,17 @@ sk_open_unix(sock *s, struct birdloop *loop, const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define CMSG_RX_SPACE MAX(CMSG4_SPACE_PKTINFO+CMSG4_SPACE_TTL, \
|
#define CMSG_RX_SPACE MAX(CMSGU_SPACE_FD, \
|
||||||
CMSG6_SPACE_PKTINFO+CMSG6_SPACE_TTL)
|
MAX(CMSG4_SPACE_PKTINFO+CMSG4_SPACE_TTL, \
|
||||||
#define CMSG_TX_SPACE MAX(CMSG4_SPACE_PKTINFO,CMSG6_SPACE_PKTINFO)
|
CMSG6_SPACE_PKTINFO+CMSG6_SPACE_TTL))
|
||||||
|
#define CMSG_TX_SPACE MAX(MAX(CMSG4_SPACE_PKTINFO,CMSG6_SPACE_PKTINFO),CMSGU_SPACE_FD)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sk_prepare_cmsgs(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
|
sk_prepare_cmsgs(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
|
||||||
{
|
{
|
||||||
if (sk_is_ipv4(s))
|
if (s->type == SK_UNIX_MSG)
|
||||||
|
sk_prepare_cmsgs_unix(s, msg, cbuf, cbuflen);
|
||||||
|
else if (sk_is_ipv4(s))
|
||||||
sk_prepare_cmsgs4(s, msg, cbuf, cbuflen);
|
sk_prepare_cmsgs4(s, msg, cbuf, cbuflen);
|
||||||
else
|
else
|
||||||
sk_prepare_cmsgs6(s, msg, cbuf, cbuflen);
|
sk_prepare_cmsgs6(s, msg, cbuf, cbuflen);
|
||||||
@ -1455,6 +1495,11 @@ sk_process_cmsgs(sock *s, struct msghdr *msg)
|
|||||||
sk_process_cmsg6_pktinfo(s, cm);
|
sk_process_cmsg6_pktinfo(s, cm);
|
||||||
sk_process_cmsg6_ttl(s, cm);
|
sk_process_cmsg6_ttl(s, cm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((cm->cmsg_level == SOL_SOCKET) && (s->type == SK_UNIX_MSG))
|
||||||
|
{
|
||||||
|
sk_process_cmsg_unix_fd(s, cm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1467,15 +1512,19 @@ sk_sendmsg(sock *s)
|
|||||||
sockaddr dst;
|
sockaddr dst;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
sockaddr_fill(&dst, s->af, s->daddr, s->iface, s->dport);
|
|
||||||
|
|
||||||
struct msghdr msg = {
|
struct msghdr msg = {
|
||||||
.msg_name = &dst.sa,
|
|
||||||
.msg_namelen = SA_LEN(dst),
|
|
||||||
.msg_iov = &iov,
|
.msg_iov = &iov,
|
||||||
.msg_iovlen = 1
|
.msg_iovlen = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (s->type != SK_UNIX_MSG)
|
||||||
|
{
|
||||||
|
sockaddr_fill(&dst, s->af, s->daddr, s->iface, s->dport);
|
||||||
|
|
||||||
|
msg.msg_name = &dst.sa;
|
||||||
|
msg.msg_namelen = SA_LEN(dst);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_DONTROUTE_UNICAST
|
#ifdef CONFIG_DONTROUTE_UNICAST
|
||||||
/* FreeBSD silently changes TTL to 1 when MSG_DONTROUTE is used, therefore we
|
/* FreeBSD silently changes TTL to 1 when MSG_DONTROUTE is used, therefore we
|
||||||
cannot use it for other cases (e.g. when TTL security is used). */
|
cannot use it for other cases (e.g. when TTL security is used). */
|
||||||
@ -1495,7 +1544,7 @@ sk_sendmsg(sock *s)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (s->flags & SKF_PKTINFO)
|
if (s->flags & (SKF_PKTINFO | SKF_FD_TX))
|
||||||
sk_prepare_cmsgs(s, &msg, cmsg_buf, sizeof(cmsg_buf));
|
sk_prepare_cmsgs(s, &msg, cmsg_buf, sizeof(cmsg_buf));
|
||||||
|
|
||||||
return sendmsg(s->fd, &msg, flags);
|
return sendmsg(s->fd, &msg, flags);
|
||||||
@ -1602,6 +1651,7 @@ sk_maybe_write(sock *s)
|
|||||||
|
|
||||||
case SK_UDP:
|
case SK_UDP:
|
||||||
case SK_IP:
|
case SK_IP:
|
||||||
|
case SK_UNIX_MSG:
|
||||||
{
|
{
|
||||||
if (s->tbuf == s->tpos)
|
if (s->tbuf == s->tpos)
|
||||||
return 1;
|
return 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user