fr_event_insert(el, request_timer, request, \
&when, &request->ev);
-
+/*
+ * We need a different VERIFY_REQUEST macro in process.c
+ * To avoid the race conditions with the master thread
+ * checking the REQUEST whilst it's being worked on by
+ * the child.
+ */
+#if defined(WITH_VERIFY_PTR) && defined(HAVE_PTHREAD_H)
+# undef VERIFY_REQUEST
+# define VERIFY_REQUEST(_x) if (pthread_equal(pthread_self(), _x->child_pid) != 0) verify_request(__FILE__, __LINE__, _x)
+#endif
/**
* @section request_timeline
}
/*
- * In daemon mode, AND this request has debug flags set.
+ * Debug the packet if requested.
*/
-#define DEBUG_PACKET if (!debug_flag && request->log.lvl && request->log.func) debug_packet
+#define DEBUG_PACKET if (request->log.lvl && request->log.func) debug_packet
static void debug_packet(REQUEST *request, RADIUS_PACKET *packet, int direction)
{
static struct timeval *request_response_window(REQUEST *request)
{
- /*
- * The client hasn't set the response window. Return
- * either the home server one, if set, or the global one.
- */
- if (!timerisset(&request->client->response_window)) {
- return &request->home_server->response_window;
- }
+ VERIFY_REQUEST(request);
+
+ if (request->client) {
+ /*
+ * The client hasn't set the response window. Return
+ * either the home server one, if set, or the global one.
+ */
+ if (!timerisset(&request->client->response_window)) {
+ return &request->home_server->response_window;
+ }
- if (timercmp(&request->client->response_window,
- &request->home_server->response_window, <)) {
- return &request->client->response_window;
+ if (timercmp(&request->client->response_window,
+ &request->home_server->response_window, <)) {
+ return &request->client->response_window;
+ }
}
+ rad_assert(request->home_server != NULL);
return &request->home_server->response_window;
}
{
struct timeval half_response_window;
+ VERIFY_REQUEST(request);
+
/* Allow client response window to lower initial delay */
if (timerisset(&request->client->response_window)) {
half_response_window.tv_sec = request->client->response_window.tv_sec >> 1;
*/
static void request_timer(void *ctx)
{
- REQUEST *request = ctx;
- int action = request->timer_action;
+ REQUEST *request = talloc_get_type_abort(ctx, REQUEST);
+ int action;
+
+ action = request->timer_action;
TRACE_STATE_MACHINE;
char buffer[128];
#endif
+ VERIFY_REQUEST(request);
+
TRACE_STATE_MACHINE;
#ifdef WITH_COA
{
struct timeval now, when;
+ VERIFY_REQUEST(request);
+
if (request->packet->code == PW_CODE_ACCOUNTING_REQUEST) goto done;
if (!request->root->cleanup_delay) goto done;
int action = FR_ACTION_TIMER;
#endif
+ VERIFY_REQUEST(request);
+
TRACE_STATE_MACHINE;
ASSERT_MASTER;
int action = FR_ACTION_TIMER;
#endif
+ VERIFY_REQUEST(request);
+
TRACE_STATE_MACHINE;
/*
char buffer[128];
#endif
+ VERIFY_REQUEST(request);
+
TRACE_STATE_MACHINE;
ASSERT_MASTER;
{
struct timeval when;
+ VERIFY_REQUEST(request);
+
TRACE_STATE_MACHINE;
ASSERT_MASTER;
STATE_MACHINE_DECL(request_response_delay)
{
+ VERIFY_REQUEST(request);
+
TRACE_STATE_MACHINE;
ASSERT_MASTER;
static int CC_HINT(nonnull) request_pre_handler(REQUEST *request, UNUSED int action)
{
- TRACE_STATE_MACHINE;
-
int rcode;
+ VERIFY_REQUEST(request);
+
+ TRACE_STATE_MACHINE;
+
if (request->master_state == REQUEST_STOP_PROCESSING) return 0;
/*
{
VALUE_PAIR *vp;
+ VERIFY_REQUEST(request);
+
TRACE_STATE_MACHINE;
(void) action; /* -Wunused */
STATE_MACHINE_DECL(request_running)
{
+ VERIFY_REQUEST(request);
+
TRACE_STATE_MACHINE;
switch (action) {
struct timeval now;
listen_socket_t *sock = NULL;
+ VERIFY_PACKET(packet);
+
/*
* Set the last packet received.
*/
* Create and initialize the new request.
*/
request = request_alloc(NULL);
- request->reply = rad_alloc(request, 0);
+ request->reply = rad_alloc(request, false);
if (!request->reply) {
ERROR("No memory");
talloc_free(request);
*/
static void tcp_socket_timer(void *ctx)
{
- rad_listen_t *listener = ctx;
+ rad_listen_t *listener = talloc_get_type_abort(ctx, rad_listen_t);
listen_socket_t *sock = listener->data;
struct timeval end, now;
char buffer[256];
*/
static int eol_proxy_listener(void *ctx, void *data)
{
- rad_listen_t *this = ctx;
+ rad_listen_t *this = talloc_get_type_abort(ctx, rad_listen_t);
RADIUS_PACKET **proxy_p = data;
REQUEST *request;
static int eol_listener(void *ctx, void *data)
{
- rad_listen_t *this = ctx;
+ rad_listen_t *this = talloc_get_type_abort(ctx, rad_listen_t);
RADIUS_PACKET **packet_p = data;
REQUEST *request;
*/
static void remove_from_proxy_hash_nl(REQUEST *request, bool yank)
{
+ VERIFY_REQUEST(request);
+
if (!request->in_proxy_hash) return;
fr_packet_list_id_free(proxy_list, request->proxy, yank);
static void remove_from_proxy_hash(REQUEST *request)
{
+ VERIFY_REQUEST(request);
+
/*
* Check this without grabbing the mutex because it's a
* lot faster that way.
int rcode, tries;
void *proxy_listener;
+ VERIFY_REQUEST(request);
+
rad_assert(request->proxy != NULL);
rad_assert(request->home_server != NULL);
rad_assert(proxy_list != NULL);
int post_proxy_type = 0;
VALUE_PAIR *vp;
+ VERIFY_REQUEST(request);
+
/*
* There may be a proxy reply, but it may be too late.
*/
}
if (reply) {
+ VERIFY_PACKET(reply);
/*
* Decode the packet.
*/
struct timeval now;
char buffer[128];
+ VERIFY_PACKET(packet);
+
PTHREAD_MUTEX_LOCK(&proxy_mutex);
proxy_p = fr_packet_list_find_byreply(proxy_list, packet);
DICT_VALUE const *dval = NULL;
VALUE_PAIR *vp;
+ VERIFY_REQUEST(request);
+
if (request->proxy->code == PW_CODE_ACCESS_REQUEST) {
dval = dict_valbyname(PW_POST_PROXY_TYPE, 0,
"Fail-Authentication");
STATE_MACHINE_DECL(proxy_no_reply)
{
+ VERIFY_REQUEST(request);
+
TRACE_STATE_MACHINE;
switch (action) {
STATE_MACHINE_DECL(proxy_running)
{
+ VERIFY_REQUEST(request);
+
TRACE_STATE_MACHINE;
switch (action) {
REALM *realm = NULL;
home_pool_t *pool = NULL;
+ VERIFY_REQUEST(request);
+
if (!request->root->proxy_requests) return 0;
if (request->packet->dst_port == 0) return 0;
if (request->packet->code == PW_CODE_STATUS_SERVER) return 0;
{
char buffer[128];
+ VERIFY_REQUEST(request);
+
rad_assert(request->parent == NULL);
rad_assert(request->home_server != NULL);
{
home_server_t *home;
+ VERIFY_REQUEST(request);
+
/*
* Delete the request from the proxy list.
*
home_server_t *home = request->home_server;
char buffer[128];
+ VERIFY_REQUEST(request);
+
TRACE_STATE_MACHINE;
ASSERT_MASTER;
*/
static void ping_home_server(void *ctx)
{
- home_server_t *home = ctx;
+ home_server_t *home = talloc_get_type_abort(ctx, home_server_t);
REQUEST *request;
VALUE_PAIR *vp;
struct timeval when, now;
request->number = request_num_counter++;
NO_CHILD_THREAD;
- request->proxy = rad_alloc(request, 1);
+ request->proxy = rad_alloc(request, true);
rad_assert(request->proxy != NULL);
if (home->ping_check == HOME_PING_CHECK_STATUS_SERVER) {
void revive_home_server(void *ctx)
{
- home_server_t *home = ctx;
+ home_server_t *home = talloc_get_type_abort(ctx, home_server_t);
char buffer[128];
#ifdef WITH_TCP
home_server_t *home = request->home_server;
char buffer[128];
+ VERIFY_REQUEST(request);
+
TRACE_STATE_MACHINE;
rad_assert(request->packet->code != PW_CODE_STATUS_SERVER);
fr_ipaddr_t ipaddr;
char buffer[256];
- rad_assert(request != NULL);
+ VERIFY_REQUEST(request);
+
rad_assert(request->coa != NULL);
rad_assert(request->proxy == NULL);
rad_assert(!request->in_proxy_hash);
uint32_t delay, frac;
struct timeval now, when, mrd;
+ VERIFY_REQUEST(request);
+
rad_assert(request->parent == NULL);
if (request->proxy_reply) return request_process_timer(request);
{
rad_assert(request->parent == NULL);
+ VERIFY_REQUEST(request);
+
TRACE_STATE_MACHINE;
switch (action) {
#ifdef DEBUG_STATE_MACHINE
int action = FR_ACTION_TIMER;
#endif
+
+ VERIFY_REQUEST(request);
+
TRACE_STATE_MACHINE;
rad_assert(request->parent != NULL);
{
char buffer[128];
+ VERIFY_REQUEST(request);
+
TRACE_STATE_MACHINE;
switch (action) {
STATE_MACHINE_DECL(coa_running)
{
+ VERIFY_REQUEST(request);
+
TRACE_STATE_MACHINE;
switch (action) {
***********************************************************************/
static void event_socket_handler(UNUSED fr_event_list_t *xel, UNUSED int fd, void *ctx)
{
- rad_listen_t *listener = ctx;
+ rad_listen_t *listener = talloc_get_type_abort(ctx, rad_listen_t);
rad_assert(xel == el);
static void event_poll_detail(void *ctx)
{
int delay;
- rad_listen_t *this = ctx;
+ rad_listen_t *this = talloc_get_type_abort(ctx, rad_listen_t);
struct timeval when, now;
listen_detail_t *detail = this->data;
#ifdef WITH_TCP
static void listener_free_cb(void *ctx)
{
- rad_listen_t *this = ctx;
+ rad_listen_t *this = talloc_get_type_abort(ctx, rad_listen_t);
char buffer[1024];
if (this->count > 0) {
if (just_started) {
DEBUG("Listening on %s", buffer);
+
+#ifdef WITH_PROXY
+ } else if (this->type == RAD_LISTEN_PROXY) {
+ home_server_t *home;
+
+ home = sock->home;
+ if (!home || !home->limit.max_connections) {
+ INFO(" ... adding new socket %s", buffer);
+ } else {
+ INFO(" ... adding new socket %s (%u of %u)", buffer,
+ home->limit.num_connections, home->limit.max_connections);
+ }
+
+#endif
} else {
INFO(" ... adding new socket %s", buffer);
}
#endif
#ifdef WITH_TCP
- INFO(" ... shutting down socket %s", buffer);
-
#ifdef WITH_PROXY
/*
* The socket is dead. Force all proxied packets
* list of outgoing sockets.
*/
if (this->type == RAD_LISTEN_PROXY) {
+ home_server_t *home;
+
+ home = sock->home;
+ if (!home || !home->limit.max_connections) {
+ INFO(" ... shutting down socket %s", buffer);
+ } else {
+ INFO(" ... shutting down socket %s (%u of %u)", buffer,
+ home->limit.num_connections, home->limit.max_connections);
+ }
+
PTHREAD_MUTEX_LOCK(&proxy_mutex);
fr_packet_list_walk(proxy_list, this, eol_proxy_listener);
} else
#endif
{
+ INFO(" ... shutting down socket %s", buffer);
+
/*
* EOL all requests using this socket.
*/
{
REQUEST *request = fr_packet2myptr(REQUEST, proxy, data);
+ VERIFY_REQUEST(request);
+
request->master_state = REQUEST_STOP_PROCESSING;
#ifdef HAVE_PTHREAD_H
{
REQUEST *request = fr_packet2myptr(REQUEST, packet, data);
+ VERIFY_REQUEST(request);
+
request->master_state = REQUEST_STOP_PROCESSING;
/*