int (*udp_recv)(int, void *, void *);
int (*udp_handle)(udp_context_t *, void *, void *);
int (*udp_send)(void *, void *);
+ int (*udp_tick)(void *, void *);
} udp_api_t;
+static int udp_noop(void *unused1, void *unused2) {
+ UNUSED(unused1);
+ UNUSED(unused2);
+ return KNOT_EOK;
+}
+
/*! \brief Control message to fit IP_PKTINFO or IPv6_RECVPKTINFO. */
typedef union {
struct cmsghdr cmsg;
udp_recvfrom_deinit,
udp_recvfrom_recv,
udp_recvfrom_handle,
- udp_recvfrom_send
+ udp_recvfrom_send,
+ udp_noop
};
#ifdef ENABLE_RECVMMSG
udp_recvmmsg_deinit,
udp_recvmmsg_recv,
udp_recvmmsg_handle,
- udp_recvmmsg_send
+ udp_recvmmsg_send,
+ udp_noop
};
#endif /* ENABLE_RECVMMSG */
return xdp_handle_send(d, xdp_sock);
}
+static int xdp_recvmmsg_tick(void *d, void *xdp_sock)
+{
+ return xdp_handle_timeout(d, xdp_sock);
+}
+
static udp_api_t xdp_recvmmsg_api = {
xdp_recvmmsg_init,
xdp_recvmmsg_deinit,
xdp_recvmmsg_recv,
xdp_recvmmsg_handle,
- xdp_recvmmsg_send
+ xdp_recvmmsg_send,
+ xdp_recvmmsg_tick
};
#endif /* ENABLE_XDP */
/* Wait for events. */
fdset_it_t it;
- (void)fdset_poll(&fds, &it, 0, -1);
+ (void)fdset_poll(&fds, &it, 0, 1000);
/* Process the events. */
for (; !fdset_it_is_done(&it); fdset_it_next(&it)) {
api->udp_send(rq, xdp_socket);
}
}
+
+ /* Regular maintenance (XDP-TCP only). */
+ api->udp_tick(rq, xdp_socket);
}
finish:
tcp_relay_dynarray_free(&ctx->tcp_relays);
if (ret == KNOT_EOK) {
- ret = knot_xdp_tcp_timeout(ctx->tcp_table, xdp_sock, 20, 2000000, 4000000, overweight(ctx->tcp_table->usage, 1000), NULL); // FIXME configurable parameters
+ ret = xdp_handle_timeout(ctx, xdp_sock);
}
return ret;
}
+int xdp_handle_timeout(xdp_handle_ctx_t *ctx, knot_xdp_socket_t *xdp_sock)
+{
+ return knot_xdp_tcp_timeout(ctx->tcp_table, xdp_sock, 20, 2000000, 4000000, overweight(ctx->tcp_table->usage, 1000), NULL); // FIXME configurable parameters
+}
+
#endif // ENABLE_XDP