Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/dnsrsrv/query.c

    r02a09ed r0aa70f4  
    3939#include <stdlib.h>
    4040#include <str.h>
    41 
     41#include <net/socket_codes.h>
    4242#include "dns_msg.h"
    4343#include "dns_std.h"
     
    4848static uint16_t msg_id;
    4949
    50 int dns_name2host(const char *name, dns_host_info_t **rinfo)
     50static int dns_name_query(const char *name, dns_qtype_t qtype,
     51    dns_host_info_t *info)
    5152{
    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;
     53        /* Start with the caller-provided name */
     54        char *sname = str_dup(name);
     55        if (sname == NULL)
     56                return ENOMEM;
     57       
     58        char *qname = str_dup(name);
     59        if (qname == NULL) {
     60                free(sname);
     61                return ENOMEM;
     62        }
     63       
     64        dns_question_t *question = calloc(1, sizeof(dns_question_t));
     65        if (question == NULL) {
     66                free(qname);
     67                free(sname);
     68                return ENOMEM;
     69        }
     70       
     71        question->qname = qname;
     72        question->qtype = qtype;
    6673        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       
     75        dns_message_t *msg = dns_message_new();
     76        if (msg == NULL) {
     77                free(question);
     78                free(qname);
     79                free(sname);
     80                return ENOMEM;
     81        }
     82       
    7483        msg->id = msg_id++;
    7584        msg->qr = QR_QUERY;
     
    7988        msg->rd = true;
    8089        msg->ra = false;
    81 
    82         rc = dns_request(msg, &amsg);
     90       
     91        list_append(&question->msg, &msg->question);
     92       
     93        dns_message_t *amsg;
     94        int rc = dns_request(msg, &amsg);
    8395        if (rc != EOK) {
     96                dns_message_destroy(msg);
     97                free(sname);
    8498                return rc;
    8599        }
    86 
    87         /* Start with the caller-provided name */
    88         sname = str_dup(name);
    89 
     100       
    90101        list_foreach(amsg->answer, link) {
    91102                dns_rr_t *rr = list_get_instance(link, dns_rr_t, msg);
    92 
     103               
    93104                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) {
     105                    rr->name, rr->rtype, rr->rclass, rr->rdata_size);
     106               
     107                if ((rr->rtype == DTYPE_CNAME) && (rr->rclass == DC_IN) &&
     108                    (str_cmp(rr->name, sname) == 0)) {
     109                       
    98110                        log_msg(LOG_DEFAULT, LVL_DEBUG, "decode cname (%p, %zu, %zu)",
    99111                            amsg->pdu.data, amsg->pdu.size, rr->roff);
     112                       
     113                        char *cname;
     114                        size_t eoff;
    100115                        rc = dns_name_decode(&amsg->pdu, rr->roff, &cname, &eoff);
    101116                        if (rc != EOK) {
    102                                 log_msg(LOG_DEFAULT, LVL_DEBUG,
    103                                     "error decoding cname");
    104                                 assert(rc == EINVAL || rc == ENOMEM);
     117                                assert((rc == EINVAL) || (rc == ENOMEM));
     118                               
     119                                log_msg(LOG_DEFAULT, LVL_DEBUG, "error decoding cname");
     120                               
    105121                                dns_message_destroy(msg);
    106122                                dns_message_destroy(amsg);
     123                                free(sname);
     124                               
    107125                                return rc;
    108126                        }
    109 
     127                       
    110128                        log_msg(LOG_DEFAULT, LVL_DEBUG, "name = '%s' "
    111129                            "cname = '%s'", sname, cname);
    112 
     130                       
     131                        /* Continue looking for the more canonical name */
    113132                        free(sname);
    114                         /* Continue looking for the more canonical name */
    115133                        sname = cname;
    116134                }
    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) {
     135               
     136                if ((qtype == DTYPE_A) && (rr->rtype == DTYPE_A) &&
     137                    (rr->rclass == DC_IN) && (rr->rdata_size == sizeof(addr32_t)) &&
     138                    (str_cmp(rr->name, sname) == 0)) {
     139                       
     140                        info->cname = str_dup(rr->name);
     141                        if (info->cname == NULL) {
    124142                                dns_message_destroy(msg);
    125143                                dns_message_destroy(amsg);
     144                                free(sname);
     145                               
    126146                                return ENOMEM;
    127147                        }
    128 
    129                         info->cname = str_dup(rr->name);
     148                       
    130149                        inet_addr_set(dns_uint32_t_decode(rr->rdata, rr->rdata_size),
    131150                            &info->addr);
     
    133152                        dns_message_destroy(msg);
    134153                        dns_message_destroy(amsg);
    135                         *rinfo = info;
     154                        free(sname);
     155                       
    136156                        return EOK;
    137157                }
    138         }
    139 
     158               
     159                if ((qtype == DTYPE_AAAA) && (rr->rtype == DTYPE_AAAA) &&
     160                    (rr->rclass == DC_IN) && (rr->rdata_size == sizeof(addr128_t)) &&
     161                    (str_cmp(rr->name, sname) == 0)) {
     162               
     163                        info->cname = str_dup(rr->name);
     164                        if (info->cname == NULL) {
     165                                dns_message_destroy(msg);
     166                                dns_message_destroy(amsg);
     167                                free(sname);
     168                               
     169                                return ENOMEM;
     170                        }
     171                       
     172                        addr128_t addr;
     173                        dns_addr128_t_decode(rr->rdata, rr->rdata_size, addr);
     174                       
     175                        inet_addr_set6(addr, &info->addr);
     176                       
     177                        dns_message_destroy(msg);
     178                        dns_message_destroy(amsg);
     179                        free(sname);
     180                       
     181                        return EOK;
     182                }
     183        }
     184       
     185        log_msg(LOG_DEFAULT, LVL_DEBUG, "'%s' not resolved, fail", sname);
     186       
    140187        dns_message_destroy(msg);
    141188        dns_message_destroy(amsg);
    142         log_msg(LOG_DEFAULT, LVL_DEBUG, "'%s' not resolved, fail", sname);
    143 
     189        free(sname);
     190       
    144191        return EIO;
     192}
     193
     194int dns_name2host(const char *name, dns_host_info_t **rinfo, uint16_t af)
     195{
     196        dns_host_info_t *info = calloc(1, sizeof(dns_host_info_t));
     197        if (info == NULL)
     198                return ENOMEM;
     199       
     200        int rc;
     201       
     202        switch (af) {
     203        case AF_NONE:
     204                rc = dns_name_query(name, DTYPE_AAAA, info);
     205               
     206                if (rc != EOK)
     207                        rc = dns_name_query(name, DTYPE_A, info);
     208               
     209                break;
     210        case AF_INET:
     211                rc = dns_name_query(name, DTYPE_A, info);
     212                break;
     213        case AF_INET6:
     214                rc = dns_name_query(name, DTYPE_AAAA, info);
     215                break;
     216        default:
     217                rc = EINVAL;
     218        }
     219       
     220        if (rc == EOK)
     221                *rinfo = info;
     222        else
     223                free(info);
     224       
     225        return rc;
    145226}
    146227
Note: See TracChangeset for help on using the changeset viewer.