]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Update ippools queries to take advantage of allocate_existing (#3568)
authorNick Porter <nick@portercomputing.co.uk>
Sat, 15 Aug 2020 10:45:38 +0000 (11:45 +0100)
committerGitHub <noreply@github.com>
Sat, 15 Aug 2020 10:45:38 +0000 (06:45 -0400)
Splitting the queries allows for significant perfomance boost.

Also tidied up the schemas to be consistent on providing a default value
for NOT NULL columns and not allow expiry_time to be NULL, simplifying
the queries chosing expired addresses.

12 files changed:
raddb/mods-config/sql/ippool/mssql/procedure.sql
raddb/mods-config/sql/ippool/mssql/queries.conf
raddb/mods-config/sql/ippool/mssql/schema.sql
raddb/mods-config/sql/ippool/mysql/procedure-no-skip-locked.sql
raddb/mods-config/sql/ippool/mysql/procedure.sql
raddb/mods-config/sql/ippool/mysql/queries.conf
raddb/mods-config/sql/ippool/mysql/schema.sql
raddb/mods-config/sql/ippool/oracle/schema.sql
raddb/mods-config/sql/ippool/postgresql/queries.conf
raddb/mods-config/sql/ippool/postgresql/schema.sql
raddb/mods-config/sql/ippool/sqlite/queries.conf
raddb/mods-config/sql/ippool/sqlite/schema.sql

index f010636d7f027cfdbad140f7ed18095624711fca..54e9f26684fd27e9c7145d977e0eed3e501fff99 100644 (file)
@@ -97,7 +97,7 @@ AS
                                SELECT TOP(1) FramedIPAddress
                                FROM radippool
                                WHERE pool_name = @v_pool_name
-                                       AND ( expiry_time < CURRENT_TIMESTAMP OR expiry_time IS NULL )
+                                       AND expiry_time < CURRENT_TIMESTAMP
                                ORDER BY
                                        expiry_time
                        )
index 18d80a937f75f92662f233231c4b731bdd5d06f6..cda204a1979f163a24ddb21e33a42ffdcbff5229 100644 (file)
@@ -4,40 +4,67 @@
 #
 #  $Id$
 
-# MSSQL-specific syntax
-allocate_begin = "BEGIN TRAN"
-allocate_commit = "COMMIT TRAN"
+# MSSQL-specific syntax - only needed if the queries need wrapping as
+# a transaction - specifically when the SELECT and UPDATE are separate queries
+#allocate_begin = "BEGIN TRAN"
+#allocate_commit = "COMMIT TRAN"
 
 #
-#  The ORDER BY clause of this query tries to allocate the same IP-address
-#  which user had last session...
+#  This query tries to allocate the same IP-address to the user
+#  that they had last session
+#
+allocate_existing = "\
+       WITH cte AS ( \
+               SELECT TOP(1) \
+               FramedIPAddress, NASIPAddress, pool_key, CallingStationId, UserName, expiry_time \
+               FROM ${ippool_table} WITH (xlock rowlock readpast) \
+               WHERE pool_name = '%{control:${pool_name}}' \
+               AND NASIPAddress = '%{NAS-IP-Address}' \
+               AND pool_key = '${pool_key}'  \
+               ORDER BY expiry_time DESC \
+       ) \
+       UPDATE cte \
+       SET \
+               CallingStationId = '%{Calling-Station-Id}', \
+               UserName = '%{User-Name}', \
+               expiry_time = DATEADD(SECOND,${lease_duration},CURRENT_TIMESTAMP) \
+       OUTPUT INSERTED.FramedIPAddress \
+       FROM ${ippool_table}"
+
+#
+#  If no address was returned by the above query, use the following
+#  to find a free one in the pool
 #
 allocate_find = "\
        WITH cte AS ( \
-               SELECT TOP(1) FramedIPAddress FROM ${ippool_table} \
+               SELECT TOP(1) \
+               FramedIPAddress, NASIPAddress, pool_key, CallingStationId, UserName, expiry_time \
+               FROM ${ippool_table} WITH (xlock rowlock readpast) \
                WHERE pool_name = '%{control:${pool_name}}' \
-               AND ( expiry_time < CURRENT_TIMESTAMP OR expiry_time IS NULL ) \
-               OR ( NASIPAddress = '%{NAS-IP-Address}' AND pool_key = '${pool_key}' ) \
-               ORDER BY \
-                       CASE WHEN UserName = '%{User-Name}' THEN 0 ELSE 1 END, \
-                       CASE WHEN CallingStationId = '%{Calling-Station-Id}' THEN 0 ELSE 1 END, \
-                       expiry_time \
+               AND expiry_time < CURRENT_TIMESTAMP \
+               ORDER BY expiry_time \
        ) \
-       UPDATE cte WITH (rowlock, readpast) \
-       SET FramedIPAddress = FramedIPAddress \
-       OUTPUT INSERTED.FramedIPAddress"
+       UPDATE cte \
+       SET \
+               NASIPAddress = '%{NAS-IP-Address}', \
+               pool_key = '${pool_key}', \
+               CallingStationId = '%{Calling-Station-Id}', \
+               UserName = '%{User-Name}', \
+               expiry_time = DATEADD(SECOND,${lease_duration},CURRENT_TIMESTAMP) \
+       OUTPUT INSERTED.FramedIPAddress \
+       FROM ${ippool_table}"
 
 #
 #  If you prefer to allocate a random IP address every time, use this query instead.
