source: mainline/uspace/srv/net/dnsrsrv/query.c@ 02a09ed

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 02a09ed was 02a09ed, checked in by Martin Decky <martin@…>, 12 years ago

add basic infrastructure for IPv6 (inactive)
make inet_addr_t a universal address type

  • Property mode set to 100644
File size: 4.0 KB
Line 
1/*
2 * Copyright (c) 2013 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup dnsres
30 * @{
31 */
32/**
33 * @file
34 */
35
36#include <errno.h>
37#include <io/log.h>
38#include <mem.h>
39#include <stdlib.h>
40#include <str.h>
41
42#include "dns_msg.h"
43#include "dns_std.h"
44#include "dns_type.h"
45#include "query.h"
46#include "transport.h"
47
48static uint16_t msg_id;
49
50int dns_name2host(const char *name, dns_host_info_t **rinfo)
51{
52 dns_message_t *msg;
53 dns_message_t *amsg;
54 dns_question_t *question;
55 dns_host_info_t *info;
56 char *sname, *cname;
57 size_t eoff;
58 int rc;
59
60 question = calloc(1, sizeof(dns_question_t));
61 if (question == NULL)
62 return ENOMEM;
63
64 question->qname = (char *)name;
65 question->qtype = DTYPE_A;
66 question->qclass = DC_IN;
67
68 msg = dns_message_new();
69 if (msg == NULL)
70 return ENOMEM;
71
72 list_append(&question->msg, &msg->question);
73
74 msg->id = msg_id++;
75 msg->qr = QR_QUERY;
76 msg->opcode = OPC_QUERY;
77 msg->aa = false;
78 msg->tc = false;
79 msg->rd = true;
80 msg->ra = false;
81
82 rc = dns_request(msg, &amsg);
83 if (rc != EOK) {
84 return rc;
85 }
86
87 /* Start with the caller-provided name */
88 sname = str_dup(name);
89
90 list_foreach(amsg->answer, link) {
91 dns_rr_t *rr = list_get_instance(link, dns_rr_t, msg);
92
93 log_msg(LOG_DEFAULT, LVL_DEBUG, " - '%s' %u/%u, dsize %zu",
94 rr->name, rr->rtype, rr->rclass, rr->rdata_size);
95
96 if (rr->rtype == DTYPE_CNAME && rr->rclass == DC_IN &&
97 str_cmp(rr->name, sname) == 0) {
98 log_msg(LOG_DEFAULT, LVL_DEBUG, "decode cname (%p, %zu, %zu)",
99 amsg->pdu.data, amsg->pdu.size, rr->roff);
100 rc = dns_name_decode(&amsg->pdu, rr->roff, &cname, &eoff);
101 if (rc != EOK) {
102 log_msg(LOG_DEFAULT, LVL_DEBUG,
103 "error decoding cname");
104 assert(rc == EINVAL || rc == ENOMEM);
105 dns_message_destroy(msg);
106 dns_message_destroy(amsg);
107 return rc;
108 }
109
110 log_msg(LOG_DEFAULT, LVL_DEBUG, "name = '%s' "
111 "cname = '%s'", sname, cname);
112
113 free(sname);
114 /* Continue looking for the more canonical name */
115 sname = cname;
116 }
117
118 if (rr->rtype == DTYPE_A && rr->rclass == DC_IN &&
119 rr->rdata_size == sizeof(uint32_t) &&
120 str_cmp(rr->name, sname) == 0) {
121
122 info = calloc(1, sizeof(dns_host_info_t));
123 if (info == NULL) {
124 dns_message_destroy(msg);
125 dns_message_destroy(amsg);
126 return ENOMEM;
127 }
128
129 info->cname = str_dup(rr->name);
130 inet_addr_set(dns_uint32_t_decode(rr->rdata, rr->rdata_size),
131 &info->addr);
132
133 dns_message_destroy(msg);
134 dns_message_destroy(amsg);
135 *rinfo = info;
136 return EOK;
137 }
138 }
139
140 dns_message_destroy(msg);
141 dns_message_destroy(amsg);
142 log_msg(LOG_DEFAULT, LVL_DEBUG, "'%s' not resolved, fail", sname);
143
144 return EIO;
145}
146
147void dns_hostinfo_destroy(dns_host_info_t *info)
148{
149 free(info->cname);
150 free(info);
151}
152
153/** @}
154 */
Note: See TracBrowser for help on using the repository browser.