diff options
author | sobomax <sobomax@FreeBSD.org> | 2005-01-12 10:15:23 +0000 |
---|---|---|
committer | sobomax <sobomax@FreeBSD.org> | 2005-01-12 10:15:23 +0000 |
commit | 34354021da6a12a0dc7dfbb987f71e829fdb211f (patch) | |
tree | a77b6b9fdd7a14bd0319674c6286f996f3a64dba /sys/kern/uipc_socket.c | |
parent | a6a100526d60244a839732a35f351c046b0422fd (diff) | |
download | FreeBSD-src-34354021da6a12a0dc7dfbb987f71e829fdb211f.zip FreeBSD-src-34354021da6a12a0dc7dfbb987f71e829fdb211f.tar.gz |
When re-connecting already connected datagram socket ensure to clean
up its pending error state, which may be set in some rare conditions resulting
in connect() syscall returning that bogus error and making application believe
that attempt to change association has failed, while it has not in fact.
There is sockets/reconnect regression test which excersises this bug.
MFC after: 2 weeks
Diffstat (limited to 'sys/kern/uipc_socket.c')
-rw-r--r-- | sys/kern/uipc_socket.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index ded3825..e81166c 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -517,10 +517,19 @@ soconnect(so, nam, td) */ 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); } |