move assertion to top of function. Found by PVS-Studio
[freeradius.git] / src / main / process.c
index 3d20e38..7b4196c 100644 (file)
@@ -285,6 +285,12 @@ static bool we_are_master(void)
 #  define ASSERT_MASTER
 #endif
 
+/*
+ *     Make state transitions simpler.
+ */
+#define FINAL_STATE(_x) NO_CHILD_THREAD; request->component = "<" #_x ">"; request->module = ""; request->child_state = _x
+
+
 static int event_new_fd(rad_listen_t *this);
 
 /*
@@ -344,7 +350,7 @@ void radius_update_listener(rad_listen_t *this)
 static int request_num_counter = 1;
 #ifdef WITH_PROXY
 static int request_will_proxy(REQUEST *request) CC_HINT(nonnull);
-static int request_proxy(REQUEST *request, int retransmit) CC_HINT(nonnull);
+static int request_proxy(REQUEST *request) CC_HINT(nonnull);
 STATE_MACHINE_DECL(request_ping) CC_HINT(nonnull);
 
 STATE_MACHINE_DECL(request_response_delay) CC_HINT(nonnull);
@@ -409,6 +415,14 @@ static void debug_packet(REQUEST *request, RADIUS_PACKET *packet, bool received)
        if (!packet) return;
        if (!RDEBUG_ENABLED) return;
 
+#ifdef WITH_DETAIL
+       /*
+        *      Don't print IP addresses for detail files.
+        */
+       if (request->listener &&
+           (request->listener->type == RAD_LISTEN_DETAIL)) return;
+
+#endif
        /*
         *      Client-specific debugging re-prints the input
         *      packet into the client log.
@@ -471,6 +485,8 @@ static struct timeval *request_response_window(REQUEST *request)
 {
        VERIFY_REQUEST(request);
 
+       rad_assert(request->home_server != NULL);
+
        if (request->client) {
                /*
                 *      The client hasn't set the response window.  Return
@@ -486,7 +502,6 @@ static struct timeval *request_response_window(REQUEST *request)
                }
        }
 
-       rad_assert(request->home_server != NULL);
        return &request->home_server->response_window;
 }
 
@@ -613,9 +628,7 @@ static void request_done(REQUEST *request, int action)
         *      and wait for the master thread timer to clean us up.
         */
        if (!we_are_master()) {
-               NO_CHILD_THREAD;
-               request->module = "<REQUEST_DONE>";
-               request->child_state = REQUEST_DONE;
+               FINAL_STATE(REQUEST_DONE);
                return;
        }
 #endif
@@ -852,9 +865,7 @@ static void request_cleanup_delay_init(REQUEST *request)
                request->process = request_cleanup_delay;
 
                if (!we_are_master()) {
-                       NO_CHILD_THREAD;
-                       request->module = "<REQUEST_CLEANUP_DELAY>";
-                       request->child_state = REQUEST_CLEANUP_DELAY;
+                       FINAL_STATE(REQUEST_CLEANUP_DELAY);
                        return;
                }
 
@@ -1110,7 +1121,7 @@ static void request_cleanup_delay(REQUEST *request, int action)
                        return;
                } /* else it's time to clean up */
 
-               request_done(request, REQUEST_DONE);
+               request_done(request, FR_ACTION_DONE);
                break;
 
        default:
@@ -1152,7 +1163,7 @@ static void request_response_delay(REQUEST *request, int action)
 
        switch (action) {
        case FR_ACTION_DUP:
-               ERROR("(%u) Discarding duplicate request from "
+               RDEBUG("(%u) Discarding duplicate request from "
                      "client %s port %d - ID: %u due to delayed response",
                      request->number, request->client->shortname,
                      request->packet->src_port,request->packet->id);
@@ -1343,9 +1354,7 @@ static void request_finish(REQUEST *request, int action)
         */
        if (request->packet->dst_port == 0) {
                RDEBUG("Finished internally proxied request.");
-               NO_CHILD_THREAD;
-               request->module = "<REQUEST_DONE>";
-               request->child_state = REQUEST_DONE;
+               FINAL_STATE(REQUEST_DONE);
                return;
        }
 
@@ -1464,9 +1473,6 @@ static void request_finish(REQUEST *request, int action)
 
        done:
                RDEBUG2("Finished request");
-               request->component = "<core>";
-               request->module = "<done>";
-
                request_cleanup_delay_init(request);
 
        } else {
@@ -1478,12 +1484,9 @@ static void request_finish(REQUEST *request, int action)
                RDEBUG2("Delaying response for %d.%06d seconds",
                        (int) request->response_delay.tv_sec, (int) request->response_delay.tv_usec);
                request->listener->encode(request->listener, request);
-               request->component = "<core>";
-               request->module = "<delay>";
                request->process = request_response_delay;
-               NO_CHILD_THREAD;
-               request->module = "<REQUEST_RESPONSE_DELAY>";
-               request->child_state = REQUEST_RESPONSE_DELAY;
+
+               FINAL_STATE(REQUEST_RESPONSE_DELAY);
        }
 }
 
