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);
|
int ac_valid_binding(unsigned short binding);
|
||||||
void ac_update_statistics(void);
|
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__ */
|
#endif /* __CAPWAP_AC_HEADER__ */
|
||||||
|
@ -8,6 +8,9 @@ int ac_dfa_state_join(struct ac_session_t* session, struct capwap_parsed_packet*
|
|||||||
int i;
|
int i;
|
||||||
struct capwap_header_data capwapheader;
|
struct capwap_header_data capwapheader;
|
||||||
struct capwap_packet_txmng* txmngpacket;
|
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;
|
int status = AC_DFA_ACCEPT_PACKET;
|
||||||
struct capwap_resultcode_element resultcode = { .code = CAPWAP_RESULTCODE_FAILURE };
|
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);
|
binding = GET_WBID_HEADER(packet->rxmngpacket->header);
|
||||||
if (ac_valid_binding(binding)) {
|
if (ac_valid_binding(binding)) {
|
||||||
if (packet->rxmngpacket->ctrlmsg.type == CAPWAP_JOIN_REQUEST) {
|
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 */
|
/* Valid session id */
|
||||||
memcpy(&session->sessionid, capwap_get_message_element_data(packet, CAPWAP_ELEMENT_SESSIONID), sizeof(struct capwap_sessionid_element));
|
memcpy(&session->sessionid, sessionid, sizeof(struct capwap_sessionid_element));
|
||||||
|
|
||||||
/* Get binding */
|
/* Get binding */
|
||||||
session->binding = 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 {
|
} else {
|
||||||
resultcode.code = CAPWAP_RESULTCODE_MSG_UNEXPECTED_INVALID_CURRENT_STATE;
|
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;
|
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) {
|
static struct ac_session_t* ac_get_session_from_keepalive(void* buffer, int buffersize) {
|
||||||
struct capwap_parsed_packet packet;
|
struct capwap_parsed_packet packet;
|
||||||
|
@ -568,6 +568,14 @@ int ac_session_release_reference(struct ac_session_t* session) {
|
|||||||
while (search != NULL) {
|
while (search != NULL) {
|
||||||
struct ac_session_t* item = (struct ac_session_t*)search->item;
|
struct ac_session_t* item = (struct ac_session_t*)search->item;
|
||||||
if (session == 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 */
|
/* Free DTSL Control */
|
||||||
capwap_crypt_freesession(&session->ctrldtls);
|
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.acipv4list.addresses);
|
||||||
capwap_array_free(session->dfa.acipv6list.addresses);
|
capwap_array_free(session->dfa.acipv6list.addresses);
|
||||||
|
|
||||||
|
if (session->wtpid) {
|
||||||
|
capwap_free(session->wtpid);
|
||||||
|
}
|
||||||
|
|
||||||
/* Remove item from list */
|
/* Remove item from list */
|
||||||
remove = 1;
|
remove = 1;
|
||||||
capwap_itemlist_free(capwap_itemlist_remove(g_ac.sessions, search));
|
capwap_itemlist_free(capwap_itemlist_remove(g_ac.sessions, search));
|
||||||
|
@ -24,6 +24,9 @@ struct ac_session_control {
|
|||||||
struct ac_session_t {
|
struct ac_session_t {
|
||||||
struct ac_state dfa;
|
struct ac_state dfa;
|
||||||
|
|
||||||
|
unsigned char* wtpid;
|
||||||
|
unsigned short wtpidlength;
|
||||||
|
|
||||||
unsigned long count;
|
unsigned long count;
|
||||||
struct sockaddr_storage acctrladdress;
|
struct sockaddr_storage acctrladdress;
|
||||||
struct sockaddr_storage acdataaddress;
|
struct sockaddr_storage acdataaddress;
|
||||||
|
@ -140,3 +140,22 @@ struct capwap_message_elements_ops capwap_element_wtpboarddata_ops = {
|
|||||||
.parsing_message_element = capwap_wtpboarddata_element_parsing,
|
.parsing_message_element = capwap_wtpboarddata_element_parsing,
|
||||||
.free_parsed_message_element = capwap_wtpboarddata_element_free
|
.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;
|
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__ */
|
#endif /* __CAPWAP_ELEMENT_WTPBOARDDATA_HEADER__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user