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

Ответить
chtito2
Сообщения: 479
Зарегистрирован: Чт апр 17, 2008 5:26 pm

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

Сообщение 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, может быть из-за этого? Не нашел в доках.

chtito2
Сообщения: 479
Зарегистрирован: Чт апр 17, 2008 5:26 pm

Сообщение 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 });
}
Защита от бесконечной рекурсии если адрес не был найден по насу тоже.

chtito2
Сообщения: 479
Зарегистрирован: Чт апр 17, 2008 5:26 pm

Сообщение chtito2 »

Ап. Проблема не решена :(

chtito2
Сообщения: 479
Зарегистрирован: Чт апр 17, 2008 5:26 pm

Сообщение chtito2 »

get_ip() глючит с множественными пулами. Переделал - и все заработало :)

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

~AsmodeuS~
Site Admin
Сообщения: 5749
Зарегистрирован: Пт янв 28, 2005 3:11 pm
Контактная информация:

Сообщение ~AsmodeuS~ »

njuда вы теряете приоритетность пулов

chtito2
Сообщения: 479
Зарегистрирован: Чт апр 17, 2008 5:26 pm

Сообщение 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 на первом свободном пуле.

ran
Сообщения: 2298
Зарегистрирован: Вс окт 21, 2007 2:29 pm

Сообщение ran »

Запрос некорректен т.к. в dv_calls есть только nas_id, там нет pool_id
а pool_id судя по приведённому коду и не берётся из dv_calls... он из nas_ippools берётся

chtito2
Сообщения: 479
Зарегистрирован: Чт апр 17, 2008 5:26 pm

Сообщение chtito2 »

ran писал(а):а pool_id судя по приведённому коду и не берётся из dv_calls...
Ессесно не берется, тогда бы запрос не скомпоновался.

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

Ответить