Esempio n. 1
0
amqp_pool_t *amqp_get_or_create_channel_pool(amqp_connection_state_t state, amqp_channel_t channel)
{
  amqp_pool_table_entry_t *entry;
  size_t index = channel % POOL_TABLE_SIZE;

  entry = state->pool_table[index];

  for ( ; NULL != entry; entry = entry->next) {
    if (channel == entry->channel) {
      return &entry->pool;
    }
  }

  entry = malloc(sizeof(amqp_pool_table_entry_t));
  if (NULL == entry) {
    return NULL;
  }

  entry->channel = channel;
  entry->next = state->pool_table[index];
  state->pool_table[index] = entry;

  init_amqp_pool(&entry->pool, state->frame_max);

  return &entry->pool;
}
Esempio n. 2
0
int amqp_tune_connection(amqp_connection_state_t state,
			 int channel_max,
			 int frame_max,
			 int heartbeat)
{
  void *newbuf;

  ENFORCE_STATE(state, CONNECTION_STATE_IDLE);

  state->channel_max = channel_max;
  state->frame_max = frame_max;
  state->heartbeat = heartbeat;

  empty_amqp_pool(&state->frame_pool);
  init_amqp_pool(&state->frame_pool, frame_max);

  state->inbound_buffer.len = frame_max;
  state->outbound_buffer.len = frame_max;
  newbuf = realloc(state->outbound_buffer.bytes, frame_max);
  if (newbuf == NULL) {
    amqp_destroy_connection(state);
    return -ENOMEM;
  }
  state->outbound_buffer.bytes = newbuf;

  return 0;
}
Esempio n. 3
0
amqp_connection_state_t amqp_new_connection(void) {
  amqp_connection_state_t state =
    (amqp_connection_state_t) calloc(1, sizeof(struct amqp_connection_state_t_));

  if (state == NULL) {
    return NULL;
  }

  init_amqp_pool(&state->frame_pool, INITIAL_FRAME_POOL_PAGE_SIZE);
  init_amqp_pool(&state->decoding_pool, INITIAL_DECODING_POOL_PAGE_SIZE);

  state->state = CONNECTION_STATE_IDLE;

  state->inbound_buffer.bytes = NULL;
  state->outbound_buffer.bytes = NULL;
  if (amqp_tune_connection(state, 0, INITIAL_FRAME_POOL_PAGE_SIZE, 0) != 0) {
    empty_amqp_pool(&state->frame_pool);
    empty_amqp_pool(&state->decoding_pool);
    free(state);
    return NULL;
  }

  state->inbound_offset = 0;
  state->target_size = HEADER_SIZE;

  state->sockfd = -1;
  state->sock_inbound_buffer.len = INITIAL_INBOUND_SOCK_BUFFER_SIZE;
  state->sock_inbound_buffer.bytes = malloc(INITIAL_INBOUND_SOCK_BUFFER_SIZE);
  if (state->sock_inbound_buffer.bytes == NULL) {
    amqp_destroy_connection(state);
    return NULL;
  }

  state->sock_inbound_offset = 0;
  state->sock_inbound_limit = 0;

  state->first_queued_frame = NULL;
  state->last_queued_frame = NULL;

  return state;
}
Esempio n. 4
0
amqp_table_t TableValueImpl::CopyTable(const amqp_table_t &table, amqp_pool_ptr_t &pool)
{
  if (0 == table.num_entries)
  {
    return AMQP_EMPTY_TABLE;
  }

  pool = boost::shared_ptr<amqp_pool_t>(new amqp_pool_t, free_pool);
  init_amqp_pool(pool.get(), 1024);

  return CopyTableInner(table, *pool.get());
}
Esempio n. 5
0
amqp_table_t TableValueImpl::CreateAmqpTable(const Table &table, amqp_pool_ptr_t &pool)
{
  if (0 == table.size())
  {
    return AMQP_EMPTY_TABLE;
  }

  pool = boost::shared_ptr<amqp_pool_t>(new amqp_pool_t, free_pool);
  init_amqp_pool(pool.get(), 1024);

  return CreateAmqpTableInner(table, *pool.get());
}
Esempio n. 6
0
amqp_connection_state_t amqp_new_connection(void) {
  amqp_connection_state_t state =
    (amqp_connection_state_t) calloc(1, sizeof(struct amqp_connection_state_t_));

  if (state == NULL)
    return NULL;

  init_amqp_pool(&state->frame_pool, INITIAL_FRAME_POOL_PAGE_SIZE);
  init_amqp_pool(&state->decoding_pool, INITIAL_DECODING_POOL_PAGE_SIZE);

  if (amqp_tune_connection(state, 0, INITIAL_FRAME_POOL_PAGE_SIZE, 0) != 0)
    goto out_nomem;

  state->inbound_buffer.bytes = amqp_pool_alloc(&state->frame_pool, state->inbound_buffer.len);
  if (state->inbound_buffer.bytes == NULL)
    goto out_nomem;

  state->state = CONNECTION_STATE_INITIAL;
  /* the server protocol version response is 8 bytes, which conveniently
     is also the minimum frame size */
  state->target_size = 8;

  state->sockfd = -1;
  state->sock_inbound_buffer.len = INITIAL_INBOUND_SOCK_BUFFER_SIZE;
  state->sock_inbound_buffer.bytes = malloc(INITIAL_INBOUND_SOCK_BUFFER_SIZE);
  if (state->sock_inbound_buffer.bytes == NULL)
    goto out_nomem;

  return state;

 out_nomem:
  free(state->sock_inbound_buffer.bytes);
  empty_amqp_pool(&state->frame_pool);
  empty_amqp_pool(&state->decoding_pool);
  free(state);
  return NULL;
}
amqp_connection_state_t amqp_new_connection(void)
{
  int res;
  amqp_connection_state_t state =
    (amqp_connection_state_t) calloc(1, sizeof(struct amqp_connection_state_t_));

  if (state == NULL) {
    return NULL;
  }

  res = amqp_tune_connection(state, 0, AMQP_INITIAL_FRAME_POOL_PAGE_SIZE, 0);
  if (0 != res) {
    goto out_nomem;
  }

  state->inbound_buffer.bytes = state->header_buffer;
  state->inbound_buffer.len = sizeof(state->header_buffer);

  state->state = CONNECTION_STATE_INITIAL;
  /* the server protocol version response is 8 bytes, which conveniently
     is also the minimum frame size */
  state->target_size = 8;

  state->sock_inbound_buffer.len = AMQP_INITIAL_INBOUND_SOCK_BUFFER_SIZE;
  state->sock_inbound_buffer.bytes = malloc(AMQP_INITIAL_INBOUND_SOCK_BUFFER_SIZE);
  if (state->sock_inbound_buffer.bytes == NULL) {
    goto out_nomem;
  }

  init_amqp_pool(&state->properties_pool, 512);

  return state;

out_nomem:
  free(state->sock_inbound_buffer.bytes);
  free(state);
  return NULL;
}
Esempio n. 8
0
static void test_table_codec(FILE *out)
{
  amqp_pool_t pool;
  int result;

  amqp_table_entry_t inner_entries[2];
  amqp_table_t inner_table;

  amqp_field_value_t inner_values[2];
  amqp_array_t inner_array;

  amqp_table_entry_t entries[14];
  amqp_table_t table;

  inner_entries[0].key = amqp_cstring_bytes("one");
  inner_entries[0].value.kind = AMQP_FIELD_KIND_I32;
  inner_entries[0].value.value.i32 = 54321;

  inner_entries[1].key = amqp_cstring_bytes("two");
  inner_entries[1].value.kind = AMQP_FIELD_KIND_UTF8;
  inner_entries[1].value.value.bytes = amqp_cstring_bytes("A long string");

  inner_table.num_entries = 2;
  inner_table.entries = inner_entries;

  inner_values[0].kind = AMQP_FIELD_KIND_I32;
  inner_values[0].value.i32 = 54321;

  inner_values[1].kind = AMQP_FIELD_KIND_UTF8;
  inner_values[1].value.bytes = amqp_cstring_bytes("A long string");

  inner_array.num_entries = 2;
  inner_array.entries = inner_values;

  entries[0].key = amqp_cstring_bytes("longstr");
  entries[0].value.kind = AMQP_FIELD_KIND_UTF8;
  entries[0].value.value.bytes = amqp_cstring_bytes("Here is a long string");

  entries[1].key = amqp_cstring_bytes("signedint");
  entries[1].value.kind = AMQP_FIELD_KIND_I32;
  entries[1].value.value.i32 = 12345;

  entries[2].key = amqp_cstring_bytes("decimal");
  entries[2].value.kind = AMQP_FIELD_KIND_DECIMAL;
  entries[2].value.value.decimal.decimals = 3;
  entries[2].value.value.decimal.value = 123456;

  entries[3].key = amqp_cstring_bytes("timestamp");
  entries[3].value.kind = AMQP_FIELD_KIND_TIMESTAMP;
  entries[3].value.value.u64 = 109876543209876;

  entries[4].key = amqp_cstring_bytes("table");
  entries[4].value.kind = AMQP_FIELD_KIND_TABLE;
  entries[4].value.value.table = inner_table;

  entries[5].key = amqp_cstring_bytes("byte");
  entries[5].value.kind = AMQP_FIELD_KIND_I8;
  entries[5].value.value.i8 = (int8_t)255;

  entries[6].key = amqp_cstring_bytes("long");
  entries[6].value.kind = AMQP_FIELD_KIND_I64;
  entries[6].value.value.i64 = 1234567890;

  entries[7].key = amqp_cstring_bytes("short");
  entries[7].value.kind = AMQP_FIELD_KIND_I16;
  entries[7].value.value.i16 = 655;

  entries[8].key = amqp_cstring_bytes("bool");
  entries[8].value.kind = AMQP_FIELD_KIND_BOOLEAN;
  entries[8].value.value.boolean = 1;

  entries[9].key = amqp_cstring_bytes("binary");
  entries[9].value.kind = AMQP_FIELD_KIND_BYTES;
  entries[9].value.value.bytes = amqp_cstring_bytes("a binary string");

  entries[10].key = amqp_cstring_bytes("void");
  entries[10].value.kind = AMQP_FIELD_KIND_VOID;

  entries[11].key = amqp_cstring_bytes("array");
  entries[11].value.kind = AMQP_FIELD_KIND_ARRAY;
  entries[11].value.value.array = inner_array;

  entries[12].key = amqp_cstring_bytes("float");
  entries[12].value.kind = AMQP_FIELD_KIND_F32;
  entries[12].value.value.f32 = M_PI;

  entries[13].key = amqp_cstring_bytes("double");
  entries[13].value.kind = AMQP_FIELD_KIND_F64;
  entries[13].value.value.f64 = M_PI;

  table.num_entries = 14;
  table.entries = entries;

  fprintf(out, "AAAAAAAAAA\n");

  {
    amqp_field_value_t val;
    val.kind = AMQP_FIELD_KIND_TABLE;
    val.value.table = table;
    dump_value(0, val, out);
  }

  init_amqp_pool(&pool, 4096);

  {
    amqp_table_t decoded;
    size_t decoding_offset = 0;
    amqp_bytes_t decoding_bytes;
    decoding_bytes.len = sizeof(pre_encoded_table);
    decoding_bytes.bytes = pre_encoded_table;

    result = amqp_decode_table(decoding_bytes, &pool, &decoded,
			       &decoding_offset);
    if (result < 0)
      die("Table decoding failed: %s", amqp_error_string(-result));

    fprintf(out, "BBBBBBBBBB\n");

    {
      amqp_field_value_t val;
      val.kind = AMQP_FIELD_KIND_TABLE;
      val.value.table = decoded;

      dump_value(0, val, out);
    }
  }

  {
    uint8_t encoding_buffer[4096];
    amqp_bytes_t encoding_result;
    size_t offset = 0;

    memset(&encoding_buffer[0], 0, sizeof(encoding_buffer));
    encoding_result.len = sizeof(encoding_buffer);
    encoding_result.bytes = &encoding_buffer[0];

    result = amqp_encode_table(encoding_result, &table, &offset);
    if (result < 0)
      die("Table encoding failed: %s", amqp_error_string(-result));

    if (offset != sizeof(pre_encoded_table))
      die("Offset should be %ld, was %ld", (long)sizeof(pre_encoded_table),
	  (long)offset);

    result = memcmp(pre_encoded_table, encoding_buffer, offset);
    if (result != 0)
      die("Table encoding differed", result);
  }

  empty_amqp_pool(&pool);
}
Esempio n. 9
0
amqp_rpc_reply_t amqp_read_message_noblock(amqp_connection_state_t state,
                                           amqp_channel_t channel,
                                           amqp_message_t *message,
                                           AMQP_UNUSED int flags,
                                           struct timeval *timeout)
{
  amqp_frame_t frame;
  amqp_rpc_reply_t ret;

