Set a timer for marking a home server dead. Closes #712
[freeradius.git] / src / main / process.c
index a3aad00..2a70e23 100644 (file)
@@ -108,7 +108,16 @@ static char const *child_state_names[REQUEST_CHILD_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
@@ -1718,7 +1727,7 @@ static REQUEST *request_setup(rad_listen_t *listener, RADIUS_PACKET *packet,
         *      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);
@@ -3046,7 +3055,6 @@ static void ping_home_server(void *ctx)
        struct timeval when, now;
 
        if ((home->state == HOME_STATE_ALIVE) ||
-           (home->ping_check == HOME_PING_CHECK_NONE) ||
 #ifdef WITH_TCP
            (home->proto == IPPROTO_TCP) ||
 #endif
@@ -3056,6 +3064,9 @@ static void ping_home_server(void *ctx)
 
        gettimeofday(&now, NULL);
 
+       /*
+        *      We've run out of zombie time.  Mark it dead.
+        */
        if (home->state == HOME_STATE_ZOMBIE) {
                when = home->zombie_period_start;
                when.tv_sec += home->zombie_period;
@@ -3067,11 +3078,30 @@ static void ping_home_server(void *ctx)
                }
        }
 
+       /*
+        *      We're not supposed to be pinging it.  Just wake up
+        *      when we're supposed to mark it dead.
+        */
+       if (home->ping_check == HOME_PING_CHECK_NONE) {
+               if (home->state == HOME_STATE_ZOMBIE) {
+                       when = home->zombie_period_start;
+                       when.tv_sec += home->zombie_period;
+                       INSERT_EVENT(ping_home_server, home);
+               }
+
+               /*
+                *      Else mark_home_server_dead will set a timer
+                *      for revive_interval.
+                */
+               return;
+       }
+
+
        request = request_alloc(NULL);
        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) {
@@ -4215,6 +4245,20 @@ static int event_new_fd(rad_listen_t *this)
 
                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);
                }
@@ -4407,8 +4451,6 @@ static int event_new_fd(rad_listen_t *this)
 #endif
 
 #ifdef WITH_TCP
-               INFO(" ... shutting down socket %s", buffer);
-
 #ifdef WITH_PROXY
                /*
                 *      The socket is dead.  Force all proxied packets
@@ -4416,6 +4458,16 @@ static int event_new_fd(rad_listen_t *this)
                 *      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);
 
@@ -4428,6 +4480,8 @@ static int event_new_fd(rad_listen_t *this)
                } else
 #endif
                {
+                       INFO(" ... shutting down socket %s", buffer);
+
                        /*
                         *      EOL all requests using this socket.
                         */