Overview of the network subsystem Adrian Chadd $Id: network.txt,v 1.2 2003/10/13 03:21:18 musirc Exp $ 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.