networking - modelo - tcp/ip model pdf
FIN vs RST en conexiones TCP (3)
De RFC 1122, que todo el mundo sigue citando, pero no citando, en mi contra:
Una conexión TCP puede terminar de dos maneras: (1) la secuencia de cierre de TCP normal utilizando un apretón de manos FIN, y (2) un "aborto" en el que se envían uno o más segmentos RST y el estado de conexión se descarta inmediatamente.
No es posible usar ambos al mismo tiempo. El concepto ni siquiera comienza a tener sentido.
Es posible por medio de trucos que no describiré aquí para cerrar una conexión TCP con un RST en lugar de un FIN, pero es una idea estúpida, y es por eso que no la estoy documentando. Por un lado, todos los datos pendientes en vuelo se pierden.
De la forma en que lo entiendo, hay dos formas de cerrar la conexión TCP:
- enviar bandera FIN
- enviar la bandera RST
RST causa la terminación inmediata de la conexión, mientras que en FIN se obtiene una confirmación.
¿Entiendo este derecho, y hay alguna otra distinción entre los dos? ¿Pueden esas 2 banderas usarse juntas?
FIN dice "terminé de hablar contigo, pero aún escucharé todo lo que tienes que decir hasta que termines"
RST dice "no hay conversación. No diré nada y no escucharé nada de lo que diga": esto es útil si tiene una conexión TCP duradera con poco tráfico. si se reinicia una de las computadoras, se olvida de la conexión y la otra computadora recibe RST tan pronto como envía otro paquete.
FIN o RST se enviarán en el siguiente caso
- su proceso cierra el zócalo
OS está haciendo la limpieza de recursos cuando su proceso sale sin cerrar el socket.
Si su proceso llama a close (), FIN se enviará desde el lado de cierre por defecto (nota: puede establecer la opción de socket SO_LINGER para que envíe RST en lugar de FIN)
Si su proceso sale sin cerrar el socket, kernel cerrará la conexión de tcp y hará la limpieza de su proceso. FIN o RST se pueden enviar. Si hay datos en su cola de recepción, se enviará RST. De lo contrario, se enviaría FIN.
Puede pasar por tcp_close () en tcp.c para obtener más detalles. (Estoy usando kernel-2.6.32-573.7.1 de la rama redhat)