kernel-netlink: Clean up response buffer management

This commit is contained in:
Martin Willi 2014-07-09 16:16:16 +02:00
parent de11d34abb
commit 4c3aca273f

View File

@ -65,10 +65,13 @@ METHOD(netlink_socket_t, netlink_send, status_t,
private_netlink_socket_t *this, struct nlmsghdr *in, struct nlmsghdr **out, private_netlink_socket_t *this, struct nlmsghdr *in, struct nlmsghdr **out,
size_t *out_len) size_t *out_len)
{ {
int len; union {
struct nlmsghdr hdr;
u_char bytes[4096];
} response;
struct sockaddr_nl addr; struct sockaddr_nl addr;
chunk_t result = chunk_empty, tmp; chunk_t result = chunk_empty;
struct nlmsghdr *msg, peek; int len;
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
@ -82,11 +85,9 @@ METHOD(netlink_socket_t, netlink_send, status_t,
if (this->protocol == NETLINK_XFRM) if (this->protocol == NETLINK_XFRM)
{ {
chunk_t in_chunk = { (u_char*)in, in->nlmsg_len }; DBG3(DBG_KNL, "sending %N: %b",
xfrm_msg_names, in->nlmsg_type, in, in->nlmsg_len);
DBG3(DBG_KNL, "sending %N: %B", xfrm_msg_names, in->nlmsg_type, &in_chunk);
} }
while (TRUE) while (TRUE)
{ {
len = sendto(this->socket, in, in->nlmsg_len, 0, len = sendto(this->socket, in, in->nlmsg_len, 0,
@ -108,13 +109,7 @@ METHOD(netlink_socket_t, netlink_send, status_t,
while (TRUE) while (TRUE)
{ {
char buf[4096]; len = recv(this->socket, &response, sizeof(response), 0);
tmp.len = sizeof(buf);
tmp.ptr = buf;
msg = (struct nlmsghdr*)tmp.ptr;
len = recv(this->socket, tmp.ptr, tmp.len, 0);
if (len < 0) if (len < 0)
{ {
if (errno == EINTR) if (errno == EINTR)
@ -128,17 +123,17 @@ METHOD(netlink_socket_t, netlink_send, status_t,
free(result.ptr); free(result.ptr);
return FAILED; return FAILED;
} }
if (!NLMSG_OK(msg, len)) if (!NLMSG_OK(&response.hdr, len))
{ {
DBG1(DBG_KNL, "received corrupted netlink message"); DBG1(DBG_KNL, "received corrupted netlink message");
this->mutex->unlock(this->mutex); this->mutex->unlock(this->mutex);
free(result.ptr); free(result.ptr);
return FAILED; return FAILED;
} }
if (msg->nlmsg_seq != this->seq) if (response.hdr.nlmsg_seq != this->seq)
{ {
DBG1(DBG_KNL, "received invalid netlink sequence number"); DBG1(DBG_KNL, "received invalid netlink sequence number");
if (msg->nlmsg_seq < this->seq) if (response.hdr.nlmsg_seq < this->seq)
{ {
continue; continue;
} }
@ -147,16 +142,13 @@ METHOD(netlink_socket_t, netlink_send, status_t,
return FAILED; return FAILED;
} }
tmp.len = len; result = chunk_cat("mc", result, chunk_create(response.bytes, len));
result.ptr = realloc(result.ptr, result.len + tmp.len);
memcpy(result.ptr + result.len, tmp.ptr, tmp.len);
result.len += tmp.len;
/* NLM_F_MULTI flag does not seem to be set correctly, we use sequence /* NLM_F_MULTI flag does not seem to be set correctly, we use sequence
* numbers to detect multi header messages */ * numbers to detect multi header messages */
len = recv(this->socket, &peek, sizeof(peek), MSG_PEEK | MSG_DONTWAIT); len = recv(this->socket, &response.hdr, sizeof(response.hdr),
MSG_PEEK | MSG_DONTWAIT);
if (len == sizeof(peek) && peek.nlmsg_seq == this->seq) if (len == sizeof(response.hdr) && response.hdr.nlmsg_seq == this->seq)
{ {
/* seems to be multipart */ /* seems to be multipart */
continue; continue;