From: Nick Porter Date: Sat, 15 Aug 2020 10:45:38 +0000 (+0100) Subject: Update ippools queries to take advantage of allocate_existing (#3568) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ee6c80487d5fcfa230c61a31181ae866ebbbbcdc;p=thirdparty%2Ffreeradius-server.git Update ippools queries to take advantage of allocate_existing (#3568) 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. --- diff --git a/raddb/mods-config/sql/ippool/mssql/procedure.sql b/raddb/mods-config/sql/ippool/mssql/procedure.sql index f010636d7f0..54e9f26684f 100644 --- a/raddb/mods-config/sql/ippool/mssql/procedure.sql +++ b/raddb/mods-config/sql/ippool/mssql/procedure.sql @@ -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 ) diff --git a/raddb/mods-config/sql/ippool/mssql/queries.conf b/raddb/mods-config/sql/ippool/mssql/queries.conf index 18d80a937f7..cda204a1979 100644 --- a/raddb/mods-config/sql/ippool/mssql/queries.conf +++ b/raddb/mods-config/sql/ippool/mssql/queries.conf @@ -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}}'" diff --git a/raddb/mods-config/sql/ippool/mssql/schema.sql b/raddb/mods-config/sql/ippool/mssql/schema.sql index 2f699b08952..d4bff44230d 100644 --- a/raddb/mods-config/sql/ippool/mssql/schema.sql +++ b/raddb/mods-config/sql/ippool/mssql/schema.sql @@ -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) diff --git a/raddb/mods-config/sql/ippool/mysql/procedure-no-skip-locked.sql b/raddb/mods-config/sql/ippool/mysql/procedure-no-skip-locked.sql index 01f06e58b0d..cc934aaee1b 100644 --- a/raddb/mods-config/sql/ippool/mysql/procedure-no-skip-locked.sql +++ b/raddb/mods-config/sql/ippool/mysql/procedure-no-skip-locked.sql @@ -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 0 END REPEAT; diff --git a/raddb/mods-config/sql/ippool/mysql/procedure.sql b/raddb/mods-config/sql/ippool/mysql/procedure.sql index 85bb818ff14..3835cd55d09 100644 --- a/raddb/mods-config/sql/ippool/mysql/procedure.sql +++ b/raddb/mods-config/sql/ippool/mysql/procedure.sql @@ -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 diff --git a/raddb/mods-config/sql/ippool/mysql/queries.conf b/raddb/mods-config/sql/ippool/mysql/queries.conf index 2ed58620e69..d5a5bbe63c7 100644 --- a/raddb/mods-config/sql/ippool/mysql/queries.conf +++ b/raddb/mods-config/sql/ippool/mysql/queries.conf @@ -45,29 +45,28 @@ #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}'" diff --git a/raddb/mods-config/sql/ippool/mysql/schema.sql b/raddb/mods-config/sql/ippool/mysql/schema.sql index 149bfee13a8..1b299bfe698 100644 --- a/raddb/mods-config/sql/ippool/mysql/schema.sql +++ b/raddb/mods-config/sql/ippool/mysql/schema.sql @@ -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), diff --git a/raddb/mods-config/sql/ippool/oracle/schema.sql b/raddb/mods-config/sql/ippool/oracle/schema.sql index d550a5d8fa1..6f92f175e3c 100644 --- a/raddb/mods-config/sql/ippool/oracle/schema.sql +++ b/raddb/mods-config/sql/ippool/oracle/schema.sql @@ -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; -/ diff --git a/raddb/mods-config/sql/ippool/postgresql/queries.conf b/raddb/mods-config/sql/ippool/postgresql/queries.conf index 3a4208f4cce..f5a45db453c 100644 --- a/raddb/mods-config/sql/ippool/postgresql/queries.conf +++ b/raddb/mods-config/sql/ippool/postgresql/queries.conf @@ -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}'" diff --git a/raddb/mods-config/sql/ippool/postgresql/schema.sql b/raddb/mods-config/sql/ippool/postgresql/schema.sql index 37a3599d187..5be573e18cb 100644 --- a/raddb/mods-config/sql/ippool/postgresql/schema.sql +++ b/raddb/mods-config/sql/ippool/postgresql/schema.sql @@ -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); diff --git a/raddb/mods-config/sql/ippool/sqlite/queries.conf b/raddb/mods-config/sql/ippool/sqlite/queries.conf index 5fc4d0671c9..3d5025bca75 100644 --- a/raddb/mods-config/sql/ippool/sqlite/queries.conf +++ b/raddb/mods-config/sql/ippool/sqlite/queries.conf @@ -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}}'" diff --git a/raddb/mods-config/sql/ippool/sqlite/schema.sql b/raddb/mods-config/sql/ippool/sqlite/schema.sql index 7547b58c304..b020c626956 100644 --- a/raddb/mods-config/sql/ippool/sqlite/schema.sql +++ b/raddb/mods-config/sql/ippool/sqlite/schema.sql @@ -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);