bool finalize_redirector() { hash_iterator iter; hash_entry *entry; host_entry *host_entry; if ( host_db != NULL ) { delete_timer_event( age_host_db, NULL ); init_hash_iterator( host_db, &iter ); while ( ( entry = iterate_hash_next( &iter ) ) != NULL ) { host_entry = entry->value; if ( host_entry != NULL ) { delete_host_route( host_entry->ip ); xfree( host_entry ); } } delete_hash( host_db ); } host_db = NULL; if ( fd >= 0 ) { set_readable( fd, false ); delete_fd_handler( fd ); } return finalize_tun(); }
static void recv_syslog_message( int fd, void *data ) { UNUSED( data ); char buf[ 1024 ]; ssize_t ret = read( fd, buf, sizeof( buf ) ); if ( ret < 0 ) { if ( errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK ) { return; } error( "Receive error ( errno = %s [%d] ).", strerror( errno ), errno ); set_readable( fd, false ); delete_fd_handler( fd ); return; } buffer *message = alloc_buffer_with_length( ( size_t ) ret ); void *p = append_back_buffer( message, ( size_t ) ret ); memcpy( p, buf, ( size_t ) ret ); relay_syslog_message( message ); free_buffer( message ); }
static void clear_connection() { if ( connection.fd >= 0 ) { close( connection.fd ); set_readable( connection.fd, false ); set_writable( connection.fd, false ); delete_fd_handler( connection.fd ); } connection.fd = -1; connection.state = INIT; }
bool finalize_http_client() { debug( "Finalizaing HTTP client ( transactions = %p ).", transactions ); assert( transactions != NULL ); if ( http_client_thread != NULL ) { pthread_cancel( *http_client_thread ); xfree( http_client_thread ); http_client_thread = NULL; } if ( http_client_efd >= 0 ) { set_writable( http_client_efd, false ); delete_fd_handler( http_client_efd ); close( http_client_efd ); http_client_efd = -1; } http_client_notify_count = 0; if ( main_efd >= 0 ) { set_readable( main_efd, false ); delete_fd_handler( main_efd ); close( main_efd ); main_efd = -1; } delete_queue( main_to_http_client_queue ); main_to_http_client_queue = NULL; delete_queue( http_client_to_main_queue ); http_client_to_main_queue = NULL; delete_http_transaction_db(); debug( "Finalization completed." ); return true; }
static void finalize_listener_info( struct listener_info *listener_info ) { if ( listener_info->switch_daemon != NULL ) { xfree( ( void * ) ( uintptr_t ) listener_info->switch_daemon ); listener_info->switch_daemon = NULL; } if ( listener_info->listen_fd >= 0 ) { set_readable( listener_info->listen_fd, false ); delete_fd_handler( listener_info->listen_fd ); close( listener_info->listen_fd ); listener_info->listen_fd = -1; } }
static bool finalize_syslog_relay( void ) { if ( syslog_fd >= 0 ) { set_readable( syslog_fd, false ); delete_fd_handler( syslog_fd ); close( syslog_fd ); syslog_fd = -1; } xfree( dump_service_name ); dump_service_name = NULL; return true; }
static bool finalize_stdin_relay( void ) { set_readable( STDIN_FILENO, false ); delete_fd_handler( STDIN_FILENO ); if ( dump_service_name != NULL ) { xfree( dump_service_name ); dump_service_name = NULL; } if ( stdin_read_buffer != NULL ) { free_buffer( stdin_read_buffer ); stdin_read_buffer = NULL; } return true; }
int switch_event_disconnected( struct switch_info *sw_info ) { int old_state = sw_info->state; sw_info->state = SWITCH_STATE_DISCONNECTED; if ( old_state == SWITCH_STATE_COMPLETED ) { delete_timer_event( echo_request_interval, sw_info ); } if ( sw_info->fragment_buf != NULL ) { free_buffer( sw_info->fragment_buf ); sw_info->fragment_buf = NULL; } if ( sw_info->send_queue != NULL ) { delete_message_queue( sw_info->send_queue ); sw_info->send_queue = NULL; } if ( sw_info->recv_queue != NULL ) { delete_message_queue( sw_info->recv_queue ); sw_info->recv_queue = NULL; } if ( sw_info->secure_channel_fd >= 0 ) { set_readable( switch_info.secure_channel_fd, false ); set_writable( switch_info.secure_channel_fd, false ); delete_fd_handler( switch_info.secure_channel_fd ); close( sw_info->secure_channel_fd ); sw_info->secure_channel_fd = -1; } if ( old_state != SWITCH_STATE_COMPLETED ) { service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_FAILD_TO_CONNECT ); } else { // send secure channle disconnect state to application service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_DISCONNECTED ); } flush_messenger(); stop_trema(); return 0; }
static void check_connected( void *user_data ) { UNUSED( user_data ); debug( "Checking a connection ( fd = %d, ip = %#x, port = %u ).", connection.fd, connection.ip, connection.port ); assert( secure_channel_initialized ); assert( connection.fd >= 0 ); set_writable( connection.fd, false ); delete_fd_handler( connection.fd ); int err = 0; socklen_t length = sizeof( error ); int ret = getsockopt( connection.fd, SOL_SOCKET, SO_ERROR, &err, &length ); if ( ret < 0 ) { error( "Failed to retrieve error code ( fd = %d, ret = %d, errno = %s [%d] ).", connection.fd, ret, strerror( errno ), errno ); return; } switch ( err ) { case 0: connected(); break; case EINTR: case EAGAIN: case ECONNREFUSED: case ENETUNREACH: case ETIMEDOUT: warn( "Failed to connect ( fd = %d, errno = %s [%d] ).", connection.fd, strerror( err ), err ); backoff(); return; case EINPROGRESS: set_fd_handler( connection.fd, NULL, NULL, ( event_fd_callback ) check_connected, NULL ); set_writable( connection.fd, true ); break; default: error( "Failed to connect ( fd = %d, errno = %s [%d] ).", connection.fd, strerror( err ), err ); clear_connection(); return; } }
bool finalize_redirector() { hash_iterator iter; hash_entry *entry; init_hash_iterator( host_db, &iter ); while ( ( entry = iterate_hash_next( &iter ) ) != NULL ) { xfree( entry->value ); } delete_hash( host_db ); if ( fd >= 0 ) { set_readable( fd, false ); delete_fd_handler( fd ); } return finalize_tun(); }
int switch_event_disconnected( struct switch_info *sw_info ) { sw_info->state = SWITCH_STATE_DISCONNECTED; if ( sw_info->fragment_buf != NULL ) { free_buffer( sw_info->fragment_buf ); sw_info->fragment_buf = NULL; } if ( sw_info->send_queue != NULL ) { delete_message_queue( sw_info->send_queue ); sw_info->send_queue = NULL; } if ( sw_info->recv_queue != NULL ) { delete_message_queue( sw_info->recv_queue ); sw_info->recv_queue = NULL; } if ( sw_info->secure_channel_fd >= 0 ) { set_readable( switch_info.secure_channel_fd, false ); set_writable( switch_info.secure_channel_fd, false ); delete_fd_handler( switch_info.secure_channel_fd ); close( sw_info->secure_channel_fd ); sw_info->secure_channel_fd = -1; } // send secure channle disconnect state to application service_send_state( sw_info, &sw_info->datapath_id, MESSENGER_OPENFLOW_DISCONNECTED ); flush_messenger(); debug( "send disconnected state" ); stop_event_handler(); stop_messenger(); return 0; }
int main( int argc, char *argv[] ) { int ret; int i; char *service_name; char management_service_name[ MESSENGER_SERVICE_NAME_LENGTH ]; init_trema( &argc, &argv ); option_parser( argc, argv ); create_list( &switch_info.vendor_service_name_list ); create_list( &switch_info.packetin_service_name_list ); create_list( &switch_info.portstatus_service_name_list ); create_list( &switch_info.state_service_name_list ); // FIXME #define VENDER_PREFIX "vendor::" #define PACKET_IN_PREFIX "packet_in::" #define PORTSTATUS_PREFIX "port_status::" #define STATE_PREFIX "state_notify::" for ( i = optind; i < argc; i++ ) { if ( strncmp( argv[i], VENDER_PREFIX, strlen( VENDER_PREFIX ) ) == 0 ) { service_name = xstrdup( argv[i] + strlen( VENDER_PREFIX ) ); insert_in_front( &switch_info.vendor_service_name_list, service_name ); } else if ( strncmp( argv[i], PACKET_IN_PREFIX, strlen( PACKET_IN_PREFIX ) ) == 0 ) { service_name = xstrdup( argv[i] + strlen( PACKET_IN_PREFIX ) ); insert_in_front( &switch_info.packetin_service_name_list, service_name ); } else if ( strncmp( argv[i], PORTSTATUS_PREFIX, strlen( PORTSTATUS_PREFIX ) ) == 0 ) { service_name = xstrdup( argv[i] + strlen( PORTSTATUS_PREFIX ) ); insert_in_front( &switch_info.portstatus_service_name_list, service_name ); } else if ( strncmp( argv[i], STATE_PREFIX, strlen( STATE_PREFIX ) ) == 0 ) { service_name = xstrdup( argv[i] + strlen( STATE_PREFIX ) ); insert_in_front( &switch_info.state_service_name_list, service_name ); } } fcntl( switch_info.secure_channel_fd, F_SETFL, O_NONBLOCK ); set_fd_handler( switch_info.secure_channel_fd, secure_channel_read, NULL, secure_channel_write, NULL ); set_readable( switch_info.secure_channel_fd, true ); set_writable( switch_info.secure_channel_fd, false ); // default switch configuration switch_info.config_flags = OFPC_FRAG_NORMAL; switch_info.miss_send_len = UINT16_MAX; switch_info.fragment_buf = NULL; switch_info.send_queue = create_message_queue(); switch_info.recv_queue = create_message_queue(); switch_info.running_timer = false; init_xid_table(); init_cookie_table(); add_message_received_callback( get_trema_name(), service_recv ); snprintf( management_service_name , MESSENGER_SERVICE_NAME_LENGTH, "%s.m", get_trema_name() ); management_service_name[ MESSENGER_SERVICE_NAME_LENGTH - 1 ] = '\0'; add_message_received_callback( management_service_name, management_recv ); ret = switch_event_connected( &switch_info ); if ( ret < 0 ) { error( "Failed to set connected state." ); return -1; } flush_secure_channel( &switch_info ); start_trema(); finalize_xid_table(); finalize_cookie_table(); if ( switch_info.secure_channel_fd >= 0 ) { delete_fd_handler( switch_info.secure_channel_fd ); } return 0; }
int main( int argc, char *argv[] ) { int ret; int i; char *service_name; init_trema( &argc, &argv ); option_parser( argc, argv ); create_list( &switch_info.vendor_service_name_list ); create_list( &switch_info.packetin_service_name_list ); create_list( &switch_info.portstatus_service_name_list ); create_list( &switch_info.state_service_name_list ); for ( i = optind; i < argc; i++ ) { if ( strncmp( argv[ i ], VENDOR_PREFIX, strlen( VENDOR_PREFIX ) ) == 0 ) { service_name = xstrdup( argv[ i ] + strlen( VENDOR_PREFIX ) ); append_to_tail( &switch_info.vendor_service_name_list, service_name ); } else if ( strncmp( argv[ i ], PACKET_IN_PREFIX, strlen( PACKET_IN_PREFIX ) ) == 0 ) { service_name = xstrdup( argv[ i ] + strlen( PACKET_IN_PREFIX ) ); append_to_tail( &switch_info.packetin_service_name_list, service_name ); } else if ( strncmp( argv[ i ], PORTSTATUS_PREFIX, strlen( PORTSTATUS_PREFIX ) ) == 0 ) { service_name = xstrdup( argv[ i ] + strlen( PORTSTATUS_PREFIX ) ); append_to_tail( &switch_info.portstatus_service_name_list, service_name ); } else if ( strncmp( argv[ i ], STATE_PREFIX, strlen( STATE_PREFIX ) ) == 0 ) { service_name = xstrdup( argv[ i ] + strlen( STATE_PREFIX ) ); append_to_tail( &switch_info.state_service_name_list, service_name ); } } struct sigaction signal_exit; memset( &signal_exit, 0, sizeof( struct sigaction ) ); signal_exit.sa_handler = handle_sigterm; sigaction( SIGINT, &signal_exit, NULL ); sigaction( SIGTERM, &signal_exit, NULL ); fcntl( switch_info.secure_channel_fd, F_SETFL, O_NONBLOCK ); set_fd_handler( switch_info.secure_channel_fd, secure_channel_read, NULL, secure_channel_write, NULL ); set_readable( switch_info.secure_channel_fd, true ); set_writable( switch_info.secure_channel_fd, false ); // default switch configuration switch_info.config_flags = OFPC_FRAG_NORMAL; switch_info.miss_send_len = UINT16_MAX; switch_info.fragment_buf = NULL; switch_info.send_queue = create_message_queue(); switch_info.recv_queue = create_message_queue(); switch_info.running_timer = false; switch_info.echo_request_xid = 0; init_xid_table(); if ( switch_info.cookie_translation ) { init_cookie_table(); } add_message_received_callback( get_trema_name(), service_recv ); set_management_application_request_handler( management_recv, NULL ); ret = switch_event_connected( &switch_info ); if ( ret < 0 ) { error( "Failed to set connected state." ); return -1; } ret = flush_secure_channel( &switch_info ); if ( ret < 0 ) { error( "Failed to flush secure channel. Terminating %s.", argv[ 0 ] ); return -1; } start_trema(); // Note: init_event_forward_interface will be called on feature_reply. finalize_event_forward_interface(); finalize_xid_table(); if ( switch_info.cookie_translation ) { finalize_cookie_table(); } if ( switch_info.secure_channel_fd >= 0 ) { delete_fd_handler( switch_info.secure_channel_fd ); } return 0; }
int switch_event_disconnected( struct switch_info *sw_info ) { int old_state = sw_info->state; if ( sw_info->state == SWITCH_STATE_DISCONNECTED || sw_info->state == SWITCH_STATE_CONNECTION_FAILED ) { debug( "already disconnected" ); return -1; } if ( sw_info->state == SWITCH_STATE_COMPLETED ) { sw_info->state = SWITCH_STATE_DISCONNECTED; } else { sw_info->state = SWITCH_STATE_CONNECTION_FAILED; } if ( old_state == SWITCH_STATE_COMPLETED ) { switch_unset_timeout( echo_reply_timeout, NULL ); } if ( sw_info->fragment_buf != NULL ) { free_buffer( sw_info->fragment_buf ); sw_info->fragment_buf = NULL; } if ( sw_info->send_queue != NULL ) { delete_message_queue( sw_info->send_queue ); sw_info->send_queue = NULL; } if ( sw_info->recv_queue != NULL ) { delete_message_queue( sw_info->recv_queue ); sw_info->recv_queue = NULL; } if ( sw_info->secure_channel_fd >= 0 ) { set_readable( switch_info.secure_channel_fd, false ); set_writable( switch_info.secure_channel_fd, false ); delete_fd_handler( switch_info.secure_channel_fd ); } uint8_t state = MESSENGER_OPENFLOW_DISCONNECTED; if ( sw_info->state == SWITCH_STATE_CONNECTION_FAILED ) { state = MESSENGER_OPENFLOW_FAILD_TO_CONNECT; } debug( "Notify switch_disconnected to switch manager." ); char switch_manager[] = SWITCH_MANAGER; list_element switch_manager_only_list; switch_manager_only_list.next = NULL; switch_manager_only_list.data = switch_manager; service_send_to_application( &switch_manager_only_list, state, &sw_info->datapath_id, NULL ); // Check switch_manager registration debug( "Checking switch manager's switch list." ); sw_info->retry_count = UNREGISTRATION_RETRY_COUNT; set_list_switches_reply_handler( confirm_self_dpid_is_unregistered ); if ( send_list_switches_request( sw_info ) ) { switch_set_timeout( UNREGISTRATION_TIMEOUT, unregistration_timeout, sw_info ); } else { error( "Failed to send switch list request to switch manager." ); stop_switch(); } return 0; }