示例#1
0
/* Close the transport to abort a connection, i.e. close the socket without an AMQP close */
static pn_event_type_t listen_abort_handler(test_handler_t *th, pn_event_t *e) {
  switch (pn_event_type(e)) {
   case PN_CONNECTION_REMOTE_OPEN:
    /* Close the transport - abruptly closes the socket */
    pn_transport_close_tail(pn_connection_transport(pn_event_connection(e)));
    pn_transport_close_head(pn_connection_transport(pn_event_connection(e)));
    return PN_EVENT_NONE;

   default:
    /* Don't auto-close the listener to keep the event sequences simple */
    return listen_handler(th, e);
  }
}
示例#2
0
static void test_netaddr(test_t *t) {
  test_proactor_t tps[] ={ test_proactor(t, open_wake_handler), test_proactor(t, listen_handler) };
  pn_proactor_t *client = tps[0].proactor;
  /* Use IPv4 to get consistent results all platforms */
  pn_listener_t *l = test_listen(&tps[1], "127.0.0.1");
  pn_connection_t *c = pn_connection();
  pn_proactor_connect2(client, c, NULL, listener_info(l).connect);
  if (!TEST_ETYPE_EQUAL(t, PN_CONNECTION_REMOTE_OPEN, TEST_PROACTORS_RUN(tps))) {
    TEST_COND_EMPTY(t, last_condition); /* Show the last condition */
    return;                     /* don't continue if connection is closed */
  }

  /* client remote, client local, server remote and server local address strings */
  char cr[1024], cl[1024], sr[1024], sl[1024];

  pn_transport_t *ct = pn_connection_transport(c);
  const pn_netaddr_t *na = pn_transport_remote_addr(ct);
  pn_netaddr_str(na, cr, sizeof(cr));
  TEST_STR_IN(t, listener_info(l).port, cr); /* remote address has listening port */

  pn_connection_t *s = last_accepted; /* server side of the connection */

  pn_transport_t *st = pn_connection_transport(s);
  if (!TEST_CHECK(t, st)) return;
  pn_netaddr_str(pn_transport_local_addr(st), sl, sizeof(sl));
  TEST_STR_EQUAL(t, cr, sl);  /* client remote == server local */

  pn_netaddr_str(pn_transport_local_addr(ct), cl, sizeof(cl));
  pn_netaddr_str(pn_transport_remote_addr(st), sr, sizeof(sr));
  TEST_STR_EQUAL(t, cl, sr);    /* client local == server remote */

  char host[MAX_STR] = "";
  char serv[MAX_STR] = "";
  int err = pn_netaddr_host_port(na, host, sizeof(host), serv, sizeof(serv));
  TEST_CHECK(t, 0 == err);
  TEST_STR_EQUAL(t, "127.0.0.1", host);
  TEST_STR_EQUAL(t, listener_info(l).port, serv);

  /* Make sure you can use NULL, 0 to get length of address string without a crash */
  size_t len = pn_netaddr_str(pn_transport_local_addr(ct), NULL, 0);
  TEST_CHECKF(t, strlen(cl) == len, "%d != %d", strlen(cl), len);

  TEST_PROACTORS_DRAIN(tps);
  TEST_PROACTORS_DESTROY(tps);
}
示例#3
0
void qd_policy_amqp_open(void *context, bool discard)
{
    qd_connection_t *qd_conn = (qd_connection_t *)context;
    if (!discard) {
        pn_connection_t *conn = qd_connection_pn(qd_conn);
        qd_dispatch_t *qd = qd_conn->server->qd;
        qd_policy_t *policy = qd->policy;
        bool connection_allowed = true;

        if (policy->enableAccessRules) {
            // Open connection or not based on policy.
            pn_transport_t *pn_trans = pn_connection_transport(conn);
            const char *hostip = qdpn_connector_hostip(qd_conn->pn_cxtr);
            const char *pcrh = pn_connection_remote_hostname(conn);
            const char *app = (pcrh ? pcrh : "");
            const char *conn_name = qdpn_connector_name(qd_conn->pn_cxtr);
#define SETTINGS_NAME_SIZE 256
            char settings_name[SETTINGS_NAME_SIZE];
            uint32_t conn_id = qd_conn->connection_id;
            qd_conn->policy_settings = NEW(qd_policy_settings_t); // TODO: memory pool for settings
            memset(qd_conn->policy_settings, 0, sizeof(qd_policy_settings_t));

            if (qd_policy_open_lookup_user(policy, qd_conn->user_id, hostip, app, conn_name,
                                           settings_name, SETTINGS_NAME_SIZE, conn_id,
                                           qd_conn->policy_settings) &&
                settings_name[0]) {
                // This connection is allowed by policy.
                // Apply transport policy settings
                if (qd_conn->policy_settings->maxFrameSize > 0)
                    pn_transport_set_max_frame(pn_trans, qd_conn->policy_settings->maxFrameSize);
                if (qd_conn->policy_settings->maxSessions > 0)
                    pn_transport_set_channel_max(pn_trans, qd_conn->policy_settings->maxSessions - 1);
            } else {
                // This connection is denied by policy.
                connection_allowed = false;
            }
        } else {
            // No policy implies automatic policy allow
            // Note that connections not governed by policy have no policy_settings.
        }
        if (connection_allowed) {
            if (pn_connection_state(conn) & PN_LOCAL_UNINIT)
                pn_connection_open(conn);
            policy_notify_opened(qd_conn->open_container, qd_conn, qd_conn->context);
        } else {
            qd_policy_private_deny_amqp_connection(conn, RESOURCE_LIMIT_EXCEEDED, CONNECTION_DISALLOWED);
        }
    }
    qd_connection_set_event_stall(qd_conn, false);
}
示例#4
0
uint32_t connection::idle_timeout() const {
    return pn_transport_get_remote_idle_timeout(pn_connection_transport(pn_object()));
}
示例#5
0
transport connection::transport() const {
    return make_wrapper(pn_connection_transport(pn_object()));
}
示例#6
0
uint16_t connection::max_sessions() const {
    return pn_transport_remote_channel_max(pn_connection_transport(pn_object()));
}
示例#7
0
uint32_t connection::max_frame_size() const {
    return pn_transport_get_remote_max_frame(pn_connection_transport(pn_object()));
}
示例#8
0
transport &connection::transport() {
    return *transport::cast(pn_connection_transport(pn_cast(this)));
}
示例#9
0
std::string connection::user() const {
    return str(pn_transport_get_user(pn_connection_transport(pn_object())));
}
示例#10
0
    void apply(connection& c) {
        pn_connection_t *pnc = connection_options::pn_connection(c);
        pn_transport_t *pnt = pn_connection_transport(pnc);
        connector *outbound = dynamic_cast<connector*>(
            connection_context::get(c).handler.get());
        bool uninit = (c.state() & endpoint::LOCAL_UNINIT);

        // pnt is NULL between reconnect attempts.
        // Only apply transport options if uninit or outbound with
        // transport not yet configured.
        if (pnt && (uninit || (outbound && !outbound->transport_configured())))
        {
            // SSL
            if (outbound && outbound->address().scheme() == url::AMQPS) {
                pn_ssl_t *ssl = pn_ssl(pnt);
                if (pn_ssl_init(ssl, ssl_client_options.value.pn_domain(), NULL))
                    throw error(MSG("client SSL/TLS initialization error"));
            } else if (!outbound) {
                pn_acceptor_t *pnp = pn_connection_acceptor(pnc);
                if (pnp) {
                    listener_context &lc(listener_context::get(pnp));
                    if (lc.ssl) {
                        pn_ssl_t *ssl = pn_ssl(pnt);
                        if (pn_ssl_init(ssl, ssl_server_options.value.pn_domain(), NULL))
                            throw error(MSG("server SSL/TLS initialization error"));
                    }
                }
            }

            // SASL
            transport t = c.transport();
            if (!sasl_enabled.set || sasl_enabled.value) {
                if (sasl_enabled.set)  // Explicitly set, not just default behaviour.
                    t.sasl();          // Force a sasl instance.  Lazily create one otherwise.
                if (sasl_allow_insecure_mechs.set)
                    t.sasl().allow_insecure_mechs(sasl_allow_insecure_mechs.value);
                if (sasl_allowed_mechs.set)
                    t.sasl().allowed_mechs(sasl_allowed_mechs.value);
                if (sasl_config_name.set)
                    t.sasl().config_name(sasl_config_name.value);
                if (sasl_config_path.set)
                    t.sasl().config_path(sasl_config_path.value);
            }

            if (max_frame_size.set)
                pn_transport_set_max_frame(pnt, max_frame_size.value);
            if (max_channels.set)
                pn_transport_set_channel_max(pnt, max_channels.value);
            if (idle_timeout.set)
                pn_transport_set_idle_timeout(pnt, idle_timeout.value.ms());
        }
        // Only apply connection options if uninit.
        if (uninit) {
            if (reconnect.set && outbound)
                outbound->reconnect_timer(reconnect.value);
            if (container_id.set)
                pn_connection_set_container(pnc, container_id.value.c_str());
            if (link_prefix.set)
                connection_context::get(pnc).link_gen.prefix(link_prefix.value);
        }
    }