<h2> Network I/O</h2>

 ap_socket_t *ap_create_tcp_socket(void)
	Create a new TCP network connection
     Arguments:
	return) Abstracted out ptr to file descriptor, pointing to
		 the created Socket.  NULL on failure.
	
 ap_status_t ap_shutdown(ap_socket_t *, ap_shutdown_how_e)
	shuts down part of a full-duplex connection on a specified socket
     Arguments:
	arg 1)  File descriptor of socket
	arg 2)	How to shutdown the socket.
                   One of:
			 APR_SHUTDOWN_READ
			 APR_SHUTDOWN_WRITE
			 APR_SHUTDOWN_READWRITE
        return) APR_SUCCESS or APR_FAILURE
Note:  This does not free the memory consumed by ap_socket, ap_clsoe will take
       care of that.

 ap_status_t ap_close_socket(ap_socket_t *)
        closes the socket descriptor
     Arguments:
        arg 1)  The socket to close
        return) APR_SUCCESS or APR_FAILURE 
Note:  If closing the socket fails, I am leaving the structure in tact, in the
       hopes that we may be able to close it later.  If we free all the memory
       used, we can't even try to recover.

 ap_ssize_t ap_send(ap_socket_t *, const char *, ap_int32_t, time_t)
	Sends a message over a socket
     Arguments:
	arg 1)  Pointer to abstracted socket  
	arg 2)  buffer containing message to send
	arg 3)  size of buf (in bytes)	
	arg 4)  Amount of time to wait for message to be sent completely 
                and without errors, in seconds. 
        return) The number of bytes sent over the network.  APR_FAILURE on 
                failure.

 ap_ssize_t ap_recv(ap_socket_t, char *, ap_int32_t, time_t)
	Receive a message from a socket
     Arguments:
	arg 1)  Pointer to abstracted socket  
	arg 2)  buffer to store message in
	arg 3)  size of buf (in bytes)	
	arg 4)  time to wait for message from network, in seconds.
        return) Amount of data received in bytes

 ap_status_t ap_setsocketopt(ap_socket_t *, ap_socketoption_t, ap_int32_t on);
	Set options on the specified socket
     Arguments:
	arg 1)  The abstracted socket to apply the options to
	arg 2)  The options to be applied.  Or'ed together
        	APR_SO_DEBUG
                APR_SO_KEEPALIVE
                APR_SO_LINGER
                APR_SO_NONBLOCK
                APR_SO_REUSEADDR
        arg 3)  1 if turning the option on, 0 if turning it off.
        return) APR_SUCCESS or APR_FAILURE.
Note: To unset an option, call ap_setsocketoption with the same argument. 

 void ap_sd_set(ap_socket_t *, sd_set *)
        set the bit in the ap_sd_set that corresponds to the socket
     Arguments:
        arg 1)  The socket we care about.
        arg 2)  The ap_sd_set we are adding to.

 void ap_sd_clr(ap_socket_t *, ap_sd_set *)
        clear the bit in the ap_sd_set that corresponds to the socket
     Arguments:
        arg 1)  The socket we care about.
        arg 2)  The ap_sd_set we are removing from.

 int ap_sd_isset(ap_socket_t *, ap_sd_set *)
        check the bit in the ap_sd_set that corresponds to the socket
     Arguments:
        arg 1)  The socket we care about.
        arg 2)  The ap_sd_set we are checking.
        return) APR_SUCCESS if there, APR_FAILURE otherwise

 void ap_sd_zero(ap_sd_set *)
        clear all bits in the ap_sd_set
     Arguments:
        arg 1)  The ap_sd_set we are clearing.

 ap_pollfd_t *ap_setup_poll(ap_context_t *, ap_int32_t)
        Allocate storage for poll variables.
     Arguments:
        arg 1)  Context to operate on.
        arg 2)  How many sockets to poll on.
        return) Allocated poll list.  NULL on error.

 void ap_add_poll_socket(ap_context_t *, ap_pollfd_t *, ap_socket_t *, ap_int16_t, ap_int32_t)
        Add a socket to the poll list.
     Arguments:
        arg 1)  context to operate on.
        arg 2)  poll list to add to
        arg 3)  socket to add
        arg 4)  events to listen for
        arg 5)  position in poll list.  (This may go away when I have time to do it.)

 ap_int32_t ap_poll(ap_pollfd_t *, ap_int32_t, ap_int32_t) 
	Monitor sockets for specifiedconditions. 
     Arguments:
	arg 1)  an array of sockets to monitor and events to wait for.
                valid events are:
                      APR_POLLIN     data to be read
                      APR_POLLPRI    urgent data to be read
                      APR_POLLOUT    a write will not block
                Only valid in return events:      
                      APR_ERR        an error occured
                      APR_HUP        Hung up
                      APR_NVAL       Invalid rquest, socket not open.
	arg 2)  the number of sockets in the array.
	arg 3)  the amount of time in seconds to monitor.  a negative number 
                means wait until a socket is triggered. 
	return) Number of file desriptors triggered.  0 means call timed out.
		-1 returned on failure.

 ap_status_t ap_setport(ap_socket_t *, ap_uint32_t)
        Assign the port to the socket variable.
     Arguments:
        arg 1)  The socket variable to modify.
        arg 2)  The port to be bound to the socket.
        return) APR_SUCCESS or APR_FAILURE

 ap_status_t ap_bind(ap_socket_t)
	Assign an address to an unnamed port
     Arguments:
	arg 1)  The abstracted socket to bind.
        return) APR_SUCCESS or APR_FAILURE

 ap_status_t ap_listen(ap_socket_t *, ap_int32_t)
	Mark a socket as accepting connections and limit the size of the 
	listen queue.
     Arguments:
	arg 1)  The socket to mark
	arg 2)  The size of the listen queue.
        return) APR_SUCCESS or APR_FAILURE

 ap_socket_t *ap_accept(ap_socket_t *)
	extract first connection from listen queue, and sets up a new 
	connection on a new socket of the same type and family.  It allocates
	a new socket for that connection.
     Arguments:
	arg 1)  The file desc of a socket that is listening.  The connection
		comes from this socket's listen queue.
	return) new socket that has the accepted connection.
