The Networking module defines the following private URI schemes corresponding to the protocol combos:
TCP | UDP | SCTP | |
IPv4 | tcp:// or tcp4:// | udp:// or udp4:// | sctp:// or sctp4:// |
IPv6 | tcp6:// | udp6:// | sctp6:// |
UNIX | unix:// | N.A. | N.A. |
Except for unix://
, which accepts only a valid pathname in the target file system, e.g.:
unix:///tmp/my.sock
every other scheme needs an host (by name or numeric address) and a port (by service name, or numeric in range [1..65535]
) separated by a single '
:' character, e.g.:
tcp://www.kame.net:http
udp6://[fe80::200:f8ff:fe21:67cf]:65432
sctp4://myhost:9999
Note that IPv6 numeric addresses must be enclosed with brackets as per RFC 3986.
Also, the wildcard address is specified with a '*'
, and the same representation is used to let the kernel choose an ephemeral port for us. e.g.:
tcp6://[*]:1025
tcp4://192.168.0.1:*
There exist two ways to obtain a socket descriptor: the first creates and consumes an address object without the caller ever noticing it and is ideal for one-shot initialization and use, e.g. a passive socket which is created once and accept'ed multiple times during the process lifetime:
int sd, asd; struct sockaddr_storage sa; socklen_t sa_len = sizeof sa; // create a passive TCP socket dbg_err_if ((sd = u_net_sd("tcp://my:http-alt", U_NET_SSOCK, 0)) == -1); for (;;) { // accept new incoming connections asd = u_accept(sd, (struct sockaddr *) &sa, &sa_len); dbg_ifb (asd == -1) continue; // handle it do_serve(asd); }
The second allows to reuse the same address object multiple times, and could easily fit a scenario where a transient connection must be set up on regular basis:
int csd; u_net_addr_t *a = NULL; // create an address object for an active TCP socket dbg_err_if (u_net_uri2addr("tcp://my:http-alt", U_NET_CSOCK, &a)); for (;;) { // sleep some time (void) u_sleep(SOME_TIME); // connect to the server host, reusing the same address dbg_ifb ((csd = u_net_sd_by_addr(a)) == -1) continue; // do some messaging over the connected socket dbg_if (do_io(csd)); }
The net module primarily aims at simplifying the socket creation process. When you receive back your brand new socket descriptor, its goal is almost done. You can use libu's u_read, u_write, u_net_readn, u_net_writen or barebones sendto(2)
, select(2)
, recvmsg(2)
, as much as you like. One of my favourite is to use it in association with libevent.
Defines | |
#define | U_NET_BACKLOG 300 |
Default backlog queue size supplied to listen(2). | |
#define | u_net_write(sd, buf, nbytes, nw, iseof) u_io((iof_t) write, sd, buf, nbytes, nw, iseof) |
u_io specialisation for output ops | |
#define | u_net_read(sd, buf, nbytes, nr, iseof) u_io(read, sd, buf, nbytes, nr, iseof) |
u_io specialisation for input ops | |
#define | u_net_writen(sd, buf, nbytes) u_io((iof_t) write, sd, buf, nbytes, NULL, NULL) |
Try to write a chunk of nbytes data to descriptor sd . | |
#define | u_net_readn(sd, buf, nbytes) u_io(read, sd, buf, nbytes, NULL, NULL) |
Try to read a chunk of nbytes data from descriptor sd . | |
Typedefs | |
typedef struct u_net_addr_s | u_net_addr_t |
Base type of the net module: holds all the addressing and semantics information needed when creating the corresponding socket. | |
Enumerations | |
enum | u_net_mode_t { U_NET_SSOCK = 0, U_NET_CSOCK = 1 } |
Socket creation semantics: passive or active, i.e. the | |
enum | u_net_opts_t { U_NET_OPT_DONT_REUSE_ADDR = (1 << 0), U_NET_OPT_DONT_CONNECT = (1 << 1), U_NET_OPT_SCTP_ONE_TO_MANY = (1 << 2), U_NET_OPT_SCTP_DATA_IO_EVENT = (1 << 3), U_NET_OPT_SCTP_ASSOCIATION_EVENT = (1 << 4), U_NET_OPT_SCTP_ADDRESS_EVENT = (1 << 5), U_NET_OPT_SCTP_SEND_FAILURE_EVENT = (1 << 6), U_NET_OPT_SCTP_PEER_ERROR_EVENT = (1 << 7), U_NET_OPT_SCTP_SHUTDOWN_EVENT = (1 << 8), U_NET_OPT_SCTP_PARTIAL_DELIVERY_EVENT = (1 << 9), U_NET_OPT_SCTP_ADAPTATION_LAYER_EVENT = (1 << 10), U_NET_OPT_SCTP_AUTHENTICATION_EVENT = (1 << 11), U_NET_OPT_DGRAM_BROADCAST = (1 << 20) } |
Address options, can be supplied (by or'ing them together through u_net_addr_set_opts and/or u_net_addr_add_opts, in order to tweek the socket creation machinery. More... | |
Functions | |
int | u_net_uri2addr (const char *uri, u_net_mode_t mode, u_net_addr_t **pa) |
Parse the supplied uri and transform it into an u_net_addr_t . | |
int | u_net_sd_by_addr_ex (u_net_addr_t *a, struct timeval *timeout) |
Create a socket (connected or passive) from a given u_net_addr_t object. | |
int | u_net_sd_by_addr (u_net_addr_t *a) |
Wrapper to u_net_sd_by_addr_ex() with no timeout. | |
int | u_net_sd_ex (const char *uri, u_net_mode_t mode, int opts, struct timeval *timeout) |
Minimalistic, one-shot interface which wraps u_net_uri2addr, u_net_addr_set_opts and u_net_sd_by_addr bits together. | |
int | u_net_sd (const char *uri, u_net_mode_t mode, int opts) |
Wrapper to u_net_sd_ex() with no timeout. | |
int | u_net_addr_can_accept (u_net_addr_t *a) |
Tell if the supplied address is entitled to call accept(2). | |
void | u_net_addr_set_opts (u_net_addr_t *a, int opts) |
Set the supplied address' options to opts . | |
void | u_net_addr_add_opts (u_net_addr_t *a, int opts) |
Add the supplied opts to the given address. | |
void | u_net_addr_free (u_net_addr_t *a) |
Free memory allocated to an u_net_addr_t object. | |
int | u_accept (int sd, struct sockaddr *addr, u_socklen_t *addrlen) |
accept(2) wrapper that handles EINTR | |
int | u_socket (int domain, int type, int protocol) |
socket(2) wrapper | |
int | u_connect (int sd, const struct sockaddr *addr, u_socklen_t addrlen) |
Wrapper to u_connect_ex with no timeout. | |
int | u_connect_ex (int sd, const struct sockaddr *addr, u_socklen_t addrlen, struct timeval *timeout) |
timeouted connect(2) wrapper that handles EINTR | |
int | u_bind (int sd, const struct sockaddr *addr, u_socklen_t addrlen) |
bind(2) wrapper | |
int | u_listen (int sd, int backlog) |
listen(2) wrapper | |
int | u_setsockopt (int sd, int lev, int name, const void *val, u_socklen_t len) |
setsockopt(2) wrapper | |
int | u_getsockopt (int sd, int lev, int name, void *val, u_socklen_t *len) |
getsockopt(2) wrapper | |
int | u_net_set_nonblocking (int s) |
Mark the supplied socket descriptor as non-blocking. | |
int | u_net_unset_nonblocking (int s) |
Unset the non-blocking bit on the supplied socket descriptor. | |
int | u_net_nagle_off (int s) |
Disable Nagle algorithm on the supplied TCP socket. | |
const char * | u_inet_ntop (int af, const void *src, char *dst, u_socklen_t len) |
Wrapper to inet_ntop(3). | |
const char * | u_sa_ntop (const struct sockaddr *sa, char *d, size_t dlen) |
Pretty print the given sockaddr (path, or address and port). |
enum u_net_mode_t |
enum u_net_opts_t |
int u_connect_ex | ( | int | sd, | |
const struct sockaddr * | addr, | |||
u_socklen_t | addrlen, | |||
struct timeval * | timeout | |||
) |
Timeouted connect(2) wrapper that handles EINTR
. In case the underlying select(2) is interrupted by a trapped signal, the object pointed to by the timeout
argument may be modified, so it's safer to explicitly reinitialize it for any subsequent use.
sd | socket descriptor | |
addr | address of the peer | |
addrlen | size of addr in bytes | |
timeout | if non-NULL specifies a maximum interval to wait for the connection attempt to complete. If a NULL value is supplied the default platform timeout is in place. |
0 | success | |
-1 | generic error | |
-2 | timeout |
Definition at line 496 of file net.c.
References u_getsockopt(), u_net_set_nonblocking(), and u_net_unset_nonblocking().
Referenced by u_connect().
void u_net_addr_add_opts | ( | u_net_addr_t * | a, | |
int | opts | |||
) |
Add the supplied options set opts
to a
options' set. This operation is not disruptive so that any option that was previously installed in the address is retained.
a | an already allocated u_net_addr_t object | |
opts | the set of options that will added to the set of options already installed |
int u_net_addr_can_accept | ( | u_net_addr_t * | a | ) |
a | A u_net_addr_t object that has been created via u_net_uri2addr |
1 | if the address is suitable for accept'ing connections | |
0 | if the address is invalid, or not eligible for accept(2) |
Definition at line 361 of file net.c.
References U_NET_SSOCK.
void u_net_addr_free | ( | u_net_addr_t * | a | ) |
Free resources allocated to the previously allocated u_net_addr_t object a
. A new u_net_addr_t object is created at each u_net_uri2addr invocation and must be explicitly released, otherwise it'll be leaked.
Definition at line 425 of file net.c.
References u_free().
Referenced by u_net_sd_ex(), and u_net_uri2addr().
void u_net_addr_set_opts | ( | u_net_addr_t * | a, | |
int | opts | |||
) |
Install the supplied options set opts
into the address pointed by a
. Beware that this operation overrides any option that was previously installed in the address.
a | an already allocated u_net_addr_t object | |
opts | the set of options that will be installed |
Definition at line 388 of file net.c.
Referenced by u_net_sd_ex().
int u_net_nagle_off | ( | int | s | ) |
s | a TCP socket descriptor |
0 | if successful or TCP_NODELAY not implemented | |
~0 | on error |
Definition at line 719 of file net.c.
References u_setsockopt().
int u_net_sd_by_addr_ex | ( | u_net_addr_t * | a, | |
struct timeval * | timeout | |||
) |
Create a socket, being connected or passive depends on mode
value, given the already filled-in u_net_addr_t object a
. The returned socket descriptor can then be used for any I/O operation compatible with its underlying nature.
a | a valid u_net_addr_t address, created by a previous call to u_net_uri2addr | |
timeout | maximum time to wait for connection |
-1
on error. Definition at line 278 of file net.c.
References U_NET_BACKLOG, U_NET_CSOCK, and U_NET_SSOCK.
Referenced by u_net_sd_by_addr(), and u_net_sd_ex().
int u_net_sd_ex | ( | const char * | uri, | |
u_net_mode_t | mode, | |||
int | opts, | |||
struct timeval * | timeout | |||
) |
uri | an URI string | |
mode | one of U_NET_CSOCK (connected) or U_NET_SSOCK (passive) | |
opts | set of OR'd U_NET_OPT_* bits | |
timeout | maximum time to wait for connection |
-1
on error. Definition at line 312 of file net.c.
References u_net_addr_free(), u_net_addr_set_opts(), u_net_sd_by_addr_ex(), and u_net_uri2addr().
Referenced by u_net_sd().
int u_net_set_nonblocking | ( | int | s | ) |
s | a TCP socket descriptor |
0 | if successful | |
~0 | on error or fcntl(2) not implemented |
Definition at line 670 of file net.c.
Referenced by u_connect_ex().
int u_net_unset_nonblocking | ( | int | s | ) |
s | a TCP socket descriptor |
0 | if successful | |
~0 | on error or fcntl(2) not implemented |
Definition at line 694 of file net.c.
Referenced by u_connect_ex().
int u_net_uri2addr | ( | const char * | uri, | |
u_net_mode_t | mode, | |||
u_net_addr_t ** | pa | |||
) |
Parse the supplied uri
string and return an u_net_addr_t object at pa
as a result argument. The address can then be used (and reused) to create passive or connected sockets by means of the u_net_sd_by_addr interface.
uri | an URI string | |
mode | one of U_NET_SSOCK if the address needs to be used for a passive socket, or U_NET_CSOCK if the address will be used for a connected (i.e. non-passive) socket | |
pa | the translated u_net_addr_t as a result argument |
0 | on success | |
~0 | on error |
Definition at line 228 of file net.c.
References u_net_addr_free(), u_uri_crumble(), u_uri_free(), u_uri_get_scheme(), and U_URI_OPT_NONE.
Referenced by u_net_sd_ex().