LINUX.ORG.RU

Но ведь это дыра для DDoS!

 , , ,


0

3

Посмотрел тут недавно лайв кодинг одного прикольного чувака из Сибири, который стримит на Твиче и позже выкладывает на Ютубе.

Ниже ссылки на этот стрим на обоих ресурсах:

Этот стрим посвящён проблеме закрытия сокета до того, как все посланные данные на самом деле ушли к получателю. Суть проблемы в том, что функция write (как и неупомянутая в стриме send) пишет данные в ядро, а дошли ли эти данные до получателя уже полностью она не знает, хотя сокеты в Linux блокирующие по-умолчанию. Если сразу после write() или send() вызвать close(sock), у принимающей стороны случится ECONNRESET (Connection reset by peer). Случиться это может в случае, если и принимающая сторона решила что-то нам послать в самом начале, а мы это не прочитали. Это важное условие, потому что в противном случае всё работает верно и без ухищрений.

Первую половину ролика сибиряк разбирает одну старую статью на эту тему, пробует повторить и исправить по статье данную проблему в своём тестовом коде. Вторая половина ролика посвящена исправлению кода в его старых проектах и в контексте этой темы она не так интересна.

В статье предлагаются следующие шаги для решения данной проблемы:

Во-первых предлагается вызывать shutdown(sock, SHUT_WR) на отправляющей стороне сразу после последнего write. Но этого недостаточно, поэтому так же предлагается выставить опцию сокета SO_LINGER которая уже сама по себе должна решить проблему, но почему-то её не решает и это выглядит так, как будто она просто не работает. Есть и Linux-only вещи, такие как SIOCOUTQ ioctl(). Но универсальным решением предлагается просто бесконечный цикл, в котором вычитываются все данные и лишь затем можно закрывать сокет.

Я проверил на своём компьютере большинство из выше перечисленного и этот бесконечный цикл действительно работает, а SO_LINGER с и без shutdown(sock, SHUT_WR) и даже с shutdown(sock, SHUT_RDWR) действительно не работает. Но ведь решение с бесконечным чтением в цикле - это дыра уровня DDoS, ведь если ко мне будет идти бесконечный поток данных, сокет я никогда не закрою.

Ещё одно наблюдение. Если перед закрытием сокета вызвать shutdown(sock, SHUT_WR) и короткий sleep, это так же решает проблему. Неужели в UNIX/Linux/POSIX нет нормального решения данной проблемы?



Последнее исправление: zg (всего исправлений: 2)
Ответ на: комментарий от hateyoufeel

сетевая инфраструктура (провайдеры) не занимается подменой адресов

А они занимаются.

Что им мешает тогда заниматься подменой UUID.

Если инфраструктура сама генерит паразитный трафик, то пользователью все равно некуда дется, придется фильтровать (ддос) трафик собственными мощностями.

anonymous
()
Ответ на: комментарий от anonymous

quic работает поверх ip (udp), там есть адреса и порты.

Я в курсе. Но порты там не нужны. Гарантирую, что 99% QUIC трафика идёт на порт 443 и мультиплексирование сервисов происходит внутри HTTP.

Что им мешает тогда заниматься подменой UUID.

Ничего не мешает. UUID нужен не для защиты от спуфинга, он нужен для идентификации сессии.

Если инфраструктура сама генерит паразитный трафик, то пользователью все равно некуда дется, придется фильтровать (ддос) трафик собственными мощностями.

Это не DDoS.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

Но порты там не нужны.

Гарантирую, что 99% QUIC трафика идёт на порт 443

Определись?

Это не DDoS.

Будет провайдер портить quic(http/3) и прочий неизвестный траффик. Перестанут работать все сайты на этом протоколе, в чем разница между tcp rst?

anonymous
()
Ответ на: комментарий от anonymous

Но порты там не нужны.

Гарантирую, что 99% QUIC трафика идёт на порт 443

Определись?

Определиться с чем? Если во всех пакетах один и тот же номер порта, то зачем его передавать? Его можно не передавать. Анон, не будь маленьким глупышом!

Будет провайдер портить quic(http/3) и прочий неизвестный траффик.

По умолчанию можно считать, что провайдеры будут портить весь трафик. Поэтому его и надо подписывать.

