Fix the handling of out-of-band (OOB) data in a socket.
* fhandler.h (class fhandler_socket_inet): Add variable bool oobinline. * fhandler_socket_inet.cc (fhandler_socket_inet::fhandler_socket_inet): Initialize variable oobinline. (fhandler_socket_inet::recv_internal): Make the handling of OOB data as consistent with POSIX as possible. Add simulation of inline mode for OOB data as a workaround for broken winsock behavior. (fhandler_socket_inet::setsockopt): Ditto. (fhandler_socket_inet::getsockopt): Ditto. (fhandler_socket_wsock::ioctl): Fix return value of SIOCATMARK command. The return value of SIOCATMARK of winsock is almost opposite to expectation. * fhandler_socket_local.cc (fhandler_socket_local::recv_internal): Remove the handling of OOB data from AF_LOCAL domain socket. Operation related to OOB data will result in an error like Linux does. (fhandler_socket_local::sendto): Ditto. (fhandler_socket_local::sendmsg): Ditto. This fixes the issue reported in following post. https://cygwin.com/ml/cygwin/2018-06/msg00143.html
This commit is contained in:
committed by
Corinna Vinschen
parent
3baadb9912
commit
9c84bfd479
@@ -1065,7 +1065,7 @@ fhandler_socket_local::recv_internal (LPWSAMSG wsamsg, bool use_recvmsg)
|
||||
{
|
||||
ssize_t res = 0;
|
||||
DWORD ret = 0, wret;
|
||||
int evt_mask = FD_READ | ((wsamsg->dwFlags & MSG_OOB) ? FD_OOB : 0);
|
||||
int evt_mask = FD_READ;
|
||||
LPWSABUF &wsabuf = wsamsg->lpBuffers;
|
||||
ULONG &wsacnt = wsamsg->dwBufferCount;
|
||||
static NO_COPY LPFN_WSARECVMSG WSARecvMsg;
|
||||
@@ -1080,7 +1080,15 @@ fhandler_socket_local::recv_internal (LPWSAMSG wsamsg, bool use_recvmsg)
|
||||
|
||||
DWORD wait_flags = wsamsg->dwFlags;
|
||||
bool waitall = !!(wait_flags & MSG_WAITALL);
|
||||
wsamsg->dwFlags &= (MSG_OOB | MSG_PEEK | MSG_DONTROUTE);
|
||||
|
||||
/* Out-of-band data not supported by AF_LOCAL */
|
||||
if (wsamsg->dwFlags & MSG_OOB)
|
||||
{
|
||||
set_errno (EOPNOTSUPP);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
wsamsg->dwFlags &= (MSG_PEEK | MSG_DONTROUTE);
|
||||
if (use_recvmsg)
|
||||
{
|
||||
if (!WSARecvMsg
|
||||
@@ -1104,7 +1112,7 @@ fhandler_socket_local::recv_internal (LPWSAMSG wsamsg, bool use_recvmsg)
|
||||
set_winsock_errno ();
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
if (is_nonblocking () || (wsamsg->dwFlags & (MSG_OOB | MSG_PEEK)))
|
||||
if (is_nonblocking () || (wsamsg->dwFlags & MSG_PEEK))
|
||||
waitall = false;
|
||||
}
|
||||
|
||||
@@ -1114,6 +1122,7 @@ fhandler_socket_local::recv_internal (LPWSAMSG wsamsg, bool use_recvmsg)
|
||||
while (!(res = wait_for_events (evt_mask | FD_CLOSE, wait_flags))
|
||||
|| saw_shutdown_read ())
|
||||
{
|
||||
DWORD dwFlags = wsamsg->dwFlags;
|
||||
if (use_recvmsg)
|
||||
res = WSARecvMsg (get_socket (), wsamsg, &wret, NULL, NULL);
|
||||
/* This is working around a really weird problem in WinSock.
|
||||
@@ -1135,11 +1144,11 @@ fhandler_socket_local::recv_internal (LPWSAMSG wsamsg, bool use_recvmsg)
|
||||
namelen is a valid pointer while name is NULL. Both parameters are
|
||||
ignored for TCP sockets, so this only occurs when using UDP socket. */
|
||||
else if (!wsamsg->name || get_socket_type () == SOCK_STREAM)
|
||||
res = WSARecv (get_socket (), wsabuf, wsacnt, &wret, &wsamsg->dwFlags,
|
||||
res = WSARecv (get_socket (), wsabuf, wsacnt, &wret, &dwFlags,
|
||||
NULL, NULL);
|
||||
else
|
||||
res = WSARecvFrom (get_socket (), wsabuf, wsacnt, &wret,
|
||||
&wsamsg->dwFlags, wsamsg->name, &wsamsg->namelen,
|
||||
&dwFlags, wsamsg->name, &wsamsg->namelen,
|
||||
NULL, NULL);
|
||||
if (!res)
|
||||
{
|
||||
@@ -1236,6 +1245,13 @@ fhandler_socket_local::sendto (const void *in_ptr, size_t len, int flags,
|
||||
char *ptr = (char *) in_ptr;
|
||||
struct sockaddr_storage sst;
|
||||
|
||||
/* Out-of-band data not supported by AF_LOCAL */
|
||||
if (flags & MSG_OOB)
|
||||
{
|
||||
set_errno (EOPNOTSUPP);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
if (to && get_inet_addr_local (to, tolen, &sst, &tolen) == SOCKET_ERROR)
|
||||
return SOCKET_ERROR;
|
||||
|
||||
@@ -1274,6 +1290,13 @@ fhandler_socket_local::sendmsg (const struct msghdr *msg, int flags)
|
||||
struct sockaddr_storage sst;
|
||||
int len = 0;
|
||||
|
||||
/* Out-of-band data not supported by AF_LOCAL */
|
||||
if (flags & MSG_OOB)
|
||||
{
|
||||
set_errno (EOPNOTSUPP);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
if (msg->msg_name
|
||||
&& get_inet_addr_local ((struct sockaddr *) msg->msg_name,
|
||||
msg->msg_namelen, &sst, &len) == SOCKET_ERROR)
|
||||
|
Reference in New Issue
Block a user