[comp.unix.programmer] binding sockets

eran@elaine7.stanford.edu (eran yehudai) (09/15/90)

I am trying to use bind() to create an entry in the file system for a
socket. I find that a socket special file is created, but its name is
only composed of the first two letters of the name I pass the system.
The same phenomena occurs on both DEC3100 and a NeXT. Any ideas?
--
Eran Yehudai
eran@thsun1.slac.stanford.edu

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (09/15/90)

In article <ERAN.90Sep14115242@elaine7.stanford.edu> eran@elaine7.stanford.edu (eran yehudai) writes:
: I am trying to use bind() to create an entry in the file system for a
: socket. I find that a socket special file is created, but its name is
: only composed of the first two letters of the name I pass the system.
: The same phenomena occurs on both DEC3100 and a NeXT. Any ideas?

I suspect you're calling bind with two arguments instead of three, and
the stack garbage happens to have a value of 2.

Larry Wall
lwall@jpl-devvax.jpl.nasa.gov

eran@adelbert9.stanford.edu (eran yehudai) (09/15/90)

It seems the namelen parameter one passes bind() should be
2 + strlen(socketname), and then everything works. 

--
Eran Yehudai
eran@thsun1.slac.stanford.edu

jik@athena.mit.edu (Jonathan I. Kamens) (09/17/90)

In article <ERAN.90Sep14175746@adelbert9.stanford.edu>, eran@adelbert9.stanford.edu (eran yehudai) writes:
|> It seems the namelen parameter one passes bind() should be
|> 2 + strlen(socketname), and then everything works. 

  No, actually, the namelen parameter one passes to bind() should be the
sizeof the sockaddr structure being passed into it, e.g. (error checking
omitted):

   #include <sys/types.h>
   #include <sys/socket.h>
   #include <sys/un.h>
   #include <strings.h>

   struct sockaddr_un name;
   int s;

   name.sun_family = AF_UNIX;
   strcpy(name.sun_path, "/tmp/testsocket");
   s = socket(PF_UNIX, SOCK_STREAM, 0);
   bind(s, &name, sizeof(name));

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8495			      Home: 617-782-0710

chris@mimsy.umd.edu (Chris Torek) (09/19/90)

In article <1990Sep16.183730.18698@athena.mit.edu>
jik@athena.mit.edu (Jonathan I. Kamens) writes:
>  No, actually, the namelen parameter one passes to bind() should be the
>sizeof the sockaddr structure being passed into it ...

Well, it `should' be 2+strlen(path), or (in 4.3BSD-reno) SUN_LEN:

>   name.sun_family = AF_UNIX;
>   strcpy(name.sun_path, "/tmp/testsocket");
>   bind(s, &name, sizeof(name));

    bind(s, &name, SUN_LEN(name));

Since the size of a sockaddr_un is carefully set to fill one mbuf, using
sizeof(name) will work, and you can `cheat' and just use sizeof(name): the
embedded '\0' will (must) be within the resulting single mbuf allocated
by the bind() system call and the name lookup will work.  But the
documentation (such as it is) says that the name length `should' be
exactly right, and a future version of the system might require this.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

jeffe@sandino.austin.ibm.com (Peter Jeffe 512.823.4091) (09/20/90)

In article <26618@mimsy.umd.edu> chris@mimsy.umd.edu (Chris Torek) writes:
>In article <1990Sep16.183730.18698@athena.mit.edu>
>jik@athena.mit.edu (Jonathan I. Kamens) writes:
>>  No, actually, the namelen parameter one passes to bind() should be the
>>sizeof the sockaddr structure being passed into it ...
>
>Well, it `should' be 2+strlen(path), or (in 4.3BSD-reno) SUN_LEN:

Not to quibble, but it `should' be "sizeof(name.sun_family)+strlen(path)";
or better yet, "sizeof(name)-sizeof(name.sun_path)+strlen(path)"; in any
case, assuming the 2 bytes is not a good idea.

-------------------------------------------------------------------------------
Peter Jeffe   ...uunet!cs.utexas.edu!ibmaus!auschs!sandino.austin.ibm.com!jeffe
        first they want a disclaimer, then they make you pee in a jar,
                   then they come for you in the night

chris@mimsy.umd.edu (Chris Torek) (09/20/90)

>In article <26618@mimsy.umd.edu> I wrote:
>>[namelen] `should' be 2+strlen(path), or (in 4.3BSD-reno) SUN_LEN:

