From 33d262398a39bc400401b6d70cfb13f8df3537ca Mon Sep 17 00:00:00 2001 From: vemax78 Date: Sun, 3 Nov 2013 21:52:14 +0100 Subject: [PATCH] Separate close action from generic action list. Now generic action list can execute only if don't wait capwap respone. --- src/ac/ac.h | 5 ---- src/ac/ac_dfa_teardown.c | 8 ------- src/ac/ac_execute.c | 50 ++++++++++++++++++++++++++++++++++++---- src/ac/ac_session.c | 30 +++++++++++------------- src/ac/ac_session.h | 18 +++++++++++---- 5 files changed, 74 insertions(+), 37 deletions(-) diff --git a/src/ac/ac.h b/src/ac/ac.h index 688d7f2..b4436ee 100644 --- a/src/ac/ac.h +++ b/src/ac/ac.h @@ -143,9 +143,4 @@ int ac_execute(void); int ac_valid_binding(unsigned short binding); void ac_update_statistics(void); -int ac_has_sessionid(struct capwap_sessionid_element* sessionid); -int ac_has_wtpid(char* wtpid); -char* ac_get_printable_wtpid(struct capwap_wtpboarddata_element* wtpboarddata); - - #endif /* __CAPWAP_AC_HEADER__ */ diff --git a/src/ac/ac_dfa_teardown.c b/src/ac/ac_dfa_teardown.c index beb1a1c..f8a3182 100644 --- a/src/ac/ac_dfa_teardown.c +++ b/src/ac/ac_dfa_teardown.c @@ -20,11 +20,3 @@ int ac_dfa_state_teardown(struct ac_session_t* session, struct capwap_parsed_pac ac_dfa_change_state(session, CAPWAP_DEAD_STATE); return AC_DFA_DROP_PACKET; } - -/* */ -int ac_dfa_state_dead(struct ac_session_t* session, struct capwap_parsed_packet* packet) { - ASSERT(session != NULL); - ASSERT(packet == NULL); - - return AC_DFA_DEAD; -} diff --git a/src/ac/ac_execute.c b/src/ac/ac_execute.c index 5a9a81b..c2024ec 100644 --- a/src/ac/ac_execute.c +++ b/src/ac/ac_execute.c @@ -160,7 +160,7 @@ static void ac_session_add_packet(struct ac_session_t* session, char* buffer, in } /* Add action to session */ -static void ac_session_send_action(struct ac_session_t* session, long action, long param, void* data, long length) { +void ac_session_send_action(struct ac_session_t* session, long action, long param, void* data, long length) { struct capwap_list_item* item; struct ac_session_action* actionsession; @@ -218,7 +218,7 @@ static struct ac_session_t* ac_search_session_from_wtpaddress(struct sockaddr_st return result; } -/* Find WTP session id */ +/* Find session from session id */ struct ac_session_t* ac_search_session_from_sessionid(struct capwap_sessionid_element* sessionid) { struct ac_session_t* result = NULL; struct capwap_list_item* search; @@ -251,6 +251,39 @@ struct ac_session_t* ac_search_session_from_sessionid(struct capwap_sessionid_el return result; } +/* Find session from wtp id */ +struct ac_session_t* ac_search_session_from_wtpid(const char* wtpid) { + struct ac_session_t* result = NULL; + struct capwap_list_item* search; + + ASSERT(wtpid != NULL); + + capwap_rwlock_rdlock(&g_ac.sessionslock); + + search = g_ac.sessions->first; + while (search != NULL) { + struct ac_session_t* session = (struct ac_session_t*)search->item; + ASSERT(session != NULL); + + if (!strcmp(session->wtpid, wtpid)) { + /* Increment session count */ + capwap_lock_enter(&session->sessionlock); + session->count++; + capwap_lock_exit(&session->sessionlock); + + /* */ + result = session; + break; + } + + search = search->next; + } + + capwap_rwlock_exit(&g_ac.sessionslock); + + return result; +} + /* */ int ac_has_sessionid(struct capwap_sessionid_element* sessionid) { int result = 0; @@ -279,7 +312,7 @@ int ac_has_sessionid(struct capwap_sessionid_element* sessionid) { } /* */ -int ac_has_wtpid(char* wtpid) { +int ac_has_wtpid(const char* wtpid) { int result = 0; struct capwap_list_item* search; @@ -395,6 +428,14 @@ static struct ac_session_t* ac_get_session_from_keepalive(void* buffer, int buff return result; } +/* */ +void ac_session_close(struct ac_session_t* session) { + capwap_lock_enter(&session->sessionlock); + session->running = 0; + capwap_event_signal(&session->waitpacket); + capwap_lock_exit(&session->sessionlock); +} + /* Close sessions */ static void ac_close_sessions() { struct capwap_list_item* search; @@ -406,7 +447,7 @@ static void ac_close_sessions() { struct ac_session_t* session = (struct ac_session_t*)search->item; ASSERT(session != NULL); - ac_session_send_action(session, AC_SESSION_ACTION_CLOSE, 0, NULL, 0); + ac_session_close(session); search = search->next; } @@ -548,6 +589,7 @@ static struct ac_session_t* ac_create_session(struct sockaddr_storage* wtpaddres memset(session, 0, sizeof(struct ac_session_t)); session->itemlist = itemlist; + session->running = 1; session->count = 2; memcpy(&session->acctrladdress, acaddress, sizeof(struct sockaddr_storage)); memcpy(&session->wtpctrladdress, wtpaddress, sizeof(struct sockaddr_storage)); diff --git a/src/ac/ac_session.c b/src/ac/ac_session.c index 3444448..6fdd0c7 100644 --- a/src/ac/ac_session.c +++ b/src/ac/ac_session.c @@ -12,12 +12,14 @@ static int ac_session_action_execute(struct ac_session_t* session, struct ac_session_action* action) { int result = ACTION_SESSION; + /* switch (action->action) { case AC_SESSION_ACTION_CLOSE: { result = DTLS_SHUTDOWN; break; } } + */ return result; } @@ -36,7 +38,9 @@ static int ac_network_read(struct ac_session_t* session, void* buffer, int lengt for (;;) { capwap_lock_enter(&session->sessionlock); - if (session->actionsession->count > 0) { + if (!session->running) { + return DTLS_SHUTDOWN; + } else if (!session->waitresponse && (session->actionsession->count > 0)) { struct capwap_list_item* itemaction; itemaction = capwap_itemlist_remove_head(session->actionsession); @@ -253,12 +257,7 @@ static int ac_dfa_execute(struct ac_session_t* session, struct capwap_parsed_pac ASSERT(0); break; } - - case CAPWAP_DTLS_TEARDOWN_STATE: { - action = ac_dfa_state_teardown(session, packet); - break; - } - + case CAPWAP_DTLS_TEARDOWN_TO_IDLE_STATE: { /* Never called with this state */ ASSERT(0); @@ -381,12 +380,7 @@ static int ac_dfa_execute(struct ac_session_t* session, struct capwap_parsed_pac action = ac_dfa_state_run_to_reset(session, packet); break; } - - case CAPWAP_DEAD_STATE: { - action = ac_dfa_state_dead(session, packet); - break; - } - + default: { capwap_logging_debug("Unknown action event: %lu", session->state); break; @@ -564,8 +558,8 @@ static void ac_session_run(struct ac_session_t* session) { ac_dfa_change_state(session, CAPWAP_JOIN_STATE); capwap_set_timeout(session->dfa.rfcWaitJoin, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION); } - - while (action != AC_DFA_DEAD) { + + while (session->state != CAPWAP_DTLS_TEARDOWN_STATE) { /* Get packet */ if ((action == AC_DFA_ACCEPT_PACKET) || (action == AC_DFA_DROP_PACKET)) { length = ac_network_read(session, buffer, sizeof(buffer), &isctrlsocket, &session->timeout); @@ -573,7 +567,7 @@ static void ac_session_run(struct ac_session_t* session) { if (length == PACKET_TIMEOUT) { action = ac_dfa_execute(session, NULL); /* Timeout */ } else if (length == DTLS_SHUTDOWN) { - action = ac_session_teardown_connection(session); + ac_session_teardown_connection(session); } else if (length == ACTION_SESSION) { /* Nothing */ } @@ -664,6 +658,10 @@ static void ac_session_run(struct ac_session_t* session) { } } + /* Wait teardown timeout before kill session */ + capwap_wait_timeout(&session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION); + ac_dfa_state_teardown(session, NULL); + /* Release reference session */ ac_session_destroy(session); } diff --git a/src/ac/ac_session.h b/src/ac/ac_session.h index 768ce90..950b37c 100644 --- a/src/ac/ac_session.h +++ b/src/ac/ac_session.h @@ -11,9 +11,6 @@ #define AC_DFA_DROP_PACKET 2 #define AC_DFA_DEAD 3 -/* */ -#define AC_SESSION_ACTION_CLOSE 0 - /* AC packet */ struct ac_packet { int plainbuffer; @@ -44,6 +41,8 @@ struct ac_session_t { /* */ char* wtpid; + int running; + int waitresponse; unsigned long count; struct sockaddr_storage acctrladdress; @@ -86,8 +85,20 @@ struct ac_session_t { /* */ void* ac_session_thread(void* param); +void ac_session_send_action(struct ac_session_t* session, long action, long param, void* data, long length); + +/* */ +int ac_has_sessionid(struct capwap_sessionid_element* sessionid); struct ac_session_t* ac_search_session_from_sessionid(struct capwap_sessionid_element* sessionid); +int ac_has_wtpid(const char* wtpid); +struct ac_session_t* ac_search_session_from_wtpid(const char* wtpid); + +/* */ +char* ac_get_printable_wtpid(struct capwap_wtpboarddata_element* wtpboarddata); + +/* */ int ac_session_teardown_connection(struct ac_session_t* session); +void ac_session_close(struct ac_session_t* session); void ac_session_release_reference(struct ac_session_t* session); /* */ @@ -140,7 +151,6 @@ int ac_dfa_state_reset_to_dtlsteardown(struct ac_session_t* session, struct capw /* */ int ac_dfa_state_teardown(struct ac_session_t* session, struct capwap_parsed_packet* packet); -int ac_dfa_state_dead(struct ac_session_t* session, struct capwap_parsed_packet* packet); /* Soap function */ struct ac_soap_response* ac_session_send_soap_request(struct ac_session_t* session, char* method, int numparam, ...);