Rejects the join with the same identifier of the WTP

This commit is contained in:
vemax78 2013-06-18 22:38:56 +02:00
parent 99b6373cd7
commit 75dcf51496
7 changed files with 135 additions and 13 deletions

View File

@ -115,4 +115,8 @@ 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(unsigned char* id, unsigned short length);
#endif /* __CAPWAP_AC_HEADER__ */

View File

@ -8,6 +8,9 @@ int ac_dfa_state_join(struct ac_session_t* session, struct capwap_parsed_packet*
int i;
struct capwap_header_data capwapheader;
struct capwap_packet_txmng* txmngpacket;
struct capwap_sessionid_element* sessionid;
struct capwap_wtpboarddata_element* wtpboarddata;
struct capwap_wtpboarddata_board_subelement* wtpboarddatamacaddress;
int status = AC_DFA_ACCEPT_PACKET;
struct capwap_resultcode_element resultcode = { .code = CAPWAP_RESULTCODE_FAILURE };
@ -20,13 +23,31 @@ int ac_dfa_state_join(struct ac_session_t* session, struct capwap_parsed_packet*
binding = GET_WBID_HEADER(packet->rxmngpacket->header);
if (ac_valid_binding(binding)) {
if (packet->rxmngpacket->ctrlmsg.type == CAPWAP_JOIN_REQUEST) {
resultcode.code = CAPWAP_RESULTCODE_SUCCESS;
/* Get sessionid and verify unique id */
sessionid = (struct capwap_sessionid_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_SESSIONID);
if (!ac_has_sessionid(sessionid)) {
/* Checking macaddress for detect if WTP already connected */
wtpboarddata = (struct capwap_wtpboarddata_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_WTPBOARDDATA);
wtpboarddatamacaddress = capwap_wtpboarddata_get_subelement(wtpboarddata, CAPWAP_BOARD_SUBELEMENT_MACADDRESS);
if (wtpboarddatamacaddress && !ac_has_wtpid((unsigned char*)wtpboarddatamacaddress->data, (unsigned short)wtpboarddatamacaddress->length)) {
/* Valid WTP id */
session->wtpid = capwap_clone(wtpboarddatamacaddress->data, wtpboarddatamacaddress->length);
session->wtpidlength = wtpboarddatamacaddress->length;
/* Get sessionid */
memcpy(&session->sessionid, capwap_get_message_element_data(packet, CAPWAP_ELEMENT_SESSIONID), sizeof(struct capwap_sessionid_element));
/* Get binding */
session->binding = binding;
/* Valid session id */
memcpy(&session->sessionid, sessionid, sizeof(struct capwap_sessionid_element));
/* Get binding */
session->binding = binding;
/* Valid Join */
resultcode.code = CAPWAP_RESULTCODE_SUCCESS;
} else {
resultcode.code = CAPWAP_RESULTCODE_JOIN_FAILURE_UNKNOWN_SOURCE;
}
} else {
resultcode.code = CAPWAP_RESULTCODE_JOIN_FAILURE_ID_ALREADY_IN_USE;
}
} else {
resultcode.code = CAPWAP_RESULTCODE_MSG_UNEXPECTED_INVALID_CURRENT_STATE;
}

View File

@ -32,11 +32,11 @@ static void ac_session_add_packet(struct ac_session_t* session, char* buffer, in
static struct ac_session_t* ac_search_session_from_wtpaddress(struct sockaddr_storage* address, int isctrlsocket) {
struct ac_session_t* result = NULL;
struct capwap_list_item* search;
ASSERT(address != NULL);
capwap_lock_enter(&g_ac.sessionslock);
search = g_ac.sessions->first;
while (search != NULL) {
struct ac_session_t* session = (struct ac_session_t*)search->item;
@ -47,12 +47,72 @@ static struct ac_session_t* ac_search_session_from_wtpaddress(struct sockaddr_st
result = session;
break;
}
search = search->next;
}
capwap_lock_exit(&g_ac.sessionslock);
return result;
}
/* */
int ac_has_sessionid(struct capwap_sessionid_element* sessionid) {
int result = 0;
struct capwap_list_item* search;
ASSERT(sessionid != NULL);
capwap_lock_enter(&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 (!memcmp(sessionid, &session->sessionid, sizeof(struct capwap_sessionid_element))) {
result = 1;
break;
}
search = search->next;
}
capwap_lock_exit(&g_ac.sessionslock);
return result;
}
/* */
int ac_has_wtpid(unsigned char* wtpid, unsigned short length) {
int result = 0;
struct capwap_list_item* search;
if (!wtpid || !length) {
return -1;
}
capwap_lock_enter(&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 (session->wtpidlength == length) {
if (!memcmp(wtpid, session->wtpid, length)) {
result = 1;
break;
}
}
search = search->next;
}
capwap_lock_exit(&g_ac.sessionslock);
return result;
}

View File

@ -568,6 +568,14 @@ int ac_session_release_reference(struct ac_session_t* session) {
while (search != NULL) {
struct ac_session_t* item = (struct ac_session_t*)search->item;
if (session == item) {
#ifdef DEBUG
char sessionname[33];
/* */
capwap_sessionid_printf(&session->sessionid, sessionname);
capwap_logging_debug("Release Session AC %s", sessionname);
#endif
/* Free DTSL Control */
capwap_crypt_freesession(&session->ctrldtls);
@ -591,6 +599,10 @@ int ac_session_release_reference(struct ac_session_t* session) {
capwap_array_free(session->dfa.acipv4list.addresses);
capwap_array_free(session->dfa.acipv6list.addresses);
if (session->wtpid) {
capwap_free(session->wtpid);
}
/* Remove item from list */
remove = 1;
capwap_itemlist_free(capwap_itemlist_remove(g_ac.sessions, search));

View File

@ -23,7 +23,10 @@ struct ac_session_control {
/* AC sessions */
struct ac_session_t {
struct ac_state dfa;
unsigned char* wtpid;
unsigned short wtpidlength;
unsigned long count;
struct sockaddr_storage acctrladdress;
struct sockaddr_storage acdataaddress;

View File

@ -140,3 +140,22 @@ struct capwap_message_elements_ops capwap_element_wtpboarddata_ops = {
.parsing_message_element = capwap_wtpboarddata_element_parsing,
.free_parsed_message_element = capwap_wtpboarddata_element_free
};
/* */
struct capwap_wtpboarddata_board_subelement* capwap_wtpboarddata_get_subelement(struct capwap_wtpboarddata_element* wtpboarddata, int subelement) {
int i;
ASSERT(wtpboarddata != NULL);
ASSERT((subelement >= CAPWAP_BOARD_SUBELEMENT_TYPE_FIRST) && (subelement <= CAPWAP_BOARD_SUBELEMENT_TYPE_LAST));
/* */
for (i = 0; i < wtpboarddata->boardsubelement->count; i++) {
struct capwap_wtpboarddata_board_subelement* desc = (struct capwap_wtpboarddata_board_subelement*)capwap_array_get_item_pointer(wtpboarddata->boardsubelement, i);
if (desc->type == subelement) {
return desc;
}
}
return NULL;
}

View File

@ -26,4 +26,7 @@ struct capwap_wtpboarddata_board_subelement {
extern struct capwap_message_elements_ops capwap_element_wtpboarddata_ops;
/* Helper function */
struct capwap_wtpboarddata_board_subelement* capwap_wtpboarddata_get_subelement(struct capwap_wtpboarddata_element* wtpboarddata, int subelement);
#endif /* __CAPWAP_ELEMENT_WTPBOARDDATA_HEADER__ */