Patchwork [v2] hostapd: Return code-17 on max-station limitation.

login
register
mail settings
Submitter Ben Greear
Date April 24, 2013, 6:57 p.m.
Message ID <1366829842-32291-1-git-send-email-greearb@candelatech.com>
Download mbox | patch
Permalink /patch/239294/
State Accepted
Commit 728d97171b9160e08689e2dc5a55de70b63813cd
Headers show

Comments

Ben Greear - April 24, 2013, 6:57 p.m.
From: Ben Greear <greearb@candelatech.com>

I believe this is a more valid response code.

Signed-hostap: Ben Greear <greearb@candelatech.com>
---
:100644 100644 2153329... 546c860... M	hostapd/ctrl_iface.c
:100644 100644 5e3caf1... 7d06ff0... M	src/ap/drv_callbacks.c
:100644 100644 b3574ba... 6e3479e... M	src/ap/gas_serv.c
:100644 100644 7bef55f... cde3e9e... M	src/ap/ieee802_11.c
:100644 100644 3e0c800... 28cd867... M	src/ap/preauth_auth.c
:100644 100644 cbafb47... a8e4e56... M	src/ap/sta_info.c
:100644 100644 32ea46e... cd9c261... M	src/ap/sta_info.h
:100644 100644 fdaaaff... be9a73f... M	src/ap/wpa_auth_glue.c
 hostapd/ctrl_iface.c   |    3 ++-
 src/ap/drv_callbacks.c |    9 +++++----
 src/ap/gas_serv.c      |    3 ++-
 src/ap/ieee802_11.c    |    3 +--
 src/ap/preauth_auth.c  |    3 ++-
 src/ap/sta_info.c      |    5 ++++-
 src/ap/sta_info.h      |    4 +++-
 src/ap/wpa_auth_glue.c |    3 ++-
 8 files changed, 21 insertions(+), 12 deletions(-)
Jouni Malinen - April 28, 2013, 1:50 p.m.
On Wed, Apr 24, 2013 at 11:57:22AM -0700, greearb@candelatech.com wrote:
> I believe this is a more valid response code.

Status code 17 is actually "Association denied because AP is unable to
handle additional associated STAs" while this is used to deny
Authentication (not Association). Anyway, I'm fine with changing the
value since 17 is more descriptive even if this is not strictly speaking
allocated for Authentication frames.

> -struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
> +struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr,
> +			     u16* resp)
> +		*resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;

