libcnx - Liquid War 6
Description: Liquid War 6

Next: libdat, Previous: libcns, Up: C API

### 5.13 libcnx

#### 5.13.1 Overview

View lcov test coverage results on http://www.ufoot.org/liquidwar/v6/doc/coverage/src/lib/cnx/index.html.

#### 5.13.2 API

— Function: lw6cnx_connection_t * lw6cnx_connection_new (const char * local_url, const char * remote_url, const char * remote_ip, int remote_port, const char * password, u_int64_t local_id, u_int64_t remote_id, int dns_ok, int network_reliability, lw6cnx_recv_callback_t recv_callback_func, void * recv_callback_data)

> local_url: the local public URL

> remote_url: the remote public URL

> remote_ip: the remote IP address

> remote_port: the remote port

> password: the password to use

> local_id: the local ID

> remote_id: the remote ID

> dns_ok: 1 if no DNS mismatch, 0 if IP does not match public URL

> network_reliability: drop 1 out of X packets

> recv_callback_func: a callback to call when data is received

> recv_callback_data: additionnal data to pass to the callback

> Create a connection object. This object in itself does nothing, it's just to share common structures among modules, more precisely, between cli and srv code. It's the responsability off the caller/backend to handle the `backend_specific_data` field which is NULL after this call.

> Return value: newly allocated object.

— Function: void lw6cnx_connection_free (lw6cnx_connection_t * connection)

> connection: object to free

> Frees a connection object. It's the responsibility of the caller/backend to handle the `backend_specific_data` field.

> Return value: none.

— Function: int lw6cnx_connection_should_send_foo (lw6cnx_connection_t * connection, int64_t now)

> connection: the connection concerned

> now: the current timestamp

> Tells wether a new foo message must be issued.

> Return value: 1 if true, 0 if false.

— Function: void lw6cnx_connection_init_foo_bar_key (lw6cnx_connection_t * connection, int64_t now, int next_foo_delay)

> connection: the connection concerned

> now: the current timestamp

> next_foo_delay: the delay (msec) before next foo message is sent

> Generates a new foo_bar_key, and schedules the next foo message send timestamp.

> Return value: none.

— Function: int lw6cnx_connection_lock_send (lw6cnx_connection_t * connection)

> connection: the connexion to lock

> Acquires a "send" lock on the connexion, the idea is to avoid too threads sending data using the same socket at the same time. Note that each backend must call this when accessing the socket, there's no top-level lock for the sake of performance.

> Return value: 1 on success, 0 if not.

— Function: void lw6cnx_connection_unlock_send (lw6cnx_connection_t * connection)

> connection: the connexion to lock

> Releases a "send" lock on the connexion, the idea is to avoid too threads sending data using the same socket at the same time. Note that each backend must call this when accessing the socket, there's no top-level lock for the sake of performance.

> Return value: none.

— Function: int lw6cnx_connection_reliability_filter (lw6cnx_connection_t * connection)

> connection: the connexion concerned

> Will filter and return true only in "rare" cases when packets must be artificially dropped for testing purpose.

> Return value: 1 if message must be sent/received, 0 if not

— Function: char * lw6cnx_password_checksum (const char * seed, const char * password)

> seed: a seed to blur the password, can be NULL

> password: the password, can be NULL

> Calculates the checksum of a password, and returns it as a string, ready to be sent on the network. If password is empty or NULL, then an empty (but not NULL unless internal error) string will be returned. All LW6 protocols should send these checksums instead of real passwords, then on server side value can be checked against both real password and its checksum. The seed is here so that eavesdropper can't reuse the checksum to connect on random sessions. Seed can typically be the node 'public_url' value.

> Return value: a dynamically allocated string

— Function: int lw6cnx_password_verify (const char * seed, const char * password_here, const char * password_received)

> seed: a seed to blur the password, can be NULL

> password_here: the local password, can be NULL

> password_received: the password received from network, can be NULL

> Tells wether a password received over the network is valid. The `password_here` argument (the local password) will be checksumed so that `password_received` is checked against both clear and checksumed values, so it can be in any form.

> Return value: 1 if OK, passwords are the same, 0 if not.

— Function: int lw6cnx_test_register (int mode)

> mode: test mode (bitmask)

> Registers all tests for the libcnx module.

> Return value: 1 if test is successfull, 0 on error.

— Function: int lw6cnx_test_run (int mode)

> mode: test mode (bitmask)

> Runs the `cnx` module test suite, testing most (if not all...) functions.

> Return value: 1 if test is successfull, 0 on error.

— Function: void lw6cnx_ticket_table_zero (lw6cnx_ticket_table_t * ticket_table)

