Index: freeDiameter/cnxctx.c
===================================================================
--- freeDiameter/cnxctx.c	(revision 258)
+++ freeDiameter/cnxctx.c	(revision 378)
@@ -37,8 +37,12 @@
 #include "cnxctx.h"
 
+#include <net/if.h>
+#include <ifaddrs.h> /* for getifaddrs */
+
 /* The maximum size of Diameter message we accept to receive (<= 2^24) to avoid too big mallocs in case of trashed headers */
 #ifndef DIAMETER_MSG_SIZE_MAX
 #define DIAMETER_MSG_SIZE_MAX	65535	/* in bytes */
 #endif /* DIAMETER_MSG_SIZE_MAX */
+
 
 /* Connections contexts (cnxctx) in freeDiameter are wrappers around the sockets and TLS operations .
@@ -74,5 +78,4 @@
  */
 
-
 /*******************************************/
 /*     Creation of a connection object     */
@@ -468,61 +471,35 @@
 
 /* Get the list of endpoints (IP addresses) of the local and remote peers on this connection */
-int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * local, struct fd_list * remote)
-{
-	TRACE_ENTRY("%p %p %p", conn, local, remote);
-	CHECK_PARAMS(conn);
-	
-	if (local) {
-		/* Retrieve the local endpoint(s) of the connection */
-		switch (conn->cc_proto) {
-			case IPPROTO_TCP: {
-				sSS ss;
-				socklen_t sl;
-				CHECK_FCT(fd_tcp_get_local_ep(conn->cc_socket, &ss, &sl));
-				CHECK_FCT(fd_ep_add_merge( local, (sSA *)&ss, sl, EP_FL_LL | EP_FL_PRIMARY));
-			}
-			break;
-
-			#ifndef DISABLE_SCTP
-			case IPPROTO_SCTP: {
-				CHECK_FCT(fd_sctp_get_local_ep(conn->cc_socket, local));
-			}
-			break;
-			#endif /* DISABLE_SCTP */
-
-			default:
-				CHECK_PARAMS(0);
-		}
-	}
-	
-	if (remote) {
-		/* Check we have a full connection object, not a listening socket (with no remote) */
-		CHECK_PARAMS( conn->cc_incoming );
-		
-		/* Retrieve the peer endpoint(s) of the connection */
-		switch (conn->cc_proto) {
-			case IPPROTO_TCP: {
-				sSS ss;
-				socklen_t sl;
-				CHECK_FCT(fd_tcp_get_remote_ep(conn->cc_socket, &ss, &sl));
-				CHECK_FCT(fd_ep_add_merge( remote, (sSA *)&ss, sl, EP_FL_LL | EP_FL_PRIMARY ));
-			}
-			break;
-
-			#ifndef DISABLE_SCTP
-			case IPPROTO_SCTP: {
-				CHECK_FCT(fd_sctp_get_remote_ep(conn->cc_socket, remote));
-			}
-			break;
-			#endif /* DISABLE_SCTP */
-
-			default:
-				CHECK_PARAMS(0);
-		}
+int fd_cnx_getremoteeps(struct cnxctx * conn, struct fd_list * eps)
+{
+	TRACE_ENTRY("%p %p %p", conn, eps);
+	CHECK_PARAMS(conn && eps);
+	
+	/* Check we have a full connection object, not a listening socket (with no remote) */
+	CHECK_PARAMS( conn->cc_incoming );
+
+	/* Retrieve the peer endpoint(s) of the connection */
+	switch (conn->cc_proto) {
+		case IPPROTO_TCP: {
+			sSS ss;
+			socklen_t sl;
+			CHECK_FCT(fd_tcp_get_remote_ep(conn->cc_socket, &ss, &sl));
+			CHECK_FCT(fd_ep_add_merge( eps, (sSA *)&ss, sl, EP_FL_LL | EP_FL_PRIMARY ));
+		}
+		break;
+
+		#ifndef DISABLE_SCTP
+		case IPPROTO_SCTP: {
+			CHECK_FCT(fd_sctp_get_remote_ep(conn->cc_socket, eps));
+		}
+		break;
+		#endif /* DISABLE_SCTP */
+
+		default:
+			CHECK_PARAMS(0);
 	}
 
 	return 0;
 }
-
 
 /* Get a string describing the remote peer address (ip address or fqdn) */
@@ -531,4 +508,28 @@
 	CHECK_PARAMS_DO( conn, return "" );
 	return conn->cc_remid;
+}
+
+/* Retrieve a list of all IP addresses of the local system from the kernel, using  */
+int fd_cnx_get_local_eps(struct fd_list * list)
+{
+	struct ifaddrs *iflist, *cur;
+	CHECK_SYS(getifaddrs(&iflist));
+	
+	for (cur = iflist; cur != NULL; cur = cur->ifa_next) {
+		if (cur->ifa_flags & IFF_LOOPBACK)
+			continue;
+		
+		if (fd_g_config->cnf_flags.no_ip4 && (cur->ifa_addr->sa_family == AF_INET))
+			continue;
+		
+		if (fd_g_config->cnf_flags.no_ip6 && (cur->ifa_addr->sa_family == AF_INET6))
+			continue;
+		
+		CHECK_FCT(fd_ep_add_merge( list, cur->ifa_addr, sSAlen(cur->ifa_addr), EP_FL_LL ));
+	}
+	
+	freeifaddrs(iflist);
+	
+	return 0;
 }
 
Index: freeDiameter/cnxctx.h
===================================================================
--- freeDiameter/cnxctx.h	(revision 258)
+++ freeDiameter/cnxctx.h	(revision 378)
@@ -137,4 +137,7 @@
 #endif /* DISABLE_SCTP */
 
+/* UDP */
+int fd_cnx_get_local_eps(struct fd_list * list);
+
 #endif /* _CNXCTX_H */
 
Index: freeDiameter/fD.h
===================================================================
--- freeDiameter/fD.h	(revision 304)
+++ freeDiameter/fD.h	(revision 378)
@@ -327,5 +327,5 @@
 int		fd_cnx_getTLS(struct cnxctx * conn);
 int             fd_cnx_getcred(struct cnxctx * conn, const gnutls_datum_t **cert_list, unsigned int *cert_list_size);
-int             fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * local, struct fd_list * remote);
+int             fd_cnx_getremoteeps(struct cnxctx * conn, struct fd_list * eps);
 char *          fd_cnx_getremoteid(struct cnxctx * conn);
 int             fd_cnx_receive(struct cnxctx * conn, struct timespec * timeout, unsigned char **buf, size_t * len);
Index: freeDiameter/p_ce.c
===================================================================
--- freeDiameter/p_ce.c	(revision 332)
+++ freeDiameter/p_ce.c	(revision 378)
@@ -63,5 +63,5 @@
 	
 	/* Read the endpoints, maybe used to reconnect to the peer later */
-	CHECK_FCT( fd_cnx_getendpoints(peer->p_cnxctx, NULL, &peer->p_hdr.info.pi_endpoints) );
+	CHECK_FCT( fd_cnx_getremoteeps(peer->p_cnxctx, &peer->p_hdr.info.pi_endpoints) );
 	
 	/* Read the protocol */
@@ -106,5 +106,5 @@
 	struct avp * avp = NULL;
 	union avp_value val;
-	struct fd_list *li, local_ep = FD_LIST_INITIALIZER(local_ep);
+	struct fd_list *li;
 	
 	/* Add the Origin-* AVPs */
@@ -114,9 +114,6 @@
 	CHECK_FCT(  fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Host-IP-Address", &dictobj, ENOENT )  );
 		
-	/* Get the list of endpoints */
-	CHECK_FCT(  fd_cnx_getendpoints(cnx, &local_ep, NULL) );
-	
 	/* Add the AVP(s) -- not sure what is the purpose... We could probably only add the primary one ? */
-	for (li = local_ep.next; li != &local_ep; li = li->next) {
+	for (li = fd_g_config->cnf_endpoints.next; li != &fd_g_config->cnf_endpoints; li = li->next) {
 		struct fd_endpoint * ep = (struct fd_endpoint *)li;
 		
@@ -125,5 +122,4 @@
 		CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp ) );
 	}
-	
 	
 	/* Vendor-Id, Product-Name, and Firmware-Revision AVPs */
Index: freeDiameter/p_psm.c
===================================================================
--- freeDiameter/p_psm.c	(revision 373)
+++ freeDiameter/p_psm.c	(revision 378)
@@ -571,7 +571,7 @@
 		
 		/* Get the new ones */
-		CHECK_FCT_DO( fd_cnx_getendpoints(peer->p_cnxctx, NULL, &peer->p_hdr.info.pi_endpoints), /* ignore the error */);
-		
-		/* We do not support local endpoints change currently, but it could be added here if needed */
+		CHECK_FCT_DO( fd_cnx_getremoteeps(peer->p_cnxctx, &peer->p_hdr.info.pi_endpoints), /* ignore the error */);
+		
+		/* We do not support local endpoints change currently, but it could be added here if needed (refresh fd_g_config->cnf_endpoints)*/
 		
 		if (TRACE_BOOL(ANNOYING)) {
Index: freeDiameter/sctp.c
===================================================================
--- freeDiameter/sctp.c	(revision 258)
+++ freeDiameter/sctp.c	(revision 378)
@@ -933,52 +933,4 @@
 }
 
