Nsock is a parallel sockets library used by NSE, service detection (service_scan.cc) and DNS (nmap_dns.cc).
It acts as an abstraction layer above socket operations and is optimized for handling multiple sockets.
The main object is a 'nsock_pool' which is a void * cast to an internal representation mspool by the corresponding
mspool is defined at nsock_internal.h and contains among other things a struct event_lists
a structure that keeps information on all pending events. It has 5
double-linked lists (gh_list) for connect, read, write, timer,
as well as a list with deleted events for later use (free_events).
Essentially, a nsock pool acts as a central aggregator for events and I/O descriptors.
The operations that manipulate a nsock_pool object are defined in nsock_pool.c
Briefly, they are:
- nsp_new (constructor)
- nsp_delete (destructor)
'nsp_new' -> allocates and initialized a nsock_pool and calls nsock_library_initialize which
calls maximize_fdlimit() from netutils.c which maximizes the number of file descriptors allowed
for the process and returns that number.
Events are represented with the msevent struct (nsock_internal.h) which contains (among other things)
- the callback handler -> nsock_ev_handler(nsock_pool, nsock_event, void *)
- a pointer to a msiod struct -> msiod *iod, which holds all the I/O descriptor related information.
- struct filespace iobuf (a buffer usually 1024 bytes which holds the write/read bytes)
- the nse_type (nsock.h)
- the nse_status (nsock.h)
- a unique id -> nsock_event_id id
Events are created with the following special functions:
They all take as arguments (except for the mspool obviously) an nsock_iod (msiod @ nsock_internal.h) and a timeout.
Each of them calls msevent_new() and nsp_add_event().
msevent_new() (@ nsock_event.c) is responsible for
allocating a msevent struct which holds all the information pertaining
to an 'event'
as well as initializing it.
nsp_add_event(mspool nsp, msevent nse) (@ nsock_core.c) appends the current msevent (in the argument) at the current mspool
by calling gh_list_append(&nsp->evl.<nse->type>, nse).
It is the main event processing function (can timeout or wait until an event or error occurs).
It calls iterate_through_event_lists() which in the end calls msevent_dispatch_and_delete() which finally
removes the event from the pool's event_lists and calls our callback handler.