Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/external/bsd/wpa/dist/src/drivers Use recvmsg(2) to read rou...
details: https://anonhg.NetBSD.org/src/rev/8e5092355b30
branches: trunk
changeset: 352814:8e5092355b30
user: roy <roy%NetBSD.org@localhost>
date: Tue Apr 11 14:13:01 2017 +0000
description:
Use recvmsg(2) to read route(4) messages.
Use a shim function for this which can grow it's buffer when needed.
diffstat:
external/bsd/wpa/dist/src/drivers/driver_bsd.c | 96 ++++++++++++++++---------
1 files changed, 62 insertions(+), 34 deletions(-)
diffs (197 lines):
diff -r dd18685ba194 -r 8e5092355b30 external/bsd/wpa/dist/src/drivers/driver_bsd.c
--- a/external/bsd/wpa/dist/src/drivers/driver_bsd.c Tue Apr 11 14:05:35 2017 +0000
+++ b/external/bsd/wpa/dist/src/drivers/driver_bsd.c Tue Apr 11 14:13:01 2017 +0000
@@ -9,7 +9,7 @@
#include "includes.h"
#include <sys/ioctl.h>
-#include <sys/sysctl.h>
+#include <sys/param.h>
#include "common.h"
#include "driver.h"
@@ -45,15 +45,13 @@
#include "common/ieee802_11_defs.h"
#include "common/wpa_common.h"
-
#include "l2_packet/l2_packet.h"
struct bsd_driver_global {
void *ctx;
int sock; /* socket for 802.11 ioctls */
int route; /* routing socket for events */
- char *event_buf;
- size_t event_buf_len;
+ struct iovec event_iov[1];
struct dl_list ifaces; /* list of interfaces */
};
@@ -78,6 +76,50 @@
/* Generic functions for hostapd and wpa_supplicant */
+#define IOVEC_BUFSIZ 256
+ssize_t
+recvmsg_realloc(int fd, struct msghdr *msg, int flags)
+{
+ struct iovec *iov;
+ ssize_t slen;
+ size_t len;
+ void *n;
+
+ /* Assume we are reallocing the last iovec. */
+ iov = &msg->msg_iov[msg->msg_iovlen - 1];
+
+ for (;;) {
+ /* Passing MSG_TRUNC should return the actual size needed. */
+ slen = recvmsg(fd, msg, flags | MSG_PEEK | MSG_TRUNC);
+ if (slen == -1)
+ return -1;
+ if (!(msg->msg_flags & MSG_TRUNC))
+ break;
+
+ len = (size_t)slen;
+
+ /* Some kernels return the size of the receive buffer
+ * on truncation, not the actual size needed.
+ * So grow the buffer and try again. */
+ if (iov->iov_len == len)
+ len = roundup(len + 1, IOVEC_BUFSIZ);
+ else if (iov->iov_len > len)
+ break;
+ if ((n = realloc(iov->iov_base, len)) == NULL)
+ return -1;
+ iov->iov_base = n;
+ iov->iov_len = len;
+ }
+
+ slen = recvmsg(fd, msg, flags);
+ if (slen != -1 && msg->msg_flags & MSG_TRUNC) {
+ /* This should not be possible ... */
+ errno = ENOBUFS;
+ return -1;
+ }
+ return slen;
+}
+
static struct bsd_driver_data *
bsd_get_drvindex(void *priv, unsigned int ifindex)
{
@@ -637,22 +679,6 @@
return 0;
}
-static size_t
-rtbuf_len(void)
-{
- size_t len;
-
- int mib[6] = {CTL_NET, AF_ROUTE, 0, AF_INET, NET_RT_DUMP, 0};
-
- if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
- wpa_printf(MSG_WARNING, "%s failed: %s", __func__,
- strerror(errno));
- len = 2048;
- }
-
- return len;
-}
-
#ifdef HOSTAPD
/*
@@ -727,7 +753,7 @@
}
-static int
+static int
bsd_flush(void *priv)
{
u8 allsta[IEEE80211_ADDR_LEN];
@@ -775,15 +801,19 @@
{
struct bsd_driver_global *global = sock_ctx;
struct bsd_driver_data *drv;
+ struct msghdr msg;
struct if_announcemsghdr *ifan;
struct rt_msghdr *rtm;
struct ieee80211_michael_event *mic;
struct ieee80211_join_event *join;
struct ieee80211_leave_event *leave;
- int n;
+ ssize_t n;
union wpa_event_data data;
- n = read(sock, global->event_buf, global->event_buf_len);
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_iov = global->event_iov;
+ msg.msg_iovlen = 1;
+ n = recvmsg_realloc(sock, &msg, 0);
if (n < 0) {
if (errno != EINTR && errno != EAGAIN)
wpa_printf(MSG_ERROR, "%s read() failed: %s",
@@ -791,7 +821,7 @@
return;
}
- rtm = (struct rt_msghdr *) global->event_buf;
+ rtm = (struct rt_msghdr *) global->event_iov[0].iov_base;
if (rtm->rtm_version != RTM_VERSION) {
wpa_printf(MSG_DEBUG, "Invalid routing message version=%d",
rtm->rtm_version);
@@ -1213,6 +1243,7 @@
{
struct bsd_driver_global *global = sock_ctx;
struct bsd_driver_data *drv;
+ struct msghdr msg;
struct if_announcemsghdr *ifan;
struct if_msghdr *ifm;
struct rt_msghdr *rtm;
@@ -1220,9 +1251,12 @@
struct ieee80211_michael_event *mic;
struct ieee80211_leave_event *leave;
struct ieee80211_join_event *join;
- int n;
+ ssize_t n;
- n = read(sock, global->event_buf, global->event_buf_len);
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_iov = global->event_iov;
+ msg.msg_iovlen = 1;
+ n = recvmsg_realloc(sock, &msg, 0);
if (n < 0) {
if (errno != EINTR && errno != EAGAIN)
wpa_printf(MSG_ERROR, "%s read() failed: %s",
@@ -1230,7 +1264,7 @@
return;
}
- rtm = (struct rt_msghdr *) global->event_buf;
+ rtm = (struct rt_msghdr *) global->event_iov[0].iov_base;
if (rtm->rtm_version != RTM_VERSION) {
wpa_printf(MSG_DEBUG, "Invalid routing message version=%d",
rtm->rtm_version);
@@ -1684,13 +1718,6 @@
goto fail;
}
- global->event_buf_len = rtbuf_len();
- global->event_buf = os_malloc(global->event_buf_len);
- if (global->event_buf == NULL) {
- wpa_printf(MSG_ERROR, "%s: os_malloc() failed", __func__);
- goto fail;
- }
-
#ifdef HOSTAPD
eloop_register_read_sock(global->route, bsd_wireless_event_receive,
NULL, global);
@@ -1717,6 +1744,7 @@
eloop_unregister_read_sock(global->route);
(void) close(global->route);
(void) close(global->sock);
+ free(global->event_iov[0].iov_base);
os_free(global);
}
Home |
Main Index |
Thread Index |
Old Index