This section explains how to use the simple synchronous API for SRV records. It applies to RULI versions greater than 0.21.
Such API is the RULI's simplest interface for querying SRV resource records. Use it if your application can afford to block on DNS queries.
This document is supposed to provide sufficient information about the high-level synchronous API. If anything is not clear enough, please post the issue to RULI's support site at Savannah.
ruli_sync_t *ruli_sync_query(const char *txt_service, const char *txt_domain, int fallback_port, long options);
Example:
ruli_sync_t *sync_query = ruli_sync_query("_http._tcp", "domain.tld", -1, RULI_RES_OPT_SEARCH);
If ruli_sync_query() fails to submit the query, a NULL pointer is returned. This may be caused by lack of system resources, improper network configuration, or system/network failures.
If ruli_sync_query() submission has succeded, use the following functions to check for other errors:
This function returns 0 (zero/false) if the underlying resolver has successfully completed the query, or an error code otherwise.
If an error code is returned by the resolver [through function ruli_sync_srv_code() above], this function may used to find out if the server sent a bad RCODE as answer.
The simplified example below shows how to properly check for main query errors.
/* * This example shows how to check for query errors */ ruli_sync_t *sync_query; int srv_code; sync_query = ruli_sync_query("_http._tcp", "domain.tld", -1, RULI_RES_OPT_SEARCH); /* Submission failure? */ if (!sync_query) { printf("COULD-NOT-SUBMIT-QUERY\n"); exit(1); } srv_code = ruli_sync_srv_code(sync_query); /* Timeout ? */ if (srv_code == RULI_SRV_CODE_ALARM) { printf("TIMEOUT\n"); exit(1); } /* Service provided ? */ if (srv_code == RULI_SRV_CODE_UNAVAILABLE) { printf("SRV-SERVICE-NOT-PROVIDED-BY-DOMAIN\n"); exit(1); } /* Server sent RCODE error? */ if (srv_code) { int rcode = ruli_sync_rcode(sync_query); if (rcode) printf("BAD-RCODE-IN-SERVER-ANSWER\n"); else printf("OTHER-FAILURE\n"); exit(1); } /* No error here */ printf("GOOD-SRV-ANSWER!\n"); |
typedef struct { char target[RULI_LIMIT_DNAME_ENCODED]; /* encoded, uncompressed */ int target_len; int port; ruli_list_t addr_list; /* list of ruli_addr_t* for host 'target' */ } ruli_srv_entry_t;If the query has completed without errors, one can use the function below to grab a pointer to that array:
ruli_list_t *ruli_sync_srv_list(ruli_sync_t *syn_qry);
Example:
ruli_list_t *srv_list = ruli_sync_srv_list(sync_query);
Notes:
/* * This example scans the results for a query in 'sync_query' */ ruli_list_t *srv_list = ruli_sync_srv_list(sync_query); int srv_list_size = ruli_list_size(srv_list); int i; /* index for array of 'ruli_srv_entry_t' pointers */ if (srv_list_size < 1) { printf("RESULT-ARRAY-IS-EMPTY\n"); exit(1); } /* * Scan array of SRV records */ for (i = 0; i < srv_list_size; ++i) { ruli_srv_entry_t *entry = ruli_list_get(srv_list, i); ruli_list_t *addr_list = &entry->addr_list; int addr_list_size = ruli_list_size(addr_list); int j; /* index for array of 'ruli_addr_t' pointers */ /* * Show target */ { char txt_dname_buf[RULI_LIMIT_DNAME_TEXT_BUFSZ]; int txt_dname_len; if (ruli_dname_decode(txt_dname_buf, RULI_LIMIT_DNAME_TEXT_BUFSZ, &txt_dname_len, entry->target, entry->target_len)) { printf("TARGET-DECODING-FAILED\n"); continue; } printf("target=%s ", txt_dname_buf); } /* * Show port number */ printf("port=%d ", entry->port); /* * Show addresses */ printf("addresses="); for (j = 0; j < addr_list_size; ++j) { ruli_addr_t *addr = ruli_list_get(addr_list, j); switch (ruli_addr_family(addr)) { case PF_INET: printf("IPv4/"); break; case PF_INET6: printf("IPv6/"); break; default: printf("?/"); } /* options: * * get as IPv4: struct in_addr ruli_addr_inet(const ruli_addr_t *addr); * get as IPv6: struct in6_addr ruli_addr_inet6(const ruli_addr_t *addr); */ ruli_addr_print(stdout, addr); printf(" "); } printf("\n"); } |
void ruli_sync_delete(ruli_sync_t *syn_qry);
Example:
ruli_sync_delete(sync_query);
sample/sync_srvsearch.c
See below how to use such sample program in the command line:
$ echo _smtp._tcp.domain.tld | ./sync_srvsearch _smtp._tcp.domain.tld target=phantom.domain.tld. priority=5 weight=0 port=25 addresses=IPv4/1.2.3.4 _smtp._tcp.domain.tld target=sitemail.host.tld. priority=10 weight=0 port=25 addresses=IPv4/4.3.2.1 $
#include <ruli.h>
And link the program against liboop and libruli, by using the following linker options:
-loop -lruli