From: Harlan Stenn Date: Thu, 6 Feb 2003 07:41:35 +0000 (-0500) Subject: Call gap stuff from Dave Mills X-Git-Tag: NTP_4_1_74~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7627b05d8aae30c8f8c0b95052f3fe68211fcdc1;p=thirdparty%2Fntp.git Call gap stuff from Dave Mills bk: 3e4211afdAH-I1IFr3uAzWWQUyxJMQ --- diff --git a/include/ntp.h b/include/ntp.h index 99c9aaacce..9e04b024a6 100644 --- a/include/ntp.h +++ b/include/ntp.h @@ -747,10 +747,11 @@ struct mon_data { 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 */ diff --git a/include/ntp_config.h b/include/ntp_config.h index 59e8407ce5..e9e55eae67 100644 --- a/include/ntp_config.h +++ b/include/ntp_config.h @@ -42,8 +42,8 @@ #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 @@ -57,9 +57,8 @@ #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 */ /* @@ -129,6 +128,12 @@ #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 */ diff --git a/include/ntp_request.h b/include/ntp_request.h index 6fa831cdeb..7299c090f0 100644 --- a/include/ntp_request.h +++ b/include/ntp_request.h @@ -482,9 +482,9 @@ struct info_sys_stats { 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 */ }; @@ -500,7 +500,7 @@ struct old_info_sys_stats { 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; }; diff --git a/include/ntpd.h b/include/ntpd.h index 05b0276130..50ffcd3cdd 100644 --- a/include/ntpd.h +++ b/include/ntpd.h @@ -384,6 +384,7 @@ extern u_long sys_badlength; /* bad length or format */ 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 @@ -398,8 +399,8 @@ extern keyid_t info_auth_keyid; /* keyid used to authenticate requests */ /* 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 */ diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index 544ba77732..52ea24da4b 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -68,10 +68,9 @@ extern int priority_done; * 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 ] ... @@ -105,8 +104,6 @@ static struct keyword keywords[] = { { "broadcastclient", CONFIG_BROADCASTCLIENT }, { "broadcastdelay", CONFIG_BDELAY }, { "calldelay", CONFIG_CDELAY}, - { "clientlimit", CONFIG_CLIENTLIMIT }, - { "clientperiod", CONFIG_CLIENTPERIOD }, #ifdef OPENSSL { "crypto", CONFIG_CRYPTO }, #endif /* OPENSSL */ @@ -127,6 +124,7 @@ static struct keyword keywords[] = { { "peer", CONFIG_PEER }, { "phone", CONFIG_PHONE }, { "pidfile", CONFIG_PIDFILE }, + { "discard", CONFIG_DISCARD }, { "requestkey", CONFIG_REQUESTKEY }, { "restrict", CONFIG_RESTRICT }, { "revoke", CONFIG_REVOKE }, @@ -248,6 +246,15 @@ static struct keyword flags_keywords[] = { { "", CONFIG_UNKNOWN } }; +/* + * "discard" modifier keywords + */ +static struct keyword discard_keywords[] = { + { "average", CONF_DISCARD_AVERAGE }, + { "minimum", CONF_DISCARD_MINIMUM }, + { "", CONFIG_UNKNOWN } +}; + /* * "tinker" modifier keywords */ @@ -1111,7 +1118,35 @@ getconfig( 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); @@ -1120,7 +1155,8 @@ getconfig( 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"); @@ -1130,43 +1166,53 @@ getconfig( 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; } } @@ -1695,49 +1741,6 @@ getconfig( } 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; diff --git a/ntpd/ntp_monitor.c b/ntpd/ntp_monitor.c index f6dd15910a..8766c85ae9 100644 --- a/ntpd/ntp_monitor.c +++ b/ntpd/ntp_monitor.c @@ -1,7 +1,6 @@ /* * ntp_monitor.c - monitor who is using the ntpd server */ - #ifdef HAVE_CONFIG_H # include #endif @@ -41,7 +40,6 @@ * * 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 @@ -56,6 +54,7 @@ #ifndef MONMEMINC #define MONMEMINC 40 /* allocate them 40 at a time */ #endif +#define MONAVG 8. /* interpacket averaging factor */ /* * Hashing stuff @@ -71,7 +70,7 @@ */ 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. @@ -79,7 +78,6 @@ struct mon_data mon_fifo_list; 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 @@ -106,9 +104,8 @@ init_mon(void) 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); } @@ -138,8 +135,6 @@ mon_start( 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; } @@ -180,9 +175,6 @@ mon_stop( 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; } @@ -203,34 +195,34 @@ ntp_monitor( 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; @@ -249,24 +241,17 @@ ntp_monitor( * 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; } @@ -274,9 +259,10 @@ ntp_monitor( /* * 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); @@ -289,20 +275,14 @@ ntp_monitor( /* * 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; } @@ -320,7 +300,6 @@ mon_getmoremem(void) sizeof(struct mon_data)); freedata = mon_free; mon_free = md; - for (i = 0; i < (MONMEMINC-1); i++) { md->hash_next = (md + 1); md++; @@ -330,7 +309,6 @@ mon_getmoremem(void) * md now points at the last. Link in the rest of the chain. */ md->hash_next = freedata; - mon_total_mem += MONMEMINC; mon_mem_increments++; } diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c index 22fde0bcc7..fce3cc8831 100644 --- a/ntpd/ntp_proto.c +++ b/ntpd/ntp_proto.c @@ -85,6 +85,7 @@ u_long sys_unknownversion; /* invalid version */ 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)); @@ -329,6 +330,15 @@ receive( * 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 @@ -369,7 +379,6 @@ receive( return; /* runt packet */ } - /* * Version check must be after the query packets, since they * intentionally use early version. @@ -378,19 +387,17 @@ receive( 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) { @@ -3125,6 +3132,7 @@ void proto_clr_stats(void) { sys_stattime = current_time; + sys_received = 0; sys_restricted = 0; sys_limitrejected = 0; sys_newversionpkt = 0; diff --git a/ntpd/ntp_request.c b/ntpd/ntp_request.c index bfd38292fc..183c044da3 100644 --- a/ntpd/ntp_request.c +++ b/ntpd/ntp_request.c @@ -1111,20 +1111,8 @@ sys_stats( /* * 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); @@ -1135,6 +1123,7 @@ sys_stats( 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(); } @@ -1878,12 +1867,9 @@ mon_getlist_0( 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) @@ -1935,12 +1921,9 @@ mon_getlist_1( 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) diff --git a/ntpd/ntp_restrict.c b/ntpd/ntp_restrict.c index bc65a436b1..7a0059c92d 100644 --- a/ntpd/ntp_restrict.c +++ b/ntpd/ntp_restrict.c @@ -1,5 +1,5 @@ /* - * ntp_restrict.c - find out what restrictions this host is running under + * ntp_restrict.c - determine host restrictions */ #ifdef HAVE_CONFIG_H #include @@ -39,7 +39,7 @@ /* * 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 { \ @@ -78,16 +78,13 @@ static int numresfree6; /* number of structures on free list 2 */ 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 @@ -109,7 +106,6 @@ void init_restrict(void) { register int i; - char bp[80]; /* * Zero the list and put all but one on the free list @@ -118,21 +114,18 @@ init_restrict(void) 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; @@ -149,20 +142,12 @@ init_restrict(void) 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); } @@ -178,20 +163,13 @@ restrictions( 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 @@ -213,7 +191,6 @@ restrictions( * 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) { @@ -222,7 +199,6 @@ restrictions( continue; match = rl; } - match->count++; if (match == restrictlist) res_not_found++; @@ -277,122 +253,29 @@ restrictions( } /* - * 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); } diff --git a/ntpdc/ntpdc_ops.c b/ntpdc/ntpdc_ops.c index 037c7ce59a..07bd5afd03 100644 --- a/ntpdc/ntpdc_ops.c +++ b/ntpdc/ntpdc_ops.c @@ -1019,30 +1019,31 @@ again: 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)); } @@ -1911,7 +1912,7 @@ again: 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) { @@ -1936,7 +1937,7 @@ again: ((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), @@ -1954,7 +1955,7 @@ again: 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) { @@ -1973,7 +1974,7 @@ again: ((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),