@@ -1525,10 +1528,7 @@ static void request_running(REQUEST *request, int action)
                                               child_state_names[request->child_state],
                                               child_state_names[REQUEST_DONE]);
 #endif
-
-                       NO_CHILD_THREAD;
-                       request->module = "<REQUEST_DONE>";
-                       request->child_state = REQUEST_DONE;
+                       FINAL_STATE(REQUEST_DONE);
                        break;
                }
 
@@ -1550,7 +1550,7 @@ static void request_running(REQUEST *request, int action)
                         *      up the post proxy fail
                         *      handler.
                         */
-                       if (request_proxy(request, 0) < 0) goto req_finished;
+                       if (request_proxy(request) < 0) goto req_finished;
                } else
 #endif
                {
@@ -1592,14 +1592,15 @@ int request_receive(TALLOC_CTX *ctx, rad_listen_t *listener, RADIUS_PACKET *pack
 #ifdef WITH_ACCOUNTING
        if (listener->type != RAD_LISTEN_DETAIL)
 #endif
+
+#ifdef WITH_TCP
        {
                sock = listener->data;
                sock->last_packet = now.tv_sec;
 
-#ifdef WITH_TCP
                packet->proto = sock->proto;
-#endif
        }
+#endif
 
        /*
         *      Skip everything if required.
@@ -1807,7 +1808,7 @@ static REQUEST *request_setup(TALLOC_CTX *ctx, rad_listen_t *listener, RADIUS_PA
                ERROR("No memory");
                return NULL;
        }
-       request->reply = rad_alloc(request, false);
+       request->reply = rad_alloc_reply(request, packet);
        if (!request->reply) {
                ERROR("No memory");
                talloc_free(request);
@@ -2015,26 +2016,6 @@ static void tcp_socket_timer(void *ctx)
 
 #ifdef WITH_PROXY
 /*
- *     Add +/- 2s of jitter, as suggested in RFC 3539
- *     and in RFC 5080.
- */
-static void add_jitter(struct timeval *when)
-{
-       uint32_t jitter;
-
-       when->tv_sec -= 2;
-
-       jitter = fr_rand();
-       jitter ^= (jitter >> 10);
-       jitter &= ((1 << 22) - 1); /* 22 bits of 1 */
-
-       /*
-        *      Add in ~ (4 * USEC) of jitter.
-        */
-       tv_add(when, jitter);
-}
-
-/*
  *     Called by socket_del to remove requests with this socket
  */
 static int eol_proxy_listener(void *ctx, void *data)
@@ -2142,8 +2123,9 @@ static void remove_from_proxy_hash_nl(REQUEST *request, bool yank)
        }
 
 #ifdef WITH_TCP
-       rad_assert(request->proxy_listener != NULL);
-       request->proxy_listener->count--;
+       if (request->proxy_listener) {
+               request->proxy_listener->count--;
+       }
 #endif
        request->proxy_listener = NULL;
 
@@ -2404,7 +2386,7 @@ static int process_proxy_reply(REQUEST *request, RADIUS_PACKET *reply)
        }
 
 #ifdef WITH_COA
