Index: include/freeDiameter/CMakeLists.txt
===================================================================
--- include/freeDiameter/CMakeLists.txt	(revision 23)
+++ include/freeDiameter/CMakeLists.txt	(revision 24)
@@ -13,4 +13,5 @@
 IF (NOT DISABLE_SCTP)
 	OPTION(DEBUG_SCTP "Verbose SCTP (for debug)?" OFF)
+	OPTION(SCTP_USE_MAPPED_ADDRESSES "Use v6-mapped v4 addresses in SCTP (workaround some SCTP limitations)?" OFF)
 ENDIF (NOT DISABLE_SCTP)
 
Index: include/freeDiameter/freeDiameter-host.h.in
===================================================================
--- include/freeDiameter/freeDiameter-host.h.in	(revision 23)
+++ include/freeDiameter/freeDiameter-host.h.in	(revision 24)
@@ -46,4 +46,5 @@
 #cmakedefine DISABLE_SCTP
 #cmakedefine DEBUG_SCTP
+#cmakedefine SCTP_USE_MAPPED_ADDRESSES
 #cmakedefine ERRORS_ON_TODO
 #cmakedefine DEBUG
Index: include/freeDiameter/freeDiameter.h
===================================================================
--- include/freeDiameter/freeDiameter.h	(revision 23)
+++ include/freeDiameter/freeDiameter.h	(revision 24)
@@ -118,23 +118,21 @@
 struct fd_endpoint {
 	struct fd_list  chain;	/* link in cnf_endpoints list */
+	
 	union {
-		sSS		ss;	/* the socket information. List is always ordered by ss value (memcmp) */
+		sSS		ss;	/* the socket information. List is always ordered by ss value (memcmp) -- see fd_ep_add_merge */
 		sSA4		sin;
 		sSA6		sin6;
 		sSA		sa;
 	};
-	struct {
-		unsigned conf : 1; /* This endpoint is statically configured in a configuration file */
-		unsigned disc : 1; /* This endpoint was resolved from the Diameter Identity or other DNS query */
-		unsigned adv  : 1; /* This endpoint was advertized in Diameter CER/CEA exchange */
-		unsigned ll   : 1; /* Lower layer mechanism provided this endpoint */
-		
-		/* To add: a validity timestamp for DNS records ? How do we retrieve this lifetime from DNS ? */
-
-	}		meta;	/* Additional information about the endpoint */
-};
-
-/* Add a new entry in a list of endpoints -- merge if the sockaddr was already there */
-int fd_ep_add_merge( struct fd_list * list, sSA * sa, socklen_t sl, int conf, int disc, int adv, int ll );
+	
+#define	EP_FL_CONF	(1 << 0)	/* This endpoint is statically configured in a configuration file */
+#define	EP_FL_DISC	(1 << 1)	/* This endpoint was resolved from the Diameter Identity or other DNS query */
+#define	EP_FL_ADV	(1 << 2)	/* This endpoint was advertized in Diameter CER/CEA exchange */
+#define	EP_FL_LL	(1 << 3)	/* Lower layer mechanism provided this endpoint */
+#define	EP_FL_PRIMARY	(1 << 4)	/* This endpoint is primary in a multihomed SCTP association */
+	uint32_t	flags;		/* Additional information about the endpoint */
+		
+	/* To add: a validity timestamp for DNS records ? How do we retrieve this lifetime from DNS ? */
+};
 
 /* Applications */
@@ -468,3 +466,13 @@
 
 
+/***************************************/
+/*   Endpoints lists helpers           */
+/***************************************/
+
+int fd_ep_add_merge( struct fd_list * list, sSA * sa, socklen_t sl, uint32_t flags );
+int fd_ep_filter( struct fd_list * list, uint32_t flags );
+int fd_ep_clearflags( struct fd_list * list, uint32_t flags );
+
+
+
 #endif /* _FREEDIAMETER_H */
Index: include/freeDiameter/libfreeDiameter.h
===================================================================
--- include/freeDiameter/libfreeDiameter.h	(revision 23)
+++ include/freeDiameter/libfreeDiameter.h	(revision 24)
@@ -336,25 +336,5 @@
 	}							\
 }
-/* Same, for a service */
-#define sSA_DUMP_SERV( sa, flag ) {				\
-	sSA * __sa = (sSA *)(sa);				\
-	char __servbuf[32];					\
-	if (__sa) {						\
-	  int __rc = getnameinfo(__sa, 				\
-	  		sizeof(sSS),				\
-			NULL,					\
-			0,					\
-			__servbuf,				\
-			sizeof(__servbuf),			\
-			flag);					\
-	  if (__rc)						\
-	  	fd_log_debug("%s", (char *)gai_strerror(__rc));	\
-	  else							\
-	  	fd_log_debug("%s", &__servbuf[0]);		\
-	} else {						\
-		fd_log_debug("(unknown)");			\
-	}							\
-}
-/* Combine both */
+/* Same but with the port (service) also */
 #define sSA_DUMP_NODE_SERV( sa, flag ) {				\
 	sSA * __sa = (sSA *)(sa);					\
@@ -376,4 +356,17 @@
 		fd_log_debug("(NULL / ANY)");				\
 	}								\
+}
+/* Inside a debug trace */
+#define TRACE_DEBUG_sSA(level, prefix, sa, flags, suffix ) {										\
+	if ( TRACE_BOOL(level) ) {												\
+		char __buf[25];													\
+		char * __thn = ((char *)pthread_getspecific(fd_log_thname) ?: "unnamed");					\
+		fd_log_debug("\t | tid:%-20s\t%s\tin %s@%s:%d\n"								\
+			  "\t%s|%*s" prefix ,  											\
+					__thn, fd_log_time(NULL, __buf, sizeof(__buf)), __PRETTY_FUNCTION__, __FILE__, __LINE__,\
+					(level < FULL)?"@":" ",level, ""); 							\
+		sSA_DUMP_NODE_SERV( sa, flags );										\
+		fd_log_debug(suffix "\n");											\
+	}															\
 }
 
@@ -481,4 +474,12 @@
 	free(buffer);
 }
+static __inline__ void fd_cleanup_socket(void * sockptr)
+{
+	if (sockptr) {
+		shutdown(*(int *)sockptr, SHUT_RDWR);
+		*(int *)sockptr = 0;
+	}
+}
+
 
 /*============================================================*/
