* 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:
		@@ -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>
 | 
			
		||||
	    Dave Korn <dave.korn.cygwin@googlemail.com>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -462,6 +462,7 @@ class fhandler_socket: public fhandler_base
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  char *sun_path;
 | 
			
		||||
  char *peer_sun_path;
 | 
			
		||||
  struct status_flags
 | 
			
		||||
  {
 | 
			
		||||
    unsigned async_io              : 1; /* async I/O */
 | 
			
		||||
@@ -533,6 +534,8 @@ class fhandler_socket: public fhandler_base
 | 
			
		||||
  int get_socket_type () {return type;}
 | 
			
		||||
  void set_sun_path (const char *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 fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
 | 
			
		||||
 
 | 
			
		||||
@@ -152,6 +152,7 @@ fhandler_socket::fhandler_socket () :
 | 
			
		||||
  wsock_mtx (NULL),
 | 
			
		||||
  wsock_evt (NULL),
 | 
			
		||||
  sun_path (NULL),
 | 
			
		||||
  peer_sun_path (NULL),
 | 
			
		||||
  status ()
 | 
			
		||||
{
 | 
			
		||||
  need_fork_fixup (true);
 | 
			
		||||
@@ -161,6 +162,8 @@ fhandler_socket::~fhandler_socket ()
 | 
			
		||||
{
 | 
			
		||||
  if (sun_path)
 | 
			
		||||
    cfree (sun_path);
 | 
			
		||||
  if (peer_sun_path)
 | 
			
		||||
    cfree (peer_sun_path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *
 | 
			
		||||
@@ -664,6 +667,7 @@ fhandler_socket::dup (fhandler_base *child)
 | 
			
		||||
  if (get_addr_family () == AF_LOCAL)
 | 
			
		||||
    {
 | 
			
		||||
      fhs->set_sun_path (get_sun_path ());
 | 
			
		||||
      fhs->set_peer_sun_path (get_peer_sun_path ());
 | 
			
		||||
      if (get_socket_type () == SOCK_STREAM)
 | 
			
		||||
	{
 | 
			
		||||
	  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))
 | 
			
		||||
    set_sun_path (name->sa_data);
 | 
			
		||||
    set_peer_sun_path (name->sa_data);
 | 
			
		||||
 | 
			
		||||
  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)
 | 
			
		||||
	    {
 | 
			
		||||
	      sock->set_sun_path (get_sun_path ());
 | 
			
		||||
	      sock->set_peer_sun_path (get_peer_sun_path ());
 | 
			
		||||
	      if (get_socket_type () == SOCK_STREAM)
 | 
			
		||||
		{
 | 
			
		||||
		  /* Don't forget to copy credentials from accepting
 | 
			
		||||
@@ -1163,8 +1168,20 @@ fhandler_socket::accept (struct sockaddr *peer, int *len)
 | 
			
		||||
	  res = res_fd;
 | 
			
		||||
	  if (peer)
 | 
			
		||||
	    {
 | 
			
		||||
	      *len = min (*len, llen);
 | 
			
		||||
	      memcpy (peer, &lpeer, *len);
 | 
			
		||||
	      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);
 | 
			
		||||
		  memcpy (peer, &lpeer, *len);
 | 
			
		||||
		}
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
      else
 | 
			
		||||
@@ -1186,28 +1203,29 @@ fhandler_socket::getsockname (struct sockaddr *name, int *namelen)
 | 
			
		||||
 | 
			
		||||
  if (get_addr_family () == AF_LOCAL)
 | 
			
		||||
    {
 | 
			
		||||
      struct sockaddr_un *sun = (struct sockaddr_un *) name;
 | 
			
		||||
      memset (sun, 0, *namelen);
 | 
			
		||||
      sun->sun_family = AF_LOCAL;
 | 
			
		||||
 | 
			
		||||
      if (!get_sun_path ())
 | 
			
		||||
	sun->sun_path[0] = '\0';
 | 
			
		||||
      else
 | 
			
		||||
	/* 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;
 | 
			
		||||
      struct sockaddr_un sun;
 | 
			
		||||
      sun.sun_family = AF_LOCAL;
 | 
			
		||||
      sun.sun_path[0] = '\0';
 | 
			
		||||
      if (get_sun_path ())
 | 
			
		||||
      	strncat (sun.sun_path, get_sun_path (), UNIX_PATH_LEN - 1);
 | 
			
		||||
      *namelen = min (*namelen, (int) SUN_LEN (&sun) + 1);
 | 
			
		||||
      memcpy (name, &sun, *namelen);
 | 
			
		||||
      res = 0;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      res = ::getsockname (get_socket (), name, namelen);
 | 
			
		||||
      if (res)
 | 
			
		||||
      /* Always use a local big enough buffer and truncate later as necessary
 | 
			
		||||
	 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)
 | 
			
		||||
	    {
 | 
			
		||||
@@ -1219,11 +1237,11 @@ fhandler_socket::getsockname (struct sockaddr *name, int *namelen)
 | 
			
		||||
		{
 | 
			
		||||
		case AF_INET:
 | 
			
		||||
		  res = 0;
 | 
			
		||||
		  *namelen = sizeof (struct sockaddr_in);
 | 
			
		||||
		  *namelen = min (*namelen, (int) sizeof (struct sockaddr_in));
 | 
			
		||||
		  break;
 | 
			
		||||
		case AF_INET6:
 | 
			
		||||
		  res = 0;
 | 
			
		||||
		  *namelen = sizeof (struct sockaddr_in6);
 | 
			
		||||
		  *namelen = min (*namelen, (int) sizeof (struct sockaddr_in6));
 | 
			
		||||
		  break;
 | 
			
		||||
		default:
 | 
			
		||||
		  WSASetLastError (WSAEOPNOTSUPP);
 | 
			
		||||
@@ -1246,9 +1264,30 @@ fhandler_socket::getsockname (struct sockaddr *name, int *namelen)
 | 
			
		||||
int
 | 
			
		||||
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)
 | 
			
		||||
    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;
 | 
			
		||||
}
 | 
			
		||||
@@ -1915,6 +1954,12 @@ fhandler_socket::set_sun_path (const char *path)
 | 
			
		||||
  sun_path = path ? cstrdup (path) : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
fhandler_socket::set_peer_sun_path (const char *path)
 | 
			
		||||
{
 | 
			
		||||
  peer_sun_path = path ? cstrdup (path) : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
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))
 | 
			
		||||
      {
 | 
			
		||||
	((fhandler_socket *) sb0)->set_sun_path ("");
 | 
			
		||||
	((fhandler_socket *) sb0)->set_peer_sun_path ("");
 | 
			
		||||
	((fhandler_socket *) sb0)->set_addr_family (family);
 | 
			
		||||
	((fhandler_socket *) sb0)->set_socket_type (type);
 | 
			
		||||
	((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))
 | 
			
		||||
	  {
 | 
			
		||||
	    ((fhandler_socket *) sb1)->set_sun_path ("");
 | 
			
		||||
	    ((fhandler_socket *) sb1)->set_peer_sun_path ("");
 | 
			
		||||
	    ((fhandler_socket *) sb1)->set_addr_family (family);
 | 
			
		||||
	    ((fhandler_socket *) sb1)->set_socket_type (type);
 | 
			
		||||
	    ((fhandler_socket *) sb1)->connect_state (connected);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user