[Git][NTPsec/ntpsec][master] 3 commits: First pass a direct output mode for mrulist

Hal Murray gitlab at mg.gitlab.com
Thu Dec 22 02:07:39 UTC 2016


Hal Murray pushed to branch master at NTPsec / ntpsec


Commits:
4322cb4d by Hal Murray at 2016-12-21T18:06:39-08:00
First pass a direct output mode for mrulist

- - - - -
c7d4a78d by Hal Murray at 2016-12-21T18:06:39-08:00
repair mru sort=avgint

- - - - -
29b69e26 by Hal Murray at 2016-12-21T18:06:39-08:00
Fix sort order within batch for direct mru

- - - - -


3 changed files:

- ntpclients/ntpq
- pylib/packet.py
- pylib/util.py


Changes:

=====================================
ntpclients/ntpq
=====================================
--- a/ntpclients/ntpq
+++ b/ntpclients/ntpq
@@ -11,7 +11,7 @@
 # SPDX-License-Identifier: BSD-2-clause
 from __future__ import print_function, division
 
-import os, sys, getopt, cmd, re
+import os, sys, getopt, cmd, re, time
 import socket, hashlib
 
 try:
@@ -147,6 +147,7 @@ class Ntpq(cmd.Cmd):
         #self.auth_keytype = "NID_md5"	# MD5 (FIXME: string value is a dummy)
         #self.auth_hashlen = 16		# MD5
         self.rawmode           = False	# Flag which indicates raw mode output.
+        self.directmode        = False	# Flag for direct MRU output.
         self.showhostnames     = True	# If false, display numeric IPs
         self.auth_delay    = 20		# delay time (default 20msec)
         self.wideremote = False		# show wide remote names?
@@ -664,6 +665,14 @@ function: print version number
 usage: version
 """)
 
+    def do_direct(self, line):
+        "toggle direct mode output"
+        self.directmode = not self.directmode
+        if self.directmode:
+            print("Direct mode is on")
+        else:
+            print("Direct mode is off")
+
     def do_raw(self, line):
         "do raw mode variable output"
         self.rawmode = True
@@ -1160,6 +1169,10 @@ function: configure ntpd using the configuration filename
 usage: config_from_file <configuration filename>
 """)
 
+    def printdirect(self, entries):
+        for entry in entries:
+            self.say(self.formatter.summary(entry) + "\n")
+
     def do_mrulist(self, line):
         "display the list of most recently seen source addresses, tags mincount=... resall=0x... resany=0x..."
         cmdvars = {}
@@ -1190,23 +1203,36 @@ usage: config_from_file <configuration filename>
         else:
             mruhook = None
         try:
-            span = self.session.mrulist(variables=cmdvars, rawhook=mruhook)
-            if not self.rawmode:
+            formatter = ntp.util.MRUSummary(interpreter.showhostnames)
+            if self.directmode:
+                formatter.now = None
+            self.formatter = formatter
+            if session.debug:
+                formatter.logfp = session.logfp
+                formatter.debug = session.debug
+            self.session.slots = 0
+            self.session.start = time.time()
+            direct = self.printdirect if self.directmode else None
+            span = self.session.mrulist(variables=cmdvars, \
+                    rawhook=mruhook, direct=direct)
+            if not self.directmode and not self.rawmode:
                 if not span.is_complete():
                     self.say("mrulist retrieval interrupted by operator.\n"
-                             "Displaying partial client list.\n")
+                         "Displaying partial client list.\n")
                 try:
-                    formatter = ntp.util.MRUSummary(interpreter.showhostnames)
-                    if session.debug:
-                        formatter.logfp = session.logfp
-                        formatter.debug = session.debug
+                    delta1 = time.time() - self.session.start
                     self.say(ntp.util.MRUSummary.header + "\n")
                     self.say(("=" * ntp.util.MRUSummary.width) + "\n")
                     # reversed to put most recent entries at the top.
                     for entry in reversed(span.entries):
                         self.say(formatter.summary(entry) + "\n")
+                    self.say("# Collected %d slots in %.3f seconds\n" \
+                            % (self.session.slots, delta1) )
                 except KeyboardInterrupt:
                     pass
+            delta2 = time.time() - self.session.start
+            self.say("# Processed %d slots in %.3f seconds\n" \
+                    % (self.session.slots, delta2) )
         except ntp.packet.ControlException as e:
             # Giving up after 8 restarts from the beginning.
             # With high-traffic NTP servers, this can occur if the


=====================================
pylib/packet.py
=====================================
--- a/pylib/packet.py
+++ b/pylib/packet.py
@@ -671,7 +671,9 @@ class MRUEntry:
         self.mv = None		# mode and version
         self.rs = None		# restriction mask (RES_* bits)
     def avgint(self):
