mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Move flags to recvmsg function in netlink
netlink_multicast used 3 calls to fcntl in order to set O_NONBLOCK on socket. It is possible to pass MSG_DONTWAIT flag just to recvmsg function, without setting it permanently on socket. Save few kernel calls and use recvmsg flags. It is supported since kernel 2.2, should be fine for any device still receiving updates.
This commit is contained in:
committed by
Simon Kelley
parent
9e147480ed
commit
8b8a4148ec
@@ -102,7 +102,7 @@ char *netlink_init(void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t netlink_recv(void)
|
static ssize_t netlink_recv(int flags)
|
||||||
{
|
{
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct sockaddr_nl nladdr;
|
struct sockaddr_nl nladdr;
|
||||||
@@ -118,7 +118,8 @@ static ssize_t netlink_recv(void)
|
|||||||
msg.msg_iovlen = 1;
|
msg.msg_iovlen = 1;
|
||||||
msg.msg_flags = 0;
|
msg.msg_flags = 0;
|
||||||
|
|
||||||
while ((rc = recvmsg(daemon->netlinkfd, &msg, MSG_PEEK | MSG_TRUNC)) == -1 && errno == EINTR);
|
while ((rc = recvmsg(daemon->netlinkfd, &msg, flags | MSG_PEEK | MSG_TRUNC)) == -1 &&
|
||||||
|
errno == EINTR);
|
||||||
|
|
||||||
/* make buffer big enough */
|
/* make buffer big enough */
|
||||||
if (rc != -1 && (msg.msg_flags & MSG_TRUNC))
|
if (rc != -1 && (msg.msg_flags & MSG_TRUNC))
|
||||||
@@ -135,7 +136,7 @@ static ssize_t netlink_recv(void)
|
|||||||
|
|
||||||
/* read it for real */
|
/* read it for real */
|
||||||
msg.msg_flags = 0;
|
msg.msg_flags = 0;
|
||||||
while ((rc = recvmsg(daemon->netlinkfd, &msg, 0)) == -1 && errno == EINTR);
|
while ((rc = recvmsg(daemon->netlinkfd, &msg, flags)) == -1 && errno == EINTR);
|
||||||
|
|
||||||
/* Make sure this is from the kernel */
|
/* Make sure this is from the kernel */
|
||||||
if (rc == -1 || nladdr.nl_pid == 0)
|
if (rc == -1 || nladdr.nl_pid == 0)
|
||||||
@@ -198,7 +199,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
|
|||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if ((len = netlink_recv()) == -1)
|
if ((len = netlink_recv(0)) == -1)
|
||||||
{
|
{
|
||||||
if (errno == ENOBUFS)
|
if (errno == ENOBUFS)
|
||||||
{
|
{
|
||||||
@@ -350,22 +351,14 @@ static void nl_multicast_state(unsigned state)
|
|||||||
{
|
{
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
struct nlmsghdr *h;
|
struct nlmsghdr *h;
|
||||||
int flags;
|
|
||||||
|
|
||||||
if ((flags = fcntl(daemon->netlinkfd, F_GETFL)) == -1 ||
|
|
||||||
fcntl(daemon->netlinkfd, F_SETFL, flags | O_NONBLOCK) == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
/* don't risk blocking reading netlink messages here. */
|
/* don't risk blocking reading netlink messages here. */
|
||||||
while ((len = netlink_recv()) != -1)
|
while ((len = netlink_recv(MSG_DONTWAIT)) != -1)
|
||||||
|
|
||||||
for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
|
for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
|
||||||
state = nl_async(h, state);
|
state = nl_async(h, state);
|
||||||
} while (errno == ENOBUFS);
|
} while (errno == ENOBUFS);
|
||||||
|
|
||||||
/* restore non-blocking status */
|
|
||||||
fcntl(daemon->netlinkfd, F_SETFL, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void netlink_multicast(void)
|
void netlink_multicast(void)
|
||||||
|
|||||||
Reference in New Issue
Block a user