quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

dns-proto.h (12238B)


      1 /* MIT License
      2  *
      3  * Copyright (c) The c-ares project and its contributors
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a copy
      6  * of this software and associated documentation files (the "Software"), to deal
      7  * in the Software without restriction, including without limitation the rights
      8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      9  * copies of the Software, and to permit persons to whom the Software is
     10  * furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice (including the next
     13  * paragraph) shall be included in all copies or substantial portions of the
     14  * Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22  * SOFTWARE.
     23  *
     24  * SPDX-License-Identifier: MIT
     25  */
     26 #ifndef DNS_PROTO_H
     27 #define DNS_PROTO_H
     28 // Utilities for processing DNS packet contents
     29 
     30 #include "ares_setup.h"
     31 #include "ares.h"
     32 // Include ares internal file for DNS protocol constants
     33 #include "ares_nameser.h"
     34 
     35 #include <memory>
     36 #include <string>
     37 #include <vector>
     38 
     39 extern "C" void arestest_strtolower(char *dest, const char *src,
     40                                     size_t dest_size);
     41 
     42 namespace ares {
     43 
     44 typedef unsigned char byte;
     45 
     46 std::string           HexDump(std::vector<byte> data);
     47 std::string           HexDump(const byte *data, int len);
     48 std::string           HexDump(const char *data, int len);
     49 
     50 std::string           StatusToString(int status);
     51 std::string           RcodeToString(int rcode);
     52 std::string           RRTypeToString(int rrtype);
     53 std::string           ClassToString(int qclass);
     54 std::string           AddressToString(const void *addr, int len);
     55 
     56 const ares_dns_rr_t  *fetch_rr_opt(const ares_dns_record_t *rec);
     57 
     58 // Convert DNS protocol data to strings.
     59 // Note that these functions are not defensive; they assume
     60 // a validly formatted input, and so should not be used on
     61 // externally-determined inputs.
     62 std::string           PacketToString(const std::vector<byte> &packet);
     63 std::string QuestionToString(const std::vector<byte> &packet, const byte **data,
     64                              int *len);
     65 std::string RRToString(const std::vector<byte> &packet, const byte **data,
     66                        int *len);
     67 
     68 
     69 // Manipulate DNS protocol data.
     70 void        PushInt32(std::vector<byte> *data, int value);
     71 void        PushInt16(std::vector<byte> *data, int value);
     72 std::vector<byte> EncodeString(const std::string &name);
     73 
     74 struct DNSQuestion {
     75   DNSQuestion(const std::string &name, int rrtype, int qclass)
     76     : name_(name), rrtype_(rrtype), qclass_(qclass)
     77   {
     78   }
     79 
     80   DNSQuestion(const std::string &name, int rrtype)
     81     : name_(name), rrtype_(rrtype), qclass_(C_IN)
     82   {
     83   }
     84 
     85   virtual ~DNSQuestion()
     86   {
     87   }
     88 
     89   virtual std::vector<byte> data(const char              *request_name,
     90                                  const ares_dns_record_t *dnsrec) const;
     91 
     92   virtual std::vector<byte> data(const ares_dns_record_t *dnsrec) const
     93   {
     94     return data(nullptr, dnsrec);
     95   }
     96 
     97   virtual std::vector<byte> data() const
     98   {
     99     return data(nullptr, nullptr);
    100   }
    101 
    102   std::string name_;
    103   int         rrtype_;
    104   int         qclass_;
    105 };
    106 
    107 struct DNSRR : public DNSQuestion {
    108   DNSRR(const std::string &name, int rrtype, int qclass, int ttl)
    109     : DNSQuestion(name, rrtype, qclass), ttl_(ttl)
    110   {
    111   }
    112 
    113   DNSRR(const std::string &name, int rrtype, int ttl)
    114     : DNSQuestion(name, rrtype), ttl_(ttl)
    115   {
    116   }
    117 
    118   virtual ~DNSRR()
    119   {
    120   }
    121 
    122   virtual std::vector<byte> data(const ares_dns_record_t *dnsrec) const = 0;
    123   int                       ttl_;
    124 };
    125 
    126 struct DNSAddressRR : public DNSRR {
    127   DNSAddressRR(const std::string &name, int rrtype, int ttl, const byte *addr,
    128                int addrlen)
    129     : DNSRR(name, rrtype, ttl), addr_(addr, addr + addrlen)
    130   {
    131   }
    132 
    133   DNSAddressRR(const std::string &name, int rrtype, int ttl,
    134                const std::vector<byte> &addr)
    135     : DNSRR(name, rrtype, ttl), addr_(addr)
    136   {
    137   }
    138 
    139   virtual std::vector<byte> data(const ares_dns_record_t *dnsrec) const;
    140   std::vector<byte>         addr_;
    141 };
    142 
    143 struct DNSARR : public DNSAddressRR {
    144   DNSARR(const std::string &name, int ttl, const byte *addr, int addrlen)
    145     : DNSAddressRR(name, T_A, ttl, addr, addrlen)
    146   {
    147   }
    148 
    149   DNSARR(const std::string &name, int ttl, const std::vector<byte> &addr)
    150     : DNSAddressRR(name, T_A, ttl, addr)
    151   {
    152   }
    153 };
    154 
    155 struct DNSAaaaRR : public DNSAddressRR {
    156   DNSAaaaRR(const std::string &name, int ttl, const byte *addr, int addrlen)
    157     : DNSAddressRR(name, T_AAAA, ttl, addr, addrlen)
    158   {
    159   }
    160 
    161   DNSAaaaRR(const std::string &name, int ttl, const std::vector<byte> &addr)
    162     : DNSAddressRR(name, T_AAAA, ttl, addr)
    163   {
    164   }
    165 };
    166 
    167 struct DNSSingleNameRR : public DNSRR {
    168   DNSSingleNameRR(const std::string &name, int rrtype, int ttl,
    169                   const std::string &other)
    170     : DNSRR(name, rrtype, ttl), other_(other)
    171   {
    172   }
    173 
    174   virtual std::vector<byte> data(const ares_dns_record_t *dnsrec) const;
    175   std::string               other_;
    176 };
    177 
    178 struct DNSCnameRR : public DNSSingleNameRR {
    179   DNSCnameRR(const std::string &name, int ttl, const std::string &other)
    180     : DNSSingleNameRR(name, T_CNAME, ttl, other)
    181   {
    182   }
    183 };
    184 
    185 struct DNSNsRR : public DNSSingleNameRR {
    186   DNSNsRR(const std::string &name, int ttl, const std::string &other)
    187     : DNSSingleNameRR(name, T_NS, ttl, other)
    188   {
    189   }
    190 };
    191 
    192 struct DNSPtrRR : public DNSSingleNameRR {
    193   DNSPtrRR(const std::string &name, int ttl, const std::string &other)
    194     : DNSSingleNameRR(name, T_PTR, ttl, other)
    195   {
    196   }
    197 };
    198 
    199 struct DNSTxtRR : public DNSRR {
    200   DNSTxtRR(const std::string &name, int ttl,
    201            const std::vector<std::string> &txt)
    202     : DNSRR(name, T_TXT, ttl), txt_(txt)
    203   {
    204   }
    205 
    206   virtual std::vector<byte> data(const ares_dns_record_t *dnsrec) const;
    207   std::vector<std::string>  txt_;
    208 };
    209 
    210 struct DNSMxRR : public DNSRR {
    211   DNSMxRR(const std::string &name, int ttl, int pref, const std::string &other)
    212     : DNSRR(name, T_MX, ttl), pref_(pref), other_(other)
    213   {
    214   }
    215 
    216   virtual std::vector<byte> data(const ares_dns_record_t *dnsrec) const;
    217   int                       pref_;
    218   std::string               other_;
    219 };
    220 
    221 struct DNSSrvRR : public DNSRR {
    222   DNSSrvRR(const std::string &name, int ttl, int prio, int weight, int port,
    223            const std::string &target)
    224     : DNSRR(name, T_SRV, ttl), prio_(prio), weight_(weight), port_(port),
    225       target_(target)
    226   {
    227   }
    228 
    229   virtual std::vector<byte> data(const ares_dns_record_t *dnsrec) const;
    230   int                       prio_;
    231   int                       weight_;
    232   int                       port_;
    233   std::string               target_;
    234 };
    235 
    236 struct DNSUriRR : public DNSRR {
    237   DNSUriRR(const std::string &name, int ttl, int prio, int weight,
    238            const std::string &target)
    239     : DNSRR(name, T_URI, ttl), prio_(prio), weight_(weight), target_(target)
    240   {
    241   }
    242 
    243   virtual std::vector<byte> data(const ares_dns_record_t *dnsrec) const;
    244   int                       prio_;
    245   int                       weight_;
    246   std::string               target_;
    247 };
    248 
    249 struct DNSSoaRR : public DNSRR {
    250   DNSSoaRR(const std::string &name, int ttl, const std::string &nsname,
    251            const std::string &rname, int serial, int refresh, int retry,
    252            int expire, int minimum)
    253     : DNSRR(name, T_SOA, ttl), nsname_(nsname), rname_(rname), serial_(serial),
    254       refresh_(refresh), retry_(retry), expire_(expire), minimum_(minimum)
    255   {
    256   }
    257 
    258   virtual std::vector<byte> data(const ares_dns_record_t *dnsrec) const;
    259   std::string               nsname_;
    260   std::string               rname_;
    261   int                       serial_;
    262   int                       refresh_;
    263   int                       retry_;
    264   int                       expire_;
    265   int                       minimum_;
    266 };
    267 
    268 struct DNSNaptrRR : public DNSRR {
    269   DNSNaptrRR(const std::string &name, int ttl, int order, int pref,
    270              const std::string &flags, const std::string &service,
    271              const std::string &regexp, const std::string &replacement)
    272     : DNSRR(name, T_NAPTR, ttl), order_(order), pref_(pref), flags_(flags),
    273       service_(service), regexp_(regexp), replacement_(replacement)
    274   {
    275   }
    276 
    277   virtual std::vector<byte> data(const ares_dns_record_t *dnsrec) const;
    278   int                       order_;
    279   int                       pref_;
    280   std::string               flags_;
    281   std::string               service_;
    282   std::string               regexp_;
    283   std::string               replacement_;
    284 };
    285 
    286 struct DNSOption {
    287   int               code_;
    288   std::vector<byte> data_;
    289 };
    290 
    291 struct DNSOptRR : public DNSRR {
    292   DNSOptRR(unsigned char extrcode, unsigned char version, unsigned short flags,
    293            int udpsize, std::vector<byte> client_cookie,
    294            std::vector<byte> server_cookie, bool expect_server_cookie)
    295     : DNSRR("", T_OPT, static_cast<int>(udpsize),
    296             ((int)extrcode) << 24 | ((int)version) << 16 |
    297               ((int)flags) /* ttl */)
    298   {
    299     client_cookie_        = client_cookie;
    300     server_cookie_        = server_cookie;
    301     expect_server_cookie_ = expect_server_cookie;
    302   }
    303 
    304   virtual std::vector<byte> data(const ares_dns_record_t *dnsrec) const;
    305   std::vector<DNSOption>    opts_;
    306   std::vector<byte>         client_cookie_;
    307   std::vector<byte>         server_cookie_;
    308   bool                      expect_server_cookie_;
    309 };
    310 
    311 struct DNSPacket {
    312   DNSPacket()
    313     : qid_(0), response_(false), opcode_(O_QUERY), aa_(false), tc_(false),
    314       rd_(false), ra_(false), z_(false), ad_(false), cd_(false), rcode_(NOERROR)
    315   {
    316   }
    317 
    318   // Convenience functions that take ownership of given pointers.
    319   DNSPacket &add_question(DNSQuestion *q)
    320   {
    321     questions_.push_back(std::unique_ptr<DNSQuestion>(q));
    322     return *this;
    323   }
    324 
    325   DNSPacket &add_answer(DNSRR *q)
    326   {
    327     answers_.push_back(std::unique_ptr<DNSRR>(q));
    328     return *this;
    329   }
    330 
    331   DNSPacket &add_auth(DNSRR *q)
    332   {
    333     auths_.push_back(std::unique_ptr<DNSRR>(q));
    334     return *this;
    335   }
    336 
    337   DNSPacket &add_additional(DNSRR *q)
    338   {
    339     adds_.push_back(std::unique_ptr<DNSRR>(q));
    340     return *this;
    341   }
    342 
    343   // Chainable setters.
    344   DNSPacket &set_qid(int qid)
    345   {
    346     qid_ = qid;
    347     return *this;
    348   }
    349 
    350   DNSPacket &set_response(bool v = true)
    351   {
    352     response_ = v;
    353     return *this;
    354   }
    355 
    356   DNSPacket &set_aa(bool v = true)
    357   {
    358     aa_ = v;
    359     return *this;
    360   }
    361 
    362   DNSPacket &set_tc(bool v = true)
    363   {
    364     tc_ = v;
    365     return *this;
    366   }
    367 
    368   DNSPacket &set_rd(bool v = true)
    369   {
    370     rd_ = v;
    371     return *this;
    372   }
    373 
    374   DNSPacket &set_ra(bool v = true)
    375   {
    376     ra_ = v;
    377     return *this;
    378   }
    379 
    380   DNSPacket &set_z(bool v = true)
    381   {
    382     z_ = v;
    383     return *this;
    384   }
    385 
    386   DNSPacket &set_ad(bool v = true)
    387   {
    388     ad_ = v;
    389     return *this;
    390   }
    391 
    392   DNSPacket &set_cd(bool v = true)
    393   {
    394     cd_ = v;
    395     return *this;
    396   }
    397 
    398   DNSPacket &set_rcode(int rcode)
    399   {
    400     rcode_ = rcode;
    401     return *this;
    402   }
    403 
    404   // Return the encoded packet.
    405   std::vector<byte> data(const char              *request_name,
    406                          const ares_dns_record_t *dnsrec) const;
    407 
    408   std::vector<byte> data() const
    409   {
    410     return data(nullptr, nullptr);
    411   }
    412 
    413   int                                       qid_;
    414   bool                                      response_;
    415   int                                       opcode_;
    416   bool                                      aa_;
    417   bool                                      tc_;
    418   bool                                      rd_;
    419   bool                                      ra_;
    420   bool                                      z_;
    421   bool                                      ad_;
    422   bool                                      cd_;
    423   int                                       rcode_;
    424   std::vector<std::unique_ptr<DNSQuestion>> questions_;
    425   std::vector<std::unique_ptr<DNSRR>>       answers_;
    426   std::vector<std::unique_ptr<DNSRR>>       auths_;
    427   std::vector<std::unique_ptr<DNSRR>>       adds_;
    428 };
    429 
    430 }  // namespace ares
    431 
    432 #endif