From nobody@FreeBSD.org  Tue Nov 25 10:55:54 2008
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 534341065676
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 25 Nov 2008 10:55:54 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 431398FC1C
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 25 Nov 2008 10:55:54 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id mAPAtrxI046311
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 25 Nov 2008 10:55:53 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id mAPAtr3P046310;
	Tue, 25 Nov 2008 10:55:53 GMT
	(envelope-from nobody)
Message-Id: <200811251055.mAPAtr3P046310@www.freebsd.org>
Date: Tue, 25 Nov 2008 10:55:53 GMT
From: Steven Hartland <steven.hartland@multiplay.co.uk>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Linux Emulation ENOTCONN error using non-blocking TCP
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         129169
>Category:       kern
>Synopsis:       [linux] [patch] Linux Emulation ENOTCONN error using non-blocking TCP
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    smh
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Nov 25 11:00:13 UTC 2008
>Closed-Date:    
>Last-Modified:  Thu Dec 13 22:16:58 UTC 2012
>Originator:     Steven Hartland
>Release:        7.0 RELEASE
>Organization:
Multiplay
>Environment:
FreeBSD loncore0.multiplay.co.uk 7.0-RELEASE-p3 FreeBSD 7.0-RELEASE-p3 #8: Sat Nov 22 18:46:41 GMT 2008     root@loncore0.multiplay.co.uk:/usr/src/sys/amd64/compile/MULTIPLAY  amd64
>Description:
In the Linux ABI a send() in a socket that is set non-blocking after a connect can produce ENOTCONN. This is caused by the underlying FreeBSD kernel call sendto() which checks for a connected end point, as this is still in progress, due to socket being non-blocking.

The fix is to check this condition in the Linux ABI and instead return EAGAIN which is what linux applications are expecting.

N.B. This currently breaks running Call of Duty World at War servers, specifically the server fails to authenticate with the global master server.
>How-To-Repeat:
In a linux application
1. Create a tcp socket
2. Set socket non-blocking
3. Connect to an end point
4. Perform a non-blocking send
5. ENOTCONN is returned.
>Fix:
Apply the attached patch or derivative there of.

Patch attached with submission follows:

--- linux_socket.c.orig	2008-11-22 18:26:27.000000000 +0000
+++ linux_socket.c	2008-11-22 18:44:56.000000000 +0000
@@ -878,4 +878,6 @@
 	} */ bsd_args;
 	int error;
+	struct socket *so;
+	u_int fflag;
 
 	if ((error = copyin(args, &linux_args, sizeof(linux_args))))
@@ -888,5 +890,26 @@
 	bsd_args.to = NULL;
 	bsd_args.tolen = 0;
-	return sendto(td, &bsd_args);
+	error = sendto(td, &bsd_args);
+	if ( ENOTCONN == error )
+	{
+		/*
+		 * Linux doesn't return ENOTCONN for non-blocking sockets.
+		 * Instead it returns the EAGAIN.
+		 *
+		 * XXXRW: Instead of using fgetsock(), check that it is a
+		 * socket and use the file descriptor reference instead of
+		 * creating a new one.
+		 */
+		error = fgetsock(td, linux_args.s, &so, &fflag);
+		if ( 0 == error )
+		{
+			if ( fflag & FNONBLOCK )
+			{
+				error = EAGAIN;
+			}
+			fputsock(so);
+		}
+    }
+    return (error);
 }
 


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-emulation 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Thu Nov 27 04:59:02 UTC 2008 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=129169 

From: "Steven Hartland" <killing@multiplay.co.uk>
To: <bug-followup@freebsd.org>
Cc:  
Subject: Re: kern/129169: [linux] [patch] Linux Emulation ENOTCONN error using non-blocking TCP
Date: Tue, 7 Feb 2012 09:23:44 -0000

 Any update on this?
 
Responsible-Changed-From-To: freebsd-emulation->smh 
Responsible-Changed-By: smh 
Responsible-Changed-When: Thu Dec 13 22:16:57 UTC 2012 
Responsible-Changed-Why:  
I'll take it. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=129169 
>Unformatted:
