NiTr0 Опубликовано 20 июня, 2015 · Жалоба Если использовать пул, то получается нельзя скрипт запускать несколькими процессами, т.к есть маленькая вероятность выдачи 1-го и того же адреса двум абонентам разными процесами. lock-и юзать... хотя у меня - он многопоточный (перепиливал немного), можете зять за основу, выкладывал раньше, но - только настатику заточен... Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ivan_83 Опубликовано 20 июня, 2015 · Жалоба Кто-то реально мерял у себя скорость работы с mysql? А смысл? У всех разные запросы по сложности, разные сервера по скорости. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
martini Опубликовано 21 июня, 2015 · Жалоба коннект к базе ни разу не падал. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Cramac Опубликовано 11 августа, 2015 · Жалоба а никто не доделывал пул адресов? Что то мой метод не очень корректно работает. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Cramac Опубликовано 15 августа, 2015 · Жалоба я все пул мучаю, как у меня работает не очень мне нравится. Сейчас хочу вставить условие на проверку. Мучал вчера то что мы добавляли новую db_get_offer_data но потом подумал может проще вставить условие в handle_discover. Сейчас оно выглядит у меня так: sub handle_discover {#my $dbh = $_[0];#my $fromaddr = $_[1];#my $dhcpreq = $_[2];my ($dhcpresp);$dhcpresp = GenDHCPRespPkt($_[2]);$dhcpresp->{options}->{DHO_DHCP_MESSAGE_TYPE()} = pack('C', DHCPOFFER);if (db_get_offer_data($_[0], $_[2], $dhcpresp) == 1) { send_reply($_[1], $_[2], $dhcpresp, $_[0]); #db_lease_offered($_[0], $_[2]);}else{# if AUTO_CONFIGURE (116) supported - send disable generate link local addrif (defined($_[2]->getOptionRaw(DHO_AUTO_CONFIGURE)) && $_[2]->getOptionValue(DHO_AUTO_CONFIGURE()) != 0) { $dhcpresp->addOptionValue(DHO_AUTO_CONFIGURE(), 0); send_reply($_[1], $_[2], $dhcpresp, $_[0]);}}} в версии БЕЗ пула так: sub handle_discover {#my $dbh = $_[0];#my $fromaddr = $_[1];#my $dhcpreq = $_[2];my ($dhcpresp);$dhcpresp = GenDHCPRespPkt($_[2]);$dhcpresp->{options}->{DHO_DHCP_MESSAGE_TYPE()} = pack('C', DHCPOFFER);if (db_get_requested_data($_[0], $_[2], $dhcpresp) == 1) { send_reply($_[1], $_[2], $dhcpresp, $_[0]); db_lease_offered($_[0], $_[2]);}else{# if AUTO_CONFIGURE (116) supported - send disable generate link local addrif (defined($_[2]->getOptionRaw(DHO_AUTO_CONFIGURE)) && $_[2]->getOptionValue(DHO_AUTO_CONFIGURE()) != 0) { $dhcpresp->addOptionValue(DHO_AUTO_CONFIGURE(), 0); send_reply($_[1], $_[2], $dhcpresp, $_[0]);}}} хочу добавить запрос к базе который возвращает либо число строк (колличество ИП на порту) или массив строк этих адресов (ИД строк) Нужно вставить запрос, потом условие что то типо: $sth = $_[0]->prepare("SELECT `cl_id` ... "); // возвратит массив строк //или такой запрос$sth = $_[0]->prepare("SELECT count(`cl_id`) ..."); // вернет 1 значение count(`cl_id`)смотря с чем проще оперироватьif (полученное >1){тут код если пул на выбранном портуif (db_get_offer_data($_[0], $_[2], $dhcpresp) == 1) { send_reply($_[1], $_[2], $dhcpresp, $_[0]); #db_lease_offered($_[0], $_[2]);}else{# if AUTO_CONFIGURE (116) supported - send disable generate link local addrif (defined($_[2]->getOptionRaw(DHO_AUTO_CONFIGURE)) && $_[2]->getOptionValue(DHO_AUTO_CONFIGURE()) != 0) { $dhcpresp->addOptionValue(DHO_AUTO_CONFIGURE(), 0); send_reply($_[1], $_[2], $dhcpresp, $_[0]);}}}else{тут код если 1 ип на портуif (db_get_requested_data($_[0], $_[2], $dhcpresp) == 1) { send_reply($_[1], $_[2], $dhcpresp, $_[0]); db_lease_offered($_[0], $_[2]);}else{# if AUTO_CONFIGURE (116) supported - send disable generate link local addrif (defined($_[2]->getOptionRaw(DHO_AUTO_CONFIGURE)) && $_[2]->getOptionValue(DHO_AUTO_CONFIGURE()) != 0) { $dhcpresp->addOptionValue(DHO_AUTO_CONFIGURE(), 0); send_reply($_[1], $_[2], $dhcpresp, $_[0]);}}} единственное для запроса нужны $dhcp_opt82_port_id $dhcp_opt82_chasis_id' $dhcp_opt82_vlan_id которые возвращает, как я понимаю my ($dhcp_opt82_vlan_id, $dhcp_opt82_unit_id, $dhcp_opt82_port_id, $dhcp_opt82_chasis_id); if (GetRelayAgentOptions($_[1], $dhcp_opt82_vlan_id, $dhcp_opt82_unit_id, $dhcp_opt82_port_id, $dhcp_opt82_chasis_id)) Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Cramac Опубликовано 15 августа, 2015 · Жалоба Должно получится что то типо: sub handle_discover { #my $dbh = $_[0]; #my $fromaddr = $_[1]; #my $dhcpreq = $_[2]; my ($dhcpresp); my ($dhcp_opt82_vlan_id, $dhcp_opt82_unit_id, $dhcp_opt82_port_id, $dhcp_opt82_chasis_id); $dhcpresp = GenDHCPRespPkt($_[2]); $dhcpresp->{options}->{DHO_DHCP_MESSAGE_TYPE()} = pack('C', DHCPOFFER); if (GetRelayAgentOptions($_[1], $dhcp_opt82_vlan_id, $dhcp_opt82_unit_id, $dhcp_opt82_port_id, $dhcp_opt82_chasis_id)) { $sth = $dbh->prepare("SELECT `cl_id` ... where ...=$dhcp_opt82_port_id ...=$dhcp_opt82_chasis_id' ..=$dhcp_opt82_vlan_id"); //вернет массив cl_id $sth->execute();if ($sth->rows()>1) //Если на порту больше 1 ИП{ if (db_get_offer_data($_[0], $_[2], $dhcpresp) == 1) { send_reply($_[1], $_[2], $dhcpresp, $_[0]); #db_lease_offered($_[0], $_[2]); }else{# if AUTO_CONFIGURE (116) supported - send disable generate link local addr if (defined($_[2]->getOptionRaw(DHO_AUTO_CONFIGURE)) && $_[2]->getOptionValue(DHO_AUTO_CONFIGURE()) != 0) { $dhcpresp->addOptionValue(DHO_AUTO_CONFIGURE(), 0); send_reply($_[1], $_[2], $dhcpresp, $_[0]); }}}else { if (db_get_requested_data($_[0], $_[2], $dhcpresp) == 1) { send_reply($_[1], $_[2], $dhcpresp, $_[0]); db_lease_offered($_[0], $_[2]); }else{# if AUTO_CONFIGURE (116) supported - send disable generate link local addr if (defined($_[2]->getOptionRaw(DHO_AUTO_CONFIGURE)) && $_[2]->getOptionValue(DHO_AUTO_CONFIGURE()) != 0) { $dhcpresp->addOptionValue(DHO_AUTO_CONFIGURE(), 0); send_reply($_[1], $_[2], $dhcpresp, $_[0]); }}} } //if (GetRelayAgentOptions} Поправьте меня Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
lamka Опубликовано 16 августа, 2015 · Жалоба Cramac, а какая у вас задача? Т.е. что имеете ввиду под работой с пулом адресов? Адреса должны выдваться из пула свободных адресов? Так эта задача решается скорее запросами к БД, а не ковырянием скрипта. Вот чего я ни у кого не увидел, так это кэширования лиз в самом перле. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Cramac Опубликовано 16 августа, 2015 · Жалоба Задача простая, сейчас выдаем адреса по опции, в некоторых местах поставили вифи, хочу чтоб он же выдавал клиентам вифи из пула адресов. Сейчас у меня так работает но не очень корректно. Вот и хочу поправить. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
lamka Опубликовано 24 августа, 2015 · Жалоба Потихоньку разбираюсь в коде. Не знаю баг или фича, но вот: в send_reply() if ($_[1]->flags() == 0 || 1) {# send unicast XXXXXXXXX - flags ignored! Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ivan_83 Опубликовано 24 августа, 2015 · Жалоба Потому что оно отправляет релей агенту, а броадкаст там не реализован, насколько помню. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
lamka Опубликовано 25 августа, 2015 · Жалоба выражение в скобках всегда истинно - я про это Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
martini Опубликовано 25 августа, 2015 · Жалоба конечно всегда истинно, Иван ведь сказал что бродкаст не реализован, вот и шлем все юникастом в любом случае.. А условие сделано на всяк случай, вдруг ктото прикрутит работу без релея ) Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
lamka Опубликовано 11 сентября, 2015 (изменено) · Жалоба Работа без релея прикрутилась одной строкой в send_reply(): setsockopt($SOCKET_RCV, SOL_SOCKET, SO_BROADCAST, $toaddr eq $ADDR_BCAST ? 1 : 0); Всовывать перед отправкой пакета: send($SOCKET_RCV, $dhcpresppkt, 0, $toaddr) || logger(0, "send error: $!"); Вроде все четко работает, но только с одним потоком. Если делать несколько, то каждый поток зависать секунд на 10 перед ответом на запрос. Даже не знаю куда смотреть. Может потому что под виндой (dwimperl) тестирую? И еще вопрос: зачем к ответам сервера прикручивать 82 опцию? Без них свитч или релей не поймет куда релеить? Я это убрал, никаких побочных эфектов не заметил. Изменено 11 сентября, 2015 пользователем lamka Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
martini Опубликовано 11 сентября, 2015 · Жалоба если в запросе есть опт82 - то и в ответе она должна быть Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
lamka Опубликовано 11 сентября, 2015 · Жалоба Да, почитал уже RFC 3046 DHCP servers claiming to support the Relay Agent Information option SHALL echo the entire contents of the Relay Agent Information option in all replies. If a server is unable to copy a full Relay Agent Information field into a response, it SHALL send the response without the Relay Information Field, and SHOULD increment an error counter for the situation. Хотя, видимо, это не так уж и страшно. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
NiTr0 Опубликовано 11 сентября, 2015 · Жалоба Хотя, видимо, это не так уж и страшно. То, что не по RFC - рулетка: на одном вендоре заработает, на другом - встанет раком... Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ivan_83 Опубликовано 11 сентября, 2015 · Жалоба Работа без релея прикрутилась одной строкой в send_reply(): Там было следующее. 1. Приём без релей агента вроде не работал в ряде случаев 2. Если клиент не выставил броадкаст флаг то ему нужно отправлять ответ юникастом на его мак адрес, а для этого нужно весь пакет ручками собирать, включая юдп заголовок Выставлять/снимать флаг с сокета - НЕ ПРАВИЛЬНО. С этим сокетом работает много потоков одновременно, и пока может возникнуть ситуация когда один поток выставил флаг, другой его тут же снял, а первый поток только поставил на отправку, в итоге каша вместо результата. Правильным решением будет создание ещё одного сокета для отправки броадкастов. И ещё один для отправки юникастом "сырых" пакетов собранных руками. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
lamka Опубликовано 11 сентября, 2015 · Жалоба то ему нужно отправлять ответ юникастом на его мак адрес, а для этого нужно весь пакет ручками собирать, включая юдп заголовок Не понял как можно послать ip пакет на мак адрес? Если у клиента нет ciaddr в запросе, то только бродкаст. Иначе как без ip слать? Мне кажется, что если у клиента нет ciaddr и флага бродкаста, то пошел он нафиг. Вообще такое часто встречается? Правильным решением будет создание ещё одного сокета для отправки броадкастов. И ещё один для отправки юникастом "сырых" пакетов собранных руками. А клиенты не проверяют исходящий порт сервера? Ведь придется сокеты вешать на разные исходящие порты, не только 68? Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ivan_83 Опубликовано 11 сентября, 2015 · Жалоба Не понял как можно послать ip пакет на мак адрес? Если у клиента нет ciaddr в запросе, то только бродкаст. Иначе как без ip слать? Мне кажется, что если у клиента нет ciaddr и флага бродкаста, то пошел он нафиг. Вообще такое часто встречается? Да легко. Заполняем L2 заголовок правильно и пакет уходит кому надо. Вон PPPoE шлёт же на мак клиента, без всяких IP адресов, чем я хуже?) Мак клиента есть в запросе. Броадкаст флаг - вроде как костыль, который позже появился. А клиенты не проверяют исходящий порт сервера? Ведь придется сокеты вешать на разные исходящие порты, не только 68? Нужно уточнять документацию. Есть ещё REUSEPORT флаг на сокет, но тогда пакеты будут дублироватся и их нужно будет или вычитывать из сокета или забить на это и после заполнения буфера они сами начнут дропатся. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
lamka Опубликовано 11 сентября, 2015 · Жалоба Заполняем L2 заголовок правильно и пакет уходит кому надо. Вон PPPoE шлёт же на мак клиента, без всяких IP адресов, чем я хуже?) Мак клиента есть в запросе. Видимо я чего-то не понимаю. PPPoE - не относится к IP-протоколам, он сам по себе. И в заголовке IP-пакета нет данных о мак-адресе. Клепать ethernet фреймы - как-то уж слишком экстремально. Есть ещё REUSEPORT флаг на сокет, но тогда пакеты будут дублироватся и их нужно будет или вычитывать из сокета или забить на это и после заполнения буфера они сами начнут дропатся. Пожалуй, логично было бы вынести работу с сокетом из потоков в основной и сделать очередь (благо что udp - пакеты улетают мгновенно), . Т.е. в потоках читаются запросы, идет обращение к БД и т.п., а ответы суются в очередь, которую обслуживает отдельный поток. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ivan_83 Опубликовано 12 сентября, 2015 · Жалоба Видимо я чего-то не понимаю. PPPoE - не относится к IP-протоколам, он сам по себе. Это я к тому, что отправить на мак можно любой пакет и IP тут никаким боком. И в заголовке IP-пакета нет данных о мак-адресе. Мак адрес у дхцп сервера есть из запроса, клиент сам присылает свой мак. Можно было бы и в л2 пакета смотреть, но это не нужно, разве что для секурности, чтобы подавлять работу подавителей дхцп серверов. :) Клепать ethernet фреймы - как-то уж слишком экстремально. Там сложного ничего нет. Совсем ничего. Единственная замута это вланы и дополнение конфига. IP/UDP сложнее - для них нужно суммы считать. Пожалуй, логично было бы вынести работу с сокетом из потоков в основной и сделать очередь (благо что udp - пакеты улетают мгновенно), . Т.е. в потоках читаются запросы, идет обращение к БД и т.п., а ответы суются в очередь, которую обслуживает отдельный поток. Нет. Чтобы был полноценный сервер без релея нужно принимать и отправлять прямо с интерфейса через BPF прослойку. Те не городить дрочиво броадкаст опции сокета, а собирать л2+л3+л4+дхцп пакет самому и слать в сеть. Тогда и очереди никакие не нужны. Я заглядывал в dnsmasq там вроде именно так и сделано было, помню видел программы-фильтры дхцп запросов для BPF. (а может это dhcpdump был) Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
martini Опубликовано 13 сентября, 2015 · Жалоба Иван - все правильно говоришь, все работает. Написал от нечего делать более развернутый ДХЦП, дергает пакеты из ядра, разбирает все сам , проверяет в базе и отдает назад собирая полный эзернет заголовок и отправляет на мак юзера и юникаст и броадкаст. Причем добавил даже unnumbered туда , осталось шейпер прикрутить и вебку хоть какую то сделать... Ну и получится какой то аналог то ли циски, то ли акселя )) Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
pppoetest Опубликовано 13 сентября, 2015 · Жалоба Аксель, емнип, модуль ядерный, а это чистой воды юзерленд. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
martini Опубликовано 13 сентября, 2015 · Жалоба а причем тут это ? я в юзерленде только дхцп пакеты разгребаю и собираю, всей маршрутизацией занимается ядро как и раньше.. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
NiTr0 Опубликовано 13 сентября, 2015 · Жалоба Аксель, емнип, модуль ядерный, а это чистой воды юзерленд. там тот модуль нужен только для псевдоинтерфейсов... Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...