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