Index: libfdcore/sctp.c
===================================================================
--- libfdcore/sctp.c	(revision 1107)
+++ libfdcore/sctp.c	(revision 1174)
@@ -45,10 +45,12 @@
 #endif /* CMSG_BUF_LEN */
 
-/* Level of SCTP-specific traces */
-#ifdef DEBUG_SCTP
-#define SCTP_LEVEL	FULL
-#else /* DEBUG_SCTP */
-#define SCTP_LEVEL	(FCTS + 1)
-#endif /* DEBUG_SCTP */
+/* Use old draft-ietf-tsvwg-sctpsocket-17 API ? If not defined, RFC6458 API will be used */
+/* #define OLD_SCTP_SOCKET_API */
+
+/* Automatically fallback to old API if some of the new symbols are not defined */
+#if (!defined(SCTP_CONNECTX_4_ARGS) || (!defined(SCTP_RECVRCVINFO)) || (!defined(SCTP_SNDINFO))) 
+# define OLD_SCTP_SOCKET_API
+#endif
+
 
 /* Temper with the retransmission timers to try and improve disconnection detection response? Undef this to keep the defaults of SCTP stack */
@@ -58,5 +60,4 @@
 
 /* Pre-binding socket options -- # streams read in config */
-/* The code of this file is based on draft-ietf-tsvwg-sctpsocket, versions 17 to 21 */
 static int fd_setsockopt_prebind(int sk)
 {
@@ -79,5 +80,5 @@
 		memset(&rtoinfo, 0, sizeof(rtoinfo));
 
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			sz = sizeof(rtoinfo);
 			/* Read socket defaults */
@@ -100,5 +101,5 @@
 		CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_RTOINFO, &rtoinfo, sizeof(rtoinfo))  );
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			/* Check new values */
 			CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_RTOINFO, &rtoinfo, &sz)  );
@@ -109,5 +110,5 @@
 	}
 	#else /* SCTP_RTOINFO */
-	TRACE_DEBUG(SCTP_LEVEL, "Skipping SCTP_RTOINFO");
+	TRACE_DEBUG(ANNOYING, "Skipping SCTP_RTOINFO");
 	#endif /* SCTP_RTOINFO */
 	
@@ -118,5 +119,5 @@
 		memset(&assoc, 0, sizeof(assoc));
 
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			sz = sizeof(assoc);
 			/* Read socket defaults */
@@ -140,5 +141,5 @@
 		CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_ASSOCINFO, &assoc, sizeof(assoc))  );
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			/* Check new values */
 			CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_ASSOCINFO, &assoc, &sz)  );
@@ -151,5 +152,5 @@
 	}
 	#else /* SCTP_ASSOCINFO */
-	TRACE_DEBUG(SCTP_LEVEL, "Skipping SCTP_ASSOCINFO");
+	TRACE_DEBUG(ANNOYING, "Skipping SCTP_ASSOCINFO");
 	#endif /* SCTP_ASSOCINFO */
 #endif /* ADJUST_RTX_PARAMS */
@@ -161,5 +162,5 @@
 		memset(&init, 0, sizeof(init));
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			sz = sizeof(init);
 
@@ -184,5 +185,5 @@
 		CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_INITMSG, &init, sizeof(init))  );
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			/* Check new values */
 			CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_INITMSG, &init, &sz)  );
@@ -194,5 +195,5 @@
 	}
 	#else /* SCTP_INITMSG */
-	TRACE_DEBUG(SCTP_LEVEL, "Skipping SCTP_INITMSG");
+	TRACE_DEBUG(ANNOYING, "Skipping SCTP_INITMSG");
 	#endif /* SCTP_INITMSG */
 	
@@ -203,5 +204,5 @@
 		memset(&linger, 0, sizeof(linger));
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			sz = sizeof(linger);
 			/* Read socket defaults */
@@ -222,5 +223,5 @@
 		CHECK_SYS(  setsockopt(sk, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger))  );
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			/* Check new values */
 			CHECK_SYS(  getsockopt(sk, SOL_SOCKET, SO_LINGER, &linger, &sz)  );
@@ -230,5 +231,5 @@
 	}
 	#else /* SO_LINGER */
-	TRACE_DEBUG(SCTP_LEVEL, "Skipping SO_LINGER");
+	TRACE_DEBUG(ANNOYING, "Skipping SO_LINGER");
 	#endif /* SO_LINGER */
 	
@@ -238,5 +239,5 @@
 		int nodelay;
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			sz = sizeof(nodelay);
 			/* Read socket defaults */
@@ -255,5 +256,5 @@
 		CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_NODELAY, &nodelay, sizeof(nodelay))  );
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			/* Check new values */
 			CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_NODELAY, &nodelay, &sz)  );
@@ -262,5 +263,5 @@
 	}
 	#else /* SCTP_NODELAY */
-	TRACE_DEBUG(SCTP_LEVEL, "Skipping SCTP_NODELAY");
+	TRACE_DEBUG(ANNOYING, "Skipping SCTP_NODELAY");
 	#endif /* SCTP_NODELAY */
 	
@@ -278,5 +279,5 @@
 		int nofrag;
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			sz = sizeof(nofrag);
 			/* Read socket defaults */
@@ -295,5 +296,5 @@
 		CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS, &nofrag, sizeof(nofrag))  );
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			/* Check new values */
 			CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS, &nofrag, &sz)  );
@@ -314,5 +315,5 @@
 		parms.spp_address.ss_family = AF_INET;
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			sz = sizeof(parms);
 
@@ -345,5 +346,5 @@
 		CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, &parms, sizeof(parms)) );
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			/* Check new values */
 			CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, &parms, &sz)  );
@@ -357,13 +358,14 @@
 	}
 	#else /* SCTP_PEER_ADDR_PARAMS */
-	TRACE_DEBUG(SCTP_LEVEL, "Skipping SCTP_PEER_ADDR_PARAMS");
+	TRACE_DEBUG(ANNOYING, "Skipping SCTP_PEER_ADDR_PARAMS");
 	#endif /* SCTP_PEER_ADDR_PARAMS */
 	
 	/*
-	   SCTP_DEFAULT_SEND_PARAM	parameters for the sendto() call, we don't use it.
+	   SCTP_DEFAULT_SEND_PARAM - DEPRECATED // parameters for the sendto() call, we don't use it.
 	*/
 
 	/* Subscribe to some notifications */
-	#ifdef SCTP_EVENTS
+#ifdef OLD_SCTP_SOCKET_API
+	#ifdef SCTP_EVENTS /* DEPRECATED */
 	{
 		struct sctp_event_subscribe event;
@@ -383,5 +385,5 @@
 		CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(event)) );
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			sz = sizeof(event);
 			CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_EVENTS, &event, &sz) );
@@ -404,6 +406,7 @@
 	}
 	#else /* SCTP_EVENTS */
-	TRACE_DEBUG(SCTP_LEVEL, "Skipping SCTP_EVENTS");
+	TRACE_DEBUG(ANNOYING, "Skipping SCTP_EVENTS");
 	#endif /* SCTP_EVENTS */
+#endif /*  OLD_SCTP_SOCKET_API */
 	
 	/* Set the v4 mapped addresses option */
@@ -412,5 +415,5 @@
 		int v4mapped;
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			sz = sizeof(v4mapped);
 			/* Read socket defaults */
@@ -433,5 +436,5 @@
 		CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_I_WANT_MAPPED_V4_ADDR, &v4mapped, sizeof(v4mapped))  );
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			/* Check new values */
 			CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_I_WANT_MAPPED_V4_ADDR, &v4mapped, &sz)  );
@@ -439,8 +442,8 @@
 		}
 	} else {
-		TRACE_DEBUG(SCTP_LEVEL, "Skipping SCTP_I_WANT_MAPPED_V4_ADDR, since IPv6 disabled.");
+		TRACE_DEBUG(ANNOYING, "Skipping SCTP_I_WANT_MAPPED_V4_ADDR, since IPv6 disabled.");
 	}
 	#else /* SCTP_I_WANT_MAPPED_V4_ADDR */
-	TRACE_DEBUG(SCTP_LEVEL, "Skipping SCTP_I_WANT_MAPPED_V4_ADDR");
+	TRACE_DEBUG(ANNOYING, "Skipping SCTP_I_WANT_MAPPED_V4_ADDR");
 	#endif /* SCTP_I_WANT_MAPPED_V4_ADDR */
 	
@@ -458,5 +461,5 @@
 		int interleave;
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			sz = sizeof(interleave);
 			/* Read socket defaults */
@@ -479,5 +482,5 @@
 		CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_FRAGMENT_INTERLEAVE, &interleave, sizeof(interleave))  );
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			/* Check new values */
 			CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_FRAGMENT_INTERLEAVE, &interleave, &sz)  );
@@ -486,10 +489,10 @@
 	}
 	#else /* SCTP_FRAGMENT_INTERLEAVE */
-	TRACE_DEBUG(SCTP_LEVEL, "Skipping SCTP_FRAGMENT_INTERLEAVE");
+	TRACE_DEBUG(ANNOYING, "Skipping SCTP_FRAGMENT_INTERLEAVE");
 	#endif /* SCTP_FRAGMENT_INTERLEAVE */
 	
 	/*
 	   SCTP_PARTIAL_DELIVERY_POINT	control partial delivery size
-	   SCTP_USE_EXT_RCVINFO		use extended receive info structure (information about the next message if available)
+	   SCTP_USE_EXT_RCVINFO	- DEPRECATED	use extended receive info structure (information about the next message if available)
 	 */
 	/* SCTP_AUTO_ASCONF is set by the postbind function */
@@ -504,5 +507,5 @@
 		int bool;
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			sz = sizeof(bool);
 			/* Read socket defaults */
@@ -521,5 +524,5 @@
 		CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_EXPLICIT_EOR, &bool, sizeof(bool))  );
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			/* Check new values */
 			CHECK_SYS(  getsockopt(sk, IPPROTO_SCTP, SCTP_EXPLICIT_EOR, &bool, &sz)  );
@@ -528,12 +531,86 @@
 	}
 	#else /* SCTP_EXPLICIT_EOR */
-	TRACE_DEBUG(SCTP_LEVEL, "Skipping SCTP_EXPLICIT_EOR");
+	TRACE_DEBUG(ANNOYING, "Skipping SCTP_EXPLICIT_EOR");
 	#endif /* SCTP_EXPLICIT_EOR */
 	
 	/*
 	   SCTP_REUSE_PORT		share one listening port with several sockets
-	   SCTP_EVENT			same as EVENTS ?
 	*/
 	
+#ifndef OLD_SCTP_SOCKET_API
+	#ifdef SCTP_EVENT
+	{
+		/* Subscribe to the following events */
+		int events_I_want[] = {
+		#ifdef SCTP_ASSOC_CHANGE
+			/* SCTP_ASSOC_CHANGE, */
+		#endif 
+		#ifdef SCTP_PEER_ADDR_CHANGE
+			SCTP_PEER_ADDR_CHANGE,
+		#endif
+		#ifdef SCTP_REMOTE_ERROR
+			SCTP_REMOTE_ERROR,
+		#endif
+		#ifdef SCTP_SEND_FAILED_EVENT
+			SCTP_SEND_FAILED_EVENT,
+		#endif
+		#ifdef SCTP_SHUTDOWN_EVENT
+			SCTP_SHUTDOWN_EVENT,
+		#endif
+		#ifdef SCTP_ADAPTATION_INDICATION
+			/* SCTP_ADAPTATION_INDICATION, */
+		#endif
+		#ifdef SCTP_PARTIAL_DELIVERY_EVENT
+			/* SCTP_PARTIAL_DELIVERY_EVENT, */
+		#endif
+		#ifdef SCTP_AUTHENTICATION_EVENT
+			/* SCTP_AUTHENTICATION_EVENT, */
+		#endif
+		#ifdef SCTP_SENDER_DRY_EVENT
+			/* SCTP_SENDER_DRY_EVENT, */
+		#endif
+			0
+		};
+		int i;
+		
+		struct sctp_event event;
+		
+		for (i = 0; i < (sizeof(events_I_want) / sizeof(events_I_want[0]) - 1; i++) {
+			memset(&event, 0, sizeof(event));
+			event.se_type = events_I_want[i];
+			event.se_on = 1;
+			
+			/* Set the option to the socket */
+			CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(event)) );
+		}
+	}
+	#else /* SCTP_EVENT */
+	TRACE_DEBUG(ANNOYING, "Skipping SCTP_EVENT");
+	#endif /* SCTP_EVENT */
+	
+	
+	#ifdef SCTP_RECVRCVINFO /* Replaces SCTP_SNDRCV */
+	{
+		int bool = 1;
+		
+		/* Set the option to the socket */
+		CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_RECVRCVINFO, &bool, sizeof(bool))  );
+		
+	}
+	#else /* SCTP_RECVRCVINFO */
+	TRACE_DEBUG(ANNOYING, "Skipping SCTP_RECVRCVINFO");
+	#endif /* SCTP_RECVRCVINFO */
+	
+	
+#endif /* OLD_SCTP_SOCKET_API */
+	
+	/* 
+		SCTP_RECVNXTINFO
+		
+		SCTP_DEFAULT_SNDINFO : send defaults
+		SCTP_DEFAULT_PRINFO  : default PR-SCTP
+	*/
+	
+
 	/* In case of no_ip4, force the v6only option */
 	#ifdef IPV6_V6ONLY
@@ -560,5 +637,5 @@
 		int asconf;
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			socklen_t sz;
 
@@ -579,5 +656,5 @@
 		CHECK_SYS(  setsockopt(sk, IPPROTO_SCTP, SCTP_AUTO_ASCONF, &asconf, sizeof(asconf))  );
 		
-		if (TRACE_BOOL(SCTP_LEVEL)) {
+		if (TRACE_BOOL(ANNOYING)) {
 			socklen_t sz = sizeof(asconf);
 			/* Check new values */
@@ -587,5 +664,5 @@
 	}
 	#else /* SCTP_AUTO_ASCONF */
-	TRACE_DEBUG(SCTP_LEVEL, "Skipping SCTP_AUTO_ASCONF");
+	TRACE_DEBUG(ANNOYING, "Skipping SCTP_AUTO_ASCONF");
 	#endif /* SCTP_AUTO_ASCONF */
 	
@@ -1005,6 +1082,11 @@
 	struct iovec  iov;
 	struct cmsghdr 		*hdr;
+#ifdef OLD_SCTP_SOCKET_API
 	struct sctp_sndrcvinfo	*sndrcv;
 	uint8_t anci[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+#else /* OLD_SCTP_SOCKET_API */
+	struct sctp_sndinfo 	*sndinf;
+	uint8_t anci[CMSG_SPACE(sizeof(struct sctp_sndinfo))];	
+#endif /* OLD_SCTP_SOCKET_API */
 	ssize_t ret;
 	int timedout = 0;
@@ -1023,9 +1105,15 @@
 	/* Anciliary data: specify SCTP stream */
 	hdr = (struct cmsghdr *)anci;
-	sndrcv = (struct sctp_sndrcvinfo *)CMSG_DATA(hdr);
 	hdr->cmsg_len   = sizeof(anci);
 	hdr->cmsg_level = IPPROTO_SCTP;
+#ifdef OLD_SCTP_SOCKET_API
 	hdr->cmsg_type  = SCTP_SNDRCV;
+	sndrcv = (struct sctp_sndrcvinfo *)CMSG_DATA(hdr);
 	sndrcv->sinfo_stream = strid;
+#else /* OLD_SCTP_SOCKET_API */
+	hdr->cmsg_type  = SCTP_SNDINFO;
+	sndinf = (struct sctp_sndinfo *)CMSG_DATA(hdr);
+	sndinf->snd_sid = strid;
+#endif /* OLD_SCTP_SOCKET_API */
 	/* note : we could store other data also, for example in .sinfo_ppid for remote peer or in .sinfo_context for errors. */
 	
@@ -1085,4 +1173,7 @@
 	mhdr.msg_controllen = sizeof(ancidata);
 	
+next_message:
+	datasize = 0;
+	
 	/* We will loop while all data is not received. */
 incomplete:
@@ -1139,10 +1230,10 @@
 		switch (notif->sn_header.sn_type) {
 			
-			case SCTP_ASSOC_CHANGE:
+			case SCTP_ASSOC_CHANGE: /* We should not receive these as we did not subscribe for it */
 				TRACE_DEBUG(FULL, "Received SCTP_ASSOC_CHANGE notification");
-				TRACE_DEBUG(SCTP_LEVEL, "    state : %hu", notif->sn_assoc_change.sac_state);
-				TRACE_DEBUG(SCTP_LEVEL, "    error : %hu", notif->sn_assoc_change.sac_error);
-				TRACE_DEBUG(SCTP_LEVEL, "    instr : %hu", notif->sn_assoc_change.sac_inbound_streams);
-				TRACE_DEBUG(SCTP_LEVEL, "   outstr : %hu", notif->sn_assoc_change.sac_outbound_streams);
+				TRACE_DEBUG(ANNOYING, "    state : %hu", notif->sn_assoc_change.sac_state);
+				TRACE_DEBUG(ANNOYING, "    error : %hu", notif->sn_assoc_change.sac_error);
+				TRACE_DEBUG(ANNOYING, "    instr : %hu", notif->sn_assoc_change.sac_inbound_streams);
+				TRACE_DEBUG(ANNOYING, "   outstr : %hu", notif->sn_assoc_change.sac_outbound_streams);
 				
 				*event = FDEVP_CNX_EP_CHANGE;
@@ -1151,27 +1242,33 @@
 			case SCTP_PEER_ADDR_CHANGE:
 				TRACE_DEBUG(FULL, "Received SCTP_PEER_ADDR_CHANGE notification");
-				/* TRACE_sSA(FD_LOG_DEBUG, SCTP_LEVEL, "    intf_change : ", &(notif->sn_paddr_change.spc_aaddr), NI_NUMERICHOST | NI_NUMERICSERV, "" ); */
-				TRACE_DEBUG(SCTP_LEVEL, "          state : %d", notif->sn_paddr_change.spc_state);
-				TRACE_DEBUG(SCTP_LEVEL, "          error : %d", notif->sn_paddr_change.spc_error);
+				/* TRACE_sSA(FD_LOG_DEBUG, ANNOYING, "    intf_change : ", &(notif->sn_paddr_change.spc_aaddr), NI_NUMERICHOST | NI_NUMERICSERV, "" ); */
+				TRACE_DEBUG(ANNOYING, "          state : %d", notif->sn_paddr_change.spc_state);
+				TRACE_DEBUG(ANNOYING, "          error : %d", notif->sn_paddr_change.spc_error);
 				
 				*event = FDEVP_CNX_EP_CHANGE;
 				break;
 	
-			case SCTP_SEND_FAILED:
-				TRACE_DEBUG(FULL, "Received SCTP_SEND_FAILED notification");
-				TRACE_DEBUG(SCTP_LEVEL, "    len : %hu", notif->sn_send_failed.ssf_length);
-				TRACE_DEBUG(SCTP_LEVEL, "    err : %d",  notif->sn_send_failed.ssf_error);
+			case SCTP_REMOTE_ERROR:
+				TRACE_DEBUG(FULL, "Received SCTP_REMOTE_ERROR notification");
+				TRACE_DEBUG(ANNOYING, "    err : %hu", ntohs(notif->sn_remote_error.sre_error));
+				TRACE_DEBUG(ANNOYING, "    len : %hu", ntohs(notif->sn_remote_error.sre_length));
 				
 				*event = FDEVP_CNX_ERROR;
 				break;
-			
-			case SCTP_REMOTE_ERROR:
-				TRACE_DEBUG(FULL, "Received SCTP_REMOTE_ERROR notification");
-				TRACE_DEBUG(SCTP_LEVEL, "    err : %hu", ntohs(notif->sn_remote_error.sre_error));
-				TRACE_DEBUG(SCTP_LEVEL, "    len : %hu", ntohs(notif->sn_remote_error.sre_length));
+	
+#ifdef OLD_SCTP_SOCKET_API
+			case SCTP_SEND_FAILED:
+				TRACE_DEBUG(FULL, "Received SCTP_SEND_FAILED notification");
+				TRACE_DEBUG(ANNOYING, "    len : %hu", notif->sn_send_failed.ssf_length);
+				TRACE_DEBUG(ANNOYING, "    err : %d",  notif->sn_send_failed.ssf_error);
 				
 				*event = FDEVP_CNX_ERROR;
 				break;
-	
+#else /*  OLD_SCTP_SOCKET_API */
+			case SCTP_SEND_FAILED_EVENT:
+				TRACE_DEBUG(FULL, "Received SCTP_SEND_FAILED_EVENT notification");
+				*event = FDEVP_CNX_ERROR;
+				break;
+#endif	/*  OLD_SCTP_SOCKET_API */		
 			case SCTP_SHUTDOWN_EVENT:
 				TRACE_DEBUG(FULL, "Received SCTP_SHUTDOWN_EVENT notification");
@@ -1179,8 +1276,15 @@
 				*event = FDEVP_CNX_SHUTDOWN;
 				break;
+				
+#ifndef OLD_SCTP_SOCKET_API
+			case SCTP_NOTIFICATIONS_STOPPED_EVENT:
+				TRACE_DEBUG(INFO, "Received SCTP_NOTIFICATIONS_STOPPED_EVENT notification, marking the association in error state");
+				*event = FDEVP_CNX_ERROR;
+				break;
+#endif	/*  OLD_SCTP_SOCKET_API */		
 			
 			default:	
-				TRACE_DEBUG(FULL, "Received unknown notification %d, assume error", notif->sn_header.sn_type);
-				*event = FDEVP_CNX_ERROR;
+				TRACE_DEBUG(FULL, "Received unknown notification %d, ignored", notif->sn_header.sn_type);
+				goto next_message;
 		}
 		
@@ -1196,5 +1300,9 @@
 	if (strid) {
 		struct cmsghdr 		*hdr;
+#ifdef OLD_SCTP_SOCKET_API
 		struct sctp_sndrcvinfo	*sndrcv;
+#else /*  OLD_SCTP_SOCKET_API */
+		struct sctp_rcvinfo	*rcvinf;
+#endif /*  OLD_SCTP_SOCKET_API */
 		
 		/* Handle the anciliary data */
@@ -1207,4 +1315,5 @@
 			}
 			
+#ifdef OLD_SCTP_SOCKET_API
 			/* Also only interested in SCTP_SNDRCV message for the moment */
 			if (hdr->cmsg_type != SCTP_SNDRCV) {
@@ -1214,5 +1323,5 @@
 			
 			sndrcv = (struct sctp_sndrcvinfo *) CMSG_DATA(hdr);
-			if (TRACE_BOOL(SCTP_LEVEL)) {
+			if (TRACE_BOOL(ANNOYING)) {
 				fd_log_debug( "Anciliary block IPPROTO_SCTP / SCTP_SNDRCV");
 				fd_log_debug( "    sinfo_stream    : %hu", sndrcv->sinfo_stream);
@@ -1228,4 +1337,17 @@
 
 			*strid = sndrcv->sinfo_stream;
+#else /*  OLD_SCTP_SOCKET_API */
+			/* Also only interested in SCTP_RCVINFO message for the moment */
+			if (hdr->cmsg_type != SCTP_RCVINFO) {
+				TRACE_DEBUG(FULL, "Anciliary block IPPROTO_SCTP / %d, skipped", hdr->cmsg_type);
+				continue;
+			}
+			
+			rcvinf = (struct sctp_rcvinfo *) CMSG_DATA(hdr);
+
+			*strid = rcvinf->rcv_sid;
+#endif /*  OLD_SCTP_SOCKET_API */
+			
+			
 		}
 		TRACE_DEBUG(FULL, "Received %zdb data on socket %d, stream %hu", datasize, conn->cc_socket, *strid);
