Bug Summary

File:s2check/s2dns.c
Warning:line 472, column 12
Although the value stored to 'prefix' is used in the enclosing expression, the value is never actually read from 'prefix'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name s2dns.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-11/lib/clang/11.0.1 -D HAVE_CONFIG_H -I . -I .. -I ../libsofia-sip-ua/su/sofia-sip -I ../libsofia-sip-ua/features -I ../libsofia-sip-ua/features -I ../libsofia-sip-ua/ipt -I ../libsofia-sip-ua/ipt -I ../libsofia-sip-ua/iptsec -I ../libsofia-sip-ua/iptsec -I ../libsofia-sip-ua/bnf -I ../libsofia-sip-ua/bnf -I ../libsofia-sip-ua/http -I ../libsofia-sip-ua/http -I ../libsofia-sip-ua/msg -I ../libsofia-sip-ua/msg -I ../libsofia-sip-ua/nth -I ../libsofia-sip-ua/nth -I ../libsofia-sip-ua/nta -I ../libsofia-sip-ua/nta -I ../libsofia-sip-ua/nea -I ../libsofia-sip-ua/nea -I ../libsofia-sip-ua/nua -I ../libsofia-sip-ua/nua -I ../libsofia-sip-ua/soa -I ../libsofia-sip-ua/soa -I ../libsofia-sip-ua/sdp -I ../libsofia-sip-ua/sdp -I ../libsofia-sip-ua/sip -I ../libsofia-sip-ua/sip -I ../libsofia-sip-ua/soa -I ../libsofia-sip-ua/soa -I ../libsofia-sip-ua/sresolv -I ../libsofia-sip-ua/sresolv -I ../libsofia-sip-ua/tport -I ../libsofia-sip-ua/tport -I ../libsofia-sip-ua/stun -I ../libsofia-sip-ua/stun -I ../libsofia-sip-ua/url -I ../libsofia-sip-ua/url -I ../libsofia-sip-ua/su -I ../libsofia-sip-ua/su -D SU_DEBUG=0 -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-11/lib/clang/11.0.1/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir /drone/src/s2check -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-output=html -faddrsig -o /drone/src/scan-build/2022-06-23-181620-12-1 -x c s2dns.c
1/* ---------------------------------------------------------------------- */
2/* S2 DNS server */
3
4#include <sofia-sip/sresolv.h>
5#include <sofia-resolv/sres_record.h>
6#include <sofia-sip/url.h>
7
8#include "s2dns.h"
9
10#include <string.h>
11#include <stdlib.h>
12#include <assert.h>
13
14extern uint16_t _sres_default_port; /* Ugly hack */
15
16static struct s2dns {
17 su_root_t *root;
18 su_socket_t socket;
19 su_wait_t wait[1];
20 int reg;
21 int (*filter)(void *data, size_t len, void *userdata);
22 void *userdata;
23} s2dns;
24
25static
26struct s2_dns_response {
27 struct s2_dns_response *next;
28 uint16_t qlen, dlen;
29 struct m_header {
30 /* Header defined in RFC 1035 section 4.1.1 (page 26) */
31 uint16_t mh_id; /* Query ID */
32 uint16_t mh_flags; /* Flags */
33 uint16_t mh_qdcount; /* Question record count */
34 uint16_t mh_ancount; /* Answer record count */
35 uint16_t mh_nscount; /* Authority records count */
36 uint16_t mh_arcount; /* Additional records count */
37 } header[1];
38 uint8_t data[1500];
39} *zonedata;
40
41enum {
42 FLAGS_QR = (1 << 15),
43 FLAGS_QUERY = (0 << 11),
44 FLAGS_IQUERY = (1 << 11),
45 FLAGS_STATUS = (2 << 11),
46 FLAGS_OPCODE = (15 << 11), /* mask */
47 FLAGS_AA = (1 << 10), /* */
48 FLAGS_TC = (1 << 9),
49 FLAGS_RD = (1 << 8),
50 FLAGS_RA = (1 << 7),
51
52 FLAGS_RCODE = (15 << 0), /* mask of return code */
53
54 FLAGS_OK = 0, /* No error condition. */
55 FLAGS_FORMAT_ERR = 1, /* Server could not interpret query. */
56 FLAGS_SERVER_ERR = 2, /* Server error. */
57 FLAGS_NAME_ERR = 3, /* No domain name. */
58 FLAGS_UNIMPL_ERR = 4, /* Not implemented. */
59 FLAGS_AUTH_ERR = 5, /* Refused */
60};
61
62uint32_t s2_dns_ttl = 3600;
63
64static int s2_dns_query(su_root_magic_t *magic,
65 su_wait_t *w,
66 su_wakeup_arg_t *arg);
67
68void s2_dns_setup(su_root_t *root)
69{
70 int n;
71 su_socket_t socket;
72 su_wait_t *wait;
73 su_sockaddr_t su[1];
74 socklen_t sulen = sizeof su->su_sin;
75
76 assert(root)((void) sizeof ((root) ? 1 : 0), __extension__ ({ if (root) ;
else __assert_fail ("root", "s2dns.c", 76, __extension__ __PRETTY_FUNCTION__
); }))
;
77
78 memset(su, 0, sulen);
79 su->su_lensu_array[0] = sulen;
80 su->su_familysu_sa.sa_family = AF_INET2;
81
82 /* su->su_port = htons(1053); */
83
84 socket = su_socket(su->su_familysu_sa.sa_family, SOCK_DGRAMSOCK_DGRAM, 0);
85
86 n = bind(socket, &su->su_sa, sulen); assert(n == 0)((void) sizeof ((n == 0) ? 1 : 0), __extension__ ({ if (n == 0
) ; else __assert_fail ("n == 0", "s2dns.c", 86, __extension__
__PRETTY_FUNCTION__); }))
;
87 n = getsockname(socket, &su->su_sa, &sulen); assert(n == 0)((void) sizeof ((n == 0) ? 1 : 0), __extension__ ({ if (n == 0
) ; else __assert_fail ("n == 0", "s2dns.c", 87, __extension__
__PRETTY_FUNCTION__); }))
;
88
89 _sres_default_port = ntohs(su->su_portsu_sin.sin_port);
90
91 s2dns.root = root;
92 wait = s2dns.wait;
93 n = su_wait_create(wait, socket, SU_WAIT_IN(0x001)); assert(n == 0)((void) sizeof ((n == 0) ? 1 : 0), __extension__ ({ if (n == 0
) ; else __assert_fail ("n == 0", "s2dns.c", 93, __extension__
__PRETTY_FUNCTION__); }))
;
94 s2dns.reg = su_root_register(root, wait, s2_dns_query, NULL((void*)0), 0);
95 assert(s2dns.reg > 0)((void) sizeof ((s2dns.reg > 0) ? 1 : 0), __extension__ ({
if (s2dns.reg > 0) ; else __assert_fail ("s2dns.reg > 0"
, "s2dns.c", 95, __extension__ __PRETTY_FUNCTION__); }))
;
96 s2dns.socket = socket;
97}
98
99/* Set filter function */
100void
101s2_dns_set_filter(int (*filter)(void *data, size_t len, void *userdata),
102 void *userdata)
103{
104 s2dns.filter = filter;
105 s2dns.userdata = userdata;
106}
107
108void
109s2_dns_teardown(void)
110{
111 struct s2_dns_response *r, *next;
112 su_root_deregister(s2dns.root, s2dns.reg), s2dns.reg = -1;
113 su_close(s2dns.socket), s2dns.socket = -1;
114 s2dns.root = NULL((void*)0);
115
116 for (r = zonedata, zonedata = NULL((void*)0); r; r = next) {
117 next = r->next;
118 free(r);
119 }
120}
121
122static int
123s2_dns_query(su_root_magic_t *magic,
124 su_wait_t *w,
125 su_wakeup_arg_t *arg)
126{
127 union {
128 struct m_header header[1];
129 uint8_t buffer[1500];
130 } request;
131 ssize_t len;
132
133 su_socket_t socket;
134 su_sockaddr_t su[1];
135 socklen_t sulen = sizeof su;
136 uint16_t flags;
137 struct s2_dns_response *r;
138 size_t const hlen = sizeof r->header;
139
140 (void)arg;
141
142 socket = s2dns.socket;
143
144 len = su_recvfrom(socket, request.buffer, sizeof request.buffer, 0,recvfrom((socket),(request.buffer),(sizeof request.buffer),(0
),(void *)(&su->su_sa),(&sulen))
145 &su->su_sa, &sulen)recvfrom((socket),(request.buffer),(sizeof request.buffer),(0
),(void *)(&su->su_sa),(&sulen))
;
146
147 flags = ntohs(request.header->mh_flags);
148
149 if (len < (ssize_t)hlen)
150 return 0;
151 if ((flags & FLAGS_QR) == FLAGS_QR)
152 return 0;
153 if ((flags & FLAGS_RCODE) != FLAGS_OK)
154 return 0;
155
156 if ((flags & FLAGS_OPCODE) != FLAGS_QUERY
157 || ntohs(request.header->mh_qdcount) != 1) {
158 flags |= FLAGS_QR | FLAGS_UNIMPL_ERR;
159 request.header->mh_flags = htons(flags);
160 if (!s2dns.filter || s2dns.filter(request.buffer, len, s2dns.userdata))
161 su_sendto(socket, request.buffer, len, 0, &su->su_sa, sulen)sendto((socket),(request.buffer),(len),(0),(void const*)(&
su->su_sa),(sulen))
;
162 return 0;
163 }
164
165 for (r = zonedata; r; r = r->next) {
166 if (memcmp(r->data, request.buffer + hlen, r->qlen) == 0)
167 break;
168 }
169
170 if (r) {
171 flags |= FLAGS_QR | FLAGS_AA | FLAGS_OK;
172 request.header->mh_flags = htons(flags);
173 request.header->mh_ancount = htons(r->header->mh_ancount);
174 request.header->mh_nscount = htons(r->header->mh_nscount);
175 request.header->mh_arcount = htons(r->header->mh_arcount);
176 memcpy(request.buffer + hlen + r->qlen,
177 r->data + r->qlen,
178 r->dlen - r->qlen);
179 len = hlen + r->dlen;
180 }
181 else {
182 flags |= FLAGS_QR | FLAGS_AA | FLAGS_NAME_ERR;
183 }
184
185 request.header->mh_flags = htons(flags);
186 if (!s2dns.filter || s2dns.filter(request.buffer, len, s2dns.userdata))
187 su_sendto(socket, request.buffer, len, 0, &su->su_sa, sulen)sendto((socket),(request.buffer),(len),(0),(void const*)(&
su->su_sa),(sulen))
;
188 return 0;
189}
190
191static char const *default_domain;
192
193/** Set default domain suffix used with s2_dns_record() */
194char const *
195s2_dns_default(char const *domain)
196{
197 assert(domain == NULL || strlen(domain))((void) sizeof ((domain == ((void*)0) || strlen(domain)) ? 1 :
0), __extension__ ({ if (domain == ((void*)0) || strlen(domain
)) ; else __assert_fail ("domain == NULL || strlen(domain)", "s2dns.c"
, 197, __extension__ __PRETTY_FUNCTION__); }))
;
198 assert(domain == NULL || domain[strlen(domain) - 1] == '.')((void) sizeof ((domain == ((void*)0) || domain[strlen(domain
) - 1] == '.') ? 1 : 0), __extension__ ({ if (domain == ((void
*)0) || domain[strlen(domain) - 1] == '.') ; else __assert_fail
("domain == NULL || domain[strlen(domain) - 1] == '.'", "s2dns.c"
, 198, __extension__ __PRETTY_FUNCTION__); }))
;
199 return default_domain = domain;
200}
201
202static void put_uint16(struct s2_dns_response *m, uint16_t h)
203{
204 uint8_t *p = m->data + m->dlen;
205
206 assert(m->dlen + (sizeof h) < sizeof m->data)((void) sizeof ((m->dlen + (sizeof h) < sizeof m->data
) ? 1 : 0), __extension__ ({ if (m->dlen + (sizeof h) <
sizeof m->data) ; else __assert_fail ("m->dlen + (sizeof h) < sizeof m->data"
, "s2dns.c", 206, __extension__ __PRETTY_FUNCTION__); }))
;
207 p[0] = h >> 8; p[1] = h;
208 m->dlen += (sizeof h);
209}
210
211static void put_uint32(struct s2_dns_response *m, uint32_t w)
212{
213 uint8_t *p = m->data + m->dlen;
214
215 assert(m->dlen + (sizeof w) < sizeof m->data)((void) sizeof ((m->dlen + (sizeof w) < sizeof m->data
) ? 1 : 0), __extension__ ({ if (m->dlen + (sizeof w) <
sizeof m->data) ; else __assert_fail ("m->dlen + (sizeof w) < sizeof m->data"
, "s2dns.c", 215, __extension__ __PRETTY_FUNCTION__); }))
;
216 p[0] = w >> 24; p[1] = w >> 16; p[2] = w >> 8; p[3] = w;
217 m->dlen += (sizeof w);
218}
219
220static void put_domain(struct s2_dns_response *m, char const *domain)
221{
222 char const *label;
223 size_t llen;
224
225 if (domain && domain[0] == 0)
226 domain = default_domain;
227
228 /* Copy domain into query label at a time */
229 for (label = domain; label && label[0]; label += llen) {
230 assert(!(label[0] == '.' && label[1] != '\0'))((void) sizeof ((!(label[0] == '.' && label[1] != '\0'
)) ? 1 : 0), __extension__ ({ if (!(label[0] == '.' &&
label[1] != '\0')) ; else __assert_fail ("!(label[0] == '.' && label[1] != '\\0')"
, "s2dns.c", 230, __extension__ __PRETTY_FUNCTION__); }))
;
231 llen = strcspn(label, ".");
232 assert(llen < 64)((void) sizeof ((llen < 64) ? 1 : 0), __extension__ ({ if (
llen < 64) ; else __assert_fail ("llen < 64", "s2dns.c"
, 232, __extension__ __PRETTY_FUNCTION__); }))
;
233 assert(m->dlen + llen + 1 < sizeof m->data)((void) sizeof ((m->dlen + llen + 1 < sizeof m->data
) ? 1 : 0), __extension__ ({ if (m->dlen + llen + 1 < sizeof
m->data) ; else __assert_fail ("m->dlen + llen + 1 < sizeof m->data"
, "s2dns.c", 233, __extension__ __PRETTY_FUNCTION__); }))
;
234 m->data[m->dlen++] = (uint8_t)llen;
235 if (llen == 0)
236 return;
237
238 memcpy(m->data + m->dlen, label, llen);
239 m->dlen += (uint16_t)llen;
240
241 if (label[llen] == '\0') {
242 if (default_domain) {
243 label = default_domain, llen = 0;
244 continue;
245 }
246 break;
247 }
248 if (label[llen + 1])
249 llen++;
250 }
251
252 assert(m->dlen < sizeof m->data)((void) sizeof ((m->dlen < sizeof m->data) ? 1 : 0),
__extension__ ({ if (m->dlen < sizeof m->data) ; else
__assert_fail ("m->dlen < sizeof m->data", "s2dns.c"
, 252, __extension__ __PRETTY_FUNCTION__); }))
;
253 m->data[m->dlen++] = '\0';
254}
255
256static void put_string(struct s2_dns_response *m, char const *string)
257{
258 uint8_t *p = m->data + m->dlen;
259 size_t len = strlen(string);
260
261 assert(len <= 255)((void) sizeof ((len <= 255) ? 1 : 0), __extension__ ({ if
(len <= 255) ; else __assert_fail ("len <= 255", "s2dns.c"
, 261, __extension__ __PRETTY_FUNCTION__); }))
;
262 assert(m->dlen + len + 1 < sizeof m->data)((void) sizeof ((m->dlen + len + 1 < sizeof m->data)
? 1 : 0), __extension__ ({ if (m->dlen + len + 1 < sizeof
m->data) ; else __assert_fail ("m->dlen + len + 1 < sizeof m->data"
, "s2dns.c", 262, __extension__ __PRETTY_FUNCTION__); }))
;
263
264 *p++ = (uint8_t)len;
265 memcpy(p, string, len);
266 m->dlen += len + 1;
267}
268
269static uint16_t put_len_at(struct s2_dns_response *m)
270{
271 uint16_t at = m->dlen;
272 assert(m->dlen + sizeof(at) < sizeof m->data)((void) sizeof ((m->dlen + sizeof(at) < sizeof m->data
) ? 1 : 0), __extension__ ({ if (m->dlen + sizeof(at) <
sizeof m->data) ; else __assert_fail ("m->dlen + sizeof(at) < sizeof m->data"
, "s2dns.c", 272, __extension__ __PRETTY_FUNCTION__); }))
;
273 memset(m->data + m->dlen, 0, sizeof(at));
274 m->dlen += sizeof(at);
275 return at;
276}
277
278static void put_len(struct s2_dns_response *m, uint16_t start)
279{
280 uint8_t *p = m->data + start;
281 uint16_t len = m->dlen - (start + 2);
282 p[0] = len >> 8; p[1] = len;
283}
284
285static void put_data(struct s2_dns_response *m, void const *data, uint16_t len)
286{
287 assert(m->dlen + len < sizeof m->data)((void) sizeof ((m->dlen + len < sizeof m->data) ? 1
: 0), __extension__ ({ if (m->dlen + len < sizeof m->
data) ; else __assert_fail ("m->dlen + len < sizeof m->data"
, "s2dns.c", 287, __extension__ __PRETTY_FUNCTION__); }))
;
288 memcpy(m->data + m->dlen, data, len);
289 m->dlen += len;
290}
291
292static void put_query(struct s2_dns_response *m, char const *domain,
293 uint16_t qtype)
294{
295 assert(m->header->mh_qdcount == 0)((void) sizeof ((m->header->mh_qdcount == 0) ? 1 : 0), __extension__
({ if (m->header->mh_qdcount == 0) ; else __assert_fail
("m->header->mh_qdcount == 0", "s2dns.c", 295, __extension__
__PRETTY_FUNCTION__); }))
;
296 put_domain(m, domain), put_uint16(m, qtype), put_uint16(m, sres_class_in);
297 m->header->mh_qdcount++;
298 m->qlen = m->dlen;
299}
300
301static void put_a_record(struct s2_dns_response *m,
302 char const *domain,
303 struct in_addr addr)
304{
305 uint16_t start;
306
307 put_domain(m, domain);
308 put_uint16(m, sres_type_a);
309 put_uint16(m, sres_class_in);
310 put_uint32(m, s2_dns_ttl);
311 start = put_len_at(m);
312
313 put_data(m, &addr, sizeof addr);
314 put_len(m, start);
315}
316
317static void put_aaaa_record(struct s2_dns_response *m,
318 char const *domain,
319 struct in6_addr addr)
320{
321 uint16_t start;
322
323 put_domain(m, domain);
324 put_uint16(m, sres_type_aaaa);
325 put_uint16(m, sres_class_in);
326 put_uint32(m, s2_dns_ttl);
327 start = put_len_at(m);
328
329 put_data(m, &addr, sizeof addr);
330 put_len(m, start);
331}
332
333static void put_cname_record(struct s2_dns_response *m,
334 char const *domain,
335 char const *cname)
336{
337 uint16_t start;
338
339 put_domain(m, domain);
340 put_uint16(m, sres_type_cname);
341 put_uint16(m, sres_class_in);
342 put_uint32(m, s2_dns_ttl);
343 start = put_len_at(m);
344
345 put_domain(m, cname);
346 put_len(m, start);
347}
348
349static void put_srv_record(struct s2_dns_response *m,
350 char const *domain,
351 uint16_t prio, uint16_t weight,
352 uint16_t port, char const *target)
353{
354 uint16_t start;
355 put_domain(m, domain);
356 put_uint16(m, sres_type_srv);
357 put_uint16(m, sres_class_in);
358 put_uint32(m, s2_dns_ttl);
359 start = put_len_at(m);
360
361 put_uint16(m, prio);
362 put_uint16(m, weight);
363 put_uint16(m, port);
364 put_domain(m, target);
365 put_len(m, start);
366}
367
368static void put_naptr_record(struct s2_dns_response *m,
369 char const *domain,
370 uint16_t order, uint16_t preference,
371 char const *flags,
372 char const *services,
373 char const *regexp,
374 char const *replace)
375{
376 uint16_t start;
377 put_domain(m, domain);
378 put_uint16(m, sres_type_naptr);
379 put_uint16(m, sres_class_in);
380 put_uint32(m, s2_dns_ttl);
381 start = put_len_at(m);
382
383 put_uint16(m, order);
384 put_uint16(m, preference);
385 put_string(m, flags);
386 put_string(m, services);
387 put_string(m, regexp);
388 put_domain(m, replace);
389 put_len(m, start);
390}
391
392static void put_srv_record_from_uri(struct s2_dns_response *m,
393 char const *base,
394 uint16_t prio, uint16_t weight,
395 url_t const *uri, char const *server)
396{
397 char domain[1024] = "none";
398 char const *service = url_port(uri);
399 uint16_t port;
400
401 if (uri->url_type == url_sips) {
402 strcpy(domain, "_sips._tcp.");
403 }
404 else if (uri->url_type == url_sip) {
405 if (url_has_param(uri, "transport=udp")) {
406 strcpy(domain, "_sip._udp.");
407 }
408 else if (url_has_param(uri, "transport=tcp")) {
409 strcpy(domain, "_sip._tcp.");
410 }
411 }
412
413 assert(strcmp(domain, "none"))((void) sizeof ((strcmp(domain, "none")) ? 1 : 0), __extension__
({ if (strcmp(domain, "none")) ; else __assert_fail ("strcmp(domain, \"none\")"
, "s2dns.c", 413, __extension__ __PRETTY_FUNCTION__); }))
;
414
415 strcat(domain, base);
416
417 if (m->header->mh_qdcount == 0)
418 put_query(m, domain, sres_type_srv);
419
420 port = (uint16_t)strtoul(service, NULL((void*)0), 10);
421
422 put_srv_record(m, domain, prio, weight, port, server);
423}
424
425static
426void s2_add_to_zone(struct s2_dns_response *_r)
427{
428 size_t size = offsetof(struct s2_dns_response, data[_r->dlen])__builtin_offsetof(struct s2_dns_response, data[_r->dlen]);
429 struct s2_dns_response *r = malloc(size); assert(r)((void) sizeof ((r) ? 1 : 0), __extension__ ({ if (r) ; else __assert_fail
("r", "s2dns.c", 429, __extension__ __PRETTY_FUNCTION__); })
)
;
430
431 memcpy(r, _r, size);
432 r->next = zonedata;
433 zonedata = r;
434}
435
436
437static void make_server(char *server, char const *prefix, char const *domain)
438{
439 strcpy(server, prefix);
440
441 if (strlen(server) == 0 || server[strlen(server) - 1] != '.') {
442 strcat(server, ".");
443 strcat(server, domain);
444 }
445}
446
447/** Set up records for SIP server */
448void s2_dns_domain(char const *domain, int use_naptr,
449 /* char *prefix, int priority, url_t const *uri, */
450 ...)
451{
452 struct s2_dns_response m[1];
453
454 char server[1024], target[1024];
455
456 va_list va0, va;
457 char const *prefix; int priority; url_t const *uri;
458 struct in_addr localhost;
459
460 assert(s2dns.reg != 0)((void) sizeof ((s2dns.reg != 0) ? 1 : 0), __extension__ ({ if
(s2dns.reg != 0) ; else __assert_fail ("s2dns.reg != 0", "s2dns.c"
, 460, __extension__ __PRETTY_FUNCTION__); }))
;
461
462 su_inet_ptoninet_pton(AF_INET2, "127.0.0.1", &localhost);
463
464 va_start(va0, use_naptr)__builtin_va_start(va0, use_naptr);
465
466 if (use_naptr) {
467 memset(m, 0, sizeof m);
468 put_query(m, domain, sres_type_naptr);
469
470 va_copy(va, va0)__builtin_va_copy(va, va0);
471
472 for (;(prefix = va_arg(va, char *)__builtin_va_arg(va, char *));) {
Although the value stored to 'prefix' is used in the enclosing expression, the value is never actually read from 'prefix'
473 char *services = NULL((void*)0);
474
475 priority = va_arg(va, int)__builtin_va_arg(va, int);
476 uri = va_arg(va, url_t *)__builtin_va_arg(va, url_t *);
477 if (uri == NULL((void*)0))
478 continue;
479
480 if (uri->url_type == url_sips) {
481 services = "SIPS+D2T";
482 strcpy(target, "_sips._tcp.");
483 }
484 else if (uri->url_type == url_sip) {
485 if (url_has_param(uri, "transport=udp")) {
486 services = "SIP+D2U";
487 strcpy(target, "_sip._udp.");
488 }
489 else if (url_has_param(uri, "transport=tcp")) {
490 services = "SIP+D2T";
491 strcpy(target, "_sip._tcp.");
492 }
493 }
494
495 strcat(target, domain);
496 assert(services)((void) sizeof ((services) ? 1 : 0), __extension__ ({ if (services
) ; else __assert_fail ("services", "s2dns.c", 496, __extension__
__PRETTY_FUNCTION__); }))
;
497 put_naptr_record(m, domain, 1, priority, "s", services, "", target);
498 m->header->mh_ancount++;
499 }
500
501 va_end(va)__builtin_va_end(va);
502 va_copy(va, va0)__builtin_va_copy(va, va0);
503
504 for (;(prefix = va_arg(va, char *)__builtin_va_arg(va, char *));) {
505 priority = va_arg(va, int)__builtin_va_arg(va, int);
506 uri = va_arg(va, url_t *)__builtin_va_arg(va, url_t *);
507 if (uri == NULL((void*)0))
508 continue;
509
510 make_server(server, prefix, domain);
511
512 put_srv_record_from_uri(m, domain, priority, 10, uri, server);
513 m->header->mh_arcount++;
514
515 put_a_record(m, server, localhost);
516 m->header->mh_arcount++;
517 }
518 va_end(va)__builtin_va_end(va);
519
520 s2_add_to_zone(m);
521 }
522
523 /* Add SRV records */
524 va_copy(va, va0)__builtin_va_copy(va, va0);
525 for (;(prefix = va_arg(va, char *)__builtin_va_arg(va, char *));) {
526 priority = va_arg(va, int)__builtin_va_arg(va, int);
527 uri = va_arg(va, url_t *)__builtin_va_arg(va, url_t *);
528 if (uri == NULL((void*)0))
529 continue;
530
531 make_server(server, prefix, domain);
532
533 memset(m, 0, sizeof m);
534 put_srv_record_from_uri(m, domain, priority, 10, uri, server);
535 m->header->mh_ancount++;
536
537 strcpy(server, prefix); strcat(server, domain);
538
539 put_a_record(m, server, localhost);
540 m->header->mh_arcount++;
541
542 s2_add_to_zone(m);
543 }
544 va_end(va)__builtin_va_end(va);
545
546 /* Add A records */
547 va_copy(va, va0)__builtin_va_copy(va, va0);
548 for (;(prefix = va_arg(va, char *)__builtin_va_arg(va, char *));) {
549 (void)va_arg(va, int)__builtin_va_arg(va, int);
550 if (va_arg(va, url_t *)__builtin_va_arg(va, url_t *) == NULL((void*)0))
551 continue;
552
553 memset(m, 0, sizeof m);
554 make_server(server, prefix, domain);
555
556 put_query(m, server, sres_type_a);
557 put_a_record(m, server, localhost);
558 m->header->mh_ancount++;
559
560 s2_add_to_zone(m);
561 }
562 va_end(va)__builtin_va_end(va);
563
564 va_end(va0)__builtin_va_end(va0);
565}
566
567/** Insert DNS response.
568
569 s2_dns_record("example.com", sres_type_naptr,
570 // order priority flags services regexp target
571 "", sres_type_naptr, 20, 50, "a", "SIP+D2U", "", "sip00",
572 "", sres_type_naptr, 20, 50, "a", "SIP+D2T", "", "sip00",
573 "", sres_type_naptr, 20, 50, "a", "SIPS+D2T", "", "sip00",
574 "sip00", sres_type_a, "12.13.14.15",
575 NULL);
576*/
577void s2_dns_record(
578 char const *qdomain, unsigned qtype,
579 /* unsigned atype, domain, */
580 ...)
581{
582 struct s2_dns_response m[1];
583 char const *domain;
584 va_list va;
585 unsigned atype;
586 unsigned ancount = 0, arcount = 0;
587
588 memset(m, 0, (sizeof m));
589
590 va_start(va, qtype)__builtin_va_start(va, qtype);
591
592 put_query(m, qdomain, qtype);
593
594 for (domain = va_arg(va, char const *)__builtin_va_arg(va, char const *); domain; domain = va_arg(va, char const *)__builtin_va_arg(va, char const *)) {
595 if (!domain[0])
596 domain = qdomain;
597
598 if (strcmp(domain, "@") == 0)
599 domain = default_domain;
600
601 atype = va_arg(va, unsigned)__builtin_va_arg(va, unsigned);
602
603 if (arcount == 0 &&
604 (atype == qtype || atype == sres_type_cname) &&
605 strcmp(qdomain, domain) == 0)
606 ancount++;
607 else
608 arcount++;
609
610 switch(atype) {
611 case sres_type_naptr:
612 {
613 unsigned order = va_arg(va, unsigned)__builtin_va_arg(va, unsigned);
614 unsigned priority = va_arg(va, unsigned)__builtin_va_arg(va, unsigned);
615 char const *flags = va_arg(va, char const *)__builtin_va_arg(va, char const *);
616 char const *services = va_arg(va, char const *)__builtin_va_arg(va, char const *);
617 char const *regexp = va_arg(va, char const *)__builtin_va_arg(va, char const *);
618 char const *target = va_arg(va, char const *)__builtin_va_arg(va, char const *);
619
620 put_naptr_record(m, domain, order, priority,
621 flags, services, regexp, target);
622 }
623 break;
624 case sres_type_srv:
625 {
626 unsigned priority = va_arg(va, unsigned)__builtin_va_arg(va, unsigned);
627 unsigned weight = va_arg(va, unsigned)__builtin_va_arg(va, unsigned);
628 unsigned port = va_arg(va, unsigned)__builtin_va_arg(va, unsigned);
629 char const *target = va_arg(va, char const *)__builtin_va_arg(va, char const *);
630
631 put_srv_record(m, domain, priority, weight, port, target);
632 }
633 break;
634 case sres_type_aaaa:
635#if SU_HAVE_IN61
636 {
637 char const *address = va_arg(va, char const *)__builtin_va_arg(va, char const *); /* target */
638 struct in6_addr aaaa;
639
640 inet_pton(AF_INET610, address, &aaaa);
641
642 put_aaaa_record(m, domain, aaaa);
643 }
644 break;
645#endif
646 case sres_type_a:
647 {
648 char const *address = va_arg(va, char const *)__builtin_va_arg(va, char const *); /* target */
649 struct in_addr a;
650
651 inet_pton(AF_INET2, address, &a);
652
653 put_a_record(m, domain, a);
654 }
655 break;
656 case sres_type_cname:
657 put_cname_record(m, domain, va_arg(va, char const *)__builtin_va_arg(va, char const *));
658 }
659 }
660
661 m->header->mh_ancount = ancount;
662 m->header->mh_arcount = arcount;
663
664 s2_add_to_zone(m);
665
666 va_end(va)__builtin_va_end(va);
667}