Apretón de manos TCP con socket SOCK_RAW

Ok, me doy cuenta de que esta situación es algo inusual, pero necesito establecer una conexión TCP (el protocolo de enlace de 3 vías) usando solo sockets sin formato (en C, en Linux), es decir, necesito construir los encabezados IP y los encabezados TCP. . Estoy escribiendo un servidor (por lo que primero tengo que responder al paquete SYN entrante), y por alguna razón parece que no puedo hacerlo bien. Sí, me doy cuenta de que un SOCK_STREAM manejará esto por mí, pero por razones que no quiero entrar no es una opción.

Los tutoriales que he encontrado en línea sobre el uso de sockets sin procesar describen cómo construir un flooder SYN, pero esto es algo más sencillo que establecer una conexión TCP, ya que no es necesario crear una respuesta basada en el paquete original. He conseguido que funcionen los ejemplos de Flooder de SYN, y puedo leer el paquete SYN entrante desde el socket sin procesar, pero todavía tengo problemas para crear una respuesta SYN / ACK válida para un SYN entrante del cliente.

Entonces, ¿alguien sabe un buen tutorial sobre el uso de sockets sin procesar que vaya más allá de crear un flooder SYN, o alguien tiene algún código que pueda hacer esto (usar SOCK_RAW, y no SOCK_STREAM)? Estaría muy agradecido.

MarkR tiene toda la razón, el problema es que el kernel está enviando paquetes de restablecimiento en respuesta al paquete inicial porque cree que el puerto está cerrado. El kernel me está venciendo a la respuesta y la conexión muere. Ya estaba usando tcpdump para monitorear la conexión. Debería haber sido más atento y noté que había DOS respuestas, una de las cuales fue un reinicio que estaba arruinando las cosas, así como la respuesta que creó mi programa. D'OH!

La solución que parece funcionar mejor es usar una regla de iptables, como sugiere MarkR, para bloquear los paquetes salientes. Sin embargo, hay una forma más fácil de hacerlo que usar la opción de marca, como se sugiere. Simplemente coincido si el indicador TCP de restablecimiento está establecido. Durante el curso de una conexión normal, es poco probable que sea necesario, y realmente no importa para mi aplicación si bloqueo todos los paquetes de reinicio de salida del puerto que se está utilizando. Esto bloquea efectivamente la respuesta no deseada del kernel, pero no mis propios paquetes. Si el puerto en el que escucha mi programa es 9999, la regla de iptables se verá así:

iptables -t filter -I OUTPUT -p tcp --sport 9999 --tcp-flags RST RST -j DROP

Respuestas a la pregunta(7)

Su respuesta a la pregunta