diff --git a/src/wps/wps_upnp.c b/src/wps/wps_upnp.c index 410df463a..d2b83155d 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 4143ecad5..b6e484afa 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;