summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_socket.c
diff options
context:
space:
mode:
authorsobomax <sobomax@FreeBSD.org>2005-01-12 10:15:23 +0000
committersobomax <sobomax@FreeBSD.org>2005-01-12 10:15:23 +0000
commit34354021da6a12a0dc7dfbb987f71e829fdb211f (patch)
treea77b6b9fdd7a14bd0319674c6286f996f3a64dba /sys/kern/uipc_socket.c
parenta6a100526d60244a839732a35f351c046b0422fd (diff)
downloadFreeBSD-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.c13
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);
}
OpenPOWER on IntegriCloud