[SR-Dev] git:ser_core_cvs: sctp: fix partial delivery point setting on linux

Andrei Pelinescu-Onciul andrei at iptel.org
Thu May 21 17:47:38 CEST 2009


Module: sip-router
Branch: ser_core_cvs
Commit: f9437a7d00b7eb8fcfa7facec9a3c90555fc7901
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=f9437a7d00b7eb8fcfa7facec9a3c90555fc7901

Author: Andrei Pelinescu-Onciul <andrei at iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei at iptel.org>
Date:   Thu May 21 15:24:57 2009 +0000

sctp: fix partial delivery point setting on linux

To disable partial delivery, the partial delivery point should be
set to the socket receive buffer size. However on linux SO_RCVBUF
will return twice the value (the "real" value, which is twice the
value used when setting SO_RCVBUF) and SCTP_PARTIAL_DELIVERY_POINT
expects value/2.

---

 sctp_server.c |   33 ++++++++++++++++++++++++++++-----
 1 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/sctp_server.c b/sctp_server.c
index 077947d..424def8 100644
--- a/sctp_server.c
+++ b/sctp_server.c
@@ -195,6 +195,8 @@ static int sctp_init_sock_opt_common(int s)
 {
 	struct sctp_event_subscribe es;
 	int optval;
+	int pd_point;
+	int saved_errno;
 	socklen_t optlen;
 	int sctp_err;
 	
@@ -267,13 +269,34 @@ static int sctp_init_sock_opt_common(int s)
 		/* try to continue */
 		optval=0;
 	}
-	if (setsockopt(s, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT,
-					(void*)&optval, sizeof(optval)) ==-1){
-		LOG(L_ERR, "ERROR: sctp_init_sock_opt_common: setsockopt: "
+#ifdef __OS_linux
+	optval/=2; /* in linux getsockopt() returns twice the set value */
+#endif
+	pd_point=optval;
+	saved_errno=0;
+	while(pd_point &&
+			setsockopt(s, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT,
+					(void*)&pd_point, sizeof(pd_point)) ==-1){
+		if (!saved_errno)
+			saved_errno=errno;
+		pd_point--;
+	}
+	
+	if (pd_point!=optval){
+		if (pd_point==0){
+			/* all attempts failed */
+			LOG(L_ERR, "ERROR: sctp_init_sock_opt_common: setsockopt: "
 						"SCTP_PARTIAL_DELIVERY_POINT (%d): %s\n",
 						optval, strerror(errno));
-		sctp_err++;
-		/* try to continue */
+			sctp_err++;
+			/* try to continue */
+		}else{
+			/* success but to a lower value (might not be disabled) */
+			LOG(L_WARN, "setsockopt SCTP_PARTIAL_DELIVERY_POINT set to %d, but"
+				" the socket rcvbuf is %d (higher values fail with"
+				" \"%s\" [%d])\n",
+				pd_point, optval, strerror(saved_errno), saved_errno);
+		}
 	}
 #else
 #warning no sctp lib support for SCTP_PARTIAL_DELIVERY_POINT, consider upgrading




More information about the sr-dev mailing list