RFC 2920 – Canalización SMTP
Por qué existe este RFC
SMTP estándar es un protocolo estricto de solicitud-respuesta. El cliente envía un comando, espera la respuesta del servidor y luego envía el siguiente. Cada viaje de ida y vuelta añade latencia, especialmente en enlaces de red de alta latencia. Para un mensaje con 50 destinatarios, el cliente necesitaría 50 viajes de ida y vuelta separados solo para los comandos RCPT TO.
RFC 2920 define la extensión SMTP PIPELINING, que permite al cliente enviar múltiples comandos en lote sin esperar respuestas individuales. El servidor almacena en buffer y procesa los comandos en orden, luego envía todas las respuestas. Esto reduce dramáticamente el tiempo total de una sesión SMTP.
Pipelining es una de las extensiones SMTP más ampliamente soportadas. Casi todo servidor de correo moderno la anuncia, y la mayoría de las bibliotecas de cliente SMTP la utilizan por defecto.
Cómo funciona
- El cliente envía
EHLOy confirma que el servidor anunciaPIPELININGen su lista de capacidades. - El cliente agrupa comandos que son seguros para pipelining — típicamente
MAIL FROM, uno o másRCPT TO, yDATA. - El cliente envía todos estos comandos en rápida sucesión sin esperar respuestas individuales.
- El servidor procesa cada comando en orden y envía una respuesta por comando, en orden.
- El cliente lee todas las respuestas y maneja cualquier error (por ejemplo, un destinatario rechazado).
Ejemplo SMTP
Sin pipelining (5 viajes de ida y vuelta para la envoltura):
Con pipelining (1 viaje de ida y vuelta para la envoltura completa):
Detalles técnicos clave
Qué comandos pueden ser pipelined
No todos los comandos SMTP son seguros para pipelining. RFC 2920 divide los comandos en dos categorías:
| Seguro para pipelining | Debe esperar respuesta |
|---|---|
MAIL FROM |
EHLO / HELO
|
RCPT TO |
STARTTLS |
DATA |
AUTH |
RSET |
QUIT |
NOOP |
contenido de DATA (el cuerpo con puntos escapados) |
Los comandos que cambian el estado de la conexión (EHLO, STARTTLS, AUTH) son puntos de sincronización — el cliente debe esperar la respuesta antes de enviar cualquier otra cosa.
Manejo de errores
Al hacer pipelining, algunos comandos en un lote pueden tener éxito mientras otros fallan. El cliente debe asociar respuestas a comandos en orden. Un RCPT TO rechazado no invalida toda la transacción — el mensaje aún se entrega a los destinatarios aceptados. Sin embargo, si MAIL FROM es rechazado, los comandos RCPT TO posteriores también fallarán.
Consideraciones de almacenamiento en búfer TCP
Pipelining depende del almacenamiento en búfer de TCP. El cliente escribe múltiples comandos al socket sin leer, confiando en que el búfer de envío TCP puede contenerlos. Para lotes muy grandes de comandos RCPT TO (cientos o miles), el cliente puede necesitar hacer pipelining en grupos para evitar llenar el búfer TCP y causar un interbloqueo.
Interacción con STARTTLS
Después de una respuesta EHLO que incluya STARTTLS, el cliente no debe hacer pipelining de STARTTLS con otros comandos. El protocolo de enlace TLS cambia el estado de toda la conexión, por lo que es un punto de sincronización duro. Después de que TLS se establece y se envía un nuevo EHLO, el pipelining puede reanudarse.
Errores comunes
- Hacer pipelining de EHLO o STARTTLS con otros comandos. Estos son puntos de sincronización. Hacer pipelining de ellos causa errores de protocolo porque la respuesta del servidor cambia el estado de sesión del que dependen los comandos posteriores.
- No leer todas las respuestas antes de actuar sobre errores. Si haces pipelining de 5 comandos, debes leer las 5 respuestas, incluso si la primera es un error. Abandonar el flujo de respuesta corrompe el estado del protocolo.
-
Asumir que todos los servidores soportan pipelining. Aunque es casi universal, pipelining es una extensión. Siempre verifica la respuesta
EHLOporPIPELININGantes de usarlo. Vuelve al modo uno-a-uno si está ausente. -
Hacer pipelining después de que MAIL FROM es rechazado. Si
MAIL FROMes rechazado y ya has hecho pipelining de comandosRCPT TO, todos fallarán. Lee la respuestaMAIL FROMantes de hacer pipelining de destinatarios, o prepárate para manejar fallos en cascada. -
Enviar contenido DATA en el pipeline. El comando
DATAmismo puede ser pipelined, pero el cuerpo del mensaje que sigue no puede. Debes esperar la respuesta354aDATAantes de enviar el contenido del mensaje.
Impacto en la entregabilidad
- Entrega más rápida para mensajes con múltiples destinatarios. Pipelining reduce un mensaje de N destinatarios de N+2 viajes de ida y vuelta a aproximadamente 2 viajes para la fase de envoltura. En conexiones de alta latencia, esto ahorra segundos por mensaje.
- Mayor rendimiento para envío masivo. Al enviar muchos mensajes a través de la misma conexión, pipelining te permite superponer la envoltura del siguiente mensaje con la transferencia de datos del actual, maximizando la utilización de la conexión.
- Reducción del tiempo de conexión. Las sesiones más cortas significan menos tiempo manteniendo conexiones abiertas. Esto es importante para servidores que aplican límites de tiempo por conexión o límites de velocidad basados en la duración de la conexión.
- Mejor comportamiento bajo carga. Pipelining reduce el número de viajes de ida y vuelta de red, lo que reduce la carga en los servidores de envío y recepción. Esto hace que tu infraestructura de envío sea más eficiente.
-
El rechazo por destinatario aún funciona. Pipelining no reduce la capacidad del servidor de rechazar destinatarios individuales. Cada
RCPT TOaún obtiene su propio código de respuesta, por lo que el manejo de rebotes funciona exactamente igual.