Date: Mon, 10 Jan 2005 18:46:15 +0200 From: Maxim Sobolev <sobomax@portaone.com> To: hackers@FreeBSD.ORG Cc: current@FreeBSD.ORG Subject: Re: Attempt to invoke connect(2) on already connected unix domain datagram socket fails with ECONNRESET Message-ID: <41E2B157.3080306@portaone.com> In-Reply-To: <41E29838.9020805@portaone.com> References: <41E27076.8080904@portaone.com> <41E29838.9020805@portaone.com>
next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------070202070809080104090402 Content-Type: text/plain; charset=KOI8-U; format=flowed Content-Transfer-Encoding: 7bit Maxim Sobolev wrote: > Further investigation revealed that the said problem only happens when > the program is trying to re-connect() socket object which previously has > been connected to the unix domain socket closed on the server side at > the time when the second connect() is called. Attached please find more > simple testcase. It seems that I've found source of the problem. It is caused by the fact that when server closes its side of unix domain socket it causes unp_drop(ref, ECONNRESET) to be called on client side of the connection, which in turn results in so_error member of client's struct socket to be set to ECONNRESET. Since we don't do any more reads on the client side of the connection, this error is never cleared up and then being picked up as a connection error by kern_connect() routine, which is obviously incorrect. The funny thing is that despite that error (ECONNRESET) one can still use resulting socket like if no error has happened. Attached please find which I believe should fix the problem in question. I would appreciate if somebody can review it. Thanks in advance! Regards, Maxim --------------070202070809080104090402 Content-Type: text/plain; name="diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="diff" Index: uipc_socket.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_socket.c,v retrieving revision 1.208.2.6 diff -d -u -r1.208.2.6 uipc_socket.c --- uipc_socket.c 16 Nov 2004 08:15:07 -0000 1.208.2.6 +++ uipc_socket.c 10 Jan 2005 16:23:07 -0000 @@ -530,10 +530,19 @@ */ if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING) && ((so->so_proto->pr_flags & PR_CONNREQUIRED) || - (error = sodisconnect(so)))) + (error = sodisconnect(so)))) { error = EISCONN; - else + } else { + SOCK_LOCK(so); + /* + * Prevent accumulated error from previous connection + * from biting us. + */ + so->so_error = 0; + SOCK_UNLOCK(so); error = (*so->so_proto->pr_usrreqs->pru_connect)(so, nam, td); + } + return (error); } --------------070202070809080104090402--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?41E2B157.3080306>