Ejemplo n.º 1
0
static void
flush_send_queue( int fd, void *user_data ) {
  UNUSED( fd );
  UNUSED( user_data );

  assert( send_queue != NULL );
  assert( connection.fd >= 0 );

  debug( "Flushing send queue ( length = %u ).", send_queue->length );

  set_writable( connection.fd, false );

  buffer *buf = NULL;
  while ( ( buf = peek_message( send_queue ) ) != NULL ) {
    ssize_t write_length = write( connection.fd, buf->data, buf->length );
    if ( write_length < 0 ) {
      if ( errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK ) {
        set_writable( connection.fd, true );
        return;
      }
      error( "Failed to send a message to secure channel ( errno = %s [%d] ).",
             strerror( errno ), errno );
      return;
    }
    if ( ( size_t ) write_length < buf->length ) {
      remove_front_buffer( buf, ( size_t ) write_length );
      set_writable( connection.fd, true );
      return;
    }

    buf = dequeue_message( send_queue );
    free_buffer( buf );
  }
}
Ejemplo n.º 2
0
int
flush_secure_channel( struct switch_info *sw_info ) {
  assert( sw_info != NULL );
  assert( sw_info->send_queue != NULL );
  assert( sw_info->secure_channel_fd >= 0 );

  buffer *buf;
  ssize_t write_length;

  while ( ( buf = peek_message( sw_info->send_queue ) ) != NULL ) {
    write_length = write( sw_info->secure_channel_fd, buf->data, buf->length );
    if ( write_length < 0 ) {
      if ( errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK ) {
        return 0;
      }
      error( "Failed to send a message to secure channel ( errno = %s [%d] ).",
             strerror( errno ), errno );
      return -1;
    }
    if ( ( size_t ) write_length < buf->length ) {
      remove_front_buffer( buf, ( size_t ) write_length );
      return 0;
    }
    buf = dequeue_message( sw_info->send_queue );
    free_buffer( buf );
  }

  return 0;
}
Ejemplo n.º 3
0
static void
test_peek_message() {
  message_queue *queue = create_message_queue();
  assert_true( queue != NULL );

  buffer *peek_buf = peek_message( queue );
  assert_true( peek_buf == NULL );

  buffer *first_buf = alloc_buffer();
  assert_true( enqueue_message( queue, first_buf ) );
  assert_int_equal( queue->length, 1 );
  buffer *second_buf = alloc_buffer();
  assert_true( enqueue_message( queue, second_buf ) );
  assert_int_equal( queue->length, 2 );
  buffer *third_buf = alloc_buffer();
  assert_true( enqueue_message( queue, third_buf ) );
  assert_int_equal( queue->length, 3 );

  peek_buf = peek_message( queue );
  assert_true( peek_buf == first_buf );
  buffer *deq_buf = dequeue_message( queue );
  assert_true( deq_buf == first_buf );
  free_buffer( deq_buf );
  assert_int_equal( queue->length, 2 );

  peek_buf = peek_message( queue );
  assert_true( peek_buf == second_buf );
  deq_buf = dequeue_message( queue );
  assert_true( deq_buf == second_buf );
  free_buffer( deq_buf );
  assert_int_equal( queue->length, 1 );

  peek_buf = peek_message( queue );
  assert_true( peek_buf == third_buf );
  deq_buf = dequeue_message( queue );
  assert_true( deq_buf == third_buf );
  free_buffer( deq_buf );
  assert_int_equal( queue->length, 0 );

  peek_buf = peek_message( queue );
  assert_true( peek_buf == NULL );
  deq_buf = dequeue_message( queue );
  assert_true( deq_buf == NULL );
  assert_int_equal( queue->length, 0 );

  assert_true( delete_message_queue( queue ) );
}
Ejemplo n.º 4
0
int
flush_secure_channel( struct switch_info *sw_info ) {
  assert( sw_info != NULL );
  assert( sw_info->send_queue != NULL );
  assert( sw_info->secure_channel_fd >= 0 );

  buffer *buf;
  ssize_t write_length;

  if ( sw_info->send_queue->length == 0 ) {
    return 0;
  }
  set_writable( sw_info->secure_channel_fd, false );
  writev_args args;
  args.iov = xmalloc( sizeof( struct iovec ) * ( size_t ) sw_info->send_queue->length );
  args.iovcnt = 0;
  foreach_message_queue( sw_info->send_queue, append_to_writev_args, &args );
  if ( args.iovcnt == 0 ) {
    xfree( args.iov );
    return 0;
  }
  write_length = writev( sw_info->secure_channel_fd, args.iov, args.iovcnt );
  xfree( args.iov );
  if ( write_length < 0 ) {
    if ( errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK ) {
      set_writable( sw_info->secure_channel_fd, true );
      return 0;
    }
    error( "Failed to send a message to secure channel ( errno = %s [%d] ).",
           strerror( errno ), errno );
    return -1;
  }
  if ( write_length == 0 ) {
    return 0;
  }
  while ( ( buf = peek_message( sw_info->send_queue ) ) != NULL ) {
    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;
    }
    write_length -= ( ssize_t ) buf->length;
    buf = dequeue_message( sw_info->send_queue );
    free_buffer( buf );
  }

  return 0;
}
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;
}
Ejemplo n.º 6
0
static void
test_peek_message_if_queue_is_not_created() {
  message_queue *queue = NULL;
  expect_assert_failure( peek_message( queue ) );
}