mirror of
https://codeberg.org/dnkl/yambar.git
synced 2025-04-24 04:45:41 +02:00
module/network: break out message receiving code
This commit is contained in:
parent
b3f3f91dc2
commit
8352d89491
1 changed files with 53 additions and 29 deletions
|
@ -341,6 +341,44 @@ handle_address(struct module *mod, uint16_t type,
|
|||
mod->bar->refresh(mod->bar);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads at least one (possibly more) message.
|
||||
*
|
||||
* On success, 'reply' will point to a malloc:ed buffer, to be freed
|
||||
* by the caller. 'len' is set to the size of the message (note that
|
||||
* the allocated size may actually be larger).
|
||||
*
|
||||
* Returns true on success, otherwise false
|
||||
*/
|
||||
static bool
|
||||
netlink_receive_messages(int sock, void **reply, size_t *len)
|
||||
{
|
||||
/* Use MSG_PEEK to find out how large buffer we need */
|
||||
const size_t chunk_sz = 1024;
|
||||
size_t sz = chunk_sz;
|
||||
*reply = malloc(sz);
|
||||
|
||||
while (true) {
|
||||
ssize_t bytes = recvfrom(sock, *reply, sz, MSG_PEEK, NULL, NULL);
|
||||
if (bytes == -1) {
|
||||
LOG_ERRNO("failed to receive from netlink socket");
|
||||
free(*reply);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bytes < sz)
|
||||
break;
|
||||
|
||||
sz += chunk_sz;
|
||||
*reply = realloc(*reply, sz);
|
||||
}
|
||||
|
||||
*len = recvfrom(sock, *reply, sz, 0, NULL, NULL);
|
||||
assert(*len >= 0);
|
||||
assert(*len < sz);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
run(struct module_run_context *ctx)
|
||||
{
|
||||
|
@ -358,6 +396,8 @@ run(struct module_run_context *ctx)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* We must wait for NLMSG_DONE from the first request, before
|
||||
* sending another one... */
|
||||
bool get_addresses = true;
|
||||
|
||||
/* Main loop */
|
||||
|
@ -379,42 +419,20 @@ run(struct module_run_context *ctx)
|
|||
|
||||
assert(fds[1].revents & POLLIN);
|
||||
|
||||
/* Use MSG_PEEK to find out how large buffer we need */
|
||||
const size_t chunk_sz = 64;
|
||||
size_t sz = chunk_sz;
|
||||
void *reply = malloc(sz);
|
||||
|
||||
while (true) {
|
||||
ssize_t bytes = recvfrom(nl_sock, reply, sz, MSG_PEEK, NULL, NULL);
|
||||
if (bytes == -1) {
|
||||
LOG_ERRNO("failed to receive from netlink socket");
|
||||
free(reply);
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
if (bytes < sz)
|
||||
/* Read one (or more) messages */
|
||||
void *reply;
|
||||
size_t len;
|
||||
if (!netlink_receive_messages(nl_sock, &reply, &len))
|
||||
break;
|
||||
|
||||
sz += chunk_sz;
|
||||
reply = realloc(reply, sz);
|
||||
}
|
||||
|
||||
ssize_t len = recvfrom(nl_sock, reply, sz, 0, NULL, NULL);
|
||||
assert(len < sz);
|
||||
|
||||
/* Process response */
|
||||
for (const struct nlmsghdr *hdr = (const struct nlmsghdr *)reply;
|
||||
NLMSG_OK(hdr, len);
|
||||
hdr = NLMSG_NEXT(hdr, len))
|
||||
{
|
||||
switch (hdr->nlmsg_type) {
|
||||
case NLMSG_ERROR:{
|
||||
const struct nlmsgerr *err = NLMSG_DATA(hdr);
|
||||
LOG_ERRNO_P("netlink", err->error);
|
||||
break;
|
||||
}
|
||||
|
||||
case NLMSG_DONE:
|
||||
/* Request initial list of IPv4/6 addresses */
|
||||
if (get_addresses && m->ifindex != -1) {
|
||||
get_addresses = false;
|
||||
send_rt_request(nl_sock, RTM_GETADDR);
|
||||
|
@ -439,6 +457,12 @@ run(struct module_run_context *ctx)
|
|||
break;
|
||||
}
|
||||
|
||||
case NLMSG_ERROR:{
|
||||
const struct nlmsgerr *err = NLMSG_DATA(hdr);
|
||||
LOG_ERRNO_P("netlink", err->error);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
LOG_WARN(
|
||||
"unrecognized netlink message type: 0x%x", hdr->nlmsg_type);
|
||||
|
|
Loading…
Add table
Reference in a new issue