> ticket_table: the ticket table to fill with zero

> Fills the ticket table struct with 0s.

> Return value: none.

— Function: int lw6cnx_ticket_table_init (lw6cnx_ticket_table_t * ticket_table, int hash_size)

> ticket_table: the ticket table to init

> hash_size: the hash size for both recv/send hashs

> Initialize a ticket table, that is, set it up with two empty hashs. Recv hash is filled automatically as it's queried for tickets, send hash must be filled explicitely with info from the network.

> Return value: none.

— Function: void lw6cnx_ticket_table_clear (lw6cnx_ticket_table_t * ticket_table)

> ticket_table: the ticket table to clear

> Clears the object (frees memory).

> Return value: none.

— Function: u_int64_t lw6cnx_ticket_table_get_recv (lw6cnx_ticket_table_t * ticket_table, const char * peer_id)

> ticket_table: the ticket table to query

> peer_id: the id of remote node

> Gets the ticket used to communicate with peer, to check its incoming (recv) messages. If ticket does not exist yet, it's automatically generated so tunction will always return a non-zero value.

> Return value: the ticket used to check incoming messages.

— Function: void lw6cnx_ticket_table_ack_recv (lw6cnx_ticket_table_t * ticket_table, const char * peer_id, int ack_delay_msec)

> ticket_table: the ticket table to query

> peer_id: the id of remote node

> ack_delay_msec: delay before which we'll consider the ticket as really received

> Acknowledges the ticket used to communicate with peer, to check its incoming (recv) messages has been received. This is to avoid sending it again when it has been received, as it's kept "forever" by peer, we never need to send it again. The delay is here to avoid checking tickets too quickly, for instance one could have sent the ticket yet, but for some reason some unsigned messages are still in the pipe, typically they transit through another slow channel such as httpd while the ticket was sent on udp.

> Return value: none.

— Function: int lw6cnx_ticket_table_was_recv_exchanged (lw6cnx_ticket_table_t * ticket_table, const char * peer_id)

> ticket_table: the ticket table to query

> peer_id: the id of remote node

> Acknowledges the ticket used to communicate with peer, to check its incoming (recv) messages has been received. This is to avoid sending it again when it has been received, as it's kept "forever" by peer, we never need to send it again.

> Return value: the ticket used to check incoming messages.

— Function: u_int64_t lw6cnx_ticket_table_get_send (lw6cnx_ticket_table_t * ticket_table, const char * peer_id)

> ticket_table: the ticket table to query

> peer_id: the id of remote node

> Gets the ticket used to communicate with peer, to stamp the outgoing messages. If ticket does not exist yet, 0 is returned, indeed this value must be initialized with the value the peer gives us.

> Return value: the ticket used to stamp outgoing messages.

— Function: void lw6cnx_ticket_table_set_send (lw6cnx_ticket_table_t * ticket_table, const char * peer_id, u_int64_t send_ticket)

> ticket_table: the ticket table to query

> peer_id: the id of remote node

> send_ticket: the ticket to use to stamp outgoing messages

> Sets the ticket used to communicate with peer, to stamp the outgoing (send) messages. This value should be received from the network. Note that once it's set, it's impossible to change it, it will remain the same for the whole duration of the node existence.

> Return value: NULL

— Struct: lw6cnx_connection_s

> This structure holds all data associated to a physical connexion with a remote peer. This includes informations about the local node, informations about the peer, and protocol specific details. Depending on which backend is used to handle the connection, it will behave differently. If you search for attributes such as socket id, search for them in backend_specific_data which is, in fact, handle by the backend code.

— Member of lw6cnx_connection_s: local_url

> Type: `char *`

> Definition: `char* lw6cnx_connection_s::local_url`

> URL of our local node.

— Member of lw6cnx_connection_s: remote_url

> Type: `char *`

> Definition: `char* lw6cnx_connection_s::remote_url`

> URL of the remote node.

— Member of lw6cnx_connection_s: remote_ip

> Type: `char *`

> Definition: `char* lw6cnx_connection_s::remote_ip`

> IP address of the remote node.

— Member of lw6cnx_connection_s: remote_port

> Type: `int`

> Definition: `int lw6cnx_connection_s::remote_port`

> IP port of the remote node.

— Member of lw6cnx_connection_s: password

> Type: `char *`

> Definition: `char* lw6cnx_connection_s::password`

> Password as clear text.

— Member of lw6cnx_connection_s: password_send_checksum

> Type: `char *`

> Definition: `char* lw6cnx_connection_s::password_send_checksum`

> Password as a checksum, what will be sent on the network.

