Esempio n. 1
0
std::string Connection::getError()
{
    std::stringstream text;
    pn_error_t* cerror = pn_connection_error(connection);
    if (cerror) text << "connection error " << pn_error_text(cerror) << " [" << cerror << "]";
    pn_error_t* terror = pn_transport_error(transport);
    if (terror) text << "transport error " << pn_error_text(terror) << " [" << terror << "]";
    return text.str();
}
Esempio n. 2
0
std::string ConnectionContext::getError()
{
    std::stringstream text;
    pn_error_t* cerror = pn_connection_error(connection);
    if (cerror) text << "connection error " << pn_error_text(cerror);
    pn_error_t* terror = pn_transport_error(engine);
    if (terror) text << "transport error " << pn_error_text(terror);
    return text.str();
}
Esempio n. 3
0
static void pni_connection_writable(pn_selectable_t *sel)
{
  pn_reactor_t *reactor = (pn_reactor_t *) pni_selectable_get_context(sel);
  pn_transport_t *transport = pni_transport(sel);
  ssize_t pending = pn_transport_pending(transport);
  if (pending > 0) {
    ssize_t n = pn_send(pni_reactor_io(reactor), pn_selectable_get_fd(sel),
                        pn_transport_head(transport), pending);
    if (n < 0) {
      if (!pn_wouldblock(pni_reactor_io(reactor))) {
        pn_condition_t *cond = pn_transport_condition(transport);
        if (!pn_condition_is_set(cond)) {
          pn_condition_set_name(cond, "proton:io");
          pn_condition_set_description(cond, pn_error_text(pn_reactor_error(reactor)));
        }
        pn_transport_close_head(transport);
      }
    } else {
      pn_transport_pop(transport, n);
    }
  }

  ssize_t newpending = pn_transport_pending(transport);
  if (newpending != pending) {
    pni_connection_update(sel);
    pn_reactor_update(reactor, sel);
  }
}
void protonError(int err, char *step, pn_messenger_t *messenger)
{
    const char *errMsg = NULL;

    if (0 == err)
    {
        return;
    }
    printf("ERROR: PROTON API: %s Errno: %d (%s)\n", step, err, pn_code(err));
    
#if (PN_VERSION_MINOR == 4)
    /*
    ** Proton-C 0.4 returns an error message directly
    */
    errMsg = pn_messenger_error(messenger);
    if (NULL == errMsg)
    {
        errMsg = "pn_messenger_error() returned NULL";
    }
#else
    /*
    ** Proton-C 0.5 and later returns an error structure which
    ** you retrieve the error message from as a separate step.
    */
    {
        pn_error_t *errInfo = pn_messenger_error(messenger);
        errMsg = pn_error_text(errInfo);
    }
#endif

    printf("ERROR: PROTON Msg: %s\n", (NULL == errMsg) ? "NULL" : errMsg);
}
Esempio n. 5
0
static void pni_connection_readable(pn_selectable_t *sel)
{
  pn_reactor_t *reactor = (pn_reactor_t *) pni_selectable_get_context(sel);
  pn_transport_t *transport = pni_transport(sel);
  ssize_t capacity = pn_transport_capacity(transport);
  if (capacity > 0) {
    ssize_t n = pn_recv(pni_reactor_io(reactor), pn_selectable_get_fd(sel),
                        pn_transport_tail(transport), capacity);
    if (n <= 0) {
      if (n == 0 || !pn_wouldblock(pni_reactor_io(reactor))) {
        if (n < 0) {
          pn_condition_t *cond = pn_transport_condition(transport);
          pn_condition_set_name(cond, "proton:io");
          pn_condition_set_description(cond, pn_error_text(pn_reactor_error(reactor)));
        }
        pn_transport_close_tail(transport);
      }
    } else {
      pn_transport_process(transport, (size_t)n);
    }
  }

  ssize_t newcap = pn_transport_capacity(transport);
  //occasionally transport events aren't generated when expected, so
  //the following hack ensures we always update the selector
  if (1 || newcap != capacity) {
    pni_connection_update(sel);
    pn_reactor_update(reactor, sel);
  }
}
Esempio n. 6
0
pn_socket_t pni_iocp_end_accept(iocpdesc_t *ld, sockaddr *addr, socklen_t *addrlen, bool *would_block, pn_error_t *error)
{
  if (!is_listener(ld)) {
    set_iocp_error_status(error, PN_ERR, WSAEOPNOTSUPP);
    return INVALID_SOCKET;
  }
  if (ld->read_closed) {
    set_iocp_error_status(error, PN_ERR, WSAENOTSOCK);
    return INVALID_SOCKET;
  }
  if (pn_list_size(ld->acceptor->accepts) == 0) {
    if (ld->events & PN_READABLE && ld->iocp->iocp_trace)
      iocp_log("listen socket readable with no available accept completions\n");
    *would_block = true;
    return INVALID_SOCKET;
  }

  accept_result_t *result = (accept_result_t *) pn_list_get(ld->acceptor->accepts, 0);
  pn_list_del(ld->acceptor->accepts, 0, 1);
  if (!pn_list_size(ld->acceptor->accepts))
    pni_events_update(ld, ld->events & ~PN_READABLE);  // No pending accepts

  pn_socket_t accept_sock;
  if (result->base.status) {
    accept_sock = INVALID_SOCKET;
    pni_win32_error(ld->error, "accept failure", result->base.status);
    if (ld->iocp->iocp_trace)
      iocp_log("%s\n", pn_error_text(ld->error));
    // App never sees this socket so close it here.
    pni_iocp_begin_close(result->new_sock);
  } else {
    accept_sock = result->new_sock->socket;
    // AcceptEx special setsockopt:
    setsockopt(accept_sock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&ld->socket,
                  sizeof (SOCKET));
    if (addr && addrlen && *addrlen > 0) {
      sockaddr_storage *local_addr = NULL;
      sockaddr_storage *remote_addr = NULL;
      int local_addrlen, remote_addrlen;
      LPFN_GETACCEPTEXSOCKADDRS fn = ld->acceptor->fn_get_accept_ex_sockaddrs;
      fn(result->address_buffer, 0, IOCP_SOCKADDRMAXLEN, IOCP_SOCKADDRMAXLEN,
         (SOCKADDR **) &local_addr, &local_addrlen, (SOCKADDR **) &remote_addr,
         &remote_addrlen);
      *addrlen = pn_min(*addrlen, remote_addrlen);
      memmove(addr, remote_addr, *addrlen);
    }
  }

  if (accept_sock != INVALID_SOCKET) {
    // Connected.
    result->new_sock->read_closed = false;
    result->new_sock->write_closed = false;
  }

  // Done with the completion result, so reuse it
  result->new_sock = NULL;
  begin_accept(ld->acceptor, result);
  return accept_sock;
}
Esempio n. 7
0
const char *pn_messenger_error(pn_messenger_t *messenger)
{
  if (messenger) {
    return pn_error_text(messenger->error);
  } else {
    return NULL;
  }
}
Esempio n. 8
0
ssize_t pni_iocp_begin_write(iocpdesc_t *iocpd, const void *buf, size_t len, bool *would_block, pn_error_t *error)
{
  if (len == 0) return 0;
  *would_block = false;
  if (is_listener(iocpd)) {
    set_iocp_error_status(error, PN_ERR, WSAEOPNOTSUPP);
    return INVALID_SOCKET;
  }
  if (iocpd->closing) {
    set_iocp_error_status(error, PN_ERR, WSAESHUTDOWN);
    return SOCKET_ERROR;
  }
  if (iocpd->write_closed) {
    assert(pn_error_code(iocpd->error));
    pn_error_copy(error, iocpd->error);
    if (iocpd->iocp->iocp_trace)
      iocp_log("write error: %s\n", pn_error_text(error));
    return SOCKET_ERROR;
  }
  if (len == 0) return 0;
  if (!(iocpd->events & PN_WRITABLE)) {
    *would_block = true;
    return SOCKET_ERROR;
  }

  size_t written = 0;
  size_t requested = len;
  const char *outgoing = (const char *) buf;
  size_t available = pni_write_pipeline_reserve(iocpd->pipeline, len);
  if (!available) {
    *would_block = true;
    return SOCKET_ERROR;
  }

  for (size_t wr_count = 0; wr_count < available; wr_count++) {
    write_result_t *result = pni_write_pipeline_next(iocpd->pipeline);
    assert(result);
    result->base.iocpd = iocpd;
    ssize_t actual_len = pn_min(len, result->buffer.size);
    result->requested = actual_len;
    memmove((void *)result->buffer.start, outgoing, actual_len);
    outgoing += actual_len;
    written += actual_len;
    len -= actual_len;

    int werror = submit_write(result, result->buffer.start, actual_len);
    if (werror && WSAGetLastError() != ERROR_IO_PENDING) {
      pni_write_pipeline_return(iocpd->pipeline, result);
      iocpdesc_fail(iocpd, WSAGetLastError(), "overlapped send");
      return SOCKET_ERROR;
    }
    iocpd->ops_in_progress++;
  }

  if (!pni_write_pipeline_writable(iocpd->pipeline))
    pni_events_update(iocpd, iocpd->events & ~PN_WRITABLE);
  return written;
}
Esempio n. 9
0
int pn_error_copy(pn_error_t *error, pn_error_t *src)
{
  assert(error);
  if (src) {
    return pn_error_set(error, pn_error_code(src), pn_error_text(src));
  } else {
    pn_error_clear(error);
    return 0;
  }
}
Esempio n. 10
0
static void iocpdesc_fail(iocpdesc_t *iocpd, HRESULT status, const char* text)
{
  pni_win32_error(iocpd->error, text, status);
  if (iocpd->iocp->iocp_trace) {
    iocp_log("connection terminated: %s\n", pn_error_text(iocpd->error));
  }
  iocpd->write_closed = true;
  iocpd->read_closed = true;
  iocpd->poll_error = true;
  pni_events_update(iocpd, iocpd->events & ~(PN_READABLE | PN_WRITABLE));
}
Esempio n. 11
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;
}
Esempio n. 12
0
pn_socket_t pni_iocp_begin_connect(iocp_t *iocp, pn_socket_t sock, struct addrinfo *addr, pn_error_t *error)
{
  // addr lives for the duration of the async connect.  Caller has passed ownership here.
  // See connect_result_finalize().
  // Use of Windows-specific ConnectEx() requires our socket to be "loosely" pre-bound:
  sockaddr_storage sa;
  memset(&sa, 0, sizeof(sa));
  sa.ss_family = addr->ai_family;
  if (bind(sock, (SOCKADDR *) &sa, addr->ai_addrlen)) {
    pni_win32_error(error, "begin async connection", WSAGetLastError());
    if (iocp->iocp_trace)
      iocp_log("%s\n", pn_error_text(error));
    closesocket(sock);
    freeaddrinfo(addr);
    return INVALID_SOCKET;
  }

  iocpdesc_t *iocpd = pni_iocpdesc_create(iocp, sock, false);
  bind_to_completion_port(iocpd);
  LPFN_CONNECTEX fn_connect_ex = lookup_connect_ex(iocpd->socket);
  connect_result_t *result = connect_result(iocpd, addr);
  DWORD unused;
  bool success = fn_connect_ex(iocpd->socket, result->addrinfo->ai_addr, result->addrinfo->ai_addrlen,
                               NULL, 0, &unused, (LPOVERLAPPED) result);
  if (!success && WSAGetLastError() != ERROR_IO_PENDING) {
    pni_win32_error(error, "ConnectEx failure", WSAGetLastError());
    pn_free(result);
    iocpd->write_closed = true;
    iocpd->read_closed = true;
    pni_iocp_begin_close(iocpd);
    sock = INVALID_SOCKET;
    if (iocp->iocp_trace)
      iocp_log("%s\n", pn_error_text(error));
  } else {
    iocpd->ops_in_progress++;
  }
  return sock;
}
Esempio n. 13
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;
}
Esempio n. 14
0
void pn_io_initialize(void *obj)
{
  pn_io_t *io = (pn_io_t *) obj;
  io->error = pn_error();
  io->wouldblock = false;
  io->trace = pn_env_bool("PN_TRACE_DRV");

  /* Request WinSock 2.2 */
  WORD wsa_ver = MAKEWORD(2, 2);
  WSADATA unused;
  int err = WSAStartup(wsa_ver, &unused);
  if (err) {
    pni_win32_error(io->error, "WSAStartup", WSAGetLastError());
    fprintf(stderr, "Can't load WinSock: %s\n", pn_error_text(io->error));
  }
  io->iocp = pni_iocp();
}
Esempio n. 15
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;
}
Esempio n. 16
0
const char *pn_scanner_error(pn_scanner_t *scanner)
{
  return pn_error_text(scanner->error);
}
Esempio n. 17
0
void amqp::Sender::_throwError()
{
	throw std::exception(pn_error_text(pn_messenger_error(m_messenger)));
}
Esempio n. 18
0
void pni_handle_bound(pn_reactor_t *reactor, pn_event_t *event) {
  assert(reactor);
  assert(event);

  pn_connection_t *conn = pn_event_connection(event);
  pn_transport_t *transport = pn_event_transport(event);
  pn_record_t *record = pn_connection_attachments(conn);
  pn_url_t *url = (pn_url_t *)pn_record_get(record, PNI_CONN_PEER_ADDRESS);
  const char *host = NULL;
  const char *port = "5672";
  pn_string_t *str = NULL;

  // link the new transport to its reactor:
  pni_record_init_reactor(pn_transport_attachments(transport), reactor);

  if (pn_connection_acceptor(conn) != NULL) {
      // this connection was created by the acceptor.  There is already a
      // socket assigned to this connection.  Nothing needs to be done.
      return;
  }

  if (url) {
      host = pn_url_get_host(url);
      const char *uport = pn_url_get_port(url);
      if (uport) {
          port = uport;
      } else {
          const char *scheme = pn_url_get_scheme(url);
          if (scheme && strcmp(scheme, "amqps") == 0) {
              port = "5671";
          }
      }
      if (!pn_connection_get_user(conn)) {
          // user did not manually set auth info
          const char *user = pn_url_get_username(url);
          if (user) pn_connection_set_user(conn, user);
          const char *passwd = pn_url_get_password(url);
          if (passwd) pn_connection_set_password(conn, passwd);
      }
  } else {
      // for backward compatibility, see if the connection's hostname can be
      // used for the remote address.  See JIRA PROTON-1133
      const char *hostname = pn_connection_get_hostname(conn);
      if (hostname) {
          str = pn_string(hostname);
          char *h = pn_string_buffer(str);
          // see if a port has been included in the hostname.  This is not
          // allowed by the spec, but the old reactor interface allowed it.
          char *colon = strrchr(h, ':');
          if (colon) {
              *colon = '\0';
              port = colon + 1;
          }
          host = h;
      }
  }

  if (!host) {
      // error: no address configured
      pn_condition_t *cond = pn_transport_condition(transport);
      pn_condition_set_name(cond, "proton:io");
      pn_condition_set_description(cond, "Connection failed: no address configured");
      pn_transport_close_tail(transport);
      pn_transport_close_head(transport);
  } else {
      pn_socket_t sock = pn_connect(pni_reactor_io(reactor), host, port);
      // invalid sockets are ignored by poll, so we need to do this manually
      if (sock == PN_INVALID_SOCKET) {
          pn_condition_t *cond = pn_transport_condition(transport);
          pn_condition_set_name(cond, "proton:io");
          pn_condition_set_description(cond, pn_error_text(pn_reactor_error(reactor)));
          pn_transport_close_tail(transport);
          pn_transport_close_head(transport);
      } else {
          pn_reactor_selectable_transport(reactor, sock, transport);
      }
  }
  pn_free(str);
}