RULI's main interface operates asynchronously in an event-driven fashion. The application registers a callback function prior to submitting the desired query. Actually, the callback function is an argument for the query. When the answer arrives, RULI asynchronously invokes the registered callback with the aproppriate result.
The asynchronous event management interface used by RULI is provided by the excellent Liboop library.
Note RULI provides a synchronous interface more suitable for multi-threaded scenarios.
/* Kind of query that returned the RCODE */ typedef enum { RULI_SRV_RCODE_SRV, /* RCODE returned for SRV query */ RULI_SRV_RCODE_WALK, /* RCODE returned for SRV target query */ RULI_SRV_RCODE_FALL /* RCODE returned for IN A fallback query */ } ruli_srv_rcode_kind_t; /* User callback function type */ typedef void *(*ruli_srv_call_t)(ruli_srv_t *srv_qry, void *srv_qry_arg); /* SRV record as returned by ruli_srv_t.answer_srv_list */ typedef struct { char target[RULI_LIMIT_DNAME_ENCODED]; /* encoded, uncompressed */ int target_len; int port; ruli_list_t addr_list; /* list of *in_addr */ } ruli_srv_entry_t; /* Query opaque context */ struct ruli_srv_t { /* * input */ ruli_res_t *srv_resolver; /* resolver context */ ruli_srv_call_t srv_on_answer; /* user callback function */ void *srv_on_answer_arg; /* user callback argument */ char *srv_service; /* encoded _service._protocol part */ int srv_service_len; /* length of above */ char *srv_domain; /* encoded domain name */ int srv_domain_len; /* length of above */ int srv_fallback_port; /* fallback port */ /* * output */ int answer_code; ruli_list_t answer_srv_list; /* list of *ruli_srv_entry_t */ };
Submit an asynchronous SRV query with parameters passed under ruli_srv_t. It's responsability of the caller to allocate and release the ruli_srv_t structure, but not its members. When the query finishes, the srv_on_answer user callback function is called. Once this callback is invoked, the answer_code member reports one of the following results:
/* Values for ruli_srv_t.answer_code */ enum { RULI_SRV_CODE_VOID = -1, /* no result yet */ RULI_SRV_CODE_OK = 0, /* successful */ RULI_SRV_CODE_UNAVAILABLE, /* service surely not avaible in domain */ RULI_SRV_CODE_QUERY_FAILED, RULI_SRV_CODE_PARSE_FAILED, RULI_SRV_CODE_MALLOC, RULI_SRV_CODE_LIST, RULI_SRV_CODE_WALK_QUERY, RULI_SRV_CODE_FALL_QUERY };
If answer_code contains RULI_SRV_CODE_OK, the desired SRV records can be obtained from ruli_srv_entry_t pointers returned in the answer_srv_list.
One of the following result codes is immediately returned by ruli_srv_query_submit():
/* Return codes for ruli_srv_query_submit() */ enum { RULI_SRV_OK = 0, RULI_SRV_QRY_SUBMIT, RULI_SRV_MALLOC };
Input parameters
Output parameters
Note the SRV records provided in this list are already properly sorted for prompt usage. The whole RFC2782 priority/weight logic is already applied. The application only needs to scan the SRV records and try to use each address in the order they appear.
Note:
The query internal state, including answer_* members, is preserved until invokation of ruli_srv_query_delete().
Dispose the query context created by ruli_srv_query_submit(). In order to release resources, ruli_srv_query_delete() must be invoked for each complete query which is not needed anymore.
Notes:
1. ruli_srv_query_delete() does not affect the query input parameters (ruli_srv_t.srv_*).
2. ruli_srv_query_delete() disposes the query output parameters (ruli_srv_t.answer_*).
This auxiliary function returns an error string describing the result code returned by ruli_srv_query_submit()
If the query is successful, returns the RCODE received from the name server.
If the RCODE returned by ruli_srv_rcode() is different from RULI_RCODE_NOERROR, it may be useful to discover the context for that RCODE. This functions informs such kind of the RCODE.