Subject: Re: unix domain socket, behavior on close
To: Jun-ichiro itojun Hagino <itojun@iijlab.net>
From: Jason R Thorpe <thorpej@zembu.com>
List: tech-net
Date: 03/20/2001 17:42:25
On Fri, Mar 09, 2001 at 03:52:27PM +0900, Jun-ichiro itojun Hagino wrote:

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

I like the per-proto flag, too.  How's this patch?

 > 	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.

I think I agree that any data transmitted should be actually received by
the server (which is the current behavior w/ TCP -- the connection is not
"disconnected" until the server gets the RST or the FIN exchange is finished).

-- 
        -- Jason R. Thorpe <thorpej@zembu.com>

Index: netccitt/ccitt_proto.c
===================================================================
RCS file: /cvsroot/syssrc/sys/netccitt/ccitt_proto.c,v
retrieving revision 1.11
diff -c -r1.11 ccitt_proto.c
*** netccitt/ccitt_proto.c	1999/07/01 05:53:04	1.11
--- netccitt/ccitt_proto.c	2001/03/20 23:41:19
***************
*** 87,93 ****
  	hd_init,	0,	 	hd_timer,	0,
  },
  #endif
! {	SOCK_STREAM,	DOMAIN,		CCITTPROTO_X25,	PR_CONNREQUIRED|PR_ATOMIC|PR_WANTRCVD|PR_LISTEN,
  	pk_input,	0,		pk_ctlinput,	pk_ctloutput,
  	pk_usrreq,
  	pk_init,	0,		pk_timer,	0,
--- 87,93 ----
  	hd_init,	0,	 	hd_timer,	0,
  },
  #endif
! {	SOCK_STREAM,	DOMAIN,		CCITTPROTO_X25,	PR_CONNREQUIRED|PR_ATOMIC|PR_WANTRCVD|PR_LISTEN|PR_ABRTACPTDIS,
  	pk_input,	0,		pk_ctlinput,	pk_ctloutput,
  	pk_usrreq,
  	pk_init,	0,		pk_timer,	0,
Index: netinet/in_proto.c
===================================================================
RCS file: /cvsroot/syssrc/sys/netinet/in_proto.c,v
retrieving revision 1.47
diff -c -r1.47 in_proto.c
*** netinet/in_proto.c	2001/03/01 16:31:38	1.47
--- netinet/in_proto.c	2001/03/20 23:41:19
***************
*** 165,171 ****
    udp_usrreq,
    udp_init,	0,		0,		0,		udp_sysctl
  },
! { SOCK_STREAM,	&inetdomain,	IPPROTO_TCP,	PR_CONNREQUIRED|PR_WANTRCVD|PR_LISTEN,
    tcp_input,	0,		tcp_ctlinput,	tcp_ctloutput,
    tcp_usrreq,
    tcp_init,	tcp_fasttimo,	tcp_slowtimo,	tcp_drain,	tcp_sysctl
--- 165,171 ----
    udp_usrreq,
    udp_init,	0,		0,		0,		udp_sysctl
  },
! { SOCK_STREAM,	&inetdomain,	IPPROTO_TCP,	PR_CONNREQUIRED|PR_WANTRCVD|PR_LISTEN|PR_ABRTACPTDIS,
    tcp_input,	0,		tcp_ctlinput,	tcp_ctloutput,
    tcp_usrreq,
    tcp_init,	tcp_fasttimo,	tcp_slowtimo,	tcp_drain,	tcp_sysctl
***************
*** 229,235 ****
    igmp_init,	igmp_fasttimo,	igmp_slowtimo,	0,
  },
  #ifdef TPIP
! { SOCK_SEQPACKET,&inetdomain,	IPPROTO_TP,	PR_CONNREQUIRED|PR_WANTRCVD|PR_LISTEN|PR_LASTHDR,
    tpip_input,	0,		tpip_ctlinput,	tp_ctloutput,
    tp_usrreq,
    tp_init,	0,		tp_slowtimo,	tp_drain,
--- 229,235 ----
    igmp_init,	igmp_fasttimo,	igmp_slowtimo,	0,
  },
  #ifdef TPIP
! { SOCK_SEQPACKET,&inetdomain,	IPPROTO_TP,	PR_CONNREQUIRED|PR_WANTRCVD|PR_LISTEN|PR_LASTHDR|PR_ABRTACPTDIS,
    tpip_input,	0,		tpip_ctlinput,	tp_ctloutput,
    tp_usrreq,
    tp_init,	0,		tp_slowtimo,	tp_drain,
Index: netinet6/in6_proto.c
===================================================================
RCS file: /cvsroot/syssrc/sys/netinet6/in6_proto.c,v
retrieving revision 1.28
diff -c -r1.28 in6_proto.c
*** netinet6/in6_proto.c	2001/03/01 16:31:41	1.28
--- netinet6/in6_proto.c	2001/03/20 23:41:19
***************
*** 147,153 ****
    0,		0,		0,
    udp6_sysctl,
  },
! { SOCK_STREAM,	&inet6domain,	IPPROTO_TCP,	PR_CONNREQUIRED|PR_WANTRCVD|PR_LISTEN,
    tcp6_input,	0,		tcp6_ctlinput,	tcp_ctloutput,
    tcp_usrreq,
  #ifdef INET	/* don't call initialization and timeout routines twice */
--- 147,153 ----
    0,		0,		0,
    udp6_sysctl,
  },
