Страница 1 из 1

Пулы адресов не учитываются

Добавлено: Пт окт 31, 2008 6:35 am
chtito2
У NAS есть два пула адресов (2х32). Но когда 32 юзера в онлайне и хочет войти еще один, то не пускает:
2008-10-30 22:37:49 LOG_WARNING: AUTH [foo] NAS: 5 Rejected! There is no free IPs in address pools (USED: 64) CID:
xxx.xxx.xxx
Оба пула заведены с приоритетом по умолчанию 0, может быть из-за этого? Не нашел в доках.

Добавлено: Пт окт 31, 2008 7:25 am
chtito2
В функции get_ip() нашел странность:
Прежде всего в начале функции:
if ($attr->{TP_IPPOOL}) {
$self->query($db, "SELECT ippools.ip, ippools.counts, ippools.id FROM ippools
WHERE ippools.id='$attr->{TP_IPPOOL}'
ORDER BY ippools.priority;");
}
ORDER BY... абсолютно не нужно т.к. выборка идет по primary key и по определению запись будет одна.

Второе, гораздо важнее: Если свободный ip не нашелся в одном пуле по $attr->{TP_IPPOOL}, то делается попытка найти его более глобально по $nas_num, для чего ближе к концу совершается рекурсивный вызов к себе же:
if ($attr->{TP_POOLS}) {
$self->get_ip($nas_num, $nas_ip);
}
Но где return? должно быть
if ($attr->{TP_POOLS}) {
return $self->get_ip($nas_num, $nas_ip);
}
Иначе забудется возвращаемое ей значение и вернется последнее return 0; в конце get_ip(). В перле всегда возвращается последнее вычисленное значение или undef, если не было явного return.

И еще: откуда взялся $attr->{TP_POOLS} ? Что в нем? Чувствуется, что вариант, когда у наса несколько пулов - недоработан. Предлагаю заменить последнее выражение на:
unless (defined $attr->{TP_POOLS}) {
return $self->get_ip($nas_num, $nas_ip, { TP_POOLS => 1 });
}
Защита от бесконечной рекурсии если адрес не был найден по насу тоже.

Добавлено: Пт окт 31, 2008 1:16 pm
chtito2
Ап. Проблема не решена :(

Добавлено: Пт окт 31, 2008 2:24 pm
chtito2
get_ip() глючит с множественными пулами. Переделал - и все заработало :)

p.s.: Мне кажется перловы хэши и референсы вконец запутали автора, как впрочем и меня когда-то ;) Здесь я просто избавился от них и собираю все пулы в один хэш.

Добавлено: Пт ноя 07, 2008 7:50 am
~AsmodeuS~
njuда вы теряете приоритетность пулов

Добавлено: Пт ноя 07, 2008 8:32 am
chtito2
Так уж и быть:
$self->query($db, "SELECT c.framed_ip_address
FROM (dv_calls c, nas_ippools np)
WHERE c.nas_id=np.nas_id AND np.pool_id in ( $used_pools ) AND (status=1 or status>=3);");
Запрос некорректен т.к. в dv_calls есть только nas_id, там нет pool_id. Таким образом, если у nas_id=5 есть 2 пула адресов и в dv_calls сидит например 12 человек с nas_id=5, то ваш запрос вернет 12*2 = 24 сидящих.
вы теряете приоритетность пулов
Приоритетность мне была не нужна и поэтому не реализована. В принципе будь это необходимо мне было бы несложно сделать раскидав пулы по разным хешам, в конце пройтись по ним в цикле в порядке убывания приоритета и выделить случайный ip на первом свободном пуле.

Добавлено: Пт ноя 07, 2008 9:23 am
ran
Запрос некорректен т.к. в dv_calls есть только nas_id, там нет pool_id
а pool_id судя по приведённому коду и не берётся из dv_calls... он из nas_ippools берётся

Добавлено: Пт ноя 07, 2008 10:27 am
chtito2
ran писал(а):а pool_id судя по приведённому коду и не берётся из dv_calls...
Ессесно не берется, тогда бы запрос не скомпоновался.

Текущее условие выборки делает join по dv.calls.nas_id. Каждый pool_id из $user_pools просто умножает кол-во сидящих в dv_calls абонентов с данным nas_id на 2.