>  	sta = os_zalloc(sizeof(struct sta_info));
>  	if (sta == NULL) {
>  		wpa_printf(MSG_ERROR, "malloc failed");
> +		*resp = WLAN_STATUS_UNSPECIFIED_FAILURE;

However, this looks excessive. It is not like that memory allocation
would fail frequently and even if it did, returning AP unable to handle
new STA sounds fine.. No point in having to change all places that use
ap_sta_add() for this, i.e., the callers that care can just use
WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA. I applied this patch with such
change instead (i.e., just two one-liner changes to the status code
values).

Patch

diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index 2153329..546c860 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -132,6 +132,7 @@  static int hostapd_ctrl_iface_new_sta(struct hostapd_data *hapd,
 {
 	u8 addr[ETH_ALEN];
 	struct sta_info *sta;
+	u16 resp;
 
 	wpa_printf(MSG_DEBUG, "CTRL_IFACE NEW_STA %s", txtaddr);
 
@@ -144,7 +145,7 @@  static int hostapd_ctrl_iface_new_sta(struct hostapd_data *hapd,
 
 	wpa_printf(MSG_DEBUG, "Add new STA " MACSTR " based on ctrl_iface "
 		   "notification", MAC2STR(addr));
-	sta = ap_sta_add(hapd, addr);
+	sta = ap_sta_add(hapd, addr, &resp);
 	if (sta == NULL)
 		return -1;
 
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
index 5e3caf1..7d06ff0 100644
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -93,7 +93,8 @@  int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
 		 */
 		sta->timeout_next = STA_NULLFUNC;
 	} else {
-		sta = ap_sta_add(hapd, addr);
+		u16 resp;
+		sta = ap_sta_add(hapd, addr, &resp);
 		if (sta == NULL) {
 			hostapd_drv_sta_disassoc(hapd, addr,
 						 WLAN_REASON_DISASSOC_AP_BUSY);
@@ -467,9 +468,8 @@  static void hostapd_notif_auth(struct hostapd_data *hapd,
 
 	sta = ap_get_sta(hapd, rx_auth->peer);
 	if (!sta) {
-		sta = ap_sta_add(hapd, rx_auth->peer);
+		sta = ap_sta_add(hapd, rx_auth->peer, &status);
 		if (sta == NULL) {
-			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
 			goto fail;
 		}
 	}
@@ -675,13 +675,14 @@  static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf,
 
 static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr)
 {
+	u16 resp;
 	struct sta_info *sta = ap_get_sta(hapd, addr);
 	if (sta)
 		return 0;
 
 	wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR
 		   " - adding a new STA", MAC2STR(addr));
-	sta = ap_sta_add(hapd, addr);
+	sta = ap_sta_add(hapd, addr, &resp);
 	if (sta) {
 		hostapd_new_assoc_sta(hapd, sta, 0);
 	} else {
diff --git a/src/ap/gas_serv.c b/src/ap/gas_serv.c
index b3574ba..6e3479e 100644
--- a/src/ap/gas_serv.c
+++ b/src/ap/gas_serv.c
@@ -28,13 +28,14 @@  gas_dialog_create(struct hostapd_data *hapd, const u8 *addr, u8 dialog_token)
 
 	sta = ap_get_sta(hapd, addr);
 	if (!sta) {
+		u16 resp;
 		/*
 		 * We need a STA entry to be able to maintain state for
 		 * the GAS query.
 		 */
 		wpa_printf(MSG_DEBUG, "ANQP: Add a temporary STA entry for "
 			   "GAS query");
-		sta = ap_sta_add(hapd, addr);
+		sta = ap_sta_add(hapd, addr, &resp);
 		if (!sta) {
 			wpa_printf(MSG_DEBUG, "Failed to add STA " MACSTR
 				   " for GAS query", MAC2STR(addr));
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 7bef55f..cde3e9e 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -643,9 +643,8 @@  static void handle_auth(struct hostapd_data *hapd,
 		return;
 	}
 
-	sta = ap_sta_add(hapd, mgmt->sa);
+	sta = ap_sta_add(hapd, mgmt->sa, &resp);
 	if (!sta) {
-		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
 		goto fail;
 	}
 
diff --git a/src/ap/preauth_auth.c b/src/ap/preauth_auth.c
index 3e0c800..28cd867 100644
--- a/src/ap/preauth_auth.c
+++ b/src/ap/preauth_auth.c
@@ -71,7 +71,8 @@  static void rsn_preauth_receive(void *ctx, const u8 *src_addr,
 		return;
 	}
 	if (!sta && hdr->type == IEEE802_1X_TYPE_EAPOL_START) {
-		sta = ap_sta_add(hapd, ethhdr->h_source);
+		u16 resp;
+		sta = ap_sta_add(hapd, ethhdr->h_source, &resp);
 		if (sta == NULL)
 			return;
 		sta->flags = WLAN_STA_PREAUTH;
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index cbafb47..a8e4e56 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -477,7 +477,8 @@  void ap_sta_no_session_timeout(struct hostapd_data *hapd, struct sta_info *sta)
 }
 
 
-struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
+struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr,
+			     u16* resp)
 {
 	struct sta_info *sta;
 
@@ -490,12 +491,14 @@  struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
 		/* FIX: might try to remove some old STAs first? */
 		wpa_printf(MSG_DEBUG, "no more room for new STAs (%d/%d)",
 			   hapd->num_sta, hapd->conf->max_num_sta);
+		*resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
 		return NULL;
 	}
 
 	sta = os_zalloc(sizeof(struct sta_info));
 	if (sta == NULL) {
 		wpa_printf(MSG_ERROR, "malloc failed");
+		*resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
 		return NULL;
 	}
 	sta->acct_interim_interval = hapd->conf->acct_interim_interval;
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index 32ea46e..cd9c261 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -163,7 +163,9 @@  void ap_sta_session_timeout(struct hostapd_data *hapd, struct sta_info *sta,
 			    u32 session_timeout);
 void ap_sta_no_session_timeout(struct hostapd_data *hapd,
 			       struct sta_info *sta);
-struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr);
+/* If failure (NULL is returned), *resp will contain the error code. */
+struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr,
+			     u16* resp);
 void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta,
 			 u16 reason);
 void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta,
diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c
index fdaaaff..be9a73f 100644
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -454,11 +454,12 @@  hostapd_wpa_auth_add_sta(void *ctx, const u8 *sta_addr)
 {
 	struct hostapd_data *hapd = ctx;
 	struct sta_info *sta;
+	u16 resp;
 
 	if (hostapd_add_sta_node(hapd, sta_addr, WLAN_AUTH_FT) < 0)
 		return NULL;
 
-	sta = ap_sta_add(hapd, sta_addr);
+	sta = ap_sta_add(hapd, sta_addr, &resp);
 	if (sta == NULL)
 		return NULL;
 	if (sta->wpa_sm) {