diff mbox

[1/2] IAPP: Set SO_REUSEPORT on listening socket

Message ID 1447179434-18596-1-git-send-email-bordjukov@gmail.com
State Changes Requested
Headers show

Commit Message

Petko Bordjukov Nov. 10, 2015, 6:17 p.m. UTC
Make it possible for several instances of hostapd to listen on the same
network interface.

Signed-off-by: Petko Bordjukov <bordjukov@gmail.com>
---
 src/ap/iapp.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

Comments

Jouni Malinen Nov. 15, 2015, 5:16 p.m. UTC | #1
On Tue, Nov 10, 2015 at 08:17:13PM +0200, Petko Bordjukov wrote:
> Make it possible for several instances of hostapd to listen on the same
> network interface.

> diff --git a/src/ap/iapp.c b/src/ap/iapp.c
> @@ -447,6 +448,15 @@ struct iapp_data * iapp_init(struct hostapd_data *hapd, const char *iface)
>  	os_memset(&uaddr, 0, sizeof(uaddr));
>  	uaddr.sin_family = AF_INET;
>  	uaddr.sin_port = htons(IAPP_UDP_PORT);
> +
> +	if (setsockopt(iapp->udp_sock, SOL_SOCKET, SO_REUSEPORT, &reuseport,
> +		       sizeof(reuseport)) < 0) {

SO_REUSEPORT is a pretty recent addition. Wouldn't this break build with
older header files? As such, this should probably be protected with
#ifdef SO_REUSEPORT or something similar.

> +		wpa_printf(MSG_INFO, "iapp_init - setsockopt[UDP,SO_REUSEPORT]: %s",
> +			   strerror(errno));
> +		iapp_deinit(iapp);
> +		return NULL;
> +	}

And this should not return failure on error since anything older than
Linux 3.9 would fail here. It sounds like it would be safe to ignore the
error and continue to get the existing behavior.
Petko Bordjukov Nov. 16, 2015, 2:56 a.m. UTC | #2
Hello and thank you for the feedback!

On нд, 2015-11-15 at 19:16 +0200, Jouni Malinen wrote:
> SO_REUSEPORT is a pretty recent addition. Wouldn't this break build
> with older header files? As such, this should probably be protected
> with #ifdef SO_REUSEPORT or something similar.

Yes, SO_REUSEPORT is indeed a fairly new addition to Linux. I could
protect it with an ifdef or I could just use SO_REUSEADDR. If I
understand correctly there is little difference between the two with
regards to multicast (with the exception of the UID checking for
SO_REUSEPORT).

Having said that, I have not tested SO_REUSEADDR yet. I will and
depending on the results will either submit a new version with
SO_REUSEADDR or one with an ifdef around the setsockopt invocation.

> It sounds like it would be safe to ignore the error and continue to
> get the existing behavior.

Yes, it would be safe to continue. Should I make it just log a
MSG_WARNING and carry on instead?

--
Regards,
P.
Jouni Malinen Nov. 22, 2015, 7:02 p.m. UTC | #3
On Mon, Nov 16, 2015 at 04:56:42AM +0200, Petko Bordjukov wrote:
> On нд, 2015-11-15 at 19:16 +0200, Jouni Malinen wrote:
> > SO_REUSEPORT is a pretty recent addition. Wouldn't this break build
> > with older header files? As such, this should probably be protected
> > with #ifdef SO_REUSEPORT or something similar.
> 
> Yes, SO_REUSEPORT is indeed a fairly new addition to Linux. I could
> protect it with an ifdef or I could just use SO_REUSEADDR. If I
> understand correctly there is little difference between the two with
> regards to multicast (with the exception of the UID checking for
> SO_REUSEPORT).
> 
> Having said that, I have not tested SO_REUSEADDR yet. I will and
> depending on the results will either submit a new version with
> SO_REUSEADDR or one with an ifdef around the setsockopt invocation.

I think I'm fine with either. Taken into account the current
implementation has been there for years, this cannot really be a
critical issue and using SO_REUSEPORT with ifdef should be fine.

> > It sounds like it would be safe to ignore the error and continue to
> > get the existing behavior.
> 
> Yes, it would be safe to continue. Should I make it just log a
> MSG_WARNING and carry on instead?

Yes.
diff mbox

Patch

diff --git a/src/ap/iapp.c b/src/ap/iapp.c
index 99aa04d..61776d8 100644
--- a/src/ap/iapp.c
+++ b/src/ap/iapp.c
@@ -385,6 +385,7 @@  struct iapp_data * iapp_init(struct hostapd_data *hapd, const char *iface)
 	struct sockaddr_in *paddr, uaddr;
 	struct iapp_data *iapp;
 	struct ip_mreqn mreq;
+	int reuseport = 1;
 
 	iapp = os_zalloc(sizeof(*iapp));
 	if (iapp == NULL)
@@ -447,6 +448,15 @@  struct iapp_data * iapp_init(struct hostapd_data *hapd, const char *iface)
 	os_memset(&uaddr, 0, sizeof(uaddr));
 	uaddr.sin_family = AF_INET;
 	uaddr.sin_port = htons(IAPP_UDP_PORT);
+
+	if (setsockopt(iapp->udp_sock, SOL_SOCKET, SO_REUSEPORT, &reuseport,
+		       sizeof(reuseport)) < 0) {
+		wpa_printf(MSG_INFO, "iapp_init - setsockopt[UDP,SO_REUSEPORT]: %s",
+			   strerror(errno));
+		iapp_deinit(iapp);
+		return NULL;
+	}
+
 	if (bind(iapp->udp_sock, (struct sockaddr *) &uaddr,
 		 sizeof(uaddr)) < 0) {
 		wpa_printf(MSG_INFO, "iapp_init - bind[UDP]: %s",