};
#ifdef DEBUG_STATE_MACHINE
-#define TRACE_STATE_MACHINE if (debug_flag) printf("(%u) ********\tSTATE %s action %s live M-%s C-%s\t********\n", request->number, __FUNCTION__, action_codes[action], master_state_names[request->master_state], child_state_names[request->child_state])
+#define TRACE_STATE_MACHINE if (debug_flag) do { struct timeval debug_tv; \
+ gettimeofday(&debug_tv, NULL);\
+ debug_tv.tv_sec -= fr_start_time;\
+ printf("(%u) %d.%06d ********\tSTATE %s action %s live M-%s C-%s\t********\n",\
+ request->number, (int) debug_tv.tv_sec, (int) debug_tv.tv_usec, __FUNCTION__, action_codes[action], master_state_names[request->master_state], child_state_names[request->child_state]); } while (0)
static char const *master_state_names[REQUEST_MASTER_NUM_STATES] = {
"?",
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)
+{
+ 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;
+ }
+ }
+
+ rad_assert(request->home_server != NULL);
+ return &request->home_server->response_window;
+}
+
+/*
+ * Determine initial request processing delay.
+ */
+static int request_init_delay(REQUEST *request)
+{
+ 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;
+ half_response_window.tv_usec =
+ ((request->client->response_window.tv_sec & 1) * USEC +
+ request->client->response_window.tv_usec) >> 1;
+ if (timercmp(&half_response_window, &request->root->init_delay, <))
+ return (int)half_response_window.tv_sec * USEC +
+ (int)half_response_window.tv_usec;
+ }
+
+ return (int)request->root->init_delay.tv_sec * USEC +
+ (int)request->root->init_delay.tv_usec;
+}
+
/*
* Callback for ALL timer events related to the request.
*/
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
when.tv_sec += request->home_server->coa_mrd;
} else
#endif
- timeradd(&when, &request->home_server->response_window, &when);
+ timeradd(&when, request_response_window(request), &when);
/*
* We haven't received all responses, AND there's still
if (request->ev) fr_event_delete(el, &request->ev);
- request_free(&request);
+ talloc_free(request);
}
{
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;
switch (request->child_state) {
case REQUEST_QUEUED:
case REQUEST_RUNNING:
-#ifdef WITH_PROXY
- case REQUEST_PROXIED:
-#endif
when = request->packet->timestamp;
when.tv_sec += request->root->max_request_time;
#endif
request->master_state = REQUEST_STOP_PROCESSING;
}
+ goto delay; /* sleep some more */
#ifdef WITH_PROXY
- /*
- * We should wait for the proxy reply.
- */
- if (request->child_state == REQUEST_PROXIED) {
- rad_assert(request->proxy != NULL);
+ case REQUEST_PROXIED:
+ when = request->packet->timestamp;
+ when.tv_sec += request->root->max_request_time;
+
+ if (timercmp(&now, &when, >=)) {
+ RWDEBUG("No response to proxied request in 'max_request_time'. Stopping it.");
+ request->master_state = REQUEST_STOP_PROCESSING;
+ request_done(request, FR_ACTION_DONE);
+ break;
+ }
+ rad_assert(request->proxy != NULL);
#ifdef WITH_COA
- /*
- * Ugh.
- */
- if (request->packet->code != request->proxy->code) {
- if (request->proxy_reply) {
- request->process = coa_running;
- } else {
- request->process = coa_wait_for_reply;
- }
- goto delay;
- }
-#endif
+ /*
+ * Ugh.
+ */
+ if (request->packet->code != request->proxy->code) {
if (request->proxy_reply) {
- request->process = proxy_running;
+ request->process = coa_running;
} else {
- request->process = proxy_wait_for_reply;
+ request->process = coa_wait_for_reply;
}
- }
+ } else
#endif
+ if (request->proxy_reply) {
+ request->process = proxy_running;
+ } else {
+ request->process = proxy_wait_for_reply;
+ }
+
+ when = request->proxy->timestamp;
+ tv_add(&when, request->delay);
+
+ if (timercmp(&now, &when, >=)) {
+ request->process(request, FR_ACTION_TIMER);
+ return;
+ }
+
/*
- * If the request has been told to die, we wait.
- * Otherwise, we wait for the child thread to
- * finish it's work.
+ * Leave the initial delay alone.
*/
- goto delay;
+ STATE_MACHINE_TIMER(FR_ACTION_TIMER);
+ return;
+#endif /* WITH_PROXY */
case REQUEST_RESPONSE_DELAY:
rad_assert(request->response_delay > 0);
int action = FR_ACTION_TIMER;
#endif
+ VERIFY_REQUEST(request);
+
TRACE_STATE_MACHINE;
/*
/*
* (re) set the initial delay.
*/
- request->delay = USEC / 3;
+ request->delay = request_init_delay(request);
+ if (request->delay > USEC) request->delay = USEC;
gettimeofday(&when, NULL);
tv_add(&when, request->delay);
request->delay += request->delay >> 1;
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 */
/*
* Catch Auth-Type := Reject BEFORE proxying the packet.
*/
- else if (request->packet->code == PW_CODE_AUTHENTICATION_REQUEST) {
+ else if (request->packet->code == PW_CODE_ACCESS_REQUEST) {
if (request->reply->code == 0) {
vp = pairfind(request->config_items, PW_AUTH_TYPE, 0, TAG_ANY);
- if (!vp || (vp->vp_integer != PW_CODE_AUTHENTICATION_REJECT)) {
+ if (!vp || (vp->vp_integer != PW_CODE_ACCESS_REJECT)) {
RDEBUG2("There was no response configured: "
"rejecting request");
}
- request->reply->code = PW_CODE_AUTHENTICATION_REJECT;
+ request->reply->code = PW_CODE_ACCESS_REJECT;
}
}
if (vp) pairadd(&request->reply->vps, vp);
switch (request->reply->code) {
- case PW_CODE_AUTHENTICATION_ACK:
+ case PW_CODE_ACCESS_ACCEPT:
rad_postauth(request);
break;
case PW_CODE_ACCESS_CHALLENGE:
* We do this separately so ACK and challenge can change the code
* to reject if a module returns reject.
*/
- if (request->reply->code == PW_CODE_AUTHENTICATION_REJECT) {
+ if (request->reply->code == PW_CODE_ACCESS_REJECT) {
pairdelete(&request->config_items, PW_POST_AUTH_TYPE, 0, TAG_ANY);
vp = pairmake_config("Post-Auth-Type", "Reject", T_OP_SET);
if (vp) rad_postauth(request);
/*
* See if we need to delay an Access-Reject packet.
*/
- if ((request->reply->code == PW_CODE_AUTHENTICATION_REJECT) &&
+ if ((request->reply->code == PW_CODE_ACCESS_REJECT) &&
(request->root->reject_delay > 0)) {
request->response_delay = request->root->reject_delay;
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.
*/
#ifdef WITH_STATS
switch (packet->code) {
- case PW_CODE_AUTHENTICATION_REQUEST:
+ case PW_CODE_ACCESS_REQUEST:
FR_STATS_INC(auth, total_dup_requests);
break;
} else {
RDEBUG("Not sending reply");
}
- request_free(&request);
+ talloc_free(request);
return 1;
}
* 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");
- request_free(&request);
+ talloc_free(request);
return NULL;
}
#ifdef WITH_STATS
request->listener->stats.last_packet = request->packet->timestamp.tv_sec;
- if (packet->code == PW_CODE_AUTHENTICATION_REQUEST) {
+ if (packet->code == PW_CODE_ACCESS_REQUEST) {
request->client->auth.last_packet = request->packet->timestamp.tv_sec;
radius_auth_stats.last_packet = request->packet->timestamp.tv_sec;
#ifdef WITH_ACCOUNTING
*/
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);
for (tries = 0; tries < 2; tries++) {
rad_listen_t *this;
+ listen_socket_t *sock;
RDEBUG3("proxy: Trying to allocate ID (%d/2)", tries);
rcode = fr_packet_list_id_alloc(proxy_list,
request->proxy->src_port = 0; /* Use any new socket */
proxy_listener = this;
+ sock = this->data;
+ if (!fr_packet_list_socket_add(proxy_list, this->fd,
+ sock->proto,
+ &sock->other_ipaddr, sock->other_port,
+ this)) {
+
+#ifdef HAVE_PTHREAD_H
+ proxy_no_new_sockets = true;
+#endif
+ PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
+
+ /*
+ * This is bad. However, the
+ * packet list now supports 256
+ * open sockets, which should
+ * minimize this problem.
+ */
+ ERROR("Failed adding proxy socket: %s",
+ fr_strerror());
+ goto fail;
+ }
+
/*
* Add it to the event loop. Ensure that we have
* only one mutex locked at a time.
int post_proxy_type = 0;
VALUE_PAIR *vp;
+ VERIFY_REQUEST(request);
+
/*
* There may be a proxy reply, but it may be too late.
*/
* post-proxy-type Reject
*/
if (!vp && reply &&
- reply->code == PW_CODE_AUTHENTICATION_REJECT) {
+ reply->code == PW_CODE_ACCESS_REJECT) {
DICT_VALUE *dval;
dval = dict_valbyname(PW_POST_PROXY_TYPE, 0, "Reject");
}
if (reply) {
+ VERIFY_PACKET(reply);
/*
* Decode the packet.
*/
* running Post-Proxy-Type = Fail.
*/
if (reply) {
- request->reply->vps = paircopy(request->reply, reply->vps);
+ pairadd(&request->reply->vps, paircopy(request->reply, reply->vps));
/*
* Delete the Proxy-State Attributes from
struct timeval now;
char buffer[128];
+ VERIFY_PACKET(packet);
+
PTHREAD_MUTEX_LOCK(&proxy_mutex);
proxy_p = fr_packet_list_find_byreply(proxy_list, packet);
*/
if (request->home_server->state == HOME_STATE_UNKNOWN) {
request->home_server->state = HOME_STATE_ALIVE;
+ request->home_server->response_timeouts = 0;
}
#ifdef WITH_STATS
request->home_server->stats.last_packet = packet->timestamp.tv_sec;
request->proxy_listener->stats.last_packet = packet->timestamp.tv_sec;
- if (request->proxy->code == PW_CODE_AUTHENTICATION_REQUEST) {
+ if (request->proxy->code == PW_CODE_ACCESS_REQUEST) {
proxy_auth_stats.last_packet = packet->timestamp.tv_sec;
#ifdef WITH_ACCOUNTING
} else if (request->proxy->code == PW_CODE_ACCOUNTING_REQUEST) {
DICT_VALUE const *dval = NULL;
VALUE_PAIR *vp;
- if (request->proxy->code == PW_CODE_AUTHENTICATION_REQUEST) {
+ 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;
/*
* Figure out which pool to use.
*/
- if (request->packet->code == PW_CODE_AUTHENTICATION_REQUEST) {
+ if (request->packet->code == PW_CODE_ACCESS_REQUEST) {
pool = realm->auth_pool;
#ifdef WITH_ACCOUNTING
if (!vp) return 0;
switch (request->packet->code) {
- case PW_CODE_AUTHENTICATION_REQUEST:
+ case PW_CODE_ACCESS_REQUEST:
pool_type = HOME_TYPE_AUTH;
break;
* since we can't use the request authenticator
* anymore - we changed it.
*/
- if ((request->packet->code == PW_CODE_AUTHENTICATION_REQUEST) &&
+ if ((request->packet->code == PW_CODE_ACCESS_REQUEST) &&
pairfind(request->proxy->vps, PW_CHAP_PASSWORD, 0, TAG_ANY) &&
pairfind(request->proxy->vps, PW_CHAP_CHALLENGE, 0, TAG_ANY) == NULL) {
vp = radius_paircreate(request->proxy, &request->proxy->vps, PW_CHAP_CHALLENGE, 0);
{
char buffer[128];
+ VERIFY_REQUEST(request);
+
rad_assert(request->parent == NULL);
rad_assert(request->home_server != NULL);
request->proxy_reply = talloc_steal(request, fake->reply);
fake->reply = NULL;
- request_free(&fake);
+ talloc_free(fake);
/*
* Just do the work here, rather than trying to
rad_assert(request->proxy->id >= 0);
+ if (debug_flag) {
+ struct timeval *response_window;
+
+ response_window = request_response_window(request);
+
#ifdef WITH_TLS
- if (request->home_server->tls) {
- RDEBUG2("Proxying request to home server %s port %d (TLS)",
- inet_ntop(request->proxy->dst_ipaddr.af,
- &request->proxy->dst_ipaddr.ipaddr,
- buffer, sizeof(buffer)),
- request->proxy->dst_port);
- } else
+ if (request->home_server->tls) {
+ RDEBUG2("Proxying request to home server %s port %d (TLS) timeout %d.%06d",
+ inet_ntop(request->proxy->dst_ipaddr.af,
+ &request->proxy->dst_ipaddr.ipaddr,
+ buffer, sizeof(buffer)),
+ request->proxy->dst_port,
+ (int) response_window->tv_sec, (int) response_window->tv_usec);
+ } else
#endif
- RDEBUG2("Proxying request to home server %s port %d",
- inet_ntop(request->proxy->dst_ipaddr.af,
- &request->proxy->dst_ipaddr.ipaddr,
- buffer, sizeof(buffer)),
- request->proxy->dst_port);
+ RDEBUG2("Proxying request to home server %s port %d timeout %d.%06d",
+ inet_ntop(request->proxy->dst_ipaddr.af,
+ &request->proxy->dst_ipaddr.ipaddr,
+ buffer, sizeof(buffer)),
+ request->proxy->dst_port,
+ (int) response_window->tv_sec, (int) response_window->tv_usec);
- DEBUG_PACKET(request, request->proxy, 1);
+ DEBUG_PACKET(request, request->proxy, 1);
+ }
gettimeofday(&request->proxy_retransmit, NULL);
if (!retransmit) {
{
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;
* pings.
*/
home->state = HOME_STATE_ALIVE;
+ home->response_timeouts = 0;
exec_trigger(request, home->cs, "home_server.alive", false);
home->currently_outstanding = 0;
home->num_sent_pings = 0;
*/
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) {
"Message-Authenticator", "0x00", T_OP_SET);
} else if (home->type == HOME_TYPE_AUTH) {
- request->proxy->code = PW_CODE_AUTHENTICATION_REQUEST;
+ request->proxy->code = PW_CODE_ACCESS_REQUEST;
pairmake(request->proxy, &request->proxy->vps,
"User-Name", home->ping_user_name, T_OP_SET);
rad_assert(!request->in_request_hash);
rad_assert(!request->in_proxy_hash);
rad_assert(request->ev == NULL);
- request_free(&request);
+ talloc_free(request);
return;
}
exec_trigger(&my_request, home->cs, trigger, false);
}
-static void mark_home_server_zombie(home_server_t *home, struct timeval *now)
+static void mark_home_server_zombie(home_server_t *home, struct timeval *now, struct timeval *response_window)
{
time_t start;
char buffer[128];
PROXY( "Marking home server %s port %d as zombie (it has not responded in %d.%06d seconds).",
inet_ntop(home->ipaddr.af, &home->ipaddr.ipaddr,
buffer, sizeof(buffer)),
- home->port, (int) home->response_window.tv_sec, (int) home->response_window.tv_usec);
+ home->port, (int) response_window->tv_sec, (int) response_window->tv_usec);
ping_home_server(home);
}
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
#endif
home->state = HOME_STATE_ALIVE;
+ home->response_timeouts = 0;
home_trigger(home, "home_server.alive");
home->currently_outstanding = 0;
gettimeofday(&home->revive_time, NULL);
STATE_MACHINE_DECL(proxy_wait_for_reply)
{
struct timeval now, when;
+ struct timeval *response_window = NULL;
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);
break;
case FR_ACTION_TIMER:
+ response_window = request_response_window(request);
+
#ifdef WITH_TCP
if (!request->proxy_listener ||
(request->proxy_listener->status != RAD_LISTEN_STATUS_KNOWN)) {
* responding to other (better looking) packets.
*/
when = request->proxy->timestamp;
- timeradd(&when, &home->response_window, &when);
+ timeradd(&when, response_window, &when);
/*
* Not at the response window. Set the timer for
* that.
*/
if (timercmp(&when, &now, >)) {
+ struct timeval diff;
+ timersub(&when, &now, &diff);
+
RDEBUG("Expecting proxy response no later than %d.%06d seconds from now",
- (int) home->response_window.tv_sec, (int) home->response_window.tv_usec);
+ (int) diff.tv_sec, (int) diff.tv_usec);
STATE_MACHINE_TIMER(FR_ACTION_TIMER);
return;
}
&& (home->proto != IPPROTO_TCP)
#endif
) {
- mark_home_server_zombie(home, &now);
+ home->response_timeouts++;
+ if (home->response_timeouts >= home->max_response_timeouts)
+ mark_home_server_zombie(home, &now, response_window);
}
FR_STATS_TYPE_INC(home->stats.total_timeouts);
* may have failed over to another home server.
* But that one may be dead, too.
*/
- RERROR("Failing request - proxy ID %u, due to lack of any response from home server %s port %d",
- request->proxy->id,
+ RERROR("Failing proxied request, due to lack of any response from home server %s port %d",
inet_ntop(request->proxy->dst_ipaddr.af,
&request->proxy->dst_ipaddr.ipaddr,
buffer, sizeof(buffer)),
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);
if (vp) {
if (vp->vp_integer == 0) {
fail:
- request_free(&request->coa);
+ TALLOC_FREE(request->coa);
return;
}
}
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) {
* added to the packet list.
*/
case RAD_LISTEN_PROXY:
- PTHREAD_MUTEX_LOCK(&proxy_mutex);
- if (!fr_packet_list_socket_add(proxy_list, this->fd,
- sock->proto,
- &sock->other_ipaddr, sock->other_port,
- this)) {
-
-#ifdef HAVE_PTHREAD_H
- proxy_no_new_sockets = true;
-#endif
- PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
-
- /*
- * This is bad. However, the
- * packet list now supports 256
- * open sockets, which should
- * minimize this problem.
- */
- ERROR("Failed adding proxy socket: %s",
- fr_strerror());
- return 0;
- }
- PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
-
#ifdef WITH_TCP
/*
* Add timers to outgoing child sockets, if necessary.
time(&fr_start_time);
- /*
- * radius_event_init() must be called first
- */
- rad_assert(el);
- if (fr_start_time == (time_t)-1) return 0;
+ if (!check_config) {
+ /*
+ * radius_event_init() must be called first
+ */
+ rad_assert(el);
- pl = fr_packet_list_create(0);
- if (!pl) return 0; /* leak el */
+ pl = fr_packet_list_create(0);
+ if (!pl) return 0; /* leak el */
+ }
request_num_counter = 0;
fr_exit(1);
}
#endif
+
+ /*
+ * The "init_delay" is set to "response_window".
+ * Reset it to half of "response_window" in order
+ * to give the event loop enough time to service
+ * the event before hitting "response_window".
+ */
+ main_config.init_delay.tv_usec += (main_config.init_delay.tv_sec & 0x01) * USEC;
+ main_config.init_delay.tv_usec >>= 1;
+ main_config.init_delay.tv_sec >>= 1;
+
}
#endif
{
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;
/*
}
#endif
- request_free(&request);
+ talloc_free(request);
/*
* Delete it from the list, and continue;