RULI Simple Synchronous API v2

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.

  1. Submit query
  2. Check for errors
  3. Scan result
  4. Delete query

  1. Submit query
  2. Use the following function to submit a synchronous query:

    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);
    

  3. Check for errors
  4. Check for possible errors on:

    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");
    

  5. Scan result
  6. The query result is an array of pointers to the following structure:
    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");
    }
    

  7. Delete query
  8. As soon as the query answer is no longer needed, use the following function to release its resources:

    void ruli_sync_delete(ruli_sync_t *syn_qry);

    Example:

    ruli_sync_delete(sync_query);
    


$Id: sync-search-srv.html,v 1.10 2005/08/17 11:44:12 evertonm Exp $