NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/47569: SOCK_NONBLOCK flag to socket(2) doesn't work



>Number:         47569
>Category:       kern
>Synopsis:       SOCK_NONBLOCK flag to socket(2) doesn't work
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Feb 14 21:35:01 +0000 2013
>Originator:     Valery Ushakov
>Release:        NetBSD 6
>Organization:
>Environment:
>Description:
SOCK_NONBLOCK flag is documented in socket(2) man page to make socket
non-blocking.  Unfortunately it doesn't.

A socket created with that flag has O_NONBLOCK in flags (as per fcntl
F_GETFL), but it seems the flag is not reflected as SS_NBIO flag in
socket::so_state correctly.

A socket created without SOCK_NONBLOCK can be made nonblocking with
either fcntl(F_SETFL) that adds O_NONBLOCK, or with ioctl(FIONBIO).

A socket created with SOCK_NONBLOCK is made nonblocking with
ioctl(FIONBIO).  On the other hand since O_NONBLOCK is already set in
flags, fcntl(F_SETFL) doesn't help and you would need to do two
F_SETFL once to clear O_NONBLOCK (from SOCK_NONBLOCK) then another to
set it (and correctly push it out to so_state).

>How-To-Repeat:
I don't have a minimized test case handy and don't have time to write
one right now, but it's trivial code along the lines of

  s = socket(PF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
  status = connect(s, ...);
  /* check errno */

where the sockaddr is e.g. some non-assigned IP that would cause
ETIMEDOUT.

This code will be blocked in connect(2) and will eventually return -1
and set ETIMEDOUT instead of returning immediately and setting
EINPROGRESS.

If ioctl(FIONBIO) is added before connect(2), connect(2) does become
nonblocking.

>Fix:



Home | Main Index | Thread Index | Old Index