-        return (self.last - self.first) / self.ct
+        last = ntp.ntpc.lfptofloat(self.last)
+        first = ntp.ntpc.lfptofloat(self.first)
+        return (last - first) / self.ct
     def __repr__(self):
         return "<MRUentry: " + repr(self.__dict__)[1:-1] + ">"
 
@@ -845,7 +847,8 @@ class ControlSession:
         while len(xdata) % 4:
             xdata += b"\x00"
         if self.debug >= 3:
-                self.logfp.write("Sending %d octets.\n" % len(xdata))
+                self.logfp.write("Sending %d octets.  seq=%d\n" % \
+                        ( len(xdata), self.sequence) )
         try:
             self.sock.sendall(polybytes(xdata))
         except socket.error:
@@ -1199,16 +1202,18 @@ class ControlSession:
         self.doquery(opcode=ntp.control.CTL_OP_REQ_NONCE)
         self.nonce_xmit = time.time()
         if not self.response.startswith(polybytes("nonce=")):
+            print("## Nonce expected: %s" % self.response)
             raise ControlException(SERR_BADNONCE)
         return polystr(self.response.strip())
 
-    def mrulist(self, variables=None, rawhook=None, recent=None):
+    def mrulist(self, variables=None, rawhook=None, direct=None):
         "Retrieve MRU list data"
         restarted_count = 0
         cap_frags = True
         warn = self.logfp.write
         sorter = None
         frags = MAXFRAGS
+        self.slots = 0
         if variables is None:
             variables = {}
 
@@ -1217,6 +1222,9 @@ class ControlSession:
                 sortkey = variables["sort"]
                 del variables["sort"]
                 # FIXME: implement sorting by address, in case anyone cares
+                # Slots are printed in reverse order so this is backwards.
+                # That avoids a sort in the normal case.
+                # Note lstint is backwards since we really sort on now-last
                 sortdict = {
                 "lstint" : lambda e: e.last,		# lstint ascending
                 "-lstint" : lambda e: -e.last,		# lstint descending
@@ -1227,7 +1235,7 @@ class ControlSession:
                 "count" : lambda e: -e.ct,	# hit count ascending
                 "-count": lambda e: e.ct,	# hit count descending
                 }
-                if sortkey == "listint":
+                if sortkey == "lstint":
                     sortkey = None
                 if sortkey is not None:
                     sorter = sortdict.get(sortkey)
@@ -1336,11 +1344,11 @@ class ControlSession:
                     elif tag == "addr.older":
                         continue
                     if tag == "now":
-                        # Don't see this in debug output, Hal, 2016-Dec-19
+                        # finished marker
                         span.now = ntp.ntpc.lfptofloat(val)
                         continue
                     elif tag == "last.newest":
-                        # Don't see this in debug output, Hal, 2016-Dec-19
+                        # more finished
                         continue
                     for prefix in ("addr", "last", "first", "ct", "mv", "rs"):
                         if tag.startswith(prefix + "."):
@@ -1354,7 +1362,10 @@ class ControlSession:
                                 curidx = idx
                                 mru = MRUEntry()
                                 span.entries.append(mru)
+                                self.slots += 1
                             setattr(mru, prefix, val)
+                if direct != None:
+                    direct(span.entries)
 
                 # If we've seen the end sentinel on the span, break out
                 if span.is_complete():
@@ -1362,7 +1373,7 @@ class ControlSession:
 
                 # Snooze for a bit between queries to let ntpd catch
                 # up with other duties.
-                time.sleep(0.05)
+                ## time.sleep(0.05)
 
                 # If there were no errors, increase the number of rows
                 # to a maximum of 3 * MAXFRAGS (the most packets ntpq
@@ -1395,6 +1406,8 @@ class ControlSession:
                         break
                     else:
                         req_buf += incr
+                if direct != None:
+                    span.entries = []
         except KeyboardInterrupt:
             pass	# We can test for interruption with is_complete()
 


=====================================
pylib/util.py
=====================================
--- a/pylib/util.py
+++ b/pylib/util.py
@@ -485,7 +485,14 @@ class MRUSummary:
 
     def summary(self, entry):
         last = ntp.ntpc.lfptofloat(entry.last)
-        lstint = int(self.now - last + 0.5)
+        if self.now:
+            lstint = int(self.now - last + 0.5)
+        else:
+            # direct mode doesn't have a reference time
+            # use seconds this day
+            days = int(last) / 86400
+            seconds = last - days*86400
+            lstint = int(seconds)
         first = ntp.ntpc.lfptofloat(entry.first)
         active = float(last - first)
         favgint = active / entry.ct  # FIXME should be ct-1



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/ae4152b84887f0027eb34acf8241aac7bad9f6f6...29b69e26e04287a3c8716e1381e5f70e150582a2
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20161222/c139d403/attachment.html>


More information about the vc mailing list