Skip to content

dns: only allow one DNS announcement #4996

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions lightningd/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,23 @@ static char *opt_set_accept_extra_tlv_types(const char *arg,
}
#endif

#if EXPERIMENTAL_FEATURES /* BOLT7 DNS RFC #911 */
/* Returns the number of wireaddr types already announced */
static size_t num_announced_types(enum wire_addr_type type, struct lightningd *ld)
{
size_t num = 0;
for (size_t i = 0; i < tal_count(ld->proposed_wireaddr); i++) {
if (ld->proposed_wireaddr[i].itype != ADDR_INTERNAL_WIREADDR)
continue;
if (ld->proposed_wireaddr[i].u.wireaddr.type != type)
continue;
if (ld->proposed_listen_announce[i] & ADDR_ANNOUNCE)
num++;
}
return num;
}
#endif

static char *opt_add_addr_withtype(const char *arg,
struct lightningd *ld,
enum addr_listen_announce ala,
Expand Down Expand Up @@ -242,6 +259,14 @@ static char *opt_add_addr_withtype(const char *arg,
#if EXPERIMENTAL_FEATURES /* BOLT7 DNS RFC #911 */
/* Add ADDR_TYPE_DNS to announce DNS hostnames */
if (is_dnsaddr(address) && ala & ADDR_ANNOUNCE) {
/* BOLT-hostnames #7:
* The origin node:
* ...
* - MUST NOT announce more than one `type 5` DNS hostname.
*/
if (num_announced_types(ADDR_TYPE_DNS, ld) > 0) {
return tal_fmt(NULL, "Only one DNS can be announced");
}
memset(&wi, 0, sizeof(wi));
wi.itype = ADDR_INTERNAL_WIREADDR;
wi.u.wireaddr.type = ADDR_TYPE_DNS;
Expand Down
23 changes: 14 additions & 9 deletions tests/test_gossip.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ def test_announce_address(node_factory, bitcoind):
opts = {'disable-dns': None, 'announce-addr':
['4acth47i6kxnvkewtm6q7ib2s3ufpo5sqbsnzjpbi7utijcltosqemad.onion',
'1.2.3.4:1234',
'localhost:1235',
'example.com:1236',
'::'],
'log-level': 'io',
Expand Down Expand Up @@ -151,24 +150,21 @@ def test_announce_address(node_factory, bitcoind):
# Also expect the address descriptor types to be sorted!
# BOLT #7:
# - MUST place address descriptors in ascending order.
l1.daemon.wait_for_log(r"\[OUT\] 0101.*0063"
l1.daemon.wait_for_log(r"\[OUT\] 0101.*0056"
"010102030404d2" # IPv4 01 1.2.3.4:1234
"017f000001...." # IPv4 01 127.0.0.1:wxyz
"0200000000000000000000000000000000...." # IPv6 02 :::<any_port>
"04e00533f3e8f2aedaa8969b3d0fa03a96e857bbb28064dca5e147e934244b9ba5023003...." # TORv3 04
"05096c6f63616c686f737404d3" # DNS 05 len localhost:1235
"050b6578616d706c652e636f6d04d4") # DNS 05 len example.com:1236

# Check other node can parse these (make sure it has digested msg)
wait_for(lambda: 'addresses' in l2.rpc.listnodes(l1.info['id'])['nodes'][0])
addresses = l2.rpc.listnodes(l1.info['id'])['nodes'][0]['addresses']
addresses_dns = [address for address in addresses if address['type'] == 'dns']
assert len(addresses) == 6
assert len(addresses_dns) == 2
assert addresses_dns[0]['address'] == 'localhost'
assert addresses_dns[0]['port'] == 1235
assert addresses_dns[1]['address'] == 'example.com'
assert addresses_dns[1]['port'] == 1236
assert len(addresses) == 5
assert len(addresses_dns) == 1
assert addresses_dns[0]['address'] == 'example.com'
assert addresses_dns[0]['port'] == 1236


@unittest.skipIf(not EXPERIMENTAL_FEATURES, "BOLT7 DNS RFC #911")
Expand Down Expand Up @@ -236,6 +232,15 @@ def test_announce_and_connect_via_dns(node_factory, bitcoind):
l4.rpc.connect(l1.info['id'])


@unittest.skipIf(not EXPERIMENTAL_FEATURES, "BOLT7 DNS RFC #911")
@pytest.mark.developer("gossip without DEVELOPER=1 is slow")
def test_only_announce_one_dns(node_factory, bitcoind):
# and test that we can't announce more than one DNS address
l1 = node_factory.get_node(may_fail=True, expect_fail=True,
options={'announce-addr': ['localhost.localdomain:12345', 'example.com:12345']})
assert l1.daemon.is_in_stderr("Only one DNS can be announced")


@pytest.mark.developer("needs DEVELOPER=1")
def test_gossip_timestamp_filter(node_factory, bitcoind, chainparams):
# Updates get backdated 5 seconds with --dev-fast-gossip.
Expand Down