🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: net.lan
Article #1128

Re: bsd networking primitives

#1128
From: Chris Torek
Date: Wed, 06 Aug 1986 02:13
268 lines
7782 bytes
In article <523@rna.UUCP> kc@rna.UUCP (Kaare Christian) writes:
>For ipc in the Unix domain it seems that both parties need a bind
>following socket creation, but when ipc is in the internet domain only
>the server needs a bind.  Why??

Sounds like a bug to me.  It is not true in 4.3BSD beta-plus-upgrades.
(See example programs below.)

>Ques 2. When you use the internet domain, but client and server are on
>the same machine, does your data go though the loop back connection?
>Is this the reason for the loop back connection.

Actually, that depends on the driver.  Some Ethernet boards cannot send
to themselves; so drivers for those will call the loopback driver in
such cases.  Other boards do not have this limitation, but usually the
driver will call the loopback code anyway.

I threw the following code together to see whether the client needed
to bind before connecting.  (It did not.)  Extract the files (the
script makes a fresh directory for them), compile, and run with an
argument as to what socket to create.  Careful: `se' (the server)
removes any file with the same name as that socket.

: Run this shell script with "sh" not "csh"
PATH=/bin:/usr/bin:/usr/ucb:/etc:$PATH
export PATH
all=FALSE
if [ x$1 = x-a ]; then
	all=TRUE
fi
echo Making directory test_AF_UNIX
mkdir test_AF_UNIX
echo Extracting test_AF_UNIX/Makefile
sed 's/^X//' <<'//go.sysin dd *' >test_AF_UNIX/Makefile
DESTDIR=
CFLAGS=	-O

STD=	cl se

all: ${STD}

${STD}: error.o
	${CC} ${CFLAGS} -o $@ $@.c error.o

install:
	@echo "test programs are never installed, silly!"

clean:
	rm -f *.o *.s a.out core *.bak
	rm -f ${STD}

depend:
	for i in ${STD} error; do \
	    ${CC} -M $$i.c | sed -e 's/\.o//' | \
	    awk '{ if ($$1 != prev) { if (rec != "") print rec; \
		rec = $$0; prev = $$1; } \
		else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \
		else rec = rec " " $$2 } } \
		END { print rec }'; done >makedep
	echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep
	echo '$$r makedep' >>eddep
	echo 'w' >>eddep
	cp Makefile Makefile.bak
	ed - Makefile <eddep
	rm eddep makedep
	echo '# DEPENDENCIES MUST END AT END OF FILE' >>Makefile
	echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >>Makefile
	echo '# see make depend above' >>Makefile

# DO NOT DELETE THIS LINE -- make depend uses it

cl: cl.c /usr/include/stdio.h /usr/include/sys/types.h
cl: /usr/include/sys/socket.h /usr/include/sys/un.h
se: se.c /usr/include/stdio.h /usr/include/sys/types.h
se: /usr/include/sys/socket.h /usr/include/sys/un.h
error: error.c /usr/include/stdio.h
# DEPENDENCIES MUST END AT END OF FILE
# IF YOU PUT STUFF HERE IT WILL GO AWAY
# see make depend above
//go.sysin dd *
if [ `wc -c < test_AF_UNIX/Makefile` != 1238 ]; then
	made=FALSE
	echo error transmitting test_AF_UNIX/Makefile --
	echo length should be 1238, not `wc -c < test_AF_UNIX/Makefile`
else
	made=TRUE
fi
if [ $made = TRUE ]; then
	chmod 644 test_AF_UNIX/Makefile
	echo -n '	'; ls -ld test_AF_UNIX/Makefile
fi
echo Extracting test_AF_UNIX/cl.c
sed 's/^X//' <<'//go.sysin dd *' >test_AF_UNIX/cl.c
X/*
 * client
 */

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

#define suntosa(x) ((struct sockaddr *) (x))
#define namesize(x) (strlen((x)->sun_path) + sizeof ((x)->sun_family))

struct	sockaddr_un servname;
int	servsock;

extern int errno;

char	*strcpy();

main(argc, argv)
	int argc;
	char **argv;
{
	char buf[20];

	if (argc < 2)
		error(1, 0, "usage: cl <server>");
	if ((servsock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
		error(1, errno, "socket");
	servname.sun_family = AF_UNIX;
	(void) strcpy(servname.sun_path, argv[1]);
	if (connect(servsock, suntosa(&servname), namesize(&servname)))
		error(1, errno, "connect");
	if (write(servsock, "hi", 2) != 2)
		error(1, errno, "write");
	if (read(servsock, buf, 5) != 5)
		error(1, errno, "read");
	buf[5] = 0;
	printf("\"hi\" => \"%s\"\n", buf);
	exit(0);
}
//go.sysin dd *
if [ `wc -c < test_AF_UNIX/cl.c` != 855 ]; then
	made=FALSE
	echo error transmitting test_AF_UNIX/cl.c --
	echo length should be 855, not `wc -c < test_AF_UNIX/cl.c`
else
	made=TRUE
fi
if [ $made = TRUE ]; then
	chmod 644 test_AF_UNIX/cl.c
	echo -n '	'; ls -ld test_AF_UNIX/cl.c
fi
echo Extracting test_AF_UNIX/error.c
sed 's/^X//' <<'//go.sysin dd *' >test_AF_UNIX/error.c
X/*
 * For other systems... mine comes from my C library.
 */

#ifdef lint

X/*VARARGS3 ARGSUSED*/
error(quit, e, fmt) int quit, e; char *fmt; {;}

#else

#include <stdio.h>

char	*_argv0;	/* set by C start up code before calling main */

error(quit, e, fmt, args)
	int quit;
	register int e;
	char *fmt;
{
	extern char *sys_errlist[];
	extern int sys_nerr;

	if (_argv0)
		(void) fprintf(stderr, "%s: ", _argv0);
	_doprnt(fmt, &args, stderr);
	if (e) {
		if (e < sys_nerr)
			(void) fprintf(stderr, ": %s", sys_errlist[e]);
		else
			(void) fprintf(stderr, ": unknown error code %d", e);
	}
	(void) putc('\n', stderr);
	(void) fflush(stderr);
	if (quit)
		exit(quit);
}

#endif
//go.sysin dd *
if [ `wc -c < test_AF_UNIX/error.c` != 677 ]; then
	made=FALSE
	echo error transmitting test_AF_UNIX/error.c --
	echo length should be 677, not `wc -c < test_AF_UNIX/error.c`
else
	made=TRUE
fi
if [ $made = TRUE ]; then
	chmod 644 test_AF_UNIX/error.c
	echo -n '	'; ls -ld test_AF_UNIX/error.c
fi
echo Extracting test_AF_UNIX/se.c
sed 's/^X//' <<'//go.sysin dd *' >test_AF_UNIX/se.c
X/*
 * server
 */

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

#define suntosa(x) ((struct sockaddr *) (x))
#define namesize(x) (strlen((x)->sun_path) + sizeof ((x)->sun_family))

struct	sockaddr_un servname, cliname;
int	servsock, clisock;

extern int errno;

char	*strcpy();

main(argc, argv)
	int argc;
	char **argv;
{
	char buf[20];
	int fromlen;

	if (argc < 2)
		error(1, 0, "usage: se <server>");
	if ((servsock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
		error(1, errno, "socket");
	(void) unlink(argv[1]);		/* clear the way */
	servname.sun_family = AF_UNIX;
	(void) strcpy(servname.sun_path, argv[1]);
	if (bind(servsock, suntosa(&servname), namesize(&servname)))
		error(1, errno, "connect");
	if (listen(servsock, 1))
		error(1, errno, "listen");
	fromlen = sizeof (cliname);
	if ((clisock = accept(servsock, suntosa(&cliname), &fromlen)) < 0)
		error(1, errno, "accept");
	if (read(clisock, buf, 2) != 2)
		error(1, errno, "read");
	if (write(clisock, "there", 5) != 5)
		error(1, errno, "write");
	exit(0);
}
//go.sysin dd *
if [ `wc -c < test_AF_UNIX/se.c` != 1063 ]; then
	made=FALSE
	echo error transmitting test_AF_UNIX/se.c --
	echo length should be 1063, not `wc -c < test_AF_UNIX/se.c`
else
	made=TRUE
fi
if [ $made = TRUE ]; then
	chmod 644 test_AF_UNIX/se.c
	echo -n '	'; ls -ld test_AF_UNIX/se.c
fi
made=TRUE
if [ $made = TRUE ]; then
	chmod 755 test_AF_UNIX
	echo -n '	'; ls -ld test_AF_UNIX
fi
-- 
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
Technical Details
Message-ID: <2745@umcp-cs.UUCP>
Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!caip!lll-crg!seismo!umcp-cs!chris
References: <523@rna.UUCP>

Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!caip!lll-crg!seismo!umcp-cs!chris
From: chris@umcp-cs.UUCP (Chris Torek)
Newsgroups: net.lan
Subject: Re: bsd networking primitives
Message-ID: <2745@umcp-cs.UUCP>
Date: Tue, 5-Aug-86 22:13:43 EDT
Article-I.D.: umcp-cs.2745
Posted: Tue Aug  5 22:13:43 1986
Date-Received: Thu, 7-Aug-86 05:57:51 EDT
References: <523@rna.UUCP>
Reply-To: chris@maryland.UUCP (Chris Torek)
Organization: University of Maryland, Dept. of Computer Sci.
Lines: 268