[net.unix-wizards] Socket Addresses

shaun@sauron.OZ (Shaun ARundell) (08/03/86)

In have been working on a BSD4.3 ipc program and have come across
a few things that puzzel me.

The format for a socket address in <sys/socket.h> is

struct sockaddr {
	u_short	sa_family;		/* address family */
	char	sa_data[14];		/* up to 14 bytes of direct address */
};

May times I have seen a AF_UNIX address structure like

struct sa {
	short	family;
	char	path[LARGE_NUMBER];
};

I take that this means that a socket address structure for AF_UNIX
consists of a short (decribing the family) and as much data following
that as you want.

This would make sense. We all know (I think) that the socket system
calls impose no address structure on the sockets but that different 
families expect there addresses in a certin formats.

NOW  - what can you say something like this

server - 
	s = socket(AF_UNIX,  SOCK_STREAM, 0);
	...
	bind(s, "server", sizeof( "server" ) );
	...
	listen(s, 5)
	...
	accept(s, &from, &fromlen ); 

client -

	s = socket(AF_UNIX, SOCK_STREAM, 0 );
	...
	bind(s, "client", sizeof( "another_server" ) );
	...
	connect(s, "server" , sizeof("server") );
	...

	chat away

socket ADDRESSES have me confused. Can any body clear up the 
confusion.



     \XX	Shaun  Arundell		ARPA: munnari!sauron.oz!shaun@SEISMO
      \X	Technical Support	UUCP: seismo!munnari!sauron.oz!shaun
XXXXX  \XXXX    GOULD COMPUTERS		ACS:  shaun@sauron.oz
XXXXX  /XXXX   
      /X 	Telephone	        STD:  (02) 957-2522
     /XX            			ISD: +61 2 957-2522 

chris@umcp-cs.UUCP (Chris Torek) (08/04/86)

In article <155@sauron.OZ> shaun@sauron.UUCP (Shaun ARundell) writes:
>In have been working on a BSD4.3 ipc program ....  [Many] times
>I have seen a AF_UNIX address structure like
>
>struct sa {
>	short	family;
>	char	path[LARGE_NUMBER];
>};

Actually, it is

	struct sockaddr_un {
		short	sun_family;
		char	sun_path[108];
	};

and comes from <sys/un.h>.

>I take that this means that a socket address structure for AF_UNIX
>consists of a short (decribing the family) and as much data following
>that as you want.

Not quite: it is a short (specifying AF_UNIX) and a path name.
The name must be small enough to fit in an `mbuf' (a kernel data
object that has no business leaking restrictions into the Unix
namespace:  it was just expedient).  That is why there is a
107-character limit on the name.  (If you use all 108 bytes, you
will get EINVAL when you try to bind or connect.  This is more
expediency: the kernel null-terminates the name and passes it into
namei().)

>This would make sense. We all know (I think) that the socket system
>calls impose no address structure on the sockets but that different 
>families expect there addresses in a certin formats.

It is not *supposed* to impose a structure.  Ah well.

>NOW  - what can you say something like this
>
>server - 
>	s = socket(AF_UNIX,  SOCK_STREAM, 0);
>	...
>	bind(s, "server", sizeof( "server" ) );

No!  Try this instead:

	int s;
	struct sockaddr_un name;

	s = socket(AF_UNIX, SOCK_STREAM, 0);
	...
	name.sun_family = AF_UNIX;
	name.sun_name = "server";
	if (bind(s, (struct sockaddr *) &name, strlen(name.sun_name))) ...

Incidentally, as it says in the revised IPC primer, there is a
natural temptation to use

	struct sockaddr_un sun;

but this fails on a certain manufacturer's 68000-based systems. . . .
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu

chris@umcp-cs.UUCP (Chris Torek) (08/05/86)

In article <2725@umcp-cs.UUCP> I wrote:
>	int s;
>	struct sockaddr_un name;
>
>	s = socket(AF_UNIX, SOCK_STREAM, 0);
>	...
>	name.sun_family = AF_UNIX;
>	name.sun_name = "server";
>	if (bind(s, (struct sockaddr *) &name, strlen(name.sun_name))) ...

Ai!  This is all wrong (and will not even compile)!  Better (tested
even):

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

char	*strcpy(*);

/*ARGSUSED*/
main(argc, argv)
	int argc;
	char **argv;
{
	int s;
	struct sockaddr_un name;

	if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
		perror("socket");
		exit(1);
	}
	name.sun_family = AF_UNIX;
	(void) strcpy(name.sun_path, "server");
	(void) unlink(name.sun_path);	/* delete previous socket, if any */
	if (bind(s, (struct sockaddr *) &name,
	    sizeof (name.sun_family) + strlen(name.sun_path))) {
		perror("bind");
		exit(1);
	}

	/*
	 * Thanks to John Bruner for pointing out the missing
	 * sizeof name.sun_family.  The rest of the corrections are
	 * from the revised 4.3 IPC primer---I should have known,
	 * since I helped revise it, and we tried to ensure that all
	 * the examples worked.
	 *
	 * Incidentally, there is a hidden assumption about structure
	 * padding even in the above.  This `path name' business needs
	 * work.
	 */

	exit(0);
}
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu

chris@umcp-cs.UUCP (Chris Torek) (08/05/86)

In article <2731@umcp-cs.UUCP> I wrote:
>Better (tested even):
...
>char	*strcpy(*);

The second asterisk was not in the tested version---a slip of the
figners :-).

Incidentally, there were two minor typographical errors in two
other recent articles of mine as well.  In the `definitive article
on multi-linguistic linking', change psub.p's `csub(i)' to `csub2(i)';
and in the one on termcap, change

	/* init expansion pointer *?

to

	/* init expansion pointer */

Fortunately, neither example compiles with the error in place.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu