diff --git a/src/ac/ac_session.c b/src/ac/ac_session.c index 890e5ae..b90d3d9 100644 --- a/src/ac/ac_session.c +++ b/src/ac/ac_session.c @@ -48,6 +48,11 @@ static int ac_network_read(struct ac_session_t* session, void* buffer, int lengt /* Free packet */ capwap_itemlist_free(itemaction); return result; + } else if (session->teardown) { + /* Remove all pending packets, connection is teardown */ + while ((session->controlpackets->count > 0) || (session->datapackets->count > 0)) { + capwap_itemlist_free(capwap_itemlist_remove_head(((session->controlpackets->count > 0) ? session->controlpackets : session->datapackets))); + } } else if ((session->controlpackets->count > 0) || (session->datapackets->count > 0)) { struct capwap_list_item* itempacket; @@ -109,7 +114,7 @@ static int ac_network_read(struct ac_session_t* session, void* buffer, int lengt if ((waittimeout <= 0) && (indextimer != CAPWAP_TIMER_UNDEF)) { return PACKET_TIMEOUT; } - + /* Wait packet */ capwap_event_wait_timeout(&session->waitpacket, waittimeout); } @@ -616,6 +621,9 @@ void ac_dfa_change_state(struct ac_session_t* session, int state) { int ac_session_teardown_connection(struct ac_session_t* session) { ASSERT(session != NULL); + /* */ + session->teardown = 1; + /* Close DTSL Control */ if (session->ctrldtls.enable) { capwap_crypt_close(&session->ctrldtls); @@ -663,6 +671,10 @@ int ac_session_release_reference(struct ac_session_t* session) { capwap_crypt_freesession(&session->datadtls); /* Free resource */ + while ((session->controlpackets->count > 0) || (session->datapackets->count > 0)) { + capwap_itemlist_free(capwap_itemlist_remove_head(((session->controlpackets->count > 0) ? session->controlpackets : session->datapackets))); + } + capwap_event_destroy(&session->waitpacket); capwap_lock_exit(&session->sessionlock); capwap_list_free(session->actionsession); diff --git a/src/ac/ac_session.h b/src/ac/ac_session.h index 2601b87..2e05cde 100644 --- a/src/ac/ac_session.h +++ b/src/ac/ac_session.h @@ -54,6 +54,7 @@ struct ac_session_t { struct capwap_sessionid_element sessionid; unsigned short binding; + int teardown; struct capwap_dtls ctrldtls; struct capwap_dtls datadtls; diff --git a/src/wtp/wtp.h b/src/wtp/wtp.h index 1db7fad..79899d5 100644 --- a/src/wtp/wtp.h +++ b/src/wtp/wtp.h @@ -132,6 +132,7 @@ struct wtp_t { struct capwap_dtls_context dtlscontext; struct capwap_dtls ctrldtls; struct capwap_dtls datadtls; + int teardown; }; #define WTP_RADIO_ENABLED 0 diff --git a/src/wtp/wtp_dfa.c b/src/wtp/wtp_dfa.c index ee0f527..fcc8c23 100644 --- a/src/wtp/wtp_dfa.c +++ b/src/wtp/wtp_dfa.c @@ -387,7 +387,7 @@ int wtp_dfa_running(void) { } if (index >= 0) { - if (action == WTP_DFA_DROP_PACKET) { + if ((action == WTP_DFA_DROP_PACKET) || g_wtp.teardown) { /* Drop packet */ continue; } else { diff --git a/src/wtp/wtp_dfa_dtls.c b/src/wtp/wtp_dfa_dtls.c index efa6c59..883dae3 100644 --- a/src/wtp/wtp_dfa_dtls.c +++ b/src/wtp/wtp_dfa_dtls.c @@ -56,6 +56,8 @@ int wtp_dfa_state_dtlsconnect_to_dtlsteardown(struct capwap_parsed_packet* packe int wtp_teardown_connection(struct timeout_control* timeout) { ASSERT(timeout != NULL); + g_wtp.teardown = 1; + /* DTSL Control */ if (g_wtp.ctrldtls.enable) { capwap_crypt_close(&g_wtp.ctrldtls); diff --git a/src/wtp/wtp_dfa_idle.c b/src/wtp/wtp_dfa_idle.c index 76cbec0..db4a5a2 100644 --- a/src/wtp/wtp_dfa_idle.c +++ b/src/wtp/wtp_dfa_idle.c @@ -6,7 +6,10 @@ int wtp_dfa_state_idle(struct capwap_parsed_packet* packet, struct timeout_control* timeout) { ASSERT(timeout != NULL); ASSERT(packet == NULL); - + + /* Remove teardown flag */ + g_wtp.teardown = 0; + if (!g_wtp.acdiscoveryrequest && (g_wtp.acpreferedarray->count > 0)) { /* Found in configuration file the AC address */ memcpy(&g_wtp.acctrladdress, capwap_array_get_item_pointer(g_wtp.acpreferedarray, g_wtp.acpreferedselected), sizeof(struct sockaddr_storage));