static void read_stdin( int fd, void *data ) { UNUSED( data ); char buf[ 1024 ]; memset( buf, '\0', sizeof( buf ) ); ssize_t ret = read( fd, buf, sizeof( buf ) ); if ( ret < 0 ) { if ( errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK ) { return; } set_readable( fd, false ); error( "Read error ( errno = %s [%d] ).", strerror( errno ), errno ); return; } else if ( ret == 0 ) { return; } if ( stdin_read_buffer == NULL ) { set_readable( fd, false ); error( "Read buffer is not allocated yet" ); return; } char *p = append_back_buffer( stdin_read_buffer, ( size_t ) ret ); memcpy( p, buf, ( size_t ) ret ); char *lf = find_character( stdin_read_buffer->data, stdin_read_buffer->length, '\n' ); while ( lf != NULL ) { size_t length = ( size_t ) ( lf - ( char * ) stdin_read_buffer->data ); if ( length > 0 ) { buffer *string = alloc_buffer_with_length( length ); p = append_back_buffer( string, length ); memcpy( p, stdin_read_buffer->data, length ); relay_string( string ); free_buffer( string ); remove_front_buffer( stdin_read_buffer, length + 1 ); } else { if ( stdin_read_buffer->length > 0 ) { remove_front_buffer( stdin_read_buffer, 1 ); } } if ( stdin_read_buffer->length == 0 ) { break; } lf = find_character( stdin_read_buffer->data, stdin_read_buffer->length, '\n' ); } // truncate head room manually buffer *truncated = duplicate_buffer( stdin_read_buffer ); free_buffer( stdin_read_buffer ); stdin_read_buffer = truncated; }
int openssl_check_connect(struct connection *conn) { int rc = mbedtls_ssl_handshake(conn->ssl); switch (rc) { case 0: /* success */ conn->connected = 1; set_writable(conn); if (verbose) printf("Ciphersuite is %s\n", mbedtls_ssl_get_ciphersuite(conn->ssl)); return 0; case MBEDTLS_ERR_SSL_WANT_READ: set_readable(conn); return 0; case MBEDTLS_ERR_SSL_WANT_WRITE: set_writable(conn); return 0; case MBEDTLS_ERR_NET_CONN_RESET: reset_connection(conn); return 1; default: printf("Not read or write 0x%x\n", rc); return 1; } }
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 ); }
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 bool init_syslog_relay( int *argc, char **argv[] ) { parse_options( argc, argv ); if ( syslog_fd >= 0 ) { close( syslog_fd ); syslog_fd = -1; } syslog_fd = socket( PF_INET, SOCK_DGRAM, 0 ); if ( syslog_fd < 0 ) { error( "Failed to create socket ( errno = %s [%d] ).", strerror( errno ), errno ); return false; } struct sockaddr_in addr; memset( &addr, 0, sizeof( struct sockaddr_in ) ); addr.sin_family = AF_INET; addr.sin_port = htons( listen_port ); addr.sin_addr.s_addr = htonl( INADDR_ANY ); int ret = bind( syslog_fd, ( struct sockaddr * ) &addr, sizeof( struct sockaddr_in ) ); if ( ret < 0 ) { error( "Failed to bind socket ( errno = %s [%d] ).", strerror( errno ), errno ); close( syslog_fd ); syslog_fd = -1; return false; } set_fd_handler( syslog_fd, recv_syslog_message, NULL, NULL, NULL ); set_readable( syslog_fd, true ); return true; }
bool init_http_client() { debug( "Initializaing HTTP client." ); assert( http_client_thread == NULL ); assert( http_client_efd == -1 ); assert( main_efd == -1 ); assert( transactions == NULL ); http_client_efd = create_event_fd(); assert( http_client_efd >= 0 ); http_client_notify_count = 0; set_fd_handler( http_client_efd, NULL, NULL, notify_http_client_actually, &http_client_notify_count ); set_writable( http_client_efd, false ); main_efd = create_event_fd(); assert( main_efd >= 0 ); set_fd_handler( main_efd, retrieve_http_transactions_from_http_client, NULL, NULL, NULL ); set_readable( main_efd, true ); assert( main_to_http_client_queue == NULL ); assert( http_client_to_main_queue == NULL ); main_to_http_client_queue = create_queue(); assert( main_to_http_client_queue != NULL ); http_client_to_main_queue = create_queue(); assert( http_client_to_main_queue != NULL ); create_http_transaction_db(); debug( "Initialization completed." ); return true; }
void write_request(struct connection *conn) { int n; /* must be signed. windows does not support ssize_t */ #ifdef WANT_SSL if (conn->ssl) { n = openssl_write(conn); /* openssl_write can return -EAGAIN if the SSL * connection needs a read or write. */ if (n == -EAGAIN) return; } else #endif n = send(conn->poll->fd, conn->curp, conn->length, MSG_NOSIGNAL); if (n == conn->length) { if (verbose > 2) printf("+ Sent request\n"); conn->length = 0; /* reset for read */ set_readable(conn); reset_buf(conn); NEXT_STATE(conn, read_reply); } else if (n > 0) { conn->length -= n; conn->curp += n; } else { printf("Write request error\n"); fail_connection(conn); } }
static bool init_stdin_relay( int *argc, char **argv[] ) { parse_options( argc, argv ); stdin_read_buffer = alloc_buffer_with_length( 1024 ); set_fd_handler( STDIN_FILENO, read_stdin, NULL, NULL, NULL ); set_readable( STDIN_FILENO, true ); return true; }
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; }
static void connected() { transit_state( CONNECTED ); set_fd_handler( connection.fd, recv_from_secure_channel, NULL, flush_send_queue, NULL ); set_readable( connection.fd, true ); set_writable( connection.fd, false ); if ( connection.connected_callback != NULL ) { connection.connected_callback(); } }
int main( int argc, char *argv[] ) { bool ret; const char *switch_daemon = NULL; char *startup_dir; // get startup directory using absolute_path() startup_dir = get_current_dir_name(); if ( startup_dir == NULL ) { die( "Failed to get_current_dir_name." ); } init_trema( &argc, &argv ); // changes the current working directory init_listener_info( &listener_info ); ret = parse_argument( &listener_info, argc, argv ); if ( !ret ) { finalize_listener_info( &listener_info ); exit( EXIT_FAILURE ); } init_dpid_table(); start_service_management(); start_switch_management(); switch_daemon = listener_info.switch_daemon; listener_info.switch_daemon = absolute_path( startup_dir, switch_daemon ); xfree( ( void * ) ( uintptr_t ) switch_daemon ); // free returned buffer of get_current_dir_name() free( startup_dir ); catch_sigchild(); // listener start (listen socket binding and listen) ret = secure_channel_listen_start( &listener_info ); if ( !ret ) { finalize_listener_info( &listener_info ); exit( EXIT_FAILURE ); } set_fd_handler( listener_info.listen_fd, secure_channel_accept, &listener_info, NULL, NULL ); set_readable( listener_info.listen_fd, true ); start_trema(); finalize_listener_info( &listener_info ); stop_switch_management(); stop_service_management(); finalize_dpid_table(); return 0; }
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; }
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(); }
bool init_redirector() { if ( !init_tun( TUN_INTERFACE ) ) { error( "Cannot create a tun interface." ); return false; } if ( host_db != NULL ) { error( "Host database is already created." ); return false; } host_db = create_hash( compare_ip_address, hash_ip_address ); set_fd_handler( fd, read_tun_fd, NULL, NULL, NULL ); set_readable( fd, true ); add_periodic_event_callback( HOST_DB_AGING_INTERVAL, age_host_db, NULL ); return true; }
static int flush_secure_channel_tls( struct switch_info *sw_info ) { assert( sw_info != NULL ); assert( sw_info->tls ); assert( sw_info->ssl != NULL ); assert( sw_info->send_queue->length > 0 ); buffer *buf = NULL; while ( ( buf = peek_message( sw_info->send_queue ) ) != NULL ) { int write_length = SSL_write( sw_info->ssl, buf->data, ( int ) buf->length ); if ( write_length < 0 ) { int error_no = SSL_get_error( sw_info->ssl, write_length ); switch ( error_no ) { case SSL_ERROR_WANT_READ: set_readable( sw_info->secure_channel_fd, true ); case SSL_ERROR_WANT_WRITE: set_writable( sw_info->secure_channel_fd, true ); return 0; default: error( "Failed to send a message to secure channel ( error = %d ).", error_no ); return -1; } } if ( write_length == 0 ) { set_writable( sw_info->secure_channel_fd, true ); return 0; } if ( ( size_t ) write_length < buf->length ) { remove_front_buffer( buf, ( size_t ) write_length ); set_writable( sw_info->secure_channel_fd, true ); return 0; } buf = dequeue_message( sw_info->send_queue ); free_buffer( buf ); } return 0; }
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; }
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; }
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; }
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 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; }