-#  Note: This is very slow if you have a lot of free IPs.
+#  Note: This is very slow if you have a lot of free IPs.  This query doesn't update
+#  the pool so a separate allocate_update will be required, as will the allocate_begin
+#  and allocate_commit transaction wrappers.
 #
 #allocate_find = "\
 #      WITH cte AS ( \
 #              SELECT TOP(1) FramedIPAddress FROM ${ippool_table} \
 #              WHERE pool_name = '%{control:${pool_name}}' \
-#              AND ( \
-#                      expiry_time < CURRENT_TIMESTAMP OR expiry_time IS NULL \
-#              ) \
+#              AND expiry_time < CURRENT_TIMESTAMP \
 #              ORDER BY \
 #                      newid() \
 #      ) \
@@ -59,13 +86,13 @@ pool_check = "\
 #
 #  This is the final IP Allocation query, which saves the allocated ip details.
 #
-allocate_update = "\
-       UPDATE ${ippool_table} \
-       SET \
-               NASIPAddress = '%{NAS-IP-Address}', pool_key = '${pool_key}', \
-               CallingStationId = '%{Calling-Station-Id}', \
-               UserName = '%{User-Name}', expiry_time = DATEADD(SECOND,${lease_duration},CURRENT_TIMESTAMP) \
-       WHERE FramedIPAddress = '%I'"
+#allocate_update = "\
+#      UPDATE ${ippool_table} \
+#      SET \
+#              NASIPAddress = '%{NAS-IP-Address}', pool_key = '${pool_key}', \
+#              CallingStationId = '%{Calling-Station-Id}', \
+#              UserName = '%{User-Name}', expiry_time = DATEADD(SECOND,${lease_duration},CURRENT_TIMESTAMP) \
+#      WHERE FramedIPAddress = '%I'"
 
 #
 #  Use a stored procedure to find AND allocate the address. Read and customise
@@ -104,10 +131,10 @@ stop_clear = "\
        UPDATE ${ippool_table} \
        SET \
                NASIPAddress = '', \
-               pool_key = 0, \
+               pool_key = '0', \
                CallingStationId = '', \
                UserName = '', \
-               expiry_time = NULL \
+               expiry_time = CURRENT_TIMESTAMP \
        WHERE NASIPAddress = '%{%{Nas-IP-Address}:-%{Nas-IPv6-Address}}' \
        AND pool_key = '${pool_key}' \
        AND UserName = '%{User-Name}' \
@@ -134,10 +161,10 @@ on_clear = "\
        UPDATE ${ippool_table} \
        SET \
                NASIPAddress = '', \
-               pool_key = 0, \
+               pool_key = '0', \
                CallingStationId = '', \
                UserName = '', \
-               expiry_time = NULL \
+               expiry_time = CURRENT_TIMESTAMP \
        WHERE NASIPAddress = '%{%{Nas-IP-Address}:-%{Nas-IPv6-Address}}'"
 
 #
@@ -147,8 +174,8 @@ off_clear = "\
        UPDATE ${ippool_table} \
        SET \
                NASIPAddress = '', \
-               pool_key = 0, \
+               pool_key = '0', \
                CallingStationId = '', \
                UserName = '', \
-               expiry_time = NULL \
+               expiry_time = CURRENT_TIMESTAMP \
        WHERE NASIPAddress = '%{%{Nas-IP-Address}:-%{Nas-IPv6-Address}}'"
index 2f699b08952905707d0f4e8dbe126c3cd206c67c..d4bff44230d85b63f5d29cfc0d4c138f0b9a9d42 100644 (file)
@@ -6,9 +6,9 @@ CREATE TABLE radippool (
   pool_name             varchar(30) NOT NULL,
   FramedIPAddress       varchar(15) NOT NULL default '',
   NASIPAddress          varchar(15) NOT NULL default '',
-  CalledStationId       VARCHAR(32) NOT NULL,
-  CallingStationId      VARCHAR(30) NOT NULL,
-  expiry_time           DATETIME NULL default NULL,
+  CalledStationId       VARCHAR(32) NOT NULL default '',
+  CallingStationId      VARCHAR(30) NOT NULL default '',
+  expiry_time           DATETIME NOT NULL default CURRENT_TIMESTAMP,
   UserName              varchar(64) NOT NULL default '',
   pool_key              varchar(30) NOT NULL default '',
   PRIMARY KEY (id)
index 01f06e58b0d18111cbab10de9242203a9850b009..cc934aaee1bfa5c90a034f72c73f77d0d8ebf4ce 100644 (file)
@@ -101,7 +101,7 @@ proc:BEGIN
                 SELECT framedipaddress INTO r_address
                 FROM radippool
                 WHERE pool_name = v_pool_name
-                        AND ( expiry_time < NOW() OR expiry_time IS NULL )
+                       AND expiry_time < NOW()
                 --
                 -- WHERE ... GET_LOCK(...,0) = 1 is a poor man's SKIP LOCKED that simulates
                 -- a row-level lock using a "user lock" that allows the locked "rows" to be
@@ -133,7 +133,7 @@ proc:BEGIN
                 -- Here we re-evaluate the original condition for selecting the address
                 -- to detect a race, in which case we try again...
                 --
-                        AND (expiry_time<NOW() OR expiry_time IS NULL);
+                        AND expiry_time<NOW();
 
         UNTIL ROW_COUNT() <> 0 END REPEAT;
 
index 85bb818ff14b123840b7fbd9522a6ed4991b7c2d..3835cd55d097c48500e69b706f90ce85c1938d27 100644 (file)
@@ -89,7 +89,7 @@ proc:BEGIN
                 SELECT framedipaddress INTO r_address
                 FROM radippool
                 WHERE pool_name = v_pool_name
-                        AND ( expiry_time < NOW() OR expiry_time IS NULL )
+                        AND expiry_time < NOW()
                 ORDER BY
                         expiry_time
                 LIMIT 1
index 2ed58620e69f5824e06451c1c32054705f92113c..d5a5bbe63c7d4209c56a9920ee206a7f0c4d9003 100644 (file)
 #skip_locked = "SKIP LOCKED"
 
 #
-#  allocate_find obtains a free ip address to satisfy a new request
+#  allocate_existing looks up a user's IP-address from their
+#  last session.
 #
-#  The ORDER BY clause of this query tries to allocate the same IP-address
-#  that the user had last session:
+allocate_existing = "\
+       SELECT framedipaddress FROM ${ippool_table} \
+       WHERE pool_lane = '%{control:Pool-Name}' \
+       AND nasipaddress = '%{NAS-IP-Address}' \
+       AND pool_key = '${pool_key}' \
+       ORDER BY expiry_time DESC \
+       LIMIT 1 \
+       FOR UPDATE ${skip_locked}"
 #
-#    username <> User-Name returns 0 on a match and 1 on a mismatch,
-#    thus a match sorts first
-#    Ths same is true for callingstationid
-#    If nothing else, return oldest expiry time
+#  If the previous query doesn't find an address then
+#  allocate_find obtains a free ip address to satisfy a new request
 #
 #  Limit 1 to ensure only one result is returned
 #
 allocate_find = "\
        SELECT framedipaddress FROM ${ippool_table} \
        WHERE pool_name = '%{control:Pool-Name}' \
-       AND ( \
-               expiry_time < NOW() OR expiry_time IS NULL \
-               OR ( nasipaddress = '%{NAS-IP-Address}' AND pool_key = '${pool_key}' ) \
-       ) \
-       ORDER BY \
-               (username <> '%{User-Name}'), \
-               (callingstationid <> '%{Calling-Station-Id}'), \
-               expiry_time \
+       AND expiry_time < NOW() \
+       ORDER BY expiry_time \
        LIMIT 1 \
        FOR UPDATE ${skip_locked}"
 
@@ -121,6 +120,7 @@ allocate_update = "\
 #  `procedure.sql` in this directory to determine the optimal configuration.
 #
 #allocate_begin = ""
+#allocate_existing = ""
 #allocate_find = "\
 #      CALL fr_allocate_previous_or_new_framedipaddress( \
 #              '%{control:${pool_name}}', \
@@ -157,7 +157,7 @@ start_update = "\
 # stop_clear = "\
 #         UPDATE ${ippool_table} \
 #         SET \
-#                 expiry_time = 0 \
+#                 expiry_time = NOW() \
 #         WHERE nasipaddress = '%{Nas-IP-Address}' \
 #         AND pool_key = '${pool_key}' \
 #         AND username = '%{User-Name}' \
@@ -168,10 +168,10 @@ stop_clear = "\
        UPDATE ${ippool_table} \
        SET \
                nasipaddress = '', \
-               pool_key = 0, \
+               pool_key = '0', \
                callingstationid = '', \
                username = '', \
-               expiry_time = 0 \
+               expiry_time = NOW() \
        WHERE nasipaddress = '%{Nas-IP-Address}' \
        AND pool_key = '${pool_key}' \
        AND username = '%{User-Name}' \
@@ -202,10 +202,10 @@ on_clear = "\
        UPDATE ${ippool_table} \
        SET \
                nasipaddress = '', \
-               pool_key = 0, \
+               pool_key = '0', \
                callingstationid = '', \
                username = '', \
-               expiry_time = 0 \
+               expiry_time = NOW() \
        WHERE nasipaddress = '%{Nas-IP-Address}'"
 
 #
@@ -218,8 +218,8 @@ off_clear = "\
        UPDATE ${ippool_table} \
        SET \
                nasipaddress = '', \
-               pool_key = 0, \
+               pool_key = '0', \
                callingstationid = '', \
                username = '', \
-               expiry_time = 0 \
+               expiry_time = NOW() \
        WHERE nasipaddress = '%{Nas-IP-Address}'"
index 149bfee13a8f5ef1ce16570c312a9989082a22c2..1b299bfe698b4e25921b2d833f0d3f5548cd5a30 100644 (file)
@@ -6,11 +6,11 @@ CREATE TABLE radippool (
   pool_name             varchar(30) NOT NULL,
   framedipaddress       varchar(15) NOT NULL default '',
   nasipaddress          varchar(15) NOT NULL default '',
-  calledstationid       VARCHAR(30) NOT NULL,
-  callingstationid      VARCHAR(30) NOT NULL,
-  expiry_time           DATETIME NOT NULL default 0,
+  calledstationid       VARCHAR(30) NOT NULL default '',
+  callingstationid      VARCHAR(30) NOT NULL default '',
+  expiry_time           DATETIME NOT NULL default NOW(),
   username              varchar(64) NOT NULL default '',
-  pool_key              varchar(30) NOT NULL,
+  pool_key              varchar(30) NOT NULL default '',
   PRIMARY KEY (id),
   KEY radippool_poolname_expire (pool_name, expiry_time),
   KEY framedipaddress (framedipaddress),
index d550a5d8fa10725d202b8a1ece6934ce093c5ab4..6f92f175e3c8d43977595fe04ab789f6d9cea8ab 100644 (file)
@@ -1,12 +1,14 @@
+CREATE SEQUENCE radippool_seq START WITH 1 INCREMENT BY 1;
+
 CREATE TABLE radippool (
-       id                      INT PRIMARY KEY,
+       id                      INT DEFAULT ON NULL radippool_seq.NEXTVAL PRIMARY KEY,
        pool_name               VARCHAR(30) NOT NULL,
        framedipaddress         VARCHAR(15) NOT NULL,
-       nasipaddress            VARCHAR(15) NOT NULL,
-       pool_key                VARCHAR(30) NOT NULL,
-       CalledStationId         VARCHAR(64) NOT NULL,
-       CallingStationId        VARCHAR(64) NOT NULL,
-       expiry_time             timestamp(0) NOT NULL,
+       nasipaddress            VARCHAR(15) DEFAULT '',
+       pool_key                VARCHAR(30) DEFAULT '',
+       CalledStationId         VARCHAR(64) DEFAULT '',
+       CallingStationId        VARCHAR(64) DEFAULT '',
+       expiry_time             timestamp(0) DEFAULT CURRENT_TIMESTAMP,
        username                VARCHAR(64)
 );
 
@@ -14,14 +16,3 @@ CREATE INDEX radippool_poolname_expire ON radippool (pool_name, expiry_time);
 CREATE INDEX radippool_framedipaddress ON radippool (framedipaddress);
 CREATE INDEX radippool_nasip_poolkey_ipaddress ON radippool (nasipaddress, pool_key, framedipaddress);
 
-CREATE SEQUENCE radippool_seq START WITH 1 INCREMENT BY 1;
-
-CREATE OR REPLACE TRIGGER radippool_serialnumber
-       BEFORE INSERT OR UPDATE OF id ON radippool
-       FOR EACH ROW
-       BEGIN
-               if ( :new.id = 0 or :new.id is null ) then
-                       SELECT radippool_seq.nextval into :new.id from dual;
-               end if;
-       END;
-/
index 3a4208f4ccea4ad97dbfe7375dd7bb5ef5b6f6f9..f5a45db453c6a8646a8a82b8da6fdc98b73311e4 100644 (file)
@@ -7,28 +7,67 @@
 #  Using SKIP LOCKED speed up the allocate_find query by 10
 #  times. However, it requires PostgreSQL >= 9.5.
 #
-#  Uncomment the next line to automatically use SKIP LOCKED
-#skip_locked = "SKIP LOCKED"
+#  If you are using an older version of PostgreSQL comment out the following:
+skip_locked = "SKIP LOCKED"
 
 #
-#  This query allocates an IP address from the Pool
-#  The ORDER BY clause of this query tries to allocate the same IP-address
-#  to the user that they had last session...
+#  This query tries to allocate the same IP-address to the user
+#  that they had last session
+#
+allocate_existing "\
+       WITH cte AS ( \
+               SELECT framedipaddress \
+               FROM ${ippool_table} \
+               WHERE pool_name = '%{control:Pool-Name}' \
+               AND nasipaddress = '%{NAS-IP-Address}' \
+               AND pool_key = '${pool_key}' \
+               LIMIT 1 \
+               FOR UPDATE ${skip_locked} \
+       ) \
+       UPDATE ${ippool_table} \
+       SET \
+               nasipaddress = '%{NAS-IP-Address}', \
+               pool_key = '${pool_key}', \
+               callingstationid = '%{Calling-Station-Id}', \
+               username = '%{SQL-User-Name}', \
+               expiry_time = 'now'::timestamp(0) + '${lease_duration} second'::interval \
+       FROM cte \
+       WHERE ${ippool_table}.framedipaddress = cte.framedipaddress \
+       RETURNING cte.framedipaddress"
+
+#
+#  If no address was returned by the above query, use the following
+#  to find a free one in the pool
 #
 allocate_find = "\
-       SELECT framedipaddress \
-       FROM ${ippool_table} \
-       WHERE pool_name = '%{control:Pool-Name}' \
-       AND ( \
-               expiry_time < 'now'::timestamp(0) \
-               OR ( nasipaddress = '%{NAS-IP-Address}' AND pool_key = '${pool_key}' ) \
+       WITH cte AS ( \
+               SELECT framedipaddress \
+               FROM ${ippool_table} \
+               WHERE pool_name = '%{control:Pool-Name}' \
+               AND expiry_time < 'now'::timestamp(0) \
+               ORDER BY expiry_time \
+               LIMIT 1 \
+               FOR UPDATE ${skip_locked} \
        ) \
-       ORDER BY \
-               (username <> '%{SQL-User-Name}'), \
-               (callingstationid <> '%{Calling-Station-Id}'), \
-               expiry_time \
-       LIMIT 1 \
-       FOR UPDATE ${skip_locked}"
+       UPDATE ${ippool_table} \
+       SET \
+               nasipaddress = '%{NAS-IP-Address}', \
+               pool_key = '${pool_key}', \
+               callingstationid = '%{Calling-Station-Id}', \
+               username = '%{SQL-User-Name}', \
+               expiry_time = 'now'::timestamp(0) + '${lease_duration} second'::interval \
+       FROM cte \
+       WHERE ${ippool_table}.framedipaddress = cte.framedipaddress \
+       RETURNING cte.framedipaddress"
+
+#
+#  Using the two queries above, the following can be blank since they
+#  do not need transactions and the update is done within the same query
+#
+
+allocate_begin = ""
+allocate_update = ""
+allocate_commit = ""
 
 #
 #  If you prefer to allocate a random IP address every time, use this query instead
@@ -56,16 +95,18 @@ pool_check = "\
 #
 #  This query marks the IP address handed out by "allocate-find" as used
 #  for the period of "lease_duration" after which time it may be reused.
-#
-allocate_update = "\
-       UPDATE ${ippool_table} \
-       SET \
-               nasipaddress = '%{NAS-IP-Address}', \
-               pool_key = '${pool_key}', \
-               callingstationid = '%{Calling-Station-Id}', \
-               username = '%{SQL-User-Name}', \
-               expiry_time = 'now'::timestamp(0) + '${lease_duration} second'::interval \
-       WHERE framedipaddress = '%I'"
+#  It is only needed if the update of the record is not done within the
+#  query that selects the address.
+#
+#allocate_update = "\
+#      UPDATE ${ippool_table} \
+#      SET \
+#              nasipaddress = '%{NAS-IP-Address}', \
+#              pool_key = '${pool_key}', \
+#              callingstationid = '%{Calling-Station-Id}', \
+#              username = '%{SQL-User-Name}', \
+#              expiry_time = 'now'::timestamp(0) + '${lease_duration} second'::interval \
+#      WHERE framedipaddress = '%I'"
 
 #
 #  Use a stored procedure to find AND allocate the address. Read and customise
@@ -112,7 +153,7 @@ stop_clear = "\
        UPDATE ${ippool_table} \
        SET \
                nasipaddress = '', \
-               pool_key = 0, \
+               pool_key = '0', \
                callingstationid = '', \
                expiry_time = 'now'::timestamp(0) - '1 second'::interval \
        WHERE nasipaddress = '%{Nas-IP-Address}' \
@@ -143,7 +184,7 @@ on_clear = "\
        UPDATE ${ippool_table} \
        SET \
                nasipaddress = '', \
-               pool_key = 0, \
+               pool_key = '0', \
                callingstationid = '', \
                expiry_time = 'now'::timestamp(0) - '1 second'::interval \
        WHERE nasipaddress = '%{Nas-IP-Address}'"
@@ -156,7 +197,7 @@ off_clear = "\
        UPDATE ${ippool_table} \
        SET \
                nasipaddress = '', \
-               pool_key = 0, \
+               pool_key = '0', \
                callingstationid = '', \
                expiry_time = 'now'::timestamp(0) - '1 second'::interval \
        WHERE nasipaddress = '%{Nas-IP-Address}'"
index 37a3599d18776c820482610ffe208a622f7a128b..5be573e18cbebb422064a42eeb8b04efb04e8baf 100644 (file)
@@ -10,11 +10,11 @@ CREATE TABLE radippool (
        pool_name               varchar(64) NOT NULL,
        FramedIPAddress         INET NOT NULL,
        NASIPAddress            VARCHAR(16) NOT NULL default '',
-       pool_key                VARCHAR(64) NOT NULL default 0,
-       CalledStationId         VARCHAR(64),
+       pool_key                VARCHAR(64) NOT NULL default '0',
+       CalledStationId         VARCHAR(64) NOT NULL default '',
        CallingStationId        text NOT NULL default ''::text,
-       expiry_time             TIMESTAMP(0) without time zone NOT NULL default 'now'::timestamp(0),
-       username                text DEFAULT ''::text
+       expiry_time             TIMESTAMP(0) without time zone NOT NULL default NOW(),
+       username                text NOT NULL DEFAULT ''::text
 );
 
 CREATE INDEX radippool_poolname_expire ON radippool USING btree (pool_name, expiry_time);
index 5fc4d0671c9a08a0ccc091ec0f1a7a58527b49d8..3d5025bca753b4f41adf8535d02c1aabe76d7e4a 100644 (file)
@@ -22,21 +22,27 @@ allocate_begin = "BEGIN EXCLUSIVE"
 allocate_commit = "COMMIT"
 
 #
-#  The ORDER BY clause of this query tries to allocate the same IP-address
-#  which user had last session...
+#  allocate_exsiting looks for a user's IP-Address from their last session
+#
+allocate_existing = "\
+       SELECT framedipaddress \
+       FROM ${ippool_table} \
+       WHERE pool_name = '%{control:${pool_name}}' \
+       AND nasipaddress = '%{NAS-IP-Address}' \
+       AND pool_key = '${pool_key}' \
+       ORDER BY expiry_time DESC \
+       LIMIT 1"
+
+#
+#  If the previous query does not return an address then
+#  allocate_find will find a free address from the pool
 #
 allocate_find = "\
        SELECT framedipaddress \
        FROM ${ippool_table} \
        WHERE pool_name = '%{control:${pool_name}}' \
-       AND ( \
-               ( expiry_time < datetime('now') OR expiry_time IS NULL ) \
-               OR ( nasipaddress = '%{NAS-IP-Address}' AND pool_key = '${pool_key}' ) \
-       ) \
-       ORDER BY \
-               (username <> '%{User-Name}'), \
-               (callingstationid <> '%{Calling-Station-Id}'), \
-               expiry_time \
+       expiry_time < datetime('now') \
+       ORDER BY expiry_time \
        LIMIT 1"
 
 #
@@ -49,7 +55,7 @@ allocate_find = "\
 #      SELECT framedipaddress \
 #      FROM ${ippool_table} \
 #      WHERE pool_name = '%{control:${pool_name}}' \
-#      AND expiry_time IS NULL \
+#      AND expiry_time < datetime('now') \
 #      ORDER BY RAND() \
 #      LIMIT 1"
 
@@ -98,10 +104,10 @@ stop_clear = "\
        UPDATE ${ippool_table} \
        SET \
                nasipaddress = '', \
-               pool_key = 0, \
+               pool_key = '0', \
                callingstationid = '', \
                username = '', \
-               expiry_time = NULL \
+               expiry_time = datetime('now') \
        WHERE nasipaddress = '%{%{Nas-IP-Address}:-%{Nas-IPv6-Address}}' \
        AND pool_key = '${pool_key}' \
        AND username = '%{User-Name}' \
@@ -128,10 +134,10 @@ on_clear = "\
        UPDATE ${ippool_table} \
        SET \
                nasipaddress = '', \
-               pool_key = 0, \
+               pool_key = '0', \
                callingstationid = '', \
                username = '', \
-               expiry_time = NULL \
+               expiry_time = datetime('now') \
        WHERE nasipaddress = '%{%{Nas-IP-Address}:-%{Nas-IPv6-Address}}'"
 
 #
@@ -141,9 +147,9 @@ off_clear = "\
        UPDATE ${ippool_table} \
        SET \
                nasipaddress = '', \
-               pool_key = 0, \
+               pool_key = '0', \
                callingstationid = '', \
                username = '', \
-               expiry_time = NULL \
+               expiry_time = datetime('now') \
        WHERE nasipaddress = '%{%{Nas-IP-Address}:-%{Nas-IPv6-Address}}'"
 
index 7547b58c304d7031c23bdc1352c4ce847aa494c7..b020c6269562323176943c31ba1d9d3163ddcdd6 100644 (file)
@@ -6,11 +6,11 @@ CREATE TABLE radippool (
   pool_name             varchar(30) NOT NULL,
   framedipaddress       varchar(15) NOT NULL default '',
   nasipaddress          varchar(15) NOT NULL default '',
-  calledstationid       VARCHAR(30) NOT NULL,
-  callingstationid      VARCHAR(30) NOT NULL,
-  expiry_time           DATETIME NULL default NULL,
+  calledstationid       VARCHAR(30) NOT NULL default '',
+  callingstationid      VARCHAR(30) NOT NULL default '',
+  expiry_time           DATETIME NOT NULL default (DATETIME('now')),
   username              varchar(64) NOT NULL default '',
-  pool_key              varchar(30) NOT NULL
+  pool_key              varchar(30) NOT NULL default ''
 );
 
 CREATE INDEX radippool_poolname_expire ON radippool(pool_name, expiry_time);