From 08a98b6544456e4590b26008b44a7328cbf07bcd Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 17 Oct 2010 21:24:12 +0300 Subject: [PATCH] WPS UPnP: Throttle WLANEvent notifications to 5 per second Do not send more than five Probe Request WLANEvent notifications per second. Even though the limit should in theory apply to all WLANEvents, it is better not to drop EAP notifications because of Probe Request frames and really, the only real reason for event bursts is Probe Request frames. --- src/wps/wps_upnp.c | 28 ++++++++++++++++++++++++++++ src/wps/wps_upnp_i.h | 2 ++ 2 files changed, 30 insertions(+) diff --git a/src/wps/wps_upnp.c b/src/wps/wps_upnp.c index 410df46..d2b8315 100644 --- a/src/wps/wps_upnp.c +++ b/src/wps/wps_upnp.c @@ -209,6 +209,8 @@ #define MAX_SUBSCRIPTIONS 4 /* how many subscribing clients we handle */ #define MAX_ADDR_PER_SUBSCRIPTION 8 +/* Maximum number of Probe Request events per second */ +#define MAX_EVENTS_PER_SEC 5 /* Write the current date/time per RFC */ void format_date(struct wpabuf *buf) @@ -474,12 +476,38 @@ static void upnp_wps_device_send_event(struct upnp_wps_device_sm *sm) "\n" "\n"; const char *format_tail = "\n"; + struct os_time now; if (dl_list_empty(&sm->subscriptions)) { /* optimize */ return; } + if (os_get_time(&now) == 0) { + if (now.sec != sm->last_event_sec) { + sm->last_event_sec = now.sec; + sm->num_events_in_sec = 1; + } else { + sm->num_events_in_sec++; + /* + * In theory, this should apply to all WLANEvent + * notifications, but EAP messages are of much higher + * priority and Probe Request notifications should not + * be allowed to drop EAP messages, so only throttle + * Probe Request notifications. + */ + if (sm->num_events_in_sec > MAX_EVENTS_PER_SEC && + sm->wlanevent_type == + UPNP_WPS_WLANEVENT_TYPE_PROBE) { + wpa_printf(MSG_DEBUG, "WPS UPnP: Throttle " + "event notifications (%u seen " + "during one second)", + sm->num_events_in_sec); + return; + } + } + } + /* Determine buffer size needed first */ buf_size += os_strlen(format_head); buf_size += 50 + 2 * os_strlen("WLANEvent"); diff --git a/src/wps/wps_upnp_i.h b/src/wps/wps_upnp_i.h index 4143eca..b6e484a 100644 --- a/src/wps/wps_upnp_i.h +++ b/src/wps/wps_upnp_i.h @@ -134,6 +134,8 @@ struct upnp_wps_device_sm { char *wlanevent; /* the last WLANEvent data */ enum upnp_wps_wlanevent_type wlanevent_type; + os_time_t last_event_sec; + unsigned int num_events_in_sec; /* FIX: maintain separate structures for each UPnP peer */ struct upnp_wps_peer peer; -- 2.1.4