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();
}
Esempio n. 2
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 );
}
Esempio n. 3
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;
}
Esempio n. 4
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;
}
Esempio n. 5
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;
  }
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 8
0
File: switch.c Progetto: 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;
}
Esempio n. 9
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;
  }
}
Esempio n. 10
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();
}
Esempio n. 11
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;
}
Esempio n. 12
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;
}
Esempio n. 13
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;
}
Esempio n. 14
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;
}