Skip site navigation (1)Skip section navigation (2)
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>