Перестанут работать все сайты на этом протоколе, в чем разница между tcp rst?

Твоё утверждение, буквально, в следующем: провайдер может заблокировать что угодно. Да, это так. Но это не повод не улучшать протоколы.

К тому же, если весь трафик вообще будет состоять из QUIC, провайдер его не будет блокировать. Иначе у такого провайдера тупо не останется клиентов. Это как если бы ты, анон, лет 10-15 назад выступал против повсеместного внедрения TLS на том основании, что, мол, провайдер может просто заблокировать шифрованный трафик, а значит шифровать нет смысла.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

Если во всех пакетах один и тот же номер порта, то зачем его передавать?

Потому что это часть адреса (сервиса). Зачем менять шило на мыло?

QUIC - это не решение проблемы избыточности/ненужности IP:PORT, это попытка спрятать/идентифицировать трафик приложения.

TLS/QUIC - это не про маршрутизацию, так как инфраструктура не может вытащить из этого трафика «адреса взаимодействющих». Это про (не)доверие к траспортному уровню.

anonymous
()
Ответ на: комментарий от anonymous

Потому что это часть адреса (сервиса). Зачем менять шило на мыло?

Это уже давно не часть адреса (сервиса). Смотри выше, что я писал про мультиплексирование. Большая часть трафика в принципе сейчас идёт на порт 443, сервис определяется по URL внутри HTTP заголовка.

Плюс, передавать имя сервиса после установки соединения совсем не нужно. Эти байты можно пустить на более полезные цели.

TLS/QUIC - это не про маршрутизацию, так как инфраструктура не может вытащить из этого трафика «адреса взаимодействющих».

Ошибаешься. Никто не мешает в NAT-таблице использовать ID сессии, который публичный, а не номера портов. Во всех остальных случаях порты – тоже не про маршрутизацию. Для маршрутизации без NAT достаточно двух IP адресов.

Другой вопрос, что NAT стоит вообще выкинуть на мороз в 99% случаев и использовать IPv6, но многие не могут (сам сайт linux.org.ru тому пример).

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Я в курсе. Но порты там не нужны. Гарантирую, что 99% QUIC трафика идёт на порт 443 и мультиплексирование сервисов происходит внутри HTTP.

Там два порта, и 443 только один из них. И тебе всё правильно пишут, если ты введёшь наобум UUID - получишь проблем. Чтобы от них избавиться, придётся применять к каждому пакету криптографию, а это уже определённо не задача для транспортного протокола.

Это надо делать в приложении поверх UDP, и только там где действительно надо (для веба - не надо).

firkax ★★★★★
()
Ответ на: комментарий от hateyoufeel

сессии

Допустим, сессия - лишняя сущность, не надо устанавливать соединение. Что делать? Хочу пингануть echo на стандартизированном порту.

Куда стучаться для устновления соединения, какой session ID ставить до соединения? Мультикаст на весь интернет без конкретного адреса только именем сервиса?

anonymous
()
Ответ на: комментарий от anonymous

Допустим, сессия - лишняя сущность, не надо устанавливать соединение. Что делать? Хочу пингануть echo на стандартизированном порту.

Используй ICMP. Кто ж тебе мешает-то?

Куда стучаться для устновления соединения, какой session ID ставить до соединения?

Session ID генерит клиент в первом же пакете.

Мультикаст на весь интернет без конкретного адреса только именем сервиса?

Чо?

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

оно всё хорошо, но не очень понятно, зачем это всё тащить на уровень tcp

для протоколов типа ssh я бы вобще не хотел, чтоб он молча реконнектился с другого адреса

есть нормальные протоколы прикладного уровня, которые делают то, что ты хочешь

кроме того, если очень хочется можно поверх IP такое запилить

sergej ★★★★★
()
Ответ на: комментарий от sergej

оно всё хорошо, но не очень понятно, зачем это всё тащить на уровень tcp

Потому что с этим всем TCP становится просто не нужен, а UDP заголовок занимает байты в пакете. Которые можно было бы освободить.

для протоколов типа ssh я бы вобще не хотел, чтоб он молча реконнектился с другого адреса

Поздно. Уже реконнектится. Повторюсь, сотовые операторы эмулируют гигантскую локалку через SDN с передачей тебя и твоего IP между базовыми станциями (тот IP, который ты видишь). При этом, в корневой сети у тебя при подключении к каждой БС будет другой IP.

