Changeset 0aa70f4 in mainline


Ignore:
Timestamp:
2013-07-19T13:23:00Z (11 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
cd18cd1
Parents:
44c9ef4
Message:

support for IPv6 DNS name resolution (AAAA)
if the desired address family of the DNS query is not explicitly specified, then IPv6 addresses take precendece over IPv4 addresses

Location:
uspace
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/dnsres/dnsres.c

    r44c9ef4 r0aa70f4  
    6060        hname = argv[1];
    6161
    62         rc = dnsr_name2host(hname, &hinfo);
     62        rc = dnsr_name2host(hname, &hinfo, 0);
    6363        if (rc != EOK) {
    6464                printf(NAME ": Error resolving '%s'.\n", argv[1]);
  • uspace/app/nettest1/nettest1.c

    r44c9ef4 r0aa70f4  
    335335                /* Interpret as a host name */
    336336                dnsr_hostinfo_t *hinfo = NULL;
    337                 rc = dnsr_name2host(addr_s, &hinfo);
     337                rc = dnsr_name2host(addr_s, &hinfo, family);
    338338               
    339339                if (rc != EOK) {
  • uspace/app/nettest2/nettest2.c

    r44c9ef4 r0aa70f4  
    271271                /* Interpret as a host name */
    272272                dnsr_hostinfo_t *hinfo = NULL;
    273                 rc = dnsr_name2host(addr_s, &hinfo);
     273                rc = dnsr_name2host(addr_s, &hinfo, family);
    274274               
    275275                if (rc != EOK) {
  • uspace/app/nettest3/nettest3.c

    r44c9ef4 r0aa70f4  
    7878                if (rc != EOK) {
    7979                        /* Try interpreting as a host name */
    80                         rc = dnsr_name2host(argv[1], &hinfo);
     80                        rc = dnsr_name2host(argv[1], &hinfo, AF_INET);
    8181                        if (rc != EOK) {
    8282                                printf("Error resolving host '%s'.\n", argv[1]);
  • uspace/app/nterm/conn.c

    r44c9ef4 r0aa70f4  
    8484                /* Interpret as a host name */
    8585                dnsr_hostinfo_t *hinfo = NULL;
    86                 rc = dnsr_name2host(addr_s, &hinfo);
     86                rc = dnsr_name2host(addr_s, &hinfo, 0);
    8787               
    8888                if (rc != EOK) {
  • uspace/app/ping/ping.c

    r44c9ef4 r0aa70f4  
    212212        if (rc != EOK) {
    213213                /* Try interpreting as a host name */
    214                 rc = dnsr_name2host(argv[argi], &hinfo);
     214                rc = dnsr_name2host(argv[argi], &hinfo, AF_INET);
    215215                if (rc != EOK) {
    216216                        printf(NAME ": Error resolving host '%s'.\n", argv[argi]);
  • uspace/app/ping6/ping6.c

    r44c9ef4 r0aa70f4  
    212212        if (rc != EOK) {
    213213                /* Try interpreting as a host name */
    214                 rc = dnsr_name2host(argv[argi], &hinfo);
     214                rc = dnsr_name2host(argv[argi], &hinfo, AF_INET6);
    215215                if (rc != EOK) {
    216216                        printf(NAME ": Error resolving host '%s'.\n", argv[argi]);
  • uspace/lib/c/generic/dnsr.c

    r44c9ef4 r0aa70f4  
    6767}
    6868
    69 int dnsr_name2host(const char *name, dnsr_hostinfo_t **rinfo)
     69int dnsr_name2host(const char *name, dnsr_hostinfo_t **rinfo, uint16_t af)
    7070{
    7171        dnsr_hostinfo_t *info = calloc(1, sizeof(dnsr_hostinfo_t));
     
    7676       
    7777        ipc_call_t answer;
    78         aid_t req = async_send_0(exch, DNSR_NAME2HOST, &answer);
     78        aid_t req = async_send_1(exch, DNSR_NAME2HOST, (sysarg_t) af,
     79            &answer);
    7980       
    8081        int rc = async_data_write_start(exch, name, str_size(name));
  • uspace/lib/c/include/inet/dnsr.h

    r44c9ef4 r0aa70f4  
    5151
    5252extern int dnsr_init(void);
    53 extern int dnsr_name2host(const char *, dnsr_hostinfo_t **);
     53extern int dnsr_name2host(const char *, dnsr_hostinfo_t **, uint16_t);
    5454extern void dnsr_hostinfo_destroy(dnsr_hostinfo_t *);
    5555extern int dnsr_get_srvaddr(inet_addr_t *);
  • uspace/srv/net/dnsrsrv/dns_msg.c

    r44c9ef4 r0aa70f4  
    296296uint32_t dns_uint32_t_decode(uint8_t *buf, size_t buf_size)
    297297{
    298         uint32_t w;
    299298        assert(buf_size >= 4);
    300 
    301         w = ((uint32_t) buf[0] << 24) +
     299       
     300        uint32_t w = ((uint32_t) buf[0] << 24) +
    302301            ((uint32_t) buf[1] << 16) +
    303302            ((uint32_t) buf[2] << 8) +
    304303            buf[3];
    305 
     304       
    306305        return w;
     306}
     307
     308/** Decode unaligned big-endian 128-bit integer */
     309void dns_addr128_t_decode(uint8_t *buf, size_t buf_size, addr128_t addr)
     310{
     311        assert(buf_size >= 16);
     312       
     313        addr128_t_be2host(buf, addr);
    307314}
    308315
     
    400407        int rc;
    401408
    402         rr = calloc(1, sizeof (dns_rr_t));
     409        rr = calloc(1, sizeof(dns_rr_t));
    403410        if (rr == NULL)
    404411                return ENOMEM;
     
    427434
    428435        rr->rtype = dns_uint16_t_decode(bp, bsz);
    429         bp += sizeof(uint16_t); bsz -= sizeof(uint16_t);
     436        bp += sizeof(uint16_t);
     437        bsz -= sizeof(uint16_t);
    430438
    431439        rr->rclass = dns_uint16_t_decode(bp, bsz);
    432         bp += sizeof(uint16_t); bsz -= sizeof(uint16_t);
     440        bp += sizeof(uint16_t);
     441        bsz -= sizeof(uint16_t);
    433442
    434443        rr->ttl = dns_uint32_t_decode(bp, bsz);
    435         bp += sizeof(uint32_t); bsz -= sizeof(uint32_t);
     444        bp += sizeof(uint32_t);
     445        bsz -= sizeof(uint32_t);
    436446
    437447        rdlength = dns_uint16_t_decode(bp, bsz);
    438         bp += sizeof(uint16_t); bsz -= sizeof(uint16_t);
     448        bp += sizeof(uint16_t);
     449        bsz -= sizeof(uint16_t);
    439450
    440451        if (rdlength > bsz) {
  • uspace/srv/net/dnsrsrv/dns_msg.h

    r44c9ef4 r0aa70f4  
    4040#include <stdbool.h>
    4141#include <stdint.h>
     42#include <inet/addr.h>
    4243#include "dns_std.h"
    4344#include "dns_type.h"
     
    4950extern int dns_name_decode(dns_pdu_t *, size_t, char **, size_t *);
    5051extern uint32_t dns_uint32_t_decode(uint8_t *, size_t);
     52extern void dns_addr128_t_decode(uint8_t *, size_t, addr128_t);
     53
    5154
    5255#endif
  • uspace/srv/net/dnsrsrv/dnsrsrv.c

    r44c9ef4 r0aa70f4  
    8989        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srvaddr_srv()");
    9090       
     91        uint16_t af = IPC_GET_ARG1(*icall);
     92       
    9193        char *name;
    9294        int rc = async_data_write_accept((void **) &name, true, 0,
     
    98100       
    99101        dns_host_info_t *hinfo;
    100         rc = dns_name2host(name, &hinfo);
     102        rc = dns_name2host(name, &hinfo, af);
    101103        if (rc != EOK) {
    102104                async_answer_0(iid, rc);
  • uspace/srv/net/dnsrsrv/query.c

    r44c9ef4 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
  • uspace/srv/net/dnsrsrv/query.h

    r44c9ef4 r0aa70f4  
    3939#include "dns_type.h"
    4040
    41 extern int dns_name2host(const char *, dns_host_info_t **);
     41extern int dns_name2host(const char *, dns_host_info_t **, uint16_t);
    4242extern void dns_hostinfo_destroy(dns_host_info_t *);
    4343
Note: See TracChangeset for help on using the changeset viewer.