1 /*++
2 /* NAME
3 /*	sane_connect 3
4 /* SUMMARY
5 /*	sanitize connect() results
6 /* SYNOPSIS
7 /*	#include <sane_connect.h>
8 /*
9 /*	int	sane_connect(sock, buf, len)
10 /*	int	sock;
11 /*	struct sockaddr	*buf;
12 /*	SOCKADDR_SIZE *len;
13 /* DESCRIPTION
14 /*	sane_connect() implements the connect(2) socket call, and maps
15 /*	known harmless error results to EAGAIN.
16 /* BUGS
17 /*	Bizarre systems may have other harmless error results. Such
18 /*	systems encourage programmers to ignore error results, and
19 /*	penalize programmers who code defensively.
20 /* LICENSE
21 /* .ad
22 /* .fi
23 /*	The Secure Mailer license must be distributed with this software.
24 /* AUTHOR(S)
25 /*	Wietse Venema
26 /*	IBM T.J. Watson Research
27 /*	P.O. Box 704
28 /*	Yorktown Heights, NY 10598, USA
29 /*--*/
30 
31 /* System library. */
32 
33 #include "sys_defs.h"
34 #include <sys/socket.h>
35 #include <errno.h>
36 
37 /* Utility library. */
38 
39 #include "msg.h"
40 #include "sane_connect.h"
41 
42 /* sane_connect - sanitize connect() results */
43 
sane_connect(int sock,struct sockaddr * sa,SOCKADDR_SIZE len)44 int     sane_connect(int sock, struct sockaddr *sa, SOCKADDR_SIZE len)
45 {
46 
47     /*
48      * XXX Solaris select() produces false read events, so that read() blocks
49      * forever on a blocking socket, and fails with EAGAIN on a non-blocking
50      * socket. Turning on keepalives will fix a blocking socket provided that
51      * the kernel's keepalive timer expires before the Postfix watchdog
52      * timer.
53      *
54      * XXX Work around NAT induced damage by sending a keepalive before an idle
55      * connection is expired. This requires that the kernel keepalive timer
56      * is set to a short time, like 100s.
57      */
58     if (sa->sa_family == AF_INET) {
59 	int     on = 1;
60 
61 	(void) setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
62 			  (void *) &on, sizeof(on));
63     }
64     return (connect(sock, sa, len));
65 }
66