Другими словами, вся эта сложность УЖЕ есть. Ты просто её не видишь как юзер. Так же и прозрачная передача соединения в случае с QUIC тебя парить не должна.

кроме того, если очень хочется можно поверх IP такое запилить

Ага. Выкинув TCP и пустив QUIC поверх IP, как я и писал выше. Это не будет работать с NAT, но в остальном должно быть жизнеспособно.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Используй ICMP

ipv4, включает адреса.

Но я хотел получить ответ конкретного echo сервиса висящего на стандартном порте (7). Придется устанавливать соединение, получать криптографические ключи соединения, только потом ждать ответ?

Session ID генерит клиент в первом же пакете.

То есть нельзя использовать одинаковые id с одного адреса? То есть можно, чтобы внедрится/перехватить в трафик.

Мультикаст на весь интернет без конкретного адреса только именем сервиса?

Чо?

Ты же вроде сказал, что и адреса не нужны, так как клиент или сервер могут гулять про разным сетям и менять адрес, трафик будет идентифицироваться и маршрутизироваться по session id. Нет конкретного адреса, есть только сессия.

anonymous
()
Ответ на: комментарий от hateyoufeel

TCP становится просто не нужен

мне не понятно желание заменить именно tcp, это просто один из сотни протоколов IP

QUIC поверх IP … не будет работать с NAT

QUIC поверх UDP, с натом работает отлично, а если сделать поверх IP, то нат будет совсем пофиг, т.к. на адреса никто не смотрит

sergej ★★★★★
()
Ответ на: комментарий от anonymous

То есть нельзя использовать одинаковые id с одного адреса?

Не-а. Как и одинаковые порты. Тут ничего нового.

Ты же вроде сказал, что и адреса не нужны

Нет, я такого не писал. Ты меня неправильно понял. Всё, о чём я тут пишу, это про уровень выше IP.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от Radjah

Но ведь это дыра для DDoS! (комментарий)

Для второго можно при установке соединения задавать уникальный ID для него (например, UUID на 128 бит) и передавать его в каждом пакете. Если из пакетов после этого будут выкинуты номера портов и прочая бесполезная ссанина, сильного оверхеда не будет. Бонусом получается возможность продолжить соединение после смены IP одним из участников, и вот это вот позволит упростить реализацию современных сетей.

anonymous
()
Ответ на: комментарий от sergej

мне не понятно желание заменить именно tcp, это просто один из сотни протоколов IP

Потому что по нему идёт большая часть трафика и он доставляет больше всего тормозов и страданий.

hateyoufeel ★★★★★
()
Ответ на: комментарий от anonymous

Это я видел. Я про адресацию узлов. Или они не входят в понятие «прочая бесполезная ссанина»? А то я уже начал терять нить повествования. Мне это всё напоминает речь Остапа Бендера в Васюках.

Radjah ★★★★★
()
Ответ на: комментарий от Radjah

Вот пусть расписывает как он хочет получить сохранение сессии при смене ip. И чтобы маршрутизация у провайдера не взбунтовалась и не начала резать трафик, который вдруг пойдет на другой адрес в другой сети. Это получается клиент может и должен управлять маршрутизацией провайдера.

anonymous
()
Ответ на: комментарий от anonymous

Вот пусть расписывает как он хочет получить сохранение сессии при смене ip. И чтобы маршрутизация у провайдера не взбунтовалась и не начала резать трафик, который вдруг пойдет на другой адрес в другой сети.

Ты не в ту степь воюешь, анон.

Всё просто: ты сидишь через wifi в кафе и срёшь на ЛОР. А потом идёшь на улицу и продолжаешь срать на ЛОР, но уже через LTE. В итоге, твой IP адрес поменялся. QUIC позволяет избежать пересоздания соединения и нового обмена ключами в этом случае.

Это получается клиент может и должен управлять маршрутизацией провайдера.

Нет, этого не получается.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 2)
Ответ на: комментарий от hateyoufeel

QUIC позволяет избежать пересоздания соединения

не соединения, а крипто-сессии. Создание крипто-сессии - это тяжело и небыстро. Упростили/облегчили восстановление крипто-сессии, ip:port (udp пакетов) никуда не делись.

