[comp.unix.questions] Perl Socket problem

frechett@spot.Colorado.EDU (-=Runaway Daemon=-) (05/31/91)

I have created an interesting server that runs on my machine.  It allows 
people to browse through an archive that I haev of hp48sx programs.  
The server is written in perl and it runs on a port of my machine.
Code fragment follows.
[deleted]
$sport = $port;  # sport is used by me for record keeping;
print "Starting server on port $port\n";
unshift(@INC,"/users/en-ecen/frechett/perl");
               require 'socket.ph';

               $sockaddr = 'S n a4 x8'; # Template for pack
# get protocol from /etc/protocols
               ($name, $aliases, $proto) = getprotobyname('tcp');
# get service by protocol name 
               ($name, $aliases, $port) = getservbyname($port, 'tcp')
                    unless $port =~ /^\d+$/;

               $this = pack($sockaddr, &AF_INET, $port, "\0\0\0\0");

               select(NS); $| = 1; select(stdout);
# Open socket
               socket(S, &PF_INET, &SOCK_STREAM, $proto) || die "socket: $!";
               bind(S, $this) || die "bind: $!";  # Bind name to socket.
               listen(S, 5) || die "connect: $!"; # Listen for connection

               select(S); $| = 1; select(stdout);

CONNECTION:         for (;;) {
                 do appendit("$sport> Listening again\n"); # Log it
                    ($addr = accept(NS,S)) || die $!
                 do appendit("$sport> accept ok\n"); # Log it
# Get Specifics on connection from addr
                    ($af,$port,$inetaddr) = unpack($sockaddr,$addr);
                    @inetaddr = unpack('C4',$inetaddr);
                do  appendit("$sport> $af port=$port Inet address @inetaddr[0].@inetaddr[1].@inetaddr[2].@inetaddr[3]\n");
# Main loop
                         select(NS);
	reset $privledged;   # Make sure privledged flag is clear. 
	do motd();
LINE:                 while (<NS>) {   # Start main loop.. Reading socket
                         chop; 
[deleted]

This is what opens the socket and gets it running.. Everthing happens 
inside this while loop.  Now this is the problem.  If someone connected to the
server from outside presses control-C it locks up the connection.  If tehy just
disconnect and come back everything is fine and if they stay connected with it
in this state teh server eventually dies.  My first try was to catch it 
with 
SIG{'INT'} but someone pointed out that this only works if connected to a tty
which appears to be true.  If I kill the server from my machine with ^C it
catches it fine and does what I want.. But when a user presses control-C it 
still doesn't catch it.  IT doesn't matter where they are or what they are
doing, if they press control-C it locks.  

SO, this leads me to believe that it is a socket problem and although there are
alot of perl hackers out there, not as many have played with sockets.  What I
need to know is if there is something special about sockets and connections of
this type that would create a problem such as this?  Is there some other way
that I can open the socket to prevent this with the same results as far as
actual operation?  I really need to work this out.  

Hmmmmmmmmmmmmmmmmmmmmmmmmmm.... Just in the last 30 seconds I found out
something else related.. I tried a few different control characters on the
server to see if anything else would kill it.  ^C ^\ and ^O all locked up the
connection.  On a hunch I toggled the autoflush on sendINT of telnet and now
none of those three control characters will do it.. This is frustrating 
because now I can't track it down to anything in particular but the combination
of an interupt and flush seem to kill it.  

Any ideas as to what might be wrong?  

	ian 
-=Runaway Daemon=-           (UNIXOPS  University of Colorado at Boulder)

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (06/02/91)

In article <1991May31.095020.15271@colorado.edu> frechett@spot.Colorado.EDU (-=Runaway Daemon=-) writes:
  [ random network code ]
> This is what opens the socket and gets it running.. Everthing happens 
> inside this while loop.  Now this is the problem.  If someone connected to the
> server from outside presses control-C it locks up the connection.

By ``connected'' you mean a telnet connection. The problem is that
TELNET is a two-way communications protocol, and when the telnet client
says ``Hey, I received a ^C, and I know that's an interrupt, so what are
you going to do about it?'' it expects an answer before it produces
further output. If you want your server to talk correctly to telnet,
you'd better support the TELNET protocol.

(You might ask at this point why every dumb little network application
has to support TELNET. The answer is that vendors don't realize the
virtue of a pure communications program---something that sets up a
connection but doesn't burden you with one protocol or another. So users
are going to use the telnet program even when the TELNET protocol is
entirely inappropriate. You might also ask why the standard TELNET
protocol daemon, namely telnetd, is so overloaded with network and pty
support. The answer, again, is that vendors don't realize the virtue of
a pure TELNET daemon---something that interprets the protocol but
doesn't assume that your application is a TCP login. So people like you
can't easily put together perfectly legitimate network applications.
Don't you feel lucky that the vendors are so smart?)

---Dan

mouse@thunder.mcrcim.mcgill.edu (der Mouse) (06/06/91)

In article <24305:Jun214:50:4891@kramden.acf.nyu.edu>, brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:

> (You might ask at this point why every dumb little network
> application has to support TELNET.  The answer is that vendors don't
> realize the virtue of a pure communications program---something that
> sets up a connection but doesn't burden you with one protocol or
> another.  [...])

Modern telnet does precisely that when you specify a port other than
the standard telnet port to connect to.

> You might also ask why the standard TELNET protocol daemon, namely
> telnetd, is so overloaded with network and pty support.  The answer,
> again, is that vendors don't realize the virtue of a pure TELNET
> daemon---something that interprets the protocol but doesn't assume
> that your application is a TCP login.

A lot of the telnet protocol features (like Interrupt Process, which we
saw in the text I didn't quote) need some sort of communication with
the daemon application other than the data byte-stream.  Propose an
interface....

> So people like you can't easily put together perfectly legitimate
> network applications.

Geesh.  Fire up ftp to uunet, fetch Berkeley telnet and/or telnetd, rip
out the pty code, and go to town.  What's the problem?

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (06/08/91)

In article <1991Jun6.143453.29926@thunder.mcrcim.mcgill.edu> mouse@thunder.mcrcim.mcgill.edu (der Mouse) writes:
> In article <24305:Jun214:50:4891@kramden.acf.nyu.edu>, brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
> > (You might ask at this point why every dumb little network
> > application has to support TELNET.  The answer is that vendors don't
> > realize the virtue of a pure communications program---something that
> > sets up a connection but doesn't burden you with one protocol or
> > another.  [...])
> Modern telnet does precisely that when you specify a port other than
> the standard telnet port to connect to.

No, it does not. The only thing it turns off is local tty processing; it
will still respond to TELNET protocol negotiations. And the original
poster was setting up a server---that's telnetd, not telnet.

> > So people like you can't easily put together perfectly legitimate
> > network applications.
> Geesh.  Fire up ftp to uunet, fetch Berkeley telnet and/or telnetd, rip
> out the pty code, and go to town.  What's the problem?

The problem is that the result isn't a standard application. How do you
expect anyone to use a server if they have to go to such lengths to make
the client? What I'm saying is that a dumb client---and a dumb server---
should be available in each vendor's distribution.

---Dan