-/* Get the list of local endpoints of the socket */
-int fd_sctp_get_local_ep(int sock, struct fd_list * list)
-{
-	union {
-		sSA	*sa;
-		uint8_t	*buf;
-	} ptr;
-	
-	sSA * data = NULL;
-	int count;
-	
-	TRACE_ENTRY("%d %p", sock, list);
-	CHECK_PARAMS(list);
-	
-	/* Read the list on the socket */
-	CHECK_SYS( count = sctp_getladdrs(sock, 0, &data)  );
-	ptr.sa = data;
-	
-	while (count) {
-		socklen_t sl;
-		switch (ptr.sa->sa_family) {
-			case AF_INET:	sl = sizeof(sSA4); break;
-			case AF_INET6:	sl = sizeof(sSA6); break;
-			default:
-				TRACE_DEBUG(INFO, "Unknown address family returned in sctp_getladdrs: %d", ptr.sa->sa_family);
-				goto stop;
-		}
-				
-		CHECK_FCT( fd_ep_add_merge( list, ptr.sa, sl, EP_FL_LL ) );
-		ptr.buf += sl;
-		count --;
-	}
-stop:
-	/* Free the list */
-	sctp_freeladdrs(data);
-	
-	/* Now get the primary address, the add function will take care of merging with existing entry */
-	{
-		sSS ss;
-		socklen_t sl = sizeof(sSS);
-	
-		CHECK_SYS(getsockname(sock, (sSA *)&ss, &sl));
-		CHECK_FCT( fd_ep_add_merge( list, (sSA *)&ss, sl, EP_FL_PRIMARY ) );
-	}
-	
-	return 0;
-}
-
 /* Get the list of remote endpoints of the socket */
 int fd_sctp_get_remote_ep(int sock, struct fd_list * list)
Index: freeDiameter/server.c
===================================================================
--- freeDiameter/server.c	(revision 258)
+++ freeDiameter/server.c	(revision 378)
@@ -270,13 +270,4 @@
 		CHECK_POSIX( pthread_create( &s->thr, NULL, serv_th, s ) );
 		
-		/* Retrieve the list of endpoints if it was empty */
-		if (empty_conf_ep) {
-			(void) fd_cnx_getendpoints(s->conn, &fd_g_config->cnf_endpoints, NULL);
-			if (TRACE_BOOL(FULL)){
-				fd_log_debug("  Local server address(es) :\n");
-				fd_ep_dump( 5, &fd_g_config->cnf_endpoints );
-			}
-		}
-		
 		/* Create the server on secure port */
 		CHECK_MALLOC( s = new_serv(IPPROTO_SCTP, 1) );
@@ -344,4 +335,16 @@
 	}
 	
+	/* Now, if we still have not got the list of local adresses, try to read it from the kernel directly */
+	if (FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints)) {
+		CHECK_FCT(fd_cnx_get_local_eps(&fd_g_config->cnf_endpoints));
+		if (FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints)) {
+			TRACE_DEBUG(INFO, "Unable to find the addresses of the local system. Please use \"ListenOn\" parameter in the configuration.");
+			return EINVAL;
+		}
+	}
+	if (TRACE_BOOL(FULL)){
+		fd_log_debug("  Local server address(es) :\n");
+		fd_ep_dump( 5, &fd_g_config->cnf_endpoints );
+	}
 	return 0;
 }
Index: freeDiameter/tcp.c
===================================================================
--- freeDiameter/tcp.c	(revision 258)
+++ freeDiameter/tcp.c	(revision 378)
@@ -170,17 +170,4 @@
 }
 
-
-/* Get the local name of a TCP socket -- would be nice if it did not return "0.0.0.0"... */
-int fd_tcp_get_local_ep(int sock, sSS * ss, socklen_t *sl)
-{
-	TRACE_ENTRY("%d %p %p", sock, ss, sl);
-	CHECK_PARAMS( ss && sl );
-	
-	*sl = sizeof(sSS);
-	CHECK_SYS(getsockname(sock, (sSA *)ss, sl));
-	
-	return 0;
-}
-
 /* Get the remote name of a TCP socket */
 int fd_tcp_get_remote_ep(int sock, sSS * ss, socklen_t *sl)
@@ -194,2 +181,3 @@
 	return 0;
 }
+
Index: include/freeDiameter/CMakeLists.txt
===================================================================
--- include/freeDiameter/CMakeLists.txt	(revision 316)
+++ include/freeDiameter/CMakeLists.txt	(revision 378)
@@ -43,4 +43,9 @@
 CHECK_INCLUDE_FILES (malloc.h HAVE_MALLOC_H)
 
+# getifaddrs ?
+CHECK_FUNCTION_EXISTS (getifaddrs HAVE_GETIFADDRS)
+IF (NOT HAVE_GETIFADDRS)
+   MESSAGE(SEND_ERROR "The getifaddrs function is currently required by freeDiameter.")
+ENDIF (NOT HAVE_GETIFADDRS)
 
 # pthreads
