|
1 |
| -/* $OpenBSD: radiusd_ipcp.c,v 1.23 2025/01/29 10:16:05 yasuoka Exp $ */ |
| 1 | +/* $OpenBSD: radiusd_ipcp.c,v 1.24 2025/06/19 09:24:49 yasuoka Exp $ */ |
2 | 2 |
|
3 | 3 | /*
|
4 | 4 | * Copyright (c) 2024 Internet Initiative Japan Inc.
|
@@ -180,6 +180,9 @@ struct assigned_ipv4
|
180 | 180 | struct in_addr);
|
181 | 181 | static struct assigned_ipv4
|
182 | 182 | *ipcp_ipv4_find(struct module_ipcp *, struct in_addr);
|
| 183 | +static struct assigned_ipv4 |
| 184 | + *ipcp_ipv4_check_valid(struct module_ipcp *, |
| 185 | + struct assigned_ipv4 *); |
183 | 186 | static void ipcp_ipv4_delete(struct module_ipcp *,
|
184 | 187 | struct assigned_ipv4 *, const char *);
|
185 | 188 | static void ipcp_ipv4_release(struct module_ipcp *,
|
@@ -740,7 +743,7 @@ ipcp_resdeco(void *ctx, u_int q_id, const u_char *req, size_t reqlen,
|
740 | 743 | bool found = false;
|
741 | 744 | char username[256], buf[128];
|
742 | 745 | struct user *user = NULL;
|
743 |
| - struct assigned_ipv4 *assigned = NULL, *assign; |
| 746 | + struct assigned_ipv4 *assigned = NULL, *assign, *assignt; |
744 | 747 |
|
745 | 748 | ipcp_update_time(self);
|
746 | 749 |
|
@@ -788,8 +791,12 @@ ipcp_resdeco(void *ctx, u_int q_id, const u_char *req, size_t reqlen,
|
788 | 791 | }
|
789 | 792 | if (self->user_max_sessions != 0) {
|
790 | 793 | n = 0;
|
791 |
| - TAILQ_FOREACH(assign, &user->ipv4s, next) |
792 |
| - n++; |
| 794 | + TAILQ_FOREACH_SAFE(assign, &user->ipv4s, next, assignt){ |
| 795 | + assign = ipcp_ipv4_check_valid(self, assign); |
| 796 | + if (assign != NULL) |
| 797 | + n++; |
| 798 | + } |
| 799 | + |
793 | 800 | if (n >= self->user_max_sessions) {
|
794 | 801 | log_info("q=%u user=%s rejected: number of "
|
795 | 802 | "sessions per a user reached the limit(%d)",
|
@@ -1280,23 +1287,32 @@ struct assigned_ipv4 *
|
1280 | 1287 | ipcp_ipv4_find(struct module_ipcp *self, struct in_addr ina)
|
1281 | 1288 | {
|
1282 | 1289 | struct assigned_ipv4 key, *ret;
|
1283 |
| - struct timespec dif; |
1284 | 1290 |
|
1285 | 1291 | key.ipv4 = ina;
|
1286 | 1292 | ret = RB_FIND(assigned_ipv4_tree, &self->ipv4s, &key);
|
1287 |
| - if (ret != NULL && ret->start.tv_sec == 0) { |
| 1293 | + ret = ipcp_ipv4_check_valid(self, ret); |
| 1294 | + return (ret); |
| 1295 | +} |
| 1296 | + |
| 1297 | +struct assigned_ipv4 * |
| 1298 | +ipcp_ipv4_check_valid(struct module_ipcp *self, struct assigned_ipv4 *ip) |
| 1299 | +{ |
| 1300 | + struct timespec dif; |
| 1301 | + |
| 1302 | + if (ip != NULL && ip->start.tv_sec == 0) { |
1288 | 1303 | /* not yet assigned */
|
1289 |
| - timespecsub(&self->uptime, &ret->authtime, &dif); |
| 1304 | + timespecsub(&self->uptime, &ip->authtime, &dif); |
1290 | 1305 | if (dif.tv_sec >= self->start_wait) {
|
1291 | 1306 | /* assumed NAS finally didn't use the address */
|
1292 |
| - TAILQ_REMOVE(&ret->user->ipv4s, ret, next); |
1293 |
| - RB_REMOVE(assigned_ipv4_tree, &self->ipv4s, ret); |
1294 |
| - free(ret); |
1295 |
| - ret = NULL; |
| 1307 | + TAILQ_REMOVE(&ip->user->ipv4s, ip, next); |
| 1308 | + RB_REMOVE(assigned_ipv4_tree, &self->ipv4s, ip); |
| 1309 | + free(ip); |
1296 | 1310 | self->nsessions--;
|
| 1311 | + return (NULL); |
1297 | 1312 | }
|
1298 | 1313 | }
|
1299 |
| - return (ret); |
| 1314 | + |
| 1315 | + return (ip); |
1300 | 1316 | }
|
1301 | 1317 |
|
1302 | 1318 | void
|
|
0 commit comments