NOTE:  accepted socket can not accept more connections.  Original socket
       remains open, and can accept more connections.

 ap_status_t ap_connect(ap_socket_t *, char *, unisigned short)
        Connect to a listening socket.
      Arguments:
        arg 1)  Socket to use to connect.
        arg 2)  hostname of the machine to connect to.
        arg 3)  port to connect to.
        return) APR_SUCCESS or APR_FAILURE. 
NOTE:  On failure, socket is closed, and memory is free'd on failure.  ALWAYS
       create the socket in ap_create_tcp_socket before calling this function.
 
char *ap_get_remote_hostname(ap_socket_t *)
        Get the host name for the remote machine
     Arguments:
        arg 1)  socket connection is on.
        return) name of remote machine. 

 ap_status_t ap_gethostname(char *, int)
       Get the host name for the machine
     Arguments:
       arg 1)  Buffer to write name to.
       arg 2)  Size of buffer.
       return) APR_SUCCESS or APR_FAILURE

 APRStatus ap_familyinet(APRInt16)
	Get the value of the address family for IP
     Arguments:
	return)  Returns the address family
 APRStatus ap_hton16(APRUInt16, APRUInt16 *)
	16 bit conversion from host to network byte order
     Arguments:
	arg 1)  the integer to convert
	arg 2)  the integer in proper  byte order. 
 APRStatus ap_ntoh16(APRUInt16, APRUInt16 *);
	16 bit conversion from network to host byte order
     Arguments:
	arg 1)  the integer to convert
	arg 2)  te integer in proper byte order.
 APRStatus ap_netaddrtostring(const APRNetAddr *, char *, APRUInt32)
	Convert an internet address to a String
     Arguments:
	arg 1)  The structure to get the Internet address from
	arg 2)  the buffer to store the converted address into
	arg 3)  The size of the buffer
 APRStatus ap_stringtonetaddr(const char *, APRNetAddr *)
	Convert a string into an internet address
     Arguments:
	arg 1)  the buffer to get the Internet address from
	arg 2)  The structure to store the converted address into
 APRStatus ap_getsockname(APRSocket, APRNetAddr *)
	retrieves the locally bound name of the specified socket.
     Arguments:
	arg 1)  The file desc of the socket to retrieve the name for.
	arg 2)  structure to store socket address in.
 APRStatus ap_initializenetaddr(APRNetAddrValue, APRUInt16, APRNetAddr);
	Initialize the fields of a APRNetAddr.  assigning well known values
	as appropriate.  This function only sets up values in the APRNetAddr
	structure.  It does not setup the connection.
     Arguments:
	arg 1)  The value to assign to the IP address portion of the 
		APRNetAddr struct.  Can only specify INADDR_ANY and
		INADR_LOOPBACK equivalents.
	arg 2)  Port number to be assigned in the struct
	arg 3)  The address of the APRNetAddr struct to be filled out.
 APRStatus ap_gethostbyname(char *, APRHostEnt)
	Lookup a host by name
     Arguments:
	arg 1)  string defining the host name of interest
	arg 2)  returns an APRHostEnt structure that has been filled out
		 on success.  On failure, it returns NULL.
 APRStatus ap_gethostbyaddr(const void *, APRInt32, APRNetAddrValue,
                             APRHostEnt)
	Lookup a host by address
     Arguments:
	arg 1)  IP addr of host, not Null-terminated string
	arg 2)  length of IP addr
	arg 3)  type of address
	arg 4)  returns an APRHostEnt structure that has been filled out
		 on success.  On failure, it returns NULL.
 APRStatus ap_enumeratehostent(APRUInt32, const APRHostEnt *, APRUInt16,
 APRNetAddr *, APRInt32);
	Evaluate each of the possible address of a Host Entry retrived from
	ap_GetHostByName or ap_GetHostByAddr.
     Arguments:
	arg 1)  The index of the enumeration.  To start, set to zero.  To
		continue, set to last returned value.
	arg 2)  pointer to structure return by ap_GetHostBy* Functions.
	arg 3)  Port number to be asssigned as part of the APRNetAddr
	        structure.
	arg 4)  Input a pointer to an APRNetAddr struct.  On output, this
	        struct
		is filled in by the runtime if the returned result is > 0.
	arg 5) Next value for the index parameter.  If 0, the enumeration
		is ended.  APR_FAILURE otherwise.



**************** IMPLEMENTATION DETAILS *****************

struct ap_socket_t {
    int socketdes
    char *remote_hostname
    struct sockaddr *addr
    size_t addr_len
}

struct ap_pollfd_t {
    ap_socket_t *sock
    ap_int16_t events
    ap_int16_t revents
}
