+ldap_int_timeval_dup( struct timeval **dest, const struct timeval *src )
+{
+ struct timeval *new;
+
+ assert( dest != NULL );
+
+ if (src == NULL) {
+ *dest = NULL;
+ return 0;
+ }
+
+ new = (struct timeval *) LDAP_MALLOC(sizeof(struct timeval));
+
+ if( new == NULL ) {
+ *dest = NULL;
+ return 1;
+ }
+
+ AC_MEMCPY( (char *) new, (const char *) src, sizeof(struct timeval));
+
+ *dest = new;
+ return 0;
+}
+
+static int
+ldap_pvt_ndelay_on(LDAP *ld, int fd)
+{
+ osip_debug(ld, "ldap_ndelay_on: %d\n",fd,0,0);
+ return ber_pvt_socket_set_nonblock( fd, 1 );
+}
+
+static int
+ldap_pvt_ndelay_off(LDAP *ld, int fd)
+{
+ osip_debug(ld, "ldap_ndelay_off: %d\n",fd,0,0);
+ return ber_pvt_socket_set_nonblock( fd, 0 );
+}
+
+static ber_socket_t
+ldap_int_socket(LDAP *ld, int family, int type )
+{
+ ber_socket_t s = socket(family, type, 0);
+ osip_debug(ld, "ldap_new_socket: %d\n",s,0,0);
+#ifdef FD_CLOEXEC
+ fcntl(s, F_SETFD, FD_CLOEXEC);
+#endif
+ return ( s );
+}
+
+static int
+ldap_pvt_close_socket(LDAP *ld, int s)
+{
+ osip_debug(ld, "ldap_close_socket: %d\n",s,0,0);
+ return tcp_close(s);
+}
+
+static int
+ldap_int_prepare_socket(LDAP *ld, int s, int proto )
+{
+ osip_debug( ld, "ldap_prepare_socket: %d\n", s, 0, 0 );
+
+#if defined( SO_KEEPALIVE ) || defined( TCP_NODELAY )
+ if ( proto == LDAP_PROTO_TCP ) {
+ int dummy = 1;
+#ifdef SO_KEEPALIVE
+ if ( setsockopt( s, SOL_SOCKET, SO_KEEPALIVE,
+ (char*) &dummy, sizeof(dummy) ) == AC_SOCKET_ERROR )
+ {
+ osip_debug( ld, "ldap_prepare_socket: "
+ "setsockopt(%d, SO_KEEPALIVE) failed (ignored).\n",
+ s, 0, 0 );
+ }
+ if ( ld->ld_options.ldo_keepalive_idle > 0 )
+ {
+#ifdef TCP_KEEPIDLE
+ if ( setsockopt( s, IPPROTO_TCP, TCP_KEEPIDLE,
+ (void*) &ld->ld_options.ldo_keepalive_idle,
+ sizeof(ld->ld_options.ldo_keepalive_idle) ) == AC_SOCKET_ERROR )
+ {
+ osip_debug( ld, "ldap_prepare_socket: "
+ "setsockopt(%d, TCP_KEEPIDLE) failed (ignored).\n",
+ s, 0, 0 );
+ }
+#else
+ osip_debug( ld, "ldap_prepare_socket: "
+ "sockopt TCP_KEEPIDLE not supported on this system.\n",
+ 0, 0, 0 );
+#endif /* TCP_KEEPIDLE */
+ }
+ if ( ld->ld_options.ldo_keepalive_probes > 0 )
+ {
+#ifdef TCP_KEEPCNT
+ if ( setsockopt( s, IPPROTO_TCP, TCP_KEEPCNT,
+ (void*) &ld->ld_options.ldo_keepalive_probes,
+ sizeof(ld->ld_options.ldo_keepalive_probes) ) == AC_SOCKET_ERROR )
+ {
+ osip_debug( ld, "ldap_prepare_socket: "
+ "setsockopt(%d, TCP_KEEPCNT) failed (ignored).\n",
+ s, 0, 0 );
+ }
+#else
+ osip_debug( ld, "ldap_prepare_socket: "
+ "sockopt TCP_KEEPCNT not supported on this system.\n",
+ 0, 0, 0 );
+#endif /* TCP_KEEPCNT */
+ }
+ if ( ld->ld_options.ldo_keepalive_interval > 0 )
+ {
+#ifdef TCP_KEEPINTVL
+ if ( setsockopt( s, IPPROTO_TCP, TCP_KEEPINTVL,
+ (void*) &ld->ld_options.ldo_keepalive_interval,
+ sizeof(ld->ld_options.ldo_keepalive_interval) ) == AC_SOCKET_ERROR )
+ {
+ osip_debug( ld, "ldap_prepare_socket: "
+ "setsockopt(%d, TCP_KEEPINTVL) failed (ignored).\n",
+ s, 0, 0 );
+ }
+#else
+ osip_debug( ld, "ldap_prepare_socket: "
+ "sockopt TCP_KEEPINTVL not supported on this system.\n",
+ 0, 0, 0 );
+#endif /* TCP_KEEPINTVL */
+ }
+#endif /* SO_KEEPALIVE */
+#ifdef TCP_NODELAY
+ if ( setsockopt( s, IPPROTO_TCP, TCP_NODELAY,
+ (char*) &dummy, sizeof(dummy) ) == AC_SOCKET_ERROR )
+ {
+ osip_debug( ld, "ldap_prepare_socket: "
+ "setsockopt(%d, TCP_NODELAY) failed (ignored).\n",
+ s, 0, 0 );
+ }
+#endif /* TCP_NODELAY */
+ }
+#endif /* SO_KEEPALIVE || TCP_NODELAY */
+
+ return 0;
+}
+
+#ifndef HAVE_WINSOCK
+
+#undef TRACE
+#define TRACE do { \
+ osip_debug(ld, \
+ "ldap_is_socket_ready: error on socket %d: errno: %d (%s)\n", \
+ s, \
+ errno, \
+ sock_errstr(errno) ); \
+} while( 0 )
+