-       if (request->packet->code == request->proxy->code)
+       if (request->packet->code == request->proxy->code) {
          /*
           *    Don't run the next bit if we originated a CoA
           *    packet, after receiving an Access-Request or
@@ -2412,21 +2394,30 @@ static int process_proxy_reply(REQUEST *request, RADIUS_PACKET *reply)
           */
 #endif
 
-       /*
-        *      There may NOT be a proxy reply, as we may be
-        *      running Post-Proxy-Type = Fail.
-        */
-       if (reply) {
-               fr_pair_add(&request->reply->vps, fr_pair_list_copy(request->reply, reply->vps));
-
                /*
-                *      Delete the Proxy-State Attributes from
-                *      the reply.  These include Proxy-State
-                *      attributes from us and remote server.
+                *      There may NOT be a proxy reply, as we may be
+                *      running Post-Proxy-Type = Fail.
                 */
-               fr_pair_delete_by_num(&request->reply->vps, PW_PROXY_STATE, 0, TAG_ANY);
-       }
+               if (reply) {
+                       fr_pair_add(&request->reply->vps, fr_pair_list_copy(request->reply, reply->vps));
 
+                       /*
+                        *      Delete the Proxy-State Attributes from
+                        *      the reply.  These include Proxy-State
+                        *      attributes from us and remote server.
+                        */
+                       fr_pair_delete_by_num(&request->reply->vps, PW_PROXY_STATE, 0, TAG_ANY);
+
+               } else {
+                       vp = fr_pair_find_by_num(request->config, PW_RESPONSE_PACKET_TYPE, 0, TAG_ANY);
+                       if (vp && (vp->vp_integer != 256)) {
+                               request->proxy_reply = rad_alloc_reply(request, request->proxy);
+                               request->proxy_reply->code = vp->vp_integer;
+                       }
+               }
+#ifdef WITH_COA
+       }
+#endif
        switch (rcode) {
        default:  /* Don't do anything */
                break;
@@ -2486,7 +2477,6 @@ int request_proxy_reply(RADIUS_PACKET *packet)
        }
 
        request = fr_packet2myptr(REQUEST, proxy, proxy_p);
-       request->num_proxied_responses++; /* needs to be protected by lock */
 
        PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
 
@@ -2521,12 +2511,16 @@ int request_proxy_reply(RADIUS_PACKET *packet)
         *      Status-Server packets don't count as real packets.
         */
        if (request->proxy->code != PW_CODE_STATUS_SERVER) {
+#ifdef WITH_TCP
                listen_socket_t *sock = request->proxy_listener->data;
 
-               request->home_server->last_packet_recv = now.tv_sec;
                sock->last_packet = now.tv_sec;
+#endif
+               request->home_server->last_packet_recv = now.tv_sec;
        }
 
+       request->num_proxied_responses++;
+
        /*
         *      If we have previously seen a reply, ignore the
         *      duplicate.
@@ -2577,6 +2571,8 @@ int request_proxy_reply(RADIUS_PACKET *packet)
 
 #ifdef WITH_ACCOUNTING
        case PW_CODE_ACCOUNTING_REQUEST:
+               proxy_acct_stats.last_packet = packet->timestamp.tv_sec;
+
                request->proxy_listener->stats.total_responses++;
                proxy_acct_stats.last_packet = packet->timestamp.tv_sec;
                break;
@@ -3071,6 +3067,14 @@ do_home:
 
                request->server = old_server;
        } else {
+               char buffer[128];
+
+               RDEBUG2("Starting proxy 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);
+
                rcode = process_pre_proxy(pre_proxy_type, request);
        }
 
@@ -3158,7 +3162,7 @@ static int proxy_to_virtual_server(REQUEST *request)
 }
 
 
-static int request_proxy(REQUEST *request, int retransmit)
+static int request_proxy(REQUEST *request)
 {
        char buffer[128];
 
@@ -3224,11 +3228,8 @@ static int request_proxy(REQUEST *request, int retransmit)
 
        }
 
-       gettimeofday(&request->proxy_retransmit, NULL);
-       if (!retransmit) {
-               request->proxy->timestamp = request->proxy_retransmit;
-       }
-       request->home_server->last_packet_sent = request->proxy_retransmit.tv_sec;
+       gettimeofday(&request->proxy->timestamp, NULL);
+       request->home_server->last_packet_sent = request->proxy->timestamp.tv_sec;
 
        /*
         *      Encode the packet before we do anything else.
@@ -3246,7 +3247,8 @@ static int request_proxy(REQUEST *request, int retransmit)
         */
        request->process = proxy_wait_for_reply;
        request->child_state = REQUEST_PROXIED;
