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