* fhandler.h (class fhandler_socket): Add peer_sun_path member.
(fhandler_socket::set_peer_sun_path): New method. (fhandler_socket::get_peer_sun_path): New method. * fhandler_socket.cc (fhandler_socket::fhandler_socket): Initialize peer_sun_path to NULL. (fhandler_socket::~fhandler_socket): Free peer_sun_path if necessary. (fhandler_socket::dup): Duplicate peer_sun_path. (fhandler_socket::accept): Ditto. Return fake unbound peer content and len in case of AF_LOCAL sockets. (fhandler_socket::getsockname): Always use local sockaddr_storage to store socket address and copy over to incoming address. Handle every namelen correctly per POSIX. (fhandler_socket::getpeername): Ditto. Add code path to return correct value for AF_LOCAL sockets. (fhandler_socket::set_peer_sun_path): New method. * net.cc (socketpair): Set peer_sun_path to empty string, just like sun_path.
This commit is contained in:
parent
af0a038ecb
commit
d3d4aa96aa
@ -1,3 +1,23 @@
|
|||||||
|
2009-08-13 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* fhandler.h (class fhandler_socket): Add peer_sun_path member.
|
||||||
|
(fhandler_socket::set_peer_sun_path): New method.
|
||||||
|
(fhandler_socket::get_peer_sun_path): New method.
|
||||||
|
* fhandler_socket.cc (fhandler_socket::fhandler_socket): Initialize
|
||||||
|
peer_sun_path to NULL.
|
||||||
|
(fhandler_socket::~fhandler_socket): Free peer_sun_path if necessary.
|
||||||
|
(fhandler_socket::dup): Duplicate peer_sun_path.
|
||||||
|
(fhandler_socket::accept): Ditto. Return fake unbound peer content
|
||||||
|
and len in case of AF_LOCAL sockets.
|
||||||
|
(fhandler_socket::getsockname): Always use local sockaddr_storage to
|
||||||
|
store socket address and copy over to incoming address. Handle every
|
||||||
|
namelen correctly per POSIX.
|
||||||
|
(fhandler_socket::getpeername): Ditto. Add code path to return
|
||||||
|
correct value for AF_LOCAL sockets.
|
||||||
|
(fhandler_socket::set_peer_sun_path): New method.
|
||||||
|
* net.cc (socketpair): Set peer_sun_path to empty string, just like
|
||||||
|
sun_path.
|
||||||
|
|
||||||
2009-08-13 Corinna Vinschen <corinna@vinschen.de>
|
2009-08-13 Corinna Vinschen <corinna@vinschen.de>
|
||||||
Dave Korn <dave.korn.cygwin@googlemail.com>
|
Dave Korn <dave.korn.cygwin@googlemail.com>
|
||||||
|
|
||||||
|
@ -462,6 +462,7 @@ class fhandler_socket: public fhandler_base
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
char *sun_path;
|
char *sun_path;
|
||||||
|
char *peer_sun_path;
|
||||||
struct status_flags
|
struct status_flags
|
||||||
{
|
{
|
||||||
unsigned async_io : 1; /* async I/O */
|
unsigned async_io : 1; /* async I/O */
|
||||||
@ -533,6 +534,8 @@ class fhandler_socket: public fhandler_base
|
|||||||
int get_socket_type () {return type;}
|
int get_socket_type () {return type;}
|
||||||
void set_sun_path (const char *path);
|
void set_sun_path (const char *path);
|
||||||
char *get_sun_path () {return sun_path;}
|
char *get_sun_path () {return sun_path;}
|
||||||
|
void set_peer_sun_path (const char *path);
|
||||||
|
char *get_peer_sun_path () {return peer_sun_path;}
|
||||||
|
|
||||||
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||||
int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
|
int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
|
||||||
|
@ -152,6 +152,7 @@ fhandler_socket::fhandler_socket () :
|
|||||||
wsock_mtx (NULL),
|
wsock_mtx (NULL),
|
||||||
wsock_evt (NULL),
|
wsock_evt (NULL),
|
||||||
sun_path (NULL),
|
sun_path (NULL),
|
||||||
|
peer_sun_path (NULL),
|
||||||
status ()
|
status ()
|
||||||
{
|
{
|
||||||
need_fork_fixup (true);
|
need_fork_fixup (true);
|
||||||
@ -161,6 +162,8 @@ fhandler_socket::~fhandler_socket ()
|
|||||||
{
|
{
|
||||||
if (sun_path)
|
if (sun_path)
|
||||||
cfree (sun_path);
|
cfree (sun_path);
|
||||||
|
if (peer_sun_path)
|
||||||
|
cfree (peer_sun_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
@ -664,6 +667,7 @@ fhandler_socket::dup (fhandler_base *child)
|
|||||||
if (get_addr_family () == AF_LOCAL)
|
if (get_addr_family () == AF_LOCAL)
|
||||||
{
|
{
|
||||||
fhs->set_sun_path (get_sun_path ());
|
fhs->set_sun_path (get_sun_path ());
|
||||||
|
fhs->set_peer_sun_path (get_peer_sun_path ());
|
||||||
if (get_socket_type () == SOCK_STREAM)
|
if (get_socket_type () == SOCK_STREAM)
|
||||||
{
|
{
|
||||||
fhs->sec_pid = sec_pid;
|
fhs->sec_pid = sec_pid;
|
||||||
@ -1043,7 +1047,7 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (get_addr_family () == AF_LOCAL && (!res || in_progress))
|
if (get_addr_family () == AF_LOCAL && (!res || in_progress))
|
||||||
set_sun_path (name->sa_data);
|
set_peer_sun_path (name->sa_data);
|
||||||
|
|
||||||
if (get_addr_family () == AF_LOCAL && get_socket_type () == SOCK_STREAM)
|
if (get_addr_family () == AF_LOCAL && get_socket_type () == SOCK_STREAM)
|
||||||
{
|
{
|
||||||
@ -1141,6 +1145,7 @@ fhandler_socket::accept (struct sockaddr *peer, int *len)
|
|||||||
if (get_addr_family () == AF_LOCAL)
|
if (get_addr_family () == AF_LOCAL)
|
||||||
{
|
{
|
||||||
sock->set_sun_path (get_sun_path ());
|
sock->set_sun_path (get_sun_path ());
|
||||||
|
sock->set_peer_sun_path (get_peer_sun_path ());
|
||||||
if (get_socket_type () == SOCK_STREAM)
|
if (get_socket_type () == SOCK_STREAM)
|
||||||
{
|
{
|
||||||
/* Don't forget to copy credentials from accepting
|
/* Don't forget to copy credentials from accepting
|
||||||
@ -1162,11 +1167,23 @@ fhandler_socket::accept (struct sockaddr *peer, int *len)
|
|||||||
sock->connect_state (connected);
|
sock->connect_state (connected);
|
||||||
res = res_fd;
|
res = res_fd;
|
||||||
if (peer)
|
if (peer)
|
||||||
|
{
|
||||||
|
if (get_addr_family () == AF_LOCAL)
|
||||||
|
{
|
||||||
|
/* FIXME: Right now we have no way to determine the
|
||||||
|
bound socket name of the peer's socket. For now
|
||||||
|
we just fake an unbound socket on the other side. */
|
||||||
|
static struct sockaddr_un un = { AF_LOCAL, "" };
|
||||||
|
*len = min (*len, 2);
|
||||||
|
memcpy (peer, &un, *len);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
*len = min (*len, llen);
|
*len = min (*len, llen);
|
||||||
memcpy (peer, &lpeer, *len);
|
memcpy (peer, &lpeer, *len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
closesocket (res);
|
closesocket (res);
|
||||||
@ -1186,28 +1203,29 @@ fhandler_socket::getsockname (struct sockaddr *name, int *namelen)
|
|||||||
|
|
||||||
if (get_addr_family () == AF_LOCAL)
|
if (get_addr_family () == AF_LOCAL)
|
||||||
{
|
{
|
||||||
struct sockaddr_un *sun = (struct sockaddr_un *) name;
|
struct sockaddr_un sun;
|
||||||
memset (sun, 0, *namelen);
|
sun.sun_family = AF_LOCAL;
|
||||||
sun->sun_family = AF_LOCAL;
|
sun.sun_path[0] = '\0';
|
||||||
|
if (get_sun_path ())
|
||||||
if (!get_sun_path ())
|
strncat (sun.sun_path, get_sun_path (), UNIX_PATH_LEN - 1);
|
||||||
sun->sun_path[0] = '\0';
|
*namelen = min (*namelen, (int) SUN_LEN (&sun) + 1);
|
||||||
else
|
memcpy (name, &sun, *namelen);
|
||||||
/* According to SUSv2 "If the actual length of the address is
|
|
||||||
greater than the length of the supplied sockaddr structure, the
|
|
||||||
stored address will be truncated." We play it save here so
|
|
||||||
that the path always has a trailing 0 even if it's truncated. */
|
|
||||||
strncpy (sun->sun_path, get_sun_path (),
|
|
||||||
*namelen - sizeof *sun + sizeof sun->sun_path - 1);
|
|
||||||
|
|
||||||
*namelen = sizeof *sun - sizeof sun->sun_path
|
|
||||||
+ strlen (sun->sun_path) + 1;
|
|
||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = ::getsockname (get_socket (), name, namelen);
|
/* Always use a local big enough buffer and truncate later as necessary
|
||||||
if (res)
|
per POSIX. WinSock unfortunaltey only returns WSAEFAULT if the buffer
|
||||||
|
is too small. */
|
||||||
|
struct sockaddr_storage sock;
|
||||||
|
int len = sizeof sock;
|
||||||
|
res = ::getsockname (get_socket (), (struct sockaddr *) &sock, &len);
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
*namelen = min (*namelen, len);
|
||||||
|
memcpy (name, &sock, *namelen);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (WSAGetLastError () == WSAEINVAL)
|
if (WSAGetLastError () == WSAEINVAL)
|
||||||
{
|
{
|
||||||
@ -1219,11 +1237,11 @@ fhandler_socket::getsockname (struct sockaddr *name, int *namelen)
|
|||||||
{
|
{
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
res = 0;
|
res = 0;
|
||||||
*namelen = sizeof (struct sockaddr_in);
|
*namelen = min (*namelen, (int) sizeof (struct sockaddr_in));
|
||||||
break;
|
break;
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
res = 0;
|
res = 0;
|
||||||
*namelen = sizeof (struct sockaddr_in6);
|
*namelen = min (*namelen, (int) sizeof (struct sockaddr_in6));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
WSASetLastError (WSAEOPNOTSUPP);
|
WSASetLastError (WSAEOPNOTSUPP);
|
||||||
@ -1246,9 +1264,30 @@ fhandler_socket::getsockname (struct sockaddr *name, int *namelen)
|
|||||||
int
|
int
|
||||||
fhandler_socket::getpeername (struct sockaddr *name, int *namelen)
|
fhandler_socket::getpeername (struct sockaddr *name, int *namelen)
|
||||||
{
|
{
|
||||||
int res = ::getpeername (get_socket (), name, namelen);
|
/* Always use a local big enough buffer and truncate later as necessary
|
||||||
|
per POSIX. WinSock unfortunately only returns WSAEFAULT if the buffer
|
||||||
|
is too small. */
|
||||||
|
struct sockaddr_storage sock;
|
||||||
|
int len = sizeof sock;
|
||||||
|
int res = ::getpeername (get_socket (), (struct sockaddr *) &sock, &len);
|
||||||
if (res)
|
if (res)
|
||||||
set_winsock_errno ();
|
set_winsock_errno ();
|
||||||
|
else if (get_addr_family () == AF_LOCAL)
|
||||||
|
{
|
||||||
|
struct sockaddr_un sun;
|
||||||
|
memset (&sun, 0, sizeof sun);
|
||||||
|
sun.sun_family = AF_LOCAL;
|
||||||
|
sun.sun_path[0] = '\0';
|
||||||
|
if (get_peer_sun_path ())
|
||||||
|
strncat (sun.sun_path, get_peer_sun_path (), UNIX_PATH_LEN - 1);
|
||||||
|
*namelen = min (*namelen, (int) SUN_LEN (&sun) + 1);
|
||||||
|
memcpy (name, &sun, *namelen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*namelen = min (*namelen, len);
|
||||||
|
memcpy (name, &sock, *namelen);
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -1915,6 +1954,12 @@ fhandler_socket::set_sun_path (const char *path)
|
|||||||
sun_path = path ? cstrdup (path) : NULL;
|
sun_path = path ? cstrdup (path) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_socket::set_peer_sun_path (const char *path)
|
||||||
|
{
|
||||||
|
peer_sun_path = path ? cstrdup (path) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_socket::getpeereid (pid_t *pid, __uid32_t *euid, __gid32_t *egid)
|
fhandler_socket::getpeereid (pid_t *pid, __uid32_t *euid, __gid32_t *egid)
|
||||||
{
|
{
|
||||||
|
@ -2867,6 +2867,7 @@ socketpair (int family, int type, int protocol, int *sb)
|
|||||||
if (sb0 >= 0 && fdsock (sb0, dev, insock))
|
if (sb0 >= 0 && fdsock (sb0, dev, insock))
|
||||||
{
|
{
|
||||||
((fhandler_socket *) sb0)->set_sun_path ("");
|
((fhandler_socket *) sb0)->set_sun_path ("");
|
||||||
|
((fhandler_socket *) sb0)->set_peer_sun_path ("");
|
||||||
((fhandler_socket *) sb0)->set_addr_family (family);
|
((fhandler_socket *) sb0)->set_addr_family (family);
|
||||||
((fhandler_socket *) sb0)->set_socket_type (type);
|
((fhandler_socket *) sb0)->set_socket_type (type);
|
||||||
((fhandler_socket *) sb0)->connect_state (connected);
|
((fhandler_socket *) sb0)->connect_state (connected);
|
||||||
@ -2878,6 +2879,7 @@ socketpair (int family, int type, int protocol, int *sb)
|
|||||||
if (sb1 >= 0 && fdsock (sb1, dev, outsock))
|
if (sb1 >= 0 && fdsock (sb1, dev, outsock))
|
||||||
{
|
{
|
||||||
((fhandler_socket *) sb1)->set_sun_path ("");
|
((fhandler_socket *) sb1)->set_sun_path ("");
|
||||||
|
((fhandler_socket *) sb1)->set_peer_sun_path ("");
|
||||||
((fhandler_socket *) sb1)->set_addr_family (family);
|
((fhandler_socket *) sb1)->set_addr_family (family);
|
||||||
((fhandler_socket *) sb1)->set_socket_type (type);
|
((fhandler_socket *) sb1)->set_socket_type (type);
|
||||||
((fhandler_socket *) sb1)->connect_state (connected);
|
((fhandler_socket *) sb1)->connect_state (connected);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user