Example #1
0
static void process_reply( pn_messenger_t *messenger,
                           pn_message_t *message)
{
    int rc;
    pn_data_t *body = pn_message_body(message);
    pn_bytes_t m_type;
    pn_bytes_t m_command;
    pn_bytes_t m_value;
    pn_bytes_t m_status;
    bool duplicate = false;

    rc = pn_data_scan( body, "{.S.S.S.S}",
                       &m_type, &m_command, &m_value, &m_status );
    check( rc == 0, "Failed to decode response message" );
    check(strncmp("response", m_type.start, m_type.size) == 0, "Unknown message type received");
    if (strncmp("DUPLICATE", m_status.start, m_status.size) == 0) {
        LOG( "Server detected duplicate request!\n" );
        duplicate = true;
    } else if (strncmp("OK", m_status.start, m_status.size)) {
        fprintf( stderr, "Request failed - error: %.*s\n", (int)m_status.size, m_status.start );
        return;
    }

    fprintf( stdout, "Fortune%s: \"%.*s\"%s\n",
             strncmp("set", m_command.start, m_command.size) == 0 ? " set to" : "",
             (int)m_value.size, m_value.start,
             duplicate ? " (duplicate detected by server)" : "" );
}
Example #2
0
int pn_message_save_text(pn_message_t *msg, char *data, size_t *size)
{
  if (!msg) return PN_ARG_ERR;

  if (!msg->body) {
    *size = 0;
    return 0;
  }

  uint64_t desc;
  pn_bytes_t str;
  bool scanned;
  int err = pn_data_scan(msg->body, "DL?S", &desc, &scanned, &str);
  if (err) return err;
  if (desc == AMQP_VALUE && scanned) {
    if (str.size >= *size) {
      return PN_OVERFLOW;
    } else {
      memcpy(data, str.start, str.size);
      data[str.size] = '\0';
      *size = str.size;
      return 0;
    }
  } else {
    return PN_STATE_ERR;
  }
}
Example #3
0
int pn_message_save_data(pn_message_t *msg, char *data, size_t *size)
{
  if (!msg) return PN_ARG_ERR;

  if (!msg->body || pn_data_size(msg->body) == 0) {
    *size = 0;
    return 0;
  }

  uint64_t desc;
  pn_bytes_t bytes;
  bool scanned;
  int err = pn_data_scan(msg->body, "DL?z", &desc, &scanned, &bytes);
  if (err) return err;
  if (desc == DATA && scanned) {
    if (bytes.size > *size) {
      return PN_OVERFLOW;
    } else {
      memcpy(data, bytes.start, bytes.size);
      *size = bytes.size;
      return 0;
    }
  } else {
    return PN_STATE_ERR;
  }
}
Example #4
0
// Received server side
int pn_do_response(pn_transport_t *transport, uint8_t frame_type, uint16_t channel, pn_data_t *args, const pn_bytes_t *payload)
{
  pn_bytes_t recv;
  int err = pn_data_scan(args, "D.[z]", &recv);
  if (err) return err;

  pni_process_response(transport, &recv);

  return 0;
}
Example #5
0
// Received Server side
int pn_do_init(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;
  pn_bytes_t mech;
  pn_bytes_t recv;
  int err = pn_data_scan(args, "D.[sz]", &mech, &recv);
  if (err) return err;
  sasl->selected_mechanism = pn_strndup(mech.start, mech.size);

  pni_process_init(transport, sasl->selected_mechanism, &recv);

  return 0;
}
Example #6
0
int buffer(int argc, char **argv)
{
  pn_buffer_t *buf = pn_buffer(16);

  pn_buffer_append(buf, "abcd", 4);
  pn_buffer_print(buf); printf("\n");
  pn_buffer_prepend(buf, "012", 3);
  pn_buffer_print(buf); printf("\n");
  pn_buffer_prepend(buf, "z", 1);
  pn_buffer_print(buf); printf("\n");
  pn_buffer_append(buf, "efg", 3);
  pn_buffer_print(buf); printf("\n");
  pn_buffer_append(buf, "hijklm", 6);
  pn_buffer_print(buf); printf("\n");
  pn_buffer_defrag(buf);
  pn_buffer_print(buf); printf("\n");
  pn_buffer_trim(buf, 1, 1);
  pn_buffer_print(buf); printf("\n");
  pn_buffer_trim(buf, 4, 0);
  pn_buffer_print(buf); printf("\n");
  pn_buffer_clear(buf);
  pn_buffer_print(buf); printf("\n");
  pn_buffer_free(buf);

  pn_data_t *data = pn_data(16);
  int err = pn_data_fill(data, "Ds[iSi]", "desc", 1, "two", 3);
  if (err) {
    printf("%s\n", pn_code(err));
  }
  pn_data_print(data); printf("\n");
  pn_bytes_t str;
  err = pn_data_scan(data, "D.[.S.]", &str);
  if (err) {
    printf("%s\n", pn_code(err));
  } else {
    printf("%.*s\n", (int) str.size, str.start);
  }

  pn_data_clear(data);
  pn_data_fill(data, "DL[SIonn?DL[S]?DL[S]nnI]", ATTACH, "asdf", 1, true,
               true, SOURCE, "queue",
               true, TARGET, "queue",
               0);

  pn_data_print(data); printf("\n");


  pn_data_free(data);

  return 0;
}
Example #7
0
// Received client side
int pn_do_outcome(pn_transport_t *transport, uint8_t frame_type, uint16_t channel, pn_data_t *args, const pn_bytes_t *payload)
{
  uint8_t outcome;
  int err = pn_data_scan(args, "D.[B]", &outcome);
  if (err) return err;

  pni_sasl_t *sasl = transport->sasl;
  sasl->outcome = (pn_sasl_outcome_t) outcome;
  bool authenticated = sasl->outcome==PN_SASL_OK;
  transport->authenticated = authenticated;
  pni_sasl_set_desired_state(transport, authenticated ? SASL_RECVED_OUTCOME_SUCCEED : SASL_RECVED_OUTCOME_FAIL);

  return 0;
}
Example #8
0
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;
}
Example #9
0
// 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;
}
Example #10
0
int pn_message_decode(pn_message_t *msg, const char *bytes, size_t size)
{
  if (!msg || !bytes || !size) return PN_ARG_ERR;

  if (!msg->data) {
    msg->data = pn_data(64);
  }
  if (!msg->body) {
    msg->body = pn_data(64);
  }

  pn_data_clear(msg->body);

  while (size) {
    size_t copy = size;
    pn_data_clear(msg->data);
    int err = pn_data_decode(msg->data, (char *) bytes, &copy);
    if (err) return err;
    size -= copy;
    bytes += copy;
    bool scanned;
    uint64_t desc;
    err = pn_data_scan(msg->data, "D?L.", &scanned, &desc);
    if (err) return err;
    if (!scanned){
      desc = 0;
    }

    switch (desc) {
    case HEADER:
      pn_data_scan(msg->data, "D.[oBIoI]", &msg->durable, &msg->priority,
                   &msg->ttl, &msg->first_acquirer, &msg->delivery_count);
      break;
    case PROPERTIES:
      {
        pn_bytes_t user_id, address, subject, reply_to, ctype, cencoding,
          group_id, reply_to_group_id;
        err = pn_data_scan(msg->data, "D.[.zSSS.ssLLSiS]", &user_id, &address,
                           &subject, &reply_to, &ctype, &cencoding,
                           &msg->expiry_time, &msg->creation_time, &group_id,
                           &msg->group_sequence, &reply_to_group_id);
        if (err) return err;
        err = pn_buffer_set_bytes(&msg->user_id, user_id);
        if (err) return err;
        err = pn_buffer_set_strn(&msg->address, address.start, address.size);
        if (err) return err;
        err = pn_buffer_set_strn(&msg->subject, subject.start, subject.size);
        if (err) return err;
        err = pn_buffer_set_strn(&msg->reply_to, reply_to.start, reply_to.size);
        if (err) return err;
        err = pn_buffer_set_strn(&msg->content_type, ctype.start, ctype.size);
        if (err) return err;
        err = pn_buffer_set_strn(&msg->content_encoding, cencoding.start,
                                 cencoding.size);
        if (err) return err;
        err = pn_buffer_set_strn(&msg->group_id, group_id.start, group_id.size);
        if (err) return err;
        err = pn_buffer_set_strn(&msg->reply_to_group_id, reply_to_group_id.start,
                                 reply_to_group_id.size);
        if (err) return err;
      }
      break;
    case DELIVERY_ANNOTATIONS:
    case MESSAGE_ANNOTATIONS:
      break;
    default:
      {
        pn_data_t *data = msg->body;
        msg->body = msg->data;
        msg->data = data;
        err = pn_data_intern(msg->body);
        if (err) return err;
      }
      break;
    }
  }

  return pn_data_clear(msg->data);
}