— Member of lw6cnx_connection_s: local_id_int

> Type: `u_int64_t`

> Definition: `u_int64_t lw6cnx_connection_s::local_id_int`

> ID of the local node, as an unsigned 64-bit integer.

— Member of lw6cnx_connection_s: local_id_str

> Type: `char *`

> Definition: `char* lw6cnx_connection_s::local_id_str`

> ID of the local node, as an hexa string.

— Member of lw6cnx_connection_s: remote_id_int

> Type: `u_int64_t`

> Definition: `u_int64_t lw6cnx_connection_s::remote_id_int`

> ID of the remote node, as an unsigned 64-bit integer.

— Member of lw6cnx_connection_s: remote_id_str

> Type: `char *`

> Definition: `char* lw6cnx_connection_s::remote_id_str`

> ID of the local node, as an hexa string.

— Member of lw6cnx_connection_s: dns_ok

> Type: `int`

> Definition: `int lw6cnx_connection_s::dns_ok`

> Will be set to 1 if the peer domain name is the same as the one reported in the URL. For instance, if we get a connection from 23.45.23.45, but this host claims to be on www.foo.bar and DNS reports www.foo.bar as being 111.222.111.222 then there's something strange. It could just be someone doing NAT, but in all cases it's worth mentionning, so we keep the information here. Having 0 here is a bad point for the connection.

— Member of lw6cnx_connection_s: network_reliability

> Type: `int`

> Definition: `int lw6cnx_connection_s::network_reliability`

> The higher, the most reliable message sending will be. It can never be perfect, LW6 will always drop some packets from time to time, just to simulate real packet loss and be sure if it happens, it's handled nicely.

— Member of lw6cnx_connection_s: properties

> Type: `lw6cnx_properties_t`

> Definition: `lw6cnx_properties_t lw6cnx_connection_s::properties`

> Properties got from the backend.

— Member of lw6cnx_connection_s: recv_callback_func

> Type: `lw6cnx_recv_callback_t`

> Definition: `lw6cnx_recv_callback_t lw6cnx_connection_s::recv_callback_func`

> Function which will be called when receiving data. This one must clearly be reentrant, depending on the backend it could be called in a separate thread, at any time.

— Member of lw6cnx_connection_s: recv_callback_data

> Type: `void *`

> Definition: `void* lw6cnx_connection_s::recv_callback_data`

> Data passed to recv_callback_func.

— Member of lw6cnx_connection_s: send_mutex

> Type: `lw6sys_mutex_t *`

> Definition: `lw6sys_mutex_t* lw6cnx_connection_s::send_mutex`

> Send mutex, this will be used so that sending operations are properly serialized. Indeed, threads that respond on the fly could be likely to call this concurrently.

— Member of lw6cnx_connection_s: foo_bar_key

> Type: `u_int32_t`

> Definition: `u_int32_t lw6cnx_connection_s::foo_bar_key`

> This is used to handle keepalive. Actually, the protocol is that from time to time FOO key is sent and then each connection (in a tentacle object, typically) is supposed to respond BAR key to show it has received the latest message. This field just stores the value so that when we receive a BAR message we know which key to check against.

— Member of lw6cnx_connection_s: last_send_foo_timestamp

> Type: `int64_t`

> Definition: `int64_t lw6cnx_connection_s::last_send_foo_timestamp`

> The last time FOO was sent.

— Member of lw6cnx_connection_s: next_send_foo_timestamp

> Type: `int64_t`

> Definition: `int64_t lw6cnx_connection_s::next_send_foo_timestamp`

> The next time FOO needs to be sent.

— Member of lw6cnx_connection_s: ping_msec

> Type: `int`

> Definition: `int lw6cnx_connection_s::ping_msec`

> The current ping, updated when receiving BAR message.

— Member of lw6cnx_connection_s: sent_nb_total

> Type: `int`

> Definition: `int lw6cnx_connection_s::sent_nb_total`

> Number of sent messages on this cnx.

— Member of lw6cnx_connection_s: sent_nb_success

> Type: `int`

> Definition: `int lw6cnx_connection_s::sent_nb_success`

> Number of successfully sent messages on this cnx.

— Member of lw6cnx_connection_s: sent_nb_fail

> Type: `int`

> Definition: `int lw6cnx_connection_s::sent_nb_fail`

> Number of failed sent messages on this cnx.

— Member of lw6cnx_connection_s: last_recv_timestamp

> Type: `int64_t`

> Definition: `int64_t lw6cnx_connection_s::last_recv_timestamp`

> Last time something was received on this connection.

— Member of lw6cnx_connection_s: backend_specific_data

