*/
typedef void (*fr_event_fd_handler_t)(fr_event_list_t *el, int sock, int flags, void *uctx);
+/** Called when an IO error event occurs on a file descriptor
+ *
+ * @param[in] el Event list the file descriptor was inserted into.
+ * @param[in] sock That experienced the IO event.
+ * @param[in] flags field as returned by kevent.
+ * @param[in] fd_errno File descriptor error.
+ * @param[in] uctx User ctx passed to #fr_event_fd_insert.
+ */
+typedef void (*fr_event_fd_error_handler_t)(fr_event_list_t *el, int sock, int flags, int fd_errno, void *uctx);
+
/** Called when a user kevent occurs
*
* @param[in] kq that received the user kevent.
int fr_event_fd_insert(fr_event_list_t *el, int fd,
fr_event_fd_handler_t read_fn,
fr_event_fd_handler_t write_fn,
- fr_event_fd_handler_t error,
+ fr_event_fd_error_handler_t error,
void *ctx);
int fr_event_timer_delete(fr_event_list_t *el, fr_event_timer_t **parent);
/** Handle errors for a socket.
*
- * @param el the event list
- * @param sockfd the socket which has a fatal error.
- * @param flags returned by kevent.
- * @param ctx the network socket context.
+ * @param[in] el the event list
+ * @param[in] sockfd the socket which has a fatal error.
+ * @param[in] flags returned by kevent.
+ * @param[in] fd_errno returned by kevent.
+ * @param[in] ctx the network socket context.
*/
-static void fr_network_error(UNUSED fr_event_list_t *el, UNUSED int sockfd, UNUSED int flags, void *ctx)
+static void fr_network_error(UNUSED fr_event_list_t *el, UNUSED int sockfd, UNUSED int flags,
+ UNUSED int fd_errno, void *ctx)
{
fr_network_socket_t *s = ctx;
fr_event_fd_handler_t read; //!< Callback for when data is available.
fr_event_fd_handler_t write; //!< Callback for when we can write data.
- fr_event_fd_handler_t error; //!< Callback for when an error occurs on the FD.
+ fr_event_fd_error_handler_t error; //!< Callback for when an error occurs on the FD.
bool is_registered; //!< Whether this fr_event_fd_t's FD has been registered with
//!< kevent. Mostly for debugging.
int fr_event_fd_insert(fr_event_list_t *el, int fd,
fr_event_fd_handler_t read_fn,
fr_event_fd_handler_t write_fn,
- fr_event_fd_handler_t error,
+ fr_event_fd_error_handler_t error,
void *ctx)
{
int filter = 0;
*/
for (i = 0; i < el->num_fd_events; i++) {
fr_event_fd_t *ev;
+ int fd_errno = 0;
int flags = el->events[i].flags;
/*
if (!fr_cond_assert(ev->is_registered)) continue;
if (flags & EV_ERROR) {
+ fd_errno = el->events[i].data;
ev_error:
/*
* Call the error handler which should
* tear down the connection.
*/
- if (ev->error) {
- ev->error(el, ev->fd, flags, ev->ctx);
- continue;
- }
+ if (ev->error) ev->error(el, ev->fd, flags, fd_errno, ev->ctx);
fr_event_fd_delete(el, ev->fd);
+ continue;
}
/*
*/
if ((ev->sock_type == SOCK_RAW) && ev->pf_attached) goto service;
#endif
+ fd_errno = el->events[i].fflags;
+
goto ev_error;
}
FR_DLIST_INIT(el->pre_callbacks);
FR_DLIST_INIT(el->post_callbacks);
FR_DLIST_INIT(el->user_callbacks);
-
+
if (status) (void) fr_event_pre_insert(el, status, status_ctx);
/*
*
* @param[in] el event list the I/O event occurred on.
* @param[in] sock the I/O even occurred for.
- * @param[in] flags from kevent.
+ * @param[in] flags from_kevent.
+ * @param[in] fd_errno from kevent.
* @param[in] uctx The #fr_connection_t this fd is associated with.
*/
-static void _connection_error(UNUSED fr_event_list_t *el, UNUSED int sock, UNUSED int flags, void *uctx)
+static void _connection_error(UNUSED fr_event_list_t *el, UNUSED int sock, UNUSED int flags, int fd_errno, void *uctx)
{
fr_connection_t *conn = talloc_get_type_abort(uctx, fr_connection_t);
struct timeval now;
- ERROR("Connection failed");
+ ERROR("Connection failed: %s", fr_syserror(fd_errno));
gettimeofday(&now, NULL);
connection_state_failed(conn, &now);
}
da = fr_dict_attr_by_name(NULL, "Packet-Type");
if (!da) {
*result = RLM_MODULE_FAIL;
- return UNLANG_ACTION_CALCULATE_RESULT;
+ return UNLANG_ACTION_CALCULATE_RESULT;
}
dval = fr_dict_enum_by_alias(NULL, da, g->vpt->name);
if (!dval) {
*result = RLM_MODULE_FAIL;
- return UNLANG_ACTION_CALCULATE_RESULT;
+ return UNLANG_ACTION_CALCULATE_RESULT;
}
child->packet->code = dval->value->vb_uint32;
* @param[in] el containing the event (not passed to the callback).
* @param[in] fd the I/O event occurred on.
* @param[in] flags from kevent.
+ * @param[in] fd_errno from kevent.
* @param[in] ctx unlang_event_t structure holding callbacks.
*/
-static void unlang_event_fd_error_handler(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, void *ctx)
+static void unlang_event_fd_error_handler(UNUSED fr_event_list_t *el, int fd,
+ UNUSED int flags, UNUSED int fd_errno, void *ctx)
{
unlang_event_t *ev = talloc_get_type_abort(ctx, unlang_event_t);
void *mutable_ctx;
/** Connection errored
*
*/
-static void _logtee_conn_error(UNUSED fr_event_list_t *el, UNUSED int sock, UNUSED int flags, void *uctx)
+static void _logtee_conn_error(UNUSED fr_event_list_t *el, int sock, UNUSED int flags, int fd_errno, void *uctx)
{
rlm_logtee_thread_t *t = talloc_get_type_abort(uctx, rlm_logtee_thread_t);
+ ERROR("Connection failed (%i): %s", sock, fr_syserror(fd_errno));
+
/*
* Something bad happened... Fix it...
*/
* @param[in] el fd was registered with.
* @param[in] fd that errored.
* @param[in] flags from kevent.
+ * @param[in] fd_errno from kevent.
* @param[in] ctx The rlm_rest_thread_t specific to this thread.
*/
-static void _rest_io_service_errored(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, void *ctx)
+static void _rest_io_service_errored(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, int fd_errno, void *ctx)
{
rlm_rest_thread_t *t;
t = talloc_get_type_abort(ctx, rlm_rest_thread_t);
- DEBUG4("libcurl fd %i errored", fd);
+ DEBUG4("libcurl fd %i errored: %s", fd, fr_syserror(fd_errno));
_rest_io_service(t, fd, CURL_CSELECT_ERR);
}