IRCaBot 2.1.0
GPLv3 © acetone, 2021-2022
#dev
/2024/03/18
~R4SAS
~orignal
~villain
@onon
&N00B
+Xeha
+r00tobo
+relaybot
+whothefuckami
AreEnn
HackerMan
Leastr
Most2
Nausicaa
Vort
WayBest
`
acetone
anon2
b3t4f4c3
flumental
karamba_i2p
nemiga
newbie8sep24
not_bob
osoznayka
poriori
profetikla
segfault
teeth
tolik
un
unwr
weko
Vort расследую всё тот же случай зависающего стрима. пачка стрим пакетов от клиента уходит, к серверу приходит на один пакет меньше. всё, этого достаточно для глюка
Vort на клиенте сразу же вижу, как начинают приходить NACK`и на этот пакет. только вот i2pd, кроме вывода сообщения в лог, похоже, не делает ровно ничего. что за фигня?
Vort может, я что-то упускаю и где-то есть их обработка?
Vort посмотрел я алгоритм работы стримов чуть получше и вижу, что и без NACK он должен, теоретически, нормально работать
Vort только вот в некоторых ситуациях случается так, что ResendTimer не срабатывает тогда, когда он нужен
Vort значит ли вот эта строчка, что 9 секунд не должно быть никаких перепосылок? github.com/PurpleI2P/i2pd/blob/b2aa34baa6480831bbd4b0f9c1f9e51b79667a83/libi2pd/Streaming.cpp#L1011
Vort по логике такого быть не должно, по факту получается именно так
Vort вот так уже стрим не зависает: github.com/Vort/i2pd/commit/b3bb563d6ffce542d660aabbe4d8606fed4ef760
Vort но не ломает ли такое изменение ожидаемый эффект от собственно установки этого INITIAL_RTO - не знаю
tetrimer Собрать и посмотреть...
Vort так я не уверен в том, зачем вообще эта установка INITIAL_RTO нужна. надеюсь, orignal расскажет
tetrimer Но у меня, например, стримы замирают больше, чем на 9 секунд... Навскидку - секунд 20-30 стоят.
Vort небось, значения, кратные 9 секундам
tetrimer Возможно, надо будет посчитать.
orignal при переключении тоннелей?
orignal потому что ты не знаешь скорость нового тоннеля
Vort orignal: ну а когда узнаешь скорость нового тоннеля - надо же обратно перепосылки включать?
orignal надо новый RTO вычислть
orignal и переосылать само собой
Vort а со старого туннеля могут же ещё остатки пакетов приходить уже после переключения на новый?
orignal могут разумеется
orignal точнее они будут
orignal потому что это не наш выбор
orignal а той стороны
orignal мы то выбираем только пару для исходящих пакетов
Vort значит, нужно как-то различать RTO от старых пакетов и от новых
Vort может, метить пакеты при отправке - куда они пошли?
orignal возможно
Vort короч тот мой код не годится. но проблему чинить всё же надо
orignal вполне годится
Vort он новый RTO по остаткам старых пакетов насчитает
Vort а надо только по новым
Vort может, запоминать seqn когда было сделано переключение?
orignal а как ты будет решать другую проблемау?
Vort и при получении ack`а смотреть, старый ack или новый
orignal если та сторона переключила тоннели
orignal то есть тут надо некий более общий метод
Vort я пока что плохо понимаю, как этот механизм работает. на "нашей" стороне переключение тоннелей "той" стороны будет как-то заметно? кроме как по лагам
orignal то то и оно что только RTT поменяется
Vort кстати, почему это переключение так тупит, что ему аж 9 секунд надо? из-за поиска RouterInfo ?
orignal откуда 9 секунд?
orignal я не понял
Vort const int INITIAL_RTO = 9000; // in milliseconds
Vort да я и сам замечал, что процесс это часто длительный
Vort когда ещё майнкрафтом тестировал
Vort ну и, соответственно, близкий по сути вопрос - могут ли туннели переключиться быстро - так, что RTT почти и не поменяется?
orignal это число тоже от фонаря
orignal могут конечно
Vort так всё же - каков источник (потенциального) лага при переключении туннелей?
Vort понятно, что RTT в стабильном состоянии будет другой. но есть ведь ещё и дополнительное подтормаживание
Vort то есть, мне кажется, что обычная ситуация такая - образно говоря, RTT 300 300 300 300 5000 400 400 400 400
orignal поиск RI на конце нового тоннеля
Vort хорошо, понял
orignal ну и пир входяшие в новый тоннель могут торомозить
orignal или маршрут проложен через австралию
Vort ну то уже стабильное состояние, это понятно
Vort меня больше момент переключения интересовал
orignal еще могут пиры в новом тоннел пересодиняться
orignal тонель есть а соединения уже нет
Vort тут ещё проблема, что вот этот первый семпл RTT с новым туннелем - он порченый получается - так как измеряется не RTT, а время поиска RI
Vort и ещё более гадкая проблема (которую, скорее всего, замечал onon) - что этот первый порченный семпл может быть единственным
orignal логично
Vort когда делается запрос к веб серверу, одной ли пачкой идёт создание стрима и HTTP запрос?
orignal одной конечно
orignal он идет вместе с SYN
Vort в итоге, вместо оценки RTT имеем какое-то рандомное значение. хреново
orignal ну так потому он и пересчитывается дальше
Vort если это скачка большого файла, то больше отправок данных не будет
Vort и ack`ов, соответственно, тоже (если я правильно понял)
orignal так а нам то какая печаль?
orignal мы получаем пакеты отпраляем аки
Vort отправляем ack`и с частотой основанной на оценке RTT. которая в данном случае - мусор
Vort auto ackTimeout = m_RTT/10;
Vort хрен_знает_что/10
orignal там же с парамтером сравнивается
orignal 10 тоже от фонаря
Vort "<~orignal> там же с парамтером сравнивается" 200мс?
Vort if (ackTimeout > m_AckDelay) ackTimeout = m_AckDelay;
orignal именно так
orignal потому сильно большой акк не будет
orignal даже если RTO дичь
orignal или 200 мс или сколько задано в конфиге
orignal довольно часто ставят 20 или 50
Vort может, реально добиться таки правильной оценки RTT? (при сценарии запроса на скачку с веб сервера)
Vort или SYN отдельно слать или пинги ещё какие-то, вроде, есть
Vort конфигом глюченый алгоритм исправлять - вариант не супер
orignal кстати да можно пинги посылать
orignal и мерять
Vort хотя бы в случае, когда нету надёжных значений
Vort да, наверно, только в этом случае и нужно. есть сомнение в правильности оценки RTT - слать пинг
tetrimer Около 30 секунд висел стрим с rtt=8000, потом по нему пошел какой-то трафик.
orignal ответа ждал
onon Проблема в том, что ещё настоящие пинги бывают больше 8000. Похоже такая задержка появляется, когда пакеты стоят в очереди на транспорт.
onon Я точно не знаю, если отвалился транспорт и пересоздаётся, висят ли пакеты в очереди на этот линк. У меня создаётся впечатление, что так.
onon Врят ли это вортовские длинные буфера успели распространиться по сети, но они проблему только усугубят.
orignal так они же влияют только на стримы
orignal то есть точка-точка
onon А транзит какими путями ходит?
onon Я имею в виду, что на промежуточных узлах такая беда может случаться.
onon И да, я имел ввиду задержки внутри туннелей, а не пинги туннелей.
orignal а транзит каким боком к стимам?
onon Мой стрим - это чей-то транзит
onon Похоже мне не удалось донести мысль, ну и ладно.
orignal твой стрим это у кого то транзит
Vort "Похоже такая задержка появляется, когда пакеты стоят в очереди на транспорт" - обсудили это выше. скорее всего, эта задержка из-за того, что ищется RouterInfo
Vort "настоящие пинги бывают больше 8000" - мне кажется, что правильнее считать их "выбросом" и стараться исключить из вычислений
Vort "Врят ли это вортовские длинные буфера успели распространиться по сети, но они проблему только усугубят" - это тоже обсудили. очередь на транспорт и очередь в транспорте - разные вещи
orignal если более 8000 держится у стрима стрим надо закрывать
Vort "<onon> Я имею в виду, что на промежуточных узлах такая беда может случаться." промежуточный узел переложит с очереди транспорта (освободив её) в очередь на транспорт
Vort orignal: если сможем закодить определение "держится", тогда да
Vort ну и надо же различать "пинг 8000" и "пинг хрен его знает какой"
orignal например если более 10 секунд
Vort ну когда SYN не пролазит никак то вот как раз так и бывает. но это не реальные 8000, это именно "хз что"
Vort ну и как-то же надо учесть прыгание по туннелям. если сейчас реально 8000, то после прыжка на другой туннель может быть совсем другое значение
Vort а прыжки там несколько раз в коде
Vort короч не всё так просто
orignal а с чего вдруг 8000?
orignal не должно такого быть
Vort ну потому что инициализируется переменная так. я бы -1 поставил вместо этого. но там надо много чего переделать чтобы такое внедрить
Vort надо мне разобраться с GarlicRoutingPath для начала, к примеру. это же что-то типа кеша? чтобы следующий стрим по тому же пути мог стартовать с готового значения RTT
Vort если кеш, то тогда там не if (!seqn && надо делать, а проверку на надёжность оценки RTT
Vort нулевой семпл - он же самый грязный. нечего всякую фигню кешировать :)
Vort пока что вижу несколько причин для отметки данных RTT грязными: 1. нулевой семпл. 2. наша смена туннеля. 3. ack перепосылки. 4. выброс (сильно отличающееся значение семпла)
orignal это чтобы одинкаовый RTT был для всех стримов с одним дестинейшином
Vort в смысле принудительно одинаковый? или просто похожий?
orignal он общий
orignal разделяемый между ними
orignal ну когда качаешь страницу с картинками например
Vort интересно. значит, я что-то не так понимаю
Vort есть же Stream::m_RTT и он же будет уникальный для каждого стрима? независимо от дестинейшена
Vort если он такой одинаковый, так, может, его вообще не надо хранить в Stream::
Vort так я и не понял, как GarlicRoutingPath работает :(
Vort к примеру - почему он удаляется при прыжке на другой туннель?
Vort другой туннель - это же другой путь? почему у него не может быть своего GarlicRoutingPath?
orignal он просто обнуляется тогда
orignal потому что данные в нем становятся невалидными
orignal для нового пути он снова создатся
Vort где? я не нашёл
Vort только для нового стрима вижу
Vort вот тут: if (!seqn && m_RoutingSession) // first message confirmed
Vort но это только для seqn 0. новый путь, как я понимаю, продолжает прошлую нумерацию seqn
Vort новый путь в старом стриме
Vort я попробовал перенести туда хранение RTT, но получил облом при прыжке на другой туннель - хранить RTT уже стало негде
Vort логика в том, что RTT - это свойство не стрима, а пути до дестинейшена, в этом стриме используемого
orignal возможно очередной мой баг
orignal естественно его надо не удалять а переписывать
orignal очередная конструкция из говна и палок
Vort и надо же где-то их всех хранить. если на нашем дестинейшене может быть одновременно несколько путей активно
Vort не перебирать же все стримы в поисках структуры нужного пути
orignal так он и сидит в дестинейшене
orignal там хэш таблица
Vort таблица с путями?
orignal ой блять какая жесть там
orignal std::shared_ptr<GarlicRoutingPath> m_SharedRoutingPath;
Vort ну да, один единственный
orignal это в GarlicRoutingSession
orignal но ньюанс в том что похоже это для эль-гамаля только
orignal а нет нормально
orignal class ECIESX25519AEADRatchetSession: public GarlicRoutingSession
orignal std::unordered_map<i2p::data::Tag<32>, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session
orignal но они по static key
orignal session = std::make_shared<ECIESX25519AEADRatchetSession> (this, true);
orignal вот тут интересно
orignal похоже сессия создается и никуда не вставляетя
Vort получается, GarlicRoutingPath может быть общим для нескольких GarlicRoutingSession ?
orignal наверное после сопдинения
orignal почему?
Vort а.. ключ (static key) - это дестинейшен, к которому подключаемся? хреново понимаю эту часть, прошу прощения
orignal да может судя по всему
orignal нет. это отдельный ключ который приходит в лизсете
orignal типа как s для роутеров
orignal вопрос интересный что может получиться несоклько сессий
Vort вот я плохо понимаю даже теоретически, как может стрим прыгнуть с одного пути на другой
Vort где эти GarlicRoutingPath должны храниться к примеру, как к ним должен получаться доступ
Vort стрим же остаётся на той же самой GarlicRoutingSession ?
Vort похоже, рано мне в это место лезть :/
orignal посмотри GarlicDestination::GetRoutingSession
orignal там либо берется существующая либо добавляется новая
orignal но только для эль гамаля
orignal почему для ECIES не так это надо разбираться
Vort ага, вижу несколько вызовов в стримах
orignal я вот вижу что может создаться несколько сессий паралельно
Vort GarlicRoutingPath состоит из outboundTunnel и remoteLease. remoteLease определяет RoutingSession ?
orignal это два тоннеля: наш исходящий и ихний входящий
orignal в RoutingSession еще много чего
orignal всякие обновления лизсета и прочая чушь
Vort может ли одновременно существовать несколько GarlicRoutingPath с одинаковыми remoteLease, но разными outboundTunnel?
orignal не должно быть
orignal должно бвть переключение у всех
Vort ага, то есть при перепрыгивании стрима на другой outbound туннель, прошлый путь таки уничтожается
orignal а это интересный вопрос
orignal ссылка на старый же останется в других стримах
orignal надо флажок ставить
Vort хотя по факту по этому пути всё ещё могут идти пакеты и на них приходить ack`и (наверно)
Vort ладно, понимаю, что всё равно я это переделывать сейчас не смогу, так что пока что отложу дальнейшие вопросы
orignal нет
orignal это же всегда исходящие
orignal это мне надо подумать
Vort исходящий то исходящий, но дойти то он может. и ответ на него прийти может
Vort но объекта для пути через который он ушёл уже не будет
orignal ответ пойдет по другой паре
orignal которую выбирает та сторона
Vort это я к тому, "чей" RTT будет, посчитанный по такому ack`у
Vort наверно такой RTT просто выкидывать надо и всё
orignal того стрима на чей номер пришел ответ
Vort понятно, но нам он (RTT старого пути) уже не будет нужен, так как выбран новый путь (новый outboundTunnel)
Vort то есть, пакеты как-то маркировать надо
Vort или отмечать как-то моменты переключения пути
Vort я думал что, может, для других стримов эта информация (о RTT старого пути) будет полезна, но пока не пойму, как им её передать
Vort то есть, идея в том, что если у нас есть несколько стримов с тем же самым путём, то может быть полезным собирать семплы RTT в одном общем месте
Vort допустим, какой-то малоактивный стрим может получать обновления RTT от более активного стрима
orignal так мы так и делаем
Vort при создании нового стрима?
Vort точнее, при получении первого ack
Vort у нового стрима
Vort хотя, наверно, наоборот
Vort новый стрим может получить RTT от старого
Vort но, в любом случае, постоянного обмена данными RTT я не находил
orignal наверное нету
orignal надо продумать
onon1 RTT меняется слишком быстро, нет смысла его куда-то передавать.
relaybot 13apophis: вы пользуете РТТ как метрику "протухания" канала ?
orignal оно используется для перепосылок пакетов
relaybot 13apophis: т.е. показатель протухания канала и следовательно перепосылок пакетов, так ?
orignal нет
orignal пакет послали за время RTO акк не получили шлем заново
orignal собственно так работает tcp
relaybot 13apophis: причем тыт тогда ртт ?
relaybot 13apophis: метрика крайне ненадежная
orignal так в tcp так же делается