diff options
author | Martin Willi <martin@revosec.ch> | 2014-07-09 16:16:16 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2014-09-24 11:19:59 +0200 |
commit | 4c3aca273fdf14f12072f3e9fd87ef75782e55fb (patch) | |
tree | 86d9bbfa14284c22e4dc19743a8b082cbff72b22 /src | |
parent | de11d34abb49a6ca64b98f586821d98312162a64 (diff) | |
download | strongswan-4c3aca273fdf14f12072f3e9fd87ef75782e55fb.tar.bz2 strongswan-4c3aca273fdf14f12072f3e9fd87ef75782e55fb.tar.xz |
kernel-netlink: Clean up response buffer management
Diffstat (limited to 'src')
-rw-r--r-- | src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c | 40 |
1 files changed, 16 insertions, 24 deletions
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c index 427499108..12df7c5ad 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c @@ -65,10 +65,13 @@ METHOD(netlink_socket_t, netlink_send, status_t, private_netlink_socket_t *this, struct nlmsghdr *in, struct nlmsghdr **out, size_t *out_len) { - int len; + union { + struct nlmsghdr hdr; + u_char bytes[4096]; + } response; struct sockaddr_nl addr; - chunk_t result = chunk_empty, tmp; - struct nlmsghdr *msg, peek; + chunk_t result = chunk_empty; + int len; this->mutex->lock(this->mutex); @@ -82,11 +85,9 @@ METHOD(netlink_socket_t, netlink_send, status_t, 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_chunk); + DBG3(DBG_KNL, "sending %N: %b", + xfrm_msg_names, in->nlmsg_type, in, in->nlmsg_len); } - while (TRUE) { len = sendto(this->socket, in, in->nlmsg_len, 0, @@ -108,13 +109,7 @@ METHOD(netlink_socket_t, netlink_send, status_t, while (TRUE) { - char buf[4096]; - tmp.len = sizeof(buf); - tmp.ptr = buf; - msg = (struct nlmsghdr*)tmp.ptr; - - len = recv(this->socket, tmp.ptr, tmp.len, 0); - + len = recv(this->socket, &response, sizeof(response), 0); if (len < 0) { if (errno == EINTR) @@ -128,17 +123,17 @@ METHOD(netlink_socket_t, netlink_send, status_t, free(result.ptr); return FAILED; } - if (!NLMSG_OK(msg, len)) + if (!NLMSG_OK(&response.hdr, len)) { DBG1(DBG_KNL, "received corrupted netlink message"); this->mutex->unlock(this->mutex); free(result.ptr); return FAILED; } - if (msg->nlmsg_seq != this->seq) + if (response.hdr.nlmsg_seq != this->seq) { DBG1(DBG_KNL, "received invalid netlink sequence number"); - if (msg->nlmsg_seq < this->seq) + if (response.hdr.nlmsg_seq < this->seq) { continue; } @@ -147,16 +142,13 @@ METHOD(netlink_socket_t, netlink_send, status_t, return FAILED; } - tmp.len = len; - result.ptr = realloc(result.ptr, result.len + tmp.len); - memcpy(result.ptr + result.len, tmp.ptr, tmp.len); - result.len += tmp.len; + result = chunk_cat("mc", result, chunk_create(response.bytes, len)); /* NLM_F_MULTI flag does not seem to be set correctly, we use sequence * numbers to detect multi header messages */ - len = recv(this->socket, &peek, sizeof(peek), MSG_PEEK | MSG_DONTWAIT); - - if (len == sizeof(peek) && peek.nlmsg_seq == this->seq) + len = recv(this->socket, &response.hdr, sizeof(response.hdr), + MSG_PEEK | MSG_DONTWAIT); + if (len == sizeof(response.hdr) && response.hdr.nlmsg_seq == this->seq) { /* seems to be multipart */ continue; |