Lloyd Zusman <[EMAIL PROTECTED]> writes:

> [ ... ]
>
> I use the following for my unique ID, encoded into base 64:
>
>   32-bit IP address
>   32-bit PID of "submit" (some systems use more than 16 bits for this)
>   64-bit time from gettimeofday() [down to microseconds]
>   32-bit incrementing counter
>
> [ ... ]
>
> Hmm ... I now realize that I don't need the incrementing counter, since
> there will be only one message processed per call to "submit".  I will
> remove it from my code and repost another patch once I test it.

I now have changed the way I construct the unique ID:

  128-bit IP address [*]
  32-bit PID of "submit"
  64-bit time from gettimeofday()

  [*] If IPv6 is enabled, this is an in6_addr; otherwise, it's
      an in_addr padded with high-order zeros to 128 bits.

This is encoded into base64, resulting in a 38-character ID.  Look at
the 3rd line of this header for an example:

  Received: from hiram.io.com (hiram.io.com [::ffff:199.170.88.27])
    (IDENT: root)
    id AAAAAAAAAAAAAP@@2LYK%vYWAAAy5CxAe3oMAA
    by asfast.net with esmtp; Fri, 13 Feb 2004 09:50:26 -0500

Attached is the latest patch.

Please look this over and see if you notice any problems.  Thanks.


*** courier/submit.C.orig	Mon Dec 15 20:51:29 2003
--- courier/submit.C	Fri Feb 13 09:19:23 2004
***************
*** 12,17 ****
--- 12,18 ----
  #include	"rfc2045/rfc2045charset.h"
  #include	"rfc1035/rfc1035.h"
  #include	"rfc1035/rfc1035mxlist.h"
+ #include	"rfc2045/rfc2045.h"
  #include	"numlib/numlib.h"
  #include	"dbobj.h"
  #include	"afx.h"
***************
*** 35,41 ****
--- 36,52 ----
  #if	HAVE_UNISTD_H
  #include	<unistd.h>
  #endif
+ #if	TIME_WITH_SYS_TIME
+ #include 	<sys/time.h>
  #include	<time.h>
+ #else
+ #if	HAVE_SYS_TIME_H
+ #include	<sys/time.h>
+ #else
+ #include	<time.h>
+ #endif
+ #endif
+ #include	<netdb.h>
  
  #define	TIMEOUT	1800
  
***************
*** 935,940 ****
--- 946,1041 ----
  static void getrcpt(struct rw_info *rwi);
  static void rcpttoerr(int, const char *, struct rw_info *);
  
+ struct unique_id_buffer
+ {
+ #if	!RFC1035_IPV6
+ 	RFC1035_ADDR dummy[3];
+ #endif
+ 	RFC1035_ADDR ip;
+ 	int pid;
+ 	struct timeval calltime;
+ };
+ #define UNIQUE_BUFFER_SIZE (sizeof (unique_id_buffer))
+ 
+ static int write_unique_bytes(const char *p, size_t l, void *vp)
+ {
+ char **cp = (char **) vp;
+ 
+ 	while (l > 0)
+ 	{
+ 		switch (*p)
+ 		{
+ 		case '\r':
+ 		case '\n':
+ 		case '=':
+ 			p++;
+ 			l--;
+ 			continue;
+ 		case '/':
+ 			*p++;
+ 			**cp = '@';
+ 			break;
+ 		case '+':
+ 			*p++;
+ 			**cp = '%';
+ 			break;
+ 		default:
+ 			**cp = *p++;
+ 			break;
+ 		}
+ 		++*cp;
+ 		l--;
+ 	}
+ 
+ 	return 0;
+ }
+ 
+ static char* unique_id()
+ {
+ static char result[ (UNIQUE_BUFFER_SIZE + 3) / 3 * 4 + 1 ];
+ 
+ struct unique_id_buffer unique_id_buff;
+ char* rp = result;
+ struct rfc2045_encode_info encodeInfo;
+ char hostbuff[256];
+ RFC1035_ADDR *addrs;
+ unsigned int naddrs;
+ 
+ 	gethostname(hostbuff, sizeof (hostbuff) - 1);
+ 	int rc = rfc1035_a(&rfc1035_default_resolver, hostbuff, &addrs,
+ 			   &naddrs);
+ 
+ 	if (rc == 0 || addrs == NULL || naddrs < 1)
+ 	{
+ #if	!RFC1035_IPV6
+ 		unique_id_buff.ipdummy[0] = 0;
+ 		unique_id_buff.ipdummy[1] = 0;
+ 		unique_id_buff.ipdummy[2] = 0;
+ #endif
+ 		memcpy((char*) &unique_id_buff.ip, (char*) &addrs[0], 
+ 		       sizeof (unique_id_buff.ip));
+ 
+ 	}
+ 	else
+ 	{
+ 
+ 		memset((char*) &unique_id_buff.ip, 0xff, 
+ 		       sizeof (unique_id_buff.ip));
+ 	}
+ 
+ 	unique_id_buff.pid = getpid();
+ 
+ 	gettimeofday(&unique_id_buff.calltime, NULL);
+ 
+ 	rfc2045_encode_start(&encodeInfo, "base64", &write_unique_bytes, &rp);
+ 	rfc2045_encode(&encodeInfo, (char*) &unique_id_buff, 
+ 		       UNIQUE_BUFFER_SIZE);
+ 	rfc2045_encode_end(&encodeInfo);
+ 	*rp = 0;
+ 
+ 	return (result);
+ }
+ 
  static void getrcpts(struct rw_info *rwi)
  {
  struct mailfrominfo *mf=(struct mailfrominfo *)rwi->udata;
***************
*** 1087,1092 ****
--- 1188,1197 ----
  		line += identinfo;
  		line += ')';
  	}
+ 
+ 	// Now, always insert a unique ID
+ 	line += "\n  id ";
+ 	line += unique_id();
  
  	line += "\n  by ";
  	line += config_me();

-- 
 Lloyd Zusman
 [EMAIL PROTECTED]

Reply via email to