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().