anonymous
()
Ответ на: комментарий от anonymous

не соединения, а крипто-сессии.

Без разницы.

Создание крипто-сессии - это тяжело и небыстро.

Это тяжело и небыстро из-за TCP. Сначала нужно три пакета на TCP handshake, потом ещё столько же на TLS. QUIC позволяет это всё в два пакета делать.

Упростили/облегчили восстановление крипто-сессии, ip:port (udp пакетов) никуда не делись.

Про IP я вообще ничего не писал тут, заметь. С ним проблем нет (есть, но это не важно сейчас). Номер порта и вообще весь UDP заголовок тут нужен исключительно чтобы всё это могло пройти через NAT и ядро ОС. Но это всё решается достаточно просто.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

Номер порта и вообще весь UDP заголовок тут нужен …

… если не надо создавать соединение, тем более крипто-сессию.

Я хочу отправить запрос (echo, dns) без алгоритмически сложного парсинга имени сервиса. И возможно/желательно получить ответ без алгоритмически сложного парсинга имени сервиса. Целочисленный номер стандартизированного порта вполне подходит. Существует и работает.

anonymous
()
Ответ на: комментарий от anonymous

… если не надо создавать соединение, тем более крипто-сессию.

Что такое «соединение»?

Я хочу отправить запрос (echo, dns) без алгоритмически сложного парсинга имени сервиса.

Ты мне сейчас хочешь сказать, что строчка «ssh» из 3 байт сложнее, чем число 22 из двух байт? Сравнение строк – это несложно. Тем более, что оно уже происходит, потому что дохрена сервисов либо основаны на HTTP, либо используют его для установки соединения, после чего делают HTTP Upgrade.

Целочисленный номер стандартизированного порта вполне подходит. Существует и работает.

Ну кроме того, что у тебя может быть не больше 65к соединений на один IP. Что, скорее всего, достаточно для пользовательского компа, но вот для NAT уже может быть проблемой. Есть и другие недостатки.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

дохрена сервисов либо основаны на HTTP

Конечно же остальные сервисы не нужны, ip только для http over quic. Все остальные типы ip должны исчезнуть со своими заголовками. Только через session id, только криптографические сессии. Не дай боже пинги подменять или украдут.

anonymous
()
Ответ на: комментарий от anonymous

Конечно же остальные сервисы не нужны, ip только для http over quic.

Сам придумал, сам обиделся. Как моя бывшая прямо!

Я здесь только про TCP и проблемы с ним пишу. Остальное – твои фантазии.

Не дай боже пинги подменять или украдут.

Используй ICMP. Кто ж тебе мешает-то?

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 2)
Ответ на: комментарий от hateyoufeel

Я здесь только про TCP

Не только, ты хочешь убрать из UDP порт и всякое прочее.

В общем, хочешь новый тип ip, который требует ассиметричную криптографию. Как с ним должно работать провайдерское оборудование? Тут мобильные операторы еле успевают за криптографией.

anonymous
()
Ответ на: комментарий от hateyoufeel

я не понимаю, мешает tcp, но при этом большинство сервисов основаны на http в котором таких проблем нет

конкретная проблема то в чем? в каком-то протоколе, который ломается от смены адреса?

sergej ★★★★★
()
Ответ на: комментарий от anonymous

Не только, ты хочешь убрать из UDP порт и всякое прочее.

Про UDP я не писал. Я писал про «пустить QUIC поверх IP, заменив этим TCP».

В общем, хочешь новый тип ip, который требует ассиметричную криптографию.

Повторюсь, протокол IP здесь не причём вообще.

hateyoufeel ★★★★★
()
Ответ на: комментарий от sergej

я не понимаю, мешает tcp, но при этом большинство сервисов основаны на http в котором таких проблем нет

Проблема миграции соединения при смене IP пользователя всё ещё есть даже с HTTP. Как и проблема внеочерёдности доставки данных.

конкретная проблема то в чем?

Там где-то выше я писал об этом. Мне лень повторять одно и то же пять раз, звиняй.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

я внимательно прочитал и проблемы не увидел