  size_t body_read;
  char *body_read_ptr;
  int res;

  memset(&ret, 0, sizeof(amqp_rpc_reply_t));
  memset(message, 0, sizeof(amqp_message_t));

  res = amqp_simple_wait_frame_on_channel_noblock(state, channel, &frame, timeout);
  if (AMQP_STATUS_OK != res) {
    ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
    ret.library_error = res;

    goto error_out1;
  }

  if (AMQP_FRAME_HEADER != frame.frame_type) {
    if (AMQP_FRAME_METHOD == frame.frame_type &&
        (AMQP_CHANNEL_CLOSE_METHOD == frame.payload.method.id ||
         AMQP_CONNECTION_CLOSE_METHOD == frame.payload.method.id)) {

      ret.reply_type = AMQP_RESPONSE_SERVER_EXCEPTION;
      ret.reply = frame.payload.method;

    } else {
      ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
      ret.library_error = AMQP_STATUS_UNEXPECTED_STATE;

      amqp_put_back_frame(state, &frame);
    }
    goto error_out1;
  }

  init_amqp_pool(&message->pool, 4096);
  res = amqp_basic_properties_clone(frame.payload.properties.decoded,
                                    &message->properties, &message->pool);

  if (AMQP_STATUS_OK != res) {
    ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
    ret.library_error = res;
    goto error_out3;
  }

