SO_REUSEADDR y SO_REUSEPORT
El contenido de este artículo es principalmente para comprender y resumir las similitudes y diferencias entre SO_REUSEADDR y SO_REUSEPORT, enfocándose en registrar las funciones y diferencias de SO_REUSEADDR y SO_REUSEPORT en Linux
SO_REUSEADDR y SO_REUSEPORT Afecta principalmente el enlace del socket a la IP y el éxito o fracaso del puerto. Primero, introduzca varias reglas vinculantes
Regla 1: puede especificar un socket para vincularlo a una IP y un puerto específicos, como 192.168.0.11:9000;
Regla 2: comodín También se admite el enlace, es decir, el enlace a la IP y el puerto "local" local, y el enlace al puerto "local" local.
Regla 3: De forma predeterminada, dos sockets no se pueden vincular a la misma dirección IP y puerto de origen.
Con los antecedentes anteriores en mente, aquí hay una breve explicación de cómo SO_REUSEADDR y SO_REUSEPORT afectan el enlace en Linux. Dado que la mayoría de las implementaciones de plataforma de SO_REUSEADDR y SO_REUSEPORT son derivados de BSD, primero describiremos el papel de estos dos parámetros en BSD.
La función de SO_REUSEADDR incluye principalmente dos puntos
1. Se cambió el método de procesamiento del enlace de comodines cuando se tratan conflictos de direcciones de origen. El rendimiento específico es el siguiente: cuando SO_REUSEADDR no está configurado. , el socket A primero se vincula a 0.0.0.0:21, luego el socket B se vincula primero a 192.168.0.1:21, luego el socket B se vincula a 192.168.0.1:21, esto no cumple con la regla 3, pero el socket B se vincula exitosamente a 192.168 .0.1:21 después de configurar SO_REUSEADDR. Para enlaces a socketA (enlace genérico) y socketB (enlace específico), esta configuración es independiente del orden. La siguiente tabla resume los enlaces BSD en cada caso
Para Linux, el orden de enlace es necesario para lograr el efecto deseado de esta configuración, es decir, después de configurar SO_REUSEADDR, el enlace específico se debe realizar primero y luego, la vinculación de comodines será exitosa si la vinculación de comodines se realiza primero, la dirección de la vinculación posterior (cuando el puerto es el mismo) solo debe ser la misma que la dirección de una de las vinculaciones de comodines si se especifica. la dirección es la misma, fallará.
2. Cambie la forma en que el sistema ve los sockets en el estado TIME_WAIT. Para comprender esta oración, primero describamos brevemente qué es un socket en el estado TIME_WAIT.
Cuando SO_REUSEADDR no está configurado, el kernel configurará el socket para que esté en el estado TIME_WAIT, que es lo mismo que un socket en el estado TIME_WAIT. El socketA en estado TIME_WAIT todavía se considera un socket válido vinculado a la IP y el puerto especificados, por lo que si otro socketB intenta vincularse a la misma IP y puerto en este momento, fallará (la regla 3 no se cumple), y antes de que el socketA sea realmente liberado, no podrá vincularse exitosamente. Si el socket B tiene SO_REUSEADDR configurado (solo el socket B necesita hacer esto), en este caso la llamada de enlace en el socket B regresará con éxito, pero no hasta que el socket A se libere realmente. (Puede que haya algún problema con mi comprensión de este lugar, lo comprobaré más tarde).
En resumen, cuando el kernel procesa un enlace de socket con SO_REUSEADDR configurado, si la IP y el puerto vinculados entran en conflicto con un socket en el estado TIME_WAIT, el kernel ignorará el conflicto, lo que cambiará la forma en que el sistema ve el socket en el estado TIME_WAIT. forma.
SO_REUSEPORT es más intuitivo, rompe la regla 3
1. Permite vincular varios sockets a la misma dirección y puerto, siempre que en cada socket se establezca SO_REUSEPORT antes del enlace de palabras. Si el primer socket vinculado no tiene SO_REUSEPORT configurado, todos los demás sockets no podrán vincularse a la misma dirección y puerto hasta que se libere el primer socket.
2: SO_REUSEPORT no significa SO_REUSEADDR, es decir, no tiene el segundo efecto de SO_REUSEADDR mencionado anteriormente (es decir, la forma de manejar sockets en estado TIME_WAIT). Por lo tanto, cuando el socket A está en estado TIME_WAIT después de vincularse sin SO_REUSEPORT configurado, el socket B no podrá vincularse a la misma IP que el socket A si el socket B solo tiene SO_REUSEPORT y puerto configurados. Solución
(1) Configure SO_REUSEADDR en el socketB, o configure SO_REUSEADDR y SO_REUSEPORT en el socketB
(2) Configure SO_REUSEPORT en ambos sockets
Se agregó el kernel de Linux 3.9 SO_REUSEPORT. Además de las funciones anteriores, también implementa
1. Para evitar el secuestro de puertos, restrinja todos los sockets que usan la misma IP y puerto para que tengan la misma ID de usuario efectiva.
2. Al procesar el conjunto de sockets SO_REUSEPORT, el kernel de Linux realizará una operación de equilibrio de carga simple, es decir, para los sockets UDP, el kernel intentará reenviar datagramas de manera uniforme para los sockets de escucha TCP. intenta enviar nuevas solicitudes de conexión de cliente (devueltas mediante aceptación) de manera uniforme a sockets con la misma dirección y puerto.
Para posibles malentendidos, consulte el artículo original /questions/14388706/socket-options-so-reuseaddr and-so-reuseport-how-do-they-differ-do-they-mean-t p>
p>