示例#1
0
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;
}
示例#2
0
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;
	}
}
示例#3
0
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();
}
示例#5
0
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;
}
示例#6
0
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;
}
示例#7
0
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);
	}
}
示例#8
0
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;
}
示例#9
0
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;
}
示例#10
0
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();
  }
}
示例#11
0
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;
}
示例#12
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;
  }
}
示例#13
0
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;
}
示例#14
0
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;
}
示例#15
0
文件: switch.c 项目: Darma/trema
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;
}
示例#16
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();
}
示例#17
0
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;
}
示例#19
0
文件: switch.c 项目: miyakz1192/trema
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;
}
示例#20
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;
}
示例#21
0
文件: switch.c 项目: Milstein/trema
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;
}
示例#22
0
文件: switch.c 项目: Milstein/trema
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;
}
示例#23
0
文件: switch.c 项目: miyakz1192/trema
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;
}