  if (0 == frame.payload.properties.body_size) {
    message->body = amqp_empty_bytes;
  } else {
    message->body = amqp_bytes_malloc(frame.payload.properties.body_size);
    if (NULL == message->body.bytes) {
      ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
      ret.library_error = AMQP_STATUS_NO_MEMORY;
      goto error_out1;
    }
  }

  body_read = 0;
  body_read_ptr = message->body.bytes;

  while (body_read < message->body.len) {
    res = amqp_simple_wait_frame_on_channel_noblock(state, channel, &frame, timeout);
    if (AMQP_STATUS_OK != res) {
      ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
      ret.library_error = res;
      goto error_out2;
    }
    if (AMQP_FRAME_BODY != frame.frame_type) {
      if (AMQP_FRAME_METHOD == frame.frame_type &&
          (AMQP_CHANNEL_CLOSE_METHOD == frame.payload.method.id ||
           AMQP_CONNECTION_CLOSE_METHOD == frame.payload.method.id)) {

        ret.reply_type = AMQP_RESPONSE_SERVER_EXCEPTION;
        ret.reply = frame.payload.method;
      } else {
        ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
        ret.library_error = AMQP_STATUS_BAD_AMQP_DATA;
      }
      goto error_out2;
    }

    if (body_read + frame.payload.body_fragment.len > message->body.len) {
      ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
      ret.library_error = AMQP_STATUS_BAD_AMQP_DATA;
      goto error_out2;
    }

    memcpy(body_read_ptr, frame.payload.body_fragment.bytes, frame.payload.body_fragment.len);

    body_read += frame.payload.body_fragment.len;
    body_read_ptr += frame.payload.body_fragment.len;
  }

  ret.reply_type = AMQP_RESPONSE_NORMAL;
  return ret;

error_out2:
  amqp_bytes_free(message->body);
error_out3:
  empty_amqp_pool(&message->pool);
error_out1:
  return ret;
}