-       request->module = "<REQUEST_PROXIED>";
+       request->component = "<REQUEST_PROXIED>";
+       request->module = "";
        NO_CHILD_THREAD;
 
        /*
@@ -3294,7 +3296,8 @@ static int request_proxy_anew(REQUEST *request)
 
 #ifdef WITH_ACCOUNTING
        /*
-        *      Update the Acct-Delay-Time attribute.
+        *      Update the Acct-Delay-Time attribute, since the LAST
+        *      time we tried to retransmit this packet.
         */
        if (request->packet->code == PW_CODE_ACCOUNTING_REQUEST) {
                VALUE_PAIR *vp;
@@ -3307,7 +3310,7 @@ static int request_proxy_anew(REQUEST *request)
                        struct timeval now;
 
                        gettimeofday(&now, NULL);
-                       vp->vp_integer += now.tv_sec - request->proxy_retransmit.tv_sec;
+                       vp->vp_integer += now.tv_sec - request->proxy->timestamp.tv_sec;
                }
        }
 #endif
@@ -3339,7 +3342,7 @@ static int request_proxy_anew(REQUEST *request)
        request->proxy->data = NULL;
        request->proxy->data_len = 0;
 
-       if (request_proxy(request, 1) != 1) goto post_proxy_fail;
+       if (request_proxy(request) != 1) goto post_proxy_fail;
 
        return 1;
 }
@@ -3367,6 +3370,7 @@ static void request_ping(REQUEST *request, int action)
                                 &request->proxy->dst_ipaddr.ipaddr,
                                 buffer, sizeof(buffer)),
                       request->proxy->dst_port);
+               remove_from_proxy_hash(request);
                break;
 
        case FR_ACTION_PROXY_REPLY:
@@ -3414,12 +3418,33 @@ static void request_ping(REQUEST *request, int action)
        }
 
        rad_assert(!request->in_request_hash);
+       rad_assert(!request->in_proxy_hash);
        rad_assert(request->ev == NULL);
        NO_CHILD_THREAD;
        request_done(request, FR_ACTION_DONE);
 }
 
 /*
+ *     Add +/- 2s of jitter, as suggested in RFC 3539
+ *     and in RFC 5080.
+ */
+static void add_jitter(struct timeval *when)
+{
+       uint32_t jitter;
+
+       when->tv_sec -= 2;
+
+       jitter = fr_rand();
+       jitter ^= (jitter >> 10);
+       jitter &= ((1 << 22) - 1); /* 22 bits of 1 */
+
+       /*
+        *      Add in ~ (4 * USEC) of jitter.
+        */
+       tv_add(when, jitter);
+}
+
+/*
  *     Called from start of zombie period, OR after control socket
  *     marks the home server dead.
  */
@@ -3431,9 +3456,6 @@ static void ping_home_server(void *ctx)
        struct timeval when, now;
 
        if ((home->state == HOME_STATE_ALIVE) ||
-#ifdef WITH_TCP
-           (home->proto == IPPROTO_TCP) ||
-#endif
            (home->ev != NULL)) {
                return;
        }
@@ -3487,7 +3509,8 @@ static void ping_home_server(void *ctx)
                fr_pair_make(request->proxy, &request->proxy->vps,
                         "Message-Authenticator", "0x00", T_OP_SET);
 
