Хорошо, я понимаю, что эта ситуация несколько необычна, но мне нужно установить TCP-соединение (трехстороннее рукопожатие) с использованием только сырых сокетов (в C, в Linux) - то есть мне нужно построить заголовки IP и TCP-заголовки. Я пишу сервер (поэтому я должен сначала ответить на входящий пакет SYN), и по какой-то причине я не могу понять, что это правильно. Да, я понимаю, что SOCK_STREAM справится с этим для меня, но по причинам, по которым я не хочу входить, это не вариант.
В учебниках, которые я нашел в Интернете по использованию raw-сокетов, описывается, как создать SYN-флудер, но это несколько проще, чем фактически устанавливать TCP-соединение, поскольку вам не нужно создавать ответ на основе исходного пакета, Я получил примеры сценариев SYN, и я могу прочитать входящий SYN-пакет как раз из сырого сокета, но мне все еще не удается создать корректный ответ SYN/ACK на входящий SYN от клиента.
Итак, кто-нибудь знает хороший учебник по использованию сырых сокетов, который выходит за рамки создания SYN-флудера, или у кого-нибудь есть код, который мог бы это сделать (используя SOCK_RAW, а не SOCK_STREAM)? Я был бы очень благодарен.
MarkR абсолютно прав - проблема в том, что ядро отправляет пакеты reset в ответ на исходный пакет, потому что он считает, что порт закрыт. Ядро отбивает меня от ответа, и соединение умирает. Я использовал tcpdump для мониторинга соединения уже - я должен был быть более наблюдательным и заметил, что были ДВА ответов, один из которых был reset, который искажал вещи, а также ответ, который создал моя программа. D'OH!
Решение, которое, как представляется, работает лучше всего, - это использовать правило iptables, как это было предложено MarkR, для блокировки исходящих пакетов. Однако есть более простой способ сделать это, чем использовать параметр метки, как это было предложено. Я просто сопоставляю, установлен ли флаг reset TCP. Во время обычной связи это вряд ли понадобится, и это не имеет большого значения для моего приложения, если я блокирую все исходящие пакеты reset из используемого порта. Это эффективно блокирует нежелательный ответ ядра, но не мои собственные пакеты. Если порт, который прослушивает моя программа, равен 9999, тогда правило iptables выглядит так:
iptables -t filter -I OUTPUT -p tcp --sport 9999 --tcp-flags RST RST -j DROP