убедился ли ты при решении своей проблемы, что например TCP URG флаг не работает и внеполосная передача данных полностью поломана за ненадобностью? или сразу решил, что нужен новый велосипед? :)

sergej ★★★★★
()
Ответ на: комментарий от hateyoufeel

пустить QUIC поверх IP, заменив этим TCP

Оверхед UDP - 8 байт, 64 бит, порты, длина и чексумма (поверх него работает quic). Ты хочешь убрать порт и всякое прочее. И добавить сессионный ключ 128 бит, это минимум. В чем профит? Зачем нужен новый тип (протокол) IP?

Кстати, скорость рукопожатия QUIC не бесплатна, на первый же пакет идет в ответ большой пакет с алгоритмически тяжелой криптографией (ддос?)

Повторюсь, протокол IP здесь не причём вообще.

нужен еще один новый протокол? Когда дойдет до потребителей экономия максимум в 8 байт?

anonymous
()
Ответ на: комментарий от Stanson

Засунь свой ролик себе туда, где ему самое место. Насмотрятся говнища всякого, а потом всякой чушью на форумах срут.

К доктору тебе надо. Нервный ты какой-то, нервный и глупый.

Ну и дебил этот автор. Во-первых, потому что только дебил будет «стримить своё программирование», а во-вторых потому что WebSocket это лютая мерзость, которая не имеет никакого смысла, и реализована теми самыми упорышами которые из браузеров сделали невменяемых глюкавых монстров с анальными зондами. Нет вообще ничего удивительного, что эта параша работает через жопу и требует камлания с бубном чтобы хоть как-то работать.

И снова советую тебе сходить к доктору. Я серьёзно, ведь необходимость использования WebSocket тут вообще не обсуждается и WebSocket тут - всего лишь пример. Он мог бы, с тем же успехом, реализовать и HTTP, в котором поле Content-Length не является обязательным. И я совершенно не согласен в твоей оценке Кутепова как дебила. Мне вот кажется, что ты гораздо больше подходишь под это определение, к тому же ещё и хамишь.

zg
() автор топика
Ответ на: комментарий от alysnix

чтобы тебя не зафлудили снаружи, ты должен сделать shutdown(sock, SHUT_RD) - то есть запретить прием, а потом вычитать все что есть принятого.

потом сделать шатдаун за запись, и тут закрыть свой сокет.

ты так делал?

Не делал, но решение интересное. Непонятно только, почему без такого вычитывания мной посланные данные могут теряться. В статье намекают на half-duplex режим работы TCP, но как это связано с потерей данных?

zg
() автор топика
Ответ на: комментарий от anonymous

Кстати, скорость рукопожатия QUIC не бесплатна, на первый же пакет идет в ответ большой пакет с алгоритмически тяжелой криптографией (ддос?)

Ну и? Повторюсь, речь идёт о замене связки IP+TCP+TLS на IP+QUIC (TLS встроен). То есть, TLS присутствует в обоих случаях.

нужен еще один новый протокол? Когда дойдет до потребителей экономия максимум в 8 байт?

Почему бы и нет? 8 байт, экономия на парсинге UDP заголовков. Несколько процентов по скорости вполне можно выиграть.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

TCP должен умереть. Абсолютно ублюдочный протокол, на самом-то деле. Благо, мир движется в этом направлении, и есть QUIC.

На сколько я понял из описания этого опротокола UDP + QUIC - это просто альтернатива TCP + TLS. Ниже, в споре с анонимом, ты предлагаешь убрать UDP и использовать номер сессии в QUIC вместо номера порта. Разве QUIC вообще расчитан на такую работу? На сколько я знаю нет, у него даже нет номера протокола для записи в IP заголовке, как у TCP (6) или UDP (17). По-моему UDP + QUIC - это всего лишь альтернатива TCP + TLS и полностью заменить TCP он не может. Например для внутреннего общения микросервисов между собой внутри кубернетиса TLS и соответственно QUIC - это просто ненужный оверхед.

zg
() автор топика

Всё что угодно, любой сервер, даже любой IP-адрес это дыра для DDoS. Сетевые каналы хоть и широкие, но ограниченные, и любой сегмент сети можно забить трафиком, если у тебя есть достаточно ресурсов. Собственно D в DDoS означает distributed, распределённая атака с множества машин. Бороться с этим можно, но сложно, нужна инфраструктура и содействие провайдеров связи. Во всяком случае, самое плохое что случится, это полежит твой сервис несколько часов и снова восстанет, потому что атакующему надоест и не захочется слишком палить свой ботнет.

