Ignore:
File:
1 edited

Legend:

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

    r0aa70f4 r02a09ed  
    3939#include <stdlib.h>
    4040#include <str.h>
    41 #include <net/socket_codes.h>
     41
    4242#include "dns_msg.h"
    4343#include "dns_std.h"
     
    4848static uint16_t msg_id;
    4949
    50 static int dns_name_query(const char *name, dns_qtype_t qtype,
    51     dns_host_info_t *info)
     50int dns_name2host(const char *name, dns_host_info_t **rinfo)
    5251{
    53         /* Start with the caller-provided name */
    54         char *sname = str_dup(name);
    55         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)
    5662                return ENOMEM;
    57        
    58         char *qname = str_dup(name);
    59         if (qname == NULL) {
    60                 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)
    6170                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;
    73         question->qclass = DC_IN;
    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        
     71
     72        list_append(&question->msg, &msg->question);
     73
    8374        msg->id = msg_id++;
    8475        msg->qr = QR_QUERY;
     
    8879        msg->rd = true;
    8980        msg->ra = false;
    90        
    91         list_append(&question->msg, &msg->question);
    92        
    93         dns_message_t *amsg;
    94         int rc = dns_request(msg, &amsg);
     81
     82        rc = dns_request(msg, &amsg);
    9583        if (rc != EOK) {
    96                 dns_message_destroy(msg);
    97                 free(sname);
    9884                return rc;
    9985        }
    100        
     86
     87        /* Start with the caller-provided name */
     88        sname = str_dup(name);
     89
    10190        list_foreach(amsg->answer, link) {
    10291                dns_rr_t *rr = list_get_instance(link, dns_rr_t, msg);
    103                
     92
    10493                log_msg(LOG_DEFAULT, LVL_DEBUG, " - '%s' %u/%u, dsize %zu",
    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                        
     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) {
    11098                        log_msg(LOG_DEFAULT, LVL_DEBUG, "decode cname (%p, %zu, %zu)",
    11199                            amsg->pdu.data, amsg->pdu.size, rr->roff);
    112                        
    113                         char *cname;
    114                         size_t eoff;
    115100                        rc = dns_name_decode(&amsg->pdu, rr->roff, &cname, &eoff);
    116101                        if (rc != EOK) {
    117                                 assert((rc == EINVAL) || (rc == ENOMEM));
    118                                
    119                                 log_msg(LOG_DEFAULT, LVL_DEBUG, "error decoding cname");
    120                                
     102                                log_msg(LOG_DEFAULT, LVL_DEBUG,
     103                                    "error decoding cname");
     104                                assert(rc == EINVAL || rc == ENOMEM);
    121105                                dns_message_destroy(msg);
    122106                                dns_message_destroy(amsg);
    123                                 free(sname);
    124                                
    125107                                return rc;
    126108                        }
    127                        
     109
    128110                        log_msg(LOG_DEFAULT, LVL_DEBUG, "name = '%s' "
    129111                            "cname = '%s'", sname, cname);
    130                        
     112
     113                        free(sname);
    131114                        /* Continue looking for the more canonical name */
    132                         free(sname);
    133115                        sname = cname;
    134116                }
    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) {
     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) {
    142124                                dns_message_destroy(msg);
    143125                                dns_message_destroy(amsg);
    144                                 free(sname);
    145                                
    146126                                return ENOMEM;
    147127                        }
    148                        
     128
     129                        info->cname = str_dup(rr->name);
    149130                        inet_addr_set(dns_uint32_t_decode(rr->rdata, rr->rdata_size),
    150131                            &info->addr);
     
    152133                        dns_message_destroy(msg);
    153134                        dns_message_destroy(amsg);
    154                         free(sname);
    155                        
    156                         return EOK;
    157                 }
    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                        
     135                        *rinfo = info;
    181136                        return EOK;
    182137                }
    183138        }
    184        
    185         log_msg(LOG_DEFAULT, LVL_DEBUG, "'%s' not resolved, fail", sname);
    186        
     139
    187140        dns_message_destroy(msg);
    188141        dns_message_destroy(amsg);
    189         free(sname);
    190        
     142        log_msg(LOG_DEFAULT, LVL_DEBUG, "'%s' not resolved, fail", sname);
     143
    191144        return EIO;
    192 }
    193 
    194 int 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;
    226145}
    227146
Note: See TracChangeset for help on using the changeset viewer.