getpeername(2) on unix domain sockets?

Mark Young myoung at ingr.UUCP
Wed Oct 26 10:14:07 AEST 1988


I have a question concerning a call to getpeername(2) in the Xwindow 
server source (version 11.2).  I am cross-posting this message to the
the X window group in hopes that someone out there will offer some
insight.

the bsd4.3 documentation for getpeername reads:

	getpeername(s,name,namelen)
	int s;
	struct sockaddr *name;
	int *namelen;

	'Getpeername' returns the name of the peer connected to socket
	's'.  The 'namelen' paramter should be initialized to indicate
	the amount of space pointed to by 'name'.  On return it contains
	the acutal size of the name returned (in bytes).  The name is 
	truncated if the buffer provided is too small.

A test case on a bsd4.3 release demonstrates that a call to getpeername 
specifying the fd for a unix domain socket returns success, with a 'namelen'
that seems somewhat random.  the 'sa_family' field, as well as the 'sa_data'
field of the sockaddr struct are all zeros, an indication that the struct
was 'bzero'd.

There are no special notes in the documentation for getpeername(2) that 
indicate wierd results with unix domain sockets.

I did note, however, that the function getsockname(2) does indeed list as 
a bug:

	Names bound to sockets in the UNIX domain are inaccessible;  
	'getsockname' returns a zero length name.

Can someone explain the behavior of the bsd4.3 system in terms of the 
documentation?  This is really strange.


/--------------------------------------------------------------------/
/--- this next section intended primarily for server implementors ---/
/--------------------------------------------------------------------/

Based upon the above documentation for getpeername, and in light of the 
documentation for getsockname, it seems like it would be nice to change
the function ConvertAddr in the file access.c.  There is no check in
ConvertAddr to make sure that the length passed is not zero, which would
indicate that the sockaddr structure and associated fields (sa_family)
would be invalid.  In fact, there is a hint in the code that someone
considered this possibility.  In the function InvalidHost, if the length
returned from getpeername is 0, the call to ConvertAddr passes a null
pointer as the length parameter just so that ConvertAddr can special 
case it.

Why not fix ConvertAddr to just check for the length equal to zero?  This
way you could remove the special case check for null and fix all the other
calls to ConvertAddr at the same time.  how about:


ConvertAddr (saddr, len, addr)
register struct sockaddr    *saddr;
int                         *len;
pointer                     *addr;
{
/*
 *   if (len == 0)  **** this is no longer needed ***
 *	return (0);
 */  

  if (*len == 0)  /* cause this fixes the REAL problem */
	return(0);

    switch (saddr->sa_family)
    {
	case AF_UNSPEC:
	case AF_UNIX:
	    return(0);

	   ...

	default:
	    break;
    }
    return(-1);
}

Forgive me if I'm missing something really obvious.  The reason that this
turned up is that our kernal folks wrote getpeername to act like the call
the getsockname in that it returns a zero length.  as far as I can tell 
using our 4.3 vax, given that it zeros out the sockaddr struct, it should
be returning zero length too!  don't have the foggiest idea why it returns
such randomness in the length parameter.


			All reasonable consideration welcome,
			Flames >/dev/null 2>&1,

						...myoung


---
ingr!myoung!myoung at uunet.uu.net       | mark allan young          | where
{uunet,ihnp4}!ingr!myoung!myoung      | intergraph corp, cr1105   | do I
                                      | one madison industrial pk | put the
"As me about our Intergraph           | huntsville, al  35807     | usual
    CLIPPER-based Workstations."      | (205) 772-6094            | disclaimer



More information about the Comp.unix.questions mailing list