Ignore:
File:
1 edited

Legend:

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

    r5a324d99 r959d2ec  
    3939#include <stdlib.h>
    4040#include <str.h>
     41
    4142#include "dns_msg.h"
    4243#include "dns_std.h"
     
    4748static uint16_t msg_id;
    4849
    49 static int dns_name_query(const char *name, dns_qtype_t qtype,
    50     dns_host_info_t *info)
     50int dns_name2host(const char *name, dns_host_info_t **rinfo)
    5151{
    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)
    5562                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)
    6070                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
    8274        msg->id = msg_id++;
    8375        msg->qr = QR_QUERY;
     
    8779        msg->rd = true;
    8880        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);
    9483        if (rc != EOK) {
    95                 dns_message_destroy(msg);
    96                 free(sname);
    9784                return rc;
    9885        }
    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
    10193                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) {
    10798                        log_msg(LOG_DEFAULT, LVL_DEBUG, "decode cname (%p, %zu, %zu)",
    10899                            amsg->pdu.data, amsg->pdu.size, rr->roff);
    109                        
    110                         char *cname;
    111                         size_t eoff;
    112100                        rc = dns_name_decode(&amsg->pdu, rr->roff, &cname, &eoff);
    113101                        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);
    118105                                dns_message_destroy(msg);
    119106                                dns_message_destroy(amsg);
    120                                 free(sname);
    121                                
    122107                                return rc;
    123108                        }
    124                        
     109
    125110                        log_msg(LOG_DEFAULT, LVL_DEBUG, "name = '%s' "
    126111                            "cname = '%s'", sname, cname);
    127                        
     112
     113                        free(sname);
    128114                        /* Continue looking for the more canonical name */
    129                         free(sname);
    130115                        sname = cname;
    131116                }
    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) {
    139124                                dns_message_destroy(msg);
    140125                                dns_message_destroy(amsg);
    141                                 free(sname);
    142                                
    143126                                return ENOMEM;
    144127                        }
    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
    149134                        dns_message_destroy(msg);
    150135                        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;
    178137                        return EOK;
    179138                }
    180139        }
    181        
    182         log_msg(LOG_DEFAULT, LVL_DEBUG, "'%s' not resolved, fail", sname);
    183        
     140
    184141        dns_message_destroy(msg);
    185142        dns_message_destroy(amsg);
    186         free(sname);
    187        
     143        log_msg(LOG_DEFAULT, LVL_DEBUG, "'%s' not resolved, fail", sname);
     144
    188145        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         else
    220                 free(info);
    221        
    222         return rc;
    223146}
    224147
Note: See TracChangeset for help on using the changeset viewer.