Rejects the join with the same identifier of the WTP
This commit is contained in:
parent
99b6373cd7
commit
75dcf51496
@ -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__ */
|
||||
|
@ -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));
|
||||
/* 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;
|
||||
}
|
||||
|
@ -56,6 +56,66 @@ static struct ac_session_t* ac_search_session_from_wtpaddress(struct sockaddr_st
|
||||
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;
|
||||
}
|
||||
|
||||
/* */
|
||||
static struct ac_session_t* ac_get_session_from_keepalive(void* buffer, int buffersize) {
|
||||
struct capwap_parsed_packet packet;
|
||||
|
@ -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));
|
||||
|
@ -24,6 +24,9 @@ struct ac_session_control {
|
||||
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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
Loading…
Reference in New Issue
Block a user