In article <3580@awdprime.UUCP>
jeffe@sandino.austin.ibm.com (Peter Jeffe 512.823.4091) writes:
>Not to quibble, but it `should' be "sizeof(name.sun_family)+strlen(path)";

Not so---and I specifically wrote `2' to avoid this---because in
4.3BSD-reno the result will be one byte too short.  (You must also
include sizeof(name.sun_len), which is 1.)

>or better yet, "sizeof(name)-sizeof(name.sun_path)+strlen(path)";

This will work, and is how SUN_LEN is defined.

>in any case, assuming the 2 bytes is not a good idea.

Recommendation: add the following to your code, and then use SUN_LEN.

#ifndef SUN_LEN
/* actual length of an initialized sockaddr_un */
#define SUN_LEN(su) \
	(sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
#endif


>
>-------------------------------------------------------------------------------
>Peter Jeffe   ...uunet!cs.utexas.edu!ibmaus!auschs!sandino.austin.ibm.com!jeffe
>        first they want a disclaimer, then they make you pee in a jar,
>                   then they come for you in the night


-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

jik@athena.mit.edu (Jonathan I. Kamens) (09/24/90)

  Now I'm confused.

  First of all, I thought all of the sockaddr structures (in 4.3BSD, "all"
means sockaddr_in and sockaddr_un, unless I've forgotten something :-) are
padded so that they're the same length.  Is this not correct?

  Second, the documentation in /usr/doc/ps1/07.ipctut and /usr/doc/ps1/08.ipc
all uses sizeof() on the sockaddr structure to get the third argument to
bind().  Is that documentation all wrong, and if so, is it updated in 4.3-Reno?

  And finally, what do you mean when you say that the documentation "says that
the name length `should' be exactly right"?  I can't find any documentation
anywhere, including the bind(2) man page in 4.3, that even mentions the
namelen argument, let alone describes what it should be, and all the
documentation that *does* show calls to bind() shows them using sizeof(), as I
did.

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8495			      Home: 617-782-0710

chris@mimsy.umd.edu (Chris Torek) (09/25/90)

In article <1990Sep24.082942.10213@athena.mit.edu> jik@athena.mit.edu
(Jonathan I. Kamens) writes:
>  First of all, I thought all of the sockaddr structures (in 4.3BSD, "all"
>means sockaddr_in and sockaddr_un, unless I've forgotten something :-) are
>padded so that they're the same length.  Is this not correct?

4.3BSD-tahoe also has `sockaddr_xn', which is padded.  However, a
sockaddr_un is 112 bytes, and sockaddr_in and sockaddr_xn are both 16
bytes (and the same size as `sizeof(struct sockaddr)').

>  Second, the documentation in /usr/doc/ps1/07.ipctut and /usr/doc/ps1/08.ipc
>all uses sizeof() on the sockaddr structure to get the third argument to
>bind().  Is that documentation all wrong,

It is now.

>and if so, is it updated in 4.3-Reno?

Not yet (or at least, I have not updated ours).

>And finally, what do you mean when you say that the documentation "says that
>the name length `should' be exactly right"?  I can't find any documentation
>anywhere ....

I guess maybe we never got around to writing it yet. :-)

There was always a sneaky suspicion that a constant (`sizeof(...)' is
always a constant) was not right.  It worked for TCP/IP and for XNS,
but it did not work properly for path names (a kludge---using the
maximum size the current implementation could handle---made it
function).  Now, with ISO variable-length addresses, it also does not
work for TP.

The solution was to discard `backwards compatibility' except where such
was essentially free, i.e., Internet, XNS, and---at least temporarily---
Unix domain sockets.  (`Backwards compatibility means we get to keep
all our old mistakes.')

The iso(4) man page in 4.3-reno hints at the fact that sizeof() will fail
under some circumstances, but is not clear on what is the `right' value
for namelen.  Something should be done about this someday.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris