Yahoo Groups archive

Milter-greylist

Index last updated: 2026-04-28 23:32 UTC

Message

Re: [milter-greylist] IP address binding

2004-06-15 by Cyril Guibourg

Emmanuel Dreyfus <manu@...> writes:

> It's not possible yet, though it is not a difficult feature to add.

I started to play with it and got something working. At this time a [-i addr]
cmd arg changes the default bind to INADD_ANY behaviour.

I choosen to make the code in sync.c to use getaddrinfo() if it is available.
For now, only sync_master() uses it. If you agree with the mods I propose to
continue working on it so that peer_connect() also uses getaddrinfo() if
available. For systems without getaddrinfo() the code uses the old socket API.

$ ps ax|grep milter
 8521  ??  SsJ    0:00.20 /usr/local/bin/milter-greylist -P /var/run/milter-gre
15790  p2  S+     0:00.02 ./milter-greylist -Dv -i 127.0.0.1 -f /milter/greylis
15796  p3  R+     0:00.00 grep milter (bash)
$ sockstat|grep milter
cyril    milter-g 15790    7 tcp4   127.0.0.1:5252        *:*                  
cyril    milter-g 15790    5 dgram  syslogd[8365]:3                            
cyril    milter-g 15790    6 stream /milter/sock          
$ telnet 127.0.0.1 5252
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
106 You have no permission to talk, go away!
Connection closed by foreign host.



--- milter-greylist.c.orig	Wed May 26 23:50:13 2004
+++ milter-greylist.c	Tue Jun 15 22:43:04 2004
@@ -79,6 +79,8 @@
 static char *gmtoffset(time_t *, char *, size_t);
 static void writepid(char *);
 
