Últimos Cambios |
||
Blog personal: El hilo del laberinto |
Última Actualización: 18 de octubre de 2005 - Martes
Los parches anteriores han estado funcionando a la perfección durante años. Pero la experiencia ha puesto en evidencia los siguientes problemas:
Estos problemas están causados, en realidad, por un abuso del sistema. La tecnología de envío diferido se diseñó como un medio para garantizar la calidad de servicio en las horas puntas, relegando el tráfico menos prioritario y menos sensible al retardo (el correo) a horas de baja utilización. Que se haya venido usando esta tecnología para programar explícitamente el envío de mensajes cuyo tiempo de llegada sea importante y delicado es un efecto secundario no intencionado.
Pero nos consta que el servicio de envío diferido es útil y está siendo utilizado de forma activa por parte de nuestros usuarios, por lo que nos hemos decidio a implementar un servicio de envío diferido "de verdad".
Más información en un boletín enviado a los usuarios de Argo:
El siguiente parche incluye a los anteriores, pero proporcionando una solución a los problemas descritos:
Index: sendmail/deliver.c =================================================================== --- sendmail/deliver.c (.../tags/sendmail-8.13.5) (revision 391) +++ sendmail/deliver.c (.../branches/sendmail-8.13.5-jcea) (revision 391) @@ -68,6 +68,13 @@ ENVELOPE *e; int mode; { +struct h { + char *host; + struct h *siguiente; +} *p=NULL,*p2; +unsigned long tamanho_por_receptores; +HDR *cabecera; + register ADDRESS *q; char *owner; int otherowners; @@ -78,6 +85,97 @@ bool somedeliveries = false, expensive = false; pid_t pid; + +/* +** jcea@argo.es - 18/May/99 +** +** Manda los mensajes largos por la noche +*/ + char hora[20]; + time_t tiempo,tiempo2; + int envio_diferido=0; + + +#define TAMANO_MAXIMO 2000000 + +/* +** jcea@argo.es - 24/may/05 +** +** Los mensajes marcados como de envio "diferido" deben procesarse apropiadamente +*/ + tiempo=time(NULL); + cftime(hora,"%H",&tiempo); + + for (q = e->e_sendqueue; q != NULL; q = q->q_next) { + if((strlen(q->q_user)==19) && (!strcasecmp("@envio_diferido",q->q_user+4)) && + ((q->q_user[0]>='0') && (q->q_user[0]<='9')) && + ((q->q_user[1]>='0') && (q->q_user[1]<='9')) && + ((q->q_user[2]>='0') && (q->q_user[2]<='5')) && + ((q->q_user[3]>='0') && (q->q_user[3]<='9'))) { + tiempo2=(e->e_ctime)+(q->q_user[0]-'0')*36000+(q->q_user[1]-'0')*3600+(q->q_user[2]-'0')*600+(q->q_user[3]-'0')*60; + if(tiempo<tiempo2) envio_diferido=1; + goto salida_envio_diferido; + } + } + salida_envio_diferido: + + tamanho_por_receptores=0; + if(((strcmp(hora,"02")<0) || (strcmp(hora,"07")>0)) && + (QueueLimitRecipient==NULL) && + (QueueLimitSender==NULL) && + (QueueLimitId==NULL)) { + for (q = e->e_sendqueue; q != NULL; q = q->q_next) { + if(!bitnset(M_LOCALMAILER,q->q_mailer->m_flags)) { + if(q->q_host!=NULL) { + p2=p; + while(p2!=NULL) { + if(!strcasecmp(p2->host,q->q_host)) goto siguiente_pasada; + p2=p2->siguiente; + } + p2=malloc(sizeof(struct h)); + if(p2!=NULL) { + p2->siguiente=p; + p=p2; + p->host=q->q_host; + } + } + tamanho_por_receptores+=e->e_msgsize; + } + siguiente_pasada: ; /* Para evitar error de compilacion en GCC 3.4 */ + } + } + + while(p!=NULL) { + p2=p->siguiente; + free(p); + p=p2; + } + +/* +** jcea@argo.es - 17/Jun/99 +** +** Si el mensaje es de baja prioridad, lo manda de noche. +*/ + for(cabecera = e->e_header; cabecera != NULL; cabecera = cabecera->h_link) { + /* Si tiene prioridad CINCO, lo larga de noche */ + if(strcasecmp(cabecera->h_field,"x-priority")==0) { + if(atoi(cabecera->h_value)==5) tamanho_por_receptores+=TAMANO_MAXIMO; + } + } + +/* +** jcea@argo.es - 17/Jun/99 +** +** Si el mensaje tiene alta prioridad, lo larga ya +*/ + for(cabecera = e->e_header; cabecera != NULL; cabecera = cabecera->h_link) { + /* Si tiene prioridad uno, lo larga YA */ + if(strcasecmp(cabecera->h_field,"x-priority")==0) { + if(atoi(cabecera->h_value)==1) tamanho_por_receptores=0; + } + } + + /* ** If this message is to be discarded, don't bother sending ** the message at all. @@ -368,6 +466,22 @@ q->q_state = QS_QUEUEUP; expensive = true; } + +/* +** jcea@argo.es - 18/May/99 +** +** Manda los mensajes largos por la noche +*/ + else if (!Verbose && (tamanho_por_receptores>TAMANO_MAXIMO) && + !bitnset(M_LOCALMAILER,q->q_mailer->m_flags)) + { + expensive=true; + q->q_state|=QS_QUEUEUP; + } + else if (!Verbose && envio_diferido) { + expensive=true; + q->q_state|=QS_QUEUEUP; + } else { if (tTd(13, 30))
Este parche incluye los anteriores, por lo que se mantienen las funcionalidades de envío nocturno y prioridad. Pero, adicionalmente, permite la programación de envíos diferidos de forma fiable y precisa.
Básicamente el sistema acepta mensajes entre cuyos destinatarios puede existir uno de la forma "HHMM@envio_diferido". Un mensaje marcado de esa forma se mantendrá en la cola, AL MENOS, durante HH horas y MM minutos. Una vez transcurrido ese tiempo, se procesará de forma normal, estando sujeto a posibles envíos nocturnos, entrega a destinatarios locales, etc.
Pero mientras no haya transcurrido ese tiempo, el mensaje no se entregará a destinos locales, ni se podrá forzar su salida de la cola de forma accidental. En caso de requerir un procesamiento explícito previo al retardo marcado, un administrador de sistemas deberá editar el mensaje directamente en la cola y eliminar el destinatario "marcador", manualmente.
Algunos detalles a tener en cuenta:
En el momento de escribir este documento, el parche lleva en producción unos seis meses, sin incidencias.
Más información sobre los OpenBadges
Donación BitCoin: 19niBN42ac2pqDQFx6GJZxry2JQSFvwAfS