| #ifndef __dispatch_posix_driver_h__ |
| #define __dispatch_posix_driver_h__ 1 |
| |
| /* |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| |
| #include <proton/error.h> |
| #include <proton/sasl.h> |
| #include <proton/selectable.h> |
| #include <proton/ssl.h> |
| #include <proton/transport.h> |
| #include <proton/types.h> |
| |
| /** @file |
| * API for the Driver Layer. |
| * |
| * The driver library provides a simple implementation of a driver for |
| * the proton engine. A driver is responsible for providing input, |
| * output, and tick events to the bottom half of the engine API. See |
| * pn_transport_input, pn_transport_output, and |
| * pn_transport_tick. The driver also provides an interface for the |
| * application to access the top half of the API when the state of the |
| * engine may have changed due to I/O or timing events. Additionally |
| * the driver incorporates the SASL engine as well in order to provide |
| * a complete network stack: AMQP over SASL over TCP. |
| * |
| */ |
| |
| typedef struct qdpn_driver_t qdpn_driver_t; |
| typedef struct qdpn_listener_t qdpn_listener_t; |
| typedef struct qdpn_connector_t qdpn_connector_t; |
| |
| typedef enum { |
| QDPN_CONNECTOR_WRITABLE, |
| QDPN_CONNECTOR_READABLE |
| } qdpn_activate_criteria_t; |
| |
| /** Construct a driver |
| * |
| * Call qdpn_driver_free() to release the driver object. |
| * @return new driver object, NULL if error |
| */ |
| qdpn_driver_t *qdpn_driver(void); |
| |
| /** Return the most recent error code. |
| * |
| * @param[in] d the driver |
| * |
| * @return the most recent error text for d |
| */ |
| int qdpn_driver_errno(qdpn_driver_t *d); |
| |
| /** Get additional error information associated with the driver. |
| * |
| * Whenever a driver operation fails, additional error information can |
| * be obtained using this function. The error object that is returned |
| * may also be used to clear the error condition. |
| * |
| * The pointer returned by this operation is valid until the |
| * driver object is freed. |
| * |
| * @param[in] d the driver |
| * |
| * @return the driver's error object |
| */ |
| pn_error_t *qdpn_driver_error(qdpn_driver_t *d); |
| |
| /** Set the tracing level for the given driver. |
| * |
| * @param[in] driver the driver to trace |
| * @param[in] trace the trace level to use. |
| * @todo pn_trace_t needs documentation |
| */ |
| void qdpn_driver_trace(qdpn_driver_t *driver, pn_trace_t trace); |
| |
| /** Force qdpn_driver_wait() to return |
| * |
| * @param[in] driver the driver to wake up |
| * |
| * @return zero on success, an error code on failure |
| */ |
| int qdpn_driver_wakeup(qdpn_driver_t *driver); |
| |
| /** Wait for an active connector or listener |
| * |
| * @param[in] driver the driver to wait on |
| * @param[in] timeout maximum time in milliseconds to wait, -1 means |
| * infinite wait |
| * |
| * @return zero on success, an error code on failure |
| */ |
| int qdpn_driver_wait(qdpn_driver_t *driver, int timeout); |
| |
| /** Get the next listener with pending data in the driver. |
| * |
| * @param[in] driver the driver |
| * @return NULL if no active listener available |
| */ |
| qdpn_listener_t *qdpn_driver_listener(qdpn_driver_t *driver); |
| |
| /** Get the next active connector in the driver. |
| * |
| * Returns the next connector with pending inbound data, available |
| * capacity for outbound data, or pending tick. |
| * |
| * @param[in] driver the driver |
| * @return NULL if no active connector available |
| */ |
| qdpn_connector_t *qdpn_driver_connector(qdpn_driver_t *driver); |
| |
| /** Free the driver allocated via qdpn_driver, and all associated |
| * listeners and connectors. |
| * |
| * @param[in] driver the driver to free, no longer valid on |
| * return |
| */ |
| void qdpn_driver_free(qdpn_driver_t *driver); |
| |
| |
| /** qdpn_listener - the server API **/ |
| |
| /** Construct a listener for the given address. |
| * |
| * @param[in] driver driver that will 'own' this listener |
| * @param[in] host local host address to listen on |
| * @param[in] port local port to listen on |
| * @param[in] protocol family to use (IPv4 or IPv6 or 0). If 0 (zero) is passed in the protocol family will be automatically determined from the address |
| * @param[in] context application-supplied, can be accessed via |
| * qdpn_listener_context() |
| * @return a new listener on the given host:port, NULL if error |
| */ |
| qdpn_listener_t *qdpn_listener(qdpn_driver_t *driver, |
| const char *host, |
| const char *port, |
| const char *protocol_family, |
| void* context); |
| |
| /** Access the head listener for a driver. |
| * |
| * @param[in] driver the driver whose head listener will be returned |
| * |
| * @return the head listener for driver or NULL if there is none |
| */ |
| qdpn_listener_t *qdpn_listener_head(qdpn_driver_t *driver); |
| |
| /** Access the next listener. |
| * |
| * @param[in] listener the listener whose next listener will be |
| * returned |
| * |
| * @return the next listener |
| */ |
| qdpn_listener_t *qdpn_listener_next(qdpn_listener_t *listener); |
| |
| /** |
| * @todo qdpn_listener_trace needs documentation |
| */ |
| void qdpn_listener_trace(qdpn_listener_t *listener, pn_trace_t trace); |
| |
| /** Accept a connection that is pending on the listener. |
| * |
| * @param[in] listener the listener to accept the connection on |
| * @param[in] policy policy that holds absolute connection limits |
| * @param[in] policy_fn function that accepts remote host name and returns |
| * decision to allow or deny this connection |
| * @param[out] counted pointer to a bool set to true when the connection was |
| * counted against absolute connection limits |
| * @return a new connector for the remote, or NULL on error |
| */ |
| qdpn_connector_t *qdpn_listener_accept(qdpn_listener_t *listener, |
| void *policy, |
| bool (*policy_fn)(void *, const char *), |
| bool *counted); |
| |
| /** Access the application context that is associated with the listener. |
| * |
| * @param[in] listener the listener whose context is to be returned |
| * @return the application context that was passed to qdpn_listener() or |
| * qdpn_listener_fd() |
| */ |
| void *qdpn_listener_context(qdpn_listener_t *listener); |
| |
| void qdpn_listener_set_context(qdpn_listener_t *listener, void *context); |
| |
| /** Close the socket used by the listener. |
| * |
| * @param[in] listener the listener whose socket will be closed. |
| */ |
| void qdpn_listener_close(qdpn_listener_t *listener); |
| |
| /** Frees the given listener. |
| * |
| * Assumes the listener's socket has been closed prior to call. |
| * |
| * @param[in] listener the listener object to free, no longer valid |
| * on return |
| */ |
| void qdpn_listener_free(qdpn_listener_t *listener); |
| |
| |
| |
| |
| /** qdpn_connector - the client API **/ |
| |
| /** Construct a connector to the given remote address. |
| * |
| * @param[in] driver owner of this connection. |
| * @param[in] host remote host to connect to. |
| * @param[in] port remote port to connect to. |
| * @param[in] protocol family to use (IPv4 or IPv6 or 0). If 0 (zero) is passed in the protocol family will be automatically determined from the address |
| * @param[in] context application supplied, can be accessed via |
| * qdpn_connector_context() @return a new connector |
| * to the given remote, or NULL on error. |
| */ |
| qdpn_connector_t *qdpn_connector(qdpn_driver_t *driver, |
| const char *host, |
| const char *port, |
| const char *protocol_family, |
| void* context); |
| |
| /** Access the head connector for a driver. |
| * |
| * @param[in] driver the driver whose head connector will be returned |
| * |
| * @return the head connector for driver or NULL if there is none |
| */ |
| qdpn_connector_t *qdpn_connector_head(qdpn_driver_t *driver); |
| |
| /** Access the next connector. |
| * |
| * @param[in] connector the connector whose next connector will be |
| * returned |
| * |
| * @return the next connector |
| */ |
| qdpn_connector_t *qdpn_connector_next(qdpn_connector_t *connector); |
| |
| /** Set the tracing level for the given connector. |
| * |
| * @param[in] connector the connector to trace |
| * @param[in] trace the trace level to use. |
| */ |
| void qdpn_connector_trace(qdpn_connector_t *connector, pn_trace_t trace); |
| |
| /** Service the given connector. |
| * |
| * Handle any inbound data, outbound data, or timing events pending on |
| * the connector. |
| * |
| * @param[in] connector the connector to process. |
| */ |
| void qdpn_connector_process(qdpn_connector_t *connector); |
| |
| /** Access the listener which opened this connector. |
| * |
| * @param[in] connector connector whose listener will be returned. |
| * @return the listener which created this connector, or NULL if the |
| * connector has no listener (e.g. an outbound client |
| * connection) |
| */ |
| qdpn_listener_t *qdpn_connector_listener(qdpn_connector_t *connector); |
| |
| /** Access the Authentication and Security context of the connector. |
| * |
| * @param[in] connector connector whose security context will be |
| * returned |
| * @return the Authentication and Security context for the connector, |
| * or NULL if none |
| */ |
| pn_sasl_t *qdpn_connector_sasl(qdpn_connector_t *connector); |
| |
| /** Access the AMQP Connection associated with the connector. |
| * |
| * @param[in] connector the connector whose connection will be |
| * returned |
| * @return the connection context for the connector, or NULL if none |
| */ |
| pn_connection_t *qdpn_connector_connection(qdpn_connector_t *connector); |
| |
| /** Assign the AMQP Connection associated with the connector. |
| * |
| * @param[in] connector the connector whose connection will be set. |
| * @param[in] connection the connection to associate with the |
| * connector |
| */ |
| void qdpn_connector_set_connection(qdpn_connector_t *connector, pn_connection_t *connection); |
| |
| /** Access the application context that is associated with the |
| * connector. |
| * |
| * @param[in] connector the connector whose context is to be returned. |
| * @return the application context that was passed to qdpn_connector() |
| * or qdpn_connector_fd() |
| */ |
| void *qdpn_connector_context(qdpn_connector_t *connector); |
| |
| /** Assign a new application context to the connector. |
| * |
| * @param[in] connector the connector which will hold the context. |
| * @param[in] context new application context to associate with the |
| * connector |
| */ |
| void qdpn_connector_set_context(qdpn_connector_t *connector, void *context); |
| |
| /** Access the name of the connector |
| * |
| * @param[in] connector the connector of interest |
| * @return the name of the connector in the form of a null-terminated character string. |
| */ |
| const char *qdpn_connector_name(const qdpn_connector_t *connector); |
| |
| /** Access the numeric host ip of the connector |
| * |
| * @param[in] connector the connector of interest |
| * @return the numeric host ip address of the connector in the form of a null-terminated character string. |
| */ |
| const char *qdpn_connector_hostip(const qdpn_connector_t *connector); |
| |
| /** Access the transport used by this connector. |
| * |
| * @param[in] connector connector whose transport will be returned |
| * @return the transport, or NULL if none |
| */ |
| pn_transport_t *qdpn_connector_transport(qdpn_connector_t *connector); |
| |
| /** Close the socket used by the connector. |
| * |
| * @param[in] connector the connector whose socket will be closed |
| */ |
| void qdpn_connector_close(qdpn_connector_t *connector); |
| |
| /** Determine if the connector is closed. |
| * |
| * @return True if closed, otherwise false |
| */ |
| bool qdpn_connector_closed(qdpn_connector_t *connector); |
| |
| bool qdpn_connector_failed(qdpn_connector_t *connector); |
| |
| |
| /** Destructor for the given connector. |
| * |
| * Assumes the connector's socket has been closed prior to call. |
| * |
| * @param[in] connector the connector object to free. No longer |
| * valid on return |
| */ |
| void qdpn_connector_free(qdpn_connector_t *connector); |
| |
| /** Activate a connector when a criteria is met |
| * |
| * Set a criteria for a connector (i.e. it's transport is writable) that, once met, |
| * the connector shall be placed in the driver's work queue. |
| * |
| * @param[in] connector The connector object to activate |
| * @param[in] criteria The criteria that must be met prior to activating the connector |
| */ |
| void qdpn_connector_activate(qdpn_connector_t *connector, qdpn_activate_criteria_t criteria); |
| |
| /** Activate all of the open file descriptors |
| */ |
| void qdpn_activate_all(qdpn_driver_t *driver); |
| |
| /** Return the activation status of the connector for a criteria |
| * |
| * Return the activation status (i.e. readable, writable) for the connector. This function |
| * has the side-effect of canceling the activation of the criteria. |
| * |
| * Please note that this function must not be used for normal AMQP connectors. It is only |
| * used for connectors created so the driver can track non-AMQP file descriptors. Such |
| * connectors are never passed into qdpn_connector_process. |
| * |
| * @param[in] connector The connector object to activate |
| * @param[in] criteria The criteria to test. "Is this the reason the connector appeared |
| * in the work list?" |
| * @return true iff the criteria is activated on the connector. |
| */ |
| bool qdpn_connector_activated(qdpn_connector_t *connector, qdpn_activate_criteria_t criteria); |
| |
| /** Create a listener using the existing file descriptor. |
| * |
| * @param[in] driver driver that will 'own' this listener |
| * @param[in] fd existing socket for listener to listen on |
| * @param[in] context application-supplied, can be accessed via |
| * qdpn_listener_context() |
| * @return a new listener on the given host:port, NULL if error |
| */ |
| qdpn_listener_t *qdpn_listener_fd(qdpn_driver_t *driver, pn_socket_t fd, void *context); |
| |
| pn_socket_t qdpn_listener_get_fd(qdpn_listener_t *listener); |
| |
| /** Create a connector using the existing file descriptor. |
| * |
| * @param[in] driver driver that will 'own' this connector. |
| * @param[in] fd existing socket to use for this connector. |
| * @param[in] context application-supplied, can be accessed via |
| * qdpn_connector_context() |
| * @return a new connector to the given host:port, NULL if error. |
| */ |
| qdpn_connector_t *qdpn_connector_fd(qdpn_driver_t *driver, pn_socket_t fd, void *context); |
| |
| pn_socket_t qdpn_connector_get_fd(qdpn_connector_t *connector); |
| |
| |
| #endif /* driver.h */ |