+char	*listen_addr = NULL;
+
 struct smfiDesc smfilter =
 {
 	"greylist",	/* filter name */
@@ -515,7 +517,7 @@
 	/* 
 	 * Process command line options 
 	 */
-	while ((ch = getopt(argc, argv, "Aa:vDd:qw:f:hp:P:Tu:rSL:")) != -1) {
+	while ((ch = getopt(argc, argv, "Aa:vDd:qw:f:hp:P:Tu:rSL:i:")) != -1) {
 		switch (ch) {
 		case 'A':
 			defconf.c_noauth = 1;
@@ -658,6 +660,16 @@
 			defconf.c_forced |= C_TESTMODE;
 			break;
 
+
+		case 'i':
+			if (optarg == NULL) {
+				fprintf(stderr, "%s: -i needs an argument\n",
+				    argv[0]);
+				usage(argv[0]);
+			}
+			listen_addr = optarg;
+			break;
+
 		case 'h':
 		default:
 			usage(argv[0]);
@@ -806,8 +818,9 @@
 	char *progname;
 {
 	fprintf(stderr, 
-	    "usage: %s [-ADvqST] [-a autowhite] [-d dumpfile] [-f configfile]\n"
-	    "       [-w delay] [-u username] [-L cidrmask] -p socket\n", 
+	   "usage: %s [-ADvqST] [-a autowhite] [-d dumpfile] [-f configfile]\n"
+	   "       [-w delay] [-u username] [-L cidrmask] [-i listen-addr]"
+	   "-p socket\n", 
 	    progname);
 	exit(EX_USAGE);
 }



--- sync.h.orig	Tue Jun 15 22:45:21 2004
+++ sync.h	Tue Jun  8 16:47:47 2004
@@ -41,7 +41,13 @@
 #define LINELEN 512
 
 #define MXGLSYNC_NAME "mxglsync"
-#define MXGLSYNC_PORT 5252
+
+#ifdef AI_PASSIVE
+#   define HAS_GETADDRINFO
+#   define MXGLSYNC_PORT "5252"
+#else
+#   define MXGLSYNC_PORT 5252
+#endif
 
 #define MXGLSYNC_BACKLOG 5 /* Maximum connexions */
 




--- sync.c.orig	Tue Jun  8 16:47:47 2004
+++ sync.c	Tue Jun 15 22:29:49 2004
@@ -287,7 +287,11 @@
 	}
 
 	if ((se = getservbyname(MXGLSYNC_NAME, "tcp")) == NULL)
+#ifdef HAS_GETADDRINFO
+		service = atoi(MXGLSYNC_PORT);
+#else
 		service = MXGLSYNC_PORT;
+#endif
 	else
 		service = se->s_port;
 
@@ -402,14 +406,37 @@
 sync_master(dontcare)
 	void *dontcare;
 {
+
+	extern char *listen_addr;
+
+#ifdef HAS_GETADDRINFO
+	/*
+	char *service;
+	*/
+	int err;
+	struct addrinfo hints, *addr_info;
+#else
 	struct protoent *pe;
 	struct servent *se;
+	struct hostent *hp;
 	int proto;
 	struct sockaddr_in laddr;
 	int service;
+#endif
 	int optval;
 	int s;
 
+#ifdef HAS_GETADDRINFO
+
+	if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+		syslog(LOG_ERR, "cannot start MX sync, socket failed: %s", 
+		    strerror(errno));
+		sync_master_runs = 0;
+		return NULL;
+	}
+
+#else
+
 	if ((pe = getprotobyname("tcp")) == NULL)
 		proto = 6;
 	else
@@ -427,6 +454,9 @@
 	else
 		service = se->s_port;
 
+#endif /* HAS_GETADDRINFO */
+
+
 	optval = 1;
 	if ((setsockopt(s, SOL_SOCKET, SO_REUSEADDR, 
 	    &optval, sizeof(optval))) != 0) {
@@ -441,13 +471,62 @@
 		    strerror(errno));
 	}
 
+
+#ifdef HAS_GETADDRINFO
+	
+	bzero(&hints, sizeof(hints));
+	hints.ai_family = PF_INET;
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_flags = AI_PASSIVE;
+
+	/*
+	 * First we try port number by service name and if
+	 * not found we use hard coded default portnum.
+	 */
+	if ((err = getaddrinfo(listen_addr, MXGLSYNC_NAME,
+			       &hints, &addr_info)) == EAI_SERVICE)
+	  err = getaddrinfo(listen_addr, MXGLSYNC_PORT, &hints, &addr_info);
+
+	if (err) {
+	  syslog(LOG_ERR, "get_socket: getaddrinfo failed: %s",
+		 gai_strerror(err));
+	  sync_master_runs = 0;
+	  close(s);
+	  return NULL;
+	}
+
+	if (bind(s, addr_info->ai_addr, addr_info->ai_addrlen) < 0) {
+	  syslog(LOG_ERR, "cannot start MX sync, bind failed: %s",
+		 strerror(errno)); 
+	  freeaddrinfo(addr_info);
+	  sync_master_runs = 0;
+	  close(s);
+	  return NULL;
+	}
+
+	freeaddrinfo(addr_info);
+
+#else
+
 	bzero((void *)&laddr, sizeof(laddr));
 #ifdef HAVE_SA_LEN
 	laddr.sin_len = sizeof(laddr);
 #endif
 	laddr.sin_family = AF_INET;
 	laddr.sin_port = htons(service);
-	laddr.sin_addr.s_addr = INADDR_ANY;
+
+	if (listen_addr && *listen_addr) {
+	  if ((hp = gethostbyname(listen_addr)) == NULL) {
+            syslog(LOG_ERR, "can't gethostbyname %s\n", listen_addr);
+	    sync_master_runs = 0;
+	    close(s);
+	    return NULL;
+	  }
+	  endhostent();
+	  bcopy(hp->h_addr, &laddr.sin_addr.s_addr, hp->h_length);
+	} else {
+	  laddr.sin_addr.s_addr = htonl(INADDR_ANY);
+	}
 
 	if (bind(s, (struct sockaddr *)&laddr, sizeof(laddr)) != 0) {
 		syslog(LOG_ERR, "cannot start MX sync, bind failed: %s", 
@@ -456,6 +535,9 @@
 		close(s);
 		return NULL;
 	}
+
+#endif /* HAS_GETADDRINFO */
+
 
 	if (listen(s, MXGLSYNC_BACKLOG) != 0) {
 		syslog(LOG_ERR, "cannot start MX sync, listen failed: %s",

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.