You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
3.1 KiB

  1. /* ex-rdns.c
  2. parallel rDNS resolver example - read IP addresses from stdin,
  3. write domain names to stdout
  4. Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
  5. This file is part of UDNS library, an async DNS stub resolver.
  6. This library is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU Lesser General Public
  8. License as published by the Free Software Foundation; either
  9. version 2.1 of the License, or (at your option) any later version.
  10. This library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. Lesser General Public License for more details.
  14. You should have received a copy of the GNU Lesser General Public
  15. License along with this library, in file named COPYING.LGPL; if not,
  16. write to the Free Software Foundation, Inc., 59 Temple Place,
  17. Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. #include <sys/types.h>
  20. #include <sys/socket.h>
  21. #include <netinet/in.h>
  22. #include <sys/poll.h>
  23. #include <unistd.h>
  24. #include <stdio.h>
  25. #include <time.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include "udns.h"
  29. static int curq;
  30. static const char *n2ip(const unsigned char *c) {
  31. static char b[sizeof("255.255.255.255")];
  32. sprintf(b, "%u.%u.%u.%u", c[0], c[1], c[2], c[3]);
  33. return b;
  34. }
  35. static void dnscb(struct dns_ctx *ctx, struct dns_rr_ptr *rr, void *data) {
  36. const char *ip = n2ip((unsigned char *)&data);
  37. int i;
  38. --curq;
  39. if (rr) {
  40. printf("%s", ip);
  41. for(i = 0; i < rr->dnsptr_nrr; ++i)
  42. printf(" %s", rr->dnsptr_ptr[i]);
  43. putchar('\n');
  44. free(rr);
  45. }
  46. else
  47. fprintf(stderr, "%s: %s\n", ip, dns_strerror(dns_status(ctx)));
  48. }
  49. int main(int argc, char **argv) {
  50. int c;
  51. time_t now;
  52. int maxq = 10;
  53. struct pollfd pfd;
  54. char linebuf[1024];
  55. char *eol;
  56. int eof;
  57. if (dns_init(NULL, 1) < 0) {
  58. fprintf(stderr, "unable to initialize dns library\n");
  59. return 1;
  60. }
  61. while((c = getopt(argc, argv, "m:r")) != EOF) switch(c) {
  62. case 'm': maxq = atoi(optarg); break;
  63. case 'r':
  64. dns_set_opt(0, DNS_OPT_FLAGS,
  65. dns_set_opt(0, DNS_OPT_FLAGS, -1) | DNS_NORD);
  66. break;
  67. default: return 1;
  68. }
  69. if (argc != optind) return 1;
  70. pfd.fd = dns_sock(0);
  71. pfd.events = POLLIN;
  72. now = time(NULL);
  73. c = optind;
  74. eof = 0;
  75. while(curq || !eof) {
  76. if (!eof && curq < maxq) {
  77. union { struct in_addr a; void *p; } pa;
  78. if (!fgets(linebuf, sizeof(linebuf), stdin)) {
  79. eof = 1;
  80. continue;
  81. }
  82. eol = strchr(linebuf, '\n');
  83. if (eol) *eol = '\0';
  84. if (!linebuf[0]) continue;
  85. if (dns_pton(AF_INET, linebuf, &pa.a) <= 0)
  86. fprintf(stderr, "%s: invalid address\n", linebuf);
  87. else if (dns_submit_a4ptr(0, &pa.a, dnscb, pa.p) == 0)
  88. fprintf(stderr, "%s: unable to submit query: %s\n",
  89. linebuf, dns_strerror(dns_status(0)));
  90. else
  91. ++curq;
  92. continue;
  93. }
  94. if (curq) {
  95. c = dns_timeouts(0, -1, now);
  96. c = poll(&pfd, 1, c < 0 ? -1 : c * 1000);
  97. now = time(NULL);
  98. if (c)
  99. dns_ioevent(0, now);
  100. }
  101. }
  102. return 0;
  103. }