! { SOCK_STREAM,	&inet6domain,	IPPROTO_TCP,	PR_CONNREQUIRED|PR_WANTRCVD|PR_LISTEN|PR_ABRTACPTDIS,
    tcp6_input,	0,		tcp6_ctlinput,	tcp_ctloutput,
    tcp_usrreq,
  #ifdef INET	/* don't call initialization and timeout routines twice */
Index: netiso/iso_proto.c
===================================================================
RCS file: /cvsroot/syssrc/sys/netiso/iso_proto.c,v
retrieving revision 1.11
diff -c -r1.11 iso_proto.c
*** netiso/iso_proto.c	1999/07/01 05:53:15	1.11
--- netiso/iso_proto.c	2001/03/20 23:41:19
***************
*** 147,153 ****
  	},
  
  	/* ISOPROTO_TP */
! 	{SOCK_SEQPACKET, &isodomain, ISOPROTO_TP, PR_CONNREQUIRED | PR_WANTRCVD | PR_LISTEN,
  		tpclnp_input, 0, tpclnp_ctlinput, tp_ctloutput,
  		tp_usrreq,
  		tp_init, tp_fasttimo, tp_slowtimo, tp_drain,
--- 147,153 ----
  	},
  
  	/* ISOPROTO_TP */
! 	{SOCK_SEQPACKET, &isodomain, ISOPROTO_TP, PR_CONNREQUIRED | PR_WANTRCVD | PR_LISTEN | PR_ABRTACPTDIS,
  		tpclnp_input, 0, tpclnp_ctlinput, tp_ctloutput,
  		tp_usrreq,
  		tp_init, tp_fasttimo, tp_slowtimo, tp_drain,
***************
*** 155,161 ****
  
  #ifdef TPCONS
  	/* ISOPROTO_TP */
! 	{SOCK_SEQPACKET, &isodomain, ISOPROTO_TP0, PR_CONNREQUIRED | PR_WANTRCVD | PR_LISTEN,
  		tpcons_input, 0, 0, tp_ctloutput,
  		tp_usrreq,
  		cons_init, 0, 0, 0,
--- 155,161 ----
  
  #ifdef TPCONS
  	/* ISOPROTO_TP */
! 	{SOCK_SEQPACKET, &isodomain, ISOPROTO_TP0, PR_CONNREQUIRED | PR_WANTRCVD | PR_LISTEN | PR_ABRTACPTDIS,
  		tpcons_input, 0, 0, tp_ctloutput,
  		tp_usrreq,
  		cons_init, 0, 0, 0,
Index: netns/ns_proto.c
===================================================================
RCS file: /cvsroot/syssrc/sys/netns/ns_proto.c,v
retrieving revision 1.9
diff -c -r1.9 ns_proto.c
*** netns/ns_proto.c	1999/07/01 05:53:18	1.9
--- netns/ns_proto.c	2001/03/20 23:41:19
***************
*** 78,84 ****
    spp_usrreq,
    spp_init,	spp_fasttimo,	spp_slowtimo,	0,
  },
! { SOCK_SEQPACKET,&nsdomain,	NSPROTO_SPP,	PR_CONNREQUIRED|PR_WANTRCVD|PR_ATOMIC|PR_LISTEN,
    spp_input,	0,		spp_ctlinput,	spp_ctloutput,
    spp_usrreq_sp,
    0,		0,		0,		0,
--- 78,84 ----
    spp_usrreq,
    spp_init,	spp_fasttimo,	spp_slowtimo,	0,
  },
! { SOCK_SEQPACKET,&nsdomain,	NSPROTO_SPP,	PR_CONNREQUIRED|PR_WANTRCVD|PR_ATOMIC|PR_LISTEN|PR_ABRTACPTDIS,
    spp_input,	0,		spp_ctlinput,	spp_ctloutput,
    spp_usrreq_sp,
    0,		0,		0,		0,
Index: sys/protosw.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/protosw.h,v
retrieving revision 1.25
diff -c -r1.25 protosw.h
*** sys/protosw.h	2001/03/01 16:31:37	1.25
--- sys/protosw.h	2001/03/20 23:41:20
***************
*** 117,122 ****
--- 117,124 ----
  #define	PR_RIGHTS	0x10		/* passes capabilities */
  #define	PR_LISTEN	0x20		/* supports listen(2) and accept(2) */
  #define	PR_LASTHDR	0x40		/* enforce ipsec policy; last header */
+ #define	PR_ABRTACPTDIS	0x80		/* abort on accept(2) to disconnected
+ 					   socket */
  
  /*
   * The arguments to usrreq are:
Index: kern/uipc_socket.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/uipc_socket.c,v
retrieving revision 1.54
diff -c -r1.54 uipc_socket.c
*** kern/uipc_socket.c	2001/02/27 05:19:13	1.54
--- kern/uipc_socket.c	2001/03/20 23:41:20
***************
*** 256,262 ****
  	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
--- 256,263 ----
  	if ((so->so_state & SS_NOFDREF) == 0)
  		panic("soaccept: !NOFDREF");
  	so->so_state &= ~SS_NOFDREF;
! 	if ((so->so_state & SS_ISDISCONNECTED) == 0 ||
! 	    (so->so_proto->pr_flags & PR_ABRTACPTDIS) == 0)
  		error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT,
  		    (struct mbuf *)0, nam, (struct mbuf *)0, (struct proc *)0);
  	else