2013-05-01 14:52:55 +02:00
# include "wtp.h"
# include "capwap_dfa.h"
# include "wtp_dfa.h"
2014-03-02 19:31:27 +01:00
/* */
static void wtp_dfa_state_dtlsconnect_timeout ( struct capwap_timeout * timeout , unsigned long index , void * context , void * param ) {
wtp_teardown_connection ( ) ;
}
2013-05-01 14:52:55 +02:00
/* */
2014-02-19 19:16:33 +01:00
void wtp_start_dtlssetup ( void ) {
2013-05-01 14:52:55 +02:00
/* Create DTLS session */
2014-09-10 21:58:23 +02:00
if ( ! capwap_crypt_createsession ( & g_wtp . dtls , & g_wtp . dtlscontext ) ) {
2013-11-07 22:06:29 +01:00
wtp_dfa_change_state ( CAPWAP_SULKING_STATE ) ;
2014-03-02 19:31:27 +01:00
capwap_timeout_set ( g_wtp . timeout , g_wtp . idtimercontrol , WTP_SILENT_INTERVAL , wtp_dfa_state_sulking_timeout , NULL , NULL ) ;
2013-05-01 14:52:55 +02:00
} else {
2014-09-10 21:58:23 +02:00
if ( capwap_crypt_open ( & g_wtp . dtls ) = = CAPWAP_HANDSHAKE_ERROR ) {
2013-11-07 22:06:29 +01:00
wtp_dfa_change_state ( CAPWAP_SULKING_STATE ) ;
2014-03-02 19:31:27 +01:00
capwap_timeout_set ( g_wtp . timeout , g_wtp . idtimercontrol , WTP_SILENT_INTERVAL , wtp_dfa_state_sulking_timeout , NULL , NULL ) ;
2013-05-01 14:52:55 +02:00
} else {
2013-11-07 22:06:29 +01:00
wtp_dfa_change_state ( CAPWAP_DTLS_CONNECT_STATE ) ;
2014-03-02 19:31:27 +01:00
capwap_timeout_set ( g_wtp . timeout , g_wtp . idtimercontrol , WTP_DTLS_INTERVAL , wtp_dfa_state_dtlsconnect_timeout , NULL , NULL ) ;
2013-05-01 14:52:55 +02:00
}
}
}
/* */
2014-02-19 19:16:33 +01:00
void wtp_start_datachannel ( void ) {
2014-09-10 21:58:23 +02:00
union sockaddr_capwap dataaddr ;
/* Set AC data address */
memcpy ( & dataaddr , & g_wtp . dtls . peeraddr , sizeof ( union sockaddr_capwap ) ) ;
CAPWAP_SET_NETWORK_PORT ( & dataaddr , ( CAPWAP_GET_NETWORK_PORT ( & g_wtp . dtls . peeraddr ) + 1 ) ) ;
2014-12-28 15:48:52 +01:00
# ifdef DEBUG
{
char addr [ INET6_ADDRSTRLEN ] ;
capwap_logging_debug ( " Create data channel with peer %s:%d " , capwap_address_to_string ( & dataaddr , addr , INET6_ADDRSTRLEN ) , ( int ) CAPWAP_GET_NETWORK_PORT ( & dataaddr ) ) ;
}
# endif
2016-02-18 15:06:39 +01:00
/* Bind data address and Connect to AC data channel */
2016-02-22 16:54:54 +01:00
if ( wtp_kmod_create ( g_wtp . net . localaddr . ss . ss_family , & dataaddr . ss , & g_wtp . sessionid , g_wtp . mtu ) = = 0 ) {
capwap_logging_error ( " Data channel connected " ) ;
2014-09-10 21:58:23 +02:00
/* Reset AC Prefered List Position */
g_wtp . acpreferedselected = 0 ;
/* Set timer */
wtp_dfa_change_state ( CAPWAP_RUN_STATE ) ;
capwap_timeout_unset ( g_wtp . timeout , g_wtp . idtimercontrol ) ;
capwap_timeout_set ( g_wtp . timeout , g_wtp . idtimerecho , g_wtp . echointerval , wtp_dfa_state_run_echo_timeout , NULL , NULL ) ;
capwap_timeout_set ( g_wtp . timeout , g_wtp . idtimerkeepalivedead , WTP_DATACHANNEL_KEEPALIVEDEAD , wtp_dfa_state_run_keepalivedead_timeout , NULL , NULL ) ;
2013-11-07 22:06:29 +01:00
} else {
2014-09-10 21:58:23 +02:00
/* Error to send packets */
capwap_logging_error ( " Error to send data channel keepalive packet " ) ;
2014-02-19 19:16:33 +01:00
wtp_teardown_connection ( ) ;
2013-11-07 22:06:29 +01:00
}
2013-05-01 14:52:55 +02:00
}
/* */
2016-03-26 17:20:50 +01:00
static void wtp_dfa_state_dtlsteardown_timeout ( struct capwap_timeout * timeout ,
unsigned long index , void * context , void * param )
{
2013-05-01 14:52:55 +02:00
/* Free and reset resource */
2016-03-26 17:25:15 +01:00
if ( g_wtp . dtls . enable )
2014-09-10 21:58:23 +02:00
capwap_crypt_freesession ( & g_wtp . dtls ) ;
2013-05-01 14:52:55 +02:00
2013-06-09 17:41:52 +02:00
/* */
if ( g_wtp . acname . name ) {
capwap_free ( g_wtp . acname . name ) ;
g_wtp . acname . name = NULL ;
}
2013-05-01 14:52:55 +02:00
/* */
wtp_free_reference_last_request ( ) ;
wtp_free_reference_last_response ( ) ;
2014-09-10 21:58:23 +02:00
wtp_free_packet_rxmng ( ) ;
2013-05-01 14:52:55 +02:00
2013-06-05 19:39:03 +02:00
/* */
if ( ! g_wtp . running ) {
2013-11-07 22:06:29 +01:00
wtp_dfa_change_state ( CAPWAP_DEAD_STATE ) ;
2016-03-26 17:20:50 +01:00
} else if ( ( g_wtp . faileddtlssessioncount > = WTP_FAILED_DTLS_SESSION_RETRY ) | |
( g_wtp . faileddtlsauthfailcount > = WTP_FAILED_DTLS_SESSION_RETRY ) ) {
2013-11-07 22:06:29 +01:00
wtp_dfa_change_state ( CAPWAP_SULKING_STATE ) ;
2016-03-26 17:20:50 +01:00
capwap_timeout_set ( g_wtp . timeout , g_wtp . idtimercontrol , WTP_SILENT_INTERVAL ,
wtp_dfa_state_sulking_timeout , NULL , NULL ) ;
2013-05-01 14:52:55 +02:00
} else {
2013-11-07 22:06:29 +01:00
wtp_dfa_change_state ( CAPWAP_IDLE_STATE ) ;
2014-03-02 19:31:27 +01:00
wtp_dfa_state_idle ( ) ;
2013-05-01 14:52:55 +02:00
}
}
2014-03-02 19:31:27 +01:00
/* */
void wtp_dfa_state_dtlsteardown ( struct capwap_parsed_packet * packet ) {
}
/* Teardown connection */
2016-03-26 17:20:50 +01:00
void wtp_teardown_connection ( void )
{
2014-03-02 19:31:27 +01:00
g_wtp . teardown = 1 ;
2014-09-10 21:58:23 +02:00
/* TODO: close SSID ? */
2014-03-02 19:31:27 +01:00
/* DTSL Control */
2016-03-26 17:25:15 +01:00
if ( g_wtp . dtls . enable )
2014-09-10 21:58:23 +02:00
capwap_crypt_close ( & g_wtp . dtls ) ;
2014-03-02 19:31:27 +01:00
2014-09-10 21:58:23 +02:00
/* Close data channel session */
wtp_kmod_resetsession ( ) ;
2014-03-02 19:31:27 +01:00
/* */
wtp_dfa_change_state ( CAPWAP_DTLS_TEARDOWN_STATE ) ;
capwap_timeout_unsetall ( g_wtp . timeout ) ;
2016-03-26 17:20:50 +01:00
capwap_timeout_set ( g_wtp . timeout , g_wtp . idtimercontrol , WTP_DTLS_SESSION_DELETE ,
wtp_dfa_state_dtlsteardown_timeout , NULL , NULL ) ;
2014-03-02 19:31:27 +01:00
}