RFC 3030 – SMTP BINARYMIME y CHUNKING
Por qué existe este RFC
SMTP tradicional usa el comando DATA para transferir contenido de mensajes. El cuerpo del mensaje se envía como una secuencia de texto, terminada por una línea que contiene solo un período (.\r\n). Este diseño tiene dos problemas:
- Sobrecarga de escape de punto: Cualquier línea en el mensaje que comience con un período debe escaparse agregando un período adicional. El servidor debe escanear cada línea para eliminar el escape. Esto agrega sobrecarga de procesamiento y puede introducir errores.
-
Sin soporte binario: El comando
DATAasume texto ASCII de 7 bits con finales de línea CRLF. El contenido binario (como archivos adjuntos) debe codificarse en Base64, lo que aumenta el tamaño de los datos aproximadamente un 33%.
RFC 3030 define dos extensiones relacionadas que solucionan estos problemas. CHUNKING introduce el comando BDAT, que transfiere datos en fragmentos de tamaño explícito, sin necesidad de escape de punto. BINARYMIME se construye sobre CHUNKING para permitir contenido binario sin procesar sin ninguna codificación.
Cómo funciona
CHUNKING (comando BDAT)
- El servidor anuncia
CHUNKINGen su respuesta EHLO. - En lugar de
DATA, el cliente usaBDAT <size>para enviar un fragmento de exactamente<size>octetos. - El servidor lee exactamente esa cantidad de bytes, luego envía una respuesta.
- El cliente puede enviar múltiples fragmentos
BDAT. El último fragmento incluye la palabra claveLAST:BDAT <size> LAST. - No se necesita escape de punto porque el tamaño es explícito.
BINARYMIME
- El servidor anuncia
CHUNKINGyBINARYMIMEen su respuesta EHLO. - El cliente declara
BODY=BINARYMIMEen el comandoMAIL FROM. - Los datos del mensaje se envían mediante
BDATy pueden contener contenido binario sin procesar, sin codificación Base64 ni requisitos de finales de línea CRLF.
Ejemplo SMTP
Envío de un mensaje usando BDAT en lugar de DATA:
Con BINARYMIME para contenido binario sin procesar:
Detalles técnicos clave
BDAT vs. DATA
| Aspecto | DATA | BDAT (CHUNKING) |
|---|---|---|
| Terminación |
.\r\n (punto en una línea por sí solo) |
Recuento de bytes explícito + palabra clave LAST |
| Escape de punto | Requerido | No necesario |
| Contenido binario | Debe estar codificado en Base64 | Binario sin procesar con BINARYMIME |
| Transmisión | El servidor escanea el terminador | El servidor lee el recuento de bytes exacto |
| Múltiples fragmentos | No aplicable | Sí, estado intermedio después de cada fragmento |
Tamaño de fragmento
No hay un tamaño de fragmento mandatorio. Los clientes típicamente eligen tamaños de fragmentos según la memoria disponible y condiciones de red. Las estrategias comunes incluyen enviar el mensaje completo como un único BDAT ... LAST, o dividir en fragmentos de unos cientos de kilobytes. Los fragmentos más pequeños permiten detección de errores intermedia; los fragmentos más grandes reducen la sobrecarga de protocolo.
Recuperación de errores
Si el servidor rechaza un fragmento BDAT (por ejemplo, mensaje demasiado grande), el cliente puede emitir BDAT 0 LAST para abortar la transacción limpiamente. Esto es más limpio que el modelo DATA, donde el cliente debe enviar el mensaje completo y el terminador de punto incluso si sabe que el servidor lo rechazará.
Reenvío de BINARYMIME
Un servidor que recibe un mensaje BINARYMIME no debe reenviarlo a un servidor que no sea compatible con BINARYMIME. Si el siguiente salto no anuncia BINARYMIME, el servidor de reenvío debe convertir partes de contenido binario a codificación Base64 antes de retransmitir. Este es un requisito crítico de interoperabilidad.
Errores comunes
-
Usar BDAT sin verificar CHUNKING. No todos los servidores admiten CHUNKING. Siempre verifica la respuesta EHLO antes de usar
BDAT. Si CHUNKING no se anuncia, retrocede aDATA. - Enviar BODY=BINARYMIME cuando el siguiente salto no lo admite. Si eres un servidor de retransmisión y el MTA descendente no anuncia BINARYMIME, debes recodificar partes binarias a Base64 antes de reenviar. Enviar binario sin procesar a un servidor que no lo entiende corrompe el mensaje.
-
Obtener el recuento de bytes incorrecto. El tamaño en
BDATdebe coincidir exactamente con el número de octetos que siguen. Enviar demasiados o muy pocos bytes desincroniza el protocolo y corrompe la sesión. -
Olvidar la palabra clave LAST. El fragmento
BDATfinal debe incluirLAST. Sin ella, el servidor espera más fragmentos y la sesión se cuelga. -
Mezclar BDAT y DATA. Un cliente debe usar
DATAoBDATpara un mensaje determinado, nunca ambos. Cambiar durante la transacción es un error de protocolo. -
No manejar errores de fragmento intermedio. Si un fragmento
BDATno final devuelve un error, el cliente debe enviarBDAT 0 LASTpara restablecer la transacción en lugar de continuar enviando datos.
Impacto en la entrega
- Ancho de banda reducido para archivos adjuntos binarios. BINARYMIME elimina la sobrecarga del 33% de la codificación Base64. Para un archivo adjunto de 10 MB, eso es ahorrar aproximadamente 3,3 MB de datos de transferencia. Esto es importante a escala.
- Procesamiento más rápido para mensajes grandes. BDAT con tamaños explícitos permite al servidor asignar memoria por adelantado y omitir escaneo línea por línea. Esto reduce la sobrecarga de CPU en ambos lados.
- Manejo de errores más limpio. Las respuestas de fragmentos intermedios permiten a los clientes detectar fallos temprano sin transmitir el mensaje completo. Esto ahorra ancho de banda y tiempo de conexión cuando un mensaje será rechazado.
- Amplio soporte entre proveedores principales. Google, Microsoft y la mayoría de plataformas de correo grandes admiten CHUNKING. Usarlo cuando esté disponible es una práctica recomendada para una entrega eficiente.
- Elimina errores de escape de punto. BDAT elimina una clase completa de posibles errores relacionados con el escape de punto y el manejo de finales de línea. Los mensajes llegan exactamente como se enviaron, byte por byte.