Write блокирует только когда буфер в ядре переполнен и не может забрать больше данных.

Close уничтожает соединение. По хорошему обе стороны перед close должны прислать друг другу shutdown. То есть, как и всегда с TCP, нельзя просто так взять, проорать в одну сторону и закрыть соединение, надо десяток раз друг друга переспросить, ты точно готов, ты точно получил, точно тот номер сегмента?

Я конечно согласен что сокетный апи проклят, нужно ещё долго с ним разбираться чтобы правильно всё приготовить. Но уж точно с ним всё в порядке, TCP уже так много лет и так много всего под него сделано, что это точно выдержавшая испытание временем технология, пусть и не 100% совершенная, из-за чего всякие QUIC делают.

neumond
()
Ответ на: комментарий от neumond

Я конечно согласен что сокетный апи проклят, нужно ещё долго с ним разбираться чтобы правильно всё приготовить. Но уж точно с ним всё в порядке…

Можешь на пальцах объяснить почему ядро приостанавливает отсылку данных из буфера, если в нём есть какие-то другие данные для чтения, которые ещё не прочитаны? Какой в этом смысл?

zg
() автор топика
Ответ на: комментарий от zg

А оно точно приостанавливает? Два направления должны работать независимо друг от друга. Сейчас набросал на питоне сервер-клиент, всё там отсылается, даже когда буфер на чтение забит до отказа.

neumond
()
Ответ на: комментарий от neumond

А оно точно приостанавливает?

Ну вот в ролике из шапки это как раз демонстрируется. Если сторона B ничего не посылает стороне A, данные из A по дороге в B не теряются. Как одно влияет на другое мне до сих пор не понятно. И там код на C, а не на Питоне.

zg
() автор топика
Ответ на: комментарий от zg

Вот тебе сервер, сторона Б, которая бесконечным циклом посылает данные стороне А.

import socket
from threading import Thread
from itertools import count


def sender_thread(conn, ident):
    for i in count():
        line = f'hello there {i}\n'
        conn.send(line.encode('ascii'))
        print(f'{ident}: sent {line}')


def reader_thread(conn, ident):
    while True:
        d = conn.recv(4096)
        if not d:
            print(f'{ident}: no more data to receive')
            break
        print(f'{ident}: received {d}')


with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind(('127.0.0.1', 50_000))
    s.listen(1)
    for i in count():
        conn, addr = s.accept()
        t = Thread(target=sender_thread, args=[conn, i], daemon=True)
        t.start()
        t = Thread(target=reader_thread, args=[conn, i], daemon=True)
        t.start()

Вот клиент, медленно, но бесконечно посылает данные на сервер и ничего при этом не читает. Его буфер на чтение набивается сразу же до отказа, что совершенно не мешает постоянно отсылать новые данные.

import socket
from itertools import count
from time import sleep


with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect(('127.0.0.1', 50_000))
    for i in count():
        s.send(f'hi server {i}'.encode('ascii'))
        sleep(1)

Подозреваю код на си сломан. И хоть Цодинг мне нравится, но смотреть видео не буду.

neumond
()
Ответ на: комментарий от neumond

Подозреваю код на си сломан. И хоть Цодинг мне нравится, но смотреть видео не буду.

Я то-же видео не смотрел, но вот взял код и выбросил все sleep и запустил принимающий сервер на VPS. У себя же запустил wireshark для мониторинга что там действительно было отправлено. Так вот write на 2 000 000 рапортует что все данные были отправлены и я сразу закрываю сокет. Но вот wireshark и сервер показывают что отправлено около 25% - 75%. То-есть write похоже возвращает управление не тогда когда ядро физически отправило все данные а когда скопировало себе во временный буфер, а закрытие сокета также уничтожает этот буфер. Итого данные не доходят.

V1KT0P ★★
()
Ответ на: комментарий от V1KT0P

Именно так. Осталось лишь понять как или почему непрочитанные данные мешают ядру отправить другие данные, уже находящиеся в буфере, в обратную сторону.

zg
() автор топика