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.
This commit is contained in:
parent
2be07f7554
commit
3b0ba65352
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue