static int proxy_fds[32];
static rad_listen_t *proxy_listeners[32];
+static void request_post_handler(REQUEST *request);
+static void wait_a_bit(void *ctx);
static void NEVER_RETURNS _rad_panic(const char *file, unsigned int line,
const char *msg)
remove_from_request_hash(request);
- if (request->proxy &&
- request->in_proxy_hash) {
+ if (request->proxy && request->in_proxy_hash) {
wait_for_proxy_id_to_expire(request);
return;
}
}
}
+
+static void post_proxy_fail(REQUEST *request)
+{
+ DICT_VALUE *dval = NULL;
+
+ if (request->packet->code == PW_AUTHENTICATION_REQUEST) {
+ dval = dict_valbyname(PW_POST_PROXY_TYPE, "Failed-Authentication");
+
+ } else if (request->packet->code == PW_ACCOUNTING_REQUEST) {
+ dval = dict_valbyname(PW_POST_PROXY_TYPE, "Failed-Accounting");
+
+ } else {
+ return;
+ }
+
+ if (!dval) dval = dict_valbyname(PW_POST_PROXY_TYPE, "Failed");
+
+ if (!dval) return;
+
+ /*
+ * Run it, and ignore the return code.
+ *
+ * FIXME: This may do a fair amount of work... we should
+ * really be pushing this onto the queue of things for
+ * the child threads to do, which would help speed up the
+ * server core.
+ */
+ module_post_proxy(dval->value, request);
+}
+
+
+static void post_proxy_fail_handler(REQUEST *request)
+{
+ /*
+ * FIXME: Insert the request into the HEAD of the queue for child
+ * threads, and then set child state to QUEUED
+ */
+ {
+ request->child_state = REQUEST_RUNNING;
+ post_proxy_fail(request);
+
+ rad_assert(request->proxy != NULL);
+ request_post_handler(request);
+ }
+
+ /*
+ * Wait for the child to be done.
+ *
+ * FIXME: Reset the default timeouts?
+ */
+ wait_a_bit(request);
+}
+
+
/* maybe check this against wait_for_proxy_id_to_expire? */
static void no_response_to_proxied_request(void *ctx)
{
buffer, sizeof(buffer)),
request->proxy->dst_port);
- /*
- * FIXME: Run packets through post-proxy-type "Fail"
- */
- if ((request->proxy->code == PW_ACCOUNTING_REQUEST) ||
- (request->proxy->code == PW_STATUS_SERVER)) {
- remove_from_request_hash(request);
- wait_for_proxy_id_to_expire(request);
-
- } else {
- request->reply->code = PW_AUTHENTICATION_REJECT;
+ check_for_zombie_home_server(request);
- request->listener->send(request->listener, request);
+ home = request->home_server;
- request->child_state = REQUEST_CLEANUP_DELAY;
- request->when.tv_sec += mainconfig.cleanup_delay;
-
- /* cleanup_delay calls wait_for_proxy_id_to_expire */
+ post_proxy_fail_handler(request);
- INSERT_EVENT(cleanup_delay, request);
- }
-
- home = request->home_server;
+ /*
+ * Don't touch request due to race conditions
+ */
if (home->state == HOME_STATE_IS_DEAD) {
- /* FIXME: assert that some event is set for the home server */
+ rad_assert(home->ev != NULL); /* or it will never wake up */
return;
}
*/
if (home->state == HOME_STATE_ALIVE) {
DEBUG2("WARNING: Home server %s port %d may be dead.",
- inet_ntop(request->proxy->dst_ipaddr.af,
- &request->proxy->dst_ipaddr.ipaddr,
+ inet_ntop(home->ipaddr.af, &home->ipaddr.ipaddr,
buffer, sizeof(buffer)),
- request->proxy->dst_port);
+ home->port);
home->state = HOME_STATE_ZOMBIE;
home->zombie_period_start = now;
home->zombie_period_start.tv_sec -= home->response_window;
return;
}
-
- check_for_zombie_home_server(request);
}
char buffer[128];
realmpair = pairfind(request->config_items, PW_PROXY_TO_REALM);
- if (!realmpair ||
- (realmpair->length == 0)) {
+ if (!realmpair || (realmpair->length == 0)) {
return 0;
}
realm = realm_find(realmname);
if (!realm) {
- DEBUG2("ERROR: Cannot proxy to unknown realm %s",
- realmname);
- reject_request:
- /*
- * Failed proxying means silently discard
- * accounting responses.
- */
- if (request->packet->code == PW_ACCOUNTING_REQUEST) {
- request->child_state = REQUEST_DONE;
- return 1;
- }
-
- rad_assert(request->packet->code == PW_AUTHENTICATION_REQUEST);
-
- request->reply->code = PW_AUTHENTICATION_REJECT;
-
+ DEBUG2("ERROR: Cannot proxy to unknown realm %s", realmname);
return 0;
}
home = home_server_ldb(realmname, pool, request);
if (!home) {
- /*
- * FIXME: Run the request through Post-Proxy-Type = Fail
- */
DEBUG2("ERROR: Failed to find live home server for realm %s",
realmname);
- goto reject_request;
+ return -1;
}
request->home_pool = pool;
case RLM_MODULE_FAIL:
case RLM_MODULE_INVALID:
case RLM_MODULE_NOTFOUND:
- case RLM_MODULE_REJECT:
case RLM_MODULE_USERLOCK:
default:
/* FIXME: debug print failed stuff */
- goto reject_request;
+ return -1;
+ case RLM_MODULE_REJECT:
case RLM_MODULE_HANDLED:
return 0;
* If it's a fake request, don't send the proxy
* packet. The outer tunnel session will take
* care of doing that.
- *
- * FIXME: Update the home_server to be NULL?
*/
if (request->packet->dst_port == 0) {
+ request->home_server = NULL;
return 1;
}
if (!insert_into_proxy_hash(request)) {
DEBUG("ERROR: Failed to proxy request %d", request->number);
- goto reject_request;
+ return -1;
}
request->proxy_listener->encode(request->proxy_listener, request);
}
if (mainconfig.proxy_requests &&
- (request->packet->code != PW_STATUS_SERVER) &&
- (request->reply->code == 0) &&
!request->proxy &&
- successfully_proxied_request(request)) {
- return;
+ (request->reply->code == 0) &&
+ (request->packet->code != PW_STATUS_SERVER)) {
+ int rcode = successfully_proxied_request(request);
+
+ if (rcode == 1) return;
+
+ /*
+ * Failed proxying it (dead home servers, etc.)
+ * Run it through Post-Proxy-Type = Fail, and
+ * respond to the request.
+ */
+ if (rcode < 0) post_proxy_fail(request);
+
+ /*
+ * Else we weren't supposed to proxy it.
+ */
}
/*
DEBUG2("Failed to find live home server for request %d", request->number);
no_home_servers:
/*
- * FIXME: Run the request through
- * Post-Proxy-Type = Fail
- *
* Do post-request processing,
* and any insertion of necessary
* events.
*/
- request->child_state = REQUEST_RUNNING;
- request_post_handler(request);
- wait_a_bit(request);
+ post_proxy_fail_handler(request);
return;
}