Skip to content

Commit

Permalink
- Fix #1154: Tag Incorrectly Applying for Other Interfaces
Browse files Browse the repository at this point in the history
  Using the Same IP. This fix is not for 1.22.0.
  • Loading branch information
wcawijngaards committed Oct 16, 2024
1 parent 0076736 commit 9a63db3
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 15 deletions.
11 changes: 0 additions & 11 deletions daemon/acl_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -551,17 +551,6 @@ acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
return 1;
}

int
acl_interface_compare(const void* k1, const void* k2)
{
struct addr_tree_node* n1 = (struct addr_tree_node*)k1;
struct addr_tree_node* n2 = (struct addr_tree_node*)k2;
return sockaddr_cmp(&n1->addr, n1->addrlen, &n2->addr,
n2->addrlen);
/* We don't care about comparing node->net. All addresses in the
* acl_interface tree have either 32 (ipv4) or 128 (ipv6). */
}

void
acl_interface_init(struct acl_list* acl_interface)
{
Expand Down
3 changes: 0 additions & 3 deletions daemon/acl_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,6 @@ acl_interface_insert(struct acl_list* acl_interface,
int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
struct views* v);

/** compare ACL interface "addr_tree" nodes (+port) */
int acl_interface_compare(const void* k1, const void* k2);

/**
* Initialise (also clean) the acl_interface struct.
* @param acl_interface: where to store.
Expand Down
2 changes: 2 additions & 0 deletions doc/Changelog
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

16 October 2024: Wouter
- Fix for dnstap with dnscrypt and dnstap without dnsoverquic.
- Fix #1154: Tag Incorrectly Applying for Other Interfaces
Using the Same IP. This fix is not for 1.22.0.

14 October 2024: Wouter
- Fix to display warning if quic-port is set but dnsoverquic is not
Expand Down
14 changes: 14 additions & 0 deletions testdata/acl_interface.tdir/acl_interface.conf
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,20 @@ server:
interface-view: @INTERFACE@@@PORT_VIEW_EXT@ "ext"
interface-view: @INTERFACE@@@PORT_VIEW_INTEXT@ "intext"

# Interface with scope_id
interface: @INTERFACE@vlan50@@PORT_ALLOW@
interface: @INTERFACE@vlan51@@PORT_ALLOW@
interface-tag: @INTERFACE@vlan50@@PORT_ALLOW@ "one"
interface-tag: @INTERFACE@vlan51@@PORT_ALLOW@ "two"
interface-action: @INTERFACE@vlan50@@PORT_ALLOW@ allow
interface-action: @INTERFACE@vlan51@@PORT_ALLOW@ allow
local-zone: one.vtest. static
local-data: "one.vtest. A 1.1.1.1"
local-zone-tag: one.vtest. "one"
local-zone: two.vtest. static
local-data: "two.vtest. A 2.2.2.2"
local-zone-tag: two.vtest. "two"

# Local zones configuration
local-zone: local. transparent
local-data: "local. A 0.0.0.0"
Expand Down
15 changes: 15 additions & 0 deletions testdata/acl_interface.tdir/acl_interface.test.scenario
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ ip addr add $INTERFACE_ADDR_3 dev $INTERFACE
ip addr add $INTERFACE_ADDR_4 dev $INTERFACE
ip link set $INTERFACE up

ip link add ${INTERFACE}vlan50 type dummy
ip addr add fe80::2/64 dev ${INTERFACE}vlan50
ip link add ${INTERFACE}vlan51 type dummy
ip addr add fe80::2/64 dev ${INTERFACE}vlan51
ip link set ${INTERFACE}vlan50 up
ip link set ${INTERFACE}vlan51 up

ip addr show

# start the forwarder in the background
get_ldns_testns
$LDNS_TESTNS -p $FORWARD_PORT acl_interface.testns >fwd.log 2>&1 &
Expand Down Expand Up @@ -250,4 +259,10 @@ for addr in $INTERFACE_ADDR_1 $INTERFACE_ADDR_2 $INTERFACE_ADDR_3 $INTERFACE_ADD
expect_external_answer
done

query_addr fe80::2%${INTERFACE}vlan50 $PORT_ALLOW "one.vtest."
expect_tag_one_answer

query_addr fe80::2%${INTERFACE}vlan51 $PORT_ALLOW "two.vtest."
expect_tag_two_answer

end 0
46 changes: 46 additions & 0 deletions util/net_help.c
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,52 @@ sockaddr_cmp_addr(struct sockaddr_storage* addr1, socklen_t len1,
}
}

int
sockaddr_cmp_scopeid(struct sockaddr_storage* addr1, socklen_t len1,
struct sockaddr_storage* addr2, socklen_t len2)
{
struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1;
struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2;
struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1;
struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2;
if(len1 < len2)
return -1;
if(len1 > len2)
return 1;
log_assert(len1 == len2);
if( p1_in->sin_family < p2_in->sin_family)
return -1;
if( p1_in->sin_family > p2_in->sin_family)
return 1;
log_assert( p1_in->sin_family == p2_in->sin_family );
/* compare ip4 */
if( p1_in->sin_family == AF_INET ) {
/* just order it, ntohs not required */
if(p1_in->sin_port < p2_in->sin_port)
return -1;
if(p1_in->sin_port > p2_in->sin_port)
return 1;
log_assert(p1_in->sin_port == p2_in->sin_port);
return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE);
} else if (p1_in6->sin6_family == AF_INET6) {
/* just order it, ntohs not required */
if(p1_in6->sin6_port < p2_in6->sin6_port)
return -1;
if(p1_in6->sin6_port > p2_in6->sin6_port)
return 1;
if(p1_in6->sin6_scope_id < p2_in6->sin6_scope_id)
return -1;
if(p1_in6->sin6_scope_id > p2_in6->sin6_scope_id)
return 1;
log_assert(p1_in6->sin6_port == p2_in6->sin6_port);
return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr,
INET6_SIZE);
} else {
/* eek unknown type, perform this comparison for sanity. */
return memcmp(addr1, addr2, len1);
}
}

int
addr_is_ip6(struct sockaddr_storage* addr, socklen_t len)
{
Expand Down
12 changes: 12 additions & 0 deletions util/net_help.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,18 @@ int sockaddr_cmp(struct sockaddr_storage* addr1, socklen_t len1,
int sockaddr_cmp_addr(struct sockaddr_storage* addr1, socklen_t len1,
struct sockaddr_storage* addr2, socklen_t len2);

/**
* Compare two sockaddrs. Imposes an ordering on the addresses.
* Compares address and port. It also compares scope_id for ip6.
* @param addr1: address 1.
* @param len1: lengths of addr1.
* @param addr2: address 2.
* @param len2: lengths of addr2.
* @return: 0 if addr1 == addr2. -1 if addr1 is smaller, +1 if larger.
*/
int sockaddr_cmp_scopeid(struct sockaddr_storage* addr1, socklen_t len1,
struct sockaddr_storage* addr2, socklen_t len2);

/**
* Checkout address family.
* @param addr: the sockaddr to examine.
Expand Down
2 changes: 1 addition & 1 deletion util/storage/dnstree.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ int addr_tree_addrport_compare(const void* k1, const void* k2)
{
struct addr_tree_node* n1 = (struct addr_tree_node*)k1;
struct addr_tree_node* n2 = (struct addr_tree_node*)k2;
return sockaddr_cmp(&n1->addr, n1->addrlen, &n2->addr,
return sockaddr_cmp_scopeid(&n1->addr, n1->addrlen, &n2->addr,
n2->addrlen);
}

Expand Down

0 comments on commit 9a63db3

Please sign in to comment.