getaddrinfo API

This section briefly shows the getaddrinfo(3)-based API for fetching DNS SRV records. It applies to RULI versions greater than 0.31.

Applications which use getaddrinfo(3) for DNS lookup can be easily extended to support SRV records by invoking RULI's getaddrinfo(3)-based API.

This document is supposed to provide introductory information about the getaddrinfo(3)-based API. Further details can be found in the getaddrinfo(3) manual page.

  1. Prepare query hints
  2. Submit query
  3. Scan result
  4. Delete result

  1. Prepare query hints
  2. Put query hints into a struct addrinfo hints. Refer to getaddrinfo(3) manual page for details.

    struct addrinfo hints;
    struct protoent *pe;
    char *protoname = "tcp";
    
    if (!strcasecmp(protoname, "tcp"))
      hints.ai_socktype = SOCK_STREAM;
    else if (!strcasecmp(protoname, "udp"))
      hints.ai_socktype = SOCK_DGRAM;
    else {
      printf("bad-socket-type: %s\n", protoname);
      exit(1);
    }
    
    pe = getprotobyname(protoname);
    if (!pe) {
      printf("bad-protocol: %s\n", protoname);
      exit(1);
    }
    
    hints.ai_protocol = pe->p_proto;
    hints.ai_flags = AI_CANONNAME;
    hints.ai_family = PF_UNSPEC;
    hints.ai_addrlen = 0;
    hints.ai_addr = 0;
    hints.ai_canonname = 0;
    

  3. Submit query
  4. Use the following function to submit a query:

    int ruli_getaddrinfo(const char *domain, const char *service, const struct addrinfo *hints, struct addrinfo **res);

    Example:
    struct addrinfo *ai_res;
    int result;
    char *domain = "domain.tld";
    char *service = "ftp";
    
    result = ruli_getaddrinfo(domain, service, &hints, &ai_res);
    if (result) {
      printf("getaddrinfo-failed: %s\n", gai_strerror(result));
      exit(1);
    }
    

  5. Scan result
  6. Scan the result as in the following example:

    struct addrinfo *ai;
    
    for (ai = ai_res; ai; ai = ai->ai_next) {
    
      switch (ai->ai_family) {
      case PF_INET:
        {
          struct sockaddr_in *sa = (struct sockaddr_in *) ai->ai_addr;
          printf(" canon=%s port=%d IPv4/%s\n",
                 ai->ai_canonname, ntohs(sa->sin_port),
                 inet_ntoa(sa->sin_addr));
        }
        break;
    
      case PF_INET6:
        {
          struct sockaddr_in6 *sa = (struct sockaddr_in6 *) ai->ai_addr;
          printf(" canon=%s port=%d IPv6/",
                 ai->ai_canonname, ntohs(sa->sin6_port));
          ruli_inet6_print(stdout, &sa->sin6_addr);
          printf("\n");
        }
        break;
    
      default:
        assert(0);
      }
    
    } /* for: scan ai list */
    

  7. Delete result
  8. Use ruli_freeaddrinfo() to delete the result.

    void ruli_freeaddrinfo(struct addrinfo *res);
    

    Example:

    ruli_freeaddrinfo(ai_res);
    


$Id: getaddrinfo.html,v 1.3 2004/12/15 16:01:15 evertonm Exp $