-       } else if (home->type == HOME_TYPE_AUTH) {
+       } else if ((home->type == HOME_TYPE_AUTH) ||
+                  (home->type == HOME_TYPE_AUTH_ACCT)) {
                request->proxy->code = PW_CODE_ACCESS_REQUEST;
 
                fr_pair_make(request->proxy, &request->proxy->vps,
@@ -3499,8 +3522,8 @@ static void ping_home_server(void *ctx)
                fr_pair_make(request->proxy, &request->proxy->vps,
                         "Message-Authenticator", "0x00", T_OP_SET);
 
-       } else {
 #ifdef WITH_ACCOUNTING
+       } else if (home->type == HOME_TYPE_ACCT) {
                request->proxy->code = PW_CODE_ACCOUNTING_REQUEST;
 
                fr_pair_make(request->proxy, &request->proxy->vps,
@@ -3512,9 +3535,14 @@ static void ping_home_server(void *ctx)
                vp = fr_pair_make(request->proxy, &request->proxy->vps,
                              "Event-Timestamp", "0", T_OP_SET);
                vp->vp_date = now.tv_sec;
-#else
-               rad_assert("Internal sanity check failed");
 #endif
+
+       } else {
+               /*
+                *      Unkown home server type.
+                */
+               talloc_free(request);
+               return;
        }
 
        vp = fr_pair_make(request->proxy, &request->proxy->vps,
@@ -3611,13 +3639,6 @@ static void mark_home_server_zombie(home_server_t *home, struct timeval *now, st
        rad_assert((home->state == HOME_STATE_ALIVE) ||
                   (home->state == HOME_STATE_UNKNOWN));
 
-#ifdef WITH_TCP
-       if (home->proto == IPPROTO_TCP) {
-               WARN("Not marking TCP server %s zombie", home->log_name);
-               return;
-       }
-#endif
-
        /*
         *      We've received a real packet recently.  Don't mark the
         *      server as zombie until we've received NO packets for a
@@ -3629,7 +3650,7 @@ static void mark_home_server_zombie(home_server_t *home, struct timeval *now, st
         */
        start = now->tv_sec - ((home->zombie_period + 3) / 4);
        if (home->last_packet_recv >= start) {
-               DEBUG("Recieved reply from home server %d seconds ago.  Might not be zombie.",
+               DEBUG("Received reply from home server %d seconds ago.  Might not be zombie.",
                      (int) (now->tv_sec - home->last_packet_recv));
                return;
        }
@@ -3663,10 +3684,6 @@ void revive_home_server(void *ctx)
        home_server_t *home = talloc_get_type_abort(ctx, home_server_t);
        char buffer[128];
 
-#ifdef WITH_TCP
-       rad_assert(home->proto != IPPROTO_TCP);
-#endif
-
        home->state = HOME_STATE_ALIVE;
        home->response_timeouts = 0;
        home_trigger(home, "home_server.alive");
@@ -3690,13 +3707,6 @@ void mark_home_server_dead(home_server_t *home, struct timeval *when)
        int previous_state = home->state;
        char buffer[128];
 
-#ifdef WITH_TCP
-       if (home->proto == IPPROTO_TCP) {
-               WARN("Not marking TCP server dead");
-               return;
-       }
-#endif
-
        PROXY( "Marking home server %s port %d as dead.",
               inet_ntop(home->ipaddr.af, &home->ipaddr.ipaddr,
                         buffer, sizeof(buffer)),
@@ -3816,7 +3826,7 @@ static void proxy_wait_for_reply(REQUEST *request, int action)
                 *      More than one retransmit a second is stupid,
                 *      and should be suppressed by the proxy.
                 */
-               when = request->proxy_retransmit;
+               when = request->proxy->timestamp;
                when.tv_sec++;
 
                if (timercmp(&now, &when, <)) {
@@ -3852,7 +3862,7 @@ static void proxy_wait_for_reply(REQUEST *request, int action)
                rad_assert(request->proxy_listener != NULL);
                FR_STATS_TYPE_INC(home->stats.total_requests);
                home->last_packet_sent = now.tv_sec;
-               request->proxy_retransmit = now;
+               request->proxy->timestamp = now;
                debug_packet(request, request->proxy, false);
                request->proxy_listener->send(request->proxy_listener, request);
                break;
@@ -3909,18 +3919,11 @@ static void proxy_wait_for_reply(REQUEST *request, int action)
                 *      "response_window", then mark the home server
                 *      as zombie.
                 *
-                *      If the connection is TCP, then another
-                *      "watchdog timer" function takes care of pings,
-                *      etc.  So we don't need to do it here.
-                *
                 *      This check should really be part of a home
                 *      server state machine.
                 */
                if (((home->state == HOME_STATE_ALIVE) ||
                     (home->state == HOME_STATE_UNKNOWN))
-#ifdef WITH_TCP
-                   && (home->proto != IPPROTO_TCP)
-#endif
                        ) {
                        home->response_timeouts++;
                        if (home->response_timeouts >= home->max_response_timeouts)
@@ -3938,6 +3941,17 @@ static void proxy_wait_for_reply(REQUEST *request, int action)
                        FR_STATS_TYPE_INC(proxy_acct_stats.total_timeouts);
                }
 #endif
+#ifdef WITH_COA
+               else if (home->type == HOME_TYPE_COA) {
+                       if (request->proxy_listener) FR_STATS_TYPE_INC(request->proxy_listener->stats.total_timeouts);
+
+                       if (request->packet->code == PW_CODE_COA_REQUEST) {
+                               FR_STATS_TYPE_INC(proxy_coa_stats.total_timeouts);
+                       } else {
+                               FR_STATS_TYPE_INC(proxy_dsc_stats.total_timeouts);
+                       }
+               }
+#endif
 
                /*
                 *      There was no response within the window.  Stop
@@ -4034,6 +4048,12 @@ static void request_coa_originate(REQUEST *request)
                }
        }
 
+       if (!main_config.proxy_requests) {
+               RWDEBUG("Cannot originate CoA packets unless 'proxy_requests = yes'");
+                       TALLOC_FREE(request->coa);
+               return;
+       }
+
        coa = request->coa;
 
        /*
@@ -4392,6 +4412,17 @@ static void coa_wait_for_reply(REQUEST *request, int action)
        case FR_ACTION_TIMER:
                if (request_max_time(request)) break;
 
+               /*
+                *      Don't do fail-over.  This is a 3.1 feature.
+                */
+               if (!request->home_server ||
+                   (request->home_server->state == HOME_STATE_IS_DEAD) ||
+                   !request->proxy_listener ||
+                   (request->proxy_listener->status >= RAD_LISTEN_STATUS_EOL)) {
+                       request_done(request, FR_ACTION_DONE);
+                       break;
+               }
+
                coa_retransmit(request);
                break;
 
@@ -4679,7 +4710,6 @@ static void listener_free_cb(void *ctx)
        rad_assert(this->next == NULL);
        talloc_free(this);
 }
-#endif
 
 #ifdef WITH_PROXY
 static int proxy_eol_cb(void *ctx, void *data)
@@ -4719,7 +4749,8 @@ static int proxy_eol_cb(void *ctx, void *data)
         */
        return 0;
 }
-#endif
+#endif /* WITH_PROXY */
+#endif /* WITH_TCP */
 
 static int event_new_fd(rad_listen_t *this)
 {
@@ -4802,7 +4833,7 @@ static int event_new_fd(rad_listen_t *this)
                                        rad_panic("Failed to insert event");
                                }
                        }
-#endif
+#endif /* WITH_TCP */
                        break;
 #endif /* WITH_PROXY */
 
@@ -4829,7 +4860,7 @@ static int event_new_fd(rad_listen_t *this)
                                        fr_exit(1);
                                }
                        }
-#endif
+#endif /* WITH_TCP */
                        break;
                } /* switch over listener types */
 
@@ -4906,7 +4937,7 @@ static int event_new_fd(rad_listen_t *this)
                        }
                        PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
                }
