]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
Call gap stuff from Dave Mills
authorHarlan Stenn <stenn@ntp.org>
Thu, 6 Feb 2003 07:41:35 +0000 (02:41 -0500)
committerHarlan Stenn <stenn@ntp.org>
Thu, 6 Feb 2003 07:41:35 +0000 (02:41 -0500)
bk: 3e4211afdAH-I1IFr3uAzWWQUyxJMQ

include/ntp.h
include/ntp_config.h
include/ntp_request.h
include/ntpd.h
ntpd/ntp_config.c
ntpd/ntp_monitor.c
ntpd/ntp_proto.c
ntpd/ntp_request.c
ntpd/ntp_restrict.c
ntpdc/ntpdc_ops.c

index 99c9aaacce9fdb2b91ce0afda050927a474b2e1b..9e04b024a6c95fe5a0bccaa1aaacd0b10c59c669 100644 (file)
@@ -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 */
index 59e8407ce5a0d630d15c324b9f8814fd93ccd2a8..e9e55eae673c7ec359444ec3fc9771349f6d58ce 100644 (file)
@@ -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 */
 
 /*
 #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
  */
index 6fa831cdeb49fcdca81ba3f3176b93d0adb7e59d..7299c090f0707cc540c91559be8811233c58f1ea 100644 (file)
@@ -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;
 };
 
index 05b0276130816531a6c6709b9df72a1218796d60..50ffcd3cdddcf8bd318f8e7c60da14b6be94b79e 100644 (file)
@@ -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 */
index 544ba77732550c76b5f833912533306e2a07d0c3..52ea24da4b333b746c80210c9f48cbcc06aa61ec 100644 (file)
@@ -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;
index f6dd15910a11787b5f9c0c602f5ddd903419058b..8766c85ae90f3a7b9e78da0df395d0227962a89f 100644 (file)
@@ -1,7 +1,6 @@
 /*
  * ntp_monitor.c - monitor who is using the ntpd server
  */
-
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #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++;
 }
index 22fde0bcc7fa8e8a49fa6ae0368595d2efc18528..fce3cc8831f21a0d70112356f0fa922e7b44deb2 100644 (file)
@@ -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;
index bfd38292fc81c9538fae6ad419f59b893ee4250a..183c044da3eff205832cb9b0ffd3cdd50261acfd 100644 (file)
@@ -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)
index bc65a436b147b0dcff4118f8e9b48e92a4367d2f..7a0059c92d9ab888ec64696c13258fc1cb2fa337 100644 (file)
@@ -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 <config.h>
@@ -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 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);
 }
 
 
index 037c7ce59ac64acaeebc48f77dcc2b63b9461194..07bd5afd03932b59070eca4f17beaa10cce4f8a9 100644 (file)
@@ -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),