/* * restrict_source - maintains dynamic "restrict source ..." entries as * peers come and go. */ void restrict_source( sockaddr_u * addr, int farewell, /* 0 to add, 1 to remove */ u_long expire /* 0 is infinite, valid until */ ) { sockaddr_u onesmask; restrict_u * res; int found_specific; if (!restrict_source_enabled || SOCK_UNSPEC(addr) || IS_MCAST(addr) || ISREFCLOCKADR(addr)) return; REQUIRE(AF_INET == AF(addr) || AF_INET6 == AF(addr)); SET_HOSTMASK(&onesmask, AF(addr)); if (farewell) { hack_restrict(RESTRICT_REMOVE, addr, &onesmask, 0, 0, 0); DPRINTF(1, ("restrict_source: %s removed", stoa(addr))); return; } /* * If there is a specific entry for this address, hands * off, as it is condidered more specific than "restrict * server ...". * However, if the specific entry found is a fleeting one * added by pool_xmit() before soliciting, replace it * immediately regardless of the expire value to make way * for the more persistent entry. */ if (IS_IPV4(addr)) { res = match_restrict4_addr(SRCADR(addr), SRCPORT(addr)); INSIST(res != NULL); found_specific = (SRCADR(&onesmask) == res->u.v4.mask); } else { res = match_restrict6_addr(&SOCK_ADDR6(addr), SRCPORT(addr)); INSIST(res != NULL); found_specific = ADDR6_EQ(&res->u.v6.mask, &SOCK_ADDR6(&onesmask)); } if (!expire && found_specific && res->expire) { found_specific = 0; free_res(res, IS_IPV6(addr)); } if (found_specific) return; hack_restrict(RESTRICT_FLAGS, addr, &onesmask, restrict_source_mflags, restrict_source_flags, expire); DPRINTF(1, ("restrict_source: %s host restriction added\n", stoa(addr))); }
TEST(hackrestrict, RestrictUnflagWorks) { sockaddr_u resaddr = create_sockaddr_u(54321, "11.22.30.20"); sockaddr_u resmask = create_sockaddr_u(54321, "255.255.0.0"); hack_restrict(RESTRICT_FLAGS, &resaddr, &resmask, 0, 11, 0); hack_restrict(RESTRICT_UNFLAG, &resaddr, &resmask, 0, 10, 0); TEST_ASSERT_EQUAL(1, restrictions(&resaddr)); }
TEST(hackrestrict, CantRemoveDefaultEntry) { sockaddr_u resaddr = create_sockaddr_u(54321, "0.0.0.0"); sockaddr_u resmask = create_sockaddr_u(54321, "0.0.0.0"); hack_restrict(RESTRICT_REMOVE, &resaddr, &resmask, 0, 0, 0); TEST_ASSERT_EQUAL(0, restrictions(&resaddr)); }
void test_CantRemoveDefaultEntry(void) { sockaddr_u resaddr = create_sockaddr_u(AF_INET, 54321, "0.0.0.0"); sockaddr_u resmask = create_sockaddr_u(AF_INET, 54321, "0.0.0.0"); hack_restrict(RESTRICT_REMOVE, &resaddr, &resmask, 0, 0, 0); TEST_ASSERT_EQUAL(0, restrictions(&resaddr)); }
TEST(hackrestrict, TheMostFittingRestrictionIsMatched) { sockaddr_u resaddr_target = create_sockaddr_u(54321, "11.22.33.44"); sockaddr_u resaddr_not_matching = create_sockaddr_u(54321, "11.99.33.44"); sockaddr_u resmask_not_matching = create_sockaddr_u(54321, "255.255.0.0"); sockaddr_u resaddr_best_match = create_sockaddr_u(54321, "11.22.30.20"); sockaddr_u resmask_best_match = create_sockaddr_u(54321, "255.255.0.0"); /* it also matches, but we prefer the one above, as it's more specific */ sockaddr_u resaddr_second_match = create_sockaddr_u(54321, "11.99.33.44"); sockaddr_u resmask_second_match = create_sockaddr_u(54321, "255.0.0.0"); hack_restrict(RESTRICT_FLAGS, &resaddr_not_matching, &resmask_not_matching, 0, 11, 0); hack_restrict(RESTRICT_FLAGS, &resaddr_best_match, &resmask_best_match, 0, 22, 0); hack_restrict(RESTRICT_FLAGS, &resaddr_second_match, &resmask_second_match, 0, 128, 0); TEST_ASSERT_EQUAL(22, restrictions(&resaddr_target)); }
TEST(hackrestrict, AddingNewRestriction) { sockaddr_u resaddr = create_sockaddr_u(54321, "11.22.33.44"); sockaddr_u resmask = create_sockaddr_u(54321, "128.0.0.0"); const u_short flags = 42; hack_restrict(RESTRICT_FLAGS, &resaddr, &resmask, 0, flags, 0); TEST_ASSERT_EQUAL(flags, restrictions(&resaddr)); }
TEST(hackrestrict, DeletedRestrictionIsNotMatched) { sockaddr_u resaddr_target = create_sockaddr_u(54321, "11.22.33.44"); sockaddr_u resaddr_not_matching = create_sockaddr_u(54321, "11.99.33.44"); sockaddr_u resmask_not_matching = create_sockaddr_u(54321, "255.255.0.0"); sockaddr_u resaddr_best_match = create_sockaddr_u(54321, "11.22.30.20"); sockaddr_u resmask_best_match = create_sockaddr_u(54321, "255.255.0.0"); sockaddr_u resaddr_second_match = create_sockaddr_u(54321, "11.99.33.44"); sockaddr_u resmask_second_match = create_sockaddr_u(54321, "255.0.0.0"); hack_restrict(RESTRICT_FLAGS, &resaddr_not_matching, &resmask_not_matching, 0, 11, 0); hack_restrict(RESTRICT_FLAGS, &resaddr_best_match, &resmask_best_match, 0, 22, 0); hack_restrict(RESTRICT_FLAGS, &resaddr_second_match, &resmask_second_match, 0, 128, 0); /* deleting the best match*/ hack_restrict(RESTRICT_REMOVE, &resaddr_best_match, &resmask_best_match, 0, 22, 0); TEST_ASSERT_EQUAL(128, restrictions(&resaddr_target)); }
TEST(hackrestrict, HackingDefaultRestriction) { /* * We change the flag of the default restriction, * and check if restriction() returns that flag */ const u_short flags = 42; sockaddr_u resaddr = create_sockaddr_u(54321, "0.0.0.0"); sockaddr_u resmask = create_sockaddr_u(54321, "0.0.0.0"); hack_restrict(RESTRICT_FLAGS, &resaddr, &resmask, 0, flags, 0); sockaddr_u sockaddr = create_sockaddr_u(54321, "111.123.251.124"); TEST_ASSERT_EQUAL(flags, restrictions(&sockaddr)); }