Changes in uspace/srv/net/dnsrsrv/query.c [5a324d99:959d2ec] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/dnsrsrv/query.c
r5a324d99 r959d2ec 39 39 #include <stdlib.h> 40 40 #include <str.h> 41 41 42 #include "dns_msg.h" 42 43 #include "dns_std.h" … … 47 48 static uint16_t msg_id; 48 49 49 static int dns_name_query(const char *name, dns_qtype_t qtype, 50 dns_host_info_t *info) 50 int dns_name2host(const char *name, dns_host_info_t **rinfo) 51 51 { 52 /* Start with the caller-provided name */ 53 char *sname = str_dup(name); 54 if (sname == NULL) 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) 55 62 return ENOMEM; 56 57 char *qname = str_dup(name); 58 if (qname == NULL) { 59 free(sname); 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) 60 70 return ENOMEM; 61 } 62 63 dns_question_t *question = calloc(1, sizeof(dns_question_t)); 64 if (question == NULL) { 65 free(qname); 66 free(sname); 67 return ENOMEM; 68 } 69 70 question->qname = qname; 71 question->qtype = qtype; 72 question->qclass = DC_IN; 73 74 dns_message_t *msg = dns_message_new(); 75 if (msg == NULL) { 76 free(question); 77 free(qname); 78 free(sname); 79 return ENOMEM; 80 } 81 71 72 list_append(&question->msg, &msg->question); 73 82 74 msg->id = msg_id++; 83 75 msg->qr = QR_QUERY; … … 87 79 msg->rd = true; 88 80 msg->ra = false; 89 90 list_append(&question->msg, &msg->question); 91 92 dns_message_t *amsg; 93 int rc = dns_request(msg, &amsg); 81 82 rc = dns_request(msg, &amsg); 94 83 if (rc != EOK) { 95 dns_message_destroy(msg);96 free(sname);97 84 return rc; 98 85 } 99 100 list_foreach(amsg->answer, msg, dns_rr_t, rr) { 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 101 93 log_msg(LOG_DEFAULT, LVL_DEBUG, " - '%s' %u/%u, dsize %zu", 102 rr->name, rr->rtype, rr->rclass, rr->rdata_size); 103 104 if ((rr->rtype == DTYPE_CNAME) && (rr->rclass == DC_IN) && 105 (str_cmp(rr->name, sname) == 0)) { 106 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) { 107 98 log_msg(LOG_DEFAULT, LVL_DEBUG, "decode cname (%p, %zu, %zu)", 108 99 amsg->pdu.data, amsg->pdu.size, rr->roff); 109 110 char *cname;111 size_t eoff;112 100 rc = dns_name_decode(&amsg->pdu, rr->roff, &cname, &eoff); 113 101 if (rc != EOK) { 114 assert((rc == EINVAL) || (rc == ENOMEM)); 115 116 log_msg(LOG_DEFAULT, LVL_DEBUG, "error decoding cname"); 117 102 log_msg(LOG_DEFAULT, LVL_DEBUG, 103 "error decoding cname"); 104 assert(rc == EINVAL || rc == ENOMEM); 118 105 dns_message_destroy(msg); 119 106 dns_message_destroy(amsg); 120 free(sname);121 122 107 return rc; 123 108 } 124 109 125 110 log_msg(LOG_DEFAULT, LVL_DEBUG, "name = '%s' " 126 111 "cname = '%s'", sname, cname); 127 112 113 free(sname); 128 114 /* Continue looking for the more canonical name */ 129 free(sname);130 115 sname = cname; 131 116 } 132 133 if ( (qtype == DTYPE_A) && (rr->rtype == DTYPE_A)&&134 (rr->rclass == DC_IN) && (rr->rdata_size == sizeof(addr32_t)) &&135 (str_cmp(rr->name, sname) == 0)) {136 137 info ->cname = str_dup(rr->name);138 if (info ->cname== NULL) {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) { 139 124 dns_message_destroy(msg); 140 125 dns_message_destroy(amsg); 141 free(sname);142 143 126 return ENOMEM; 144 127 } 145 146 inet_addr_set(dns_uint32_t_decode(rr->rdata, rr->rdata_size), 147 &info->addr); 148 128 129 info->cname = str_dup(rr->name); 130 info->addr.ipv4 = dns_uint32_t_decode(rr->rdata, rr->rdata_size); 131 log_msg(LOG_DEFAULT, LVL_DEBUG, "info->name = '%s' " 132 "info->addr = %x", info->cname, info->addr.ipv4); 133 149 134 dns_message_destroy(msg); 150 135 dns_message_destroy(amsg); 151 free(sname); 152 153 return EOK; 154 } 155 156 if ((qtype == DTYPE_AAAA) && (rr->rtype == DTYPE_AAAA) && 157 (rr->rclass == DC_IN) && (rr->rdata_size == sizeof(addr128_t)) && 158 (str_cmp(rr->name, sname) == 0)) { 159 160 info->cname = str_dup(rr->name); 161 if (info->cname == NULL) { 162 dns_message_destroy(msg); 163 dns_message_destroy(amsg); 164 free(sname); 165 166 return ENOMEM; 167 } 168 169 addr128_t addr; 170 dns_addr128_t_decode(rr->rdata, rr->rdata_size, addr); 171 172 inet_addr_set6(addr, &info->addr); 173 174 dns_message_destroy(msg); 175 dns_message_destroy(amsg); 176 free(sname); 177 136 *rinfo = info; 178 137 return EOK; 179 138 } 180 139 } 181 182 log_msg(LOG_DEFAULT, LVL_DEBUG, "'%s' not resolved, fail", sname); 183 140 184 141 dns_message_destroy(msg); 185 142 dns_message_destroy(amsg); 186 free(sname);187 143 log_msg(LOG_DEFAULT, LVL_DEBUG, "'%s' not resolved, fail", sname); 144 188 145 return EIO; 189 }190 191 int dns_name2host(const char *name, dns_host_info_t **rinfo, ip_ver_t ver)192 {193 dns_host_info_t *info = calloc(1, sizeof(dns_host_info_t));194 if (info == NULL)195 return ENOMEM;196 197 int rc;198 199 switch (ver) {200 case ip_any:201 rc = dns_name_query(name, DTYPE_AAAA, info);202 203 if (rc != EOK)204 rc = dns_name_query(name, DTYPE_A, info);205 206 break;207 case ip_v4:208 rc = dns_name_query(name, DTYPE_A, info);209 break;210 case ip_v6:211 rc = dns_name_query(name, DTYPE_AAAA, info);212 break;213 default:214 rc = EINVAL;215 }216 217 if (rc == EOK)218 *rinfo = info;219 else220 free(info);221 222 return rc;223 146 } 224 147
Note:
See TracChangeset
for help on using the changeset viewer.