From nobody@FreeBSD.org  Thu Mar 21 16:21:43 2002
Return-Path: <nobody@FreeBSD.org>
Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21])
	by hub.freebsd.org (Postfix) with ESMTP id 18D2F37B417
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 21 Mar 2002 16:21:43 -0800 (PST)
Received: (from nobody@localhost)
	by freefall.freebsd.org (8.11.6/8.11.6) id g2M0LhR46640;
	Thu, 21 Mar 2002 16:21:43 -0800 (PST)
	(envelope-from nobody)
Message-Id: <200203220021.g2M0LhR46640@freefall.freebsd.org>
Date: Thu, 21 Mar 2002 16:21:43 -0800 (PST)
From: Emmanuel Duros <eduros@udcast.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: select() always returns available for writing on SOCK_RAW socket (E.g. Divert)
X-Send-Pr-Version: www-1.0

>Number:         36184
>Category:       kern
>Synopsis:       select() always returns available for writing on SOCK_RAW socket (E.g. Divert)
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    ru
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Mar 21 16:30:01 PST 2002
>Closed-Date:    Fri Mar 22 04:52:38 PST 2002
>Last-Modified:  Fri Mar 22 04:52:38 PST 2002
>Originator:     Emmanuel Duros
>Release:        FreeBSD 4.4R
>Organization:
UDcast
>Environment:
FreeBSD box132 4.4-RELEASE FreeBSD 4.4-RELEASE #10: Thu Mar  7 18:08:57 GMT 2002
>Description:
the select() fonction seems to always return "write available" when writing to a SOCK_RAW socket. 
I am writing an application similar to natd using the DIVERT mechanism. I extract packets from the kernel and reinject them into the stack.

When the IP stack is full (eg with a bdwth limited with dumynet), the select() indicates I can still write in the socket whereas sendto() returns no buffer space available.

This pb appears with natd which starts using much cpu when the IP stack is full. For more details see: http://www.freebsd.org/cgi/query-pr.cgi?pr=36183

Is there a workaround to that ? How can we be informed that the socket is ready for writing without using an active pooling ?

Thanks...

>How-To-Repeat:
     
>Fix:
     
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->ru 
Responsible-Changed-By: cjc 
Responsible-Changed-When: Fri Mar 22 03:23:06 PST 2002 
Responsible-Changed-Why:  
Related to (same as?) PR 36183. 

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

From: Ruslan Ermilov <ru@FreeBSD.org>
To: Emmanuel Duros <eduros@udcast.com>
Cc: "Crist J. Clark" <cjc@FreeBSD.org>, bug-followup@FreeBSD.org
Subject: Re: kern/36184: select() always returns available for writing on SOCK_RAW socket (E.g. Divert)
Date: Fri, 22 Mar 2002 14:46:50 +0200

 On Thu, Mar 21, 2002 at 04:21:43PM -0800, Emmanuel Duros wrote:
 > 
 > the select() fonction seems to always return "write available" when
 > writing to a SOCK_RAW socket.  I am writing an application similar
 > to natd using the DIVERT mechanism.  I extract packets from the kernel
 > and reinject them into the stack.
 > 
 This is expected and covered in details by Richard Stevens in his TCP/IP
 Ill. Vol. 2, Section 16.13 (select System Call, Is socket writeable?).
 
 In short, with unreliable protocols like udp(4) and divert(4), no data
 is ever stored in the send buffer (because no acknowledgment is ever
 expected).  Each message is passed immediately to the protocol where
 it is queued for transmission on the appropriate network device.  In
 this case, "sb_cc" is always 0, and "sb_hiwat" specifies the maximum
 size of each write.  So, sowriteable() is always true in this case,
 because sbspace() is always equal to "sb_hiwat", which is always greater
 than or equal to "sb_lowat", and a connection is not required.
 
 > When the IP stack is full (eg with a bdwth limited with dumynet), the
 > select() indicates I can still write in the socket whereas sendto()
 > returns no buffer space available.
 > 
 This is the dummynet's pipe write routine that returns ENOBUFS (or
 network interface's output routine), not sosend().
 
 > This pb appears with natd which starts using much cpu when the IP stack
 > is full.  For more details see: http://www.freebsd.org/cgi/query-pr.cgi?pr=36183
 > 
 This problem was already fixed in recent versions of natd(8).
 
 > Is there a workaround to that?  How can we be informed that the socket
 > is ready for writing without using an active pooling?
 > 
 The socket for unreliable protocol appears to always be ready for writing.
 If you know in advance which interface the packet should go (and you perhaps
 do not!), there's probably a way to be notified through a kqueue(2) mechanism,
 but I'm not sure...
 
 
 Cheers,
 -- 
 Ruslan Ermilov		Sysadmin and DBA,
 ru@sunbay.com		Sunbay Software AG,
 ru@FreeBSD.org		FreeBSD committer,
 +380.652.512.251	Simferopol, Ukraine
 
 http://www.FreeBSD.org	The Power To Serve
 http://www.oracle.com	Enabling The Information Age
State-Changed-From-To: open->closed 
State-Changed-By: ru 
State-Changed-When: Fri Mar 22 04:51:55 PST 2002 
State-Changed-Why:  
Not a problem. 

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