packages icon
olib 1.0.1 -- a simple set of re-useable c++ objects

Copyright/General Information
-----------------------------
Copyright 1998 Kyle R. Burton, All Rights Reserved 
				 Email:  mortis@voicenet.com
         Web:    http://www.voicenet.com/~mortis/tcp_server

  This package can be freely distributed and used under the terms of the
GNU General Public License, either version 2 or (at your opinion) any later
version. See the file COPYING or see http://www.gnu.org/ for more detains 
on the GNU project.

	Send all comments and suggestions to the author:
		Kyle R. Burton  mortis@voicenet.com
		(I'd love to know if/how you're using this code)

  The most recent version(s) can currently be obtained from:
		http://www.voicenet.com/~mortis/projects/tcp_server


Synopsis
--------
  This is just a set of small, mostly template based, generic C++ objects.

  This program provides a server that listens on a tcp socket, takes the
first line of input from the client connection, and execs a predefined
process to handle the connection.  It ties the input/output of the handler
process to the socket.  This makes writing the handler processes extrememly
simple -- all they need to do is read from standard in, and write to standard 
out.  This even allows you to use anything that can use stdin/stdout to
handle the connections, this includes:  shell scripts, perl, python, lisp,
C, C++, pascal, assembler, basic, expect, fortran, and just about any other
programming language you can think of.


Building the software
---------------------
  First off, you'll need to get my library: o'lib.  You can get it from:
http://www.voicenet.com/~mortis/projects/lib.   Untar it into it's own 
directory.  The best way to do this is at the same directory level that
you put tcp_sever at.  If you unarchive tcp_server in a directory
/stuff, you'll end up with /stuff/tcp_server, unarchive olib in the
same place, so you end up with /stuff/olib.

	All the code should be pretty much platform independant.  I've just
started using autoconf (the thing that creates the configure script),
so it may or may not be what you expect.  You'll have to have olib
built before you try to run the configure script for tcp_server.
The configure script looks for olib in '../olib'.  If olib is not in
'../olib' (e.g. it's in olib-1.0.1 because that's where it untarred to),
you can set the following two enviornment variables:

[mortis@warhammer tcp_server-1.0.1]$ export USER_OLIB_HEADERS=/home/mortis/projects/olib-1.0.1/include
[mortis@warhammer tcp_server-1.0.1]$ export USER_OLIB_LIB=/home/mortis/projects/olib-1.0.1/src

If all this stuff is set up, then just run configure, and then make.

[mortis@warhammer tcp_server-1.0.1]$ ./configure
[mortis@warhammer tcp_server-1.0.1]$ make

To test it, you can cd into the test directory, and run it like this:

[mortis@warhammer test]$ ../src/tcp_server

Then from another terminal, telnet to the machine on port 4137, and type
  test_server
and hit enter.  The test server is a perl script that just echo's back
whatever you send it - line by line.  The only exception is a line that 
starts with quit, which causes it to exit.  By defualt, there should be
alot of output from the server.

Oh, something else to keep in mind is that the default conf file restricts
client connections to the local machine.

  
Writing a Protocol Handler
--------------------------
  Just make something that reads from stdin, and writes to stdout!
You should need to write exactly zero lines of socket code.  See echo.pl
for a simple example.

  Please be aware that there are a plethora of dangerous things you can do 
with this code.  Special care should be taken when writing protocol handlers, 
as small mistakes could cause severe security issues with the machine you're 
running it on.  Remember, there is no warranty with this software, all use is
at YOUR OWN risk.

The three standard file descriptors
  stdin  - filedes 0 
  stdout - filedes 1
  stderr - filedes 2 
should all be bound to the socket by the time your handler starts.



Problems/General Issues
----------------------------
Q:  Why won't tcp_server/olib compile under compiler X?
A:  
  I've only tested it under the egcs version of g++: egcs-2.90.27 under 
linux, and aCC under HP-UX,.  From what I know of using some other compilers 
(like g++ v2.7.2) is that they lack the ability to properly generate the 
specializations for the template code.


Q:  Why does the bind step always fail for ports < 1024?
A:
  You need to be root to run a process that binds to a port less than 1024.
This is a restriction imposed by most operating systems, and is for security 
reasons.  tcp_server is not necessarily in and of itself insecure, but I 
wouldn't personaly run it on any of the standard ports...


Q:  Why does tcp_server fail with a message like "can't rebind to port WXYZ"
during a restart after I kill it?
A:
	There are 2 possible things happening here:
1 - if a client is still connected to the server, _or_ if the process
forked() by the server doesn't exit, then the socket will never get closed.
If this happens, then according to the IP stack, there is still something
listening on the port in question.

2 - This behaviour has been observed under HP-UX.  Something about the IP
stack on HP doesn't free the port.  I've never really investigated this issue
on HP.  If I wait a few minutes before trying to re-use the same port, 
HP seems fine.  I'd appricate hearing any other input anyone has.

  Thanks to: itamars@ibm.net for helping me flesh this question out.



Changes/Revisions
-----------------
Sat Jan  2 21:08:47 EST 1999 1.0.2 - applied patch submitted by 
  Kevin <kevin.ng@reuters.com> to src/c_socket.cc and test/test.cc that
  fixed broken compiles on earlier versions of g++ than mentioned
  above.

Mon Mar 29 09:53:37 EST 1999 1.0.4-SunOS - this version has 1 minor bug
  fix to c_socket::get_line(), and porting changes for SunOS.  For now, the
  detection of SunOS isn't automatic via configure, so to get it to compile
  properly for SunOS, you'll have to add -D_SUN_OS to the CCFLAGS in the 
  generated make file(s).  When I've got time (and learn how to do it 
  correctly), I'll merge these into the normal configure script.

	The bug in get_line() caused it to overrun the read buffer - it wasn't 
	paying attention to the size that was passed in correctly.