コード例 #1
0
ファイル: reactor-send.c プロジェクト: MZDN/qpid-proton
void sender_context_init(sender_context_t *sc, Options_t *opts, Statistics_t *stats)
{
  sc->opts = opts;
  sc->stats = stats;
  sc->sent = 0;
  sc->received = 0;
  sc->id.type = PN_ULONG;
  sc->reply_message = 0;
  // 4096 extra bytes should easily cover the message metadata
  sc->encoded_data_size = sc->opts->msg_size + 4096;
  sc->encoded_data = (char *)calloc(1, sc->encoded_data_size);
  check(sc->encoded_data, "failed to allocate encoding buffer");
  sc->container_id = pn_string("reactor-send"); // prefer uuid-like name

  sc->reply_message = (sc->opts->get_replies) ? pn_message() : 0;
  sc->message = pn_message();
  check(sc->message, "failed to allocate a message");
  pn_string_t *rpto = pn_string("amqp://");
  pn_string_addf(rpto, "%s", pn_string_get(sc->container_id));
  pn_message_set_reply_to(sc->message, pn_string_get(rpto));
  pn_free(rpto);
  pn_data_t *body = pn_message_body(sc->message);
  // borrow the encoding buffer this one time
  char *data = sc->encoded_data;
  pn_data_put_binary(body, pn_bytes(sc->opts->msg_size, data));

  check(sc->opts->targets.count > 0, "no specified address");
  sc->send_url = pn_url_parse(sc->opts->targets.addresses[0]);
  const char *host = pn_url_get_host(sc->send_url);
  const char *port = pn_url_get_port(sc->send_url);
  sc->hostname = pn_string(host);
  if (port && strlen(port))
    pn_string_addf(sc->hostname, ":%s", port);
}
コード例 #2
0
ファイル: object.c プロジェクト: MZDN/qpid-proton
static void test_build_map_odd(void)
{
  pn_map_t *m = build_map(0, 0.75,
                          pn_string("key"),
                          pn_string("value"),
                          pn_string("key2"),
                          pn_string("value2"),
                          pn_string("key3"),
                          END);

  assert(pn_map_size(m) == 3);

  pn_string_t *key = pn_string(NULL);

  pn_string_set(key, "key");
  assert(pn_strequals(pn_string_get((pn_string_t *) pn_map_get(m, key)),
                      "value"));
  pn_string_set(key, "key2");
  assert(pn_strequals(pn_string_get((pn_string_t *) pn_map_get(m, key)),
                      "value2"));
  pn_string_set(key, "key3");
  assert(pn_map_get(m, key) == NULL);

  pn_free(m);
  pn_free(key);
}
コード例 #3
0
ファイル: transform.c プロジェクト: sdnnfv/qpid
int pn_transform_apply(pn_transform_t *transform, const char *src,
                       pn_string_t *dst)
{
    for (size_t i = 0; i < pn_list_size(transform->rules); i++)
    {
        pn_rule_t *rule = (pn_rule_t *) pn_list_get(transform->rules, i);
        if (pni_match(&transform->matcher, pn_string_get(rule->pattern), src)) {
            transform->matched = true;
            if (!pn_string_get(rule->substitution)) {
                return pn_string_set(dst, NULL);
            }

            while (true) {
                size_t capacity = pn_string_capacity(dst);
                size_t n = pni_substitute(&transform->matcher,
                                          pn_string_get(rule->substitution),
                                          pn_string_buffer(dst), capacity);
                int err = pn_string_resize(dst, n);
                if (err) return err;
                if (n <= capacity) {
                    return 0;
                }
            }
        }
    }

    transform->matched = false;
    return pn_string_set(dst, src);
}
コード例 #4
0
ファイル: subscription.c プロジェクト: 850361813/qpid-proton
const char *pn_subscription_address(pn_subscription_t *sub)
{
  assert(sub);
  while (!pn_string_get(sub->address)) {
    int err = pni_messenger_work(sub->messenger);
    if (err < 0) {
      return NULL;
    }
  }
  return pn_string_get(sub->address);
}
コード例 #5
0
ファイル: object.c プロジェクト: MZDN/qpid-proton
void test_inspect(void *o, const char *expected)
{
  pn_string_t *dst = pn_string(NULL);
  pn_inspect(o, dst);
  assert(pn_strequals(pn_string_get(dst), expected));
  pn_free(dst);
}
コード例 #6
0
ファイル: openssl.c プロジェクト: flaper87/qpid-proton
pn_ssl_t *pn_ssl(pn_transport_t *transport)
{
  if (!transport) return NULL;
  if (transport->ssl) return (pn_ssl_t *) transport;

  pni_ssl_t *ssl = (pni_ssl_t *) calloc(1, sizeof(pni_ssl_t));
  if (!ssl) return NULL;
  ssl->out_size = APP_BUF_SIZE;
  uint32_t max_frame = pn_transport_get_max_frame(transport);
  ssl->in_size =  max_frame ? max_frame : APP_BUF_SIZE;
  ssl->outbuf = (char *)malloc(ssl->out_size);
  if (!ssl->outbuf) {
    free(ssl);
    return NULL;
  }
  ssl->inbuf =  (char *)malloc(ssl->in_size);
  if (!ssl->inbuf) {
    free(ssl->outbuf);
    free(ssl);
    return NULL;
  }

  transport->ssl = ssl;

  // Set up hostname from any bound connection
  if (transport->connection) {
    if (pn_string_size(transport->connection->hostname)) {
      pn_ssl_set_peer_hostname((pn_ssl_t *) transport, pn_string_get(transport->connection->hostname));
    }
  }

  return (pn_ssl_t *) transport;
}
コード例 #7
0
ファイル: object.c プロジェクト: MZDN/qpid-proton
static void test_stringn(const char *value, size_t size)
{
  pn_string_t *strn = pn_stringn(value, size);
  assert(equals(pn_string_get(strn), value));
  assert(pn_string_size(strn) == size);

  pn_string_t *strsetn = pn_string(NULL);
  pn_string_setn(strsetn, value, size);
  assert(equals(pn_string_get(strsetn), value));
  assert(pn_string_size(strsetn) == size);

  assert(pn_hashcode(strn) == pn_hashcode(strsetn));
  assert(!pn_compare(strn, strsetn));

  pn_free(strn);
  pn_free(strsetn);
}
コード例 #8
0
ファイル: url.c プロジェクト: marcelmeulemans/qpid-proton-1
/** Return the string form of a URL. */
PN_EXTERN const char *pn_url_str(pn_url_t *url) {
    if (pn_string_get(url->str) == NULL) {
        pn_string_set(url->str, "");
        if (url->scheme) pn_string_addf(url->str, "%s://", url->scheme);
        if (url->username) pni_urlencode(url->str, url->username);
        if (url->password) {
            pn_string_addf(url->str, ":");
            pni_urlencode(url->str, url->password);
        }
        if (url->username || url->password) pn_string_addf(url->str, "@");
        if (url->host) {
            if (strchr(url->host, ':')) pn_string_addf(url->str, "[%s]", url->host);
            else pn_string_addf(url->str, "%s", url->host);
        }
        if (url->port) pn_string_addf(url->str, ":%s", url->port);
        if (url->path) pn_string_addf(url->str, "/%s", url->path);
    }
    return pn_string_get(url->str);
}
コード例 #9
0
ファイル: object.c プロジェクト: MZDN/qpid-proton
static void test_build_list(void)
{
  pn_list_t *l = build_list(0,
                            pn_string("one"),
                            pn_string("two"),
                            pn_string("three"),
                            END);

  assert(pn_list_size(l) == 3);

  assert(pn_strequals(pn_string_get((pn_string_t *) pn_list_get(l, 0)),
                      "one"));
  assert(pn_strequals(pn_string_get((pn_string_t *) pn_list_get(l, 1)),
                      "two"));
  assert(pn_strequals(pn_string_get((pn_string_t *) pn_list_get(l, 2)),
                      "three"));

  pn_free(l);
}
コード例 #10
0
ファイル: dispatcher.c プロジェクト: dpocock/qpid-proton-deb
int pn_post_frame(pn_dispatcher_t *disp, uint16_t ch, const char *fmt, ...)
{
  va_list ap;
  va_start(ap, fmt);
  pn_data_clear(disp->output_args);
  int err = pn_data_vfill(disp->output_args, fmt, ap);
  va_end(ap);
  if (err) {
    pn_transport_logf(disp->transport,
                      "error posting frame: %s, %s: %s", fmt, pn_code(err),
                      pn_error_text(pn_data_error(disp->output_args)));
    return PN_ERR;
  }

  pn_do_trace(disp, ch, OUT, disp->output_args, disp->output_payload, disp->output_size);

 encode_performatives:
  pn_buffer_clear( disp->frame );
  pn_bytes_t buf = pn_buffer_bytes( disp->frame );
  buf.size = pn_buffer_available( disp->frame );

  ssize_t wr = pn_data_encode( disp->output_args, buf.start, buf.size );
  if (wr < 0) {
    if (wr == PN_OVERFLOW) {
      pn_buffer_ensure( disp->frame, pn_buffer_available( disp->frame ) * 2 );
      goto encode_performatives;
    }
    pn_transport_logf(disp->transport,
                      "error posting frame: %s", pn_code(wr));
    return PN_ERR;
  }

  pn_frame_t frame = {disp->frame_type};
  frame.channel = ch;
  frame.payload = buf.start;
  frame.size = wr;
  size_t n;
  while (!(n = pn_write_frame(disp->output + disp->available,
                              disp->capacity - disp->available, frame))) {
    disp->capacity *= 2;
    disp->output = (char *) realloc(disp->output, disp->capacity);
  }
  disp->output_frames_ct += 1;
  if (disp->trace & PN_TRACE_RAW) {
    pn_string_set(disp->scratch, "RAW: \"");
    pn_quote(disp->scratch, disp->output + disp->available, n);
    pn_string_addf(disp->scratch, "\"");
    pn_transport_log(disp->transport, pn_string_get(disp->scratch));
  }
  disp->available += n;

  return 0;
}
コード例 #11
0
ファイル: subscription.c プロジェクト: 850361813/qpid-proton
int pni_subscription_set_address(pn_subscription_t *sub, const char *address)
{
  assert(sub);

  if (!address) return 0;

  bool absolute = strncmp(address, "amqp:", 5) == 0;

  if (absolute) {
    return pn_string_set(sub->address, address);
  } else {
    pn_string_set(sub->address, "");
    bool scheme = pn_string_get(sub->scheme);
    if (scheme) {
      int e = pn_string_addf(sub->address, "%s:", pn_string_get(sub->scheme));
      if (e) return e;
    }
    if (pn_string_get(sub->host)) {
      int e = pn_string_addf(sub->address, scheme ? "//%s" : "%s", pn_string_get(sub->host));
      if (e) return e;
    }
    if (pn_string_get(sub->port)) {
      int e = pn_string_addf(sub->address, ":%s", pn_string_get(sub->port));
      if (e) return e;
    }
    return pn_string_addf(sub->address, "/%s", address);
  }
}
コード例 #12
0
ファイル: dispatcher.c プロジェクト: dpocock/qpid-proton-deb
int pn_dispatch_frame(pn_dispatcher_t *disp, pn_frame_t frame)
{
  if (frame.size == 0) { // ignore null frames
    if (disp->trace & PN_TRACE_FRM)
      pn_transport_logf(disp->transport, "%u <- (EMPTY FRAME)\n", frame.channel);
    return 0;
  }

  ssize_t dsize = pn_data_decode(disp->args, frame.payload, frame.size);
  if (dsize < 0) {
    pn_string_format(disp->scratch,
                     "Error decoding frame: %s %s\n", pn_code(dsize),
                     pn_error_text(pn_data_error(disp->args)));
    pn_quote(disp->scratch, frame.payload, frame.size);
    pn_transport_log(disp->transport, pn_string_get(disp->scratch));
    return dsize;
  }

  disp->channel = frame.channel;
  // XXX: assuming numeric
  uint64_t lcode;
  bool scanned;
  int e = pn_data_scan(disp->args, "D?L.", &scanned, &lcode);
  if (e) {
    pn_transport_log(disp->transport, "Scan error");
    return e;
  }
  if (!scanned) {
    pn_transport_log(disp->transport, "Error dispatching frame");
    return PN_ERR;
  }
  uint8_t code = lcode;
  disp->code = code;
  disp->size = frame.size - dsize;
  if (disp->size)
    disp->payload = frame.payload + dsize;

  pn_do_trace(disp, disp->channel, IN, disp->args, disp->payload, disp->size);

  pn_action_t *action = disp->actions[code];
  int err = action(disp);

  disp->channel = 0;
  disp->code = 0;
  pn_data_clear(disp->args);
  disp->size = 0;
  disp->payload = NULL;

  return err;
}
コード例 #13
0
ファイル: object.c プロジェクト: MZDN/qpid-proton
static void test_string(const char *value)
{
  size_t size = value ? strlen(value) : 0;

  pn_string_t *str = pn_string(value);
  assert(equals(pn_string_get(str), value));
  assert(pn_string_size(str) == size);

  pn_string_t *strn = pn_stringn(value, size);
  assert(equals(pn_string_get(strn), value));
  assert(pn_string_size(strn) == size);

  pn_string_t *strset = pn_string(NULL);
  pn_string_set(strset, value);
  assert(equals(pn_string_get(strset), value));
  assert(pn_string_size(strset) == size);

  pn_string_t *strsetn = pn_string(NULL);
  pn_string_setn(strsetn, value, size);
  assert(equals(pn_string_get(strsetn), value));
  assert(pn_string_size(strsetn) == size);

  assert(pn_hashcode(str) == pn_hashcode(strn));
  assert(pn_hashcode(str) == pn_hashcode(strset));
  assert(pn_hashcode(str) == pn_hashcode(strsetn));

  assert(!pn_compare(str, str));
  assert(!pn_compare(str, strn));
  assert(!pn_compare(str, strset));
  assert(!pn_compare(str, strsetn));

  pn_free(str);
  pn_free(strn);
  pn_free(strset);
  pn_free(strsetn);
}
コード例 #14
0
ファイル: dispatcher.c プロジェクト: dpocock/qpid-proton-deb
static void pn_do_trace(pn_dispatcher_t *disp, uint16_t ch, pn_dir_t dir,
                        pn_data_t *args, const char *payload, size_t size)
{
  if (disp->trace & PN_TRACE_FRM) {
    pn_string_format(disp->scratch, "%u %s ", ch, dir == OUT ? "->" : "<-");
    pn_inspect(args, disp->scratch);

    if (size) {
      char buf[1024];
      int e = pn_quote_data(buf, 1024, payload, size);
      pn_string_addf(disp->scratch, " (%" PN_ZU ") \"%s\"%s", size, buf,
                     e == PN_OVERFLOW ? "... (truncated)" : "");
    }

    pn_transport_log(disp->transport, pn_string_get(disp->scratch));
  }
}
コード例 #15
0
ファイル: sasl.c プロジェクト: mbroadst/debian-qpid-proton
// Received client side
int pn_do_mechanisms(pn_transport_t *transport, uint8_t frame_type, uint16_t channel, pn_data_t *args, const pn_bytes_t *payload)
{
  pni_sasl_t *sasl = transport->sasl;

  // If we already pretended we got the ANONYMOUS mech then ignore
  if (sasl->last_state==SASL_PRETEND_OUTCOME) return 0;

  // This scanning relies on pn_data_scan leaving the pn_data_t cursors
  // where they are after finishing the scan
  int err = pn_data_scan(args, "D.[@[");
  if (err) return err;

  pn_string_t *mechs = pn_string("");

  // Now keep checking for end of array and pull a symbol
  while(pn_data_next(args)) {
    pn_bytes_t s = pn_data_get_symbol(args);
    if (pni_included_mech(transport->sasl->included_mechanisms, s)) {
      pn_string_addf(mechs, "%*s ", (int)s.size, s.start);
    }
  }

  if (pn_string_size(mechs)) {
      pn_string_buffer(mechs)[pn_string_size(mechs)-1] = 0;
  }

  if (pni_init_client(transport) &&
      pni_process_mechanisms(transport, pn_string_get(mechs))) {
    pni_sasl_set_desired_state(transport, SASL_POSTED_INIT);
  } else {
    sasl->outcome = PN_SASL_PERM;
    pni_sasl_set_desired_state(transport, SASL_RECVED_OUTCOME_FAIL);
  }

  pn_free(mechs);
  return 0;
}
コード例 #16
0
ファイル: dispatcher.c プロジェクト: dpocock/qpid-proton-deb
int pn_post_transfer_frame(pn_dispatcher_t *disp, uint16_t ch,
                           uint32_t handle,
                           pn_sequence_t id,
                           const pn_bytes_t *tag,
                           uint32_t message_format,
                           bool settled,
                           bool more,
                           pn_sequence_t frame_limit)
{
  bool more_flag = more;
  int framecount = 0;

  // create preformatives, assuming 'more' flag need not change

 compute_performatives:
  pn_data_clear(disp->output_args);
  int err = pn_data_fill(disp->output_args, "DL[IIzIoo]", TRANSFER,
                         handle, id, tag->size, tag->start,
                         message_format,
                         settled, more_flag);
  if (err) {
    pn_transport_logf(disp->transport,
                      "error posting transfer frame: %s: %s", pn_code(err),
                      pn_error_text(pn_data_error(disp->output_args)));
    return PN_ERR;
  }

  do { // send as many frames as possible without changing the 'more' flag...

  encode_performatives:
    pn_buffer_clear( disp->frame );
    pn_bytes_t buf = pn_buffer_bytes( disp->frame );
    buf.size = pn_buffer_available( disp->frame );

    ssize_t wr = pn_data_encode(disp->output_args, buf.start, buf.size);
    if (wr < 0) {
      if (wr == PN_OVERFLOW) {
        pn_buffer_ensure( disp->frame, pn_buffer_available( disp->frame ) * 2 );
        goto encode_performatives;
      }
      pn_transport_logf(disp->transport, "error posting frame: %s", pn_code(wr));
      return PN_ERR;
    }
    buf.size = wr;

    // check if we need to break up the outbound frame
    size_t available = disp->output_size;
    if (disp->remote_max_frame) {
      if ((available + buf.size) > disp->remote_max_frame - 8) {
        available = disp->remote_max_frame - 8 - buf.size;
        if (more_flag == false) {
          more_flag = true;
          goto compute_performatives;  // deal with flag change
        }
      } else if (more_flag == true && more == false) {
        // caller has no more, and this is the last frame
        more_flag = false;
        goto compute_performatives;
      }
    }

    if (pn_buffer_available( disp->frame ) < (available + buf.size)) {
      // not enough room for payload - try again...
      pn_buffer_ensure( disp->frame, available + buf.size );
      goto encode_performatives;
    }

    pn_do_trace(disp, ch, OUT, disp->output_args, disp->output_payload, available);

    memmove( buf.start + buf.size, disp->output_payload, available);
    disp->output_payload += available;
    disp->output_size -= available;
    buf.size += available;

    pn_frame_t frame = {disp->frame_type};
    frame.channel = ch;
    frame.payload = buf.start;
    frame.size = buf.size;

    size_t n;
    while (!(n = pn_write_frame(disp->output + disp->available,
                                disp->capacity - disp->available, frame))) {
      disp->capacity *= 2;
      disp->output = (char *) realloc(disp->output, disp->capacity);
    }
    disp->output_frames_ct += 1;
    framecount++;
    if (disp->trace & PN_TRACE_RAW) {
      pn_string_set(disp->scratch, "RAW: \"");
      pn_quote(disp->scratch, disp->output + disp->available, n);
      pn_string_addf(disp->scratch, "\"");
      pn_transport_log(disp->transport, pn_string_get(disp->scratch));
    }
    disp->available += n;
  } while (disp->output_size > 0 && framecount < frame_limit);

  disp->output_payload = NULL;
  return framecount;
}
コード例 #17
0
ファイル: subscription.c プロジェクト: 850361813/qpid-proton
const char *pn_subscription_scheme(pn_subscription_t *sub)
{
  assert(sub);
  return pn_string_get(sub->scheme);
}
コード例 #18
0
ファイル: reactor-send.c プロジェクト: MZDN/qpid-proton
void sender_dispatch(pn_handler_t *h, pn_event_t *event, pn_event_type_t type)
{
  sender_context_t *sc = sender_context(h);

  switch (type) {
  case PN_CONNECTION_INIT:
    {
      pn_connection_t *conn = pn_event_connection(event);
      pn_connection_set_container(conn, pn_string_get(sc->container_id));
      pn_connection_set_hostname(conn, pn_string_get(sc->hostname));
      pn_connection_open(conn);
      pn_session_t *ssn = pn_session(conn);
      pn_session_open(ssn);
      pn_link_t *snd = pn_sender(ssn, "sender");
      const char *path = pn_url_get_path(sc->send_url);
      if (path && strlen(path)) {
        pn_terminus_set_address(pn_link_target(snd), path);
        pn_terminus_set_address(pn_link_source(snd), path);
      }
      pn_link_open(snd);
    }
    break;
  case PN_LINK_FLOW:
    {
      pn_link_t *snd = pn_event_link(event);
      while (pn_link_credit(snd) > 0 && sc->sent < sc->opts->msg_count) {
        if (sc->sent == 0)
          statistics_start(sc->stats);

        char tag[8];
        void *ptr = &tag;
        *((uint64_t *) ptr) = sc->sent;
        pn_delivery_t *dlv = pn_delivery(snd, pn_dtag(tag, 8));

        // setup the message to send
        pn_message_t *msg = sc->message;
        pn_message_set_address(msg, sc->opts->targets.addresses[0]);
        sc->id.u.as_ulong = sc->sent;
        pn_message_set_correlation_id(msg, sc->id);
        pn_message_set_creation_time(msg, msgr_now());

        size_t size = sc->encoded_data_size;
        int err = pn_message_encode(msg, sc->encoded_data, &size);
        check(err == 0, "message encoding error");
        pn_link_send(snd, sc->encoded_data, size);
        pn_delivery_settle(dlv);
        sc->sent++;
      }
      if (sc->sent == sc->opts->msg_count && !sc->opts->get_replies) {
        pn_link_close(snd);
        pn_connection_t *conn = pn_event_connection(event);
        pn_connection_close(conn);
      }
    }
    break;
  case PN_LINK_INIT:
    {
      pn_link_t *link = pn_event_link(event);
      if (pn_link_is_receiver(link)) {
        // Response messages link.  Could manage credit and deliveries in this handler but
        // a dedicated handler also works.
        pn_handler_t *replyto = replyto_handler(sc);
        pn_flowcontroller_t *fc = pn_flowcontroller(1024);
        pn_handler_add(replyto, fc);
        pn_decref(fc);
        pn_handshaker_t *handshaker = pn_handshaker();
        pn_handler_add(replyto, handshaker);
        pn_decref(handshaker);
        pn_record_t *record = pn_link_attachments(link);
        pn_record_set_handler(record, replyto);
        pn_decref(replyto);
      }
    }
    break;
  case PN_CONNECTION_LOCAL_CLOSE:
    {
      statistics_report(sc->stats, sc->sent, sc->received);
    }
    break;
  default:
    break;
  }
}