Beispiel #1
0
void process_flow(ldp_connection_t *conn, pn_event_t *event) {
    fprintf(stderr, "flow event %s\n", pn_event_type_name(pn_event_type(event)));

    pn_link_t *sender = pn_event_link(event);

    pn_message_t *message = pn_message();
    pn_message_set_address(message, "amqp://foo/bar");
    pn_data_t *body = pn_message_body(message);
    char *msgtext = "hello world!";
    pn_data_put_string(body, pn_bytes(strlen(msgtext), msgtext));
    pn_buffer_t *buffer = pn_buffer(1000);
    char *encoded = pn_buffer_bytes(buffer).start;
    size_t size = pn_buffer_capacity(buffer);
    int err = pn_message_encode(message, encoded, &size);
    if (err) {
        fprintf(stderr, "trouble encoding message\n");
    } else {
        char tag[8];
        static uint64_t next_tag;
        *((uint64_t*)tag) = ++next_tag;
        pn_delivery_t *d = pn_delivery(sender, pn_dtag(tag, 8));
        pn_link_send(sender, encoded, size);
        pn_link_advance(sender);
    }
    pn_buffer_free(buffer);
    pn_message_free(message);
}
Beispiel #2
0
static ssize_t pn_input_read_sasl_encrypt(pn_transport_t* transport, unsigned int layer, const char* bytes, size_t available)
{
  pn_buffer_t *in = transport->sasl->decoded_buffer;
  const size_t max_buffer = transport->sasl->max_encrypt_size;
  for (size_t processed = 0; processed<available;) {
    pn_bytes_t decoded = pn_bytes(0, NULL);
    size_t decode_size = (available-processed)<=max_buffer?(available-processed):max_buffer;
    ssize_t size = pni_sasl_impl_decode(transport, pn_bytes(decode_size, bytes+processed), &decoded);
    if (size<0) return size;
    if (size>0) {
      size = pn_buffer_append(in, decoded.start, decoded.size);
      if (size) return size;
    }
    processed += decode_size;
  }
  pn_bytes_t decoded = pn_buffer_bytes(in);
  size_t processed_size = 0;
  while (processed_size < decoded.size) {
    ssize_t size = pni_passthru_layer.process_input(transport, layer, decoded.start+processed_size, decoded.size-processed_size);
    if (size==0) break;
    if (size<0) return size;
    pn_buffer_trim(in, size, 0);
    processed_size += size;
  }
  return available;
}
Beispiel #3
0
static const char *pn_buffer_str(pn_buffer_t *buf)
{
  if (buf) {
    pn_bytes_t bytes = pn_buffer_bytes(buf);
    if (bytes.size) {
      return bytes.start;
    }
  }

  return NULL;
}
Beispiel #4
0
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;
}
Beispiel #5
0
int pn_message_encode(pn_message_t *msg, char *bytes, size_t *size)
{
  if (!msg || !bytes || !size || !*size) return PN_ARG_ERR;
  if (!msg->data) {
    msg->data = pn_data(64);
  }
  if (!msg->body) {
    msg->body = pn_data(64);
  }

  int err = pn_data_clear(msg->data);
  if (err) return err;

  err = pn_data_fill(msg->data, "DL[oBIoI]", HEADER, msg->durable,
                     msg->priority, msg->ttl, msg->first_acquirer,
                     msg->delivery_count);
  if (err) return err;

  err = pn_data_fill(msg->data, "DL[nzSSSnssLLSiS]", PROPERTIES,
                     pn_buffer_bytes(msg->user_id),
                     pn_buffer_str(msg->address),
                     pn_buffer_str(msg->subject),
                     pn_buffer_str(msg->reply_to),
                     pn_buffer_str(msg->content_type),
                     pn_buffer_str(msg->content_encoding),
                     msg->expiry_time,
                     msg->creation_time,
                     pn_buffer_str(msg->group_id),
                     msg->group_sequence,
                     pn_buffer_str(msg->reply_to_group_id));
  if (err) return err;

  size_t remaining = *size;
  size_t encoded = remaining;

  err = pn_data_encode(msg->data, bytes, &encoded);
  if (err) return err;

  bytes += encoded;
  remaining -= encoded;

  encoded = remaining;
  err = pn_data_encode(msg->body, bytes, &encoded);
  if (err) return err;
  bytes += encoded;
  remaining -= encoded;

  *size -= remaining;

  return 0;
}
Beispiel #6
0
pn_bytes_t pn_message_get_user_id(pn_message_t *msg)
{
  return msg && msg->user_id ? pn_buffer_bytes(msg->user_id) : pn_bytes(0, NULL);
}
Beispiel #7
0
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;
}