if (!GREEDY_REALLOC(rtnl->wqueue, rtnl->wqueue_allocated, 1))
return -ENOMEM;
+ /* We guarantee that the read buffer has at least space for
+ * a message header */
+ if (!greedy_realloc((void**)&rtnl->rbuffer, &rtnl->rbuffer_allocated,
+ sizeof(struct nlmsghdr), sizeof(uint8_t)))
+ return -ENOMEM;
+
*ret = rtnl;
rtnl = NULL;
int sd_rtnl_open(sd_rtnl **ret, uint32_t groups) {
_cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
socklen_t addrlen;
- int r;
+ int r, one = 1;
assert_return(ret, -EINVAL);
if (rtnl->fd < 0)
return -errno;
+ if (setsockopt(rtnl->fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
+ return -errno;
+
rtnl->sockaddr.nl.nl_groups = groups;
addrlen = sizeof(rtnl->sockaddr);
sd_rtnl_message_unref(rtnl->rqueue[i]);
free(rtnl->rqueue);
+ for (i = 0; i < rtnl->rqueue_partial_size; i++)
+ sd_rtnl_message_unref(rtnl->rqueue_partial[i]);
+ free(rtnl->rqueue_partial);
+
for (i = 0; i < rtnl->wqueue_size; i++)
sd_rtnl_message_unref(rtnl->wqueue[i]);
free(rtnl->wqueue);
+ free(rtnl->rbuffer);
+
hashmap_free_free(rtnl->reply_callbacks);
prioq_free(rtnl->reply_callbacks_prioq);
}
} else {
/* append to queue */
- if (nl->wqueue_size >= RTNL_WQUEUE_MAX)
+ if (nl->wqueue_size >= RTNL_WQUEUE_MAX) {
+ log_debug("rtnl: exhausted the write queue size (%d)", RTNL_WQUEUE_MAX);
return -ENOBUFS;
+ }
if (!GREEDY_REALLOC(nl->wqueue, nl->wqueue_allocated, nl->wqueue_size + 1))
return -ENOMEM;
int rtnl_rqueue_make_room(sd_rtnl *rtnl) {
assert(rtnl);
- if (rtnl->rqueue_size >= RTNL_RQUEUE_MAX)
+ if (rtnl->rqueue_size >= RTNL_RQUEUE_MAX) {
+ log_debug("rtnl: exhausted the read queue size (%d)", RTNL_RQUEUE_MAX);
return -ENOBUFS;
+ }
if (!GREEDY_REALLOC(rtnl->rqueue, rtnl->rqueue_allocated, rtnl->rqueue_size + 1))
return -ENOMEM;
return 0;
}
+int rtnl_rqueue_partial_make_room(sd_rtnl *rtnl) {
+ assert(rtnl);
+
+ if (rtnl->rqueue_partial_size >= RTNL_RQUEUE_MAX) {
+ log_debug("rtnl: exhausted the partial read queue size (%d)", RTNL_RQUEUE_MAX);
+ return -ENOBUFS;
+ }
+
+ if (!GREEDY_REALLOC(rtnl->rqueue_partial, rtnl->rqueue_partial_allocated,
+ rtnl->rqueue_partial_size + 1))
+ return -ENOMEM;
+
+ return 0;
+}
+
static int dispatch_rqueue(sd_rtnl *rtnl, sd_rtnl_message **message) {
int r;