[PATCH] bsd: Use correct size for routing socket

Masashi Honma honma at ictec.co.jp
Tue Feb 22 22:22:19 EST 2011


(2011/02/22 21:01), Jouni Malinen wrote:
> On Tue, Feb 22, 2011 at 08:39:57PM +0900, Masashi Honma wrote:
>> The buffer size for routing socket is fixed to 2048.
>> This patch fix it to obtain the size from OS.
>
> Does this patch fix an issue that results in incorrect behavior? Are the
> event messages really longer than 2048 bytes?

No. I haven't seen it caused a problem. But the fact doesn't
guarantee 2048 is enough. At least rtbuf_len() returns the value
which OS guarantees it is enough.

>
> Wouldn't it be better to determine the buffer length once during
> initialization and cache that information in struct bsd_driver_data to
> avoid the extra sysctl calls? Or can this change dynamically during
> wpa_supplicant/hostapd process runtime?

I have thought as you. But this can change dynamically. At
wpa_driver_bsd_init(), wpa_driver_bsd_event_receive()
rtbuf_len() returns 4259, 5046 respectively.

> Is the realloc() to smaller
> buffer really of any help here? Isn't the buffer freed more or less
> immediately?
>

I used realloc() because rtbuf_len() returns larger value than
practical message size. If wpa_supplicant_event() returns immediately,
following patch can be used.


diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c
index d57d218..b42fab6 100644
--- a/src/drivers/driver_bsd.c
+++ b/src/drivers/driver_bsd.c
@@ -15,6 +15,7 @@
  
  #include "includes.h"
  #include <sys/ioctl.h>
+#include <sys/sysctl.h>
  
  #include "common.h"
  #include "driver.h"
@@ -569,6 +570,21 @@ bsd_set_opt_ie(void *priv, const u8 *ie, size_t ie_len)
  	return 0;
  }
  
+static int
+rtbuf_len(void)
+{
+	size_t len;
+
+	int mib[6] = {CTL_NET, AF_ROUTE, 0, AF_INET6, NET_RT_DUMP, 0};
+
+	if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
+		wpa_printf(MSG_ERROR, "%s failed: %s\n", __func__,
+			   strerror(errno));
+		return -1;
+	}
+
+	return len;
+}
  
  #ifdef HOSTAPD
  
@@ -691,26 +707,39 @@ static void
  bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
  {
  	struct bsd_driver_data *drv = ctx;
-	char buf[2048] __attribute__ ((aligned (4)));
+	char *buf;
  	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;
+	int n, len;
  	union wpa_event_data data;
  
-	n = read(sock, buf, sizeof(buf));
+	len = rtbuf_len();
+	if (len < 0)
+		return;
+
+	buf = os_malloc(len);
+	if (buf == NULL) {
+		wpa_printf(MSG_ERROR, "%s os_malloc() failed\n", __func__);
+		return;
+	}
+
+	n = read(sock, buf, len);
  	if (n < 0) {
  		if (errno != EINTR && errno != EAGAIN)
-			perror("read(PF_ROUTE)");
+			wpa_printf(MSG_ERROR, "%s read() failed: %s\n",
+				   __func__, strerror(errno));
+		os_free(buf);
  		return;
  	}
  
  	rtm = (struct rt_msghdr *) buf;
  	if (rtm->rtm_version != RTM_VERSION) {
-		wpa_printf(MSG_DEBUG, "Routing message version %d not "
-			"understood\n", rtm->rtm_version);
+		wpa_printf(MSG_ERROR, "Invalid routing message version=%d",
+			   rtm->rtm_version);
+		os_free(buf);
  		return;
  	}
  	ifan = (struct if_announcemsghdr *) rtm;
@@ -751,6 +780,7 @@ bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
  		}
  		break;
  	}
+	os_free(buf);
  }
  
  static void
@@ -1115,7 +1145,7 @@ static void
  wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
  {
  	struct bsd_driver_data *drv = sock_ctx;
-	char buf[2048] __attribute__ ((aligned (4)));
+	char *buf;
  	struct if_announcemsghdr *ifan;
  	struct if_msghdr *ifm;
  	struct rt_msghdr *rtm;
@@ -1123,19 +1153,32 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
  	struct ieee80211_michael_event *mic;
  	struct ieee80211_leave_event *leave;
  	struct ieee80211_join_event *join;
-	int n;
+	int n, len;
+
+	len = rtbuf_len();
+	if (len < 0)
+		return;
+
+	buf = os_malloc(len);
+	if (buf == NULL) {
+		wpa_printf(MSG_ERROR, "%s os_malloc() failed\n", __func__);
+		return;
+	}
  
-	n = read(sock, buf, sizeof(buf));
+	n = read(sock, buf, len);
  	if (n < 0) {
  		if (errno != EINTR && errno != EAGAIN)
-			perror("read(PF_ROUTE)");
+			wpa_printf(MSG_ERROR, "%s read() failed: %s\n",
+				   __func__, strerror(errno));
+		os_free(buf);
  		return;
  	}
  
  	rtm = (struct rt_msghdr *) buf;
  	if (rtm->rtm_version != RTM_VERSION) {
-		wpa_printf(MSG_DEBUG, "Routing message version %d not "
-			"understood\n", rtm->rtm_version);
+		wpa_printf(MSG_ERROR, "Invalid routing message version=%d",
+			   rtm->rtm_version);
+		os_free(buf);
  		return;
  	}
  	os_memset(&event, 0, sizeof(event));
@@ -1150,6 +1193,7 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
  		case IFAN_DEPARTURE:
  			event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
  		default:
+			os_free(buf);
  			return;
  		}
  		wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: Interface '%s' %s",
@@ -1222,6 +1266,7 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
  		}
  		break;
  	}
+	os_free(buf);
  }
  
  static void


Regards,
Masashi Honma.


More information about the HostAP mailing list