struct mon_data *mru_prev; /* previous structure in MRU list */
struct mon_data *fifo_next; /* next structure in FIFO list */
struct mon_data *fifo_prev; /* previous structure in FIFO list */
- u_long lastdrop; /* last time dropped due to RES_LIMIT*/
- u_long lasttime; /* last time data updated */
- u_long firsttime; /* time structure initialized */
- u_long count; /* count we have seen */
+ u_long drop_count; /* dropped due RESLIMIT*/
+ double avg_interval; /* average interpacket interval */
+ u_long lasttime; /* last packet received time */
+ u_long firsttime; /* first packet received time */
+ u_long count; /* total packet count */
struct sockaddr_storage rmtadr; /* address of remote host */
struct interface *interface; /* interface on which this arrived */
u_short rmtport; /* remote port last came from */
#define CONFIG_STATISTICS 21
#define CONFIG_PIDFILE 22
#define CONFIG_SETVAR 23
-#define CONFIG_CLIENTLIMIT 24
-#define CONFIG_CLIENTPERIOD 25
+#define CONFIG_DISCARD 24
+#define CONFIG_ADJ 25
#define CONFIG_MULTICASTCLIENT 26
#define CONFIG_ENABLE 27
#define CONFIG_DISABLE 28
#define CONFIG_INCLUDEFILE 36
#define CONFIG_KEYSDIR 37
#define CONFIG_CDELAY 38
-#define CONFIG_ADJ 39
#ifdef OPENSSL
-#define CONFIG_CRYPTO 40
+#define CONFIG_CRYPTO 39
#endif /* OPENSSL */
/*
#define CONF_PPS_CLEAR 2
#define CONF_PPS_HARDPPS 3
+/*
+ * "discard" modifier keywords
+ */
+#define CONF_DISCARD_AVERAGE 1
+#define CONF_DISCARD_MINIMUM 2
+
/*
* "tinker" modifier keywords
*/
u_int32 unknownversion; /* don't know version packets */
u_int32 badlength; /* packets with bad length */
u_int32 processed; /* packets processed */
- u_int32 badauth; /* packets dropped because of authorization */
- u_int32 wanderhold; /* (obsolete) */
- u_int32 limitrejected; /* rejected because of client limitation */
+ u_int32 badauth; /* packets dropped because of authorization */
+ u_int32 received; /* packets received */
+ u_int32 limitrejected; /* rate limited packets */
};
u_int32 unknownversion; /* don't know version packets */
u_int32 badlength; /* packets with bad length */
u_int32 processed; /* packets processed */
- u_int32 badauth; /* packets dropped because of authorization */
+ u_int32 badauth; /* packets dropped because of authorization */
u_int32 wanderhold;
};
extern u_long sys_processed; /* packets processed */
extern u_long sys_badauth; /* bad authentication */
extern u_long sys_limitrejected; /* rate limit exceeded */
+extern u_long sys_received; /* packets received */
/* ntp_refclock.c */
#ifdef REFCLOCK
/* ntp_restrict.c */
extern struct restrictlist *restrictlist; /* the ipv4 restriction list */
extern struct restrictlist6 *restrictlist6; /* the ipv6 restriction list */
-extern u_long client_limit;
-extern u_long client_limit_period;
+extern u_long res_min_interval;
+extern u_long res_avg_interval;
/* ntp_timer.c */
extern volatile int alarm_flag; /* alarm flag */
* privatekey file_name
* statsdir /var/NTP/
* filegen peerstats [ file peerstats ] [ type day ] [ link ]
- * clientlimit [ n ]
- * clientperiod [ 3600 ]
+ * police [ min n ] [ avg n ]
* trustedkey [ key ]
- * requestkey [ key]
+ * requestkey [ key ]
* controlkey [ key ]
* trap [ -4 | -6 ] [ addr ]
* fudge [ addr ] [ stratum ] [ refid ] ...
{ "broadcastclient", CONFIG_BROADCASTCLIENT },
{ "broadcastdelay", CONFIG_BDELAY },
{ "calldelay", CONFIG_CDELAY},
- { "clientlimit", CONFIG_CLIENTLIMIT },
- { "clientperiod", CONFIG_CLIENTPERIOD },
#ifdef OPENSSL
{ "crypto", CONFIG_CRYPTO },
#endif /* OPENSSL */
{ "peer", CONFIG_PEER },
{ "phone", CONFIG_PHONE },
{ "pidfile", CONFIG_PIDFILE },
+ { "discard", CONFIG_DISCARD },
{ "requestkey", CONFIG_REQUESTKEY },
{ "restrict", CONFIG_RESTRICT },
{ "revoke", CONFIG_REVOKE },
{ "", CONFIG_UNKNOWN }
};
+/*
+ * "discard" modifier keywords
+ */
+static struct keyword discard_keywords[] = {
+ { "average", CONF_DISCARD_AVERAGE },
+ { "minimum", CONF_DISCARD_MINIMUM },
+ { "", CONFIG_UNKNOWN }
+};
+
/*
* "tinker" modifier keywords
*/
if (ntokens >= 2)
sys_automax = 1 << max(atoi(tokens[1]), 10);
break;
-
+
+ case CONFIG_DISCARD:
+ for (i = 1; i < ntokens; i++) {
+ int temp;
+
+ temp = matchkey(tokens[i++],
+ discard_keywords, 1);
+ if (i > ntokens - 1) {
+ msyslog(LOG_ERR,
+ "discard: missing argument");
+ errflg++;
+ break;
+ }
+ switch(temp) {
+ case CONF_DISCARD_AVERAGE:
+ res_avg_interval = atoi(tokens[i++]);
+ break;
+
+ case CONF_DISCARD_MINIMUM:
+ res_min_interval = atoi(tokens[i++]);
+ break;
+ default:
+ msyslog(LOG_ERR,
+ "discard: unknown keyword");
+ break;
+ }
+ }
+ break;
+
case CONFIG_CRYPTO:
if (ntokens == 1) {
crypto_config(CRYPTO_CONF_NONE, NULL);
for (i = 1; i < ntokens; i++) {
int temp;
- temp = matchkey(tokens[i++], crypto_keywords, 1);
+ temp = matchkey(tokens[i++],
+ crypto_keywords, 1);
if (i > ntokens - 1) {
msyslog(LOG_ERR,
"crypto: missing argument");
switch(temp) {
case CONF_CRYPTO_CERT:
- crypto_config(CRYPTO_CONF_CERT, tokens[i]);
+ crypto_config(CRYPTO_CONF_CERT,
+ tokens[i]);
break;
case CONF_CRYPTO_RSA:
- crypto_config(CRYPTO_CONF_PRIV, tokens[i]);
+ crypto_config(CRYPTO_CONF_PRIV,
+ tokens[i]);
break;
case CONF_CRYPTO_IFFPAR:
- crypto_config(CRYPTO_CONF_IFFPAR, tokens[i]);
+ crypto_config(CRYPTO_CONF_IFFPAR,
+ tokens[i]);
break;
case CONF_CRYPTO_GQPAR:
- crypto_config(CRYPTO_CONF_GQPAR, tokens[i]);
+ crypto_config(CRYPTO_CONF_GQPAR,
+ tokens[i]);
break;
case CONF_CRYPTO_MVPAR:
- crypto_config(CRYPTO_CONF_MVPAR, tokens[i]);
+ crypto_config(CRYPTO_CONF_MVPAR,
+ tokens[i]);
break;
case CONF_CRYPTO_LEAP:
- crypto_config(CRYPTO_CONF_LEAP, tokens[i]);
+ crypto_config(CRYPTO_CONF_LEAP,
+ tokens[i]);
break;
case CONF_CRYPTO_PW:
- crypto_config(CRYPTO_CONF_PW, tokens[i]);
+ crypto_config(CRYPTO_CONF_PW,
+ tokens[i]);
break;
case CONF_CRYPTO_RAND:
- crypto_config(CRYPTO_CONF_RAND, tokens[i]);
+ crypto_config(CRYPTO_CONF_RAND,
+ tokens[i]);
break;
case CONF_CRYPTO_SIGN:
- crypto_config(CRYPTO_CONF_SIGN, tokens[i]);
+ crypto_config(CRYPTO_CONF_SIGN,
+ tokens[i]);
break;
default:
- msyslog(LOG_ERR, "crypto: unknown keyword");
+ msyslog(LOG_ERR,
+ "crypto: unknown keyword");
break;
}
}
}
break;
- case CONFIG_CLIENTLIMIT:
- if (ntokens < 2) {
- msyslog(LOG_ERR,
- "no value for clientlimit command - line ignored");
- } else {
- u_long ui;
-
- if (!atouint(tokens[1], &ui)) {
- msyslog(LOG_ERR,
- "illegal value for clientlimit command - line ignored");
- } else {
- char bp[80];
-
-#ifdef DEBUG
- if (debug)
- sprintf(bp, "client_limit=%lu", ui);
-#endif
- set_sys_var(bp, strlen(bp)+1, RO);
- client_limit = ui;
- }
- }
- break;
-
- case CONFIG_CLIENTPERIOD:
- if (ntokens < 2) {
- msyslog(LOG_ERR,
- "no value for clientperiod command - line ignored");
- } else {
- u_long ui;
-
- if (!atouint(tokens[1], &ui)) {
- msyslog(LOG_ERR,
- "illegal value for clientperiod command - line ignored");
- } else {
- char bp[80];
-
- sprintf(bp, "client_limit_period=%ld", ui);
- set_sys_var(bp, strlen(bp)+1, RO);
- client_limit_period = ui;
- }
- }
- break;
-
case CONFIG_ENABLE:
for (i = 1; i < ntokens; i++) {
int flag;
/*
* ntp_monitor.c - monitor who is using the ntpd server
*/
-
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
*
* trimmed back memory consumption ... jdg 8/94
*/
-
/*
* Limits on the number of structures allocated. This limit is picked
* with the illicit knowlege that we can only return somewhat less
#ifndef MONMEMINC
#define MONMEMINC 40 /* allocate them 40 at a time */
#endif
+#define MONAVG 8. /* interpacket averaging factor */
/*
* Hashing stuff
*/
static struct mon_data *mon_hash[MON_HASH_SIZE]; /* list ptrs */
struct mon_data mon_mru_list;
-struct mon_data mon_fifo_list;
+
/*
* List of free structures structures, and counters of free and total
* structures. The free structures are linked with the hash_next field.
static struct mon_data *mon_free; /* free list or null if none */
static int mon_total_mem; /* total structures allocated */
static int mon_mem_increments; /* times called malloc() */
-static u_long mon_thresh = .5; /* MRU overflow call gap */
/*
* Initialization state. We may be monitoring, we may not. If
mon_total_mem = 0;
mon_mem_increments = 0;
mon_free = NULL;
- memset((char *)&mon_hash[0], 0, sizeof mon_hash);
- memset((char *)&mon_mru_list, 0, sizeof mon_mru_list);
- memset((char *)&mon_fifo_list, 0, sizeof mon_fifo_list);
+ memset(&mon_hash[0], 0, sizeof mon_hash);
+ memset(&mon_mru_list, 0, sizeof mon_mru_list);
}
mon_mru_list.mru_next = &mon_mru_list;
mon_mru_list.mru_prev = &mon_mru_list;
- mon_fifo_list.fifo_next = &mon_fifo_list;
- mon_fifo_list.fifo_prev = &mon_fifo_list;
mon_enabled = mode;
}
mon_mru_list.mru_next = &mon_mru_list;
mon_mru_list.mru_prev = &mon_mru_list;
-
- mon_fifo_list.fifo_next = &mon_fifo_list;
- mon_fifo_list.fifo_prev = &mon_fifo_list;
}
if (mon_enabled == MON_OFF)
return;
- /*
- * For the really busy servers, we need to call-gap the packet
- * flow. So, if the MRU list fills up we need to start dropping
- * some packets.
- */
- if (mon_total_mem >= MAXMONMEM && (RANDOM & 0xffffffff) / FRAC >
- mon_thresh)
- return;
-
pkt = &rbufp->recv_pkt;
memset(&addr, 0, sizeof(addr));
memcpy(&addr, &(rbufp->recv_srcadr),
sizeof(rbufp->recv_srcadr));
hash = MON_HASH(&addr);
mode = PKT_MODE(pkt->li_vn_mode);
-
md = mon_hash[hash];
while (md != NULL) {
- if(SOCKCMP(&md->rmtadr, &addr) &&
- md->mode == (u_char)mode) {
+
+ /*
+ * Match address only to conserve MRU size.
+ */
+ if (SOCKCMP(&md->rmtadr, &addr)) {
+ if (md->lasttime == md->firsttime)
+ md->avg_interval = current_time -
+ md->lasttime;
+ else
+ md->avg_interval += ((current_time -
+ md->lasttime) - md->avg_interval) /
+ MONAVG;
md->lasttime = current_time;
md->count++;
- md->version = PKT_VERSION(pkt->li_vn_mode);
md->rmtport = NSRCPORT(&rbufp->recv_srcadr);
+ md->mode = (u_char) mode;
+ md->version = PKT_VERSION(pkt->li_vn_mode);
/*
- * Shuffle him to the head of the mru list.
- * What a crock.
+ * Shuffle to the head of the MRU list.
*/
md->mru_next->mru_prev = md->mru_prev;
md->mru_prev->mru_next = md->mru_next;
* or from the tail of the MRU list.
*/
if (mon_free == NULL && mon_total_mem >= MAXMONMEM) {
+
/*
- * Get it from MRU list
+ * Get it from MRU list.
*/
md = mon_mru_list.mru_prev;
md->mru_prev->mru_next = &mon_mru_list;
mon_mru_list.mru_prev = md->mru_prev;
-
remove_from_hash(md);
-
- /*
- * Get it from FIFO list
- */
- md->fifo_prev->fifo_next = md->fifo_next;
- md->fifo_next->fifo_prev = md->fifo_prev;
-
} else {
- if (mon_free == NULL) /* if free list empty */
- mon_getmoremem(); /* then get more */
+ if (mon_free == NULL)
+ mon_getmoremem();
md = mon_free;
mon_free = md->hash_next;
}
/*
* Got one, initialize it
*/
+ md->avg_interval = 0;
md->lasttime = md->firsttime = current_time;
- md->lastdrop = 0;
md->count = 1;
+ md->drop_count = 0;
memset(&md->rmtadr, 0, sizeof(md->rmtadr));
memcpy(&md->rmtadr, &addr, sizeof(addr));
md->rmtport = NSRCPORT(&rbufp->recv_srcadr);
/*
* Drop him into front of the hash table. Also put him on top of
- * the MRU list and at bottom of THE FIFO list.
+ * the MRU list.
*/
md->hash_next = mon_hash[hash];
mon_hash[hash] = md;
-
md->mru_next = mon_mru_list.mru_next;
md->mru_prev = &mon_mru_list;
mon_mru_list.mru_next->mru_prev = md;
mon_mru_list.mru_next = md;
-
- md->fifo_prev = mon_fifo_list.fifo_prev;
- md->fifo_next = &mon_fifo_list;
- mon_fifo_list.fifo_prev->fifo_next = md;
- mon_fifo_list.fifo_prev = md;
}
sizeof(struct mon_data));
freedata = mon_free;
mon_free = md;
-
for (i = 0; i < (MONMEMINC-1); i++) {
md->hash_next = (md + 1);
md++;
* md now points at the last. Link in the rest of the chain.
*/
md->hash_next = freedata;
-
mon_total_mem += MONMEMINC;
mon_mem_increments++;
}
u_long sys_badlength; /* bad length or mode */
u_long sys_badauth; /* bad authentication */
u_long sys_processed; /* packets processed */
+u_long sys_received; /* packets received */
static double root_distance P((struct peer *));
static double clock_combine P((struct peer **, int));
* simply discarded without prejudice. Some restrictions have to
* be handled later in order to generate a kiss-of-death packet.
*/
+ /*
+ * Bogus port check is before anything, since it probably
+ * reveals a clogging attack.
+ */
+ sys_received++;
+ if (SRCPORT(&rbufp->recv_srcadr) == 0) {
+ sys_badlength++;
+ return; /* bogus port */
+ }
ntp_monitor(rbufp);
restrict_mask = restrictions(&rbufp->recv_srcadr);
#ifdef DEBUG
return; /* runt packet */
}
-
/*
* Version check must be after the query packets, since they
* intentionally use early version.
sys_newversionpkt++; /* new version */
} else if (!(restrict_mask & RES_VERSION) &&
PKT_VERSION(pkt->li_vn_mode) >= NTP_OLDVERSION) {
- sys_oldversionpkt++; /* old version */
+ sys_oldversionpkt++; /* previous version */
} else {
sys_unknownversion++;
- return; /* invalid version */
+ return; /* old version */
}
/*
* Figure out his mode and validate the packet. This has some
- * legacy raunch that probably should be removed. If from NTPv1
- * mode zero, The NTPv4 mode is determined from the source port.
- * If the port number is zero, it is from a symmetric active
- * association, which is not supported in NTPv4. Otherwise, it
- * is from a client association and we fake it.
+ * legacy raunch that probably should be removed. In very early
+ * NTP versions mode 0 was equivalent to what later versions
+ * would interpret as client mode.
*/
if (hismode == MODE_UNSPEC) {
if (PKT_VERSION(pkt->li_vn_mode) == NTP_OLDVERSION) {
proto_clr_stats(void)
{
sys_stattime = current_time;
+ sys_received = 0;
sys_restricted = 0;
sys_limitrejected = 0;
sys_newversionpkt = 0;
/*
* Importations from the protocol module
*/
-/*
- extern u_long sys_stattime;
- extern u_long sys_oldversionpkt;
- extern u_long sys_newversionpkt;
- extern u_long sys_unknownversion;
- extern u_long sys_badlength;
- extern u_long sys_badauth;
- extern u_long sys_processed;
- extern u_long sys_restricted;
- extern u_long sys_limitrejected;
-*/
ss = (struct info_sys_stats *)prepare_pkt(srcadr, inter, inpkt,
- sizeof(struct info_sys_stats));
-
+ sizeof(struct info_sys_stats));
ss->timeup = htonl((u_int32)current_time);
ss->timereset = htonl((u_int32)(current_time - sys_stattime));
ss->badstratum = htonl((u_int32)sys_restricted);
ss->processed = htonl((u_int32)sys_processed);
ss->badauth = htonl((u_int32)sys_badauth);
ss->limitrejected = htonl((u_int32)sys_limitrejected);
+ ss->received = htonl((u_int32)sys_received);
(void) more_pkt();
flush_pkt();
}
sizeof(struct info_monitor) - offset);
for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0;
md = md->mru_next) {
- im->lasttime = htonl((u_int32)(current_time - md->lasttime));
+ im->lasttime = htonl((u_int32)md->avg_interval);
im->firsttime = htonl((u_int32)(current_time - md->firsttime));
- if (md->lastdrop)
- im->lastdrop = htonl((u_int32)(current_time - md->lastdrop));
- else
- im->lastdrop = 0;
+ im->lastdrop = htonl((u_int32)md->drop_count);
im->count = htonl((u_int32)(md->count));
if (md->rmtadr.ss_family == AF_INET6) {
if (!client_v6_capable)
sizeof(struct info_monitor_1) - offset);
for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0;
md = md->mru_next) {
- im->lasttime = htonl((u_int32)(current_time - md->lasttime));
+ im->lasttime = htonl((u_int32)md->avg_interval);
im->firsttime = htonl((u_int32)(current_time - md->firsttime));
- if (md->lastdrop)
- im->lastdrop = htonl((u_int32)(current_time - md->lastdrop));
- else
- im->lastdrop = 0;
+ im->lastdrop = htonl((u_int32)md->drop_count);
im->count = htonl((u_int32)md->count);
if (md->rmtadr.ss_family == AF_INET6) {
if (!client_v6_capable)
/*
- * ntp_restrict.c - find out what restrictions this host is running under
+ * ntp_restrict.c - determine host restrictions
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
/*
* We will use two lists, one for IPv4 addresses and one for IPv6
* addresses. This is not protocol-independant but for now I can't
- * find way to respect this. We'll check this later... JFB 07/2001
+ * find a way to respect this. We'll check this later... JFB 07/2001
*/
#define SET_IPV6_ADDR_MASK(dst, src, msk) \
do { \
static u_long res_calls;
static u_long res_found;
static u_long res_not_found;
-/* static u_long res_timereset; */
/*
* Parameters of the RES_LIMITED restriction option.
- * client_limit is the number of hosts allowed per source net
- * client_limit_period is the number of seconds after which an entry
- * is no longer considered for client limit determination
*/
-u_long client_limit;
-u_long client_limit_period;
+u_long res_avg_interval = 6; /* min average interpacket interval */
+u_long res_min_interval = 1; /* min interpacket interval */
+
/*
* Count number of restriction entries referring to RES_LIMITED controls
* activation/deactivation of monitoring (with respect to RES_LIMITED
init_restrict(void)
{
register int i;
- char bp[80];
/*
* Zero the list and put all but one on the free list
memset((char *)resinit, 0, sizeof resinit);
resfree6 = 0;
memset((char *)resinit6, 0, sizeof resinit6);
-
for (i = 1; i < INITRESLIST; i++) {
resinit[i].next = resfree;
resinit6[i].next = resfree6;
resfree = &resinit[i];
resfree6 = &resinit6[i];
}
-
numresfree = INITRESLIST-1;
numresfree6 = INITRESLIST-1;
/*
- * Put the remaining item at the head of the
- * list as our default entry. Everything in here
- * should be zero for now.
+ * Put the remaining item at the head of the list as our default
+ * entry. Everything in here should be zero for now.
*/
resinit[0].addr = htonl(INADDR_ANY);
resinit[0].mask = 0;
res_calls = 0;
res_found = 0;
res_not_found = 0;
- /* res_timereset = 0; */
/*
* set default values for RES_LIMIT functionality
*/
- client_limit = 10;
- client_limit_period = 60;
res_limited_refcnt = 0;
res_limited_refcnt6 = 0;
-
- sprintf(bp, "client_limit=%ld", client_limit);
- set_sys_var(bp, strlen(bp) + 1, RO);
- sprintf(bp, "client_limit_period=%ld", client_limit_period);
- set_sys_var(bp, strlen(bp) + 1, RO);
}
struct restrictlist *match = NULL;
struct restrictlist6 *rl6;
struct restrictlist6 *match6 = NULL;
- int flags = 0;
- u_int32 hostaddr;
struct in6_addr hostaddr6;
struct in6_addr hostservaddr6;
-
- int isntpport;
- struct sockaddr_storage *netsrcaddr;
- struct sockaddr_storage *mdnet;
+ u_int32 hostaddr;
+ int flags = 0;
+ int isntpport;
res_calls++;
-
- netsrcaddr = netof(srcadr);
-
- /* IPv4 source address */
if (srcadr->ss_family == AF_INET) {
/*
* We need the host address in host order. Also need to
* Work our way down from there.
*/
match = restrictlist;
-
for (rl = match->next; rl != 0 && rl->addr <= hostaddr;
rl = rl->next)
if ((hostaddr & rl->mask) == rl->addr) {
continue;
match = rl;
}
-
match->count++;
if (match == restrictlist)
res_not_found++;
}
/*
- * The following implements limiting the number of clients
- * accepted from a given network. The notion of "same network"
- * is determined by the mask and addr fields of the restrict
- * list entry. The monitor mechanism has to be enabled for
- * collecting info on current clients.
- *
- * The policy is as follows:
- * - take the list of clients recorded
- * from the given "network" seen within the last
- * client_limit_period seconds
- * - if there are at most client_limit entries:
- * --> access allowed
- * - otherwise sort by time first seen
- * - current client among the first client_limit seen
- * hosts?
- * if yes: access allowed
- * else: eccess denied
+ * The following implements a generalized call gap facility.
+ * Douse the RES_LIMITED bit only if the interval since the last
+ * packet is greater than res_min_interval and the average is
+ * greater thatn res_avg_interval.
*/
- if (flags & RES_LIMITED) {
- int lcnt;
- struct mon_data *md, *this_client;
-
-#ifdef DEBUG
- if (debug > 2)
- printf("limited clients check: %ld clients, period %ld seconds, net is %s\n",
- client_limit, client_limit_period,
- stoa(netsrcaddr));
-#endif /*DEBUG*/
- if (mon_enabled == MON_OFF) {
-#ifdef DEBUG
- if (debug > 4)
- printf("no limit - monitoring is off\n");
-#endif
- return (int)(match->flags & ~RES_LIMITED);
- }
+ if (mon_enabled == MON_OFF) {
+ flags &= ~RES_LIMITED;
+ } else {
+ struct mon_data *md;
/*
- * How nice, MRU list provides our current client as the
- * first entry in the list. Monitoring was verified to
- * be active above, thus we know an entry for our client
- * must exist, or some brain dead set the memory limit
- * for mon entries to ZERO!!!
+ * At this poin the most recent arrival is first in the
+ * MRU list. Let the first 10 packets in for free until
+ * the average stabilizes.
*/
- this_client = mon_mru_list.mru_next;
-
- for (md = mon_fifo_list.fifo_next,lcnt = 0;
- md != &mon_fifo_list;
- md = md->fifo_next) {
- mdnet = netof(&(md->rmtadr));
- if ((current_time - md->lasttime)
- > client_limit_period) {
-#ifdef DEBUG
- if (debug > 5)
- printf("checking: %s: ignore: too old: %ld\n",
- stoa(&(md->rmtadr)),
- current_time - md->lasttime);
-#endif
- continue;
- }
- if (md->mode == MODE_BROADCAST ||
- md->mode == MODE_CONTROL ||
- md->mode == MODE_PRIVATE) {
-#ifdef DEBUG
- if (debug > 5)
- printf("checking: %s: ignore mode %d\n",
- stoa(&(md->rmtadr)),
- md->mode);
-#endif
- continue;
- }
- if (!SOCKCMP(mdnet, &netsrcaddr)) {
-#ifdef DEBUG
- if (debug > 5) {
- printf("checking: %s: different net %s\n",
- stoa(&(md->rmtadr)),
- stoa(mdnet));
- }
-#endif
- continue;
- }
- lcnt++;
- if (lcnt > (int) client_limit ||
- SOCKCMP(&(md->rmtadr), srcadr)) {
-#ifdef DEBUG
- if (debug > 5)
- printf("considering %s: found host\n",
- stoa(&(md->rmtadr)));
-#endif
- break;
- }
-#ifdef DEBUG
- else {
- if (debug > 5)
- printf("considering %s: same net\n",
- stoa(&(md->rmtadr)));
- }
-#endif
- } /* for */
-#ifdef DEBUG
- if (debug > 4)
- printf("this one is rank %d in list, limit is %lu: %s\n",
- lcnt, client_limit,
- (lcnt <= (int) client_limit) ? "ALLOW" : "REJECT");
-#endif
- if (lcnt <= (int) client_limit) {
- this_client->lastdrop = 0;
- if (srcadr->ss_family == AF_INET)
- return (int)(match->flags & ~RES_LIMITED);
- else
- return (int)(match6->flags & ~RES_LIMITED);
-
- } else {
- this_client->lastdrop = current_time;
- }
+ md = mon_mru_list.mru_next;
+ if (md->count < 10 && current_time - md->lasttime >
+ res_min_interval && md->avg_interval >
+ res_avg_interval)
+ flags &= ~RES_LIMITED;
+ md->drop_count = flags;
}
- return flags;
+ return (flags);
}
checkitemsize(itemsize, sizeof(struct info_sys_stats));
return;
}
-
- (void) fprintf(fp, "system uptime: %ld\n",
- (u_long)ntohl(ss->timeup));
- (void) fprintf(fp, "time since reset: %ld\n",
- (u_long)ntohl(ss->timereset));
- (void) fprintf(fp, "packets restricted: %ld\n",
- (u_long)ntohl(ss->badstratum));
- (void) fprintf(fp, "old version packets: %ld\n",
- (u_long)ntohl(ss->oldversionpkt));
- (void) fprintf(fp, "new version packets: %ld\n",
- (u_long)ntohl(ss->newversionpkt));
- (void) fprintf(fp, "unknown version number: %ld\n",
- (u_long)ntohl(ss->unknownversion));
- (void) fprintf(fp, "bad packet format: %ld\n",
- (u_long)ntohl(ss->badlength));
- (void) fprintf(fp, "packets processed: %ld\n",
- (u_long)ntohl(ss->processed));
- (void) fprintf(fp, "bad authentication: %ld\n",
- (u_long)ntohl(ss->badauth));
+ fprintf(fp, "system uptime: %ld\n",
+ (u_long)ntohl(ss->timeup));
+ fprintf(fp, "time since reset: %ld\n",
+ (u_long)ntohl(ss->timereset));
+ fprintf(fp, "packets received: %ld\n",
+ (u_long)ntohl(ss->received));
+ fprintf(fp, "packets restricted: %ld\n",
+ (u_long)ntohl(ss->badstratum));
+ fprintf(fp, "old version packets: %ld\n",
+ (u_long)ntohl(ss->oldversionpkt));
+ fprintf(fp, "new version packets: %ld\n",
+ (u_long)ntohl(ss->newversionpkt));
+ fprintf(fp, "unknown version number: %ld\n",
+ (u_long)ntohl(ss->unknownversion));
+ fprintf(fp, "bad packet format: %ld\n",
+ (u_long)ntohl(ss->badlength));
+ fprintf(fp, "packets processed: %ld\n",
+ (u_long)ntohl(ss->processed));
+ fprintf(fp, "bad authentication: %ld\n",
+ (u_long)ntohl(ss->badauth));
if (itemsize != sizeof(struct info_sys_stats))
return;
- (void) fprintf(fp, "packets limited: %ld\n",
- (u_long)ntohl(ss->limitrejected));
+ fprintf(fp, "packets limited: %ld\n",
+ (u_long)ntohl(ss->limitrejected));
}
struct info_monitor_1 *ml = (struct info_monitor_1 *) struct_star;
(void) fprintf(fp,
- "remote address port local address count m ver drop last first\n");
+ "remote address port local address count m ver code avglen first\n");
(void) fprintf(fp,
"===============================================================================\n");
while (items > 0) {
((pcmd->argval->ival == 6) && (ml->v6_flag != 0)) ||
((pcmd->argval->ival == 4) && (ml->v6_flag == 0)))
(void) fprintf(fp,
- "%-22.22s %5d %-15s %8ld %1d %1d %6lu %6lu %7lu\n",
+ "%-22.22s %5d %-15s %8ld %1d %1d %6lx %6lu %7lu\n",
nntohost(&addr),
ntohs(ml->port),
stoa(&dstadr),
struct info_monitor *ml = (struct info_monitor *) struct_star;
(void) fprintf(fp,
- " address port count mode ver lastdrop lasttime firsttime\n");
+ " address port count mode ver code avglen first\n");
(void) fprintf(fp,
"===============================================================================\n");
while (items > 0) {
((pcmd->argval->ival == 6) && (ml->v6_flag != 0)) ||
((pcmd->argval->ival == 4) && (ml->v6_flag == 0)))
(void) fprintf(fp,
- "%-25.25s %5d %9ld %4d %2d %9lu %9lu %9lu\n",
+ "%-25.25s %5d %9ld %4d %2d %9lx %9lu %9lu\n",
nntohost(&dstadr),
ntohs(ml->port),
(u_long)ntohl(ml->count),