Improve memory administration for tx/rx packet manager
This commit is contained in:
18
src/ac/ac.c
18
src/ac/ac.c
@ -22,11 +22,11 @@ static int ac_init(void) {
|
||||
g_ac.binding = capwap_array_create(sizeof(unsigned short), 0);
|
||||
|
||||
/* Standard name */
|
||||
strcpy(g_ac.acname.name, AC_STANDARD_NAME);
|
||||
strcpy((char*)g_ac.acname.name, AC_STANDARD_NAME);
|
||||
|
||||
/* Descriptor */
|
||||
g_ac.descriptor.stationlimit = AC_DEFAULT_MAXSTATION;
|
||||
g_ac.descriptor.wtplimit = AC_DEFAULT_MAXSESSIONS;
|
||||
g_ac.descriptor.maxwtp = AC_DEFAULT_MAXSESSIONS;
|
||||
g_ac.descriptor.security = 0;
|
||||
g_ac.descriptor.rmacfield = CAPWAP_ACDESC_RMACFIELD_NOTSUPPORTED;
|
||||
g_ac.descriptor.dtlspolicy = CAPWAP_ACDESC_CLEAR_DATA_CHANNEL_ENABLED;
|
||||
@ -44,8 +44,8 @@ static int ac_init(void) {
|
||||
g_ac.dfa.wtpfallback.mode = AC_DEFAULT_WTP_FALLBACK_MODE;
|
||||
|
||||
/* */
|
||||
g_ac.dfa.acipv4list = capwap_array_create(sizeof(struct capwap_acipv4list_element), 0);
|
||||
g_ac.dfa.acipv6list = capwap_array_create(sizeof(struct capwap_acipv6list_element), 0);
|
||||
g_ac.dfa.acipv4list.addresses = capwap_array_create(sizeof(struct in_addr), 0);
|
||||
g_ac.dfa.acipv6list.addresses = capwap_array_create(sizeof(struct in6_addr), 0);
|
||||
|
||||
/* */
|
||||
g_ac.dfa.rfcWaitJoin = AC_DEFAULT_WAITJOIN_INTERVAL;
|
||||
@ -72,8 +72,8 @@ static void ac_destroy(void) {
|
||||
capwap_array_free(g_ac.binding);
|
||||
|
||||
/* */
|
||||
capwap_array_free(g_ac.dfa.acipv4list);
|
||||
capwap_array_free(g_ac.dfa.acipv6list);
|
||||
capwap_array_free(g_ac.dfa.acipv4list.addresses);
|
||||
capwap_array_free(g_ac.dfa.acipv6list.addresses);
|
||||
|
||||
/* Sessions */
|
||||
capwap_list_free(g_ac.sessions);
|
||||
@ -152,7 +152,7 @@ static int ac_parsing_configuration_1_0(config_t* config) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
strcpy(g_ac.acname.name, configString);
|
||||
strcpy((char*)g_ac.acname.name, configString);
|
||||
}
|
||||
|
||||
/* Set binding of AC */
|
||||
@ -190,7 +190,7 @@ static int ac_parsing_configuration_1_0(config_t* config) {
|
||||
/* Set max wtp of AC */
|
||||
if (config_lookup_int(config, "application.descriptor.maxwtp", &configLongInt) == CONFIG_TRUE) {
|
||||
if ((configLongInt > 0) && (configLongInt < 65536)) {
|
||||
g_ac.descriptor.wtplimit = (unsigned short)configLongInt;
|
||||
g_ac.descriptor.maxwtp = (unsigned short)configLongInt;
|
||||
} else {
|
||||
capwap_logging_error("Invalid configuration file, unknown application.descriptor.maxwtp value");
|
||||
return 0;
|
||||
@ -266,7 +266,7 @@ static int ac_parsing_configuration_1_0(config_t* config) {
|
||||
desc->vendor = (unsigned long)configVendor;
|
||||
desc->type = type;
|
||||
desc->length = lengthValue;
|
||||
strcpy(desc->data, configValue);
|
||||
strcpy((char*)desc->data, configValue);
|
||||
} else {
|
||||
capwap_logging_error("Invalid configuration file, application.descriptor.info.value string length exceeded");
|
||||
return 0;
|
||||
|
@ -55,8 +55,8 @@ struct ac_state {
|
||||
struct capwap_wtpfallback_element wtpfallback;
|
||||
|
||||
/* */
|
||||
capwap_acipv4list_element_array* acipv4list;
|
||||
capwap_acipv6list_element_array* acipv6list;
|
||||
struct capwap_acipv4list_element acipv4list;
|
||||
struct capwap_acipv6list_element acipv6list;
|
||||
|
||||
/* */
|
||||
int rfcWaitJoin;
|
||||
|
@ -4,115 +4,73 @@
|
||||
#include "ac_session.h"
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_configure(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
int ac_dfa_state_configure(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
unsigned long i;
|
||||
unsigned short binding;
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
int status = AC_DFA_ACCEPT_PACKET;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
|
||||
if (packet) {
|
||||
struct capwap_build_packet* buildpacket;
|
||||
|
||||
buildpacket = capwap_rx_packet_create((void*)packet->header, packet->packetsize, packet->socket.isctrlsocket);
|
||||
if (buildpacket) {
|
||||
if (!capwap_build_packet_validate(buildpacket, NULL)) {
|
||||
unsigned short binding;
|
||||
binding = GET_WBID_HEADER(packet->rxmngpacket->header);
|
||||
/* TODO: gestione richiesta */
|
||||
|
||||
/* */
|
||||
binding = GET_WBID_HEADER(&buildpacket->header);
|
||||
if (ac_valid_binding(binding) && (ntohl(buildpacket->ctrlmsg.type) == CAPWAP_CONFIGURATION_STATUS_REQUEST) && IS_SEQUENCE_SMALLER(session->remoteseqnumber, buildpacket->ctrlmsg.seq)) {
|
||||
struct capwap_element_configurationstatus_request configurationstatusrequest;
|
||||
|
||||
/* Configuration Status request info*/
|
||||
capwap_init_element_configurationstatus_request(&configurationstatusrequest, binding);
|
||||
|
||||
/* Parsing elements list */
|
||||
if (capwap_parsing_element_configurationstatus_request(&configurationstatusrequest, buildpacket->elementslist->first)) {
|
||||
struct capwap_build_packet* responsepacket;
|
||||
/* Create response */
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, binding);
|
||||
txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_CONFIGURATION_STATUS_RESPONSE, packet->rxmngpacket->ctrlmsg.seq, session->mtu);
|
||||
|
||||
/* TODO: gestione richiesta */
|
||||
/* Add message element */
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_TIMERS, &session->dfa.timers);
|
||||
|
||||
/* Create response */
|
||||
responsepacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, binding);
|
||||
responsepacket->isctrlmsg = 1;
|
||||
for (i = 0; i < packet->messageelements.radioadmstate->count; i++) {
|
||||
struct capwap_decrypterrorreportperiod_element report;
|
||||
struct capwap_radioadmstate_element* radioadm = *(struct capwap_radioadmstate_element**)capwap_array_get_item_pointer(packet->messageelements.radioadmstate, i);
|
||||
|
||||
/* Prepare configuration status response */
|
||||
capwap_build_packet_set_control_message_type(responsepacket, CAPWAP_CONFIGURATION_STATUS_RESPONSE, buildpacket->ctrlmsg.seq);
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_TIMERS_ELEMENT(&session->dfa.timers));
|
||||
|
||||
for (i = 0; i < configurationstatusrequest.radioadmstatus->count; i++) {
|
||||
struct capwap_decrypterrorreportperiod_element report;
|
||||
struct capwap_radioadmstate_element* radioadm = (struct capwap_radioadmstate_element*)capwap_array_get_item_pointer(configurationstatusrequest.radioadmstatus, i);
|
||||
|
||||
report.radioid = radioadm->radioid;
|
||||
report.interval = session->dfa.decrypterrorreport_interval;
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_DECRYPTERRORREPORTPERIOD_ELEMENT(&report));
|
||||
}
|
||||
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_IDLETIMEOUT_ELEMENT(&session->dfa.idletimeout));
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_WTPFALLBACK_ELEMENT(&session->dfa.wtpfallback));
|
||||
|
||||
if (session->dfa.acipv4list->count > 0) {
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_ACIPV4LIST_ELEMENT(session->dfa.acipv4list));
|
||||
}
|
||||
|
||||
if (session->dfa.acipv6list->count > 0) {
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_ACIPV6LIST_ELEMENT(session->dfa.acipv6list));
|
||||
}
|
||||
|
||||
/* CAPWAP_CREATE_RADIOOPRSTATE_ELEMENT */ /* TODO */
|
||||
/* CAPWAP_CREATE_WTPSTATICIPADDRESS_ELEMENT */ /* TODO */
|
||||
/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */ /* TODO */
|
||||
|
||||
if (!capwap_build_packet_validate(responsepacket, NULL)) {
|
||||
int result;
|
||||
|
||||
/* Free old reference for this request */
|
||||
ac_free_reference_last_response(session);
|
||||
|
||||
/* Send configuration status response to WTP */
|
||||
result = capwap_fragment_build_packet(responsepacket, session->responsefragmentpacket, session->mtu, session->fragmentid);
|
||||
if (result >= 0) {
|
||||
if (result == 1) {
|
||||
session->fragmentid++;
|
||||
}
|
||||
|
||||
/* Save remote sequence number */
|
||||
session->remoteseqnumber = buildpacket->ctrlmsg.seq;
|
||||
capwap_get_packet_digest((void*)packet->header, packet->packetsize, session->lastrecvpackethash);
|
||||
|
||||
/* Send */
|
||||
for (i = 0; i < session->responsefragmentpacket->count; i++) {
|
||||
struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(session->responsefragmentpacket, i);
|
||||
ASSERT(txpacket != NULL);
|
||||
|
||||
if (!capwap_crypt_sendto(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], txpacket->header, txpacket->packetsize, &session->acctrladdress, &session->wtpctrladdress)) {
|
||||
/* Response is already created and saved. When receive a re-request, DFA autoresponse */
|
||||
capwap_logging_debug("Warning: error to send configuration status response packet");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Change status */
|
||||
ac_dfa_change_state(session, CAPWAP_DATA_CHECK_STATE);
|
||||
capwap_set_timeout(session->dfa.rfcChangeStatePendingTimer, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
}
|
||||
} else {
|
||||
capwap_logging_debug("Warning: build invalid configuration status response packet");
|
||||
}
|
||||
|
||||
/* Free memory */
|
||||
capwap_build_packet_free(responsepacket);
|
||||
}
|
||||
|
||||
/* Free */
|
||||
capwap_free_element_configurationstatus_request(&configurationstatusrequest, binding);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free */
|
||||
capwap_build_packet_free(buildpacket);
|
||||
report.radioid = radioadm->radioid;
|
||||
report.interval = session->dfa.decrypterrorreport_interval;
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_DECRYPTERRORREPORTPERIOD, &report);
|
||||
}
|
||||
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_IDLETIMEOUT, &session->dfa.idletimeout);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_WTPFALLBACK, &session->dfa.wtpfallback);
|
||||
|
||||
if (session->dfa.acipv4list.addresses->count > 0) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACIPV4LIST, &session->dfa.acipv4list);
|
||||
}
|
||||
|
||||
if (session->dfa.acipv6list.addresses->count > 0) {
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACIPV6LIST, &session->dfa.acipv6list);
|
||||
}
|
||||
|
||||
/* CAPWAP_CREATE_RADIOOPRSTATE_ELEMENT */ /* TODO */
|
||||
/* CAPWAP_CREATE_WTPSTATICIPADDRESS_ELEMENT */ /* TODO */
|
||||
/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */ /* TODO */
|
||||
|
||||
/* Configure response complete, get fragment packets */
|
||||
ac_free_reference_last_response(session);
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, session->responsefragmentpacket, session->fragmentid);
|
||||
if (session->responsefragmentpacket->count > 1) {
|
||||
session->fragmentid++;
|
||||
}
|
||||
|
||||
/* Free packets manager */
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
|
||||
/* Save remote sequence number */
|
||||
session->remoteseqnumber = packet->rxmngpacket->ctrlmsg.seq;
|
||||
capwap_get_packet_digest(packet->rxmngpacket, packet->connection, session->lastrecvpackethash);
|
||||
|
||||
/* Send Configure response to WTP */
|
||||
if (!capwap_crypt_sendto_fragmentpacket(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], session->responsefragmentpacket, &session->acctrladdress, &session->wtpctrladdress)) {
|
||||
/* Response is already created and saved. When receive a re-request, DFA autoresponse */
|
||||
capwap_logging_debug("Warning: error to send configuration status response packet");
|
||||
}
|
||||
|
||||
/* Change state */
|
||||
ac_dfa_change_state(session, CAPWAP_DATA_CHECK_STATE);
|
||||
capwap_set_timeout(session->dfa.rfcChangeStatePendingTimer, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
} else {
|
||||
/* Configure timeout */
|
||||
ac_dfa_change_state(session, CAPWAP_CONFIGURE_TO_DTLS_TEARDOWN_STATE);
|
||||
@ -123,6 +81,6 @@ int ac_dfa_state_configure(struct ac_session_t* session, struct capwap_packet* p
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_configure_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
int ac_dfa_state_configure_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
return ac_session_teardown_connection(session);
|
||||
}
|
||||
|
@ -4,91 +4,48 @@
|
||||
#include "ac_session.h"
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_datacheck(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
unsigned long i;
|
||||
int ac_dfa_state_datacheck(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
unsigned short binding;
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
int status = AC_DFA_ACCEPT_PACKET;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
|
||||
if (packet) {
|
||||
struct capwap_build_packet* buildpacket;
|
||||
|
||||
buildpacket = capwap_rx_packet_create((void*)packet->header, packet->packetsize, packet->socket.isctrlsocket);
|
||||
if (buildpacket) {
|
||||
if (!capwap_build_packet_validate(buildpacket, NULL)) {
|
||||
unsigned short binding;
|
||||
binding = GET_WBID_HEADER(packet->rxmngpacket->header);
|
||||
/* TODO: gestione richiesta */
|
||||
|
||||
/* */
|
||||
binding = GET_WBID_HEADER(&buildpacket->header);
|
||||
if (ac_valid_binding(binding) && (ntohl(buildpacket->ctrlmsg.type) == CAPWAP_CHANGE_STATE_EVENT_REQUEST) && IS_SEQUENCE_SMALLER(session->remoteseqnumber, buildpacket->ctrlmsg.seq)) {
|
||||
struct capwap_element_changestateevent_request changeeventrequest;
|
||||
|
||||
/* Change event request info */
|
||||
capwap_init_element_changestateevent_request(&changeeventrequest, binding);
|
||||
|
||||
/* Parsing elements list */
|
||||
if (capwap_parsing_element_changestateevent_request(&changeeventrequest, buildpacket->elementslist->first)) {
|
||||
struct capwap_build_packet* responsepacket;
|
||||
/* Create response */
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, binding);
|
||||
txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_CHANGE_STATE_EVENT_RESPONSE, packet->rxmngpacket->ctrlmsg.seq, session->mtu);
|
||||
|
||||
/* TODO: gestione richiesta */
|
||||
/* Add message element */
|
||||
/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */ /* TODO */
|
||||
|
||||
/* Create response */
|
||||
responsepacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, binding);
|
||||
responsepacket->isctrlmsg = 1;
|
||||
|
||||
/* Prepare change event response */
|
||||
capwap_build_packet_set_control_message_type(responsepacket, CAPWAP_CHANGE_STATE_EVENT_RESPONSE, buildpacket->ctrlmsg.seq);
|
||||
/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */ /* TODO */
|
||||
|
||||
if (!capwap_build_packet_validate(responsepacket, NULL)) {
|
||||
int result;
|
||||
|
||||
/* Free old reference for this request */
|
||||
ac_free_reference_last_response(session);
|
||||
|
||||
/* Send change event response to WTP */
|
||||
result = capwap_fragment_build_packet(responsepacket, session->responsefragmentpacket, session->mtu, session->fragmentid);
|
||||
if (result >= 0) {
|
||||
if (result == 1) {
|
||||
session->fragmentid++;
|
||||
}
|
||||
|
||||
/* Save remote sequence number */
|
||||
session->remoteseqnumber = buildpacket->ctrlmsg.seq;
|
||||
capwap_get_packet_digest((void*)packet->header, packet->packetsize, session->lastrecvpackethash);
|
||||
|
||||
/* Send */
|
||||
for (i = 0; i < session->responsefragmentpacket->count; i++) {
|
||||
struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(session->responsefragmentpacket, i);
|
||||
ASSERT(txpacket != NULL);
|
||||
|
||||
if (!capwap_crypt_sendto(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], txpacket->header, txpacket->packetsize, &session->acctrladdress, &session->wtpctrladdress)) {
|
||||
/* Response is already created and saved. When receive a re-request, DFA autoresponse */
|
||||
capwap_logging_debug("Warning: error to send change event response packet");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Change status */
|
||||
ac_dfa_change_state(session, CAPWAP_DATA_CHECK_TO_RUN_STATE);
|
||||
capwap_set_timeout(session->dfa.rfcDataCheckTimer, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
}
|
||||
} else {
|
||||
capwap_logging_debug("Warning: build invalid configuration status response packet");
|
||||
}
|
||||
|
||||
/* Free memory */
|
||||
capwap_build_packet_free(responsepacket);
|
||||
}
|
||||
|
||||
/* Free */
|
||||
capwap_free_element_changestateevent_request(&changeeventrequest, binding);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free */
|
||||
capwap_build_packet_free(buildpacket);
|
||||
/* Change event response complete, get fragment packets */
|
||||
ac_free_reference_last_response(session);
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, session->responsefragmentpacket, session->fragmentid);
|
||||
if (session->responsefragmentpacket->count > 1) {
|
||||
session->fragmentid++;
|
||||
}
|
||||
|
||||
/* Free packets manager */
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
|
||||
/* Save remote sequence number */
|
||||
session->remoteseqnumber = packet->rxmngpacket->ctrlmsg.seq;
|
||||
capwap_get_packet_digest(packet->rxmngpacket, packet->connection, session->lastrecvpackethash);
|
||||
|
||||
/* Send Change event response to WTP */
|
||||
if (!capwap_crypt_sendto_fragmentpacket(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], session->responsefragmentpacket, &session->acctrladdress, &session->wtpctrladdress)) {
|
||||
/* Response is already created and saved. When receive a re-request, DFA autoresponse */
|
||||
capwap_logging_debug("Warning: error to send change event response packet");
|
||||
}
|
||||
|
||||
/* Change state */
|
||||
ac_dfa_change_state(session, CAPWAP_DATA_CHECK_TO_RUN_STATE);
|
||||
capwap_set_timeout(session->dfa.rfcDataCheckTimer, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
} else {
|
||||
/* Configure timeout */
|
||||
ac_dfa_change_state(session, CAPWAP_DATA_CHECK_TO_DTLS_TEARDOWN_STATE);
|
||||
@ -99,59 +56,54 @@ int ac_dfa_state_datacheck(struct ac_session_t* session, struct capwap_packet* p
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_datacheck_to_run(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
int ac_dfa_state_datacheck_to_run(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
struct capwap_list* txfragpacket;
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
int status = AC_DFA_ACCEPT_PACKET;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
|
||||
if (packet) {
|
||||
/* Wait Data Channel Keep-Alive packet */
|
||||
if (!packet->socket.isctrlsocket) {
|
||||
struct capwap_build_packet* buildpacket;
|
||||
|
||||
buildpacket = capwap_rx_packet_create((void*)packet->header, packet->packetsize, packet->socket.isctrlsocket);
|
||||
if (buildpacket) {
|
||||
struct capwap_sessionid_element sessionid;
|
||||
|
||||
if (capwap_get_sessionid_from_keepalive(buildpacket, &sessionid)) {
|
||||
if (!memcmp(&sessionid, &session->sessionid, sizeof(struct capwap_sessionid_element))) {
|
||||
int result;
|
||||
capwap_fragment_packet_array* txfragpacket;
|
||||
|
||||
/* Receive data packet keepalive, response with same packet */
|
||||
txfragpacket = capwap_array_create(sizeof(struct capwap_packet), 0);
|
||||
result = capwap_fragment_build_packet(buildpacket, txfragpacket, CAPWAP_DONT_FRAGMENT, 0);
|
||||
if (!result) {
|
||||
struct capwap_packet* txpacket;
|
||||
|
||||
ASSERT(txfragpacket->count == 1);
|
||||
|
||||
txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(txfragpacket, 0);
|
||||
ASSERT(txpacket != NULL);
|
||||
|
||||
if (!capwap_crypt_sendto(&session->datadtls, session->datasocket.socket[session->datasocket.type], txpacket->header, txpacket->packetsize, &session->acdataaddress, &session->wtpdataaddress)) {
|
||||
capwap_logging_debug("Warning: error to send data channel keepalive packet");
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_fragment_free(txfragpacket);
|
||||
capwap_array_free(txfragpacket);
|
||||
|
||||
if (!result) {
|
||||
/* Capwap handshake complete */
|
||||
ac_dfa_change_state(session, CAPWAP_RUN_STATE);
|
||||
capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
} else {
|
||||
ac_dfa_change_state(session, CAPWAP_DATA_CHECK_TO_DTLS_TEARDOWN_STATE);
|
||||
status = AC_DFA_NO_PACKET;
|
||||
}
|
||||
if (!packet->rxmngpacket->isctrlpacket && IS_FLAG_K_HEADER(packet->rxmngpacket->header)) {
|
||||
if (!memcmp(packet->messageelements.sessionid, &session->sessionid, sizeof(struct capwap_sessionid_element))) {
|
||||
int result = 0;
|
||||
|
||||
/* Build packet */
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, GET_WBID_HEADER(packet->rxmngpacket->header));
|
||||
capwap_header_set_keepalive_flag(&capwapheader, 1);
|
||||
txmngpacket = capwap_packet_txmng_create_data_message(&capwapheader, session->mtu);
|
||||
|
||||
/* Add message element */
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_SESSIONID, &session->sessionid);
|
||||
|
||||
/* Data keepalive complete, get fragment packets into local list */
|
||||
txfragpacket = capwap_list_create();
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, txfragpacket, 0);
|
||||
if (txfragpacket->count == 1) {
|
||||
/* Send Data keepalive to WTP */
|
||||
if (capwap_crypt_sendto_fragmentpacket(&session->datadtls, session->datasocket.socket[session->datasocket.type], txfragpacket, &session->acdataaddress, &session->wtpdataaddress)) {
|
||||
result = 1;
|
||||
} else {
|
||||
capwap_logging_debug("Warning: error to send data channel keepalive packet");
|
||||
}
|
||||
} else {
|
||||
capwap_logging_debug("Warning: error to send data channel keepalive packet, fragment packet");
|
||||
}
|
||||
|
||||
/* Free packets manager */
|
||||
capwap_list_free(txfragpacket);
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
|
||||
if (result) {
|
||||
/* Capwap handshake complete */
|
||||
ac_dfa_change_state(session, CAPWAP_RUN_STATE);
|
||||
capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
} else {
|
||||
ac_dfa_change_state(session, CAPWAP_DATA_CHECK_TO_DTLS_TEARDOWN_STATE);
|
||||
status = AC_DFA_NO_PACKET;
|
||||
}
|
||||
|
||||
/* Free */
|
||||
capwap_build_packet_free(buildpacket);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -164,6 +116,6 @@ int ac_dfa_state_datacheck_to_run(struct ac_session_t* session, struct capwap_pa
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_datacheck_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
int ac_dfa_state_datacheck_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
return ac_session_teardown_connection(session);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ int ac_bio_send(struct capwap_dtls* dtls, char* buffer, int length, void* param)
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_dtlssetup(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
int ac_dfa_state_dtlssetup(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
int status = AC_DFA_ACCEPT_PACKET;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
@ -37,7 +37,7 @@ int ac_dfa_state_dtlssetup(struct ac_session_t* session, struct capwap_packet* p
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_dtlsconnect(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
int ac_dfa_state_dtlsconnect(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(packet == NULL);
|
||||
|
||||
@ -46,6 +46,6 @@ int ac_dfa_state_dtlsconnect(struct ac_session_t* session, struct capwap_packet*
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_dtlsconnect_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
int ac_dfa_state_dtlsconnect_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
return ac_session_teardown_connection(session);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "ac_session.h"
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_imagedata(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
int ac_dfa_state_imagedata(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
int status = AC_DFA_ACCEPT_PACKET;
|
||||
|
||||
/* TODO */
|
||||
@ -13,6 +13,6 @@ int ac_dfa_state_imagedata(struct ac_session_t* session, struct capwap_packet* p
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_imagedata_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
int ac_dfa_state_imagedata_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
return ac_session_teardown_connection(session);
|
||||
}
|
||||
|
@ -4,227 +4,130 @@
|
||||
#include "ac_session.h"
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_join(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
int ac_dfa_state_join(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
int i;
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
int status = AC_DFA_ACCEPT_PACKET;
|
||||
struct capwap_resultcode_element resultcode = { CAPWAP_RESULTCODE_FAILURE };
|
||||
struct capwap_build_packet* responsepacket;
|
||||
struct capwap_resultcode_element resultcode = { .code = CAPWAP_RESULTCODE_FAILURE };
|
||||
|
||||
ASSERT(session != NULL);
|
||||
|
||||
if (packet) {
|
||||
struct capwap_build_packet* buildpacket;
|
||||
|
||||
buildpacket = capwap_rx_packet_create((void*)packet->header, packet->packetsize, packet->socket.isctrlsocket);
|
||||
if (buildpacket) {
|
||||
int validpacket;
|
||||
unsigned long checkpacket;
|
||||
struct capwap_array* returnedmessagearray = NULL;
|
||||
capwap_unrecognized_element_array* unrecognizedarray;
|
||||
struct capwap_element_join_request joinrequest;
|
||||
unsigned short binding = GET_WBID_HEADER(&buildpacket->header);
|
||||
unsigned short binding;
|
||||
|
||||
/* */
|
||||
unrecognizedarray = capwap_array_create(sizeof(struct unrecognized_info), 0);
|
||||
|
||||
/* */
|
||||
checkpacket = capwap_build_packet_validate(buildpacket, unrecognizedarray);
|
||||
if (!checkpacket) {
|
||||
if (ac_valid_binding(binding)) {
|
||||
if (ntohl(buildpacket->ctrlmsg.type) == CAPWAP_JOIN_REQUEST) {
|
||||
resultcode.code = CAPWAP_RESULTCODE_SUCCESS;
|
||||
} else {
|
||||
resultcode.code = CAPWAP_RESULTCODE_MSG_UNEXPECTED_INVALID_CURRENT_STATE;
|
||||
}
|
||||
} else {
|
||||
resultcode.code = CAPWAP_RESULTCODE_JOIN_FAILURE_BINDING_NOT_SUPPORTED;
|
||||
}
|
||||
/* Check binding */
|
||||
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 */
|
||||
memcpy(&session->sessionid, packet->messageelements.sessionid, sizeof(struct capwap_sessionid_element));
|
||||
|
||||
/* Get binding */
|
||||
session->binding = binding;
|
||||
} else {
|
||||
if ((checkpacket & CAPWAP_MISSING_MANDATORY_MSG_ELEMENT) != 0) {
|
||||
resultcode.code = CAPWAP_RESULTCODE_FAILURE_MISSING_MANDATORY_MSG_ELEMENT;
|
||||
} else if ((checkpacket & CAPWAP_UNRECOGNIZED_MSG_ELEMENT) != 0) {
|
||||
struct capwap_list_item* itemelement;
|
||||
|
||||
resultcode.code = CAPWAP_RESULTCODE_FAILURE_UNRECOGNIZED_MESSAGE_ELEMENT;
|
||||
returnedmessagearray = capwap_array_create(sizeof(struct capwap_returnedmessage_element), unrecognizedarray->count);
|
||||
resultcode.code = CAPWAP_RESULTCODE_MSG_UNEXPECTED_INVALID_CURRENT_STATE;
|
||||
}
|
||||
} else {
|
||||
resultcode.code = CAPWAP_RESULTCODE_JOIN_FAILURE_BINDING_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
for (i = 0; i < unrecognizedarray->count; i++) {
|
||||
struct unrecognized_info* reasoninfo = capwap_array_get_item_pointer(unrecognizedarray, i);
|
||||
|
||||
/* Search element */
|
||||
itemelement = buildpacket->elementslist->first;
|
||||
while (itemelement != NULL) {
|
||||
struct capwap_message_element* elementitem = (struct capwap_message_element*)itemelement->item;
|
||||
|
||||
if (ntohs(elementitem->type) == reasoninfo->element) {
|
||||
struct capwap_returnedmessage_element* returnedelement = capwap_array_get_item_pointer(returnedmessagearray, i);
|
||||
unsigned short length = sizeof(struct capwap_message_element) + ntohs(elementitem->length);
|
||||
/* Create response */
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, binding);
|
||||
txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_JOIN_RESPONSE, packet->rxmngpacket->ctrlmsg.seq, session->mtu);
|
||||
|
||||
returnedelement->reason = reasoninfo->reason;
|
||||
returnedelement->length = min(length, CAPWAP_RETURNED_MESSAGE_MAX_LENGTH);
|
||||
memcpy(&returnedelement->message[0], elementitem, returnedelement->length);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Next */
|
||||
itemelement = itemelement->next;
|
||||
}
|
||||
}
|
||||
/* Add message element */
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_RESULTCODE, &resultcode);
|
||||
|
||||
/* Check is valid packet after parsing request */
|
||||
if ((resultcode.code == CAPWAP_RESULTCODE_SUCCESS) || (resultcode.code == CAPWAP_RESULTCODE_SUCCESS_NAT_DETECTED)) {
|
||||
struct capwap_list* controllist;
|
||||
struct capwap_list_item* item;
|
||||
|
||||
/* Update statistics */
|
||||
ac_update_statistics();
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACDESCRIPTION, &g_ac.descriptor);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACNAME, &g_ac.acname);
|
||||
|
||||
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
|
||||
for (i = 0; i < packet->messageelements.ieee80211.wtpradioinformation->count; i++) {
|
||||
struct capwap_80211_wtpradioinformation_element* radio;
|
||||
|
||||
radio = *(struct capwap_80211_wtpradioinformation_element**)capwap_array_get_item_pointer(packet->messageelements.ieee80211.wtpradioinformation, i);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION, radio);
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_array_free(unrecognizedarray);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ECNSUPPORT, &session->dfa.ecn);
|
||||
|
||||
/* */
|
||||
capwap_init_element_join_request(&joinrequest, binding);
|
||||
if (resultcode.code == CAPWAP_RESULTCODE_SUCCESS) {
|
||||
/* Parsing elements list */
|
||||
if (capwap_parsing_element_join_request(&joinrequest, buildpacket->elementslist->first)) {
|
||||
/* TODO: gestione richiesta */
|
||||
/* Get information from any local address */
|
||||
controllist = capwap_list_create();
|
||||
ac_get_control_information(controllist);
|
||||
|
||||
for (item = controllist->first; item != NULL; item = item->next) {
|
||||
struct ac_session_control* sessioncontrol = (struct ac_session_control*)item->item;
|
||||
|
||||
if (sessioncontrol->localaddress.ss_family == AF_INET) {
|
||||
struct capwap_controlipv4_element element;
|
||||
|
||||
memcpy(&element.address, &((struct sockaddr_in*)&sessioncontrol->localaddress)->sin_addr, sizeof(struct in_addr));
|
||||
element.wtpcount = sessioncontrol->count;
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_CONTROLIPV4, &element);
|
||||
} else if (sessioncontrol->localaddress.ss_family == AF_INET6) {
|
||||
struct capwap_controlipv6_element element;
|
||||
|
||||
/* Get sessionid */
|
||||
memcpy(&session->sessionid, joinrequest.sessionid, sizeof(struct capwap_sessionid_element));
|
||||
|
||||
/* Get binding */
|
||||
session->binding = binding;
|
||||
|
||||
resultcode.code = CAPWAP_RESULTCODE_SUCCESS;
|
||||
memcpy(&element.address, &((struct sockaddr_in6*)&sessioncontrol->localaddress)->sin6_addr, sizeof(struct in6_addr));
|
||||
element.wtpcount = sessioncontrol->count;
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_CONTROLIPV6, &element);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create response */
|
||||
responsepacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, binding);
|
||||
responsepacket->isctrlmsg = 1;
|
||||
|
||||
/* Prepare join response */
|
||||
capwap_build_packet_set_control_message_type(responsepacket, CAPWAP_JOIN_RESPONSE, buildpacket->ctrlmsg.seq);
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_RESULTCODE_ELEMENT(&resultcode));
|
||||
capwap_list_free(controllist);
|
||||
|
||||
/* Check is valid packet after parsing request */
|
||||
validpacket = (((resultcode.code == CAPWAP_RESULTCODE_SUCCESS) || (resultcode.code == CAPWAP_RESULTCODE_SUCCESS_NAT_DETECTED)) ? 1 : 0);
|
||||
if (validpacket) {
|
||||
struct capwap_list* controllist;
|
||||
struct capwap_list_item* item;
|
||||
|
||||
/* Update statistics */
|
||||
ac_update_statistics();
|
||||
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_ACDESCRIPTOR_ELEMENT(&g_ac.descriptor));
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_ACNAME_ELEMENT(&g_ac.acname));
|
||||
if (session->acctrladdress.ss_family == AF_INET) {
|
||||
struct capwap_localipv4_element addr;
|
||||
|
||||
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
|
||||
for (i = 0; i < joinrequest.binding.ieee80211.wtpradioinformation->count; i++) {
|
||||
struct capwap_80211_wtpradioinformation_element* radio;
|
||||
|
||||
radio = (struct capwap_80211_wtpradioinformation_element*)capwap_array_get_item_pointer(joinrequest.binding.ieee80211.wtpradioinformation, i);
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_80211_WTPRADIOINFORMATION_ELEMENT(radio));
|
||||
}
|
||||
} else {
|
||||
capwap_logging_debug("Unknown capwap binding");
|
||||
}
|
||||
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_ECNSUPPORT_ELEMENT(&session->dfa.ecn));
|
||||
memcpy(&addr.address, &((struct sockaddr_in*)&session->acctrladdress)->sin_addr, sizeof(struct in_addr));
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_LOCALIPV4, &addr);
|
||||
} else if (session->acctrladdress.ss_family == AF_INET6) {
|
||||
struct capwap_localipv6_element addr;
|
||||
|
||||
/* Get information from any local address */
|
||||
controllist = capwap_list_create();
|
||||
ac_get_control_information(controllist);
|
||||
|
||||
for (item = controllist->first; item != NULL; item = item->next) {
|
||||
struct ac_session_control* sessioncontrol = (struct ac_session_control*)item->item;
|
||||
|
||||
if (sessioncontrol->localaddress.ss_family == AF_INET) {
|
||||
struct capwap_controlipv4_element element;
|
||||
|
||||
memcpy(&element.address, &((struct sockaddr_in*)&sessioncontrol->localaddress)->sin_addr, sizeof(struct in_addr));
|
||||
element.wtpcount = sessioncontrol->count;
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_CONTROLIPV4_ELEMENT(&element));
|
||||
} else if (sessioncontrol->localaddress.ss_family == AF_INET6) {
|
||||
struct capwap_controlipv6_element element;
|
||||
|
||||
memcpy(&element.address, &((struct sockaddr_in6*)&sessioncontrol->localaddress)->sin6_addr, sizeof(struct in6_addr));
|
||||
element.wtpcount = sessioncontrol->count;
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_CONTROLIPV6_ELEMENT(&element));
|
||||
}
|
||||
}
|
||||
|
||||
capwap_list_free(controllist);
|
||||
|
||||
if (session->acctrladdress.ss_family == AF_INET) {
|
||||
struct capwap_localipv4_element addr;
|
||||
|
||||
memcpy(&addr.address, &((struct sockaddr_in*)&session->acctrladdress)->sin_addr, sizeof(struct in_addr));
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_LOCALIPV4_ELEMENT(&addr));
|
||||
} else if (session->acctrladdress.ss_family == AF_INET6) {
|
||||
struct capwap_localipv6_element addr;
|
||||
|
||||
memcpy(&addr.address, &((struct sockaddr_in6*)&session->acctrladdress)->sin6_addr, sizeof(struct in6_addr));
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_LOCALIPV6_ELEMENT(&addr));
|
||||
}
|
||||
|
||||
/* CAPWAP_CREATE_ACIPV4LIST_ELEMENT */ /* TODO */
|
||||
/* CAPWAP_CREATE_ACIPV6LIST_ELEMENT */ /* TODO */
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_TRANSPORT_ELEMENT(&session->dfa.transport));
|
||||
/* CAPWAP_CREATE_IMAGEIDENTIFIER_ELEMENT */ /* TODO */
|
||||
/* CAPWAP_CREATE_MAXIMUMMESSAGELENGTH_ELEMENT */ /* TODO */
|
||||
/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */ /* TODO */
|
||||
} else if (resultcode.code == CAPWAP_RESULTCODE_FAILURE_UNRECOGNIZED_MESSAGE_ELEMENT) {
|
||||
ASSERT(returnedmessagearray != NULL);
|
||||
|
||||
for (i = 0; i < returnedmessagearray->count; i++) {
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_RETURNEDMESSAGE_ELEMENT(capwap_array_get_item_pointer(returnedmessagearray, i)));
|
||||
}
|
||||
|
||||
capwap_array_free(returnedmessagearray);
|
||||
memcpy(&addr.address, &((struct sockaddr_in6*)&session->acctrladdress)->sin6_addr, sizeof(struct in6_addr));
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_LOCALIPV6, &addr);
|
||||
}
|
||||
|
||||
/* Validate packet */
|
||||
if (!validpacket || !capwap_build_packet_validate(responsepacket, NULL)) {
|
||||
int result;
|
||||
|
||||
/* Free old reference for this request */
|
||||
ac_free_reference_last_response(session);
|
||||
/* CAPWAP_CREATE_ACIPV4LIST_ELEMENT */ /* TODO */
|
||||
/* CAPWAP_CREATE_ACIPV6LIST_ELEMENT */ /* TODO */
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_TRANSPORT, &session->dfa.transport);
|
||||
/* CAPWAP_CREATE_IMAGEIDENTIFIER_ELEMENT */ /* TODO */
|
||||
/* CAPWAP_CREATE_MAXIMUMMESSAGELENGTH_ELEMENT */ /* TODO */
|
||||
/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */ /* TODO */
|
||||
}
|
||||
|
||||
/* Send join response to WTP */
|
||||
result = capwap_fragment_build_packet(responsepacket, session->responsefragmentpacket, session->mtu, session->fragmentid);
|
||||
if (result >= 0) {
|
||||
if (result == 1) {
|
||||
session->fragmentid++;
|
||||
}
|
||||
/* Join response complete, get fragment packets */
|
||||
ac_free_reference_last_response(session);
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, session->responsefragmentpacket, session->fragmentid);
|
||||
if (session->responsefragmentpacket->count > 1) {
|
||||
session->fragmentid++;
|
||||
}
|
||||
|
||||
/* Save remote sequence number */
|
||||
session->remoteseqnumber = buildpacket->ctrlmsg.seq;
|
||||
capwap_get_packet_digest((void*)packet->header, packet->packetsize, session->lastrecvpackethash);
|
||||
/* Free packets manager */
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
|
||||
/* Send */
|
||||
for (i = 0; i < session->responsefragmentpacket->count; i++) {
|
||||
struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(session->responsefragmentpacket, i);
|
||||
ASSERT(txpacket != NULL);
|
||||
|
||||
if (!capwap_crypt_sendto(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], txpacket->header, txpacket->packetsize, &session->acctrladdress, &session->wtpctrladdress)) {
|
||||
/* Response is already created and saved. When receive a re-request, DFA autoresponse */
|
||||
capwap_logging_debug("Warning: error to send join response packet");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
capwap_logging_debug("Warning: build invalid join response packet");
|
||||
}
|
||||
/* Save remote sequence number */
|
||||
session->remoteseqnumber = packet->rxmngpacket->ctrlmsg.seq;
|
||||
capwap_get_packet_digest(packet->rxmngpacket, packet->connection, session->lastrecvpackethash);
|
||||
|
||||
/* Free memory */
|
||||
capwap_build_packet_free(responsepacket);
|
||||
capwap_free_element_join_request(&joinrequest, binding);
|
||||
capwap_build_packet_free(buildpacket);
|
||||
|
||||
/* Change state */
|
||||
if (validpacket) {
|
||||
ac_dfa_change_state(session, CAPWAP_POSTJOIN_STATE);
|
||||
} else {
|
||||
ac_dfa_change_state(session, CAPWAP_JOIN_TO_DTLS_TEARDOWN_STATE);
|
||||
status = AC_DFA_NO_PACKET;
|
||||
}
|
||||
/* Send Join response to WTP */
|
||||
if (capwap_crypt_sendto_fragmentpacket(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], session->responsefragmentpacket, &session->acctrladdress, &session->wtpctrladdress)) {
|
||||
ac_dfa_change_state(session, CAPWAP_POSTJOIN_STATE);
|
||||
} else {
|
||||
/* Error to send packets */
|
||||
capwap_logging_debug("Warning: error to send join response packet");
|
||||
ac_dfa_change_state(session, CAPWAP_JOIN_TO_DTLS_TEARDOWN_STATE);
|
||||
status = AC_DFA_NO_PACKET;
|
||||
}
|
||||
} else {
|
||||
/* Join timeout */
|
||||
@ -236,26 +139,21 @@ int ac_dfa_state_join(struct ac_session_t* session, struct capwap_packet* packet
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_postjoin(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
int ac_dfa_state_postjoin(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
int status = AC_DFA_ACCEPT_PACKET;
|
||||
|
||||
|
||||
ASSERT(session != NULL);
|
||||
|
||||
|
||||
if (packet) {
|
||||
unsigned short lengthpayload;
|
||||
|
||||
lengthpayload = packet->packetsize - GET_HLEN_HEADER(packet->header) * 4;
|
||||
if (lengthpayload >= sizeof(struct capwap_control_message)) {
|
||||
struct capwap_control_message* ctrlmsg = (struct capwap_control_message*)packet->payload;
|
||||
unsigned long type = ntohl(ctrlmsg->type);
|
||||
|
||||
if (type == CAPWAP_CONFIGURATION_STATUS_REQUEST) {
|
||||
ac_dfa_change_state(session, CAPWAP_CONFIGURE_STATE);
|
||||
status = ac_dfa_state_configure(session, packet);
|
||||
} else if (type == CAPWAP_IMAGE_DATA_REQUEST) {
|
||||
ac_dfa_change_state(session, CAPWAP_IMAGE_DATA_STATE);
|
||||
status = ac_dfa_state_imagedata(session, packet);
|
||||
}
|
||||
if (packet->rxmngpacket->ctrlmsg.type == CAPWAP_CONFIGURATION_STATUS_REQUEST) {
|
||||
ac_dfa_change_state(session, CAPWAP_CONFIGURE_STATE);
|
||||
status = ac_dfa_state_configure(session, packet);
|
||||
} else if (packet->rxmngpacket->ctrlmsg.type == CAPWAP_IMAGE_DATA_REQUEST) {
|
||||
ac_dfa_change_state(session, CAPWAP_IMAGE_DATA_STATE);
|
||||
status = ac_dfa_state_imagedata(session, packet);
|
||||
} else {
|
||||
ac_dfa_change_state(session, CAPWAP_JOIN_TO_DTLS_TEARDOWN_STATE);
|
||||
status = AC_DFA_NO_PACKET;
|
||||
}
|
||||
} else {
|
||||
/* Join timeout */
|
||||
@ -267,6 +165,6 @@ int ac_dfa_state_postjoin(struct ac_session_t* session, struct capwap_packet* pa
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_join_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
int ac_dfa_state_join_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
return ac_session_teardown_connection(session);
|
||||
}
|
||||
|
@ -4,69 +4,34 @@
|
||||
#include "ac_session.h"
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_reset(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
int ac_dfa_state_reset(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
int status = AC_DFA_ACCEPT_PACKET;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
|
||||
if (packet) {
|
||||
if (!capwap_compare_ip(&session->wtpctrladdress, &packet->remoteaddr)) {
|
||||
struct capwap_build_packet* buildpacket;
|
||||
unsigned short binding;
|
||||
|
||||
/* Parsing packet */
|
||||
buildpacket = capwap_rx_packet_create((void*)packet->header, packet->packetsize, packet->socket.isctrlsocket);
|
||||
if (buildpacket) {
|
||||
if (!capwap_build_packet_validate(buildpacket, NULL)) {
|
||||
unsigned short binding;
|
||||
|
||||
/* */
|
||||
binding = GET_WBID_HEADER(&buildpacket->header);
|
||||
if ((binding == session->binding) && (ntohl(buildpacket->ctrlmsg.type) == CAPWAP_RESET_RESPONSE) && ((session->localseqnumber - 1) == buildpacket->ctrlmsg.seq)) {
|
||||
struct capwap_element_reset_response resetresponse;
|
||||
|
||||
/* Valid packet, free request packet */
|
||||
ac_free_reference_last_request(session);
|
||||
|
||||
/* Configuration status response info */
|
||||
capwap_init_element_reset_response(&resetresponse, binding);
|
||||
|
||||
/* Parsing elements list */
|
||||
if (capwap_parsing_element_reset_response(&resetresponse, buildpacket->elementslist->first)) {
|
||||
ac_dfa_change_state(session, CAPWAP_RESET_TO_DTLS_TEARDOWN_STATE);
|
||||
status = AC_DFA_NO_PACKET;
|
||||
}
|
||||
|
||||
/* Free join response */
|
||||
capwap_free_element_reset_response(&resetresponse, binding);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free */
|
||||
capwap_build_packet_free(buildpacket);
|
||||
}
|
||||
/* */
|
||||
binding = GET_WBID_HEADER(packet->rxmngpacket->header);
|
||||
if ((binding == session->binding) && (packet->rxmngpacket->ctrlmsg.type == CAPWAP_RESET_RESPONSE) && ((session->localseqnumber - 1) == packet->rxmngpacket->ctrlmsg.seq)) {
|
||||
ac_dfa_change_state(session, CAPWAP_RESET_TO_DTLS_TEARDOWN_STATE);
|
||||
status = AC_DFA_NO_PACKET;
|
||||
}
|
||||
} else {
|
||||
int i;
|
||||
|
||||
/* No Configuration status response received */
|
||||
session->dfa.rfcRetransmitCount++;
|
||||
if (session->dfa.rfcRetransmitCount >= session->dfa.rfcMaxRetransmit) {
|
||||
/* Timeout join state */
|
||||
/* Timeout reset state */
|
||||
ac_free_reference_last_request(session);
|
||||
ac_dfa_change_state(session, CAPWAP_RESET_TO_DTLS_TEARDOWN_STATE);
|
||||
status = AC_DFA_NO_PACKET;
|
||||
} else {
|
||||
/* Retransmit configuration request */
|
||||
for (i = 0; i < session->requestfragmentpacket->count; i++) {
|
||||
struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(session->requestfragmentpacket, i);
|
||||
ASSERT(txpacket != NULL);
|
||||
|
||||
if (!capwap_crypt_sendto(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], txpacket->header, txpacket->packetsize, &session->acctrladdress, &session->wtpctrladdress)) {
|
||||
capwap_logging_debug("Warning: error to send configuration status request packet");
|
||||
break;
|
||||
}
|
||||
if (!capwap_crypt_sendto_fragmentpacket(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], session->requestfragmentpacket, &session->acctrladdress, &session->wtpctrladdress)) {
|
||||
capwap_logging_debug("Warning: error to resend reset request packet");
|
||||
}
|
||||
|
||||
|
||||
/* Update timeout */
|
||||
capwap_set_timeout(session->dfa.rfcRetransmitInterval, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
}
|
||||
@ -76,6 +41,6 @@ int ac_dfa_state_reset(struct ac_session_t* session, struct capwap_packet* packe
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_reset_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
int ac_dfa_state_reset_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
return ac_session_teardown_connection(session);
|
||||
}
|
||||
|
@ -4,185 +4,148 @@
|
||||
#include "ac_session.h"
|
||||
|
||||
/* */
|
||||
static int receive_echo_request(struct ac_session_t* session, struct capwap_build_packet* buildpacket, struct capwap_packet* packet) {
|
||||
unsigned long i;
|
||||
unsigned short binding;
|
||||
static int receive_echo_request(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(buildpacket != NULL);
|
||||
ASSERT(packet != NULL);
|
||||
|
||||
/* */
|
||||
binding = GET_WBID_HEADER(&buildpacket->header);
|
||||
if (ac_valid_binding(binding) && IS_SEQUENCE_SMALLER(session->remoteseqnumber, buildpacket->ctrlmsg.seq)) {
|
||||
struct capwap_element_echo_request echorequest;
|
||||
|
||||
/* Echo request info*/
|
||||
capwap_init_element_echo_request(&echorequest, binding);
|
||||
|
||||
/* Parsing elements list */
|
||||
if (capwap_parsing_element_echo_request(&echorequest, buildpacket->elementslist->first)) {
|
||||
struct capwap_build_packet* responsepacket;
|
||||
/* Create response */
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, GET_WBID_HEADER(packet->rxmngpacket->header));
|
||||
txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_ECHO_RESPONSE, packet->rxmngpacket->ctrlmsg.seq, session->mtu);
|
||||
|
||||
/* Create response */
|
||||
responsepacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, binding);
|
||||
responsepacket->isctrlmsg = 1;
|
||||
/* Add message element */
|
||||
/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */ /* TODO */
|
||||
|
||||
/* Prepare echo response */
|
||||
capwap_build_packet_set_control_message_type(responsepacket, CAPWAP_ECHO_RESPONSE, buildpacket->ctrlmsg.seq);
|
||||
/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */ /* TODO */
|
||||
/* Echo response complete, get fragment packets */
|
||||
ac_free_reference_last_response(session);
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, session->responsefragmentpacket, session->fragmentid);
|
||||
if (session->responsefragmentpacket->count > 1) {
|
||||
session->fragmentid++;
|
||||
}
|
||||
|
||||
if (!capwap_build_packet_validate(responsepacket, NULL)) {
|
||||
int result;
|
||||
|
||||
/* Free old reference for this request */
|
||||
ac_free_reference_last_response(session);
|
||||
/* Free packets manager */
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
|
||||
/* Send echo response to WTP */
|
||||
result = capwap_fragment_build_packet(responsepacket, session->responsefragmentpacket, session->mtu, session->fragmentid);
|
||||
if (result >= 0) {
|
||||
if (result == 1) {
|
||||
session->fragmentid++;
|
||||
}
|
||||
/* Save remote sequence number */
|
||||
session->remoteseqnumber = packet->rxmngpacket->ctrlmsg.seq;
|
||||
capwap_get_packet_digest(packet->rxmngpacket, packet->connection, session->lastrecvpackethash);
|
||||
|
||||
/* Save remote sequence number */
|
||||
session->remoteseqnumber = buildpacket->ctrlmsg.seq;
|
||||
capwap_get_packet_digest((void*)packet->header, packet->packetsize, session->lastrecvpackethash);
|
||||
|
||||
/* Send */
|
||||
for (i = 0; i < session->responsefragmentpacket->count; i++) {
|
||||
struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(session->responsefragmentpacket, i);
|
||||
ASSERT(txpacket != NULL);
|
||||
|
||||
if (!capwap_crypt_sendto(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], txpacket->header, txpacket->packetsize, &session->acctrladdress, &session->wtpctrladdress)) {
|
||||
/* Response is already created and saved. When receive a re-request, DFA autoresponse */
|
||||
capwap_logging_debug("Warning: error to send echo response packet");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Free memory */
|
||||
capwap_build_packet_free(responsepacket);
|
||||
}
|
||||
|
||||
/* Free */
|
||||
capwap_free_element_echo_request(&echorequest, binding);
|
||||
/* Send Configure response to WTP */
|
||||
if (!capwap_crypt_sendto_fragmentpacket(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], session->responsefragmentpacket, &session->acctrladdress, &session->wtpctrladdress)) {
|
||||
/* Response is already created and saved. When receive a re-request, DFA autoresponse */
|
||||
capwap_logging_debug("Warning: error to send echo response packet");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_run(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
static int ac_send_data_keepalive(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
struct capwap_list* txfragpacket;
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
int result = -1;
|
||||
|
||||
/* Build packet */
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, GET_WBID_HEADER(packet->rxmngpacket->header));
|
||||
capwap_header_set_keepalive_flag(&capwapheader, 1);
|
||||
txmngpacket = capwap_packet_txmng_create_data_message(&capwapheader, session->mtu);
|
||||
|
||||
/* Add message element */
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_SESSIONID, &session->sessionid);
|
||||
|
||||
/* Data keepalive complete, get fragment packets into local list */
|
||||
txfragpacket = capwap_list_create();
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, txfragpacket, 0);
|
||||
if (txfragpacket->count == 1) {
|
||||
/* Send Data keepalive to WTP */
|
||||
if (capwap_crypt_sendto_fragmentpacket(&session->datadtls, session->datasocket.socket[session->datasocket.type], txfragpacket, &session->acdataaddress, &session->wtpdataaddress)) {
|
||||
result = 0;
|
||||
} else {
|
||||
capwap_logging_debug("Warning: error to send data channel keepalive packet");
|
||||
}
|
||||
} else {
|
||||
capwap_logging_debug("Warning: error to send data channel keepalive packet, fragment packet");
|
||||
}
|
||||
|
||||
/* Free packets manager */
|
||||
capwap_list_free(txfragpacket);
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_run(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
int status = AC_DFA_ACCEPT_PACKET;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
|
||||
if (packet) {
|
||||
struct capwap_build_packet* buildpacket;
|
||||
|
||||
buildpacket = capwap_rx_packet_create((void*)packet->header, packet->packetsize, packet->socket.isctrlsocket);
|
||||
if (buildpacket) {
|
||||
if (!capwap_build_packet_validate(buildpacket, NULL)) {
|
||||
if (packet->socket.isctrlsocket) {
|
||||
unsigned long typemsg = ntohl(buildpacket->ctrlmsg.type);
|
||||
|
||||
if (capwap_is_request_type(typemsg) || ((session->localseqnumber - 1) == buildpacket->ctrlmsg.seq)) {
|
||||
switch (typemsg) {
|
||||
case CAPWAP_CONFIGURATION_UPDATE_REQUEST: {
|
||||
/* TODO */
|
||||
capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CHANGE_STATE_EVENT_RESPONSE: {
|
||||
/* TODO */
|
||||
capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_ECHO_REQUEST: {
|
||||
if (!receive_echo_request(session, buildpacket, packet)) {
|
||||
capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
} else {
|
||||
ac_dfa_change_state(session, CAPWAP_RUN_TO_DTLS_TEARDOWN_STATE);
|
||||
status = AC_DFA_NO_PACKET;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CLEAR_CONFIGURATION_REQUEST: {
|
||||
/* TODO */
|
||||
capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_WTP_EVENT_RESPONSE: {
|
||||
/* TODO */
|
||||
capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DATA_TRANSFER_REQUEST: {
|
||||
/* TODO */
|
||||
capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DATA_TRANSFER_RESPONSE: {
|
||||
/* TODO */
|
||||
capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (IS_FLAG_K_HEADER(&buildpacket->header)) {
|
||||
struct capwap_sessionid_element sessionid;
|
||||
|
||||
if (capwap_get_sessionid_from_keepalive(buildpacket, &sessionid)) {
|
||||
if (!memcmp(&sessionid, &session->sessionid, sizeof(struct capwap_sessionid_element))) {
|
||||
int result;
|
||||
capwap_fragment_packet_array* txfragpacket;
|
||||
|
||||
/* Receive data packet keepalive, response with same packet */
|
||||
txfragpacket = capwap_array_create(sizeof(struct capwap_packet), 0);
|
||||
result = capwap_fragment_build_packet(buildpacket, txfragpacket, CAPWAP_DONT_FRAGMENT, 0);
|
||||
if (!result) {
|
||||
struct capwap_packet* txpacket;
|
||||
|
||||
ASSERT(txfragpacket->count == 1);
|
||||
|
||||
txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(txfragpacket, 0);
|
||||
ASSERT(txpacket != NULL);
|
||||
|
||||
if (!capwap_crypt_sendto(&session->datadtls, session->datasocket.socket[session->datasocket.type], txpacket->header, txpacket->packetsize, &session->acdataaddress, &session->wtpdataaddress)) {
|
||||
capwap_logging_debug("Warning: error to send data channel keepalive packet");
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_fragment_free(txfragpacket);
|
||||
capwap_array_free(txfragpacket);
|
||||
|
||||
if (result) {
|
||||
ac_dfa_change_state(session, CAPWAP_RUN_TO_DTLS_TEARDOWN_STATE);
|
||||
status = AC_DFA_NO_PACKET;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (packet->rxmngpacket->isctrlpacket) {
|
||||
if (capwap_is_request_type(packet->rxmngpacket->ctrlmsg.type) || ((session->localseqnumber - 1) == packet->rxmngpacket->ctrlmsg.seq)) {
|
||||
switch (packet->rxmngpacket->ctrlmsg.type) {
|
||||
case CAPWAP_CONFIGURATION_UPDATE_REQUEST: {
|
||||
/* TODO */
|
||||
capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CHANGE_STATE_EVENT_RESPONSE: {
|
||||
/* TODO */
|
||||
capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_ECHO_REQUEST: {
|
||||
if (!receive_echo_request(session, packet)) {
|
||||
capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
} else {
|
||||
ac_dfa_change_state(session, CAPWAP_RUN_TO_DTLS_TEARDOWN_STATE);
|
||||
status = AC_DFA_NO_PACKET;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_CLEAR_CONFIGURATION_REQUEST: {
|
||||
/* TODO */
|
||||
capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_WTP_EVENT_RESPONSE: {
|
||||
/* TODO */
|
||||
capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DATA_TRANSFER_REQUEST: {
|
||||
/* TODO */
|
||||
capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
break;
|
||||
}
|
||||
|
||||
case CAPWAP_DATA_TRANSFER_RESPONSE: {
|
||||
/* TODO */
|
||||
capwap_set_timeout(AC_MAX_ECHO_INTERVAL, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Free */
|
||||
capwap_build_packet_free(buildpacket);
|
||||
} else {
|
||||
if (IS_FLAG_K_HEADER(packet->rxmngpacket->header)) {
|
||||
if (!memcmp(packet->messageelements.sessionid, &session->sessionid, sizeof(struct capwap_sessionid_element))) {
|
||||
if (ac_send_data_keepalive(session, packet)) {
|
||||
ac_dfa_change_state(session, CAPWAP_RUN_TO_DTLS_TEARDOWN_STATE);
|
||||
status = AC_DFA_NO_PACKET;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* TODO */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ac_dfa_change_state(session, CAPWAP_RUN_TO_DTLS_TEARDOWN_STATE);
|
||||
@ -193,71 +156,49 @@ int ac_dfa_state_run(struct ac_session_t* session, struct capwap_packet* packet)
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_run_to_reset(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
int ac_dfa_state_run_to_reset(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
int status = AC_DFA_NO_PACKET;
|
||||
struct capwap_build_packet* buildpacket;
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(packet == NULL);
|
||||
|
||||
/* Build packet */
|
||||
buildpacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, session->binding);
|
||||
buildpacket->isctrlmsg = 1;
|
||||
|
||||
/* Prepare reset request */
|
||||
capwap_build_packet_set_control_message_type(buildpacket, CAPWAP_RESET_REQUEST, session->localseqnumber++);
|
||||
capwap_build_packet_add_message_element(buildpacket, CAPWAP_CREATE_IMAGEIDENTIFIER_ELEMENT(&session->startupimage));
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, session->binding);
|
||||
txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_RESET_REQUEST, session->localseqnumber++, session->mtu);
|
||||
|
||||
/* Add message element */
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_IMAGEIDENTIFIER, &session->startupimage);
|
||||
/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */ /* TODO */
|
||||
|
||||
if (!capwap_build_packet_validate(buildpacket, NULL)) {
|
||||
int i;
|
||||
int result;
|
||||
|
||||
/* Free old reference for this request */
|
||||
ac_free_reference_last_request(session);
|
||||
|
||||
/* Send reset request to WTP */
|
||||
result = capwap_fragment_build_packet(buildpacket, session->requestfragmentpacket, session->mtu, session->fragmentid);
|
||||
if (result >= 0) {
|
||||
if (result == 1) {
|
||||
session->fragmentid++;
|
||||
}
|
||||
|
||||
/* Send */
|
||||
for (i = 0; i < session->requestfragmentpacket->count; i++) {
|
||||
struct capwap_packet* txpacket = (struct capwap_packet*)capwap_array_get_item_pointer(session->requestfragmentpacket, i);
|
||||
ASSERT(txpacket != NULL);
|
||||
|
||||
if (!capwap_crypt_sendto(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], txpacket->header, txpacket->packetsize, &session->acctrladdress, &session->wtpctrladdress)) {
|
||||
capwap_logging_debug("Warning: error to send reset request packet");
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result == -1) {
|
||||
/* Error to send packets */
|
||||
ac_free_reference_last_request(session);
|
||||
ac_dfa_change_state(session, CAPWAP_RESET_TO_DTLS_TEARDOWN_STATE);
|
||||
} else {
|
||||
session->dfa.rfcRetransmitCount = 0;
|
||||
|
||||
capwap_killall_timeout(&session->timeout);
|
||||
capwap_set_timeout(session->dfa.rfcRetransmitInterval, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
|
||||
ac_dfa_change_state(session, CAPWAP_RESET_STATE);
|
||||
status = AC_DFA_ACCEPT_PACKET;
|
||||
}
|
||||
/* Reset request complete, get fragment packets */
|
||||
ac_free_reference_last_request(session);
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, session->requestfragmentpacket, session->fragmentid);
|
||||
if (session->requestfragmentpacket->count > 1) {
|
||||
session->fragmentid++;
|
||||
}
|
||||
|
||||
/* Free packets manager */
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
|
||||
/* Send Configure response to WTP */
|
||||
if (capwap_crypt_sendto_fragmentpacket(&session->ctrldtls, session->ctrlsocket.socket[session->ctrlsocket.type], session->requestfragmentpacket, &session->acctrladdress, &session->wtpctrladdress)) {
|
||||
session->dfa.rfcRetransmitCount = 0;
|
||||
capwap_killall_timeout(&session->timeout);
|
||||
capwap_set_timeout(session->dfa.rfcRetransmitInterval, &session->timeout, CAPWAP_TIMER_CONTROL_CONNECTION);
|
||||
ac_dfa_change_state(session, CAPWAP_RESET_STATE);
|
||||
status = AC_DFA_ACCEPT_PACKET;
|
||||
} else {
|
||||
capwap_logging_debug("Warning: error to send reset request packet");
|
||||
ac_free_reference_last_request(session);
|
||||
ac_dfa_change_state(session, CAPWAP_RESET_TO_DTLS_TEARDOWN_STATE);
|
||||
}
|
||||
|
||||
/* Free memory */
|
||||
capwap_build_packet_free(buildpacket);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_run_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
int ac_dfa_state_run_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
return ac_session_teardown_connection(session);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "ac_session.h"
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_teardown(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
int ac_dfa_state_teardown(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(packet == NULL);
|
||||
|
||||
@ -14,7 +14,7 @@ int ac_dfa_state_teardown(struct ac_session_t* session, struct capwap_packet* pa
|
||||
}
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_dead(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
int ac_dfa_state_dead(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
ASSERT(session != NULL);
|
||||
ASSERT(packet == NULL);
|
||||
|
||||
|
@ -88,44 +88,39 @@ void ac_discovery_add_packet(void* buffer, int buffersize, int sock, struct sock
|
||||
}
|
||||
|
||||
/* */
|
||||
static struct capwap_build_packet* ac_create_discovery_response(struct capwap_build_packet* packet, struct capwap_element_discovery_request* discoveryrequest, struct sockaddr_storage* sender) {
|
||||
static struct capwap_packet_txmng* ac_create_discovery_response(struct capwap_parsed_packet* packet) {
|
||||
int i;
|
||||
unsigned short binding;
|
||||
struct capwap_list* controllist;
|
||||
struct capwap_list_item* item;
|
||||
struct capwap_build_packet* responsepacket;
|
||||
struct capwap_header_data capwapheader;
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
|
||||
ASSERT(packet != NULL);
|
||||
ASSERT(discoveryrequest != NULL);
|
||||
ASSERT(sender != NULL);
|
||||
|
||||
/* Check is valid binding */
|
||||
binding = GET_WBID_HEADER(&packet->header);
|
||||
binding = GET_WBID_HEADER(packet->rxmngpacket->header);
|
||||
if (!ac_valid_binding(binding)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Build packet */
|
||||
responsepacket = capwap_tx_packet_create(CAPWAP_RADIOID_NONE, binding);
|
||||
responsepacket->isctrlmsg = 1;
|
||||
|
||||
/* Update statistics */
|
||||
ac_update_statistics();
|
||||
|
||||
/* Prepare discovery response */
|
||||
capwap_build_packet_set_control_message_type(responsepacket, CAPWAP_DISCOVERY_RESPONSE, packet->ctrlmsg.seq);
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_ACDESCRIPTOR_ELEMENT(&g_ac.descriptor));
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_ACNAME_ELEMENT(&g_ac.acname));
|
||||
|
||||
/* Build packet */
|
||||
capwap_header_init(&capwapheader, CAPWAP_RADIOID_NONE, binding);
|
||||
txmngpacket = capwap_packet_txmng_create_ctrl_message(&capwapheader, CAPWAP_DISCOVERY_RESPONSE, packet->rxmngpacket->ctrlmsg.seq, g_ac.mtu);
|
||||
|
||||
/* Prepare discovery response */
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACDESCRIPTION, &g_ac.descriptor);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_ACNAME, &g_ac.acname);
|
||||
if (binding == CAPWAP_WIRELESS_BINDING_IEEE80211) {
|
||||
for (i = 0; i < discoveryrequest->binding.ieee80211.wtpradioinformation->count; i++) {
|
||||
for (i = 0; i < packet->messageelements.ieee80211.wtpradioinformation->count; i++) {
|
||||
struct capwap_80211_wtpradioinformation_element* radio;
|
||||
|
||||
radio = (struct capwap_80211_wtpradioinformation_element*)capwap_array_get_item_pointer(discoveryrequest->binding.ieee80211.wtpradioinformation, i);
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_80211_WTPRADIOINFORMATION_ELEMENT(radio));
|
||||
radio = *(struct capwap_80211_wtpradioinformation_element**)capwap_array_get_item_pointer(packet->messageelements.ieee80211.wtpradioinformation, i);
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_80211_WTPRADIOINFORMATION, radio);
|
||||
}
|
||||
} else {
|
||||
capwap_logging_debug("Unknown capwap binding");
|
||||
}
|
||||
|
||||
/* Get information from any local address */
|
||||
@ -137,24 +132,24 @@ static struct capwap_build_packet* ac_create_discovery_response(struct capwap_bu
|
||||
|
||||
if (sessioncontrol->localaddress.ss_family == AF_INET) {
|
||||
struct capwap_controlipv4_element element;
|
||||
|
||||
|
||||
memcpy(&element.address, &((struct sockaddr_in*)&sessioncontrol->localaddress)->sin_addr, sizeof(struct in_addr));
|
||||
element.wtpcount = sessioncontrol->count;
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_CONTROLIPV4_ELEMENT(&element));
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_CONTROLIPV4, &element);
|
||||
} else if (sessioncontrol->localaddress.ss_family == AF_INET6) {
|
||||
struct capwap_controlipv6_element element;
|
||||
|
||||
|
||||
memcpy(&element.address, &((struct sockaddr_in6*)&sessioncontrol->localaddress)->sin6_addr, sizeof(struct in6_addr));
|
||||
element.wtpcount = sessioncontrol->count;
|
||||
capwap_build_packet_add_message_element(responsepacket, CAPWAP_CREATE_CONTROLIPV6_ELEMENT(&element));
|
||||
capwap_packet_txmng_add_message_element(txmngpacket, CAPWAP_ELEMENT_CONTROLIPV6, &element);
|
||||
}
|
||||
}
|
||||
|
||||
capwap_list_free(controllist);
|
||||
|
||||
capwap_list_free(controllist);
|
||||
|
||||
/* CAPWAP_CREATE_VENDORSPECIFICPAYLOAD_ELEMENT */ /* TODO */
|
||||
|
||||
return responsepacket;
|
||||
return txmngpacket;
|
||||
}
|
||||
|
||||
/* Cleanup info discovery */
|
||||
@ -167,21 +162,21 @@ static void ac_discovery_cleanup(void) {
|
||||
static void ac_discovery_run(void) {
|
||||
int sizedata;
|
||||
struct capwap_list_item* itempacket;
|
||||
struct capwap_build_packet* buildpacket;
|
||||
struct ac_discovery_packet* packet;
|
||||
unsigned short binding;
|
||||
|
||||
struct ac_discovery_packet* acpacket;
|
||||
struct capwap_parsed_packet packet;
|
||||
struct capwap_packet_rxmng* rxmngpacket;
|
||||
|
||||
while (!g_ac_discovery.endthread) {
|
||||
/* Get packet */
|
||||
capwap_lock_enter(&g_ac_discovery.packetslock);
|
||||
|
||||
|
||||
itempacket = NULL;
|
||||
if (g_ac_discovery.packets->count > 0) {
|
||||
itempacket = capwap_itemlist_remove_head(g_ac_discovery.packets);
|
||||
}
|
||||
|
||||
|
||||
capwap_lock_exit(&g_ac_discovery.packetslock);
|
||||
|
||||
|
||||
if (!itempacket) {
|
||||
/* Wait packet with timeout*/
|
||||
if (!capwap_event_wait_timeout(&g_ac_discovery.waitpacket, AC_DISCOVERY_CLEANUP_TIMEOUT)) {
|
||||
@ -190,74 +185,56 @@ static void ac_discovery_run(void) {
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* */
|
||||
packet = (struct ac_discovery_packet*)itempacket->item;
|
||||
acpacket = (struct ac_discovery_packet*)itempacket->item;
|
||||
sizedata = itempacket->itemsize - sizeof(struct ac_discovery_packet);
|
||||
|
||||
/* Parsing packet */
|
||||
buildpacket = capwap_rx_packet_create(packet->data, sizedata, 1);
|
||||
if (buildpacket) {
|
||||
if (!capwap_build_packet_validate(buildpacket, NULL)) {
|
||||
struct capwap_element_discovery_request discoveryrequest;
|
||||
|
||||
/* */
|
||||
binding = GET_WBID_HEADER(&buildpacket->header);
|
||||
capwap_init_element_discovery_request(&discoveryrequest, binding);
|
||||
|
||||
/* Parsing elements list */
|
||||
if (capwap_parsing_element_discovery_request(&discoveryrequest, buildpacket->elementslist->first)) {
|
||||
struct capwap_build_packet* txpacket;
|
||||
capwap_fragment_packet_array* responsefragmentpacket = NULL;
|
||||
/* Accept only discovery request don't fragment */
|
||||
rxmngpacket = capwap_packet_rxmng_create_message(1);
|
||||
if (capwap_packet_rxmng_add_recv_packet(rxmngpacket, acpacket->data, sizedata) == CAPWAP_RECEIVE_COMPLETE_PACKET) {
|
||||
/* Validate message */
|
||||
if (capwap_check_message_type(rxmngpacket) == VALID_MESSAGE_TYPE) {
|
||||
/* Parsing packet */
|
||||
if (!capwap_parsing_packet(rxmngpacket, NULL, &packet)) {
|
||||
/* Validate packet */
|
||||
if (!capwap_validate_parsed_packet(&packet, NULL)) {
|
||||
struct capwap_packet_txmng* txmngpacket;
|
||||
|
||||
/* Creare discovery response */
|
||||
txpacket = ac_create_discovery_response(buildpacket, &discoveryrequest, &packet->sender);
|
||||
if (txpacket) {
|
||||
int result = -1;
|
||||
|
||||
if (!capwap_build_packet_validate(txpacket, NULL)) {
|
||||
responsefragmentpacket = capwap_array_create(sizeof(struct capwap_packet), 0);
|
||||
result = capwap_fragment_build_packet(txpacket, responsefragmentpacket, g_ac.mtu, g_ac_discovery.fragmentid);
|
||||
if (result == 1) {
|
||||
/* Creare discovery response */
|
||||
txmngpacket = ac_create_discovery_response(&packet);
|
||||
if (txmngpacket) {
|
||||
struct capwap_list* responsefragmentpacket;
|
||||
|
||||
/* Discovery response complete, get fragment packets */
|
||||
responsefragmentpacket = capwap_list_create();
|
||||
capwap_packet_txmng_get_fragment_packets(txmngpacket, responsefragmentpacket, g_ac_discovery.fragmentid);
|
||||
if (responsefragmentpacket->count > 1) {
|
||||
g_ac_discovery.fragmentid++;
|
||||
}
|
||||
} else {
|
||||
capwap_logging_debug("Warning: build invalid discovery response packet");
|
||||
}
|
||||
|
||||
capwap_build_packet_free(txpacket);
|
||||
|
||||
/* Send discovery response to WTP */
|
||||
if (result >= 0) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < responsefragmentpacket->count; i++) {
|
||||
struct capwap_packet* sendpacket = (struct capwap_packet*)capwap_array_get_item_pointer(responsefragmentpacket, i);
|
||||
ASSERT(sendpacket != NULL);
|
||||
|
||||
if (!capwap_sendto(packet->sendsock, sendpacket->header, sendpacket->packetsize, NULL, &packet->sender)) {
|
||||
capwap_logging_debug("Warning: error to send discovery response packet");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Free packets manager */
|
||||
capwap_packet_txmng_free(txmngpacket);
|
||||
|
||||
/* Send discovery response to WTP */
|
||||
if (!capwap_sendto_fragmentpacket(acpacket->sendsock, responsefragmentpacket, NULL, &acpacket->sender)) {
|
||||
capwap_logging_debug("Warning: error to send discovery response packet");
|
||||
}
|
||||
|
||||
/* Don't buffering a packets sent */
|
||||
capwap_list_free(responsefragmentpacket);
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't buffering a packets sent */
|
||||
if (responsefragmentpacket) {
|
||||
capwap_fragment_free(responsefragmentpacket);
|
||||
capwap_array_free(responsefragmentpacket);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free discovery request */
|
||||
capwap_free_element_discovery_request(&discoveryrequest, binding);
|
||||
|
||||
/* Free resource */
|
||||
capwap_free_parsed_packet(&packet);
|
||||
}
|
||||
|
||||
/* */
|
||||
capwap_build_packet_free(buildpacket);
|
||||
}
|
||||
|
||||
/* Free resource */
|
||||
capwap_packet_rxmng_free(rxmngpacket);
|
||||
|
||||
/* Free packet */
|
||||
capwap_itemlist_free(itempacket);
|
||||
}
|
||||
|
@ -58,44 +58,68 @@ static struct ac_session_t* ac_search_session_from_wtpaddress(struct sockaddr_st
|
||||
|
||||
/* */
|
||||
static struct ac_session_t* ac_get_session_from_keepalive(void* buffer, int buffersize) {
|
||||
struct capwap_parsed_packet packet;
|
||||
struct capwap_packet_rxmng* rxmngpacket;
|
||||
struct ac_session_t* result = NULL;
|
||||
struct capwap_build_packet* buildpacket;
|
||||
|
||||
ASSERT(buffer != NULL);
|
||||
ASSERT(buffersize > 0);
|
||||
|
||||
buildpacket = capwap_rx_packet_create(buffer, buffersize, 0);
|
||||
if (buildpacket) {
|
||||
struct capwap_sessionid_element sessionid;
|
||||
|
||||
if (capwap_get_sessionid_from_keepalive(buildpacket, &sessionid)) {
|
||||
/* Build receive manager CAPWAP message */
|
||||
rxmngpacket = capwap_packet_rxmng_create_message(0);
|
||||
if (capwap_packet_rxmng_add_recv_packet(rxmngpacket, buffer, buffersize) != CAPWAP_RECEIVE_COMPLETE_PACKET) {
|
||||
/* Accept only keep alive without fragmentation */
|
||||
capwap_packet_rxmng_free(rxmngpacket);
|
||||
capwap_logging_debug("Receive data keep alive packet fragmentated");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Validate message */
|
||||
if (capwap_check_message_type(rxmngpacket) != VALID_MESSAGE_TYPE) {
|
||||
/* Invalid message */
|
||||
capwap_packet_rxmng_free(rxmngpacket);
|
||||
capwap_logging_debug("Invalid data packet message type");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Parsing packet */
|
||||
if (!capwap_parsing_packet(rxmngpacket, NULL, &packet)) {
|
||||
/* Validate packet */
|
||||
if (!capwap_validate_parsed_packet(&packet, NULL)) {
|
||||
struct capwap_list_item* search;
|
||||
|
||||
ASSERT(packet.messageelements.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))) {
|
||||
|
||||
if (!memcmp(packet.messageelements.sessionid, &session->sessionid, sizeof(struct capwap_sessionid_element))) {
|
||||
session->count++;
|
||||
result = session;
|
||||
break;
|
||||
}
|
||||
|
||||
search = search->next;
|
||||
|
||||
search = search->next;
|
||||
}
|
||||
|
||||
|
||||
capwap_lock_exit(&g_ac.sessionslock);
|
||||
} else {
|
||||
capwap_logging_debug("Failed validation parsed data packet");
|
||||
}
|
||||
|
||||
/* Free */
|
||||
capwap_build_packet_free(buildpacket);
|
||||
} else {
|
||||
capwap_logging_debug("Failed parsing data packet");
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
/* Free resource */
|
||||
capwap_free_parsed_packet(&packet);
|
||||
capwap_packet_rxmng_free(rxmngpacket);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Close session */
|
||||
@ -117,7 +141,7 @@ static void ac_close_sessions() {
|
||||
|
||||
ac_close_session(session);
|
||||
|
||||
search = search->next;
|
||||
search = search->next;
|
||||
}
|
||||
|
||||
capwap_lock_exit(&g_ac.sessionslock);
|
||||
@ -246,7 +270,7 @@ static struct ac_session_t* ac_create_session(struct sockaddr_storage* wtpaddres
|
||||
int result;
|
||||
struct capwap_list_item* itemlist;
|
||||
struct ac_session_t* session;
|
||||
|
||||
|
||||
ASSERT(acaddress != NULL);
|
||||
ASSERT(wtpaddress != NULL);
|
||||
ASSERT(ctrlsock != NULL);
|
||||
@ -263,37 +287,36 @@ static struct ac_session_t* ac_create_session(struct sockaddr_storage* wtpaddres
|
||||
|
||||
/* Duplicate state for DFA */
|
||||
memcpy(&session->dfa, &g_ac.dfa, sizeof(struct ac_state));
|
||||
session->dfa.acipv4list = capwap_array_clone(g_ac.dfa.acipv4list);
|
||||
session->dfa.acipv6list = capwap_array_clone(g_ac.dfa.acipv6list);
|
||||
session->dfa.acipv4list.addresses = capwap_array_clone(g_ac.dfa.acipv4list.addresses);
|
||||
session->dfa.acipv6list.addresses = capwap_array_clone(g_ac.dfa.acipv6list.addresses);
|
||||
|
||||
session->dfa.rfcRetransmitInterval = AC_DEFAULT_RETRANSMIT_INTERVAL;
|
||||
session->dfa.rfcMaxRetransmit = AC_MAX_RETRANSMIT;
|
||||
session->dfa.rfcDTLSSessionDelete = AC_DEFAULT_DTLS_SESSION_DELETE;
|
||||
|
||||
/* Add default AC list if empty*/
|
||||
if ((session->dfa.acipv4list->count == 0) && (session->dfa.acipv6list->count == 0)) {
|
||||
if ((session->dfa.acipv4list.addresses->count == 0) && (session->dfa.acipv6list.addresses->count == 0)) {
|
||||
if (session->acctrladdress.ss_family == AF_INET) {
|
||||
struct capwap_acipv4list_element* acip = (struct capwap_acipv4list_element*)capwap_array_get_item_pointer(session->dfa.acipv4list, 0);
|
||||
memcpy(&acip->address, &((struct sockaddr_in*)&session->acctrladdress)->sin_addr, sizeof(struct in_addr));
|
||||
struct in_addr* acip = (struct in_addr*)capwap_array_get_item_pointer(session->dfa.acipv4list.addresses, 0);
|
||||
memcpy(acip, &((struct sockaddr_in*)&session->acctrladdress)->sin_addr, sizeof(struct in_addr));
|
||||
} else if (session->acctrladdress.ss_family == AF_INET6) {
|
||||
struct capwap_acipv6list_element* acip = (struct capwap_acipv6list_element*)capwap_array_get_item_pointer(session->dfa.acipv6list, 0);
|
||||
memcpy(&acip->address, &((struct sockaddr_in6*)&session->acctrladdress)->sin6_addr, sizeof(struct in6_addr));
|
||||
struct in6_addr* acip = (struct in6_addr*)capwap_array_get_item_pointer(session->dfa.acipv6list.addresses, 0);
|
||||
memcpy(acip, &((struct sockaddr_in6*)&session->acctrladdress)->sin6_addr, sizeof(struct in6_addr));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Init */
|
||||
capwap_event_init(&session->waitpacket);
|
||||
capwap_lock_init(&session->packetslock);
|
||||
|
||||
session->controlpackets = capwap_list_create();
|
||||
session->datapackets = capwap_list_create();
|
||||
session->requestfragmentpacket = capwap_array_create(sizeof(struct capwap_packet), 0);
|
||||
session->responsefragmentpacket = capwap_array_create(sizeof(struct capwap_packet), 0);
|
||||
session->rxfragmentpacket = capwap_defragment_init_list();
|
||||
|
||||
session->requestfragmentpacket = capwap_list_create();
|
||||
session->responsefragmentpacket = capwap_list_create();
|
||||
|
||||
session->mtu = g_ac.mtu;
|
||||
session->state = CAPWAP_IDLE_STATE;
|
||||
|
||||
|
||||
/* Update session list */
|
||||
capwap_lock_enter(&g_ac.sessionslock);
|
||||
capwap_itemlist_insert_after(g_ac.sessions, NULL, itemlist);
|
||||
@ -323,10 +346,10 @@ static struct ac_session_t* ac_create_session(struct sockaddr_storage* wtpaddres
|
||||
/* Update statistics */
|
||||
void ac_update_statistics(void) {
|
||||
|
||||
g_ac.descriptor.station = 0; /* TODO */
|
||||
g_ac.descriptor.stations = 0; /* TODO */
|
||||
|
||||
capwap_lock_enter(&g_ac.sessionslock);
|
||||
g_ac.descriptor.wtp = g_ac.sessions->count;
|
||||
g_ac.descriptor.activewtp = g_ac.sessions->count;
|
||||
capwap_lock_exit(&g_ac.sessionslock);
|
||||
}
|
||||
|
||||
@ -344,7 +367,7 @@ int ac_execute(void) {
|
||||
int result = CAPWAP_SUCCESSFUL;
|
||||
|
||||
int index;
|
||||
int check;
|
||||
int check;
|
||||
int isctrlsocket = 0;
|
||||
struct sockaddr_storage recvfromaddr;
|
||||
struct sockaddr_storage recvtoaddr;
|
||||
@ -400,15 +423,15 @@ int ac_execute(void) {
|
||||
if (getsockname(fds[index].fd, (struct sockaddr*)&sockinfo, &sockinfolen) < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
CAPWAP_SET_NETWORK_PORT(&recvtoaddr, CAPWAP_GET_NETWORK_PORT(&sockinfo));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Search the AC session */
|
||||
isctrlsocket = ((index < (fdscount / 2)) ? 1 : 0);
|
||||
session = ac_search_session_from_wtpaddress(&recvfromaddr, isctrlsocket);
|
||||
|
||||
|
||||
if (session) {
|
||||
/* Add packet*/
|
||||
ac_session_add_packet(session, buffer, buffersize, isctrlsocket, 0);
|
||||
@ -418,38 +441,38 @@ int ac_execute(void) {
|
||||
} else {
|
||||
if (isctrlsocket) {
|
||||
unsigned short sessioncount;
|
||||
|
||||
|
||||
/* Get current session number */
|
||||
capwap_lock_enter(&g_ac.sessionslock);
|
||||
sessioncount = g_ac.sessions->count;
|
||||
capwap_lock_exit(&g_ac.sessionslock);
|
||||
|
||||
|
||||
/* PreParsing packet for reduce a DoS attack */
|
||||
check = capwap_sanity_check(isctrlsocket, CAPWAP_UNDEF_STATE, buffer, buffersize, g_ac.enabledtls, 0);
|
||||
if (check == CAPWAP_PLAIN_PACKET) {
|
||||
struct capwap_header* header = (struct capwap_header*)buffer;
|
||||
|
||||
|
||||
/* Accepted only packet without fragmentation */
|
||||
if (!IS_FLAG_F_HEADER(header)) {
|
||||
int headersize = GET_HLEN_HEADER(header) * 4;
|
||||
if (buffersize >= (headersize + sizeof(struct capwap_control_message))) {
|
||||
struct capwap_control_message* control = (struct capwap_control_message*)((char*)buffer + headersize);
|
||||
unsigned long type = ntohl(control->type);
|
||||
|
||||
|
||||
if (type == CAPWAP_DISCOVERY_REQUEST) {
|
||||
if (sessioncount < g_ac.descriptor.wtplimit) {
|
||||
if (sessioncount < g_ac.descriptor.maxwtp) {
|
||||
ac_discovery_add_packet(buffer, buffersize, fds[index].fd, &recvfromaddr);
|
||||
}
|
||||
} else if (!g_ac.enabledtls && (type == CAPWAP_JOIN_REQUEST)) {
|
||||
if (sessioncount < g_ac.descriptor.wtplimit) {
|
||||
if (sessioncount < g_ac.descriptor.maxwtp) {
|
||||
/* Retrive socket info */
|
||||
capwap_get_network_socket(&g_ac.net, &ctrlsock, fds[index].fd);
|
||||
|
||||
|
||||
/* Create a new session */
|
||||
session = ac_create_session(&recvfromaddr, &recvtoaddr, &ctrlsock);
|
||||
if (session) {
|
||||
ac_session_add_packet(session, buffer, buffersize, isctrlsocket, 1);
|
||||
|
||||
|
||||
/* Release reference */
|
||||
ac_session_release_reference(session);
|
||||
}
|
||||
@ -459,7 +482,7 @@ int ac_execute(void) {
|
||||
}
|
||||
} else if (check == CAPWAP_DTLS_PACKET) {
|
||||
/* Need create a new sessione for check if it is a valid DTLS handshake */
|
||||
if (sessioncount < g_ac.descriptor.wtplimit) {
|
||||
if (sessioncount < g_ac.descriptor.maxwtp) {
|
||||
/* TODO prevent dos attack add filtering ip for multiple error */
|
||||
|
||||
/* Retrive socket info */
|
||||
@ -512,7 +535,7 @@ int ac_execute(void) {
|
||||
|
||||
/* Wait that list is changed */
|
||||
capwap_logging_debug("Waiting for %d session terminate", count);
|
||||
capwap_event_wait(&g_ac.changesessionlist);
|
||||
capwap_event_wait(&g_ac.changesessionlist);
|
||||
}
|
||||
|
||||
/* Free handshark session */
|
||||
|
@ -27,6 +27,11 @@ static int ac_network_read(struct ac_session_t* session, void* buffer, int lengt
|
||||
struct capwap_list_item* itempacket;
|
||||
|
||||
*isctrlpacket = ((session->controlpackets->count > 0) ? 1 : 0);
|
||||
if (*isctrlpacket) {
|
||||
capwap_logging_debug("Receive control packet");
|
||||
} else {
|
||||
capwap_logging_debug("Receive data packet");
|
||||
}
|
||||
|
||||
/* Get packet */
|
||||
itempacket = capwap_itemlist_remove_head((*isctrlpacket ? session->controlpackets : session->datapackets));
|
||||
@ -70,7 +75,7 @@ static int ac_network_read(struct ac_session_t* session, void* buffer, int lengt
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
capwap_lock_exit(&session->packetslock);
|
||||
|
||||
/* Update timeout */
|
||||
@ -88,7 +93,7 @@ static int ac_network_read(struct ac_session_t* session, void* buffer, int lengt
|
||||
}
|
||||
|
||||
/* */
|
||||
static int ac_dfa_execute(struct ac_session_t* session, struct capwap_packet* packet) {
|
||||
static int ac_dfa_execute(struct ac_session_t* session, struct capwap_parsed_packet* packet) {
|
||||
int action = AC_DFA_ACCEPT_PACKET;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
@ -366,12 +371,47 @@ static int ac_dfa_execute(struct ac_session_t* session, struct capwap_packet* pa
|
||||
return action;
|
||||
}
|
||||
|
||||
/* */
|
||||
static struct capwap_packet_rxmng* ac_get_packet_rxmng(struct ac_session_t* session, int isctrlmsg) {
|
||||
struct capwap_packet_rxmng* rxmngpacket = NULL;
|
||||
|
||||
if (isctrlmsg) {
|
||||
if (!session->rxmngctrlpacket) {
|
||||
session->rxmngctrlpacket = capwap_packet_rxmng_create_message(1);
|
||||
}
|
||||
|
||||
rxmngpacket = session->rxmngctrlpacket;
|
||||
} else {
|
||||
if (!session->rxmngdatapacket) {
|
||||
session->rxmngdatapacket = capwap_packet_rxmng_create_message(0);
|
||||
}
|
||||
|
||||
rxmngpacket = session->rxmngdatapacket;
|
||||
}
|
||||
|
||||
return rxmngpacket;
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_free_packet_rxmng(struct ac_session_t* session, int isctrlmsg) {
|
||||
if (isctrlmsg && session->rxmngctrlpacket) {
|
||||
capwap_packet_rxmng_free(session->rxmngctrlpacket);
|
||||
session->rxmngctrlpacket = NULL;
|
||||
} else if (!isctrlmsg && session->rxmngdatapacket) {
|
||||
capwap_packet_rxmng_free(session->rxmngdatapacket);
|
||||
session->rxmngdatapacket = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
static void ac_session_run(struct ac_session_t* session) {
|
||||
int res;
|
||||
int check;
|
||||
int length;
|
||||
int isctrlsocket;
|
||||
int action = AC_DFA_ACCEPT_PACKET;
|
||||
struct capwap_connection connection;
|
||||
char buffer[CAPWAP_MAX_PACKET_SIZE];
|
||||
int action = AC_DFA_ACCEPT_PACKET;
|
||||
|
||||
ASSERT(session != NULL);
|
||||
|
||||
@ -402,35 +442,66 @@ static void ac_session_run(struct ac_session_t* session) {
|
||||
/* Check generic capwap packet */
|
||||
check = capwap_sanity_check(isctrlsocket, CAPWAP_UNDEF_STATE, buffer, length, 0, 0);
|
||||
if (check == CAPWAP_PLAIN_PACKET) {
|
||||
struct capwap_packet packet;
|
||||
|
||||
check = capwap_defragment_packets(&session->wtpctrladdress, buffer, length, session->rxfragmentpacket, &packet);
|
||||
struct capwap_parsed_packet packet;
|
||||
struct capwap_packet_rxmng* rxmngpacket;
|
||||
|
||||
/* Defragment management */
|
||||
rxmngpacket = ac_get_packet_rxmng(session, isctrlsocket);
|
||||
|
||||
/* If request, defragmentation packet */
|
||||
check = capwap_packet_rxmng_add_recv_packet(rxmngpacket, buffer, length);
|
||||
if (check == CAPWAP_RECEIVE_COMPLETE_PACKET) {
|
||||
int ignorepacket = 0;
|
||||
|
||||
|
||||
/* Receive all fragment */
|
||||
memcpy(&connection.socket, (isctrlsocket ? &session->ctrlsocket : &session->datasocket), sizeof(struct capwap_socket));
|
||||
memcpy(&connection.localaddr, (isctrlsocket ? &session->acctrladdress : &session->acdataaddress), sizeof(struct sockaddr_storage));
|
||||
memcpy(&connection.remoteaddr, (isctrlsocket ? &session->wtpctrladdress : &session->wtpdataaddress), sizeof(struct sockaddr_storage));
|
||||
|
||||
if (isctrlsocket) {
|
||||
/* Check for already response to packet */
|
||||
if (capwap_recv_retrasmitted_request(&session->ctrldtls, &packet, session->remoteseqnumber, session->lastrecvpackethash, &session->ctrlsocket, session->responsefragmentpacket, &session->acctrladdress, &session->wtpctrladdress)) {
|
||||
ignorepacket = 1;
|
||||
}
|
||||
|
||||
/* Check message type */
|
||||
if (!capwap_check_message_type(&session->ctrldtls, &packet, session->mtu)) {
|
||||
if (!capwap_recv_retrasmitted_request(&session->ctrldtls, rxmngpacket, &connection, session->lastrecvpackethash, session->responsefragmentpacket)) {
|
||||
/* Check message type */
|
||||
res = capwap_check_message_type(rxmngpacket);
|
||||
if (res != VALID_MESSAGE_TYPE) {
|
||||
if (res == INVALID_REQUEST_MESSAGE_TYPE) {
|
||||
/*TODO wtp_send_invalid_request(rxmngpacket, &connection);*/
|
||||
}
|
||||
|
||||
ignorepacket = 1;
|
||||
capwap_logging_debug("Invalid message type");
|
||||
}
|
||||
} else {
|
||||
ignorepacket = 1;
|
||||
capwap_logging_debug("Retrasmitted packet");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Parsing packet */
|
||||
if (!ignorepacket) {
|
||||
if (!capwap_parsing_packet(rxmngpacket, &connection, &packet)) {
|
||||
/* Validate packet */
|
||||
if (capwap_validate_parsed_packet(&packet, NULL)) {
|
||||
/* TODO gestione errore risposta */
|
||||
ignorepacket = 1;
|
||||
capwap_logging_debug("Failed validation parsed packet");
|
||||
}
|
||||
} else {
|
||||
ignorepacket = 1;
|
||||
capwap_logging_debug("Failed parsing packet");
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
if (!ignorepacket && (action == AC_DFA_ACCEPT_PACKET)) {
|
||||
memcpy(&packet.socket, (isctrlsocket ? &session->ctrlsocket : &session->datasocket), sizeof(struct capwap_socket));
|
||||
action = ac_dfa_execute(session, &packet);
|
||||
}
|
||||
|
||||
/* Free packet */
|
||||
capwap_free_packet(&packet);
|
||||
|
||||
/* Free memory */
|
||||
capwap_free_parsed_packet(&packet);
|
||||
ac_free_packet_rxmng(session, isctrlsocket);
|
||||
} else if (check != CAPWAP_REQUEST_MORE_FRAGMENT) {
|
||||
/* Discard fragments */
|
||||
capwap_defragment_remove_sender(session->rxfragmentpacket, &session->wtpctrladdress);
|
||||
ac_free_packet_rxmng(session, isctrlsocket);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -508,27 +579,27 @@ int ac_session_release_reference(struct ac_session_t* session) {
|
||||
capwap_lock_exit(&session->packetslock);
|
||||
capwap_list_free(session->controlpackets);
|
||||
capwap_list_free(session->datapackets);
|
||||
capwap_defragment_free_list(session->rxfragmentpacket);
|
||||
|
||||
/* Free fragments packet */
|
||||
capwap_fragment_free(session->requestfragmentpacket);
|
||||
capwap_fragment_free(session->responsefragmentpacket);
|
||||
capwap_array_free(session->requestfragmentpacket);
|
||||
capwap_array_free(session->responsefragmentpacket);
|
||||
ac_free_packet_rxmng(session, 1);
|
||||
ac_free_packet_rxmng(session, 0);
|
||||
|
||||
capwap_list_free(session->requestfragmentpacket);
|
||||
capwap_list_free(session->responsefragmentpacket);
|
||||
|
||||
/* Free DFA resource */
|
||||
capwap_array_free(session->dfa.acipv4list);
|
||||
capwap_array_free(session->dfa.acipv6list);
|
||||
capwap_array_free(session->dfa.acipv4list.addresses);
|
||||
capwap_array_free(session->dfa.acipv6list.addresses);
|
||||
|
||||
/* Remove item from list */
|
||||
remove = 1;
|
||||
capwap_itemlist_free(capwap_itemlist_remove(g_ac.sessions, search));
|
||||
capwap_event_signal(&g_ac.changesessionlist);
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
search = search->next;
|
||||
|
||||
search = search->next;
|
||||
}
|
||||
}
|
||||
|
||||
@ -547,7 +618,7 @@ void* ac_session_thread(void* param) {
|
||||
|
||||
/* Thread exit */
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* */
|
||||
@ -596,22 +667,22 @@ void ac_get_control_information(struct capwap_list* controllist) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* */
|
||||
capwap_lock_exit(&g_ac.sessionslock);
|
||||
capwap_lock_exit(&g_ac.sessionslock);
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_free_reference_last_request(struct ac_session_t* session) {
|
||||
ASSERT(session);
|
||||
|
||||
capwap_fragment_free(session->requestfragmentpacket);
|
||||
capwap_list_flush(session->requestfragmentpacket);
|
||||
}
|
||||
|
||||
/* */
|
||||
void ac_free_reference_last_response(struct ac_session_t* session) {
|
||||
ASSERT(session);
|
||||
|
||||
capwap_fragment_free(session->responsefragmentpacket);
|
||||
capwap_list_flush(session->responsefragmentpacket);
|
||||
memset(&session->lastrecvpackethash[0], 0, sizeof(session->lastrecvpackethash));
|
||||
}
|
||||
|
@ -51,9 +51,10 @@ struct ac_session_t {
|
||||
unsigned char remoteseqnumber;
|
||||
unsigned short mtu;
|
||||
unsigned short fragmentid;
|
||||
capwap_fragment_list* rxfragmentpacket;
|
||||
capwap_fragment_packet_array* requestfragmentpacket;
|
||||
capwap_fragment_packet_array* responsefragmentpacket;
|
||||
struct capwap_packet_rxmng* rxmngctrlpacket;
|
||||
struct capwap_packet_rxmng* rxmngdatapacket;
|
||||
struct capwap_list* requestfragmentpacket;
|
||||
struct capwap_list* responsefragmentpacket;
|
||||
unsigned char lastrecvpackethash[16];
|
||||
|
||||
unsigned long state;
|
||||
@ -73,40 +74,40 @@ void ac_free_reference_last_request(struct ac_session_t* session);
|
||||
void ac_free_reference_last_response(struct ac_session_t* session);
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_join(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
int ac_dfa_state_postjoin(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
int ac_dfa_state_join_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
int ac_dfa_state_join(struct ac_session_t* session, struct capwap_parsed_packet* packet);
|
||||
int ac_dfa_state_postjoin(struct ac_session_t* session, struct capwap_parsed_packet* packet);
|
||||
int ac_dfa_state_join_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet);
|
||||
|
||||
/* */
|
||||
int ac_bio_send(struct capwap_dtls* dtls, char* buffer, int length, void* param);
|
||||
int ac_dfa_state_dtlssetup(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
int ac_dfa_state_dtlsconnect(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
int ac_dfa_state_dtlsconnect_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
int ac_dfa_state_dtlssetup(struct ac_session_t* session, struct capwap_parsed_packet* packet);
|
||||
int ac_dfa_state_dtlsconnect(struct ac_session_t* session, struct capwap_parsed_packet* packet);
|
||||
int ac_dfa_state_dtlsconnect_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet);
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_configure(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
int ac_dfa_state_configure_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
int ac_dfa_state_configure(struct ac_session_t* session, struct capwap_parsed_packet* packet);
|
||||
int ac_dfa_state_configure_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet);
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_datacheck(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
int ac_dfa_state_datacheck_to_run(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
int ac_dfa_state_datacheck_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
int ac_dfa_state_datacheck(struct ac_session_t* session, struct capwap_parsed_packet* packet);
|
||||
int ac_dfa_state_datacheck_to_run(struct ac_session_t* session, struct capwap_parsed_packet* packet);
|
||||
int ac_dfa_state_datacheck_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet);
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_imagedata(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
int ac_dfa_state_imagedata_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
int ac_dfa_state_imagedata(struct ac_session_t* session, struct capwap_parsed_packet* packet);
|
||||
int ac_dfa_state_imagedata_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet);
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_run(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
int ac_dfa_state_run_to_reset(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
int ac_dfa_state_run_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
int ac_dfa_state_run(struct ac_session_t* session, struct capwap_parsed_packet* packet);
|
||||
int ac_dfa_state_run_to_reset(struct ac_session_t* session, struct capwap_parsed_packet* packet);
|
||||
int ac_dfa_state_run_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet);
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_reset(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
int ac_dfa_state_reset_to_dtlsteardown(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
int ac_dfa_state_reset(struct ac_session_t* session, struct capwap_parsed_packet* packet);
|
||||
int ac_dfa_state_reset_to_dtlsteardown(struct ac_session_t* session, struct capwap_parsed_packet* packet);
|
||||
|
||||
/* */
|
||||
int ac_dfa_state_teardown(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
int ac_dfa_state_dead(struct ac_session_t* session, struct capwap_packet* packet);
|
||||
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);
|
||||
|
||||
#endif /* __AC_SESSION_HEADER__ */
|
||||
|
Reference in New Issue
Block a user