105 lines
2.9 KiB
Plaintext
105 lines
2.9 KiB
Plaintext
Overview of the network subsystem
|
|
Adrian Chadd <adrian@creative.net.au>
|
|
|
|
|
|
|
|
This document is an overview of the new and hopefully improved network
|
|
subsystem.
|
|
|
|
The code is based loosely upon the network core found in the Squid web cache
|
|
server, with some optimizations for ircd-specific IO patterns.
|
|
|
|
|
|
|
|
Filedescriptor IO
|
|
-----------------
|
|
|
|
Filedescriptor IO is initiated using comm_setselect(). comm_setselect()
|
|
registers interest in reading from or writing to a file descriptor.
|
|
When a filedescriptor is ready for the required IO a callback is called
|
|
from the IO loop.
|
|
|
|
The comm_setselect() usage is:
|
|
|
|
void
|
|
comm_setselect(int fd, fdlist_t list, int type, PF *callback, void *cbdata,
|
|
int timeout)
|
|
|
|
where:
|
|
fd filedescriptor
|
|
list Which list the FD should be put on
|
|
type IO type. Can currently include:
|
|
COMM_SELECT_READ - register for read
|
|
COMM_SELECT_WRITE - register for write
|
|
callback Function to call when the FD is ready
|
|
cbdata Data to be passed to above function
|
|
timeout Update the timeout value. 0 is "don't update".
|
|
|
|
|
|
A typical use is:
|
|
|
|
..
|
|
|
|
/* Register interest in the FD for a read event */
|
|
comm_setselect(fd, FDLIST_SERVICE, COMM_SELECT_READ, read_callback, read_data,
|
|
0);
|
|
|
|
..
|
|
|
|
(FD becomes ready for read in the IO loop)
|
|
|
|
void
|
|
read_callback(int fd, void *data)
|
|
{
|
|
/* called when the FD becomes ready for read */
|
|
retval = read(fd, buf, len);
|
|
|
|
..
|
|
/* Ok, we need to read some more when its ready */
|
|
comm_setselect(fd, FDLIST_SERVICE, COMM_SELECT_READ, read_callback, data,
|
|
0);
|
|
}
|
|
|
|
|
|
|
|
|
|
Socket timeouts
|
|
---------------
|
|
|
|
A "socket timeout" is a callback registered to be called when a certain
|
|
amount of time has elapsed. Think of it as an event, but against a FD.
|
|
|
|
A good example of socket timeouts is in the comm_connect_tcp() code.
|
|
When the connect() begins, comm_settimeout() is called to call
|
|
comm_connect_timeout() if the timeout occurs. Once the connect() completes,
|
|
comm_settimeout() is called with a timeout of 0 and callback of NULL
|
|
to deregister the timeout. If the timeout occurs, comm_connect_timeout()
|
|
is called and the connection attempt is aborted.
|
|
|
|
|
|
|
|
|
|
Functions
|
|
---------
|
|
|
|
comm_open() - a socket() wrapper, enforcing fd limitations and tagging the
|
|
file descriptor with a note
|
|
|
|
comm_accept() - an accept() wrapper, enforcing fd limitations and tagging
|
|
the file descriptor with a note
|
|
|
|
comm_connect_tcp() - attempt an async connect(). Handles DNS lookups if
|
|
required, and will call the given callback at completion or error
|
|
|
|
comm_settimeout() - set a callback to be called after a given time period.
|
|
This is good to implement things like PING checks and connect() timeouts.
|
|
|
|
Notes:
|
|
|
|
* All socket creation should go through comm_open() / comm_accept().
|
|
* All socket closing should go through fd_close(). comm_close() isn't
|
|
implemented yet.
|
|
* comm_connect_tcp() is your best friend. :-)
|
|
* *ALL* network sockets should be non-blocking. If your OS doesn't support
|
|
non-blocking sockets, you shouldn't be here.
|