Что делать
Но у меня есть стойкое ощущение, что я могу получить новый ивент по сокету даже без того, чтобы дочитаться до EAGAIN. иначе я не могу объяснить, почему у меня постоянно новые ивенты появляются, при том, что я не успеваю получить ошибку
Если так, то я в жопе. А выглядит всё пока именно так
Что делать
Если так, то я в жопе. А выглядит всё пока именно так
Первые EAGAIN всплывают только после того, как я получаю дубликатный ивент. Пиздец.
Хотя, на самом деле, у меня есть два варианта. Первое - у меня поломанный еполл (учитывая, что у меня твикнутое ядро от cachyos, то допущение валидно). Второе - чтобы не дрочить epoll_ctl с EPOLL_CTL_MOD каждый раз, когда я сменяю состояние таски с READ на WRITE и наоборот, я выставил изначально интересы
Ну так вот. Подозреваю, что мне просто ивент прилетает дважды, один раз - по поводу чтения, второй раз - по поводу записи. Тогда у меня в кэше оказывается две таски - точнее, два указателя на одну и ту же таску. Таким образом, обрабатывая таски в кэше, я обрабатываю одну и ту же как минимум дважды. Первый раз получаю данные, второй раз получаю EAGAIN. Ещё хорошо, если других ивентов нет - тогда я просто сую вместо дубликатной таски нулл. Поскольку я словил EAGAIN, при втором проходе получаю снова эту же таску. И дубликат, который сейчас равен нуллу, я заменяю на "новый" ивент. То есть, совершенно тем же, что и было там до этого. Цикл повторяется.
А если добавить ещё парочку подключений, которые тоже активно обмениваются сообщениями - ситуация совсем уже распиздос. Тут и с одним-то подключением кэш будет расти, хоть и медленно, а с 16 одновременными подключениями он улетает в небеса. А я откровенно хуй знает, что с этим делать...
Хотя, на самом деле, у меня есть два варианта. Первое - у меня поломанный еполл (учитывая, что у меня твикнутое ядро от cachyos, то допущение валидно). Второе - чтобы не дрочить epoll_ctl с EPOLL_CTL_MOD каждый раз, когда я сменяю состояние таски с READ на WRITE и наоборот, я выставил изначально интересы
EPOLLIN | EPOLLOUT | EPOLLRDHUP (ну, ладно, последнее - как костыль, чтобы такие ивенты просто скипать, это еполл сам по себе такую хуйню творит - см. линк на СО от 1 августа)Ну так вот. Подозреваю, что мне просто ивент прилетает дважды, один раз - по поводу чтения, второй раз - по поводу записи. Тогда у меня в кэше оказывается две таски - точнее, два указателя на одну и ту же таску. Таким образом, обрабатывая таски в кэше, я обрабатываю одну и ту же как минимум дважды. Первый раз получаю данные, второй раз получаю EAGAIN. Ещё хорошо, если других ивентов нет - тогда я просто сую вместо дубликатной таски нулл. Поскольку я словил EAGAIN, при втором проходе получаю снова эту же таску. И дубликат, который сейчас равен нуллу, я заменяю на "новый" ивент. То есть, совершенно тем же, что и было там до этого. Цикл повторяется.
А если добавить ещё парочку подключений, которые тоже активно обмениваются сообщениями - ситуация совсем уже распиздос. Тут и с одним-то подключением кэш будет расти, хоть и медленно, а с 16 одновременными подключениями он улетает в небеса. А я откровенно хуй знает, что с этим делать...
Наверное, стоит всё же перестать носом воротить, и начать смотреть, как остальные кэш ивентов оборудовали. Потому что я, по всей видимости, охуею разбираться, почему еполл - настолько ущербный и поломанный. Нет, ну реально, он отправляет EPOLLRDHUP ивенты даже тогда, когда ты их и не просил вовсе! Так ладно это. Он это делает избирательно! Не всегда! Он, сука, НЕКОНСИСТЕНТНЫЙ!!!
Надеюсь, что это я его просто не осилил, но это всё ещё какой-то пиздес.
Надеюсь, что это я его просто не осилил, но это всё ещё какой-то пиздес.
https://idea.popcount.org/2017-03-20-epoll-is-fundamentally-broken-22/
продолжение охуенной серии статей. Здесь, конечно, не описывается моя проблема, а только то, что, несмотря на заявления в мане, удалять сокет из еполла перед close() необходимо. А теперь осталось понять, КАКИМ ОБРАЗОМ МНЕ ДУБЛИРУЮЩИЕСЯ ИВЕНТЫ ПРИЛЕТАЮТ
продолжение охуенной серии статей. Здесь, конечно, не описывается моя проблема, а только то, что, несмотря на заявления в мане, удалять сокет из еполла перед close() необходимо. А теперь осталось понять, КАКИМ ОБРАЗОМ МНЕ ДУБЛИРУЮЩИЕСЯ ИВЕНТЫ ПРИЛЕТАЮТ
idea.popcount.org
Epoll is fundamentally broken 2/2 —
Idea of the day
Idea of the day
Forwarded from Hacker News
Hacker News
Linear Algebra Done Wrong (2004) Article, Comments
Заебись. Вводим транспозицию, чтобы место на бумаге сэкономить
Так атаки с амплификацией трафика - это просто отправка IP пакетов с полем source address жертвы? А разговоров-то было...
Я наконец допёр (с помощью умного поляка), почему при инстанциации сокета мы не указываем условно
Ещё у AF_UNIX есть интересная штука - SOCK_SEQPACKET, которая по своим свойствам чётко между udp и tcp. То есть, оно даёт те же гарантии доставки и сохранения очередности, что и tcp, но сигнализирует об окончании пакета (в оригинале они это называют record) явно, как и udp. При том, что такая удобная и очень дружелюбная к программисту штука есть, в целом-то, только для AF_UNIX, в AF_INET/6 аналогичного транспортного протокола нет. Хоть его и можно имитировать на уровне tcp, что, отнюдь, всё ещё приводит к костылям. Возможно, на этом этапе уже действительно проще вынести это как часть собственного протокола над tcp (который у тебя есть примерно всегда).
Кому интересно, вот текст, описывающий всё это, только языком более компетентного человека: https://urchin.earth.li/~twic/Sequenced_Packets_Over_Ordinary_TCP.html
socket(AF_INET, SOCK_TCP), а SOCK_STREAM, SOCK_DGRAM. Сетевой стэк следует той философии, что ты выбираешь не столько протокол, сколько требуемую семантику от подключения. Соответственно, семантика SOCK_STREAM может быть реализована и по другому семейству, и не по TCP. Всё тот же AF_UNIX к примеру.Ещё у AF_UNIX есть интересная штука - SOCK_SEQPACKET, которая по своим свойствам чётко между udp и tcp. То есть, оно даёт те же гарантии доставки и сохранения очередности, что и tcp, но сигнализирует об окончании пакета (в оригинале они это называют record) явно, как и udp. При том, что такая удобная и очень дружелюбная к программисту штука есть, в целом-то, только для AF_UNIX, в AF_INET/6 аналогичного транспортного протокола нет. Хоть его и можно имитировать на уровне tcp, что, отнюдь, всё ещё приводит к костылям. Возможно, на этом этапе уже действительно проще вынести это как часть собственного протокола над tcp (который у тебя есть примерно всегда).
Кому интересно, вот текст, описывающий всё это, только языком более компетентного человека: https://urchin.earth.li/~twic/Sequenced_Packets_Over_Ordinary_TCP.html
❤1
> In short, this principle argues that important functions (e.g., error control, encryption, delivery acknowledgment) should usually not be implemented at low levels (or layers; see Section 1.2.1) of large systems. However, low levels may provide capabilities that make the job of the endpoints somewhat easier and consequently may improve performance. A nuanced reading reveals that this argument suggests that lowlevel functions should not aim for perfection because a perfect guess at what the application may require is unlikely to be possible.
А я знал! Я знал! Индига шла по правильному пути.
А я знал! Я знал! Индига шла по правильному пути.
М, забавно.
TL;DR заметная доля well-known портов, зарегистрированных в IANA, нечётные. Потому что они существуют ещё со времён arpanet, в которой подключения были унидирекционные (полудуплексными), т.е. односторонними, для чего для каждого приложения резервировалось сразу два порта - один для IN, второй для OUT
TL;DR заметная доля well-known портов, зарегистрированных в IANA, нечётные. Потому что они существуют ещё со времён arpanet, в которой подключения были унидирекционные (полудуплексными), т.е. односторонними, для чего для каждого приложения резервировалось сразу два порта - один для IN, второй для OUT
👍3