* Decode interface flags on receive() debug output. HStenn.
* Warn the user if deprecated "driftfile name WanderThreshold" is used. HStenn.
* Update the documentation in ntp.conf.def . HStenn.
+* restrictions() must return restrict flags and ippeerlimit. HStenn.
---
(4.2.8p10) 2017/03/21 Released by Harlan Stenn <stenn@ntp.org>
#define V6_SIZEOF_RESTRICT_U (offsetof(restrict_u, u) \
+ sizeof(res_addr6))
+typedef struct r4addr_tag r4addr;
+struct r4addr_tag {
+ u_short rflags; /* match flags */
+ short ippeerlimit; /* IP peer limit */
+};
+
char *build_iflags(u_int32 flags);
char *build_mflags(u_short flags);
char *build_rflags(u_short flags);
extern struct peer *findpeer (struct recvbuf *, int, int *);
extern struct peer *findpeerbyassoc(associd_t);
extern void set_peerdstadr (struct peer *, endpt *);
-extern struct peer *newpeer (sockaddr_u *, const char *,
- endpt *, u_char, u_char,
- u_char, u_char, u_int, u_char, u_int32,
+extern struct peer *newpeer (sockaddr_u *, const char *, endpt *,
+ int, u_char, u_char, u_char, u_char,
+ u_int, u_char, u_int32,
keyid_t, const char *);
extern void peer_all_reset (void);
extern void peer_clr_stats (void);
-extern struct peer *peer_config(sockaddr_u *, const char *,
- endpt *, u_char, u_char,
- u_char, u_char, u_int, u_int32,
+extern struct peer *peer_config(sockaddr_u *, const char *, endpt *,
+ int, u_char, u_char, u_char, u_char,
+ u_int, u_int32,
keyid_t, const char *);
extern void peer_reset (struct peer *);
extern void refresh_all_peerinterfaces(void);
/* ntp_restrict.c */
extern void init_restrict (void);
-extern u_short restrictions (sockaddr_u *);
+extern void restrictions (sockaddr_u *, r4addr *);
extern void hack_restrict (int, sockaddr_u *, sockaddr_u *,
short, u_short, u_short, u_long);
extern void restrict_source (sockaddr_u *, int, u_long);
* If we have a numeric address, we can safely
* proceed in the mainline with it. Otherwise, hand
* the hostname off to the blocking child.
+ *
+ * Note that if we're told to add the peer here, we
+ * do that regardless of ippeerlimit.
*/
if (is_ip_address(*cmdline_servers, AF_UNSPEC,
&peeraddr)) {
&peeraddr,
NULL,
NULL,
+ -1,
MODE_CLIENT,
NTP_VERSION,
0,
&peeraddr,
curr_peer->addr->address,
NULL,
+ -1,
hmode,
curr_peer->peerversion,
curr_peer->minpoll,
&peeraddr,
NULL,
NULL,
+ -1,
hmode,
curr_peer->peerversion,
curr_peer->minpoll,
&peeraddr,
NULL,
NULL,
+ -1,
ctx->hmode,
ctx->version,
ctx->minpoll,
sockaddr_u * srcadr,
const char * hostname,
endpt * dstadr,
+ int ippeerlimit,
u_char hmode,
u_char version,
u_char minpoll,
flags |= FLAG_IBURST;
if ((MDF_ACAST | MDF_POOL) & cast_flags)
flags &= ~FLAG_PREEMPT;
- return newpeer(srcadr, hostname, dstadr, hmode, version,
+ return newpeer(srcadr, hostname, dstadr, ippeerlimit, hmode, version,
minpoll, maxpoll, flags, cast_flags, ttl, key, ident);
}
sockaddr_u * srcadr,
const char * hostname,
endpt * dstadr,
+ int ippeerlimit,
u_char hmode,
u_char version,
u_char minpoll,
: stoa(srcadr),
ip_count));
+ /* Check ippeerlimit wrt ip_count */
+ if (ippeerlimit > -1) {
+ if (ip_count + 1 > ippeerlimit) {
+ DPRINTF(2, ("newpeer(%s) denied - ippeerlimit %d\n",
+ (hostname)
+ ? hostname
+ : stoa(srcadr),
+ ippeerlimit));
+ return NULL;
+ }
+ }
+
/*
* Allocate a new peer structure. Some dirt here, since some of
* the initialization requires knowlege of our system state.
u_char hisleap; /* packet leap indicator */
u_char hismode; /* packet mode */
u_char hisstratum; /* packet stratum */
+ r4addr r4a; /* address restrictions */
u_short restrict_mask; /* restrict bits */
const char *hm_str; /* hismode string */
const char *am_str; /* association match string */
sys_badlength++;
return; /* bogus port */
}
- restrict_mask = restrictions(&rbufp->recv_srcadr);
+ restrictions(&rbufp->recv_srcadr, &r4a);
+ restrict_mask = r4a.rflags;
+
pkt = &rbufp->recv_pkt;
hisversion = PKT_VERSION(pkt->li_vn_mode);
hisleap = PKT_LEAP(pkt->li_vn_mode);
sys_declined++;
return; /* no help */
}
- peer = newpeer(&rbufp->recv_srcadr, NULL, rbufp->dstadr,
+ peer = newpeer(&rbufp->recv_srcadr, NULL, rbufp->dstadr, -1,
MODE_CLIENT, hisversion, peer2->minpoll,
peer2->maxpoll, FLAG_PREEMPT |
(FLAG_IBURST & peer2->flags), MDF_UCAST |
* Do not execute the volley. Start out in
* broadcast client mode.
*/
- peer = newpeer(&rbufp->recv_srcadr, NULL,
- match_ep, MODE_BCLIENT, hisversion,
- pkt->ppoll, pkt->ppoll, FLAG_PREEMPT,
- MDF_BCLNT, 0, skeyid, sys_ident);
+ peer = newpeer(&rbufp->recv_srcadr, NULL, match_ep, -1,
+ MODE_BCLIENT, hisversion, pkt->ppoll, pkt->ppoll,
+ FLAG_PREEMPT, MDF_BCLNT, 0, skeyid, sys_ident);
if (NULL == peer) {
DPRINTF(2, ("receive: AM_NEWBCL drop: duplicate\n"));
sys_restricted++;
* packet, normally 6 (64 s) and that the poll interval
* is fixed at this value.
*/
- peer = newpeer(&rbufp->recv_srcadr, NULL, match_ep,
+ peer = newpeer(&rbufp->recv_srcadr, NULL, match_ep, -1,
MODE_CLIENT, hisversion, pkt->ppoll, pkt->ppoll,
FLAG_BC_VOL | FLAG_IBURST | FLAG_PREEMPT, MDF_BCLNT,
0, skeyid, sys_ident);
/*
* The message is correctly authenticated and allowed.
- * Mobilize a symmetric passive association.
+ * Mobilize a symmetric passive association, if we won't
+ * exceed the ippeerlimit.
*/
- if ((peer = newpeer(&rbufp->recv_srcadr, NULL,
- rbufp->dstadr, MODE_PASSIVE, hisversion, pkt->ppoll,
- NTP_MAXDPOLL, 0, MDF_UCAST, 0, skeyid,
- sys_ident)) == NULL) {
+ if ((peer = newpeer(&rbufp->recv_srcadr, NULL, rbufp->dstadr,
+ -1, MODE_PASSIVE, hisversion, pkt->ppoll,
+ NTP_MAXDPOLL, 0, MDF_UCAST, 0, skeyid,
+ sys_ident)) == NULL) {
DPRINTF(2, ("receive: AM_NEWPASS drop: newpeer() failed\n"));
sys_declined++;
return; /* ignore duplicate */
int rc;
struct interface * lcladr;
sockaddr_u * rmtadr;
+ r4addr r4a;
int restrict_mask;
struct peer * p;
l_fp xmt_tx;
} while (p != NULL && pool->ai != NULL);
if (p != NULL)
return; /* out of addresses, re-query DNS next poll */
- restrict_mask = restrictions(rmtadr);
+ restrictions(rmtadr, &r4a);
+ restrict_mask = r4a.rflags;
if (RES_FLAGS & restrict_mask)
restrict_source(rmtadr, 0,
current_time + POOL_SOLICIT_WINDOW + 1);
*
* - minpoll/maxpoll, but they are treated properly
* for all cases internally. Checking not necessary.
+ *
+ * Note that we ignore any previously-specified ippeerlimit.
+ * If we're told to create the peer, we create the peer.
*/
/* finally create the peer */
- if (peer_config(&peeraddr, NULL, NULL,
+ if (peer_config(&peeraddr, NULL, NULL, -1,
temp_cp.hmode, temp_cp.version, temp_cp.minpoll,
temp_cp.maxpoll, fl, temp_cp.ttl, temp_cp.keyid,
NULL) == 0)
/*
- * restrictions - return restrictions for this host
+ * restrictions - return restrictions for this host in *r4a
*/
-u_short
+void
restrictions(
- sockaddr_u *srcadr
+ sockaddr_u *srcadr,
+ r4addr *r4a
)
{
restrict_u *match;
struct in6_addr *pin6;
- u_short flags;
+
+ REQUIRE(NULL != r4a);
res_calls++;
- flags = 0;
+ r4a->rflags = RES_IGNORE;
+ r4a->ippeerlimit = 0;
+
/* IPv4 source address */
if (IS_IPV4(srcadr)) {
/*
* not later!)
*/
if (IN_CLASSD(SRCADR(srcadr)))
- return (int)RES_IGNORE;
+ return;
match = match_restrict4_addr(SRCADR(srcadr),
SRCPORT(srcadr));
res_not_found++;
else
res_found++;
- flags = match->flags;
+ r4a->rflags = match->flags;
+ r4a->ippeerlimit = match->ippeerlimit;
}
/* IPv6 source address */
* not later!)
*/
if (IN6_IS_ADDR_MULTICAST(pin6))
- return (int)RES_IGNORE;
+ return;
match = match_restrict6_addr(pin6, SRCPORT(srcadr));
INSIST(match != NULL);
res_not_found++;
else
res_found++;
- flags = match->flags;
+ r4a->rflags = match->flags;
+ r4a->ippeerlimit = match->ippeerlimit;
}
- return (flags);
+ return;
}
NULL,
loopback_interface,
MODE_CLIENT,
+ -1,
NTP_VERSION,
NTP_MINDPOLL,
NTP_MAXDPOLL,
{
sockaddr_u sockaddr = create_sockaddr_u(AF_INET,
54321, "63.161.169.137");
+ r4addr r4a;
- u_short retval = restrictions(&sockaddr);
+ restrictions(&sockaddr, &r4a);
- TEST_ASSERT_EQUAL(0, retval);
+ TEST_ASSERT_EQUAL(0, r4a.rflags);
}
*/
const u_short flags = 42;
+ r4addr r4a;
sockaddr_u resaddr = create_sockaddr_u(AF_INET,
54321, "0.0.0.0");
sockaddr_u sockaddr = create_sockaddr_u(AF_INET,
54321, "111.123.251.124");
- TEST_ASSERT_EQUAL(flags, restrictions(&sockaddr));
+ restrictions(&sockaddr, &r4a);
+ TEST_ASSERT_EQUAL(flags, r4a.rflags);
}
{
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");
+ r4addr r4a;
hack_restrict(RESTRICT_REMOVE, &resaddr, &resmask, -1, 0, 0, 0);
- TEST_ASSERT_EQUAL(0, restrictions(&resaddr));
+ restrictions(&resaddr, &r4a);
+ TEST_ASSERT_EQUAL(0, r4a.rflags);
}
{
sockaddr_u resaddr = create_sockaddr_u(AF_INET, 54321, "11.22.33.44");
sockaddr_u resmask = create_sockaddr_u(AF_INET, 54321, "128.0.0.0");
+ r4addr r4a;
const u_short flags = 42;
hack_restrict(RESTRICT_FLAGS, &resaddr, &resmask, -1, 0, flags, 0);
- TEST_ASSERT_EQUAL(flags, restrictions(&resaddr));
+ restrictions(&resaddr, &r4a);
+ TEST_ASSERT_EQUAL(flags, r4a.rflags);
}
/* it also matches, but we prefer the one above, as it's more specific */
sockaddr_u resaddr_second_match = create_sockaddr_u(AF_INET, 54321, "11.99.33.44");
sockaddr_u resmask_second_match = create_sockaddr_u(AF_INET, 54321, "255.0.0.0");
+ r4addr r4a;
hack_restrict(RESTRICT_FLAGS, &resaddr_not_matching, &resmask_not_matching, -1, 0, 11, 0);
hack_restrict(RESTRICT_FLAGS, &resaddr_best_match, &resmask_best_match, -1, 0, 22, 0);
hack_restrict(RESTRICT_FLAGS, &resaddr_second_match, &resmask_second_match, -1, 0, 128, 0);
- TEST_ASSERT_EQUAL(22, restrictions(&resaddr_target));
+ restrictions(&resaddr_target, &r4a);
+ TEST_ASSERT_EQUAL(22, r4a.rflags);
}
sockaddr_u resaddr_second_match = create_sockaddr_u(AF_INET, 54321, "11.99.33.44");
sockaddr_u resmask_second_match = create_sockaddr_u(AF_INET, 54321, "255.0.0.0");
+ r4addr r4a;
hack_restrict(RESTRICT_FLAGS, &resaddr_not_matching, &resmask_not_matching, -1, 0, 11, 0);
hack_restrict(RESTRICT_FLAGS, &resaddr_best_match, &resmask_best_match, -1, 0, 22, 0);
/* deleting the best match*/
hack_restrict(RESTRICT_REMOVE, &resaddr_best_match, &resmask_best_match, -1, 0, 22, 0);
- TEST_ASSERT_EQUAL(128, restrictions(&resaddr_target));
+ restrictions(&resaddr_target, &r4a);
+ TEST_ASSERT_EQUAL(128, r4a.rflags);
}
{
sockaddr_u resaddr = create_sockaddr_u(AF_INET, 54321, "11.22.30.20");
sockaddr_u resmask = create_sockaddr_u(AF_INET, 54321, "255.255.0.0");
+ r4addr r4a;
hack_restrict(RESTRICT_FLAGS, &resaddr, &resmask, -1, 0, 11, 0);
hack_restrict(RESTRICT_UNFLAG, &resaddr, &resmask, -1, 0, 10, 0);
- TEST_ASSERT_EQUAL(1, restrictions(&resaddr));
+ restrictions(&resaddr, &r4a);
+ TEST_ASSERT_EQUAL(1, r4a.rflags);
}