> Type: `void *`

> Definition: `void* lw6cnx_connection_s::backend_specific_data`

> Store backend data, this is when, for instance, a socket handle will be kept, or a library handle (CURL, to name it). Common code does not know what's in there.

— Struct: lw6cnx_properties_s

> Used to hold generic client/server properties, set up by the backend, can then be queried by the caller.

— Member of lw6cnx_properties_s: hint_timeout

> Type: `int`

> Definition: `int lw6cnx_properties_s::hint_timeout`

> Gives an idea of what timeout one can expect with this backend, this is not necessarly the exact timeout but it gives an order of magnitude. Unit is seconds.

— Member of lw6cnx_properties_s: ping_alter_base

> Type: `int`

> Definition: `int lw6cnx_properties_s::ping_alter_base`

> Modifies the ping returned by terrain experience, this is a way to help some kind of connections to be preferred over others. Set it to N to add N milliseconds to the real ping. Adding a few msecs, such as 1 or 5 will just give an advantage to a given connection while not giving really wrong results. High values like 50 or 100 seriously penalizes some kind of connections, which is whishable, think of the httpd way to send things for instance.

— Member of lw6cnx_properties_s: ping_alter_percent

> Type: `int`

> Definition: `int lw6cnx_properties_s::ping_alter_percent`

> Modifies the ping returned by terrain experience, this is a way to help some kind of connections to be preferred over others. Set it to 100 for default value, means 100% of real ping delay, set it to 50 to make the algorithm believe lag is twice lower (this means, connection twice faster) and set it to 1000 to make believe that everything is slow. In practice only a slight alteration should be required, one should still favor really fast connections when it's proved in real life that they are faster!

— Member of lw6cnx_properties_s: reliable

> Type: `int`

> Definition: `int lw6cnx_properties_s::reliable`

> Wether this connexion is to be considered reliable or not. Well, in LW6, all connexions are unrealiable since LW6 will drop packets on purpose to simulate problems, but however, some are well-known to be unreliable (UDP...) while others are OK.

— Member of lw6cnx_properties_s: backend_id

> Type: `const char *`

> Definition: `const char* lw6cnx_properties_s::backend_id`

> The backend id, beware, this is a static string, must not be freed, and depends on backend library to be here, if this one is unloaded, will point to nowhere.

— Struct: lw6cnx_ticket_table_s

> A common, shared table, to store all the tickets associated with various connections. This needs to be in-memory and quite fast for it's called very often (at each message, in fact) to perform sanity checks and avoid fakes/cheaters.

— Member of lw6cnx_ticket_table_s: recv_spinlock

> Type: `lw6sys_spinlock_t *`

> Definition: `lw6sys_spinlock_t* lw6cnx_ticket_table_s::recv_spinlock`

> Lock for the recv_table hash.

— Member of lw6cnx_ticket_table_s: recv_ack_spinlock

> Type: `lw6sys_spinlock_t *`

> Definition: `lw6sys_spinlock_t* lw6cnx_ticket_table_s::recv_ack_spinlock`

> Lock for the recv_ack_table hash.

— Member of lw6cnx_ticket_table_s: send_spinlock

> Type: `lw6sys_spinlock_t *`

> Definition: `lw6sys_spinlock_t* lw6cnx_ticket_table_s::send_spinlock`

> Lock for the send_table hash.

— Member of lw6cnx_ticket_table_s: recv_table

> Type: `lw6sys_hash_t *`

> Definition: `lw6sys_hash_t* lw6cnx_ticket_table_s::recv_table`

> Hash table containing the tickets for recv operations. This table is auto-generated, if one asks for a ticket for an unknown host, one is generated. The key is the ID (64-bit integer) of the host, as an hexa string.

— Member of lw6cnx_ticket_table_s: recv_ack_table

> Type: `lw6sys_hash_t *`

> Definition: `lw6sys_hash_t* lw6cnx_ticket_table_s::recv_ack_table`

> Hash table containing wether the send ticket was received by a given host. The data is just a NULL pointer, only if the key is present, we know we don't need to resend our key to the peer. An easy way to know that the key was sent is if the peer was abled to produce a valid message/checksum. The key is the ID (64-bit integer) of the host, as an hexa string.

— Member of lw6cnx_ticket_table_s: send_table

> Type: `lw6sys_hash_t *`

> Definition: `lw6sys_hash_t* lw6cnx_ticket_table_s::send_table`

> Hash table containing the tickets for send operations. Those tickets are typically received from the peers themselves who generate them on the fly. The key is the ID (64-bit integer) of the host, as an hexa string.