[erlang-questions] prim_inet:accept() bug with {fd, N} socket option?

Per Hedeland <>
Mon Oct 8 14:42:03 CEST 2007


Serge Aleynikov <> wrote:
>
>Per Hedeland wrote:
>
>> I converted the patch to match R11B-5, it was pretty trivial, but let me
>> know if you want it (untested though).
>
>Yes, please. Since I haven't applied it yet, I'd rather start with what 
>you have for R11B-5 to begin with.

Below - it does compile at least (all three times:-).

--Per


--- otp_src_R11B-5/erts/emulator/drivers/common/inet_drv.c.ORIG	2007-10-07 19:13:52.000000000 +0200
+++ otp_src_R11B-5/erts/emulator/drivers/common/inet_drv.c	2007-10-07 19:40:05.000000000 +0200
@@ -4821,9 +4821,17 @@
 }
 #endif
 
+/* Per H @ Tail-f: The original code here had problems that possibly
+   only occur if you abuse it for non-INET sockets, but anyway:
+   a) If the getsockopt for SO_PRIORITY or IP_TOS failed, the actual
+      requested setsockopt was never even attempted.
+   b) If {get,set}sockopt for one of IP_TOS and SO_PRIORITY failed,
+      but ditto for the other worked and that was actually the requested
+      option, failure was still reported to erlang.                  */
+
 #if  defined(IP_TOS) && defined(SOL_IP) && defined(SO_PRIORITY)
 static int setopt_prio_tos_trick
-	   (int fd, int proto, int type, char* arg_ptr, int arg_sz)
+	(int fd, int proto, int type, char* arg_ptr, int arg_sz, int propagate)
 {
     /* The relations between SO_PRIORITY, TOS and other options
        is not what you (or at least I) would expect...:
@@ -4836,6 +4844,8 @@
     int          tmp_ival_prio;
     int          tmp_ival_tos;
     int          res;
+    int          res_prio;
+    int          res_tos;
 #ifdef HAVE_SOCKLEN_T
 	    socklen_t
 #else
@@ -4844,30 +4854,30 @@
 		tmp_arg_sz_prio = sizeof(tmp_ival_prio),
 		tmp_arg_sz_tos  = sizeof(tmp_ival_tos);
 
-    res = sock_getopt(fd, SOL_SOCKET, SO_PRIORITY,
-		      (char *) &tmp_ival_prio, &tmp_arg_sz_prio);
+    res_prio = sock_getopt(fd, SOL_SOCKET, SO_PRIORITY,
+			   (char *) &tmp_ival_prio, &tmp_arg_sz_prio);
+    res_tos = sock_getopt(fd, SOL_IP, IP_TOS, 
+			  (char *) &tmp_ival_tos, &tmp_arg_sz_tos);
+    res = sock_setopt(fd, proto, type, arg_ptr, arg_sz);
     if (res == 0) {
-	res = sock_getopt(fd, SOL_IP, IP_TOS, 
-		      (char *) &tmp_ival_tos, &tmp_arg_sz_tos);
-	if (res == 0) {
-	    res = sock_setopt(fd, proto, type, arg_ptr, arg_sz);
-	    if (res == 0) {
-		if (type != SO_PRIORITY) {
-		    if (type != IP_TOS) {
-			res = sock_setopt(fd, 
-					  SOL_IP, 
-					  IP_TOS,
-					  (char *) &tmp_ival_tos, 
-					  tmp_arg_sz_tos);
-		    }
-		    if (res == 0) {
-			res =  sock_setopt(fd, 
-					   SOL_SOCKET, 
-					   SO_PRIORITY,
-					   (char *) &tmp_ival_prio, 
-					   tmp_arg_sz_prio);
-		    }
-		}
+	if (type != SO_PRIORITY) {
+	    if (type != IP_TOS && res_tos == 0) {
+		res_tos = sock_setopt(fd, 
+				      SOL_IP, 
+				      IP_TOS,
+				      (char *) &tmp_ival_tos, 
+				      tmp_arg_sz_tos);
+		if (propagate)
+		    res = res_tos;
+	    }
+	    if (res == 0 && res_prio == 0) {
+		res_prio = sock_setopt(fd, 
+				       SOL_SOCKET, 
+				       SO_PRIORITY,
+				       (char *) &tmp_ival_prio, 
+				       tmp_arg_sz_prio);
+		if (propagate)
+		    res = res_prio;
 	    }
 	}
     }
@@ -5205,7 +5215,7 @@
 	    return -1;
 	}
 #if  defined(IP_TOS) && defined(SOL_IP) && defined(SO_PRIORITY)
-	res = setopt_prio_tos_trick (desc->s, proto, type, arg_ptr, arg_sz);
+	res = setopt_prio_tos_trick (desc->s, proto, type, arg_ptr, arg_sz, propagate);
 #else
 	res = sock_setopt	    (desc->s, proto, type, arg_ptr, arg_sz);
 #endif
@@ -5718,7 +5728,7 @@
 	    return -1;
 	}
 #if  defined(IP_TOS) && defined(SOL_IP) && defined(SO_PRIORITY)
-	res = setopt_prio_tos_trick (desc->s, proto, type, arg_ptr, arg_sz);
+	res = setopt_prio_tos_trick (desc->s, proto, type, arg_ptr, arg_sz, 1);
 #else
 	res = sock_setopt	    (desc->s, proto, type, arg_ptr, arg_sz);
 #endif



More information about the erlang-questions mailing list