-#endif
+#endif /* WITH_PROXY */
 
                /*
                 *      Requests are still using the socket.  Wait for
@@ -4938,7 +4969,7 @@ static int event_new_fd(rad_listen_t *this)
                 */
                this->status = RAD_LISTEN_STATUS_REMOVE_NOW;
        } /* socket is at EOL */
-#endif
+#endif   /* WITH_TCP */
 
        /*
         *      Nuke the socket.
@@ -4947,8 +4978,8 @@ static int event_new_fd(rad_listen_t *this)
                int devnull;
 #ifdef WITH_TCP
                listen_socket_t *sock = this->data;
-#endif
                struct timeval when;
+#endif
 
                /*
                 *      Re-open the socket, pointing it to /dev/null.
@@ -5009,7 +5040,7 @@ static int event_new_fd(rad_listen_t *this)
                        }
                        PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
                } else
-#endif
+#endif /* WITH_PROXY */
                {
                        INFO(" ... shutting down socket %s", buffer);
 
@@ -5040,8 +5071,8 @@ static int event_new_fd(rad_listen_t *this)
                                     &(sock->ev))) {
                        rad_panic("Failed to insert event");
                }
-       }
 #endif /* WITH_TCP */
+       }
 
        return 1;
 }
@@ -5145,6 +5176,10 @@ static void handle_signal_self(int flag)
 #ifndef HAVE_PTHREAD_H
 void radius_signal_self(int flag)
 {
+       if (flag == RADIUS_SIGNAL_SELF_TERM) {
+               main_config.exiting = true;
+       }
+
        return handle_signal_self(flag);
 }
 
@@ -5159,6 +5194,10 @@ void radius_signal_self(int flag)
        ssize_t rcode;
        uint8_t buffer[16];
 
+       if (flag == RADIUS_SIGNAL_SELF_TERM) {
+               main_config.exiting = true;
+       }
+
        /*
         *      The read MUST be non-blocking for this to work.
         */