Selaa lähdekoodia

[206724] Replacing PR_SetNetAddr with PRLDAP_SET_PORT for IPv6 support
slapi-private.h: introduced PRLDAP_SET_PORT to set port to the port field in
PRNetAddr. A copy of the same macro in LDAP C SDK (v6). Note: once NSPR
provides an equivalent API, we may want to replace this macro with the one.
(the NSPR compatibility issue remains, though.)
connection.c, daemon.c: replaced PR_SetNetAddr with PRLDAP_SET_PORT.

Noriko Hosoi 19 vuotta sitten
vanhempi
sitoutus
8afc3ccec0
3 muutettua tiedostoa jossa 164 lisäystä ja 163 poistoa
  1. 109 104
      ldap/servers/slapd/connection.c
  2. 39 59
      ldap/servers/slapd/daemon.c
  3. 16 0
      ldap/servers/slapd/slapi-private.h

+ 109 - 104
ldap/servers/slapd/connection.c

@@ -43,7 +43,6 @@
 #include <sys/socket.h>
 #include <stdlib.h>
 #endif
-#define TCPLEN_T	int
 #include <signal.h>
 #include "slap.h"
 #include "prcvar.h"
@@ -64,7 +63,6 @@ static void op_copy_identity(Connection *conn, Operation *op);
 static int is_ber_too_big(const Connection *conn, ber_len_t ber_len);
 static void log_ber_too_big_error(const Connection *conn,
 				ber_len_t ber_len, ber_len_t maxbersize);
-static int add_to_select_set(Connection *conn);
 
 /*
  * We maintain a global work queue of Slapi_PBlock's that have not yet
@@ -206,11 +204,10 @@ void
 connection_reset(Connection* conn, int ns, PRNetAddr * from, int fromLen, int is_SSL)
 {
     char *		pTmp = is_SSL ? "SSL " : "";
-    TCPLEN_T		addrlen, destaddrlen;
-    struct sockaddr_in	addr, destaddr;
-    char		*str_ip, *str_destip, buf_ip[ 256 ], buf_destip[ 256 ];
+    char		*str_ip = NULL, *str_destip;
+    char		buf_ip[ 256 ], buf_destip[ 256 ];
     char		*str_unknown = "unknown";
-	int			in_referral_mode = config_check_referral_mode();
+    int			in_referral_mode = config_check_referral_mode();
 
     LDAPDebug( LDAP_DEBUG_CONNS, "new %sconnection on %d\n", pTmp, conn->c_sd, 0 );
 
@@ -220,120 +217,127 @@ connection_reset(Connection* conn, int ns, PRNetAddr * from, int fromLen, int is
     PR_Unlock( num_conns_mutex );
 
     if (! in_referral_mode) {
-		PR_AtomicIncrement(g_get_global_snmp_vars()->ops_tbl.dsConnectionSeq);
-		PR_AtomicIncrement(g_get_global_snmp_vars()->ops_tbl.dsConnections);
+	PR_AtomicIncrement(g_get_global_snmp_vars()->ops_tbl.dsConnectionSeq);
+	PR_AtomicIncrement(g_get_global_snmp_vars()->ops_tbl.dsConnections);
     }
 
-    /* get peer address (IP address of this client) */
-    addrlen = sizeof( addr );
-    memset( &addr, 0, addrlen );
-
-    if ( ((from->ipv6.ip.pr_s6_addr32[0] != 0) || 
+    /* 
+     * get peer address (IP address of this client)
+     */
+    slapi_ch_free( (void**)&conn->cin_addr ); /* just to be conservative */
+    if ( ((from->ipv6.ip.pr_s6_addr32[0] != 0) || /* from contains non zeros */
 	  (from->ipv6.ip.pr_s6_addr32[1] != 0) || 
 	  (from->ipv6.ip.pr_s6_addr32[2] != 0) || 
 	  (from->ipv6.ip.pr_s6_addr32[3] != 0)) || 
 	 ((conn->c_prfd != NULL) && (PR_GetPeerName( conn->c_prfd, from ) == 0)) ) {
-                conn->cin_addr = (PRNetAddr *) slapi_ch_malloc( sizeof( PRNetAddr ) );
-		memcpy( conn->cin_addr, from, sizeof( PRNetAddr ) );
+	conn->cin_addr = (PRNetAddr *) slapi_ch_malloc( sizeof( PRNetAddr ) );
+	memcpy( conn->cin_addr, from, sizeof( PRNetAddr ) );
 		
-		if ( PR_IsNetAddrType( conn->cin_addr, PR_IpAddrV4Mapped ) ) {
-		     PRNetAddr v4addr;
-		     memset( &v4addr, 0, sizeof( v4addr ) );
-		     v4addr.inet.family = PR_AF_INET;
-		     v4addr.inet.ip = conn->cin_addr->ipv6.ip.pr_s6_addr32[3];
-		     PR_NetAddrToString( &v4addr, buf_ip, sizeof( buf_ip ) );
-		} else {
-		     PR_NetAddrToString( conn->cin_addr, buf_ip, sizeof( buf_ip ) );
-		}
-		buf_ip[ sizeof( buf_ip ) - 1 ] = '\0';
-		str_ip = buf_ip;		        
-		
-    } else if ( (conn->c_prfd == NULL) && 
-		(getpeername( conn->c_sd, (struct sockaddr*)&addr, &addrlen ) == 0) ) {
-                conn->cin_addr = (PRNetAddr *)slapi_ch_malloc( sizeof( PRNetAddr ) );
+	if ( PR_IsNetAddrType( conn->cin_addr, PR_IpAddrV4Mapped ) ) {
+	     PRNetAddr v4addr;
+	     memset( &v4addr, 0, sizeof( v4addr ) );
+	     v4addr.inet.family = PR_AF_INET;
+	     v4addr.inet.ip = conn->cin_addr->ipv6.ip.pr_s6_addr32[3];
+	     PR_NetAddrToString( &v4addr, buf_ip, sizeof( buf_ip ) );
+	} else {
+	     PR_NetAddrToString( conn->cin_addr, buf_ip, sizeof( buf_ip ) );
+	}
+	buf_ip[ sizeof( buf_ip ) - 1 ] = '\0';
+	str_ip = buf_ip;		        
 		
-		if ( PR_SetNetAddr(PR_IpAddrNull, PR_AF_INET6, addr.sin_port, conn->cin_addr)
-		     != PR_SUCCESS ) {
-		        int oserr = PR_GetError();
-			LDAPDebug( LDAP_DEBUG_ANY, "PR_SetNetAddr() failed, "
-					SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
-					oserr, slapd_pr_strerror(oserr), 0 );
-		} else {
-		        PR_ConvertIPv4AddrToIPv6(addr.sin_addr.s_addr, &(conn->cin_addr->ipv6.ip));
-		}
-
-                /* copy string equivalent of address into a buffer to use for
-                 * logging since each call to inet_ntoa() returns a pointer to a
-                 * single thread-specific buffer (which prevents us from calling
-                 * inet_ntoa() twice in one call to slapi_log_access()).
-                 */
-                str_ip = inet_ntoa( addr.sin_addr );
-                strncpy( buf_ip, str_ip, sizeof( buf_ip ) - 1 );
-                buf_ip[ sizeof( buf_ip ) - 1 ] = '\0';
-                str_ip = buf_ip;
-
     } else {
-                str_ip = str_unknown;
-    }      
-
+	/* try syscall since "from" was not given and PR_GetPeerName failed */
+	/* a corner case */
+	struct sockaddr_in addr; /* assuming IPv4 */
+	socklen_t          addrlen;
+
+	addrlen = sizeof( addr );
+	memset( &addr, 0, addrlen );
+
+	if ( (conn->c_prfd == NULL) && 
+	     (getpeername( conn->c_sd, (struct sockaddr *)&addr, &addrlen )
+	      == 0) ) {
+	    conn->cin_addr = (PRNetAddr *)slapi_ch_malloc( sizeof( PRNetAddr ));
+	    memset( conn->cin_addr, 0, sizeof( PRNetAddr ) );
+	    PR_NetAddrFamily( conn->cin_addr ) = AF_INET6;
+	    /* note: IPv4-mapped IPv6 addr does not work on Windows */
+	    PR_ConvertIPv4AddrToIPv6(addr.sin_addr.s_addr, &(conn->cin_addr->ipv6.ip));
+	    PRLDAP_SET_PORT(conn->cin_addr, addr.sin_port);
+
+	    /* copy string equivalent of address into a buffer to use for
+	     * logging since each call to inet_ntoa() returns a pointer to a
+	     * single thread-specific buffer (which prevents us from calling
+	     * inet_ntoa() twice in one call to slapi_log_access()).
+	     */
+	    str_ip = inet_ntoa( addr.sin_addr );
+	    strncpy( buf_ip, str_ip, sizeof( buf_ip ) - 1 );
+	    buf_ip[ sizeof( buf_ip ) - 1 ] = '\0';
+	    str_ip = buf_ip;
+	} else {
+	    str_ip = str_unknown;
+	}
+    }
 
     /*
      * get destination address (server IP address this client connected to)
      */
-    destaddrlen = sizeof( destaddr );
-    memset( &destaddr, 0, destaddrlen );
-			    
-
+    slapi_ch_free( (void**)&conn->cin_addr ); /* just to be conservative */
     if ( conn->c_prfd != NULL ) {
-                conn->cin_destaddr = (PRNetAddr *) slapi_ch_malloc( sizeof( PRNetAddr ) );
-		if (PR_GetSockName( conn->c_prfd, conn->cin_destaddr ) == 0) {
-		        if ( PR_IsNetAddrType( conn->cin_destaddr, PR_IpAddrV4Mapped ) ) {
-			     PRNetAddr v4destaddr;
-			     memset( &v4destaddr, 0, sizeof( v4destaddr ) );
-			     v4destaddr.inet.family = PR_AF_INET;
-			     v4destaddr.inet.ip = conn->cin_destaddr->ipv6.ip.pr_s6_addr32[3];
-			     PR_NetAddrToString( &v4destaddr, buf_destip, sizeof( buf_destip ) );
-			} else {
-			     PR_NetAddrToString( conn->cin_destaddr, buf_destip, sizeof( buf_destip ) );
-			}
-			buf_destip[ sizeof( buf_destip ) - 1 ] = '\0';
-			str_destip = buf_destip;		        
-		} else {
-		        str_destip = str_unknown;
-		}
-    } else if ( (conn->c_prfd == NULL) && 
-		(getsockname( conn->c_sd, (struct sockaddr*)&destaddr, &destaddrlen ) == 0) ) {
-                conn->cin_destaddr = (PRNetAddr *)slapi_ch_malloc( sizeof( PRNetAddr ) );
-		
-		if ( PR_SetNetAddr(PR_IpAddrNull, PR_AF_INET6, destaddr.sin_port, conn->cin_destaddr)
-		     != PR_SUCCESS ) {
-		        int oserr = PR_GetError();
-			LDAPDebug( LDAP_DEBUG_ANY, "PR_SetNetAddr() failed, "
-					SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
-					oserr, slapd_pr_strerror(oserr), 0 );
-		} else {
-		        PR_ConvertIPv4AddrToIPv6(destaddr.sin_addr.s_addr, &(conn->cin_destaddr->ipv6.ip));
-		}
-
-                /* copy string equivalent of address into a buffer to use for
-                 * logging since each call to inet_ntoa() returns a pointer to a
-                 * single thread-specific buffer (which prevents us from calling
-                 * inet_ntoa() twice in one call to slapi_log_access()).
-                 */
-                str_destip = inet_ntoa( destaddr.sin_addr );
-                strncpy( buf_destip, str_destip, sizeof( buf_destip ) - 1 );
-                buf_destip[ sizeof( buf_destip ) - 1 ] = '\0';
-                str_destip = buf_destip;
-     
+	conn->cin_destaddr = (PRNetAddr *) slapi_ch_malloc( sizeof( PRNetAddr ) );
+	memset( conn->cin_destaddr, 0, sizeof( PRNetAddr ));
+	if (PR_GetSockName( conn->c_prfd, conn->cin_destaddr ) == 0) {
+	    if ( PR_IsNetAddrType( conn->cin_destaddr, PR_IpAddrV4Mapped ) ) {
+		PRNetAddr v4destaddr;
+		memset( &v4destaddr, 0, sizeof( v4destaddr ) );
+		v4destaddr.inet.family = PR_AF_INET;
+		v4destaddr.inet.ip = conn->cin_destaddr->ipv6.ip.pr_s6_addr32[3];
+		PR_NetAddrToString( &v4destaddr, buf_destip, sizeof( buf_destip ) );
+	    } else {
+		PR_NetAddrToString( conn->cin_destaddr, buf_destip, sizeof( buf_destip ) );
+	    }
+	    buf_destip[ sizeof( buf_destip ) - 1 ] = '\0';
+	    str_destip = buf_destip;		        
+	} else {
+	    str_destip = str_unknown;
+	}
     } else {
-                str_destip = str_unknown;
-    }      
+	/* try syscall since c_prfd == NULL */
+	/* a corner case */
+	struct sockaddr_in	destaddr; /* assuming IPv4 */
+	socklen_t		destaddrlen;
+
+	destaddrlen = sizeof( destaddr );
+	memset( &destaddr, 0, destaddrlen );
+	if ( (getsockname( conn->c_sd, (struct sockaddr *)&destaddr,
+					&destaddrlen ) == 0) ) {
+	    conn->cin_destaddr =
+		    (PRNetAddr *)slapi_ch_malloc( sizeof( PRNetAddr ));
+	    memset( conn->cin_destaddr, 0, sizeof( PRNetAddr ));
+	    PR_NetAddrFamily( conn->cin_destaddr ) = AF_INET6;
+	    PRLDAP_SET_PORT( conn->cin_destaddr, destaddr.sin_port );
+	    /* note: IPv4-mapped IPv6 addr does not work on Windows */
+	    PR_ConvertIPv4AddrToIPv6(destaddr.sin_addr.s_addr,
+				     &(conn->cin_destaddr->ipv6.ip));
+
+	    /* copy string equivalent of address into a buffer to use for
+	     * logging since each call to inet_ntoa() returns a pointer to a
+	     * single thread-specific buffer (which prevents us from calling
+	     * inet_ntoa() twice in one call to slapi_log_access()).
+	     */
+	    str_destip = inet_ntoa( destaddr.sin_addr );
+	    strncpy( buf_destip, str_destip, sizeof( buf_destip ) - 1 );
+	    buf_destip[ sizeof( buf_destip ) - 1 ] = '\0';
+	    str_destip = buf_destip;
+	} else {
+	    str_destip = str_unknown;
+	}      
+    }
 
 
-	if ( !in_referral_mode ) {
-		/* create a sasl connection */
-		ids_sasl_server_new(conn);
-	}
+    if ( !in_referral_mode ) {
+	/* create a sasl connection */
+	ids_sasl_server_new(conn);
+    }
 
     /* log useful stuff to our access log */
     slapi_log_access( LDAP_DEBUG_STATS,
@@ -343,7 +347,7 @@ connection_reset(Connection* conn, int ns, PRNetAddr * from, int fromLen, int is
     /* initialize the remaining connection fields */
     conn->c_ldapversion = LDAP_VERSION3;
     conn->c_starttime = current_time();
-	conn->c_idlesince = conn->c_starttime;
+    conn->c_idlesince = conn->c_starttime;
     conn->c_flags = is_SSL ? CONN_FLAG_SSL : 0;
     conn->c_authtype = slapi_ch_strdup(SLAPD_AUTH_NONE);
 }
@@ -624,6 +628,7 @@ Operation *get_current_op(Connection *conn);
 static int handle_read_data(Connection *conn,Operation **op,
 	 int * connection_referenced);
 int queue_pushed_back_data(Connection *conn);
+static int add_to_select_set(Connection *conn);
 
 static void inc_op_count(Connection* conn)
 {

+ 39 - 59
ldap/servers/slapd/daemon.c

@@ -277,7 +277,7 @@ accept_and_configure(int s, PRFileDesc *pr_acceptfd, PRNetAddr *pr_netaddr,
 
 	PRIntervalTime pr_timeout = PR_MillisecondsToInterval(slapd_wakeup_timer);
 
-#if !defined( XP_WIN32 )
+#if !defined( XP_WIN32 ) /* UNIX */
 	(*pr_clonefd) = PR_Accept(pr_acceptfd, pr_netaddr, pr_timeout);
 	if( !(*pr_clonefd) ) {
 		PRErrorCode prerr = PR_GetError();
@@ -289,7 +289,7 @@ accept_and_configure(int s, PRFileDesc *pr_acceptfd, PRNetAddr *pr_netaddr,
 
 	ns = configure_pr_socket( pr_clonefd, secure );
 
-#else
+#else /* Windows */
 	if( secure ) {
 		(*pr_clonefd) = PR_Accept(pr_acceptfd, pr_netaddr, pr_timeout);
 		if( !(*pr_clonefd) ) {
@@ -315,10 +315,10 @@ accept_and_configure(int s, PRFileDesc *pr_acceptfd, PRNetAddr *pr_netaddr,
 
 		ns = configure_pr_socket( pr_clonefd, secure );
 
-	} else { 
-	        struct sockaddr *addr;
+	} else { /* !secure */
+		struct sockaddr *addr; /* NOT IPv6 enabled */
 
-			addr = (struct sockaddr *) slapi_ch_malloc( sizeof(struct sockaddr) );
+		addr = (struct sockaddr *) slapi_ch_malloc( sizeof(struct sockaddr) );
 		ns = accept (s, addr, (TCPLEN_T *)&addrlen);
 
 		if (ns == SLAPD_INVALID_SOCKET) {
@@ -329,25 +329,18 @@ accept_and_configure(int s, PRFileDesc *pr_acceptfd, PRNetAddr *pr_netaddr,
 				   s, oserr, slapd_system_strerror(oserr));
 		}
 
-        else if (syn_scan (ns))
-        {
-            /* this is a work around for accept problem with SYN scan on NT.
-            See bug 391414 for more details */
-            LDAPDebug(LDAP_DEBUG_ANY, "syn-scan request is received - ignored\n", 0, 0, 0);			    
-            closesocket (ns);
-            ns = SLAPD_INVALID_SOCKET;
-        }
-
-		if ( PR_SetNetAddr(PR_IpAddrNull, PR_AF_INET6, ((struct sockaddr_in *)addr)->sin_port, pr_netaddr)
-		     != PR_SUCCESS ) {
-			int oserr = PR_GetError();
-			LDAPDebug( LDAP_DEBUG_ANY, "PR_SetNetAddr() failed, "
-					SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
-					oserr, slapd_pr_strerror(oserr), 0 );
-		} else {
-		        PR_ConvertIPv4AddrToIPv6(((struct sockaddr_in *)addr)->sin_addr.s_addr, &(pr_netaddr->ipv6.ip));
+		else if (syn_scan (ns))
+		{
+			/* this is a work around for accept problem with SYN scan on NT.
+			See bug 391414 for more details */
+			LDAPDebug(LDAP_DEBUG_ANY, "syn-scan request is received - ignored\n", 0, 0, 0);				
+			closesocket (ns);
+			ns = SLAPD_INVALID_SOCKET;
 		}
 
+		PRLDAP_SET_PORT( pr_netaddr, ((struct sockaddr_in *)addr)->sin_port );
+		PR_ConvertIPv4AddrToIPv6(((struct sockaddr_in *)addr)->sin_addr.s_addr, &(pr_netaddr->ipv6.ip));
+
 		(*pr_clonefd) = NULL;
 
 		slapi_ch_free( (void **)&addr );
@@ -2278,7 +2271,7 @@ suppressed:
 
 
 static PRFileDesc *
-createprlistensocket(unsigned short port, const PRNetAddr *listenaddr,
+createprlistensocket(PRUint16 port, const PRNetAddr *listenaddr,
 		int secure)
 {
 	PRFileDesc			*sock;
@@ -2313,15 +2306,7 @@ createprlistensocket(unsigned short port, const PRNetAddr *listenaddr,
 
 	/* set up listener address, including port */
 	memcpy(&sa_server, listenaddr, sizeof(sa_server));
-	if ( PR_SetNetAddr(PR_IpAddrNull, PR_AF_INET6, port, &sa_server)
-				!= PR_SUCCESS ) {
-		prerr = PR_GetError();
-		slapi_log_error(SLAPI_LOG_FATAL, logname,
-				"PR_SetNetAddr() failed: %s error %d (%s)\n",
-				SLAPI_COMPONENT_NAME_NSPR,
-				prerr, slapd_pr_strerror(prerr));
-		goto failed;
-	}
+	PRLDAP_SET_PORT( &sa_server, port );
 
 	if ( PR_Bind(sock, &sa_server) == PR_FAILURE) {
 		prerr = PR_GetError();
@@ -2354,8 +2339,7 @@ slapd_listenhost2addr(const char *listenhost, PRNetAddr *addr)
 {
 	char			*logname = "slapd_listenhost2addr";
 	PRErrorCode		prerr = 0;
-	PRHostEnt		hent;
-	char			hbuf[ PR_NETDB_BUF_SIZE ];
+	int				rval = 0;
 
 	PR_ASSERT( addr != NULL );
 
@@ -2366,37 +2350,33 @@ slapd_listenhost2addr(const char *listenhost, PRNetAddr *addr)
 			slapi_log_error( SLAPI_LOG_FATAL, logname,
 					"PR_SetNetAddr(PR_IpAddrAny) failed - %s error %d (%s)\n",
 					SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror(prerr));
-			goto failed;
+			rval = -1;
 		}
 	} else if (PR_SUCCESS == PR_StringToNetAddr(listenhost, addr)) {
-		if (PR_AF_INET == PR_NetAddrFamily(addr)) {
-			PRUint32	ipv4ip = addr->inet.ip;
-			memset(addr, 0, sizeof(PRNetAddr));
-			PR_ConvertIPv4AddrToIPv6(ipv4ip, &addr->ipv6.ip);
-			addr->ipv6.family = PR_AF_INET6;
-		}
-	} else if (PR_SUCCESS == PR_GetIPNodeByName(listenhost,
-				PR_AF_INET6, PR_AI_DEFAULT | PR_AI_ALL,
-				hbuf, sizeof(hbuf), &hent )) {
-		/* just use the first IP address returned */
-		if (PR_EnumerateHostEnt(0, &hent, 0, addr) < 0) {
+		/* PR_StringNetAddr newer than NSPR v4.6.2 supports both IPv4&v6 */; 
+	} else {
+		PRAddrInfo *infop = PR_GetAddrInfoByName( listenhost,
+						PR_AF_UNSPEC, (PR_AI_ADDRCONFIG|PR_AI_NOCANONNAME) );
+		if ( NULL != infop ) {
+			memset( addr, 0, sizeof( PRNetAddr ));
+			if ( NULL == PR_EnumerateAddrInfo( NULL, infop, 0, addr )) {
+				slapi_log_error( SLAPI_LOG_FATAL, logname,
+					"PR_EnumerateAddrInfo for %s failed - %s error %d (%s)\n",
+					listenhost, SLAPI_COMPONENT_NAME_NSPR, prerr,
+					slapd_pr_strerror(prerr));
+				rval = -1;
+			}
+			PR_FreeAddrInfo( infop );
+		} else {
 			slapi_log_error( SLAPI_LOG_FATAL, logname,
-					"PR_EnumerateHostEnt() failed - %s error %d (%s)\n",
-					SLAPI_COMPONENT_NAME_NSPR, prerr, slapd_pr_strerror(prerr));
-			goto failed;
+					"PR_GetAddrInfoByName(%s) failed - %s error %d (%s)\n",
+					listenhost, SLAPI_COMPONENT_NAME_NSPR, prerr,
+					slapd_pr_strerror(prerr));
+			rval = -1;
 		}
-	} else {	/* failure */
-		slapi_log_error( SLAPI_LOG_FATAL, logname,
-				"PR_GetIPNodeByName(%s) failed - %s error %d (%s)\n",
-				listenhost, SLAPI_COMPONENT_NAME_NSPR, prerr,
-				slapd_pr_strerror(prerr));
-		goto failed;
 	}
 
-	return( 0 );
-
-failed:
-	return( -1 );
+	return rval;
 }
 
 

+ 16 - 0
ldap/servers/slapd/slapi-private.h

@@ -1236,6 +1236,22 @@ void    DS_Sleep(PRIntervalTime ticks);
 #define SLAPI_UPGRADEDB_SKIPINIT 0x2 /* call upgradedb as part of other op */
 #endif
 
+/*
+ * Macro to set port to the 'port' field of a NSPR PRNetAddr union.
+ ** INPUTS:
+ ** PRNetAddr *myaddr   A network address.
+ ** PRUint16   myport   port to set to the 'port' field of 'addr'.
+ ** RETURN: none
+ *
+ * Note: Copy from ldappr-int.h in
+ *   ldapcsdk:mozilla/directory/c-sdk/ldap/libraries/libprldap
+ * Introduced to avoid calling PR_SetNetAddr w/ PR_IpAddrNull just to set port.
+ * Once NSPR starts providing better function/macro to do the same job,
+ * this macro should be replaced with it. (newer than NSPR v4.6.2)
+ */
+#define PRLDAP_SET_PORT(myaddr,myport) \
+    ((myaddr)->raw.family == PR_AF_INET6 ? ((myaddr)->ipv6.port = PR_htons(myport)) : ((myaddr)->inet.port = PR_htons(myport)))
+
 #ifdef __cplusplus
 }
 #endif