Commit a6351bf8 authored by Daniel Salzman's avatar Daniel Salzman

conf: move address range item into yparser schema

parent 67e7952c
......@@ -640,9 +640,9 @@ struct sockaddr_storage conf_addr_range(
{
assert(val != NULL && val->item != NULL && max_ss != NULL &&
prefix_len != NULL);
assert(val->item->type == YP_TDATA ||
assert(val->item->type == YP_TNET ||
(val->item->type == YP_TREF &&
val->item->var.r.ref->var.g.id->type == YP_TDATA));
val->item->var.r.ref->var.g.id->type == YP_TNET));
struct sockaddr_storage out = { AF_UNSPEC };
......
......@@ -143,8 +143,7 @@ static const yp_item_t desc_server[] = {
{ C_RATE_LIMIT, YP_TINT, YP_VINT = { 0, INT32_MAX, 0 } },
{ C_RATE_LIMIT_SLIP, YP_TINT, YP_VINT = { 0, 100, 1 } },
{ C_RATE_LIMIT_TBL_SIZE, YP_TINT, YP_VINT = { 1, INT32_MAX, 393241 } },
{ C_RATE_LIMIT_WHITELIST, YP_TDATA, YP_VDATA = { 0, NULL, addr_range_to_bin,
addr_range_to_txt }, YP_FMULTI },
{ C_RATE_LIMIT_WHITELIST, YP_TNET, YP_VNONE, YP_FMULTI },
{ NULL }
};
......@@ -223,8 +222,7 @@ static const yp_item_t desc_key[] = {
static const yp_item_t desc_acl[] = {
{ C_ID, YP_TSTR, YP_VNONE, CONF_IO_FREF },
{ C_ADDR, YP_TDATA, YP_VDATA = { 0, NULL, addr_range_to_bin,
addr_range_to_txt }, YP_FMULTI },
{ C_ADDR, YP_TNET, YP_VNONE, YP_FMULTI },
{ C_KEY, YP_TREF, YP_VREF = { C_KEY }, YP_FMULTI, { check_ref } },
{ C_ACTION, YP_TOPT, YP_VOPT = { acl_actions, ACL_ACTION_NONE }, YP_FMULTI },
{ C_DENY, YP_TBOOL, YP_VNONE },
......
......@@ -185,122 +185,6 @@ int edns_opt_to_txt(
YP_CHECK_RET;
}
int addr_range_to_bin(
YP_TXT_BIN_PARAMS)
{
YP_CHECK_PARAMS_BIN;
// Format: 0 - single address, 1 - address prefix, 2 - address range.
uint8_t format = 0;
// Check for the "addr/mask" format.
const uint8_t *pos = (uint8_t *)strchr((char *)in->position, '/');
if (pos >= stop) {
pos = NULL;
}
if (pos != NULL) {
format = 1;
} else {
// Check for the "addr1-addr2" format.
pos = (uint8_t *)strchr((char *)in->position, '-');
if (pos >= stop) {
pos = NULL;
}
if (pos != NULL) {
format = 2;
}
}
// Store address1 type position.
uint8_t *type1 = out->position;
// Write the first address.
int ret = yp_addr_noport_to_bin(in, out, pos, false);
if (ret != KNOT_EOK) {
return ret;
}
wire_ctx_write_u8(out, format);
switch (format) {
case 1:
// Skip the separator.
wire_ctx_skip(in, sizeof(uint8_t));
// Write the prefix length.
ret = yp_int_to_bin(in, out, stop, 0, (*type1 == 4) ? 32 : 128,
YP_SNONE);
if (ret != KNOT_EOK) {
return ret;
}
break;
case 2:
// Skip the separator.
wire_ctx_skip(in, sizeof(uint8_t));
// Store address2 type position.
uint8_t *type2 = out->position;
// Write the second address.
ret = yp_addr_noport_to_bin(in, out, stop, false);
if (ret != KNOT_EOK) {
return ret;
}
// Check for address mismatch.
if (*type1 != *type2) {
return KNOT_EINVAL;
}
break;
default:
break;
}
YP_CHECK_RET;
}
int addr_range_to_txt(
YP_BIN_TXT_PARAMS)
{
YP_CHECK_PARAMS_TXT;
// Write the first address.
int ret = yp_addr_noport_to_txt(in, out);
if (ret != KNOT_EOK) {
return ret;
}
uint8_t format = wire_ctx_read_u8(in);
switch (format) {
case 1:
// Write the separator.
wire_ctx_write_u8(out, '/');
// Write the prefix length.
ret = yp_int_to_txt(in, out, YP_SNONE);
if (ret != KNOT_EOK) {
return ret;
}
break;
case 2:
// Write the separator.
wire_ctx_write_u8(out, '-');
// Write the second address.
ret = yp_addr_noport_to_txt(in, out);
if (ret != KNOT_EOK) {
return ret;
}
break;
default:
break;
}
YP_CHECK_RET;
}
int check_ref(
conf_check_t *args)
{
......
/* Copyright (C) 2015 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -64,14 +64,6 @@ int edns_opt_to_txt(
YP_BIN_TXT_PARAMS
);
int addr_range_to_bin(
YP_TXT_BIN_PARAMS
);
int addr_range_to_txt(
YP_BIN_TXT_PARAMS
);
int check_ref(
conf_check_t *args
);
......
......@@ -30,8 +30,7 @@ const yp_item_t scheme_mod_rrl[] = {
{ MOD_RATE_LIMIT, YP_TINT, YP_VINT = { 1, INT32_MAX } },
{ MOD_SLIP, YP_TINT, YP_VINT = { 0, RRL_SLIP_MAX, 1 } },
{ MOD_TBL_SIZE, YP_TINT, YP_VINT = { 1, INT32_MAX, 393241 } },
{ MOD_WHITELIST, YP_TDATA, YP_VDATA = { 0, NULL, addr_range_to_bin,
addr_range_to_txt }, YP_FMULTI },
{ MOD_WHITELIST, YP_TNET, YP_VNONE, YP_FMULTI },
{ C_COMMENT, YP_TSTR, YP_VNONE },
{ NULL }
};
......
......@@ -55,8 +55,7 @@ const yp_item_t scheme_mod_synth_record[] = {
{ MOD_PREFIX, YP_TSTR, YP_VSTR = { "" }, YP_FNONE, { check_prefix } },
{ MOD_ORIGIN, YP_TDNAME, YP_VNONE },
{ MOD_TTL, YP_TINT, YP_VINT = { 0, UINT32_MAX, 3600, YP_STIME } },
{ MOD_NET, YP_TDATA, YP_VDATA = { 0, NULL, addr_range_to_bin,
addr_range_to_txt }, YP_FMULTI },
{ MOD_NET, YP_TNET, YP_VNONE, YP_FMULTI },
{ C_COMMENT, YP_TSTR, YP_VNONE },
{ NULL }
};
......
......@@ -55,6 +55,7 @@ struct knot_lookup;
#define YP_VOPT .var.o
#define YP_VSTR .var.s
#define YP_VADDR .var.a
#define YP_VNET .var.d
#define YP_VDNAME .var.d
#define YP_VHEX .var.d
#define YP_VB64 .var.d
......@@ -74,6 +75,7 @@ typedef enum {
YP_TSTR, /*!< String. */
YP_THEX, /*!< String or hexadecimal string if "0x" prefix. */
YP_TADDR, /*!< Address (address[@port] or UNIX socket path). */
YP_TNET, /*!< Network address range (address[/mask] or address-address). */
YP_TDNAME, /*!< Domain name. */
YP_TB64, /*!< Base64 encoded string. */
YP_TDATA, /*!< Customized data. */
......
/* Copyright (C) 2015 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -502,6 +502,122 @@ int yp_addr_to_txt(
YP_CHECK_RET;
}
int yp_addr_range_to_bin(
YP_TXT_BIN_PARAMS)
{
YP_CHECK_PARAMS_BIN;
// Format: 0 - single address, 1 - address prefix, 2 - address range.
uint8_t format = 0;
// Check for the "addr/mask" format.
const uint8_t *pos = (uint8_t *)strchr((char *)in->position, '/');
if (pos >= stop) {
pos = NULL;
}
if (pos != NULL) {
format = 1;
} else {
// Check for the "addr1-addr2" format.
pos = (uint8_t *)strchr((char *)in->position, '-');
if (pos >= stop) {
pos = NULL;
}
if (pos != NULL) {
format = 2;
}
}
// Store address1 type position.
uint8_t *type1 = out->position;
// Write the first address.
int ret = yp_addr_noport_to_bin(in, out, pos, false);
if (ret != KNOT_EOK) {
return ret;
}
wire_ctx_write_u8(out, format);
switch (format) {
case 1:
// Skip the separator.
wire_ctx_skip(in, sizeof(uint8_t));
// Write the prefix length.
ret = yp_int_to_bin(in, out, stop, 0, (*type1 == 4) ? 32 : 128,
YP_SNONE);
if (ret != KNOT_EOK) {
return ret;
}
break;
case 2:
// Skip the separator.
wire_ctx_skip(in, sizeof(uint8_t));
// Store address2 type position.
uint8_t *type2 = out->position;
// Write the second address.
ret = yp_addr_noport_to_bin(in, out, stop, false);
if (ret != KNOT_EOK) {
return ret;
}
// Check for address mismatch.
if (*type1 != *type2) {
return KNOT_EINVAL;
}
break;
default:
break;
}
YP_CHECK_RET;
}
int yp_addr_range_to_txt(
YP_BIN_TXT_PARAMS)
{
YP_CHECK_PARAMS_TXT;
// Write the first address.
int ret = yp_addr_noport_to_txt(in, out);
if (ret != KNOT_EOK) {
return ret;
}
uint8_t format = wire_ctx_read_u8(in);
switch (format) {
case 1:
// Write the separator.
wire_ctx_write_u8(out, '/');
// Write the prefix length.
ret = yp_int_to_txt(in, out, YP_SNONE);
if (ret != KNOT_EOK) {
return ret;
}
break;
case 2:
// Write the separator.
wire_ctx_write_u8(out, '-');
// Write the second address.
ret = yp_addr_noport_to_txt(in, out);
if (ret != KNOT_EOK) {
return ret;
}
break;
default:
break;
}
YP_CHECK_RET;
}
int yp_option_to_bin(
YP_TXT_BIN_PARAMS,
const knot_lookup_t *opts)
......@@ -766,6 +882,9 @@ int yp_item_to_bin(
case YP_TADDR:
ret = yp_addr_to_bin(&in, &out, NULL);
break;
case YP_TNET:
ret = yp_addr_range_to_bin(&in, &out, NULL);
break;
case YP_TDNAME:
ret = yp_dname_to_bin(&in, &out, NULL);
break;
......@@ -841,6 +960,9 @@ int yp_item_to_txt(
case YP_TADDR:
ret = yp_addr_to_txt(&in, &out);
break;
case YP_TNET:
ret = yp_addr_range_to_txt(&in, &out);
break;
case YP_TDNAME:
ret = yp_dname_to_txt(&in, &out);
break;
......
/* Copyright (C) 2015 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -261,6 +261,14 @@ int yp_addr_to_txt(
YP_BIN_TXT_PARAMS
);
int yp_addr_range_to_bin(
YP_TXT_BIN_PARAMS
);
int yp_addr_range_to_txt(
YP_BIN_TXT_PARAMS
);
int yp_option_to_bin(
YP_TXT_BIN_PARAMS,
const struct knot_lookup *opts
......
......@@ -177,6 +177,37 @@ static void addr_bad_test(const char *txt, int code)
ok(ret == code, "invalid txt to bin");
}
static void addr_range_test(const char *txt)
{
int ret;
uint8_t b[64];
size_t b_len = sizeof(b);
char t[64];
size_t t_len = sizeof(t);
yp_item_t i = { NULL, YP_TNET, YP_VNONE };
diag("address range \"%s\":", txt);
ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len);
is_int(KNOT_EOK, ret, "txt to bin");
ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE);
is_int(KNOT_EOK, ret, "bin to txt");
ok(strlen(t) == t_len, "txt ret length");
ok(strlen(txt) == t_len, "txt length");
ok(memcmp(txt, t, t_len) == 0, "compare");
}
static void addr_range_bad_test(const char *txt, int code)
{
int ret;
uint8_t b[64];
size_t b_len = sizeof(b);
yp_item_t i = { NULL, YP_TNET, YP_VNONE };
diag("address range \"%s\":", txt);
ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len);
ok(ret == code, "invalid txt to bin");
}
static void dname_test(const char *txt, const char *val)
{
int ret;
......@@ -336,6 +367,22 @@ int main(int argc, char *argv[])
addr_bad_test("192.168.123.1@1x", KNOT_EINVAL);
addr_bad_test("192.168.123.1@65536", KNOT_ERANGE);
/* Address range tests. */
addr_range_test("1.1.1.1");
addr_range_test("1.1.1.1/0");
addr_range_test("1.1.1.1/32");
addr_range_test("1.1.1.1-1.2.3.4");
addr_range_test("::1");
addr_range_test("::1/0");
addr_range_test("::1/32");
addr_range_test("1::-5::");
addr_range_bad_test("unix", KNOT_EINVAL);
addr_range_bad_test("1.1.1", KNOT_EINVAL);
addr_range_bad_test("1.1.1.1/", KNOT_EINVAL);
addr_range_bad_test("1.1.1.1/33", KNOT_ERANGE);
addr_range_bad_test("1.1.1.1-", KNOT_EINVAL);
addr_range_bad_test("1.1.1.1-::1", KNOT_EINVAL);
/* Dname tests. */
dname_test("example.com.", "\x07""example""\x03""com""\x00");
......
/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -99,41 +99,6 @@ static void edns_opt_bad_test(const char *txt, int code)
ok(ret == code, "invalid txt to bin");
}
static void addr_range_test(const char *txt)
{
int ret;
uint8_t b[64];
size_t b_len = sizeof(b);
char t[64];
size_t t_len = sizeof(t);
yp_item_t i = { NULL, YP_TDATA, YP_VDATA = { 0, NULL,
addr_range_to_bin,
addr_range_to_txt } };
diag("address range \"%s\":", txt);
ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len);
is_int(KNOT_EOK, ret, "txt to bin");
ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE);
is_int(KNOT_EOK, ret, "bin to txt");
ok(strlen(t) == t_len, "txt ret length");
ok(strlen(txt) == t_len, "txt length");
ok(memcmp(txt, t, t_len) == 0, "compare");
}
static void addr_range_bad_test(const char *txt, int code)
{
int ret;
uint8_t b[64];
size_t b_len = sizeof(b);
yp_item_t i = { NULL, YP_TDATA, YP_VDATA = { 0, NULL,
addr_range_to_bin,
addr_range_to_txt } };
diag("address range \"%s\":", txt);
ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len);
ok(ret == code, "invalid txt to bin");
}
int main(int argc, char *argv[])
{
plan_lazy();
......@@ -155,21 +120,5 @@ int main(int argc, char *argv[])
edns_opt_bad_test("65536:a", KNOT_ERANGE);
edns_opt_bad_test("0:0xa", KNOT_EINVAL);
/* Address range tests. */
addr_range_test("1.1.1.1");
addr_range_test("1.1.1.1/0");
addr_range_test("1.1.1.1/32");
addr_range_test("1.1.1.1-1.2.3.4");
addr_range_test("::1");
addr_range_test("::1/0");
addr_range_test("::1/32");
addr_range_test("1::-5::");
addr_range_bad_test("unix", KNOT_EINVAL);
addr_range_bad_test("1.1.1", KNOT_EINVAL);
addr_range_bad_test("1.1.1.1/", KNOT_EINVAL);
addr_range_bad_test("1.1.1.1/33", KNOT_ERANGE);
addr_range_bad_test("1.1.1.1-", KNOT_EINVAL);
addr_range_bad_test("1.1.1.1-::1", KNOT_EINVAL);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment