Subject: Re: unix domain socket, behavior on close
To: None <tech-net@netbsd.org>
From: Jun-ichiro itojun Hagino <itojun@iijlab.net>
List: tech-net
Date: 03/09/2001 15:52:27
>	if a unix domain socket gets closed before the listener accepts it,
>	due to ECONNABORTED change, the listener will not be able to receive
>	the data traffic.  does the following (or something similar) look okay?
>	(move check for SO_ISDISCONNECTED down to tcp layer)

	not sure if it is completely correct.  i prefer to define some per-
	socket/per-domain flag bit somewhere.  comments?

	i'm not sure about what unix domain socket behavior should be,
	when a client closed connection before the server accepted it.
	SUSv2 accept(2) manpage does not give me enough information.

itojun


Index: kern/uipc_socket.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/uipc_socket.c,v
retrieving revision 1.54
diff -u -r1.54 uipc_socket.c
--- kern/uipc_socket.c	2001/02/27 05:19:13	1.54
+++ kern/uipc_socket.c	2001/03/09 06:50:33
@@ -256,11 +256,8 @@
 	if ((so->so_state & SS_NOFDREF) == 0)
 		panic("soaccept: !NOFDREF");
 	so->so_state &= ~SS_NOFDREF;
-	if ((so->so_state & SS_ISDISCONNECTED) == 0)
-		error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT,
-		    (struct mbuf *)0, nam, (struct mbuf *)0, (struct proc *)0);
-	else
-		error = ECONNABORTED;
+	error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT, (struct mbuf *)0,
+	    nam, (struct mbuf *)0, (struct proc *)0);
 
 	splx(s);
 	return (error);
Index: netccitt/pk_usrreq.c
===================================================================
RCS file: /cvsroot/syssrc/sys/netccitt/pk_usrreq.c,v
retrieving revision 1.19
diff -u -r1.19 pk_usrreq.c
--- netccitt/pk_usrreq.c	2000/03/30 13:53:37	1.19
+++ netccitt/pk_usrreq.c	2001/03/09 06:50:36
@@ -208,6 +208,10 @@
 		 * user.
 		 */
 	case PRU_ACCEPT:
+		if ((so->so_state & SS_ISDISCONNECTED) != 0) {
+			error = ECONNABORTED;
+			break;
+		}
 		if (lcp->lcd_craddr == NULL)
 			break;
 		pk_setpeeraddr(lcp, nam);
Index: netinet/tcp_usrreq.c
===================================================================
RCS file: /cvsroot/syssrc/sys/netinet/tcp_usrreq.c,v
retrieving revision 1.60
diff -u -r1.60 tcp_usrreq.c
--- netinet/tcp_usrreq.c	2001/02/11 06:39:35	1.60
+++ netinet/tcp_usrreq.c	2001/03/09 06:50:39
@@ -460,6 +460,10 @@
 	 * of the peer, storing through addr.
 	 */
 	case PRU_ACCEPT:
+		if ((so->so_state & SS_ISDISCONNECTED) != 0) {
+			error = ECONNABORTED;
+			break;
+		}
 #ifdef INET
 		if (inp)
 			in_setpeeraddr(inp, nam);
Index: netiso/tp_usrreq.c
===================================================================
RCS file: /cvsroot/syssrc/sys/netiso/tp_usrreq.c,v
retrieving revision 1.15
diff -u -r1.15 tp_usrreq.c
--- netiso/tp_usrreq.c	2000/03/30 13:10:16	1.15
+++ netiso/tp_usrreq.c	2001/03/09 06:50:40
@@ -560,6 +560,10 @@
 		break;
 
 	case PRU_ACCEPT:
+		if ((so->so_state & SS_ISDISCONNECTED) != 0) {
+			error = ECONNABORTED;
+			break;
+		}
 		(tpcb->tp_nlproto->nlp_getnetaddr) (tpcb->tp_npcb, nam, TP_FOREIGN);
 #ifdef ARGO_DEBUG
 		if (argo_debug[D_REQUEST]) {
Index: netns/spp_usrreq.c
===================================================================
RCS file: /cvsroot/syssrc/sys/netns/spp_usrreq.c,v
retrieving revision 1.24
diff -u -r1.24 spp_usrreq.c
--- netns/spp_usrreq.c	2000/03/30 13:02:59	1.24
+++ netns/spp_usrreq.c	2001/03/09 06:50:45
@@ -1473,6 +1473,10 @@
 	 * of the peer, storing through addr.
 	 */
 	case PRU_ACCEPT:
+		if ((so->so_state & SS_ISDISCONNECTED) != 0) {
+			error = ECONNABORTED;
+			break;
+		}
 		ns_setpeeraddr(nsp, nam);
 		break;