Fixes communication on netlink sockets
Independent sessions on netlink sockets mixed state in some common variables.
This commit is contained in:
parent
20e94fb85b
commit
19e10907c1
1 changed files with 20 additions and 21 deletions
|
@ -42,16 +42,16 @@ struct nl_sock
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
u32 seq;
|
u32 seq;
|
||||||
|
byte *rx_buffer; /* Receive buffer */
|
||||||
|
struct nlmsghdr *last_hdr; /* Recently received packet */
|
||||||
|
unsigned int last_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct nl_sock nl_scan = {-1, 0}; /* Netlink socket for synchronous scan */
|
|
||||||
static struct nl_sock nl_req = {-1, 0}; /* Netlink socket for requests */
|
|
||||||
|
|
||||||
static byte *nl_rx_buffer; /* Receive buffer */
|
|
||||||
#define NL_RX_SIZE 8192
|
#define NL_RX_SIZE 8192
|
||||||
|
|
||||||
static struct nlmsghdr *nl_last_hdr; /* Recently received packet */
|
static struct nl_sock nl_scan = {.fd = -1}; /* Netlink socket for synchronous scan */
|
||||||
static unsigned int nl_last_size;
|
static struct nl_sock nl_req = {.fd = -1}; /* Netlink socket for requests */
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nl_open_sock(struct nl_sock *nl)
|
nl_open_sock(struct nl_sock *nl)
|
||||||
|
@ -62,6 +62,9 @@ nl_open_sock(struct nl_sock *nl)
|
||||||
if (nl->fd < 0)
|
if (nl->fd < 0)
|
||||||
die("Unable to open rtnetlink socket: %m");
|
die("Unable to open rtnetlink socket: %m");
|
||||||
nl->seq = now;
|
nl->seq = now;
|
||||||
|
nl->rx_buffer = xmalloc(NL_RX_SIZE);
|
||||||
|
nl->last_hdr = NULL;
|
||||||
|
nl->last_size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,9 +73,6 @@ nl_open(void)
|
||||||
{
|
{
|
||||||
nl_open_sock(&nl_scan);
|
nl_open_sock(&nl_scan);
|
||||||
nl_open_sock(&nl_req);
|
nl_open_sock(&nl_req);
|
||||||
|
|
||||||
if (nl_rx_buffer == NULL)
|
|
||||||
nl_rx_buffer = xmalloc(NL_RX_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -86,7 +86,7 @@ nl_send(struct nl_sock *nl, struct nlmsghdr *nh)
|
||||||
nh->nlmsg_seq = ++(nl->seq);
|
nh->nlmsg_seq = ++(nl->seq);
|
||||||
if (sendto(nl->fd, nh, nh->nlmsg_len, 0, (struct sockaddr *)&sa, sizeof(sa)) < 0)
|
if (sendto(nl->fd, nh, nh->nlmsg_len, 0, (struct sockaddr *)&sa, sizeof(sa)) < 0)
|
||||||
die("rtnetlink sendto: %m");
|
die("rtnetlink sendto: %m");
|
||||||
nl_last_hdr = NULL;
|
nl->last_hdr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -108,9 +108,9 @@ nl_get_reply(struct nl_sock *nl)
|
||||||
{
|
{
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
if (!nl_last_hdr)
|
if (!nl->last_hdr)
|
||||||
{
|
{
|
||||||
struct iovec iov = { nl_rx_buffer, NL_RX_SIZE };
|
struct iovec iov = { nl->rx_buffer, NL_RX_SIZE };
|
||||||
struct sockaddr_nl sa;
|
struct sockaddr_nl sa;
|
||||||
struct msghdr m = { (struct sockaddr *) &sa, sizeof(sa), &iov, 1, NULL, 0, 0 };
|
struct msghdr m = { (struct sockaddr *) &sa, sizeof(sa), &iov, 1, NULL, 0, 0 };
|
||||||
int x = recvmsg(nl->fd, &m, 0);
|
int x = recvmsg(nl->fd, &m, 0);
|
||||||
|
@ -121,15 +121,15 @@ nl_get_reply(struct nl_sock *nl)
|
||||||
DBG("Non-kernel packet\n");
|
DBG("Non-kernel packet\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
nl_last_size = x;
|
nl->last_size = x;
|
||||||
nl_last_hdr = (void *) nl_rx_buffer;
|
nl->last_hdr = (void *) nl->rx_buffer;
|
||||||
if (m.msg_flags & MSG_TRUNC)
|
if (m.msg_flags & MSG_TRUNC)
|
||||||
bug("nl_get_reply: got truncated reply which should be impossible");
|
bug("nl_get_reply: got truncated reply which should be impossible");
|
||||||
}
|
}
|
||||||
if (NLMSG_OK(nl_last_hdr, nl_last_size))
|
if (NLMSG_OK(nl->last_hdr, nl->last_size))
|
||||||
{
|
{
|
||||||
struct nlmsghdr *h = nl_last_hdr;
|
struct nlmsghdr *h = nl->last_hdr;
|
||||||
nl_last_hdr = NLMSG_NEXT(h, nl_last_size);
|
nl->last_hdr = NLMSG_NEXT(h, nl->last_size);
|
||||||
if (h->nlmsg_seq != nl->seq)
|
if (h->nlmsg_seq != nl->seq)
|
||||||
{
|
{
|
||||||
log(L_WARN "nl_get_reply: Ignoring out of sequence netlink packet (%x != %x)",
|
log(L_WARN "nl_get_reply: Ignoring out of sequence netlink packet (%x != %x)",
|
||||||
|
@ -138,9 +138,9 @@ nl_get_reply(struct nl_sock *nl)
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
if (nl_last_size)
|
if (nl->last_size)
|
||||||
log(L_WARN "nl_get_reply: Found packet remnant of size %d", nl_last_size);
|
log(L_WARN "nl_get_reply: Found packet remnant of size %d", nl->last_size);
|
||||||
nl_last_hdr = NULL;
|
nl->last_hdr = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -797,7 +797,6 @@ nl_async_hook(sock *sk, int size UNUSED)
|
||||||
int x;
|
int x;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
|
||||||
nl_last_hdr = NULL; /* Discard packets accidentally remaining in the rxbuf */
|
|
||||||
x = recvmsg(sk->fd, &m, 0);
|
x = recvmsg(sk->fd, &m, 0);
|
||||||
if (x < 0)
|
if (x < 0)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue