]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add a stored procedure for PostgreSQL rlm_sqlippool. 2540/head
authorNathan Ward <nward@braintrust.co.nz>
Thu, 28 Feb 2019 02:47:27 +0000 (15:47 +1300)
committerNathan Ward <nward@braintrust.co.nz>
Thu, 28 Feb 2019 02:47:27 +0000 (15:47 +1300)
This matches the functionality of the existing example query which returns the users previous IP, if possible, however it runs approx 400x faster.

raddb/mods-config/sql/ippool/postgresql/queries.conf
raddb/mods-config/sql/ippool/postgresql/schema.sql

index ca52d3287d4a7b786299740e6782b98fe386ad68..c6c932f20227b1928f3f467724b26ed012fd19c2 100644 (file)
@@ -36,6 +36,17 @@ allocate_find = "\
 #      LIMIT 1 \
 #      FOR UPDATE SKIP LOCKED"
 
+#
+#  Use a stored procedure to find the address. This requires PostgreSQL >= 9.5 as
+#  SKIP LOCKED is used.
+#
+# allocate_find = "\
+#  SELECT find_previous_or_new_framedipaddress( \
+#      '%{control:${pool_name}}', \
+#      '%{SQL-User-Name}', \
+#      '%{Calling-Station-Id}' \
+#      )"
+
 #
 #  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.
index 9328f386c7dcde334c940e01390fc377e1fc8703..66591725bed9928250c44bd5c2959ae561f7ac6c 100644 (file)
@@ -17,3 +17,62 @@ CREATE TABLE radippool (
 CREATE INDEX radippool_poolname_expire ON radippool USING btree (pool_name, expiry_time);
 CREATE INDEX radippool_framedipaddress ON radippool USING btree (framedipaddress);
 CREATE INDEX radippool_nasip_poolkey_ipaddress ON radippool USING btree (nasipaddress, pool_key, framedipaddress);
+
+
+--
+-- Use the following indexes and function if using the stored procedure to
+-- find the previously used address.
+--
+-- You may wish to set the ORDER BY expiry_time to DESC for the first two
+-- queries in order to assign the address that the user last had, rather
+-- than the oldest address the user had.
+--
+
+-- CREATE INDEX radippool_pool_name ON radippool USING btree (pool_name);
+-- CREATE INDEX radippool_username ON radippool USING btree (username);
+-- CREATE INDEX radippool_callingstationid ON radippool USING btree (callingstationid);
+
+-- CREATE OR REPLACE FUNCTION find_previous_or_new_framedipaddress (
+--     v_pool_name VARCHAR(64),
+--     v_username VARCHAR(64),
+--     v_callingstationid VARCHAR(64)
+-- )
+-- RETURNS inet
+-- LANGUAGE plpgsql
+-- AS $$
+-- DECLARE
+--     r_address inet;
+-- BEGIN
+--     SELECT framedipaddress INTO r_address
+--             FROM radippool
+--             WHERE radippool.pool_name = v_pool_name
+--                     AND radippool.expiry_time < 'now'::timestamp(0)
+--                     AND radippool.username = v_username
+--                     AND radippool.callingstationid = v_callingstationid
+--             ORDER BY expiry_time
+--             LIMIT 1
+--             FOR UPDATE SKIP LOCKED;
+--     IF r_address <> NULL THEN
+--             RETURN r_address;
+--     END IF;
+--  SELECT framedipaddress INTO r_address
+--             FROM radippool
+--             WHERE radippool.pool_name = v_pool_name
+--                     AND radippool.expiry_time < 'now'::timestamp(0)
+--                     AND radippool.username = v_username
+--             ORDER BY expiry_time
+--             LIMIT 1
+--             FOR UPDATE SKIP LOCKED;
+--     IF r_address <> NULL THEN
+--             RETURN r_address;
+--     END IF;
+--  SELECT framedipaddress INTO r_address
+--             FROM radippool
+--             WHERE radippool.pool_name = v_pool_name
+--                     AND radippool.expiry_time < 'now'::timestamp(0)
+--             ORDER BY expiry_time
+--             LIMIT 1
+--             FOR UPDATE SKIP LOCKED;
+--     RETURN r_address;
+-- END
+-- $$;