From owner-freebsd-hackers@FreeBSD.ORG Mon Jan 10 16:46:24 2005 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0C8DD16A4CE; Mon, 10 Jan 2005 16:46:24 +0000 (GMT) Received: from www.portaone.com (web.portaone.com [195.70.151.35]) by mx1.FreeBSD.org (Postfix) with ESMTP id D5F0A43D45; Mon, 10 Jan 2005 16:46:22 +0000 (GMT) (envelope-from sobomax@portaone.com) Received: from [192.168.1.26] (SIRIUS-ats227-UTC.ukrtel.net [195.5.25.154]) (authenticated bits=0) by www.portaone.com (8.12.11/8.12.11) with ESMTP id j0AGkJ03093388 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 10 Jan 2005 17:46:20 +0100 (CET) (envelope-from sobomax@portaone.com) Message-ID: <41E2B157.3080306@portaone.com> Date: Mon, 10 Jan 2005 18:46:15 +0200 From: Maxim Sobolev Organization: Porta Software Ltd User-Agent: Mozilla Thunderbird 1.0 (Windows/20041206) X-Accept-Language: en-us, en MIME-Version: 1.0 To: hackers@FreeBSD.ORG References: <41E27076.8080904@portaone.com> <41E29838.9020805@portaone.com> In-Reply-To: <41E29838.9020805@portaone.com> Content-Type: multipart/mixed; boundary="------------070202070809080104090402" X-Virus-Scanned: ClamAV 0.80/589/Wed Nov 17 13:38:41 2004 clamav-milter version 0.80j on www.portaone.com X-Virus-Status: Clean X-Mailman-Approved-At: Tue, 11 Jan 2005 13:45:50 +0000 cc: current@FreeBSD.ORG Subject: Re: Attempt to invoke connect(2) on already connected unix domain datagram socket fails with ECONNRESET X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Jan 2005 16:46:24 -0000 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--