Я так понимаю, что патч сначала нужно написать.
Если он есть - с радостью добавлю, только скажите, где его взять.
Вот что я там пропатчил http://www.sendspace.com/file/pugvnk
С тех пор как написал вышеупомянутое письмо, так и не дошли руки потестировать - совершенно не хватает времени
У меня просьба - сделайте unified diff. (-u) Иначе читать тяжело.
Посмотрел патч - это не совсем то, что требуется. Да, с ним можно указать имя, но резолвится оно в момент запуска, а надо, чтобы резолвилось в момент соединения, т.к. в момент запуска ДНСа может не быть (не получили по DHCP). Можете переделать?
Насколько я понял структуру l2tpd происходит в нем все так:
1. при старте l2tpd составляет список peer'ов (в нашем случае VPN серверов) согласно конфиг файлу, при этом он резолвит имя peer'а и использует его как ключ в массиве этих peer'ов
2. само соединение инициируется путем вызова функии cmd_start_session в handlers/cmd.c, в которую еще раз передается имя peerа с которым надо устанавливать соединение. Оно тут резолвится и по полученному адресу ищется в списке peer'ов, полученных на первом этапе, подходящая запись (см l2tp_peer_find).
Собственно проблема l2tp имеено в первом шаге, когда при старте он читает конфиг, резолвит имена peer'ов и обламывается. Мой патч заключется в том, что на первом этапе он, даже если не удалось срезолвить peer, все равно создает соотв запись с адресом 0xfffffffff. А на втором этапе, если в функции l2tp_peer_find не удалось найти запись на соотв peer, он находит запись с адресом 0xfffffffff и создает на ее основе новую запись с тем адресом, который он срезолвил только что.
Теперь понял. Но почему бы не хранить символическое имя вместо ip адреса?
Оно там и так хранится уже, но оно никому не нужно Потому что резолвинг по имени и так производится в момент создания соединения в той самой cmd_start_session в handlers/cmd.c, куда это самое имя передается в качестве параметра. Весь смысл списка peer'ов это найти доп параметры для этого пира. При этом ключем в этом списке служит ip адрес пира и менять это поведение по всему l2tp смысла нет, проще добавить в момент поиска peer'а в этот список еще один с отрезолвленным ip адресом и параметрами по шаблону (с ip 0xffffffff), созданному при старте l2tp.
Уважаемые Oleg и nickk, пришли ли вы едимому мнению как должен выглядить патч для резолвинга l2tp? Может быть есть тестовый вариант прошивки Олега с этим патчем?
Кстати, проблема с невостановлением соединения в l2tp имеет место. Несколько раз заставал роутер с ситуации, когда он потерял соединение и не думает его восстанавливать. На pptp такого не случалась. Может быть параметр maxfail 0 для l2tp автоматически не применяется и его нужно прописать ручками?
Мне тяжело с этим разбираться, ибо L2TP у меня был только тестовый. Что касается дисконнекта - нужно чтобы кто-то запустил L2TP в отладочном режиме и глянул, в каком он состоянии оказывается. Я, когда-то, нашёл одно место не хорошее, поправил, полсе этого сильно полегчало.
Но для начала нужно при обнаружении такого дисконнекта, зайти на роутер, и сделать ps, чтобы выяснить, жив ли l2tpd в принципе и состояние, в котором находится pppd. И наверное конфиг файлы обоих.
В качестве воркараунда предлагаю попробовать вставить в крон такой перловый скриптец:
Code:#!/opt/bin/microperl -w my $date = localtime; print STDERR "Run on $date\n"; # also may check "l2tp-control dump-sessions" open F, "ifconfig|" or die "Cant query if ppp0 is up"; my $f = 0; while (<F>) { if (/^ppp0\s+Link encap:Point-to-Point Protocol/) { $f = 1; last; } } close F; if ($f) { print STDERR "ppp0 is up\n"; exit(0); } open F, "nvram get wan_heartbeat_x|" or die "Cant query VPN hearbeat server"; my $vpn = <F>; $vpn =~ s/\s+$//; close F; print STDERR "VPN server <$vpn>\n"; system("l2tp-control", "start-session $vpn"); print STDERR "l2tp-control ret $?\n"; exit($?);
Last edited by nickk; 24-03-2007 at 22:55.