From c2ff7e0db53ba0d9d49cea4707794b765bb6887e Mon Sep 17 00:00:00 2001 From: vemax78 Date: Thu, 25 Jul 2013 23:12:43 +0200 Subject: [PATCH] First stone for the management the AC via webservice --- src/ac/ac_backend.c | 3 -- src/ac/ac_backend.h | 3 ++ src/ac/ac_dfa_join.c | 39 +++++++++++++++------- src/ac/ac_execute.c | 16 +++++----- src/ac/ac_session.c | 64 ++++++++++++++++++++++++++++++++++--- src/ac/ac_session.h | 13 +++++++- webservice/smartcapwap.wsdl | 29 +++++++++++++++-- 7 files changed, 136 insertions(+), 31 deletions(-) diff --git a/src/ac/ac_backend.c b/src/ac/ac_backend.c index 27be7b2..eea355c 100644 --- a/src/ac/ac_backend.c +++ b/src/ac/ac_backend.c @@ -2,9 +2,6 @@ #include "ac_backend.h" #include "ac_soap.h" -/* */ -#define SOAP_NAMESPACE_URI "http://smartcapwap/namespace" - /* */ #define AC_BACKEND_WAIT_TIMEOUT 10000 #define SOAP_PROTOCOL_RESPONSE_WAIT_EVENT_TIMEOUT 70000 diff --git a/src/ac/ac_backend.h b/src/ac/ac_backend.h index c24119d..4f3ce47 100644 --- a/src/ac/ac_backend.h +++ b/src/ac/ac_backend.h @@ -1,6 +1,9 @@ #ifndef __AC_BACKEND_HEADER__ #define __AC_BACKEND_HEADER__ +/* */ +#define SOAP_NAMESPACE_URI "http://smartcapwap/namespace" + /* */ int ac_backend_start(void); void ac_backend_stop(void); diff --git a/src/ac/ac_dfa_join.c b/src/ac/ac_dfa_join.c index 3e48979..7d61397 100644 --- a/src/ac/ac_dfa_join.c +++ b/src/ac/ac_dfa_join.c @@ -2,6 +2,12 @@ #include "capwap_dfa.h" #include "capwap_array.h" #include "ac_session.h" +#include "ac_backend.h" + +/* */ +static int ac_dfa_state_join_check_authorizejoin(struct ac_session_t* session, struct ac_soap_response* response) { + return CAPWAP_RESULTCODE_SUCCESS; +} /* */ int ac_dfa_state_join(struct ac_session_t* session, struct capwap_parsed_packet* packet) { @@ -30,18 +36,29 @@ int ac_dfa_state_join(struct ac_session_t* session, struct capwap_parsed_packet* wtpboarddata = (struct capwap_wtpboarddata_element*)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_WTPBOARDDATA); wtpboarddatamacaddress = capwap_wtpboarddata_get_subelement(wtpboarddata, CAPWAP_BOARD_SUBELEMENT_MACADDRESS); if (wtpboarddatamacaddress && !ac_has_wtpid((unsigned char*)wtpboarddatamacaddress->data, (unsigned short)wtpboarddatamacaddress->length)) { - /* Valid WTP id */ - session->wtpid = capwap_clone(wtpboarddatamacaddress->data, wtpboarddatamacaddress->length); - session->wtpidlength = wtpboarddatamacaddress->length; + struct ac_soap_response* response; - /* Valid session id */ - memcpy(&session->sessionid, sessionid, sizeof(struct capwap_sessionid_element)); - - /* Get binding */ - session->binding = binding; - - /* Valid Join */ - resultcode.code = CAPWAP_RESULTCODE_SUCCESS; + /* Request authorization of Backend for complete join */ + response = ac_session_send_soap_request(session, "authorizeJoin"); + if (response) { + /* Validate Join */ + resultcode.code = ac_dfa_state_join_check_authorizejoin(session, response); + ac_soapclient_free_response(response); + + /* Valid WTP */ + if (resultcode.code == CAPWAP_RESULTCODE_SUCCESS) { + session->wtpid = capwap_clone(wtpboarddatamacaddress->data, wtpboarddatamacaddress->length); + session->wtpidlength = wtpboarddatamacaddress->length; + + /* Session id */ + memcpy(&session->sessionid, sessionid, sizeof(struct capwap_sessionid_element)); + + /* Binding */ + session->binding = binding; + } + } else { + resultcode.code = CAPWAP_RESULTCODE_JOIN_FAILURE_UNKNOWN_SOURCE; + } } else { resultcode.code = CAPWAP_RESULTCODE_JOIN_FAILURE_UNKNOWN_SOURCE; } diff --git a/src/ac/ac_execute.c b/src/ac/ac_execute.c index f9ee733..8066063 100644 --- a/src/ac/ac_execute.c +++ b/src/ac/ac_execute.c @@ -23,10 +23,10 @@ static void ac_session_add_packet(struct ac_session_t* session, char* buffer, in memcpy(packet->buffer, buffer, size); /* Append to packets list */ - capwap_lock_enter(&session->packetslock); + capwap_lock_enter(&session->sessionlock); capwap_itemlist_insert_after((isctrlsocket ? session->controlpackets : session->datapackets), NULL, item); capwap_event_signal(&session->waitpacket); - capwap_lock_exit(&session->packetslock); + capwap_lock_exit(&session->sessionlock); } /* Add action to session */ @@ -49,10 +49,10 @@ void ac_session_send_action(struct ac_session_t* session, long action, long para } /* Append to actions list */ - capwap_lock_enter(&session->packetslock); + capwap_lock_enter(&session->sessionlock); capwap_itemlist_insert_after(session->actionsession, NULL, item); capwap_event_signal(&session->waitpacket); - capwap_lock_exit(&session->packetslock); + capwap_lock_exit(&session->sessionlock); } /* Find AC sessions */ @@ -392,7 +392,7 @@ static struct ac_session_t* ac_create_session(struct sockaddr_storage* wtpaddres /* Init */ capwap_event_init(&session->waitpacket); - capwap_lock_init(&session->packetslock); + capwap_lock_init(&session->sessionlock); session->actionsession = capwap_list_create(); session->controlpackets = capwap_list_create(); @@ -555,11 +555,11 @@ int ac_execute(void) { unsigned long type = ntohl(control->type); if (type == CAPWAP_DISCOVERY_REQUEST) { - if (sessioncount < g_ac.descriptor.maxwtp) { + if (ac_backend_isconnect() && (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.maxwtp) { + if (ac_backend_isconnect() && (sessioncount < g_ac.descriptor.maxwtp)) { /* Retrive socket info */ capwap_get_network_socket(&g_ac.net, &ctrlsock, fds[index].fd); @@ -577,7 +577,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.maxwtp) { + if (ac_backend_isconnect() && (sessioncount < g_ac.descriptor.maxwtp)) { /* TODO prevent dos attack add filtering ip for multiple error */ /* Retrive socket info */ diff --git a/src/ac/ac_session.c b/src/ac/ac_session.c index 72fbbd5..be0f024 100644 --- a/src/ac/ac_session.c +++ b/src/ac/ac_session.c @@ -1,6 +1,7 @@ #include "ac.h" #include "capwap_dfa.h" #include "ac_session.h" +#include "ac_backend.h" #define PACKET_TIMEOUT -1 #define DTLS_SHUTDOWN -2 @@ -32,13 +33,13 @@ static int ac_network_read(struct ac_session_t* session, void* buffer, int lengt ASSERT(isctrlpacket != NULL); for (;;) { - capwap_lock_enter(&session->packetslock); + capwap_lock_enter(&session->sessionlock); if (session->actionsession->count > 0) { struct capwap_list_item* itemaction; itemaction = capwap_itemlist_remove_head(session->actionsession); - capwap_lock_exit(&session->packetslock); + capwap_lock_exit(&session->sessionlock); /* */ result = ac_session_action_execute(session, (struct ac_session_action*)itemaction->item); @@ -58,7 +59,7 @@ static int ac_network_read(struct ac_session_t* session, void* buffer, int lengt /* Get packet */ itempacket = capwap_itemlist_remove_head((*isctrlpacket ? session->controlpackets : session->datapackets)); - capwap_lock_exit(&session->packetslock); + capwap_lock_exit(&session->sessionlock); if (itempacket) { struct ac_packet* packet = (struct ac_packet*)itempacket->item; @@ -99,7 +100,7 @@ static int ac_network_read(struct ac_session_t* session, void* buffer, int lengt return result; } - capwap_lock_exit(&session->packetslock); + capwap_lock_exit(&session->sessionlock); /* Update timeout */ capwap_update_timeout(timeout); @@ -609,7 +610,7 @@ int ac_session_release_reference(struct ac_session_t* session) { /* Free resource */ capwap_event_destroy(&session->waitpacket); - capwap_lock_exit(&session->packetslock); + capwap_lock_exit(&session->sessionlock); capwap_list_free(session->actionsession); capwap_list_free(session->controlpackets); capwap_list_free(session->datapackets); @@ -724,3 +725,56 @@ void ac_free_reference_last_response(struct ac_session_t* session) { capwap_list_flush(session->responsefragmentpacket); memset(&session->lastrecvpackethash[0], 0, sizeof(session->lastrecvpackethash)); } + +/* */ +struct ac_soap_response* ac_session_send_soap_request(struct ac_session_t* session, char* method) { + struct ac_soap_request* request; + struct ac_http_soap_server* server; + struct ac_soap_response* response = NULL; + + ASSERT(session != NULL); + ASSERT(session->soaprequest == NULL); + ASSERT(method != NULL); + + /* Get HTTP Soap Server */ + server = ac_backend_gethttpsoapserver(); + if (!server) { + return NULL; + } + + /* Critical section */ + capwap_lock_enter(&session->sessionlock); + + /* Build Soap Request */ + request = ac_soapclient_create_request(method, SOAP_NAMESPACE_URI); + if (request) { + session->soaprequest = ac_soapclient_prepare_request(request, server); + } + + capwap_lock_exit(&session->sessionlock); + + /* */ + if (!session->soaprequest) { + if (request) { + ac_soapclient_free_request(request); + } + + return NULL; + } + + /* Send Request & Recv Response */ + if (ac_soapclient_send_request(session->soaprequest, "")) { + response = ac_soapclient_recv_response(session->soaprequest); + } + + /* Critical section */ + capwap_lock_enter(&session->sessionlock); + + /* Free resource */ + ac_soapclient_close_request(session->soaprequest, 1); + session->soaprequest = NULL; + + capwap_lock_exit(&session->sessionlock); + + return response; +} diff --git a/src/ac/ac_session.h b/src/ac/ac_session.h index 63e2895..16cb277 100644 --- a/src/ac/ac_session.h +++ b/src/ac/ac_session.h @@ -2,6 +2,7 @@ #define __AC_SESSION_HEADER__ #include "capwap_dtls.h" +#include "ac_soap.h" #define AC_DFA_NO_PACKET 0 #define AC_DFA_ACCEPT_PACKET 1 @@ -35,6 +36,10 @@ struct ac_session_action { struct ac_session_t { struct ac_state dfa; + /* Soap */ + struct ac_http_soap_request* soaprequest; + + /* */ unsigned char* wtpid; unsigned short wtpidlength; @@ -56,7 +61,7 @@ struct ac_session_t { pthread_t threadid; capwap_event_t waitpacket; - capwap_lock_t packetslock; + capwap_lock_t sessionlock; struct capwap_list* actionsession; struct capwap_list* controlpackets; struct capwap_list* datapackets; @@ -76,16 +81,22 @@ struct ac_session_t { struct capwap_imageidentifier_element startupimage; }; +/* */ void* ac_session_thread(void* param); int ac_session_teardown_connection(struct ac_session_t* session); int ac_session_release_reference(struct ac_session_t* session); +/* */ void ac_session_send_action(struct ac_session_t* session, long action, long param, void* data, long length); +struct ac_soap_response* ac_session_send_soap_request(struct ac_session_t* session, char* method); +/* */ void ac_dfa_change_state(struct ac_session_t* session, int state); +/* */ void ac_get_control_information(struct capwap_list* controllist); +/* */ void ac_free_reference_last_request(struct ac_session_t* session); void ac_free_reference_last_response(struct ac_session_t* session); diff --git a/webservice/smartcapwap.wsdl b/webservice/smartcapwap.wsdl index 7f786f1..cc12626 100644 --- a/webservice/smartcapwap.wsdl +++ b/webservice/smartcapwap.wsdl @@ -12,6 +12,8 @@ + + @@ -28,6 +30,12 @@ + + + + + + @@ -52,7 +60,19 @@ - + + + + + + + + + + + + + @@ -63,10 +83,13 @@ - + - + + + +