source: code/dns.c

Last change on this file was 4a74b5b, checked in by Izuru Yakumo <eternal-servant@…>, 7 weeks ago

Nitori Engineering

  • Property mode set to 100644
File size: 4.4 KB
Line 
1/*
2 * Copyright (c) 2014 Mike Belopuhov
3 * Copyright (c) 2014 Eric Faurot <eric@faurot.net>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
14 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
15 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/types.h>
19#include <sys/socket.h>
20#include <sys/time.h>
21#include <netinet/in.h>
22#include <netdb.h>
23#include <errno.h>
24#include <event.h>
25#include <resolv.h>
26#include <stdlib.h>
27#include <string.h>
28#include <syslog.h>
29
30#ifdef __NetBSD__
31#define NO_ASYNC
32#endif
33
34#ifdef NO_ASYNC
35struct asr_result {
36 struct addrinfo* ar_addrinfo;
37 int ar_gai_errno;
38};
39#else
40#include <asr.h>
41#endif
42
43#include "icb.h"
44#include "icbd.h"
45
46void dns_done_host(struct asr_result *, void *);
47void dns_done_reverse(struct asr_result *, void *);
48int cmp_addr(struct sockaddr *, struct sockaddr *);
49
50extern int dodns;
51
52void
53dns_done_host(struct asr_result *ar, void *arg)
54{
55 struct icb_session *is = arg;
56 struct addrinfo *res;
57 int found = 0;
58
59 if (ISSETF(is->flags, ICB_SF_PENDINGDROP)) {
60 if (ar->ar_addrinfo)
61 freeaddrinfo(ar->ar_addrinfo);
62 free(is);
63 return;
64 }
65
66 if (ar->ar_gai_errno == 0) {
67 if (strncmp(is->hostname, "localhost",
68 sizeof "localhost" - 1) == 0)
69 strlcpy(is->host, "unknown", ICB_MAXHOSTLEN);
70 else if (strlen(is->hostname) < ICB_MAXHOSTLEN) {
71 for (res = ar->ar_addrinfo; res; res = res->ai_next) {
72 if (cmp_addr(res->ai_addr, (struct sockaddr *)
73 &is->ss) == 0) {
74 strlcpy(is->host, is->hostname,
75 ICB_MAXHOSTLEN);
76 found = 1;
77 break;
78 }
79 }
80 if (!found)
81 icbd_log(is, LOG_WARNING, "hostname %s does "
82 "not resolve back to connecting ip %s",
83 is->hostname, is->host);
84 }
85 } else
86 icbd_log(is, LOG_DEBUG, "dns resolution failed: %s",
87 gai_strerror(ar->ar_gai_errno));
88
89 if (ar->ar_addrinfo)
90 freeaddrinfo(ar->ar_addrinfo);
91
92 CLRF(is->flags, ICB_SF_DNSINPROGRESS);
93}
94
95void
96dns_done_reverse(struct asr_result *ar, void *arg)
97{
98 struct icb_session *is = arg;
99#ifdef NO_ASYNC
100 struct asr_result result;
101#else
102 struct asr_query *as;
103#endif
104 struct addrinfo hints;
105
106 if (ISSETF(is->flags, ICB_SF_PENDINGDROP)) {
107 free(is);
108 return;
109 }
110
111 if (ar->ar_gai_errno == 0) {
112 icbd_log(is, LOG_DEBUG, "reverse dns resolved %s to %s",
113 is->host, is->hostname);
114 /* try to verify that it resolves back */
115 memset(&hints, 0, sizeof(hints));
116 hints.ai_family = PF_UNSPEC;
117#ifdef NO_ASYNC
118 getaddrinfo(is->hostname, NULL, &hints, &result.ar_addrinfo);
119 result.ar_gai_errno = errno;
120 dns_done_host(&result, is);
121#else
122 as = getaddrinfo_async(is->hostname, NULL, &hints, NULL);
123 event_asr_run(as, dns_done_host, is);
124#endif
125 } else {
126 icbd_log(is, LOG_DEBUG, "reverse dns resolution failed: %s",
127 gai_strerror(ar->ar_gai_errno));
128 CLRF(is->flags, ICB_SF_DNSINPROGRESS);
129 }
130}
131
132int
133cmp_addr(struct sockaddr *a, struct sockaddr *b)
134{
135 if (a->sa_family != b->sa_family)
136 return (a->sa_family - b->sa_family);
137
138 if (a->sa_family == AF_INET)
139 return (((struct sockaddr_in *)a)->sin_addr.s_addr -
140 ((struct sockaddr_in *)b)->sin_addr.s_addr);
141
142 if (a->sa_family == AF_INET6)
143 return (memcmp(&((struct sockaddr_in6 *)a)->sin6_addr,
144 &((struct sockaddr_in6 *)b)->sin6_addr,
145 sizeof (struct in6_addr)));
146
147 return -1;
148}
149
150void
151dns_resolve(struct icb_session *is)
152{
153#ifdef NO_ASYNC
154 struct asr_result result;
155#else
156 struct asr_query *as;
157#endif
158
159 if (!dodns)
160 return;
161
162 SETF(is->flags, ICB_SF_DNSINPROGRESS);
163
164 if (verbose)
165 icbd_log(is, LOG_DEBUG, "resolving: %s", is->host);
166
167#ifdef NO_ASYNC
168 getnameinfo((struct sockaddr *)&is->ss,
169 ((struct sockaddr *)&is->ss)->sa_len, is->hostname,
170 sizeof is->hostname, NULL, 0, NI_NOFQDN);
171 result.ar_gai_errno = errno;
172 dns_done_reverse(&result, is);
173#else
174 as = getnameinfo_async((struct sockaddr *)&is->ss,
175 ((struct sockaddr *)&is->ss)->sa_len, is->hostname,
176 sizeof is->hostname, NULL, 0, NI_NOFQDN, NULL);
177 event_asr_run(as, dns_done_reverse, is);
178#endif
179}
180
Note: See TracBrowser for help on using the repository browser.