public inbox for cygwin-cvs@sourceware.org help / color / mirror / Atom feed
From: Ken Brown <kbrown@sourceware.org> To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin] Cygwin: connect: implement resetting a connected DGRAM socket Date: Tue, 27 Apr 2021 14:16:07 +0000 (GMT) [thread overview] Message-ID: <20210427141607.905BF3894C36@sourceware.org> (raw) https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=3b0ba6535218631b1ab467cd29d36b1eae4a0af6 commit 3b0ba6535218631b1ab467cd29d36b1eae4a0af6 Author: Ken Brown <kbrown@cornell.edu> Date: Fri Apr 23 18:17:57 2021 -0400 Cygwin: connect: implement resetting a connected DGRAM socket Following POSIX and Linux, allow a connected DGRAM socket's connection to be reset (so that the socket becomes unconnected). This is done by calling connect and specifing an address whose family is AF_UNSPEC. Diff: --- winsup/cygwin/fhandler_socket_inet.cc | 21 +++++++++++++++++++-- winsup/cygwin/fhandler_socket_local.cc | 30 +++++++++++++++++++++++++----- winsup/cygwin/fhandler_socket_unix.cc | 7 +++++++ winsup/cygwin/release/3.2.1 | 5 +++++ 4 files changed, 56 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/fhandler_socket_inet.cc b/winsup/cygwin/fhandler_socket_inet.cc index f6bb8c503..30eab4099 100644 --- a/winsup/cygwin/fhandler_socket_inet.cc +++ b/winsup/cygwin/fhandler_socket_inet.cc @@ -781,8 +781,20 @@ int fhandler_socket_inet::connect (const struct sockaddr *name, int namelen) { struct sockaddr_storage sst; + bool reset = (name->sa_family == AF_UNSPEC + && get_socket_type () == SOCK_DGRAM); - if (get_inet_addr_inet (name, namelen, &sst, &namelen) == SOCKET_ERROR) + if (reset) + { + if (connect_state () == unconnected) + return 0; + /* To reset a connected DGRAM socket, call Winsock's connect + function with the address member of the sockaddr structure + filled with zeroes. */ + memset (&sst, 0, sizeof sst); + sst.ss_family = get_addr_family (); + } + else if (get_inet_addr_inet (name, namelen, &sst, &namelen) == SOCKET_ERROR) return SOCKET_ERROR; /* Initialize connect state to "connect_pending". In the SOCK_STREAM @@ -804,7 +816,12 @@ fhandler_socket_inet::connect (const struct sockaddr *name, int namelen) int res = ::connect (get_socket (), (struct sockaddr *) &sst, namelen); if (!res) - connect_state (connected); + { + if (reset) + connect_state (unconnected); + else + connect_state (connected); + } else if (!is_nonblocking () && res == SOCKET_ERROR && WSAGetLastError () == WSAEWOULDBLOCK) diff --git a/winsup/cygwin/fhandler_socket_local.cc b/winsup/cygwin/fhandler_socket_local.cc index 1c8d48b58..bd4081622 100644 --- a/winsup/cygwin/fhandler_socket_local.cc +++ b/winsup/cygwin/fhandler_socket_local.cc @@ -894,19 +894,34 @@ fhandler_socket_local::connect (const struct sockaddr *name, int namelen) { struct sockaddr_storage sst; int type = 0; + bool reset = (name->sa_family == AF_UNSPEC + && get_socket_type () == SOCK_DGRAM); - if (get_inet_addr_local (name, namelen, &sst, &namelen, &type, connect_secret) - == SOCKET_ERROR) + if (reset) + { + if (connect_state () == unconnected) + return 0; + /* To reset a connected DGRAM socket, call Winsock's connect + function with the address member of the sockaddr structure + filled with zeroes. */ + memset (&sst, 0, sizeof sst); + sst.ss_family = get_addr_family (); + } + else if (get_inet_addr_local (name, namelen, &sst, &namelen, &type, + connect_secret) == SOCKET_ERROR) return SOCKET_ERROR; - if (get_socket_type () != type) + if (get_socket_type () != type && !reset) { WSASetLastError (WSAEPROTOTYPE); set_winsock_errno (); return SOCKET_ERROR; } - set_peer_sun_path (name->sa_data); + if (reset) + set_peer_sun_path (NULL); + else + set_peer_sun_path (name->sa_data); /* Don't move af_local_set_cred into af_local_connect which may be called via select, possibly running under another identity. Call early here, @@ -933,7 +948,12 @@ fhandler_socket_local::connect (const struct sockaddr *name, int namelen) int res = ::connect (get_socket (), (struct sockaddr *) &sst, namelen); if (!res) - connect_state (connected); + { + if (reset) + connect_state (unconnected); + else + connect_state (connected); + } else if (!is_nonblocking () && res == SOCKET_ERROR && WSAGetLastError () == WSAEWOULDBLOCK) diff --git a/winsup/cygwin/fhandler_socket_unix.cc b/winsup/cygwin/fhandler_socket_unix.cc index 252bcd9a9..a2428e952 100644 --- a/winsup/cygwin/fhandler_socket_unix.cc +++ b/winsup/cygwin/fhandler_socket_unix.cc @@ -1696,6 +1696,13 @@ fhandler_socket_unix::connect (const struct sockaddr *name, int namelen) conn_unlock (); return -1; } + if (name->sa_family == AF_UNSPEC && get_socket_type () == SOCK_DGRAM) + { + connect_state (unconnected); + peer_sun_path (NULL); + conn_unlock (); + return 0; + } connect_state (connect_pending); conn_unlock (); /* Check validity of name */ diff --git a/winsup/cygwin/release/3.2.1 b/winsup/cygwin/release/3.2.1 index 7662c7114..6ebe68fa6 100644 --- a/winsup/cygwin/release/3.2.1 +++ b/winsup/cygwin/release/3.2.1 @@ -28,3 +28,8 @@ Bug Fixes - Fix a bug in recognizing a successful completion of connect(2) on a datagram socket. + +- Fix connect(2) when called with an address structure whose family is + AF_UNSPEC. As specified by POSIX and Linux, this is allowed on + datagram sockets, and its effect is to reset the socket's peer + address.
reply other threads:[~2021-04-27 14:16 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210427141607.905BF3894C36@sourceware.org \ --to=kbrown@sourceware.org \ --cc=cygwin-cvs@sourceware.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).