"Fossies" - the Fresh Open Source Software Archive

Member "knot-2.8.3/tests/libknot/test_edns.c" (16 Jul 2019, 16462 Bytes) of package /linux/misc/dns/knot-2.8.3.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "test_edns.c": 2.7.6_vs_2.8.0.

    1 /*  Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
    2 
    3     This program is free software: you can redistribute it and/or modify
    4     it under the terms of the GNU General Public License as published by
    5     the Free Software Foundation, either version 3 of the License, or
    6     (at your option) any later version.
    7 
    8     This program is distributed in the hope that it will be useful,
    9     but WITHOUT ANY WARRANTY; without even the implied warranty of
   10     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11     GNU General Public License for more details.
   12 
   13     You should have received a copy of the GNU General Public License
   14     along with this program.  If not, see <https://www.gnu.org/licenses/>.
   15  */
   16 
   17 #include <tap/basic.h>
   18 
   19 #include <assert.h>
   20 #include "libknot/libknot.h"
   21 #include "libknot/rrtype/opt.h"
   22 #include "libknot/descriptor.h"
   23 #include "libknot/wire.h"
   24 #include "contrib/sockaddr.h"
   25 
   26 static const uint16_t E_MAX_PLD = 10000;
   27 static const uint16_t E_MAX_PLD2 = 20000;
   28 static const uint8_t E_VERSION = 1;
   29 static const uint8_t E_VERSION2 = 2;
   30 static const uint8_t E_RCODE = 0;
   31 static const uint8_t E_RCODE2 = 200;
   32 
   33 static const char *E_NSID_STR = "FooBar";
   34 static const uint16_t E_NSID_LEN = 6;
   35 
   36 #define E_NSID_SIZE (4 + E_NSID_LEN)
   37 
   38 static const uint16_t E_OPT3_CODE = 15;
   39 static const char *E_OPT3_FAKE_DATA = "Not used";
   40 static const char *E_OPT3_DATA = NULL;
   41 static const uint16_t E_OPT3_LEN = 0;
   42 static const uint16_t E_OPT3_FAKE_LEN = 8;
   43 
   44 #define E_OPT3_SIZE (4 + E_OPT3_LEN)
   45 
   46 static const uint16_t E_OPT4_CODE = 30;
   47 static const char *E_OPT4_DATA = NULL;
   48 static const uint16_t E_OPT4_LEN = 0;
   49 
   50 #define E_OPT4_SIZE (4 + E_OPT4_LEN)
   51 
   52 enum offsets {
   53     /*! \brief Offset of Extended RCODE in wire order of TTL. */
   54     OFFSET_ERCODE = 0,
   55     /*! \brief Offset of Version in wire order of TTL. */
   56     OFFSET_VER = 1,
   57     /*! \brief Offset of Flags in wire order of TTL. */
   58     OFFSET_FLAGS = 2,
   59     /*! \brief Offset of OPTION code in one OPTION in RDATA. */
   60     OFFSET_OPT_CODE = 0,
   61     /*! \brief Offset of OPTION size in one OPTION in RDATA. */
   62     OFFSET_OPT_SIZE = 2,
   63     /*! \brief Offset of OPTION data in one OPTION in RDATA. */
   64     OFFSET_OPT_DATA = 4
   65 };
   66 
   67 static const uint16_t DO_FLAG = (uint16_t)1 << 15;
   68 
   69 static void check_ttl(knot_rrset_t *rrset, uint8_t ext_rcode, uint8_t ver,
   70                       uint16_t flags, char *msg)
   71 {
   72     if (rrset == NULL) {
   73         return;
   74     }
   75 
   76     /* TTL should be stored in machine byte order.
   77        We need network byte order to compare its parts. */
   78     uint8_t ttl_wire[4] = { 0, 0, 0, 0 };
   79     knot_wire_write_u32(ttl_wire, rrset->ttl);
   80 
   81     /* Convert Flags from EDNS parameters to wire format for comparison. */
   82     uint8_t flags_wire[2] = { 0, 0 };
   83     knot_wire_write_u16(flags_wire, flags);
   84 
   85     /* TTL = Ext RCODE + Version + Flags */
   86     bool check = (ttl_wire[OFFSET_ERCODE] == ext_rcode);
   87     ok(check, "%s: extended RCODE", msg);
   88 
   89     check = (ttl_wire[OFFSET_VER] == ver);
   90     ok(check, "%s: version", msg);
   91 
   92     check = (memcmp(flags_wire, ttl_wire + OFFSET_FLAGS, 2) == 0);
   93     ok(check, "%s: flags", msg);
   94 }
   95 
   96 static void check_option(knot_rdata_t *rdata, uint16_t opt_code,
   97                          uint16_t opt_len, uint8_t *opt_data, char *msg)
   98 {
   99     assert(rdata != NULL);
  100 
  101     uint8_t *data = rdata->data;
  102     uint16_t data_len = rdata->len;
  103 
  104     /* Check RDLENGTH according to given data length. */
  105     bool check = (data_len >= 4 + opt_len);
  106     ok(check, "%s: RDLENGTH (%u)", msg, data_len);
  107 
  108     /* Find the desired option. */
  109     bool found = false;
  110     int pos = 0;
  111     while (pos <= data_len - 4) {
  112         uint16_t code = knot_wire_read_u16(data + pos + OFFSET_OPT_CODE);
  113         if (code == opt_code) {
  114             found = true;
  115             break;
  116         }
  117         uint16_t len = knot_wire_read_u16(data + pos + OFFSET_OPT_SIZE);
  118         pos += 4 + len;
  119     }
  120 
  121     /* Check that the option is present. */
  122     ok(found, "%s: find OPTION %u in OPT RR", msg, opt_code);
  123 
  124     /* Check that the first OPTION's size si the size of the option data. */
  125     uint16_t opt_size = knot_wire_read_u16(data + pos + OFFSET_OPT_SIZE);
  126     check = (opt_size == opt_len);
  127     ok(check, "%s: OPTION data size", msg);
  128 
  129     /* Check the actual NSID data. */
  130     check = (opt_data == 0 || memcmp(data + pos + OFFSET_OPT_DATA, opt_data, opt_len) == 0);
  131     ok(check, "%s: OPTION data", msg);
  132 }
  133 
  134 static void check_header(knot_rrset_t *opt_rr, uint16_t payload, uint8_t ver,
  135                          uint16_t flags, uint8_t ext_rcode, char *msg)
  136 {
  137     assert(opt_rr != NULL);
  138     bool check;
  139 
  140     /* Check values in OPT RR by hand. */
  141     /* CLASS == Max UDP payload */
  142     check = (opt_rr->rclass == payload);
  143     ok(check, "%s: max payload", msg);
  144 
  145     /* The OPT RR should have exactly one RDATA. */
  146     check = (opt_rr->rrs.count == 1);
  147     ok(check, "%s: RR count == 1", msg);
  148 
  149     knot_rdata_t *rdata = opt_rr->rrs.rdata;
  150     check = (rdata != NULL);
  151     ok(check, "%s: RDATA exists", msg);
  152 
  153     check_ttl(opt_rr, ext_rcode, ver, flags, msg);
  154 }
  155 
  156 static void test_getters(knot_rrset_t *opt_rr)
  157 {
  158     assert(opt_rr != NULL);
  159 
  160     /* These values should be set from the setters test:
  161      * Max UDP payload: E_MAX_PLD2
  162      * Version:         E_VERSION2
  163      * RCODE:           E_RCODE2
  164      * Flags:           E_FLAGS | KNOT_EDNS_FLAG_DO
  165      * OPTIONs:         1) KNOT_EDNS_OPTION_NSID, E_NSID_LEN, E_NSID_STR
  166      *                  2) E_OPT3_CODE, 0, 0
  167      *                  3) E_OPT4_CODE, 0, 0
  168      */
  169 
  170     /* Payload */
  171     bool check = (knot_edns_get_payload(opt_rr) == E_MAX_PLD2);
  172     ok(check, "OPT RR getters: payload");
  173 
  174     /* Extended RCODE */
  175     check = (knot_edns_get_ext_rcode(opt_rr) == E_RCODE2);
  176     ok(check, "OPT RR getters: extended RCODE");
  177 
  178     /* Extended RCODE */
  179     check = (knot_edns_get_version(opt_rr) == E_VERSION2);
  180     ok(check, "OPT RR getters: version");
  181 
  182     /* DO bit */
  183     check = knot_edns_do(opt_rr);
  184     ok(check, "OPT RR getters: DO bit check");
  185 
  186     /* Wire size */
  187     size_t total_size = KNOT_EDNS_MIN_SIZE
  188                         + E_NSID_SIZE + E_OPT3_SIZE + E_OPT4_SIZE;
  189     size_t actual_size = knot_edns_wire_size(opt_rr);
  190     check = actual_size == total_size;
  191     ok(check, "OPT RR getters: wire size (expected: %zu, actual: %zu)",
  192        total_size, actual_size);
  193 
  194     /* NSID */
  195     check = knot_edns_get_option(opt_rr, KNOT_EDNS_OPTION_NSID) != NULL;
  196     ok(check, "OPT RR getters: NSID check");
  197 
  198     /* Other OPTIONs */
  199     check = knot_edns_get_option(opt_rr, E_OPT3_CODE) != NULL;
  200     ok(check, "OPT RR getters: empty option 1");
  201 
  202     check = knot_edns_get_option(opt_rr, E_OPT4_CODE) != NULL;
  203     ok(check, "OPT RR getters: empty option 2");
  204 
  205     uint16_t code = knot_edns_opt_get_code((const uint8_t *)"\x00\x0a" "\x00\x00");
  206     ok(code == KNOT_EDNS_OPTION_COOKIE, "OPT RR getters: EDNS OPT code");
  207 }
  208 
  209 static void test_setters(knot_rrset_t *opt_rr)
  210 {
  211     assert(opt_rr != NULL);
  212 
  213     /* Header-related setters. */
  214     knot_edns_set_payload(opt_rr, E_MAX_PLD2);
  215     knot_edns_set_ext_rcode(opt_rr, E_RCODE2);
  216     knot_edns_set_version(opt_rr, E_VERSION2);
  217     knot_edns_set_do(opt_rr);
  218 
  219     check_header(opt_rr, E_MAX_PLD2, E_VERSION2, DO_FLAG, E_RCODE2,
  220                  "OPT RR setters");
  221 
  222     /* OPTION(RDATA)-related setters. */
  223 
  224     /* Proper option. */
  225     int ret = knot_edns_add_option(opt_rr, KNOT_EDNS_OPTION_NSID,
  226                                E_NSID_LEN, (uint8_t *)E_NSID_STR, NULL);
  227     is_int(KNOT_EOK, ret, "OPT RR setters: add option with data (ret = %s)",
  228        knot_strerror(ret));
  229 
  230     /* Wrong argument: no OPT RR. */
  231     ret = knot_edns_add_option(NULL, E_OPT3_CODE, E_OPT3_FAKE_LEN,
  232                                (uint8_t *)E_OPT3_FAKE_DATA, NULL);
  233     is_int(KNOT_EINVAL, ret, "OPT RR setters: add option (rr == NULL) "
  234        "(ret = %s)", knot_strerror(ret));
  235 
  236     /* Wrong argument: option length != 0 && data == NULL. */
  237     ret = knot_edns_add_option(opt_rr, E_OPT3_CODE, E_OPT3_FAKE_LEN, NULL,
  238                                NULL);
  239     is_int(KNOT_EINVAL, ret, "OPT RR setters: add option (data == NULL, "
  240        "len != 0) (ret = %s)", knot_strerror(ret));
  241 
  242     /* Empty OPTION (length 0, data != NULL). */
  243     ret = knot_edns_add_option(opt_rr, E_OPT3_CODE, E_OPT3_LEN,
  244                                (uint8_t *)E_OPT3_FAKE_DATA, NULL);
  245     is_int(KNOT_EOK, ret, "OPT RR setters: add empty option 1 (ret = %s)",
  246        knot_strerror(ret));
  247 
  248     /* Empty OPTION (length 0, data == NULL). */
  249     ret = knot_edns_add_option(opt_rr, E_OPT4_CODE, E_OPT4_LEN,
  250                                (uint8_t *)E_OPT4_DATA, NULL);
  251     is_int(KNOT_EOK, ret, "OPT RR setters: add empty option 2 (ret = %s)",
  252        knot_strerror(ret));
  253 
  254     knot_rdata_t *rdata = opt_rr->rrs.rdata;
  255     ok(rdata != NULL, "OPT RR setters: non-empty RDATA");
  256 
  257     /* Check proper option */
  258     check_option(rdata, KNOT_EDNS_OPTION_NSID, E_NSID_LEN,
  259                  (uint8_t *)E_NSID_STR, "OPT RR setters (proper option)");
  260 
  261     /* Check empty option 1 */
  262     check_option(rdata, E_OPT3_CODE, E_OPT3_LEN,
  263                  (uint8_t *)E_OPT3_DATA, "OPT RR setters (empty option 1)");
  264 
  265     /* Check empty option 2 */
  266     check_option(rdata, E_OPT4_CODE, E_OPT4_LEN,
  267                  (uint8_t *)E_OPT4_DATA, "OPT RR setters (empty option 2)");
  268 }
  269 
  270 static void test_alignment(void)
  271 {
  272     int ret;
  273 
  274     ret = knot_edns_alignment_size(1, 1, 1);
  275     ok(ret == -1, "no alignment");
  276 
  277     ret = knot_edns_alignment_size(1, 1, 2);
  278     ok(ret == -1, "no alignment");
  279 
  280     ret = knot_edns_alignment_size(1, 1, 3);
  281     ok(ret == (6 - (1 + 1 + KNOT_EDNS_OPTION_HDRLEN)), "%i-Byte alignment", ret);
  282 
  283     ret = knot_edns_alignment_size(1, 1, 4);
  284     ok(ret == (8 - (1 + 1 + KNOT_EDNS_OPTION_HDRLEN)), "%i-Byte alignment", ret);
  285 
  286     ret = knot_edns_alignment_size(1, 1, 512);
  287     ok(ret == (512 - (1 + 1 + KNOT_EDNS_OPTION_HDRLEN)), "%i-Byte alignment", ret);
  288 }
  289 
  290 static void test_keepalive(void)
  291 {
  292     typedef struct {
  293         char *msg;
  294         uint16_t opt_len;
  295         char *opt;
  296         uint16_t val;
  297     } test_t;
  298 
  299     // OK tests.
  300 
  301     static const test_t TESTS[] = {
  302         { "ok 0",     0, "",         0 },
  303         { "ok 1",     2, "\x00\x01", 1 },
  304         { "ok 258",   2, "\x01\x02", 258 },
  305         { "ok 65535", 2, "\xFF\xFF", 65535 },
  306         { NULL }
  307     };
  308 
  309     for (const test_t *t = TESTS; t->msg != NULL; t++) {
  310         uint16_t len = knot_edns_keepalive_size(t->val);
  311         ok(len == t->opt_len, "%s: %s, size", __func__, t->msg);
  312 
  313         uint8_t wire[8] = { 0 };
  314         int ret = knot_edns_keepalive_write(wire, sizeof(wire), t->val);
  315         is_int(KNOT_EOK, ret, "%s: %s, write, return", __func__, t->msg);
  316         ok(memcmp(wire, t->opt, t->opt_len) == 0, "%s: %s, write, value",
  317                                                   __func__, t->msg);
  318 
  319         uint16_t timeout = 0;
  320         ret = knot_edns_keepalive_parse(&timeout, (uint8_t *)t->opt, t->opt_len);
  321         is_int(KNOT_EOK, ret, "%s: %s, parse, return", __func__, t->msg);
  322         ok(timeout == t->val, "%s: %s, parse, value", __func__, t->msg);
  323     }
  324 
  325     // Error tests.
  326 
  327     uint8_t wire[8] = { 0 };
  328     ok(knot_edns_keepalive_write(NULL, 0, 0) == KNOT_EINVAL,
  329        "%s: write, NULL", __func__);
  330     ok(knot_edns_keepalive_write(wire, 1, 1) == KNOT_ESPACE,
  331        "%s: write, no room", __func__);
  332 
  333     uint16_t timeout = 0;
  334     ok(knot_edns_keepalive_parse(NULL, (const uint8_t *)"", 0) == KNOT_EINVAL,
  335        "%s: parse, NULL", __func__);
  336     ok(knot_edns_keepalive_parse(&timeout, NULL, 0) == KNOT_EINVAL,
  337        "%s: parse, NULL", __func__);
  338     ok(knot_edns_keepalive_parse(&timeout, (const uint8_t *)"\x01", 1) == KNOT_EMALF,
  339        "%s: parse, malformed", __func__);
  340 }
  341 
  342 static void test_chain(void)
  343 {
  344     typedef struct {
  345         char *msg;
  346         uint16_t opt_len;
  347         knot_dname_t *dname;
  348     } test_t;
  349 
  350     // OK tests.
  351 
  352     static const test_t TESTS[] = {
  353         { ".",  1, (knot_dname_t *)"" },
  354         { "a.", 3, (knot_dname_t *)"\x01" "a" },
  355         { NULL }
  356     };
  357 
  358     for (const test_t *t = TESTS; t->msg != NULL; t++) {
  359         uint16_t len = knot_edns_chain_size(t->dname);
  360         ok(len == t->opt_len, "%s: dname %s, size", __func__, t->msg);
  361 
  362         uint8_t wire[8] = { 0 };
  363         int ret = knot_edns_chain_write(wire, sizeof(wire), t->dname);
  364         is_int(KNOT_EOK, ret, "%s: dname %s, write, return", __func__, t->msg);
  365         ok(memcmp(wire, t->dname, t->opt_len) == 0, "%s: dname %s, write, value",
  366                                                     __func__, t->msg);
  367 
  368         knot_dname_t *dname = NULL;
  369         ret = knot_edns_chain_parse(&dname, (uint8_t *)t->dname, t->opt_len, NULL);
  370         is_int(KNOT_EOK, ret, "%s: dname %s, parse, return", __func__, t->msg);
  371         ok(knot_dname_is_equal(dname, t->dname), "%s: dname %s, parse, value",
  372                                                  __func__, t->msg);
  373         knot_dname_free(dname, NULL);
  374     }
  375 
  376     // Error tests.
  377 
  378     ok(knot_edns_chain_size(NULL) == 0, "%s: size, NULL", __func__);
  379 
  380     uint8_t wire[8] = { 0 };
  381     ok(knot_edns_chain_write(NULL, 0, wire) == KNOT_EINVAL,
  382        "%s: write, NULL", __func__);
  383     ok(knot_edns_chain_write(wire, 0, NULL) == KNOT_EINVAL,
  384        "%s: write, NULL", __func__);
  385     ok(knot_edns_chain_write(wire, 0, (const knot_dname_t *)"") == KNOT_ESPACE,
  386        "%s: write, no room", __func__);
  387 
  388     knot_dname_t *dname = NULL;
  389     ok(knot_edns_chain_parse(NULL, wire, 0, NULL) == KNOT_EINVAL && dname == NULL,
  390        "%s: parse, NULL", __func__);
  391     ok(knot_edns_chain_parse(&dname, NULL, 0, NULL) == KNOT_EINVAL && dname == NULL,
  392        "%s: parse, NULL", __func__);
  393     ok(knot_edns_chain_parse(&dname, (const uint8_t *)"\x01", 1, NULL) == KNOT_EMALF &&
  394        dname == NULL, "%s: parse, malformed", __func__);
  395 }
  396 
  397 static void check_cookie_parse(const char *opt, knot_edns_cookie_t *cc,
  398                                knot_edns_cookie_t *sc, int code, const char *msg)
  399 {
  400     const uint8_t *data = NULL;
  401     uint16_t data_len = 0;
  402     if (opt != NULL) {
  403         data = knot_edns_opt_get_data((uint8_t *)opt);
  404         data_len = knot_edns_opt_get_length((uint8_t *)opt);
  405     }
  406 
  407     int ret = knot_edns_cookie_parse(cc, sc, data, data_len);
  408     is_int(code, ret, "cookie parse ret: %s", msg);
  409 }
  410 
  411 static void ok_cookie_check(const char *opt, knot_edns_cookie_t *cc,
  412                             knot_edns_cookie_t *sc, uint16_t cc_len, uint16_t sc_len,
  413                             const char *msg)
  414 {
  415     check_cookie_parse(opt, cc, sc, KNOT_EOK, msg);
  416 
  417     is_int(cc->len, cc_len, "cookie parse cc len: %s", msg);
  418     is_int(sc->len, sc_len, "cookie parse cc len: %s", msg);
  419 
  420     uint16_t size = knot_edns_cookie_size(cc, sc);
  421     is_int(size, cc_len + sc_len, "cookie len: %s", msg);
  422 
  423     uint8_t buf[64];
  424     int ret = knot_edns_cookie_write(buf, sizeof(buf), cc, sc);
  425     is_int(KNOT_EOK, ret, "cookie write ret: %s", msg);
  426 }
  427 
  428 static void test_cookie(void)
  429 {
  430     const char *good[] = {
  431         "\x00\x0a" "\x00\x08" "\x00\x01\x02\x03\x04\x05\x06\x07", /* Only client cookie. */
  432         "\x00\x0a" "\x00\x10" "\x00\x01\x02\x03\x04\x05\x06\x07" "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", /* 8 octets long server cookie. */
  433         "\x00\x0a" "\x00\x28" "\x00\x01\x02\x03\x04\x05\x06\x07" "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27" /* 32 octets long server cookie. */
  434     };
  435 
  436     const char *bad[] = {
  437         "\x00\x0a" "\x00\x00", /* Zero length cookie. */
  438         "\x00\x0a" "\x00\x01" "\x00", /* Short client cookie. */
  439         "\x00\x0a" "\x00\x07" "\x00\x01\x02\x03\x04\x05\x06", /* Short client cookie. */
  440         "\x00\x0a" "\x00\x09" "\x00\x01\x02\x03\x04\x05\x06\x07" "\x08", /* Short server cookie. */
  441         "\x00\x0a" "\x00\x0f" "\x00\x01\x02\x03\x04\x05\x06\x07" "\x08\x09\x0a\x0b\x0c\x0d\x0e", /* Short server cookie. */
  442         "\x00\x0a" "\x00\x29" "\x00\x01\x02\x03\x04\x05\x06\x07" "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28", /* Long server cookie. */
  443     };
  444 
  445     knot_edns_cookie_t cc, sc;
  446 
  447     ok_cookie_check(good[0], &cc,  &sc, 8, 0,  "good cookie 0");
  448     ok_cookie_check(good[1], &cc,  &sc, 8, 8,  "good cookie 1");
  449     ok_cookie_check(good[2], &cc,  &sc, 8, 32, "good cookie 2");
  450 
  451     check_cookie_parse(NULL,    &cc,  &sc,  KNOT_EINVAL, "no data");
  452     check_cookie_parse(good[0], NULL, &sc,  KNOT_EINVAL, "no client cookie");
  453     check_cookie_parse(good[1], &cc,  NULL, KNOT_EINVAL, "no server cookie");
  454 
  455     check_cookie_parse(bad[0],  &cc,  &sc,  KNOT_EMALF,  "bad cookie 0");
  456     check_cookie_parse(bad[1],  &cc,  &sc,  KNOT_EMALF,  "bad cookie 1");
  457     check_cookie_parse(bad[2],  &cc,  &sc,  KNOT_EMALF,  "bad cookie 2");
  458     check_cookie_parse(bad[3],  &cc,  &sc,  KNOT_EMALF,  "bad cookie 3");
  459     check_cookie_parse(bad[4],  &cc,  &sc,  KNOT_EMALF,  "bad cookie 4");
  460     check_cookie_parse(bad[5],  &cc,  &sc,  KNOT_EMALF,  "bad cookie 5");
  461 }
  462 
  463 int main(int argc, char *argv[])
  464 {
  465     plan_lazy();
  466 
  467     knot_rrset_t opt_rr;
  468     int ret = knot_edns_init(&opt_rr, E_MAX_PLD, E_RCODE, E_VERSION, NULL);
  469     is_int(KNOT_EOK, ret, "OPT RR: init");
  470 
  471     /* Check initialized values (no NSID yet). */
  472     check_header(&opt_rr, E_MAX_PLD, E_VERSION, 0, E_RCODE, "OPT RR: check header");
  473 
  474     test_setters(&opt_rr);
  475     test_getters(&opt_rr);
  476     test_alignment();
  477     test_keepalive();
  478     test_chain();
  479     test_cookie();
  480 
  481     knot_rrset_clear(&opt_rr, NULL);
  482 
  483     return 0;
  484 }