]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
reference count tracking table entries
authorAlan T. DeKok <aland@freeradius.org>
Fri, 26 Jan 2018 14:07:42 +0000 (09:07 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 26 Jan 2018 14:09:48 +0000 (09:09 -0500)
src/modules/proto_radius/track.c
src/modules/proto_radius/track.h

index be13a4f616d48d84df035c5b46efdf14e715b258..84936f407886a19fb533545f316d578c2f646323 100644 (file)
@@ -126,10 +126,16 @@ int fr_radius_tracking_entry_delete(fr_tracking_t *ft, fr_tracking_entry_t *entr
 
        if (entry->timestamp == 0) return -1;
 
+       rad_assert(entry->uses > 0);
+       entry->uses--;
+
        /*
         *      Someone else is using it, so we don't delete it.
         */
-       if (recv_time != entry->timestamp) return 0;
+       if (recv_time != entry->timestamp) {
+               if (entry->uses == 0) goto delete;
+               return 0;
+       }
 
        /*
         *      Mark the reply (if any) as done.
@@ -143,6 +149,12 @@ int fr_radius_tracking_entry_delete(fr_tracking_t *ft, fr_tracking_entry_t *entr
        rad_assert(entry->ev == NULL);
        entry->timestamp = 0;
 
+       /*
+        *      Don't delete it.  Someone else is still using it.
+        */
+       if (entry->uses > 0) return 0;
+
+delete:
        /*
         *      We are tracking src/dst ip/port, we have to remove
         *      this entry from the tracking tree, and then free it.
@@ -199,6 +211,7 @@ fr_tracking_status_t fr_radius_tracking_entry_insert(fr_tracking_entry_t **p_ent
 
                entry->ft = ft;
                entry->timestamp = timestamp;
+               entry->uses = 1;
 
                /*
                 *      Copy the src_dst information over to the entry.
@@ -234,19 +247,16 @@ fr_tracking_status_t fr_radius_tracking_entry_insert(fr_tracking_entry_t **p_ent
         *      Over-write an existing entry.
         */
        entry->timestamp = timestamp;
+       entry->uses++;
 
        /*
-        *      Toss the conflicting packet (for now).
+        *      The new packet conflicts with the old one.  Allow BOTH
+        *      to operate, and let the caller figure out what to do.
         */
        if (entry->reply_len == 0) {
                return FR_TRACKING_CONFLICTING;
        }
 
-       /*
-        *      Over-write an existing entry.
-        */
-       entry->timestamp = timestamp;
-
        if (entry->reply) {
                talloc_const_free(entry->reply);
                entry->reply = NULL;
index 43b9ff299b257bcfa3a2a7da0b3cba90c792fd8a..0349d927e9cf18561e90493e19f9e4a19d953d84 100644 (file)
@@ -47,6 +47,7 @@ typedef struct fr_tracking_entry_t {
 
        size_t                  src_dst_size;   //!< size of the data in src_dst
        fr_time_t               timestamp;      //!< when the request was received
+       int                     uses;           //!< how many packets are using us
        uint8_t const           *reply;         //!< the response (if any);
        size_t                  reply_len;      //!< the length of the response
        uint8_t                 data[20];       //!< the full RADIUS packet header