debian/0000775000000000000000000000000012063113764007173 5ustar debian/dsc-collector.cfg0000664000000000000000000000766212063113746012424 0ustar # local_address # # specifies a local IP address. used to determine the # "direction" of an IP packet: sending or receiving or other. # Repeat any number of times for all local addresses. # DSClocal_addressDSC # run_dir # # dsc passes this directory to chdir() after starting. # run_dir "DSClibdirDSC"; # minfree_bytes # # If the filesystem has less than this amount of free # space, then dsc will not write its XML files to disk. # The data will be lost. # minfree_bytes 5000000; # pid_file # # filename where DSC should store its process-id # pid_file "DSCpidfileDSC"; # bpf_program # # a berkely packet filter program. it can be used to limit # the number and type of queries that the application receives # from the kernel. note if you limit it to "udp port 53" the # IP-based collectors do not work # # NOTE: bpf_program must GO BEFORE interface # # use this to see only DNS messages #bpf_program "udp port 53"; # # use this to see only DNS *queries* #bpf_program "udp dst port 53 and udp[10:2] & 0x8000 = 0"; DSCbpf_programDSC # interface # # specifies a network interface to sniff packets from. # can specify more than one. # DSCinterfaceDSC # qname_filter # # Defines a custom QNAME-based filter for DNS messages. If # you refer to this named filter on a dataset line, then only # queries or replies for matching QNAMEs will be counted. # The QNAME argument is a regular expression. For example: # # qname_filter WWW-Only ^www\. ; # dataset qtype dns All:null Qtype:qtype queries-only,WWW-Only ; # # datasets # # please see the DSC manual for more information. dataset qtype dns All:null Qtype:qtype queries-only; dataset rcode dns All:null Rcode:rcode replies-only; dataset opcode dns All:null Opcode:opcode queries-only; dataset rcode_vs_replylen dns Rcode:rcode ReplyLen:msglen replies-only; dataset client_subnet dns All:null ClientSubnet:cip4_net queries-only max-cells=200; dataset qtype_vs_qnamelen dns Qtype:qtype QnameLen:qnamelen queries-only; dataset qtype_vs_tld dns Qtype:qtype TLD:tld queries-only,popular-qtypes max-cells=200; dataset certain_qnames_vs_qtype dns CertainQnames:certain_qnames Qtype:qtype queries-only; dataset client_subnet2 dns Class:query_classification ClientSubnet:cip4_net queries-only max-cells=200; dataset client_addr_vs_rcode dns Rcode:rcode ClientAddr:client replies-only max-cells=50; dataset chaos_types_and_names dns Qtype:qtype Qname:qname chaos-class,queries-only; dataset idn_qname dns All:null IDNQname:idn_qname queries-only; dataset edns_version dns All:null EDNSVersion:edns_version queries-only; dataset edns_bufsiz dns All:null EDNSBufSiz:edns_bufsiz queries-only; dataset do_bit dns All:null D0:do_bit queries-only; dataset rd_bit dns All:null RD:rd_bit queries-only; dataset idn_vs_tld dns All:null TLD:tld queries-only,idn-only; dataset ipv6_rsn_abusers dns All:null ClientAddr:client queries-only,aaaa-or-a6-only,root-servers-net-only max-cells=50; dataset transport_vs_qtype dns Transport:transport Qtype:qtype queries-only; dataset client_port_range dns All:null PortRange:dns_sport_range queries-only; #dataset second_ld_vs_rcode dns Rcode:rcode SecondLD:second_ld replies-only max-cells=50; #dataset third_ld_vs_rcode dns Rcode:rcode ThirdLD:third_ld replies-only max-cells=50; dataset direction_vs_ipproto ip Direction:ip_direction IPProto:ip_proto any; # dataset dns_ip_version_vs_qtype dns IPVersion:dns_ip_version Qtype:qtype queries-only; # datasets for collecting data on priming queries at root nameservers # dataset priming_queries dns Transport:transport EDNSBufSiz:edns_bufsiz priming-query,queries-only; # dataset priming_responses dns All:null ReplyLen:msglen priming-query,replies-only; # bpf_vlan_tag_byte_order # # Set this to 'host' on FreeBSD-4 where the VLAN id that we # get from BPF appears to already be in host byte order. #bpf_vlan_tag_byte_order host; # match_vlan # # A whitespace-separated list of VLAN IDs. If set, only the # packets with these VLAN IDs will be analyzed by DSC. # #match_vlan 100 200; debian/dsc-statistics-presenter.postinst0000664000000000000000000000177212063113746015755 0ustar #!/bin/bash -e # postinst USERNAME="Debian-dsc-statistics" HOMEDIR="/var/lib/dsc-statistics" [ -n "$DSCDEBUG" ] && set -x # Add user if [ "$1" = "configure" ]; then echo >&2 'Adding system user' adduser --system --group --home $HOMEDIR --shell /bin/bash \ --disabled-password --force-badname $USERNAME chown www-data /var/cache/dsc-statistics-presenter chown -R $USERNAME /var/lib/dsc-statistics/data fi # Handle apache2 if [ "$1" = "configure" ] ; then CONF="dsc-statistics-presenter" if [ -e /usr/share/apache2/apache2-maintscript-helper ] ; then . /usr/share/apache2/apache2-maintscript-helper apache2_invoke enconf $CONF elif dpkg-query -f '${Version}' -W 'apache2.2-common' > /dev/null 2>&1 ; then [ -d /etc/apache2/conf.d/ ] && [ ! -L /etc/apache2/conf.d/$CONF.conf ] && ln -s ../conf-available/$CONF.conf /etc/apache2/conf.d/$CONF.conf fi if [ -x /etc/init.d/apache2 ]; then invoke-rc.d apache2 reload fi fi #DEBHELPER# debian/TODO0000664000000000000000000000034312063113746007663 0ustar * this file is a preliminary bug tracker while the package is still in NEW - init script should ignore files ._~ in ALLINSTANCECONFDIR - local processing script should optionally delete un-collected files older than X days debian/dsc-statistics-collector.cron.d0000664000000000000000000000044112063113746015224 0ustar # /etc/cron.d/dsc-collector: crontab entries for the dsc-collector package SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin */5 * * * * root test -x /usr/share/dsc-statistics-collector/upload-prep && /usr/share/dsc-statistics-collector/upload-prep debian/README0000664000000000000000000000175612063113746010064 0ustar Co-Maintainers for this package are happily accepted. This package currently supports only the apache 2 web server. Patches to add support for other web servers and/or more automation are happily accepted as long as you commit yourself to taking care of the additional code. After installation, the Grapher is accessible under http://localhost/cgi-bin/dsc-statistics/dsc-grapher The presenter package comes with an activated cron.d job which processes data collected by the local host, so that the package will automatically start producing results after installation. This might not be what you intend to do if your collectors and presenter run on different hosts. This package currently does not implement any of the XML transfer mechanisms that come with the package. You'll need to implement these yourself. Patches to configure XML transfer automatically are happily accepted as long as you commit yourself to taking care of the additional code. The dsc man page is in dire need of improvement. debian/copy-local-and-process-data0000775000000000000000000000144612063113746014313 0ustar #!/bin/bash # this is a simple dsc cronjob to be run on the presenter side # of a single-host setup. This only works if dsc-grapher.cfg # has only one "server localhost localhost" line. set -u set -e LOCKFILE="/var/run/dsc-statistics-presenter/copy-local-and-process-data.lock" if ! dotlockfile -p -l "$LOCKFILE"; then echo >&2 "ERR: lockfile cannot be obtained" exit 1 fi LOCKED=yes CONFFILE="/etc/dsc-statistics/dsc-grapher.cfg" BASEDIR="/var/lib/dsc-statistics" DATADIR="$BASEDIR/data" mkdir -p $DATADIR/localhost/localhost/incoming cp -R /var/lib/dsc-statistics/default/upload/default/* $DATADIR/localhost/localhost/incoming rm -f /var/lib/dsc-statistics/default/upload/default/*/* /usr/share/dsc-statistics-presenter/refile-and-grok dotlockfile -u "$LOCKFILE" || true exit 0 # EOF debian/changelog0000664000000000000000000001225612063113746011053 0ustar dsc-statistics (201203250530-2) unstable; urgency=low * don't remove account on purge * move home directory to /var/lib/dsc-statistics (Closes: #668740) * add a NEWS file documenting the home directory change -- Marc Haber Sat, 15 Dec 2012 16:25:58 +0100 dsc-statistics (201203250530-1) unstable; urgency=low * Imported Upstream version 201203250530 * refresh patches * add texlive-generic-recommended to Build-Depends. Thanks to Lucas Nussbaum and Salvatore Bonaccorso. Closes: #669530 * add plot.page patch to move control panel to the right. Closes: #651260 * apache 2.4 transition: Closes: #669744 * Fix dependencies of -presenter. * move /etc/apache2/conf.d to /etc/apache2/conf-available * move conf.d file to conf-available * handle existing but empty docsrc/ * Standards-Version: 3.9.3 (no changes needed) -- Marc Haber Mon, 07 May 2012 22:31:47 +0200 dsc-statistics (201106061022-4) unstable; urgency=low * copy-local-and-process-data: use cp, rm instead of rsync to avoid dependency * dsc-rsync-pull: log missing rsync, streamline logging, allow sf options * new pull-and-process-data allowing parallel processing * replace refile-and-grok script with local, parallel version * dsc-statistics-presenter.cron.d: fix wrong binary path * dsc-statistics-presenter: add openssh-client to Suggests -- Marc Haber Tue, 06 Sep 2011 17:51:32 +0200 dsc-statistics (201106061022-3) unstable; urgency=low * new upload to fix botched previous upload -- Marc Haber Mon, 05 Sep 2011 13:36:22 +0200 dsc-statistics (201106061022-2) unstable; urgency=low * remove lintian overrides, we now declare our changes in debian/source * add iproute to -collector dependencies * add geoip-database to -collector dependencies * add cron to -collector and -presenter dependencies -- Marc Haber Fri, 26 Aug 2011 13:34:58 +0000 dsc-statistics (201106061022-1) unstable; urgency=low * new upstream release 201106061022 * remove patches/pcap-nonblock (applied upstream). Take care, quilt will happily add the three lines a second time. * relax wdiff of the generated docs, Debian LaTeX will generate different whitespace. * clean up doc/dsc-manual.txt * Standards-Version: 3.9.2 (no changes necessary) * Change lintian override to format-3.0-but-debian-changes-patch -- Marc Haber Mon, 18 Jul 2011 15:38:10 +0200 dsc-statistics (201008131729-6) unstable; urgency=low * work around debhelper limitation to allow arch-only builds. Thanks to Ansgar Burchardt. * make puiparts (hopefully) happy: improve dsc-statistics-presenter.cron.daily's behavior on removed package and/or non-existent data -- Marc Haber Tue, 12 Apr 2011 11:23:51 +0200 dsc-statistics (201008131729-5) unstable; urgency=low * restrict Architecture to linux-any - libpcap seems to be slightly strange on kFreeBSD. Closes: #622226 * Add sharutils to build-depends. Closes: #621765, #621771 * Optimize package descriptions, make lintian happy. -- Marc Haber Mon, 11 Apr 2011 11:16:35 +0200 dsc-statistics (201008131729-4) unstable; urgency=low * do not ship upstream .ps in binary package * do not ship upstream .pdf in binary package * pdftotext both upstream .pdf and locally built .pdfs, wdiff both text files and abort if differences found * add VCS-Lines to debian/control -- Marc Haber Wed, 23 Mar 2011 09:58:56 +0100 dsc-statistics (201008131729-3) unstable; urgency=low * add logging to pull-and-process-data, to cater for munin plugin * add munin plugin for dsc-presenter * patch in upstream doc sources from svn https://www.measurement-factory.com/svn/dsc/trunk/doc/dsc-manual.tex (Revision: 12842, Username: anonsvn, Password: anonsvn) -- Marc Haber Fri, 11 Feb 2011 12:37:23 +0100 dsc-statistics (201008131729-2) unstable; urgency=low * fix broken processing of single-instance configuration * do not abort pull-and-process-data if one host is down * remove virtual host statement from apache2 config * pull-and-process-data now aborts if a symlink is found on the way to the config file. * fix presenter cron.daily job to actually process cache dir * depend on libgeo-ip-perl instead of libip-country-perl * collector init script: generate interface clause for interfaces that are actually up. dsc-collector won't start if any interfaces are not up. * add cron.daily job cleaning up XML files and cache * Package is team maintained * ship presenter cron job in disabled state * mention grapher URL in README * remove /var/cache/dsc-statistics-presenter on purge * add a basic cron job processing locally collected data -- Marc Haber Tue, 30 Nov 2010 21:12:30 +0100 dsc-statistics (201008131729-0) UNRELEASED; urgency=low * Initial release. (Closes: #505405) -- Marc Haber Wed, 08 Sep 2010 14:31:54 +0200 debian/control0000664000000000000000000000535212063113746010603 0ustar Source: dsc-statistics Section: utils Priority: optional Build-Depends: debhelper (>= 8.1.0~), libpcap0.8-dev, libproc-pid-file-perl, libgeoip-dev, autotools-dev, transfig, netpbm, texlive-latex-recommended, texlive-generic-recommended, ghostscript, wdiff, poppler-utils, sharutils Maintainer: Debian dsc Maintainer Team Uploaders: Marc Haber , Sebastian Laubscher Homepage: http://dns.measurement-factory.com/tools/dsc/index.html VCS-Git: https://alioth.debian.org/anonscm/git/dsc/dsc.git VCS-Browser: https://alioth.debian.org/scm/browser.php?group_id=100554 Standards-Version: 3.9.3 Package: dsc-statistics-collector Architecture: linux-any Depends: ${shlibs:Depends}, ${misc:Depends}, libproc-pid-file-perl, adduser, iproute, geoip-database, cron Suggests: rsync Conflicts: dsc-collector Description: DNS Statistics Collector - Collector component dsc (A DNS Statistics Collector) is a system for collecting and exploring statistics from busy DNS servers. It currently has two major components, the Collector and the Presenter, each of which being its own binary package built from the same source. . This package contains the Collector, which uses libpcap to sniff DNS messages sent and received on a network interface. It may run on the same machine as the DNS server, or on another system connected to a switch configured with port mirroring. Datasets are dumped to disk every 60 seconds as XML files. These can then be moved to a separate server running dsc's presenter component for archiving and further processing. Package: dsc-statistics-presenter Architecture: all Depends: ${shlibs:Depends}, ${misc:Depends}, libcgi-untaint-perl, libfile-flock-perl, libfile-nfslock-perl, libhash-merge-perl, libgeo-ip-perl, libmath-calc-units-perl, libnet-dns-perl, libtext-template-perl, liburi-perl, libproc-pid-file-perl, libxml-simple-perl, ploticus, liblockfile1, adduser, cron Recommends: apache2 | httpd Suggests: rsync, openssh-client Conflicts: dsc-presenter Description: DNS Statistics Collector - Presenter component dsc (A DNS Statistics Collector) is a system for collecting and exploring statistics from busy DNS servers. It currently has two major components, the Collector and the Presenter, each of which being its own binary package built from the same source. . This package contains the Presenter. A variety of methods moves XML datasets from the hosts running the collector. Next, an extractor process converts them to line-based text files. . To display data in a web browser, dsc uses a CGI script. The interface allows you to change time scales, select particular nodes within a server cluster, and isolate individual dataset keys. debian/dsc-statistics-collector.default0000664000000000000000000000175612063113746015477 0ustar # defaults file for dsc-statistics-collector INTERFACE="all" LOCAL_ADDRESS="all" OPTS="-p" # if you want/need to run multiple dsc instances, this can be controlled with # the INSTANCES variable. Give each instance a name listed here. # Settings are controlled by VARIABLE_instname, if a VARIABLE_instname is not set, # VARIABLE is taken as a default. # # INSTANCES="inst1 inst2" # INTERFACE_inst1="eth0" # INTERFACE="all" # This will start two instances called inst1 and inst2. inst1 will only listen on eth0; # inst2 will listen on all interfaces # Alternatively, you can specify EXTRAINSTANCEDIR. That directory contains one # configuration file per instance, containing any combination of INTERFACE, # LOCAL_ADDRESS, OPTS, and/or BPF variables. This is especially handy if you # need your instance names to contain dashes or if you want to use a # configuration management system which likes to distribute files instead # of snippets # EXTRAINSTANCEDIR="/etc/dsc-statistics/dsc-collector-instances" debian/patches/0000775000000000000000000000000012063113764010622 5ustar debian/patches/presenter-grapher-paths0000664000000000000000000000327712063113746015330 0ustar Description: Fix hard-coded non-FHS compliant paths in grapher.pm Author: Marc Haber Forwarded: no --- a/presenter/perllib/DSC/grapher.pm +++ b/presenter/perllib/DSC/grapher.pm @@ -27,8 +27,8 @@ # CONSTANTS my $dbg_lvl = 0; # also set debug_file in dsc-grapher.cfg -my $DATAROOT = '/usr/local/dsc/data'; -my $DEFAULTCONFIG = '/usr/local/dsc/etc/dsc-grapher.cfg'; +my $DATAROOT = '/var/lib/dsc-statistics/data'; +my $DEFAULTCONFIG = '/etc/dsc-statistics/dsc-grapher.cfg'; my $CacheImageTTL = 60; # 1 min my $expires_time = '+1m'; my $sublist_item ='› '; @@ -180,7 +180,7 @@ $self->make_image($cache_name); } } - my $source = "/usr/local/dsc/share/html/plot.page"; + my $source = "/usr/share/dsc-statistics-presenter/html/plot.page"; my $t = Text::Template->new( TYPE => 'FILE', SOURCE => $source, @@ -1005,13 +1005,13 @@ sub cache_image_path { my $self = shift; my $prefix = shift || die; - "/usr/local/dsc/cache/$prefix.png"; + "/var/cache/dsc-statistics-presenter/$prefix.png"; } sub cache_mapfile_path { my $self = shift; my $prefix = shift || confess "cache_mapfile_path: no prefix given"; - "/usr/local/dsc/cache/$prefix.map"; + "/var/cache/dsc-statistics-presenter/$prefix.map"; } # return 0 if we should generate a cached image @@ -1587,11 +1587,11 @@ my $self = shift; my $icon = shift; # should be like 'foo.png" my $buf; - if (open(F, "/usr/local/dsc/share/html/$icon")) { + if (open(F, "/usr/share/dsc-statistics-presenter/html/$icon")) { $buf .= $_ while (); close(F); } else { - warn "/usr/local/dsc/htdocs/$icon: $!\n"; + warn "/usr/share/dsc-statistics-presenter/html/$icon: $!\n"; } $buf; } debian/patches/series0000664000000000000000000000017012063113764012035 0ustar upload-prep grapher-runtime-paths presenter-grapher-paths use-geo-ip doc-sources plot-page-layout-651260 debian-changes debian/patches/doc-sources0000664000000000000000000032070312063113746013000 0ustar --- /dev/null +++ b/docsrc/Makefile @@ -0,0 +1,45 @@ + +.SUFFIXES: .fig .eps .png + +FIGS=\ + dsc-arch.eps \ + screenshot1.eps + +DOC=dsc-manual + +$(DOC).pdf: $(DOC).ps + ps2pdf $(DOC).ps > $@ + +$(DOC).ps: $(DOC).dvi + dvips $(DOC).dvi > $@ + +$(DOC).dvi: $(DOC).tex $(FIGS) + latex $(DOC).tex + latex $(DOC).tex + latex $(DOC).tex + +.fig.eps: + fig2dev -L eps $< > $@ + +.png.eps: + pngtopnm $< | pnmtops -noturn > $@ + + +all: $(DOC).ps $(DOC).pdf + +clean-junk: + rm -f $(FIGS) + rm -f $(DOC).aux + rm -f $(DOC).dvi + rm -f $(DOC).log + rm -f $(DOC).toc + +clean: clean-junk + rm -f $(DOC).pdf + rm -f $(DOC).ps + +clean-release: clean-junk + rm -f $(DOC).tex + rm -f dsc-arch.fig + rm -f screenshot1.png + rm -f Makefile --- /dev/null +++ b/docsrc/dsc-arch.fig @@ -0,0 +1,231 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +0 32 #c6b797 +0 33 #eff8ff +0 34 #dccba6 +0 35 #404040 +0 36 #808080 +0 37 #c0c0c0 +0 38 #e0e0e0 +0 39 #8e8f8e +0 40 #aaaaaa +0 41 #555555 +0 42 #8e8e8e +0 43 #d7d7d7 +0 44 #aeaeae +0 45 #bebebe +0 46 #515151 +0 47 #e7e3e7 +0 48 #000049 +0 49 #797979 +0 50 #303430 +0 51 #414141 +0 52 #c7b696 +0 53 #414541 +0 54 #868286 +0 55 #c7c3c7 +0 56 #444444 +0 57 #868686 +0 58 #c7c7c7 +0 59 #e7e7e7 +0 60 #f7f7f7 +0 61 #9e9e9e +0 62 #717571 +0 63 #757575 +0 64 #effbff +0 65 #f3f3f3 +0 66 #d7d3d7 +0 67 #aeaaae +0 68 #c2c2c2 +0 69 #303030 +0 70 #515551 +0 71 #f7f3f7 +0 72 #666666 +0 73 #717171 +0 74 #636363 +0 75 #cdcdcd +0 76 #6c6c6c +0 77 #c9c9c9 +0 78 #dfd8df +0 79 #6e6e6e +0 80 #333333 +0 81 #949395 +0 82 #747075 +0 83 #b3b3b3 +0 84 #c3c3c3 +0 85 #6d6d6d +0 86 #454545 +0 87 #9c0000 +0 88 #8c8c8c +0 89 #424242 +0 90 #8c8c8c +0 91 #424242 +0 92 #8c8c8c +0 93 #424242 +0 94 #8c8c8c +0 95 #424242 +0 96 #8c8c8c +0 97 #424242 +0 98 #8c8c8c +0 99 #424242 +0 100 #e2e2ee +0 101 #94949a +0 102 #dbdbdb +0 103 #a1a1b7 +0 104 #ededed +0 105 #86acff +0 106 #7070ff +0 107 #dd9d93 +0 108 #f1ece0 +0 109 #e2c8a8 +0 110 #e1e1e1 +0 111 #d2d2d2 +0 112 #da7a1a +0 113 #f1e41a +0 114 #887dc2 +0 115 #d6d6d6 +0 116 #8c8ca5 +0 117 #4a4a4a +0 118 #8c6b6b +0 119 #5a5a5a +0 120 #b79b73 +0 121 #4193ff +0 122 #bf703b +0 123 #db7700 +0 124 #dab800 +0 125 #006400 +0 126 #5a6b3b +0 127 #d3d3d3 +0 128 #8e8ea4 +0 129 #f3b95d +0 130 #89996b +0 131 #646464 +0 132 #b7e6ff +0 133 #86c0ec +0 134 #bdbdbd +0 135 #d39552 +0 136 #98d2fe +0 137 #8c9c6b +0 138 #f76b00 +0 139 #5a6b39 +0 140 #8c9c6b +0 141 #8c9c7b +0 142 #184a18 +0 143 #adadad +0 144 #f7bd5a +0 145 #636b9c +0 146 #de0000 +0 147 #adadad +0 148 #f7bd5a +0 149 #adadad +0 150 #f7bd5a +0 151 #636b9c +0 152 #526b29 +0 153 #949494 +0 154 #006300 +0 155 #00634a +0 156 #7b844a +0 157 #e7bd7b +0 158 #a5b5c6 +0 159 #6b6b94 +0 160 #846b6b +0 161 #529c4a +0 162 #d6e7e7 +0 163 #526363 +0 164 #186b4a +0 165 #9ca5b5 +0 166 #ff9400 +0 167 #ff9400 +0 168 #00634a +0 169 #7b844a +0 170 #63737b +0 171 #e7bd7b +0 172 #184a18 +0 173 #f7bd5a +0 174 #dedede +0 175 #f3eed3 +0 176 #f5ae5d +0 177 #95ce99 +0 178 #b5157d +0 179 #eeeeee +0 180 #848484 +0 181 #7b7b7b +0 182 #005a00 +0 183 #e77373 +0 184 #ffcb31 +0 185 #29794a +0 186 #de2821 +0 187 #2159c6 +0 188 #f8f8f8 +0 189 #e6e6e6 +0 190 #21845a +6 5700 3825 6300 4200 +4 0 0 51 -1 0 12 0.0000 4 135 555 5700 3975 HTTPS\001 +4 0 0 51 -1 0 12 0.0000 4 135 435 5700 4200 PUTs\001 +-6 +6 4725 5400 6075 6394 +2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5 + 4729 5404 6071 5404 6071 6388 4729 6388 4729 5404 +2 2 0 1 0 7 100 0 15 0.000 0 0 -1 0 0 5 + 4729 5404 6071 5404 6071 5493 4729 5493 4729 5404 +-6 +6 2625 5100 3600 6600 +5 1 0 1 -1 -1 0 0 -1 0.000 0 1 0 0 3090.000 4875.000 2640 5475 3090 5625 3540 5475 +5 1 0 1 -1 -1 0 0 -1 0.000 0 1 0 0 3090.000 5775.000 2640 6375 3090 6525 3540 6375 +1 2 0 1 -1 -1 0 0 -1 0.000 1 0.0000 3090 5325 450 150 2640 5175 3540 5475 +2 1 0 1 -1 -1 0 0 -1 0.000 0 0 0 0 0 2 + 3540 5400 3540 6375 +2 1 0 1 -1 -1 0 0 -1 0.000 0 0 0 0 0 2 + 2640 5400 2640 6375 +-6 +1 3 0 1 0 7 50 -1 20 0.000 1 0.0000 4875 2475 424 424 4875 2475 5175 2775 +1 3 0 1 0 7 50 -1 20 0.000 1 0.0000 5775 2475 424 424 5775 2475 6075 2775 +1 3 0 1 0 7 50 -1 20 0.000 1 0.0000 6675 2475 424 424 6675 2475 6975 2775 +1 3 0 1 0 7 50 -1 20 0.000 1 0.0000 1950 2250 424 424 1950 2250 2250 2550 +1 3 0 1 0 7 50 -1 20 0.000 1 0.0000 2850 2250 424 424 2850 2250 3150 2550 +1 3 0 1 0 7 50 -1 20 0.000 1 0.0000 1050 2250 424 424 1050 2250 1350 2550 +2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 + 7350 3150 7350 1725 4200 1725 4200 3150 7350 3150 +2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1950 2250 3600 4950 +2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2850 2250 3600 4950 +2 1 0 1 0 7 51 -1 20 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 4875 2475 4500 4950 +2 1 0 1 0 7 51 -1 20 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 5775 2475 4500 4950 +2 1 0 1 0 7 51 -1 20 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 6675 2475 4500 4950 +2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1725 4950 6900 4950 6900 7200 1725 7200 1725 4950 +2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 + 3525 2925 3525 1500 375 1500 375 2925 3525 2925 +2 1 0 1 0 7 51 -1 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1050 2250 3600 4950 +4 1 0 50 -1 0 12 0.0000 4 135 450 6675 2550 node3\001 +4 1 0 50 -1 0 12 0.0000 4 135 450 4875 2550 node1\001 +4 1 0 50 -1 0 12 0.0000 4 135 810 5775 1950 SERVER2\001 +4 1 0 50 -1 0 12 0.0000 4 135 450 5775 2550 node2\001 +4 1 0 50 -1 0 12 0.0000 4 135 780 3900 1275 Collectors\001 +4 1 0 50 -1 0 12 0.0000 4 135 855 3075 6825 STORAGE\001 +4 1 0 50 -1 0 12 0.0000 4 135 780 5400 6825 DISPLAY\001 +4 1 0 50 -1 0 12 0.0000 4 180 840 3075 6975 (extractor)\001 +4 1 0 50 -1 0 12 0.0000 4 180 720 5400 6975 (grapher)\001 +4 1 0 50 -1 0 12 0.0000 4 135 735 1125 6225 Presenter\001 +4 1 0 49 -1 0 12 0.0000 4 135 450 2850 2325 node3\001 +4 1 0 50 -1 0 12 0.0000 4 135 810 1950 1725 SERVER1\001 +4 1 0 49 -1 0 12 0.0000 4 135 450 1050 2325 node1\001 +4 1 0 49 -1 0 12 0.0000 4 135 450 1950 2325 node2\001 --- /dev/null +++ b/docsrc/dsc-manual.tex @@ -0,0 +1,1810 @@ +\documentclass{report} +\usepackage{epsfig} +\usepackage{path} +\usepackage{fancyvrb} + +\def\dsc{{\sc dsc}} + +\DefineVerbatimEnvironment% + {MyVerbatim}{Verbatim} + {frame=lines,framerule=0.8mm,fontsize=\small} + +\renewcommand{\abstractname}{} + +\begin{document} + +\begin{titlepage} +\title{DSC Manual} +\author{Duane Wessels, Measurement Factory\\ +Ken Keys, CAIDA\\ +\\ +http://dns.measurement-factory.com/tools/dsc/} +\date{\today} +\end{titlepage} + +\maketitle + +\begin{abstract} +\setlength{\parskip}{1ex} +\section{Copyright} + +The DNS Statistics Collector (dsc) + +Copyright 2007 by The Measurement Factory, Inc. and Internet Systems +Consortium, Inc. + +{\em info@measurement-factory.com\/}, {\em info@isc.org\/} + +\section{License} + +{\dsc} is licensed under the terms of the BSD license: + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +Neither the name of The Measurement Factory nor the names of its +contributors may be used to endorse or promote products derived +from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +\section{Contributors} +\begin{itemize} +\item Duane Wessels, Measurement Factory +\item Ken Keys, Cooperative Association for Internet Data Analysis +\end{itemize} +\end{abstract} + + +\tableofcontents + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chapter{Introduction} + +{\dsc} is a system for collecting and presenting statistics from +a busy DNS server. + +\section{Components} + +{\dsc} consists of the following components: +\begin{itemize} +\item A data collector +\item A data presenter, where data is archived and rendered +\item A method for securely transferring data from the collector + to the presenter +\item Utilities and scripts that parse XML and archive files from the collector +\item Utilities and scripts that generate graphs and HTML pages +\end{itemize} + +\subsection{The Collector} + +The collector is a binary program, named {\tt dsc\/}, which snoops +on DNS messages. It is written in C and uses {\em libpcap\/} for +packet capture. + +{\tt dsc\/} uses a relatively simple configuration file called {\em +dsc.conf\/} to define certain parameters and options. The configuration +file also determines the {\em datasets\/} that {\tt dsc\/} collects. + +A Dataset is a 2-D array of counters of IP/DNS message properties. +You can define each dimension of the array independently. For +example you might define a dataset categorized by DNS query type +along one dimension and TLD along the other. +{\tt dsc\/} dumps the datasets from memory to XML files every 60 seconds. + +\subsection{XML Data Transfer} + +You may run the {\dsc} collector on a remote machine. That +is, the collector may run on a different machine than where the +data is archived and displayed. {\dsc} includes some Perl and {\tt /bin/sh} +scripts to move XML files from collector to presenter. One +technique uses X.509 certificates and a secure HTTP server. The other +uses {\em rsync\/}, presumably over {\em ssh\/}. + +\subsubsection{X.509/SSL} + +To make this work, Apache/mod\_ssl should run on the machine where data +is archived and presented. +Data transfer is authenticated via SSL X.509 certificates. A Perl +CGI script handles all PUT requests on the server. If the client +certificate is allowed, XML files are stored in the appropriate +directory. + +A shell script runs on the collector to upload the XML files. It +uses {\tt curl\/}\footnote{http://curl.haxx.se} to establish an +HTTPS connection. XML files are bundled together with {\tt tar\/} +before transfer to eliminate per-connection delays. +You could use {\tt scp\/} or {\tt rsync\/} instead of +{\tt curl\/} if you like. + +\path|put-file.pl| is the script that accepts PUT requests on the +HTTP server. The HTTP server validates the client's X.509 certificate. +If the certificate is invalid, the PUT request is denied. This +script reads environment variables to get X.509 parameters. The +uploaded-data is stored in a directory based on the X.509 Organizational +Unit (server) and Common Name fields (node). + +\subsubsection{rsync/ssh} + +This technique uses the {\em rsync\/} utility to transfer files. +You'll probably want to use {\em ssh\/} as the underlying transport, +although you can still use the less-secure {\em rsh\/} or native +rsync server transports if you like. + +If you use {\em ssh\/} then you'll need to create passphrase-less +SSH keys so that the transfer can occur automatically. You may +want to create special {\em dsc\/} userids on both ends as well. + +\subsection{The Extractor} + +The XML extractor is a Perl script that reads the XML files from +{\tt dsc\/}. The extractor essentially converts the XML-structured +data to a format that is easier (faster) for the graphing tools to +parse. Currently the extracted data files are line-based ASCII +text files. Support for SQL databases is planned for the future. + +\subsection{The Grapher} + +{\dsc} uses {\em Ploticus\/}\footnote{http://ploticus.sourceforge.net/} +as the graphing engine. A Perl module and CGI script read extracted +data files and generate Ploticus scriptfiles to generate plots. Plots +are always generated on demand via the CGI application. + +\path|dsc-grapher.pl| is the script that displays graphs from the +archived data. + + +\section{Architecture} + +Figure~\ref{fig-architecture} shows the {\dsc} architecture. + +\begin{figure} +\centerline{\psfig{figure=dsc-arch.eps,width=3.5in}} +\caption{\label{fig-architecture}The {\dsc} architecture.} +\end{figure} + +Note that {\dsc} utilizes the concept of {\em servers\/} and {\em +nodes\/}. A server is generally a logical service, which may +actually consist of multiple nodes. Figure~\ref{fig-architecture} +shows six collectors (the circles) and two servers (the rounded +rectangles). For a real-world example, consider a DNS root server. +IP Anycast allows a DNS root server to have geographically distributed +nodes that share a single IP address. We call each instance a +{\em node\/} and all nodes sharing the single IP address belong +to the same {\em server\/}. + +The {\dsc} collector program runs on or near\footnote{by +``near'' we mean that packets may be sniffed remotely via Ethernet taps, switch +port mirroring, or a SPAN port.} the remote nodes. Its XML output +is transferred to the presentation machine via HTTPS PUTs (or something simpler +if you prefer). + +The presentation machine includes an HTTP(S) server. The extractor looks +for XML files PUT there by the collectors. A CGI script also runs on +the HTTP server to display graphs and other information. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Installing the Presenter} + +You'll probably want to get the Presenter working before the Collector. +If you're using the secure XML data transfer, you'll need to +generate both client- and server-side X.509 certificates. + +Installing the Presenter involves the following steps: +\begin{itemize} +\setlength{\itemsep}{0ex plus 0.5ex minus 0.0ex} +\item + Install Perl dependencies +\item + Install {\dsc} software +\item + Create X.509 certificates (optional) +\item + Set up a secure HTTP server (e.g., Apache and mod\_ssl) +\item + Add some cron jobs +\end{itemize} + + +\section{Install Perl Dependencies} + +{\dsc} uses Perl for the extractor and grapher components. Chances are +that you'll need Perl-5.8, or maybe only Perl-5.6. You'll also need +these readily available third-party Perl modules, which you +can find via CPAN: + +\begin{itemize} +\setlength{\itemsep}{0ex plus 0.5ex minus 0.0ex} + \item CGI-Untaint (CGI::Untaint) + \item CGI.pm (CGI) + \item Digest-MD5 (Digest::MD5) + \item File-Flock (File::Flock) + \item File-Spec (File::Spec) + \item File-Temp (File::Temp) + \item Geography-Countries (Geography::Countries) + \item Hash-Merge (Hash::Merge) + \item IP-Country (IP::Country) + \item MIME-Base64 (MIME::Base64) + \item Math-Calc-Units (Math::Calc::Units) + \item Scalar-List-Utils (List::Util) + \item Text-Template (Text::Template) + \item URI (URI::Escape) + \item XML-Simple (XML::Simple) + \item Net-DNS-Resolver (Net::DNS::Resolver) + +\end{itemize} + +\noindent +Also note that XML::Simple requires XML::Parser, which in +turn requires the {\em expat\/} package. + +\section{Install Ploticus} + +{\dsc} uses Ploticus to generate plots and graphs. You can find +this software at \verb|http://ploticus.sourceforge.net|. The {\em +Download\/} page has links to some pre-compiled binaries and packages. +FreeBSD and NetBSD users can find Ploticus in the ports/packages +collection. + + +\section{Install {\dsc} Software} + +All of the extractor and grapher tools are Perl or {\tt /bin/sh} +scripts, so there is no need to compile anything. Still, +you should run {\tt make} first: + +\begin{MyVerbatim} +% cd presenter +% make +\end{MyVerbatim} + +If you see errors about missing Perl prerequisites, you may want +to correct those before continuing. + +The next step is to install the files. Recall that +\path|/usr/local/dsc| is the hard-coded installation prefix. +You must create it manually: + +\begin{MyVerbatim} +% mkdir /usr/local/dsc +% make install +\end{MyVerbatim} + +Note that {\dsc}'s Perl modules are installed in the +``site\_perl'' directory. You'll probably need {\em root\/} +privileges to install files there. + +\section{CGI Symbolic Links} + +{\dsc} has a couple of CGI scripts that are installed +into \path|/usr/local/dsc/libexec|. You should add symbolic +links from your HTTP server's \path|cgi-bin| directory to +these scripts. + +Both of these scripts have been designed to be mod\_perl-friendly. + +\begin{MyVerbatim} +% cd /usr/local/apache/cgi-bin +% ln -s /usr/local/dsc/libexec/put-file.pl +% ln -s /usr/local/dsc/libexec/dsc-grapher.pl +\end{MyVerbatim} + +You can skip the \path|put-file.pl| link if you plan to use +{\em rsync\/} to transfer XML files. +If you cannot create symbolic links, you'll need to manually +copy the scripts to the appropriate directory. + + +\section{/usr/local/dsc/data} + +\subsection{X.509 method} + +This directory is where \path|put-file.pl| writes incoming XML +files. It should have been created when you ran {\em make install\/} earlier. +XML files are actually placed in {\em server\/} and {\em +node\/} subdirectories based on the authorized client X.509 certificate +parameters. If you want \path|put-file.pl| to automatically create +the subdirectories, the \path|data| directory must be writable by +the process owner: + +\begin{MyVerbatim} +% chgrp nobody /usr/local/dsc/data/ +% chmod 2775 /usr/local/dsc/data/ +\end{MyVerbatim} + +Alternatively, you can create {\em server\/} and {\em node\/} directories +in advance and make those writable. + +\begin{MyVerbatim} +% mkdir /usr/local/dsc/data/x-root/ +% mkdir /usr/local/dsc/data/x-root/blah/ +% mkdir /usr/local/dsc/data/x-root/blah/incoming/ +% chgrp nobody /usr/local/dsc/data/x-root/blah/ +% chmod 2775 /usr/local/dsc/data/x-root/blah/incoming/ +\end{MyVerbatim} + +Make sure that \path|/usr/local/dsc/data/| is on a large partition with +plenty of free space. You can make it a symbolic link to another +partition if necessary. Note that a typical {\dsc} installation +for a large DNS root server requires about 4GB to hold a year's worth +of data. + +\subsection{rsync Method} + +The directory structure is the same as above (for X.509). The only +differences are that: +\begin{itemize} +\item + The {\em server\/}, {\em node\/}, and {\em incoming\/} + directories must be made in advance. +\item + The directories should be writable by the userid associated + with the {\em rsync}/{\em ssh\/} connection. You may want + to create a dedicated {\em dsc\/} userid for this. +\end{itemize} + + +\section{/usr/local/dsc/var/log} + +The \path|put-file.pl| script logs its activity to +\path|put-file.log| in this directory. It should have been +created when you ran {\em make install\/} earlier. The directory +should be writable by the HTTP server userid (usually {\em nobody\/} +or {\em www\/}). Unfortunately the installation isn't fancy enough +to determine that userid yet, so you must change the ownership manually: + +\begin{MyVerbatim} +% chgrp nobody /usr/local/dsc/var/log/ +\end{MyVerbatim} + +Furthermore, you probably want to make sure the log file does not +grow indefinitely. For example, on FreeBSD we add this line to \path|/etc/newsyslog.conf|: + +\begin{MyVerbatim} +/usr/local/dsc/var/log/put-file.log nobody:wheel 644 10 * @T00 BN +\end{MyVerbatim} + +You need not worry about this directory if you are using the +{\em rsync\/} upload method. + +\section{/usr/local/dsc/cache} + +This directory, also created by {\em make install\/} above, holds cached +plot images. It also must be writable by the HTTP userid: + +\begin{MyVerbatim} +% chgrp nobody /usr/local/dsc/cache/ +\end{MyVerbatim} + +\section{Cron Jobs} + +{\dsc} requires two cron jobs on the Presenter. The first +is the one that processes incoming XML files. It is called +\path|refile-and-grok.sh|. We recommend running it every +minute. You also may want to run the jobs at a lowerer priority +with {\tt nice\/}. Here is the cron job that we use: + +\begin{MyVerbatim} +* * * * * /usr/bin/nice -10 /usr/local/dsc/libexec/refile-and-grok.sh +\end{MyVerbatim} + +The other useful cron script is \path|remove-xmls.pl|. It removes +XML files older than a specified number of days. Since most of the +information in the XML files is archived into easier-to-parse +data files, you can remove the XML files after a few days. This is +the job that we use: + +\begin{MyVerbatim} +@midnight find /usr/local/dsc/data/ | /usr/local/dsc/libexec/remove-xmls.pl 7 +\end{MyVerbatim} + +\section{Data URIs} + +{\dsc} uses ``Data URIs'' by default. This is a URI where the +content is base-64 encoded into the URI string. It allows us +to include images directly in HTML output, such that the browser +does not have to make additional HTTP requests for the images. +Data URIs may not work with some browsers. + +To disable Data URIs, edit {\em presenter/perllib/DSC/grapher.pm\/} +and change this line: + +\begin{verbatim} + $use_data_uri = 1; +\end{verbatim} + +to + +\begin{verbatim} + $use_data_uri = 0; +\end{verbatim} + +Also make this symbolic link from your HTTP servers ``htdocs'' directory: + +\begin{verbatim} +# cd htdocs +# ln -s /usr/local/dsc/share/html dsc +\end{verbatim} + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Configuring the {\dsc} Presenter} + +This chapter describes how to create X.509 certificates and configure +Apache/mod\_ssl. If you plan on using a different upload +technique (such as scp or rsync) you can skip these instructions. + +\section{Generating X.509 Certificates} + +We use X.509 certificates to authenticate both sides +of an SSL connection when uploading XML data files from +the collector to the presenter. + +Certificate generation is a tricky thing. We use three different +types of certificates: +\begin{enumerate} +\item A self-signed root CA certificate +\item A server certificate +\item Client certificates for each collector node +\end{enumerate} + +In the client certificates +we use X.509 fields to store the collector's server and node name. +The Organizational Unit Name (OU) becomes the server name and +the Common Name (CN) becomes the node name. + +The {\dsc} source code distribution includes some shell scripts +that we have +used to create X.509 certificates. You can find them in the +\path|presenter/certs| directory. Note these are not installed +into \path|/usr/local/dsc|. You should edit \path|openssl.conf| +and enter the relevant information for your organization. + +\subsection{Certificate Authority} + +You may need to create a self-signed certificate authority if you +don't already have one. The CA signs client and server certificates. +You will need to distribute the CA and client certificates to +collector sites. Here is how to use our \path|create-ca-cert.sh| +script: + +\begin{MyVerbatim} +% sh create-ca-cert.sh +CREATING CA CERT +Generating a 2048 bit RSA private key +.............................................................................. +............+++ +......+++ +writing new private key to './private/cakey.pem' +Enter PEM pass phrase: +Verifying - Enter PEM pass phrase: +----- +\end{MyVerbatim} + + +\subsection{Server Certificate} + +The server certificate is used by the HTTP server (Apache/mod\_ssl). +The clients will have a copy of the CA certificate so they +can validate the server's certificate when uploading XML files. +Use the \path|create-srv-cert.sh| script to create a server +certificate: + +\begin{MyVerbatim} +% sh create-srv-cert.sh +CREATING SERVER REQUEST +Generating a 1024 bit RSA private key +..........................++++++ +.....................................++++++ +writing new private key to 'server/server.key' +Enter PEM pass phrase: +Verifying - Enter PEM pass phrase: +----- +You are about to be asked to enter information that will be incorporated +into your certificate request. +What you are about to enter is what is called a Distinguished Name or a DN. +There are quite a few fields but you can leave some blank +For some fields there will be a default value, +If you enter '.', the field will be left blank. +----- +Country Name (2 letter code) [AU]:US +State or Province Name (full name) [Some-State]:Colorado +Locality Name (eg, city) []:Boulder +Organization Name (eg, company) [Internet Widgits Pty Ltd]:The Measurement Factory, Inc +Organizational Unit Name (eg, section) []:DNS +Common Name (eg, YOUR name) []:dns.measurement-factory.com +Email Address []:wessels@measurement-factory.com + +Please enter the following 'extra' attributes +to be sent with your certificate request +A challenge password []: +An optional company name []: +Enter pass phrase for server/server.key: +writing RSA key +CREATING SERVER CERT +Using configuration from ./openssl.conf +Enter pass phrase for ./private/cakey.pem: +Check that the request matches the signature +Signature ok +The Subject's Distinguished Name is as follows +countryName :PRINTABLE:'US' +stateOrProvinceName :PRINTABLE:'Colorado' +localityName :PRINTABLE:'Boulder' +organizationName :PRINTABLE:'The Measurement Factory, Inc' +organizationalUnitName:PRINTABLE:'DNS' +commonName :PRINTABLE:'dns.measurement-factory.com' +emailAddress :IA5STRING:'wessels@measurement-factory.com' +Certificate is to be certified until Jun 3 20:06:17 2013 GMT (3000 days) +Sign the certificate? [y/n]:y + + +1 out of 1 certificate requests certified, commit? [y/n]y +Write out database with 1 new entries +Data Base Updated +\end{MyVerbatim} + +Note that the Common Name must match the hostname of the HTTP +server that receives XML files. + +Note that the \path|create-srv-cert.sh| script rewrites the +server key file without the RSA password. This allows your +HTTP server to start automatically without prompting for +the password. + +The script leaves the server certificate and key in the \path|server| +directory. You'll need to copy these over to the HTTP server config +directory as described later in this chapter. + +\section{Client Certificates} + +Generating client certificates is similar. Remember that +the Organizational Unit Name and Common Name correspond to the +collector's {\em server\/} and {\em node\/} names. For example: + +\begin{MyVerbatim} +% sh create-clt-cert.sh +CREATING CLIENT REQUEST +Generating a 1024 bit RSA private key +................................++++++ +..............++++++ +writing new private key to 'client/client.key' +Enter PEM pass phrase: +Verifying - Enter PEM pass phrase: +----- +You are about to be asked to enter information that will be incorporated +into your certificate request. +What you are about to enter is what is called a Distinguished Name or a DN. +There are quite a few fields but you can leave some blank +For some fields there will be a default value, +If you enter '.', the field will be left blank. +----- +Country Name (2 letter code) [AU]:US +State or Province Name (full name) [Some-State]:California +Locality Name (eg, city) []:Los Angeles +Organization Name (eg, company) [Internet Widgits Pty Ltd]:Some DNS Server +Organizational Unit Name (eg, section) []:x-root +Common Name (eg, YOUR name) []:LAX +Email Address []:noc@example.com + +Please enter the following 'extra' attributes +to be sent with your certificate request +A challenge password []: +An optional company name []: +CREATING CLIENT CERT +Using configuration from ./openssl.conf +Enter pass phrase for ./private/cakey.pem: +Check that the request matches the signature +Signature ok +The Subject's Distinguished Name is as follows +countryName :PRINTABLE:'US' +stateOrProvinceName :PRINTABLE:'California' +localityName :PRINTABLE:'Los Angeles' +organizationName :PRINTABLE:'Some DNS Server' +organizationalUnitName:PRINTABLE:'x-root ' +commonName :PRINTABLE:'LAX' +emailAddress :IA5STRING:'noc@example.com' +Certificate is to be certified until Jun 3 20:17:24 2013 GMT (3000 days) +Sign the certificate? [y/n]:y + + +1 out of 1 certificate requests certified, commit? [y/n]y +Write out database with 1 new entries +Data Base Updated +Enter pass phrase for client/client.key: +writing RSA key +writing RSA key +\end{MyVerbatim} + +The client's key and certificate will be placed in a directory +based on the server and node names. For example: + +\begin{MyVerbatim} +% ls -l client/x-root/LAX +total 10 +-rw-r--r-- 1 wessels wessels 3311 Mar 17 13:17 client.crt +-rw-r--r-- 1 wessels wessels 712 Mar 17 13:17 client.csr +-r-------- 1 wessels wessels 887 Mar 17 13:17 client.key +-rw-r--r-- 1 wessels wessels 1953 Mar 17 13:17 client.pem +\end{MyVerbatim} + +The \path|client.pem| (and \path|cacert.pem|) files should be copied +to the collector machine. + +\section{Apache Configuration} + +\noindent +You need to configure Apache for SSL. Here is what our configuration +looks like: + +\begin{MyVerbatim} +SSLRandomSeed startup builtin +SSLRandomSeed startup file:/dev/random +SSLRandomSeed startup file:/dev/urandom 1024 +SSLRandomSeed connect builtin +SSLRandomSeed connect file:/dev/random +SSLRandomSeed connect file:/dev/urandom 1024 + + +DocumentRoot "/httpd/htdocs-ssl" +SSLEngine on +SSLCertificateFile /httpd/conf/SSL/server/server.crt +SSLCertificateKeyFile /httpd/conf/SSL/server/server.key +SSLCertificateChainFile /httpd/conf/SSL/cacert.pem + +# For client-validation +SSLCACertificateFile /httpd/conf/SSL/cacert.pem +SSLVerifyClient require + +SSLOptions +CompatEnvVars +Script PUT /cgi-bin/put-file.pl + +\end{MyVerbatim} + +\noindent +Note the last line of the configuration specifies the CGI script +that accepts PUT requests. The {\em SSLOptions\/} +line is necessary so that the CGI script receives certain HTTP +headers as environment variables. Those headers/variables convey +the X.509 information to the script so it knows where to store +received XML files. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Collector Installation} + + +A collector machine needs only the {\em dsc\/} binary, a configuration +file, and a couple of cron job scripts. + +At this point, {\dsc} lacks certain niceties such as a \path|./configure| +script. The installation prefix, \path|/usr/local/dsc| is currently +hard-coded. + + +\section{Prerequisites} + +You'll need a C/C++ compiler to compile the {\tt dsc\/} source code. + +If the collector and archiver are different systems, you'll need a +way to transfer data files. We recommend that you use the {\tt +curl\/} HTTP/SSL client You may use another technique, such as {\tt +scp\/} or {\tt rsync\/} if you prefer. + +\section{\tt Installation} + +You can compile {\tt dsc\/} from the {\tt collector\/} directory: + +\begin{MyVerbatim} +% cd collector +% make +\end{MyVerbatim} + +Assuming there are no errors or problems during compilation, install +the {\tt dsc\/} binary and other scripts with: + +\begin{MyVerbatim} +% make install +\end{MyVerbatim} + +This installs five files: +\begin{Verbatim} +/usr/local/dsc/bin/dsc +/usr/local/dsc/etc/dsc.conf.sample +/usr/local/dsc/libexec/upload-prep.pl +/usr/local/dsc/libexec/upload-rsync.sh +/usr/local/dsc/libexec/upload-x509.sh +\end{Verbatim} + +Of course, if you don't want to use the default installation +prefix, you can manually copy these files to a location +of your choosing. If you do that, you'll also need to +edit the cron scripts to match your choice of pathnames, etc. + +\section{Uploading XML Files} +\label{sec-install-collector-cron} + +This section describes how XML files are transferred from +the collector to one or more Presenter systems. + +As we'll see in the next chapter, each {\tt dsc} process +has its own {\em run directory\/}. This is the directory +where {\tt dsc} leaves its XML files. It usually has a +name like \path|/usr/local/dsc/run/NODENAME|\@. XML files +are removed after they are successfully transferred. If the +Presenter is unreachable, XML files accumulate here until +they can be transferred. Make sure that you have +enough disk space to queue a lot of XML files in the +event of an outage. + +In general we want to be able to upload XML files to multiple +presenters. This is the reason behind the {\tt upload-prep.pl} +script. This script runs every 60 seconds from cron: + +\begin{MyVerbatim} +* * * * * /usr/local/dsc/libexec/upload-prep.pl +\end{MyVerbatim} + +{\tt upload-prep.pl} looks for \path|dsc.conf| files in +\path|/usr/local/dsc/etc| by default. For each config file +found, it cd's to the {\em run\_dir\/} and links\footnote{as in +``hard link'' made with \path|/bin/ln|.} +XML files to one or more upload directories. The upload directories +are named \path|upload/dest1|, \path|upload/dest2|, and so on. + +In order for all this to work, you must create the directories +in advance. For example, if you are collecting stats on +your nameserver named {\em ns0\/}, and want to send the XML files +to two presenters (named oarc and archive), the directory structure +might look like: + +\begin{MyVerbatim} +% set prefix=/usr/local/dsc +% mkdir $prefix/run +% mkdir $prefix/run/ns0 +% mkdir $prefix/run/ns0/upload +% mkdir $prefix/run/ns0/upload/oarc +% mkdir $prefix/run/ns0/upload/archive +\end{MyVerbatim} + +With that directory structure, the {\tt upload-prep.pl} script moves +XML files from the \path|ns0| directory to the two +upload directories, \path|oarc| and \path|archive|. + +To actually transfer files to the presenter, use either +\path|upload-x509.sh| or \path|upload-rsync.sh|. + +\subsection{upload-x509.sh} + +This cron script is responsible for +actually transferring XML files from the upload directories +to the remote server. It creates a {\em tar\/} archive +of XML files and then uploads it to the remote server with +{\tt curl}. The script takes three commandline arguments: + +\begin{MyVerbatim} +% upload-x509.sh NODE DEST URI +\end{MyVerbatim} + +{\em NODE\/} must match the name of a directory under +\path|/usr/local/dsc/run|. Similarly, {\em DEST\/} must match the +name of a directory under \path|/usr/local/dsc/run/NODE/upload|. +{\em URI\/} is the URL/URI that the data is uploaded to. Usually +it is just an HTTPS URL with the name of the destination server. +We also recommend running this from cron every 60 seconds. For +example: + +\begin{MyVerbatim} +* * * * * /usr/local/dsc/libexec/upload-x509.sh ns0 oarc \ + https://collect.oarc.isc.org/ +* * * * * /usr/local/dsc/libexec/upload-x509.sh ns0 archive \ + https://archive.example.com/ +\end{MyVerbatim} + +\path|upload-x509.sh| looks for X.509 certificates in +\path|/usr/local/dsc/certs|. The client certificate should be named +\path|/usr/local/dsc/certs/DEST/NODE.pem| and the CA certificate +should be named +\path|/usr/local/dsc/certs/DEST/cacert.pem|. Note that {\em DEST\/} +and {\em NODE\/} must match the \path|upload-x509.sh| +command line arguments. + +\subsection{upload-rsync.sh} + +This script can be used to transfer XML files files from the upload +directories to the remote server. It uses {\em rsync\/} and +assumes that {\em rsync\/} will use {\em ssh\/} for transport. +This script also takes three arguments: + +\begin{MyVerbatim} +% upload-rsync.sh NODE DEST RSYNC-DEST +\end{MyVerbatim} + +Note that {\em DEST\/} is the name of the local ``upload'' directory +and {\em RSYNC-DEST\/} is an {\em rsync\/} destination (i.e., hostname and remote directory). +Here is how you might use it in a crontab: + +\begin{MyVerbatim} +* * * * * /usr/local/dsc/libexec/upload-rsync.sh ns0 oarc \ + dsc@collect.oarc.isc.org:/usr/local/dsc/data/Server/ns0 +* * * * * /usr/local/dsc/libexec/upload-rsync.sh ns0 archive \ + dsc@archive.oarc.isc.org:/usr/local/dsc/data/Server/ns0 +\end{MyVerbatim} + +Also note that \path|upload-rsync.sh| will actually store the remote +XML files in \path|incoming/YYYY-MM-DD| subdirectories. That is, +if your {\em RSYNC-DEST\/} is \path|host:/usr/local/dsc/data/Server/ns0| +then files will actually be written to +\path|/usr/local/dsc/data/Server/ns0/incoming/YYYY-MM-DD| on {\em host}, +where \path|YYYY-MM-DD| is replaced by the year, month, and date of the +XML files. These subdirectories reduce filesystem pressure in the event +of backlogs. + +{\em rsync\/} over {\em ssh\/} requires you to use RSA or DSA public keys +that do not have a passphrase. If you do not want to use one of +{\em ssh\/}'s default identity files, you can create one specifically +for this script. It should be named \path|dsc_uploader_id| (and +\path|dsc_uploader_id.pub|) in the \$HOME/.ssh directory of the user +that will be running the script. For example, you can create it +with this command: + +\begin{MyVerbatim} +% ssh-keygen -t dsa -C dsc-uploader -f $HOME/.ssh/dsc_uploader_id +\end{MyVerbatim} + +Then add \path|dsc_uploader_id.pub| to the \path|authorized_keys| +file of the receiving userid on the presenter system. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Configuring and Running the {\dsc} Collector} + +\section{dsc.conf} + +Before running {\tt dsc\/} you need to create a configuration file. +Note that configuration directive lines are terminated with a semi-colon. +The configuration file currently understands the following directives: + +\begin{description} + +\item[local\_address] + + Specifies the DNS server's local IP address. It is used + to determine the ``direction'' of an IP packet: sending, + receiving, or other. You may specify multiple local addresses + by repeating the {\em local\_address} line any number of times. + + Example: {\tt local\_address 172.16.0.1;\/} + Example: {\tt local\_address 2001:4f8:0:2::13;\/} + +\item[run\_dir] + + A directory that should become {\tt dsc\/}'s current directory + after it starts. XML files will be written here, as will + any core dumps. + + Example: {\tt run\_dir "/var/run/dsc";\/} + +\item[minfree\_bytes] + + If the filesystem where {\tt dsc\/} writes its XML files + does not have at least this much free space, then + {\tt dsc\/} will not write the XML files. This prevents + {\tt dsc\/} from filling up the filesystem. The XML + files that would have been written are simply lost and + cannot be receovered. {\tt dsc\/} will begin writing + XML files again when the filesystem has the necessary + free space. + +\item[bpf\_program] + + A Berkeley Packet Filter program string. Normally you + should leave this unset. You may use this to further + restrict the traffic seen by {\tt dsc\/}. Note that {\tt + dsc\/} currently has one indexer that looks at all IP + packets. If you specify something like {\em udp port 53\/} + that indexer will not work. + + However, if you want to monitor multiple DNS servers with + separate {\dsc} instances on one collector box, then you + may need to use {\em bpf\_program} to make sure that each + {\tt dsc} process sees only the traffic it should see. + + Note that this directive must go before the {\em interface\/} + directive because {\tt dsc\/} makes only one pass through + the configuration file and the BPF filter is set when the + interface is initialized. + + Example: {\tt bpf\_program "dst host 192.168.1.1";\/} + +\item[interface] + + The interface name to sniff packets from. You may specify multiple + interfaces. + + Example: {\tt interface fxp0;\/} + +\item[bpf\_vlan\_tag\_byte\_order] + + {\tt dsc\/} knows about VLAN tags. Some operating systems + (FreeBSD-4.x) have a bug whereby the VLAN tag id is + byte-swapped. Valid values for this directive are {\tt + host\/} and {\tt net\/} (the default). Set this to {\tt + host\/} if you suspect your operating system has the VLAN + tag byte order bug. + + Example: {\tt bpf\_vlan\_tag\_byte\_order host;\/} + +\item[match\_vlan] + + A list of VLAN identifiers (integers). If set, only the + packets belonging to these VLANs are counted. + + Example: {\tt match\_vlan 101 102;\/} + +\item[qname\_filter] + + This directive allows you to define custom filters + to match query names in DNS messages. Please see + Section~\ref{sec-qname-filter} for more information. + +\item[dataset] + + This directive is the hart of {\dsc}. However, it is also + the most complex. + To save time we recommend that you copy interesting-looking + dataset definitions from \path|dsc.conf.sample|. Comment + out any that you feel are irrelevant or uninteresting. + Later, as you become more familiar with {\dsc}, you may + want to read the next chapter and add your own custom + datasets. +\end{description} + + +\section{A Complete Sample dsc.conf} + +Here's how your entire {\em dsc.conf\/} file might look: + +\begin{MyVerbatim} +#bpf_program +interface em0; + +local_address 192.5.5.241; + +run_dir "/usr/local/dsc/run/foo"; + +dataset qtype dns All:null Qtype:qtype queries-only; +dataset rcode dns All:null Rcode:rcode replies-only; +dataset opcode dns All:null Opcode:opcode queries-only; +dataset rcode_vs_replylen dns Rcode:rcode ReplyLen:msglen replies-only; +dataset client_subnet dns All:null ClientSubnet:client_subnet queries-only + max-cells=200; +dataset qtype_vs_qnamelen dns Qtype:qtype QnameLen:qnamelen queries-only; +dataset qtype_vs_tld dns Qtype:qtype TLD:tld queries-only,popular-qtypes + max-cells=200; +dataset certain_qnames_vs_qtype dns CertainQnames:certain_qnames + Qtype:qtype queries-only; +dataset client_subnet2 dns Class:query_classification + ClientSubnet:client_subnet queries-only max-cells=200; +dataset client_addr_vs_rcode dns Rcode:rcode ClientAddr:client + replies-only max-cells=50; +dataset chaos_types_and_names dns Qtype:qtype Qname:qname + chaos-class,queries-only; +dataset idn_qname dns All:null IDNQname:idn_qname queries-only; +dataset edns_version dns All:null EDNSVersion:edns_version queries-only; +dataset do_bit dns All:null D0:do_bit queries-only; +dataset rd_bit dns All:null RD:rd_bit queries-only; +dataset idn_vs_tld dns All:null TLD:tld queries-only,idn-only; +dataset ipv6_rsn_abusers dns All:null ClientAddr:client + queries-only,aaaa-or-a6-only,root-servers-n et-only max-cells=50; +dataset transport_vs_qtype dns Transport:transport Qtype:qtype queries-only; + +dataset direction_vs_ipproto ip Direction:ip_direction IPProto:ip_proto + any; +\end{MyVerbatim} + +\section{Running {\tt dsc}} + +{\tt dsc\/} accepts a single command line argument, which is +the name of the configuration file. For example: + +\begin{MyVerbatim} +% cd /usr/local/dsc +% bin/dsc etc/foo.conf +\end{MyVerbatim} + +If you run {\tt ps} when {\tt dsc} is running, you'll see two processes: + +\begin{MyVerbatim} +60494 ?? S 0:00.36 bin/dsc etc/foo.conf +69453 ?? Ss 0:10.65 bin/dsc etc/foo.conf +\end{MyVerbatim} + +The first process simply forks off child processes every +60 seconds. The child processes do the work of analyzing +and tabulating DNS messages. + +Please use NTP or another technique to keep the collector's +clock synchronized to the correct time. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{Viewing {\dsc} Graphs} + +To view {\dsc} data in a web browser, simply enter the +URL to the \path|dsc-grapher.pl| CGI. But before you +do that, you'll need to create a grapher configuration file. + +\path|dsc-grapher.pl| uses a simple configuration file to set certain +menu options. This configuration file is +\path|/usr/local/dsc/etc/dsc-grapher.cfg|. You should find +a sample version in the same directory. For example: + +\begin{MyVerbatim} +server f-root pao1 sfo2 +server isc senna+piquet +server tmf hq sc lgh +trace_windows 1hour 4hour 1day 1week 1month +accum_windows 1day 2days 3days 1week +timezone Asia/Tokyo +domain_list isc_tlds br nl ca cz il pt cl +domain_list isc_tlds sk ph hr ae bg is si za +valid_domains isc isc_tlds + +\end{MyVerbatim} + +\begin{figure} +\centerline{\psfig{figure=screenshot1.eps,width=6.5in}} +\caption{\label{fig-screenshot1}A sample graph} +\end{figure} + +Refer to Figure~\ref{fig-screenshot1} to see how +the directives affect the visual display. +The following three directives should always be set in +the configuration file: + +\begin{description} +\item[server] + This directive tells \path|dsc-grapher.pl| to list + the given server and its associated nodes in the + ``Servers/Nodes'' section of its navigation menu. + You can repeat this directive for each server that + the Presenter has. +\item[trace\_windows] + Specifies the ``Time Scale'' menu options for + trace-based plots. +\item[accum\_windows] + Specifies the ``Time Scale'' menu options for + ``cumulative'' plots, such as the Classification plot. +\end{description} + +Note that the \path|dsc-grapher.cfg| only affects what +may appear in the navigation window. It does NOT prevent users +from entering other values in the URL parameters. For example, +if you have data for a server/node in your +\path|/usr/local/dsc/data/| directory that is not listed in +\path|dsc-grapher.cfg|, a user may still be able to view that +data by manually setting the URL query parameters. + +The configuration file accepts a number of optional directives +as well. You may set these if you like, but they are not +required: + +\begin{description} +\item[timezone] + Sets the time zone for dates and times displayed in the + graphs. + You can use this if you want to override the system + time zone. + The value for this directive should be the name + of a timezone entry in your system database (usually found + in {\path|/usr/share/zoneinfo|}. + For example, if your system time zone is set + to UTC but you want the times displayed for the + London timezone, you can set this directive to + {\tt Europe/London\/}. +\item[domain\_list] + This directive, along with {\em valid\_domains\/}, tell the + presenter which domains a nameserver is authoritative for. + That information is used in the TLDs subgraphs to differentiate + requests for ``valid'' and ``invalid'' domains. + + The {\em domain\_list\/} creates a named list of domains. + The first token is a name for the list, and the remaining + tokens are domain names. The directive may be repeated with + the same list name, as shown in the above example. +\item[valid\_domains] + This directive glues servers and domain\_lists together. The + first token is the name of a {\em server\/} and the second token is + the name of a {\em domain\_list\/}. +\item[embargo] + The {\em embargo\/} directive may be used to delay the + availability of data via the presenter. For example, you + may have one instance of {\em dsc-grapher.pl\/} for internal + use only (password protected, etc). You may also have a + second instance for third-parties where data is delayed by + some amount of time, such as hours, days, or weeks. The value + of the {\em embargo\/} directive is the number of seconds which + data availability should be delayed. For example, if you set + it to 604800, then viewers will not be able to see any data + less than one week old. +\item[anonymize\_ip] + When the {\em anonymize\_ip\/} directive is given, IP addresses + in the display will be anonymized. The anonymization algorithm + is currently hard-coded and designed only for IPv4 addresses. + It masks off the lower 24 bits and leaves only the first octet + in place. +\item[hide\_nodes] + When the {\em hide\_nodes\/} directive is given, the presenter + will not display the list node names underneath the current + server. This might be useful if you have a number of nodes + but only want viewers to see the server as a whole, without + exposing the particular nodes in the cluster. Note, however, + that if someone already knows the name of a node they can + hand-craft query terms in the URL to display the data for + only that node. In other words, the {\em hide\_nodes\/} + only provides ``security through obscurity.'' +\end{description} + + +The first few times you try \path|dsc-grapher.pl|, be sure to run +{\tt tail -f} on the HTTP server error.log file. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\chapter{{\dsc} Datasets} + +A {\em dataset\/} is a 2-D array of counters. For example, you +might have a dataset with ``Query Type'' along one dimension and +``Query Name Length'' on the other. The result is a table that +shows the distribution of query name lengths for each query type. +For example: + +\vspace{1ex} +\begin{center} +\begin{tabular}{l|rrrrrr} +Len & A & AAAA & A6 & PTR & NS & SOA \\ +\hline +$\cdots$ & & & & & \\ +11 & 14 & 8 & 7 & 11 & 2 & 0 \\ +12 & 19 & 2 & 3 & 19 & 4 & 1 \\ +$\cdots$ & & & & & & \\ +255 & 0 & 0 & 0 & 0 & 0 & 0 \\ +\hline +\end{tabular} +\end{center} +\vspace{1ex} + +\noindent +A dataset is defined by the following parameters: +\begin{itemize} +\setlength{\itemsep}{0ex plus 0.5ex minus 0.0ex} +\item A name +\item A protocol layer (IP or DNS) +\item An indexer for the first dimension +\item An indexer for the second dimension +\item One or more filters +\item Zero or more options and parameters +\end{itemize} + +\noindent +The {\em dataset\/} definition syntax in \path|dsc.conf| is: + +{\tt dataset\/} +{\em name\/} +{\em protocol\/} +{\em Label1:Indexer1\/} +{\em Label2:Indexer2\/} +{\em filter\/} +{\em [parameters]\/}; +\vspace{2ex} + +\section{Dataset Name} + +The dataset name is used in the filename for {\tt dsc\/}'s XML +files. Although this is an opaque string in theory, the Presenter's +XML extractor routines must recognize the dataset name to properly +parse it. The source code file +\path|presenter/perllib/DSC/extractor/config.pm| contains an entry +for each known dataset name. + +\section{Protocol} + +{\dsc} currently knows about two protocol layers: IP and DNS. +On the {\tt dataset\/} line they are written as {\tt ip\/} and {\tt dns\/}. + + +\section{Indexers} + +An {\em indexer\/} is simply a function that transforms the attributes +of an IP/DNS message into an array index. For some attributes the +transformation is straightforward. For example, the ``Query Type'' +indexer simply extracts the query type value from a DNS message and +uses this 16-bit value as the array index. + +Other attributes are slightly more complicated. For example, the +``TLD'' indexer extracts the TLD of the QNAME field of a DNS message +and maps it to an integer. The indexer maintains a simple internal +table of TLD-to-integer mappings. The actual integer values are +unimportant because the TLD strings, not the integers, appear in +the resulting XML data. + +When you specify an indexer on a {\tt dataset\/} line, you must +provide both the name of the indexer and a label. The Label appears +as an attribute in the XML output. For example, +Figure~\ref{fig-sample-xml} shows the XML corresponding to this +{\em dataset\/} line: + +\begin{MyVerbatim} +dataset the_dataset dns Foo:foo Bar:bar queries-only; +\end{MyVerbatim} + +\begin{figure} +\begin{MyVerbatim} + + + + + + ... + + + + ... + + + +\end{MyVerbatim} +\caption{\label{fig-sample-xml}Sample XML output} +\end{figure} + +In theory you are free to choose any label that you like, however, +the XML extractors look for specific labels. Please use the labels +given for the indexers in Tables~\ref{tbl-dns-indexers} +and~\ref{tbl-ip-indexers}. + +\subsection{IP Indexers} + +\begin{table} +\begin{center} +\begin{tabular}{|lll|} +\hline +Indexer & Label & Description \\ +\hline +ip\_direction & Direction & one of sent, recv, or other \\ +ip\_proto & IPProto & IP protocol (icmp, tcp, udp) \\ +ip\_version & IP version number (4, 6) \\ +\hline +\end{tabular} +\caption{\label{tbl-ip-indexers}IP packet indexers} +\end{center} +\end{table} + +{\dsc} includes only minimal support for collecting IP-layer +stats. Mostly we are interested in finding out the mix of +IP protocols received by the DNS server. It can also show us +if/when the DNS server is the subject of denial-of-service +attack. +Table~\ref{tbl-ip-indexers} shows the indexers for IP packets. +Here are their longer descriptions: + +\begin{description} +\item[ip\_direction] + One of three values: sent, recv, or else. Direction is determined + based on the setting for {\em local\_address\/} in the configuration file. +\item[ip\_proto] + The IP protocol type, e.g.: tcp, udp, icmp. + Note that the {\em bpf\_program\/} setting affects all traffic + seen by {\dsc}. If the program contains the word ``udp'' + then you won't see any counts for non-UDP traffic. +\item[ip\_version] + The IP version number, e.g.: 4 or 6. Can be used to compare how much + traffic comes in via IPv6 compared to IPV4. +\end{description} + +\subsection{IP Filters} + +Currently there is only one IP protocol filter: {\tt any\/}. +It includes all received packets. + + +\subsection{DNS Indexers} + +\begin{table} +\begin{center} +\begin{tabular}{|lll|} +\hline +Indexer & Label & Description \\ +\hline +certain\_qnames & CertainQnames & Popular query names seen at roots \\ +client\_subnet & ClientSubnet & The client's IP subnet (/24 for IPv4, /96 for IPv6) \\ +client & ClientAddr & The client's IP address \\ +do\_bit & DO & Whether the DO bit is on \\ +edns\_version & EDNSVersion & The EDNS version number \\ +idn\_qname & IDNQname & If the QNAME is in IDN format \\ +msglen & MsgLen & The DNS message length \\ +null & All & A ``no-op'' indexer \\ +opcode & Opcode & DNS message opcode \\ +qclass & - & Query class \\ +qname & Qname & Full query name \\ +qnamelen & QnameLen & Length of the query name \\ +qtype & Qtype & DNS query type \\ +query\_classification & Class & A classification for bogus queries \\ +rcode & Rcode & DNS reply code \\ +rd\_bit & RD & Check if Recursion Desired bit set \\ +tld & TLD & TLD of the query name \\ +transport & Transport & Transport protocol for the DNS message (UDP or TCP) \\ +dns\_ip\_version & IPVersion & IP version of the packet carrying the DNS message \\ +\hline +\end{tabular} +\caption{\label{tbl-dns-indexers}DNS message indexers} +\end{center} +\end{table} + +Table~\ref{tbl-dns-indexers} shows the currently-defined indexers +for DNS messages, and here are their descriptions: + +\begin{description} +\item[certain\_qnames] + This indexer isolates the two most popular query names seen + by DNS root servers: {\em localhost\/} and {\em + [a--m].root-servers.net\/}. +\item[client\_subnet] + Groups DNS messages together by the subnet of the + client's IP address. The subnet is maked by /24 for IPv4 + and by /96 for IPv6. We use this to make datasets with + large, diverse client populations more manageable and to + provide a small amount of privacy and anonymization. +\item[client] + The IP (v4 and v6) address of the DNS client. +\item[do\_bit] + This indexer has only two values: 0 or 1. It indicates + whether or not the ``DO'' bit is set in a DNS query. According to + RFC 2335: {\em Setting the DO bit to one in a query indicates + to the server that the resolver is able to accept DNSSEC + security RRs.} +\item[edns\_version] + The EDNS version number, if any, in a DNS query. EDNS + Version 0 is documented in RFC 2671. +\item[idn\_qname] + This indexer has only two values: 0 or 1. It returns 1 + when the first QNAME in the DNS message question section + is an internationalized domain name (i.e., containing + non-ASCII characters). Such QNAMEs begin with the string + {\tt xn--\/}. This convention is documented in RFC 3490. +\item[msglen] + The overall length (size) of the DNS message. +\item[null] + A ``no-op'' indexer that always returns the same value. + This can be used to effectively turn the 2-D table into a + 1-D array. +\item[opcode] + The DNS message opcode is a four-bit field. QUERY is the + most common opcode. Additional currently defined opcodes + include: IQUERY, STATUS, NOTIFY, and UPDATE. +\item[qclass] + The DNS message query class (QCLASS) is a 16-bit value. IN + is the most common query class. Additional currently defined + query class values include: CHAOS, HS, NONE, and ANY. +\item[qname] + The full QNAME string from the first (and usually only) + QNAME in the question section of a DNS message. +\item[qnamelen] + The length of the first (and usually only) QNAME in a DNS + message question section. Note this is the ``expanded'' + length if the message happens to take advantage of DNS + message ``compression.'' +\item[qtype] + The query type (QTYPE) for the first QNAME in the DNS message + question section. Well-known query types include: A, AAAA, + A6, CNAME, PTR, MX, NS, SOA, and ANY. +\item[query\_classification] + A stateless classification of ``bogus'' queries: + \begin{itemize} + \setlength{\itemsep}{0ex plus 0.5ex minus 0.0ex} + \item non-auth-tld: when the TLD is not one of the IANA-approved TLDs. + \item root-servers.net: a query for a root server IP address. + \item localhost: a query for the localhost IP address. + \item a-for-root: an A query for the DNS root (.). + \item a-for-a: an A query for an IPv4 address. + \item rfc1918-ptr: a PTR query for an RFC 1918 address. + \item funny-class: a query with an unknown/undefined query class. + \item funny-qtype: a query with an unknown/undefined query type. + \item src-port-zero: when the UDP message's source port equals zero. + \item malformed: a malformed DNS message that could not be entirely parsed. + \end{itemize} +\item[rcode] + The RCODE value in a DNS reply. The most common response + codes are 0 (NO ERROR) and 3 (NXDOMAIN). +\item[rd\_bit] + This indexer returns 1 if the RD (recursion desired) bit is + set in the query. Usually only stub resolvers set the RD bit. + Usually authoritative servers do not offer recursion to their + clients. +\item[tld] + the TLD of the first QNAME in a DNS message's question section. +\item[transport] + Indicates whether the DNS message is carried via UDP or TCP\@. +\item[dns\_ip\_version] + The IP version number that carried the DNS message. +\end{description} + +\subsection{DNS Filters} + +You must specify one or more of the following filters (separated by commas) on +the {\tt dataset\/} line: + +\begin{description} +\item[any] + The no-op filter, counts all messages. +\item[queries-only] + Count only DNS query messages. A query is a DNS message + where the QR bit is set to 0. +\item[replies-only] + Count only DNS reply messages. A query is a DNS message + where the QR bit is set to 1. +\item[popular-qtypes] + Count only DNS messages where the query type is one of: + A, NS, CNAME, SOA, PTR, MX, AAAA, A6, ANY. +\item[idn-only] + Count only DNS messages where the query name is in the + internationalized domain name format. +\item[aaaa-or-a6-only] + Count only DNS Messages where the query type is AAAA or A6. +\item[root-servers-net-only] + Count only DNS messages where the query name is within + the {\em root-servers.net\/} domain. +\item[chaos-class] + Counts only DNS messages where QCLASS is equal to + CHAOS (3). The CHAOS class is generally used + for only the special {\em hostname.bind\/} and + {\em version.bind\/} queries. +\end{description} + +\noindent +Note that multiple filters are ANDed together. That is, they +narrow the input stream, rather than broaden it. + +In addition to these pre-defined filters, you can add your own +custom filters. + +\subsubsection{qname\_filter} +\label{sec-qname-filter} + +The {\em qname\_filter} directive defines a new +filter that uses regular expression matching on the QNAME field of +a DNS message. This may be useful if you have a server that is +authoritative for a number of zones, but you want to limit +your measurements to a small subset. The {\em qname\_filter} directive +takes two arguments: a name for the filter and a regular expression. +For example: + +\begin{MyVerbatim} +qname_filter MyFilterName example\.(com|net|org)$ ; +\end{MyVerbatim} + +This filter matches queries (and responses) for names ending with +{\em example.com\/}, {\em example.net\/}, and {\em example.org\/}. +You can reference the named filter in the filters part of a {\em +dataset\/} line. For example: + +\begin{MyVerbatim} +dataset qtype dns All:null Qtype:qtype queries-only,MyFilterName; +\end{MyVerbatim} + +\subsection{Parameters} +\label{sec-dataset-params} + +\noindent +{\tt dsc\/} currently supports the following optional parameters: + +\begin{description} +\item[min-count={\em NN\/}] + Cells with counts less than {\em NN\/} are not included in + the output. Instead, they are aggregated into the special + values {\tt -:SKIPPED:-\/} and {\tt -:SKIPPED\_SUM:-\/}. + This helps reduce the size of datasets with a large number + of small counts. +\item[max-cells={\em NN\/}] + A different, perhaps better, way of limiting the size + of a dataset. Instead of trying to determine an appropriate + {\em min-count\/} value in advance, {\em max-cells\/} + allows you put a limit on the number of cells to + include for the second dataset dimension. If the dataset + has 9 possible first-dimension values, and you specify + a {\em max-cell\/} count of 100, then the dataset will not + have more than 900 total values. The cell values are sorted + and the top {\em max-cell\/} values are output. Values + that fall below the limit are aggregated into the special + {\tt -:SKIPPED:-\/} and {\tt -:SKIPPED\_SUM:-\/} entries. +\end{description} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chapter{Data Storage} + +\section{XML Structure} + +A dataset XML file has the following structure: + +\begin{MyVerbatim} + + + + + + + + + + + + + + + + +\end{MyVerbatim} + +\noindent +{\em dataset-name\/}, +{\em Label1\/}, and +{\em Label2\/} come from the dataset definition in {\em dsc.conf\/}. + +The {\em start\_time\/} and {\em stop\_time\/} attributes +are given in Unix seconds. They are normally 60-seconds apart. +{\tt dsc} usually starts a new measurement interval on 60 second +boundaries. That is: + +\begin{equation} +stop\_time \bmod{60} == 0 +\end{equation} + +The LABEL1 VAL attributes ({\em D1-V1\/}, {\em D1-V2\/}, etc) are +values for the first dimension indexer. +Similarly, the LABEL2 VAL attributes ({\em D2-V1\/}, {\em D2-V2\/}, +{\em D2-V3\/}) are values for the second dimension indexer. +For some indexers these +values are numeric, for others they are strings. If the value +contains certain non-printable characters, the string is base64-encoded +and the optional BASE64 attribute is set to 1. + +There are two special VALs that help keep large datasets down +to a reasonable size: {\tt -:SKIPPED:-\/} and {\tt -:SKIPPED\_SUM:-\/}. +These may be present on datasets that use the {\em min-count\/} +and {\em max-cells\/} parameters (see Section~\ref{sec-dataset-params}). +{\tt -:SKIPPED:-\/} is the number of cells that were not included +in the XML output. {\tt -:SKIPPED\_SUM:-\/}, on the other hand, is the +sum of the counts for all the skipped cells. + +Note that ``one-dimensional datasets'' still use two dimensions in +the XML file. The first dimension type and value will be ``All'', +as shown in the example below. + +The {\em count\/} values are always integers. If the count for +a particular tuple is zero, it should not be included in the +XML file. + +Note that the contents of the XML file do not indicate +where it came from. In particular, the server and node that +it came from are not present. Instead, DSC relies on the +presenter to store XML files in a directory hierarchy +with the server and node as directory names. + + +\noindent +Here is a short sample XML file with real content: +\begin{MyVerbatim} + + + + + + + + + + + + + +\end{MyVerbatim} + +\noindent +Please see +\path|http://dns.measurement-factory.com/tools/dsc/sample-xml/| +for more sample XML files. + +The XML is not very strict and might cause XML purists to cringe. +{\tt dsc} writes the XML files the old-fashioned way (with printf()) +and reads them with Perl's XML::Simple module. +Here is a possibly-valid DTD for the dataset XML format. +Note, however, that the {\em LABEL1\/} +and {\em LABEL2\/} strings are different +for each dataset: + +\begin{MyVerbatim} + + + + + + + + + + + + + + + +]> +\end{MyVerbatim} + +\subsection{XML File Naming Conventions} + +{\tt dsc\/} relies on certain file naming conventions for XML files. +The file name should be of the format: + +\begin{quote} +{\em timestamp\/}.dscdata.xml +\end{quote} + +\noindent +For example: + +\begin{quote} +1154649660.dscdata.xml +\end{quote} + +NOTE: Versions of DSC prior to 2008-01-30 used a different naming +convention. Instead of ``dscdata'' the XML file was named after +the dataset that generated the data. The current XML extraction +code still supports the older naming convention for backward compatibility. +If the second component of the XML file name is not ``dscdata'' then +the extractor assume it is a dataset name. + +\noindent +Dataset names come from {\em dsc.conf\/}, and should match the NAME +attribute of the ARRAY tag inside the XML file. The timestamp is in +Unix epoch seconds and is usually the same as the {\em stop\_time\/} +value. + + +\section{Archived Data Format} + +{\dsc} actually uses four different file formats for archived +datasets. These are all text-based and designed to be quickly +read from, and written to, by Perl scripts. + +\subsection{Format 1} + +\noindent +\begin{tt}time $k1$ $N_{k1}$ $k2$ $N_{k2}$ $k3$ $N_{k3}$ ... +\end{tt} + +\vspace{1ex}\noindent +This is a one-dimensional time-series format.\footnote{Which means +it can only be used for datasets where one of the indexers is set +to the Null indexer.} The first column is a timestamp (unix seconds). +The remaining space-separated fields are key-value pairs. For +example: + +\begin{MyVerbatim} +1093219980 root-servers.net 122 rfc1918-ptr 112 a-for-a 926 funny-qclass 16 +1093220040 root-servers.net 121 rfc1918-ptr 104 a-for-a 905 funny-qclass 15 +1093220100 root-servers.net 137 rfc1918-ptr 116 a-for-a 871 funny-qclass 12 +\end{MyVerbatim} + +\subsection{Format 2} + +\noindent +\begin{tt}time $j1$ $k1$:$N_{j1,k1}$:$k2$:$N_{j1,k2}$:... $j2$ $k1$:$N_{j2,k1}$:$k2$:$N_{j2,k2}$:... ... +\end{tt} + +\vspace{1ex}\noindent +This is a two-dimensional time-series format. In the above, +$j$ represents the first dimension indexer and $k$ represents +the second. Key-value pairs for the second dimension are +separated by colons, rather than space. For example: + +\begin{MyVerbatim} +1093220160 recv icmp:2397:udp:136712:tcp:428 sent icmp:819:udp:119191:tcp:323 +1093220220 recv icmp:2229:udp:124708:tcp:495 sent icmp:716:udp:107652:tcp:350 +1093220280 recv udp:138212:icmp:2342:tcp:499 sent udp:120788:icmp:819:tcp:364 +1093220340 recv icmp:2285:udp:137107:tcp:468 sent icmp:733:udp:118522:tcp:341 +\end{MyVerbatim} + +\subsection{Format 3} + +\noindent +\begin{tt}$k$ $N_{k}$ +\end{tt} + +\vspace{1ex}\noindent +This format is used for one-dimensional datasets where the key space +is (potentially) very large. That is, putting all the key-value pairs +on a single line would result in a very long line in the datafile. +Furthermore, for these larger datasets, it is prohibitive to +store the data as a time series. Instead the counters are incremented +over time. For example: + +\begin{MyVerbatim} +10.0.160.0 3024 +10.0.20.0 92 +10.0.244.0 5934 +\end{MyVerbatim} + +\subsection{Format 4} + +\noindent +\begin{tt}$j$ $k$ $N_{j,k}$ +\end{tt} + +\vspace{1ex}\noindent +This format is used for two-dimensional datasets where one or both +key spaces are very large. Again, counters are incremented over +time, rather than storing the data as a time series. +For example: + +\begin{MyVerbatim} +10.0.0.0 non-auth-tld 105 +10.0.0.0 ok 37383 +10.0.0.0 rfc1918-ptr 5941 +10.0.0.0 root-servers.net 1872 +10.0.1.0 a-for-a 6 +10.0.1.0 non-auth-tld 363 +10.0.1.0 ok 144 +\end{MyVerbatim} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chapter{Bugs} + +\begin{itemize} + +\item + Seems too confusing to have an opaque name for indexers in + dsc.conf dataset line. The names are pre-determined anyway + since they must match what the XML extractors look for. +\item + Also stupid to have indexer names and a separate ``Label'' for + the XML file. + +\item + {\dsc} perl modules are installed in the ``site\_perl'' directory + but they should probably be installed under /usr/local/dsc. + +\item + {\dsc} collector silently drops UDP frags + +\end{itemize} + +\end{document} --- /dev/null +++ b/docsrc/screenshot1.png.uu @@ -0,0 +1,578 @@ +begin 664 screenshot1.png +MB5!.1PT*&@H````-24A$4@```Y,```+P"`,````])M'[````!&=!34$``+&/ +M"_QA!0```O%03%1%!`($!+($_`($A(*$#$*L[.H$1$)$!/X$!(+\1(;D!`*< +MA,+\!&KDQ,+$)(;LQ.+\_)XD!"*4_$)$1&*T+&*\)"*$));\##*)$*L/)KT'&['1E;G-I;VX@-2XS+C,@*R!03D<@<&%T8V@@,2XR9"G< +M>Q,P```@`$E$051XG.V]?8#;Z'W?^8@ZS^UM.O%EV^[)(I%U>K;EU&Q39Y+N +M1;NKQQCZAK+&V[")0S>VTTW6=L=LZ[AMH#DZUVL[PPZ&I%UIM:N55G9?TDO? +M63=)G3K;BR_.NDESK9O8EXO?ZO&D=E)(7&9O9K"61[Z_#L_SX.4!"9(`"6"` +MF>]'$HF7!P\>4OCPP0,\SP^$`@"R!#GJ`@``?,!)`+(%G`0@6\!)`+(%G`0@ +M6\!)`+(%G`0@6\!)`+(%G`0@6\!)`+*%S\G3QY"C^F(!F!&_DT=5BN0XAA\) +M''/@)`#9`DX"D"W@)`#9`DX"D"W@)`#9(M-.=CNM>;/(VD<"8!IS.EG>UC6M +M=3#KWC?;6SK1=JVI#96H&T-K%PDQ9\W9`4Z"O#&?DXL&6:<]==;.0#V]896` +MK+#I!FD$E`Y.@A/'?$Y6B6J]-F=ULK+$2M`DY9&2V!"=UU_J"967;FBBQAJ7.E!'GFQNLD;BY,;J"J#5Z +MAF_;ZCHE6"0'HB3;Q!+QD)0H;9-%*MJ3;@;>EA&`DR!OS'U_LKS-I=0)ASKJ +MU31K8:LVNJ)/.OR2#MU;\$I0(@/^KC+_^*NB47L3-P-WRRC`29`W8N@SL,$N +MOA+%S5%HF]:W@%U$;!P:IK%D32MTKP9K:HIZV"G$K55/*P-TR"G`2 +MY(WYG-3O\%?#JML,-T?AY"HI5YAU(RMHL4\JE"Y5Y!)LD77VKHMZTCI1U51G +M$R\#>\M(P$F0-^:\%])DKYIU%EIQ+\#:]Q1KZB:_2"JMX$Y:6^Q821IZSU>" +MCB;.89WVY`+IVGFY&=A;1@-.@KPQIY/:*ETK:59]6#;4U;4NL]"I#DMDG;T- +MKR!E.B`K]/2FG<6NZ+]3YDW.HF:)UU0M,;M$W:BWV>U/-P-[RVC`29`WYG/R +MP#2(7N(UWJ!C:-;):KE/2(5?4.T2T?8;6M%1J^;*[IIJ-PSW-+N?ZPHO2:^I +M*$V>WYY).EW"&I-V!FQ+):J21S[O!R01.1F=B +MLS:JDR*SF=K*X'@2Q%0[-M-SXS&`EL(CCYV.777;WT +M/D-?>5O]PMN`MS1@:[ +M04RJ_0(N#8&3QL1Z\J[SQ*`]`EV\O';MZ]]]$JA\"RU7B[0"[<+5YYZJ5"XDK<>Z'`2Y`^,U0(@ +M6\#)R(3HADKSN\OS&^I%)J?P'#EWHT +MR;&4$DY&1NY&1Z7;_&-_Y?TU!IEP1(TYN@/J`R(7PWWU9^W;^W`64^NF!$L] +M5,#0I0[4]O@!)R,C'2Y#AR#Q)7%_Z8.KJ'%G7L0>=2*_C:O5O-\"J5[Q)N1C +M?=B1`,72++5;^BBEAI/'@B3K2?+0X?% +M&:?8L),9+S68W@GTRAU09[X.4J'Z#^@U7>48).1BZUWZWPI1YU\EAZ.=') +M+1+Y>8]9(W$GJ:]U*241_T;/`H>OY/M%\:WSOP6FI-Z.W(63<_%]BL#F6O*E +M]B6)4&I_GN/:MGEG4<;N))67@RN0.V7R6.B?`R3'8 +M=5#R4@+@!TX&0]Q72`G299J3K>Z"4>4/3E[J5'5].Z5BQ<;,3HJV#96_(0). +M++$3J#A!H@0Z6?)66Q+NL(NO +MI\DBF\W=95@X"?)&H).;U:*SVK1?3,V=S17S.1EXC0=.@D0)/G>]HSBK6_:+ +ML/'D..G-Q +M.X)YPXM(B+8DI7!R!N`D2!0X&1DX"1(%3D8&3H)$@9.1@9,@4>!D9.`D2!0X +M&1DX"1)ELI,W7SIW[I;U_MB%N[>NO36U0L4(G`2)$W,LK<)Z$X7FY/K3MPZ>O.EPJ-T^?(O]XJ.7"]>>QG57CON56?\'\><.\L>D +M>I)&?XPI^O%$!DX"/W`R$G`2)$Y0/Q[_71`X*9&!D9.`D2!0X&1DX"1)ELI,;'7/L7#Z`DR!O3'1RB\@/"/'/Y00X +M"1(GU3'-0P\(R=_C0N`D2![R"@T9=G-DP$F0.$%.RL_2BIJ=/.,5DE>Q2JFOVW$Z^+K["29`X$YR< +MY5+LY#@#W,(.6:-45>VYG#4JX21(G$`GW:=&)D\?;D/;*YNT3:]AQ% +M/2G>X"2PF7SN&I.3Z[JSFE6*>RVBK[MS)Z.>=&X`!WRA"]DL4-(LT@/#8T0?:_>8?,K64JUZN'C/7DW8;`O="0-H@]D=DX"3P +M$_.U(#@9&3@)_)#_T0%.A@!.@L1)QBSU)`_YH>U0G=)]O=.@VZ0XNFDN@),@<29>XQG7'6Q"=O*,STFB +M4GJ&T@-2I_3>]NY\I3XRX"1('$(,CJ\?C^\N2!Q.MBA=(!TVD%E7YRKN40,G +M0=X87T\V#@AIKE&2SS%:#G`2Y(WQ3E):[),*58VTBQ0KMFBO6 +M7*^BD=;Z$10M%N`DR!OHQQ,9.`G\8$QS).`D2!SRI`.<#`&#A0PE)9R,#)P$?N!D).`D2)Q` +M)_E5V-'7,-G),]X!7&YJ^F%<13Y*X"1(G%3JR:)VIEX=Q%+>(P9.@L1)Q"G"PJ +MS/@-/MW;5LP]T^C2PZ:B5/CH$&=J7V7)-E,N<$3@),@;T^M)0MH-RU.U27>; +M:E&>"EF='BEP$N2-$$[RZ6UBU8R'I"1/P4DX">(GK).JZKQZ4W`23OK`%Q(+ +MX^,,4+-EMIQI6S^%R%/VJDP#)U,$7T@LA*TG14A)59>G4$_B$)0XN5](ZO=" +MQ'3);466I/9D]N-,PLG4.+E?"#GKD*J31:U):5/MR5/4(.4XRI`DB3KYY)/Q +MYYY73IV"D[*3$?ON^+*39^P#N-PGI'(H37>MB5Y349K\_J0WM6*05L8C32;J +MY-FS\>>>3^Z__WXXZ7>2\+\T)B>/$W`R%4Z=0CTY7$_:3_")?CH+)R-C?V7\ +M_R#^W/,)G!SCY`Q*PLGHI.2D=3J88.ZQXIZYPDEOF?0O:G;R#)P,0TI.YN@` +M/W4*]>08)W'N.DJ(CS3NKA)Q7P*6I^-D+NK*4Z?@9.+778\34S_2V'N]8Q]$ +MGZZ36;?2.VV%DW`R%-,^DM`Q0$KWN=ZJ30=\#M9L"0TX2'^)W,3FL`YSPPSS!?<3`D)-'79RDF%NT"*2ZLQP1 +MY*2WBH%ZDH-Z,G;\]22K6([5W].SGHZ+'T%+K +M\$[<2;O+6EP9\NSBRLP%3J8TIOGX$+(?3Y0ODR<]Q4:%)%U/QGN8)^,,G+2. +MB/,.<#($2H +MDP'_PF8GSR3DY!F%&(JN;]?I%DD[U-WTOG61LX23([G"R;PY*6+ZE%MD0%,/ +M=1>BOVM4*^'D2*YP,I].T@'9'G$R\2=S3?](D:6$DR.YPLDQ[4G;QRRV)X6) +M[+S5[V3R3^8*=8TGFI5P&GHR5Z^O*)V$ +M]ASJ(T7['8.3([G"R2E.1K^P[Y!L/;E'5L34\).YJNH.U1/:<\B/!"?GRA5. +M3G,R@^U)A38V5'-'2#C\9"ZBUNB9A/:,>R'^#./*S)_K27?=!*+IQZN'T^DKQ-.CN1ZPIV,F32O\?`I]SJ/]V2NQH%!*FO)[!E. +MVL3<>=8%3L9.ZDZ:04_F*O9))9D]AQL7<@+ZUB7E#)R,G12ONXHI<_3)7$U* +M=Y+JWP,G_=G%D]EHOG`R/HZBGAQ^,I?U;\"NR29!V'/7"%G"R8!\X61\I.'D +M8HN03I=/=0CI%WU/YC):]SIJ54E(2?09&,HNGLQ&\X63\8&Q6I&!DP'YGF@G +M1_ZY`;)X\RJNVL,9>G;0(G_?G"R6$GB1QA/X/] +M78^.F9]-,&$3]@(G_?G"R2$GO;[G46.PG7@GQS_#9_P6[`5.^O.%DP%.#ID9 +M.CMYYB0Z&7T`)9P,R#>HL"?&T#'GKA1.!H)K//[LXLEL-%\X.7J-A[A.SC`8 +MT`%.A@%.!N0+)P.NNY)8Z\G'GKU1N/'L8_,4-!O`27]V\60VFB^FOYZKRE/7*2=3+)BQIY=S*I'6:0:?="XG"R=NY:C;U=N\'>GKLV +M9Y&/$CCISRZ>S$;S/=E.IM"/Y^G"-_C[-PI/6V9>NAO'CHX(..G/+I[,1O,] +MT4[&3*"3MPK7^?OUPBWZV'+!XD9A^5EZ_:7"2]OGR3K +M=PO.W.,%JV:\\!R;9?H];;GX#!/VG#5WVYIX76HEC@:<]&<73V:C^0J>?')D +M:>P[//X$UY-.K7?CLO528-=X;A:>I35^L8CV-TD8GV>=/PDG92>F&+9R<@T`G'RD\Q=^?8M==;0F?*KSE"O?.KB=?HLNW +MW0UOOE1X-(7"SD!2SVF&D_Y\3[23:=P+J=VXQ-\O+;/ZTJX/EV\]P]^YDV\M +MO)4^:IM+K[`:-:,W,>&D/[MX,AO-5YRYGE0G_S>'!,*R18@C;>RXD(<*'_&G?/FM +MXKV0JVX].;\7\F3FG61?PED/_]Y.N)/4=M+IB4["!1P8ZV3M\KFK]'K-6W#! +MGCZ63F:PGGR2^7CV2?>6WYPDYZ0/_][@I.NAZ^3TD[+QXR38ZJ37$1OW-:T[.29\0?P`[?M!N/5 +M*X7"E1R-JPSIY.A7-3[@6$I.\MSA9!Z8Y"0E_E&4\3F96\+&R!K^JB8$'(.3 +M,G!RXC4>.#G*/''KQ@P0AY,R<'+ZO1#?Z\SW0HX-8<]=`Q:/#!"7(T2[3H8+ +M*#T#KI/Q9&=E]HI7//ED/)E)##GI[#9./H)#I0@(GQS.IGA2WY/)5 +M3\:7F03JR=B9Z&17(8:I*)4]:WI+)]JN];ZA$G6#TO*VKFFM`^I-B<2F(GXK +MNA7%,)3F/3NG_4V=Z`?[B7^<$<+V&0CZ@9ODI#@"DW7R25]WM3F!D[EA2CW) +M'QRYH71VV+1X1F2#-"A=-,@Z[:E$GK*?,MFT)AL5X_0A;71;]G,GRVJGWJAW +M]'JR'R:`6?O63;O&DX:3_L-\3N!D;@CC)-U7%]ATDSW`56Q2)>SYYTP_;\I. +MO*Y3VM<&(D/A9$-OL2JV82KLK9O0(YD#F;D/.IE\+X0?@.?A))R,GU!.TCMD +MU9KN:1UG$T(L\VA]29[RGL:\1^RO6V9639H>28T+84:>AY-P +M,@&F.2GJM#HY8$GOD"U[$ZO5N"%2>%,B<<7ZUR=KOEPZ['378H=TK#J7G2GJ +M1%VA:TW27VN;YD:+=%B]>M@T5=9"[?45I1/3YPOG9*0+9G!2!DZF?=W5KOH: +MI,J3MM0=L.*:84VHJC\7S9G7-3O9KJI84XL5NFIMWAS<,[0B +M+:I;M,S:K%5K+WH<'R[P(P41?5P(G+2!D]81\=\[).=DR5MMGV>R*I!=T!'U +MI45]P9*I[9]R?RG(T-FI.Z^X:U=(W=I/E\TR_9;()BTQB:.#T>3 +M&Q<")VW@9#I.;E:+SFI_/4E+9.!L4MZV572G6.(&JR?UX7K2J?7<>I+V+`EW +MJ^XN]JT=Z([3?=(IQ_'9Y(\T'C)3'W0X:0,G@YUT+MS/<#H;?.YZ1W%6^]J3 +ME*ZI+6^3#:+ZIKA=3,XFZ?EVTB&[_+U!.FZ>"RH]<8]@->=BLVN)T_SZZYL:HNLLW>=ZZ0; +M\I1WBMH5=S(I'8B*](Y]&6B#77>UDVV0U?Z.NXLBZ5/5<`M2[)-*U$\2S'0G +M(_^6$?L`SY>3L68VFB^<'.MD].SDF7'GKD5Q?Y(OZ6C<_2:;UA;D*:=2M3S< +M)ET^N2*6[.C\+)5657;]U:X/U8YHMO*M[I$M6G$NX#;9%=J8;F*&LA(3UM]5L?N[6K-Z?\O.J7B@:OJFZ.^Z8I#J/4I[=DUH;:7K*\SW0M(^UN"D+]\@)Y,=-W-\.:(QS0N&W6`L]PFI%"ATR0,N%;&+$1WLFP7R><]`$G +MK2.HX)"PD[1')@7@.#Y.,B)$Y(&3/H*1(6U6JS%F]4 +MJW@)>^X*)V<$3HYQ6J&[3;5H*=DR>T); +M%M6JSD95=;3XHEK%2T@G(^0()WW`R6`G9^I][FWJXCG)$$..#U@PJWO;N]OD +MT*H7V<(V'[#,G.11K10>U8K&%M4J7I*]%Y+D,00CTO)%*.<-('G!SCY.QW1B:T)[=YY&0G<3-/)!A]/5;+C`Y18>[)'MEGX5:<]*4>U:F3S +MY@B)GU67?C@9,^X&3L!#G9U0E1>I:.56UAG_8J&FFM\_N3>I/? +MG]Q32+5+F)2##M$J`Q[5RLRDDG!2`"=S!,9J105.^O`I>1Y.Q@"<=..+A01. +M^I"-/`\GXP!.4O'`D-`YPDD?<#)VX&34YS3#21]P,G;@9*:=/)]Y)\^?YS*> +MAY.Q`2=GNN[ZY),I.6D11V9).BD#)V,`3D8=&&+7DG!2`"=C9YJ3&YT)\03$ +MHP;*34T_E)\Z$)SL:$CH7@B<=/`I68"3,3#.R6Y%,0REN4TF=9G3^]9+43M3 +MKR[RR4G)CHB$SEU3<-)IHL7G9"(/YX.3L1/L9*-BG#ZDC6[+G!AWI\J&6!YH +M[N2D9$=$_$[RR@9..L#)V`EVLJ\-Q(+)3G+T"0FZ1]XO/>RY:V0GK0,03E+A +M9*$`)V,DT,D]8D^5EZ8[.2%!HWKDP>UF=M*N.D==/7OV27;5-2TG"X4X,DO% +M23<8"IR$V%IKM\S%OM'JI?/Y9CUW=1X?."JE>X,\#2?9F+PX,DO.2>:C +M.WP03L9!H).J*B6PJKH66:*+I&FU#%4>"\M^$U6DJ"?9ZYH=3LM-+JTKJDT1 +M8JMK'?^=;INO3H'P<>L"5@0.@DO/25'U9-Y)&3@9`X%.RJ>C;'JSM$AW685) +MU!J+A66_#3MY0,H\G):;7%JW37IVB"U*]%V_]DDRQ[T0,CPP552H0TZ2I'"= +MC",SR2,MKGK2:0*CGLP!@4XVB=?: +MX_7=NKE99Q.-`X-4UIPWLZ&S'*2R^NXG0H_R#/EY+A?0O<*S[%P\JQ] +M\P9.YH!`)[M.'(]!VS[Q'#A6V;&PQ-MP7:C5^%9>\N$Z5'5;H=EQ4KP&*CGI +M&@\_!.'DD)/B"X&3#5F:3L["^/ZN.B%Z?Z5#2+/7U;7FH4F4_8Y:559JE+_1G0[1 +MVN4^(95#/FG5@Q7-:!NK#J,``"``241!5*WO.LG7Z(IAS8MUO::BL!!;Y2:Q +M=-ZTLCU,X_.%OL83&CCI`T[&#L9J105.^H"3L0,GHP(G?8QUDMU>A9.S`">C +MDE5XI.QE3#_H3!IR,"IST`2=C!TY&)==.ON(5KX@C.PDX&3MP,BJY=C+^ +M`L/)V(&348&3/L8XZ0ZKC'EW)X'I,;)8KYO7U)(OB=A3W,!)SA$Y&5/I3Q@3 +M8F01$2.+];I1PD2YNK>@$JUZ,&-!MLC4B`:S`"D +M,/<.FZ:Z67."7%4/Z1J/@;7)DRV0'2\?.Z47&,MJ+K86-"OQ]K9N[IE:EX71 +M4A=Z5F:FN=$BU0'?4W?!J/9HAZB;=*U)8HG4#" +MJZANT3I9H:O$"W+EG6YJTB9.2MI3*R(P%KU'SEB+^":DW1!1M[JDPC-K#NYI +MFI6&:.WN`=FF-97ENEB)Y?/!20Z5*9'DO2B:NCN@,-O4`!7A-0;++%4JRZ*<5"5H566<18O\;U.UYHNR+I +M2/;W+$-WJ_%\/CC)@9,Y(M#)BAPCRS'%JSR]@#I>[=BTFZ`Z:7@IQ6J6CR?+VDGX^_4[0`G3RJA8F2)"%B&NTV`DWM$ +M2,06NRFEP%A[)E'XQ5Q1M6Z3NBQAD34UO4AW&V2UZ45BGXOXG72?&0`G&7`R +M=H+O3Y:(:,W9,;+X2X5L.-NX`76DAN>"QNM6MMA-66+MR1[A'0X6=J2-Y3!: +M[&6+W/-%]U$[TSLIA`-.ENZ2]Y\5I9E&W]D48+?8R4*O4Y^0*68SI\\%) +M#IS,$6%B9)4[Q+":@H,.T2H#>MAD]R17V'(>`VO+V62I:A"US_*P4_+`6'J3 +MUY\]0R-$W:BSD%I=*WM=JY19U"U*#$715QK4VHF5K;6ZO\9^#.+Z?$DXZ3XU +M`$["R01(::S6NE6A'BX1+:``03WJ!O?BVG&R3B8Q<-\!3IY44G)2="G0E=$U +M@4X>-.+:,9SDP,D +M.AA]#BP+V=PL^I_K^!#D +M)%%-Q2"*J1*ZIQ.BL!L37848IJ)4]HZ@C/,`)SEP,D<$.ED67>=ZOBZM_$;B +MAM+9H7D"3G+@9(X(8'3OHR@Y,Y8%Q[TGV.\I"3 +M]`Z))P!`2L!)7V9).RF*.S0K`R>G,\Y)TW6RY9^HDP/:ZRM*)X7"Q4"J3L9Z +MP,')D\IT)X?JR0:ITJJZ0W6:"^"D+[/X@Y7`R=B)["2K+XE:HV>2+UL$/'== +M=^O)T_RZ:[%/XHF)G#1PTI<9G,P!(9TTG(DBNS_9I'0GD:=[Q`^<]&4&)W-` +M.">+Q)Y855IKO*//@,0XR#%!9G>22*\RN78RINR"^GA$IX>2XG.%D/&!<2#!"1N>? +M#)PD[QN`DG(P!.#F.<-=X +MX&3*3IZ`!BF<#,9I1$R[%P(GX63P3Y.2B0@Q%5QQ^Q\&3OHS@Y/9)[B>9`=\KT,F2!G\[!V&.<[)1E-K +M']+=KO-0RVJ8Y[[6"9$'H'A[A9-A@),Y9+R3M$([F1?JXN]F).%6I17 +MKAS8#V4?WFMFG)0.DE@O],/)0$ZNDRWO==R&XU:.JLFWZ +M6K4:N->0XU).BI-C#M6L.CE[./23ZR33HDQ*;'JM9'9:2Y0>-A6EPI^,U=A4 +M3),G.6R:ZF:-^H)FMT0=9.N-8G=;.R3?2KEOUM2I!S6VBUSL6]4 +M#^F:RNY";-H)NTVZ1`ZI?Z_.5&];-_=,K3M<#+DT<-*?&9S,/F.=W%VLLF%9 +M=%_O-.@V*?;4"MUMJD5+B9;9$]H6U2VKP;=BZ:=Y0;-,TJ-UDRS2FLH$6G3& +M/JM25"VNEIS#JN5AI]LF3>H_*RWMT3729E/>7KTI2DB[,5H,N339<'*6`^E8 +M.SF[62?720:O)>D!L5J!][9WMUEU=<@6M@E[M"MSHJ1:$XK.GF9`W:!9_-QU +M0!:LMB`96&F<<+!$>DBSZZ2;@Y7%KN6M2OU.ZI9R3;ZAMU=ORDXZ7`RY-'#2 +MGQFTYU^LPO2$&S1'M2T]A%HDVZZ[8& +M557::VLX!['(=*<$&V+U(I7WZDW93@X70R[-,75RY-SO:)RT]CKJI'_AT!:! +M3D;Y>DZRD]0Z867GKD[U)@Y_)HU8PN;=JJ]Q0$C3OFT^Q6I7IRN!AR:8[427>5F(AV.$5V,BAW +M.)E#)CBYRN]/JH98).I+UBAD5:!(XJRC[)%M=@'5:<]5G%X%31;WU3[EY%Z5A8!J1^H74+*? +M--(V/2?=',2BEN])7G1+B+7'$GE[[0^W)X>+(9<&3@X7.D(1DG72RQU.^IC@ +M)%W0=RP--6V]5S[=ZZF5&N777;M$WZBWF3EE0UU=ZR[PH%F+3C7(GY)7;;&' +M5M(5WA2TV2T9FW5KG=./AVGCYB"U)PWBM`;[XFF7#:,I[]6;LLLY7`RY-"?< +M2:=`(Y*$*DH,3@YG`2>G$^1DEST(ML?,TA;V::^BD=8ZOS^I-WF3<$\AU2YA +M4@PZ1*L,>-`LTPF:U2)F2X328O[Y=M:M6#GK_96.U=XK=XC1=G,X;+)[DBML +M.5TQC-:6G=.2];9O)6^Y>]6]_=?[A%18G3E4#+DTV7'2:@+"2;^33JL83OI( +M=JS6X%[<.48E.TX*:\+7EFJ:3 +M8^^D).6D^$*B.VFEA)-ST.JWEV+-MB-ML5B==&:3=C+T?N!D3"P8 +M&8C+G+23Y\]+D>OF=U):/=%);T_V%K[?!H\Q3@X+'*N35MG&.VD7@)7_[%GG +M4\!)'XC]$95A)R41AY_&,>RD>)V4^1Q.!C:T\N&D+R!G($Z"!)R,=C4\#>!D +M5$Z0DU.OIU@RS>6D_7U-OV[C)("3QX`C==)==5R=].EWA$[.X]4Q`D*9&:D^S?1">%-6YDF.9OR(5' +MROB^=>46&_XX9>NQ]201G=L:Y(CO4&;#2?L0G.ZD=+4CI)-GV?['.ND4:,C) +MX<3).2EG,>3D^?/G9W$RZ*FV)\5).B!3`\M-<+(I>JVF^D"B`'+FI+1ZHI,L +MP^2<=-:FX23OJ>,.BE>Y'?C3WF]?\1*-C/%2>E* +ML)B1'(C\I13Z+MT1T;`T.[:5SF-;U=R@5C&3HI-, +MHR$GG>/'[^3(+W-8)[UQ3NR8%M>#;">]"R:4CCAY2NIN8SOI'^[O<](IA>\' +M)/AH]>D7U4FQFA/%R:!.^>*K&,G$OVO^N>0D[H^:\P&S[:2%LK+F!+;RPLGM +ML_-9OY,6]75YSLVW1`9._G(*-\J'[L2VZDM!K6(F#2?Y_^J33[(CW_[=YPGY +M,>W(Q&=&G7S%*UY!)3,]"WQ..EGZG10'TWFV_[%.NDK[G702S^:D5_XYG+1^ +MO>)R4BKPR`II*I236;!RTC4>=T+QPN2PZLZ-.B=>ULW-NC09B3 +MWNZ]\O"OT?TRQ4H1V,&SC!=EHI/.#\@1UY>3GA="V>FGUYYDR^ZQBZG$592] +M&`H=YR3M:#S`CD)]E:MS[BK'MMH)^?R/J!R!D^X!SEIM]L]O@=MX7ERBL#L& +M>$>!79?YMG"OGO`D+$MQ9(KCI2#N`U+92>_`]KH4B*->[BIN.^GU>_6.RTE. +MRE='IC@9].W0$2?%Y2''2;.D<\)J?TRI"#3021>_D\YOI+N=_>7;,\-. +M'I&94^K)HF;YTE39C0MVIEE760CE*KDSN..*J9#!VFDI8A5G5_3?*?-PRD,I +M7"=%;*L.CVTU(,D,MDS127;D\QGG1(H==8Z3_(`H^.Y1,C-]3IX]&^RD^'T_ +M)8Y,]]"VLW$/\L)X)^7+HV>=U"R=LX6H-MURV94Y,]GYU#$ZR?;%RS7J)-NG +MTY7)^2SN)Z>BH`41-\0N@JW>6??5YZ2U0]9B/^5T-?:<=!UV+JNQ&7N!DT66 +MG%QLL8=WB.E>4U%$9"Q"3%U?8:H-%*-Y2(C29;&N>EU=:QZ:UIP3LYW'9S#JY`)\75E8*O9A%9.4E7:.;JTZ +MULE3_B&5GI/VIQ`7JD>=/"N^*>DTPZNRG`L[O*#\5T4ZH;=_S,Y*3KJ%M3M. +MV:O8MRM=UW8^DQ/Y0.3C9)$Q)\>DS/P8D"!2=]*YV&*;(#DITK*#]KQ[+)P] +MRW['SSM=[\[;9Z*VT'XGQ9%I'R]!3LK'_U@G>;/3<](^N!T)Q<;?MW_2SCJ&GN55KM]) +MY]MEL,K63N]&(W$R<%:$&&N="!&<3*;!ES!'XN0I<16&'77VS^^0D_S_7%SX +MX>>\3N]/<=2(H^>\G/]YVU*ING%,=@YR?O=N4HEG=CQ+4^)9NTP9X>[$9P7>3O5[["38LK60?PJB1-GVT9`J-.VEL$.BD$'^ND6^^Y?6%\3MJUC#T5Z*0]9V\N#O#"*>\"TWG1 +M9K/K+[L])G9K-^6<\\2`R!]CG.0&V`4?=M+WPV:7B']IKE_.C]LI^TNT/Z#L +MI/0M";=D)[T$?`7[7W0^_5GGYJCX'W&=/)\#)\NLM5A,NC3QDY*3-IY`GI/N +M"J]*D`X05\-3YX<9R?V\X^1Y[Q18[$-XX&;E..FH.M%)8;M]++-36:F0(K7G +MI%VW.D=RD)-^UYQ?"N<+\8H;X*3S;4AGH\Z7Q)SDOQ/>3X^\12!20>6OW/G) +M]+[RL^X-WO.VE>[_R=FI(U82`+$_HA+"2?<_/,C)P./'/4"DW(*<]-*=$CT4 +M1IV4[KJ(DU0YLV`G_;\44B%M)X,*ZM3<(9P<^8!3G#SO[<'[Y-Z7$O3]34*N +M2#F\#>WE7AARTCY'<+:-_0":"IR,RNAAR(^30.&F.^G5K$-;!#MIG4E*&=I5 +MB-A]X,$ZZHF[V%.G=QH),%7Q[G@YV4ZR'? +M(>MW4N@T\N,AEW&2D_(G\A4WBI6!3@[E'&!FP;?*VY%/.^^S!Y9CS@-HWF,N +M62>[S2,8X#SG1R*C4@8Z&7!\!<[(CA7\1\RD:J3@'-_>.>!N8]\'>YY0F&:DZ-:^#-QOS?YN_+E[_\IE+[;L:M&_[O<5?,=0+,= +M=!).GP&%$/7,&>M5T97*4*2LWF;5/)QE3XOB&>DI,Y^3A([6E$&'>=#Q%3A3 +M&'%2.L*\])-REK:0CC/_8>T>LM.**9=(WKFTRN=D<)&G?QW^U&.V'-)O="NY +MP),R"MIUH)/#&?MRSY23]D`0.U*6X8N4M:ZU9Q[`8>;<23&T+.1!&&UEV`/< +M=R!-31C2R=#[=&?"^QAE7[[?I8CY1RG):/Z3_D^<`87I$>RDZ3I)![X!&_?( +M7LB,%T=O9^;=26GA?%D>V>;8^=%L/L?.AIWD/7?8*&:'?2WLB*I&%4Z.S?+( +M-L?.CV;S.7;F'L`MKY[<(=6FH6[2G2;IT].D*R7O;>OFGJEUW4!:4D@ME57X +MFSP9"Y&E+O18KINZT5JE/)P6"[-E>N&Q6+BLS9J;96Q1L^*_QI/G@P,[/YK- +MY]A9T+DKBY2US4]B*VR4UGJ_I37=0!TB*E9/K8A`6M*4U!6/A3YX,#.CV;S.78V[*03*6N5 +MQ4_>W&"1K:Q:KMC2>L[67+QM1U.^P69&KICEKV=8+(CR6ZE[=$EDNQ!4U"TYBYT>^\WEV%M2>Y%@G +MKZNL<:CQJ%8UUS<[;A9_Y5&OW"EY&,D=.T26R-4TG+7LI<%&-Z]YX;+L[>S% +M\P,GL?,CW_D\.PMJ3W*LDU?^E*TJ7[Y#G,LO0DXOD-9P2"W.-JE+YZY4]8*` +M\*UY>"PO7);C>TQ1LXYA=T%PS`GG)%4W^1V1=6*U)^D>N>-LS5.46"NRQY[X +MXTU)-9\;1(OGR@.?4\/1MLF>O=7RPF796=J+YP=.@KP1TLD266=ONU6S2,NZ +M>\=2I.BIE1IUKKO:4]0@3H-0(8-]'B*+Y=JKMEA('Q%FRUIFI5JT+!7ALMRK +M/\[B^8&3(&\$.3GH$-+:Z%:]2%FT2_;Y>V-3U95V32PL.U&Q>DU%%X&TO*D5 +MPVAMB6UUK5(VB;)O$K-57=_ENQ!AMG06'LM<$?O4*@,W2V?QW,!)D#A*&VYS.ZF4./+.A\8V1-RY/_$,GWR>G1_M +M)Q_9./3.9P=.AH$0^2/N)`WWOSNRN;?]],V)^W,_Q\[ES6?8 +MN3,WX\ZES:/OW$DZZ]S['P>X&0H[/\;[W_7/2F;:7-_5B&W=@^. +MV78N'5N1=RX;/3X:<6Q.GDZ,4& +M&N7(E#;WIH_"R<@[C]/)&3YY?$ZF^JYV[7]Z,7[MO\Q0_^>P$.UE6.X/=>D<--U[J +MV#OI_KZZ4ME+PET7']VUBW*V]G@0@10*=[(@GG_.! +MDFMMT]QHD0Z+\KIV8'9:]Z@4$ZNQJ9@F=Y(%N3J@7M"KC``G0=X(=%)3[0E= +MHUWK_+DYN&=H1;JF=QITFQ1[:M..A-4PS9ZH)UF0*SXTLJK&%-TJ'N`DR!N! +M3KHGHSP>.F&*+9%->L"&1-[;WMTF/3L25EL$H6O90:YT*R51:_%$MXH'.`GR +M1G`]Z51T.H]GQ0S=)U4[LH<3"8N]*AJU$^A.D*M^7-&MX@%.@KPQI3TIC?QO +MN>$\Q`)6AWHQLMQ0'XT#@U3BB&X5#W`2Y(TQUUU%=)P-LD1M\8JD3U5-!!CP +M(F&)AB=+X`6YBBNZ53S`29`W`IWW'>V2+;A/14"RY[IJ3HDN+NP%) +MOGO+B6%,?]=BB?5W%7&Q"#%U?86U,`\K&JFNUZ1(6'LFZ70)LW;0,33V_-B. +M6E6RHR2=>M.7#M=X$@%.`A]!#4E_C"PWH2]\ +M%.Z%Q`:F0GI.OJ=%N,_7_53@)\L88)]?"Q\B2,9OCURG]Q2,XOX&3 +M(&\$.UE6._5&Z!A9+G5"QFM:YDF6-RC"P>Y8/WK6.=7EDMB8$74<1[$*L7J;.-\VH[V7+:DYKF +MYNJ^N'DOQ!MC"TZ"O#$Q1E:#L):=6YFY<;`L:+E%YA%X8:1LE+,%)/ +MMOCN3(..U)-2C"U"FO'%V(*3(&\$.GG'C9'%C'/;DUX<+'M(Y099]?1IJ/SA +M(DTWO*3[*A*[YZY45>B(DTG%V(*3(&^,N3\ISDBK*JLO#:<%Z<;!KB*5'&.K$>,H:C@)\D9P/YZ!UBS28E.MLYDJ +MN3.XP\01<;"\D*_L*L^BNW%?W--L&*Q_G<%"IMNO0^W)7K75D',5J=R\K9G% +M&&-LP4F0-\;T=]T_T#4G1M9`,9J'A`6G&W2(5AF(815:BYBL@\%^ +MAS#Y5@RCM<5?VPL\<:-#C#9+U*JN[_IS%6GMO%F,+3/&&%MP$N2-L>-"%LG6 +M]*T']V(N3NS`29`WQCK9T)0Z;4SI[WH0K3_L$0`G0=X8/WYRL6J0UJ1;A:U^ +M.UIWV*,`3H*\,<>8Y@4C0[&5QP$G0=Y`[`\`L@6.H[5HD'7:4S,8_Q-.@KP1[&1?&X@%IOM4+?M] +M<]..T=/03?8D]9JI[++.JVR@9?K16Z<#)T'>"'1RC]A3Y76WN[G]KJRUQ)@1 +M+X[6.@OOP6K1>@:[$,!)D#<"G>Q+85K]3KIAL-QQSSMLW+-"W&%<&0-.@KP1 +MZ*2J2@E\3K(P6`8/@^7&T=(U$?:CE,D'XL%)D#$DR!N!3C9)STL@.UEAK<;7\#!87GMRP4ZY0225LP*#Q>6B%U8SK;ARM):NNO,,F=8-F#C@)\D;P_3A7VD")T'> +M"*XG^9A(WIVNW#(&3E+_;,3]P$D`0A'LI.DZ20?N@\R'9F46IQH')P$(QT0G +M>1N05)VD_EF)1G6ZDVA/`A"*8"=;7CVYXSEIS_:V=7//U+KTL*DHE1ZE:RH+ +M/K#ISEM+2F:GM42E)6SC7E]1.JE\JH"/!$!.F'KNNN>,;Y9F"6DW+,74"MUM +MJD5GE3>_KW<:=)L4AU)TM!VJTW2!DR!O3'12H8T-5=EQDKJSHG&XS8)*'A(6 +M"(0O\.8/2)W2>]N[0RE8;)`SZ7RLT8\$0$Z8Z*2%LK+C)G5GA9,BXB2/E<5; +MB]Z\$V-K*,4"'XJ9+G`2Y(VI[4DIJ>F?$J]<7S[IS1-%3N>F:!P0TERCJ0(G +M0=Z8VIZ4DGI.\HNHHC94=6>5-Z_:P;*&4]!B/_!62H+`29`W9G-2Q$1GK<4> +MV:9VQ>C-E\@6'4YA;=*TJLJT[XG`29`WYG"RIU9J5%Q5-4A9GN]IVGJO?+HG +MI>#7>,ITT;V*FQ)P$N2-("<'+`C61I>%Q>JZZQ9;SFRY3TB%3?6:BM[D=Q]7 +M#*.UQ>Y&VO.]BD9:Z]1=LFCEV.QUU*J9LI)P$N0.C-4"(%O`20"R!9P$(%O` +M20"R!9P$(%O`20"R!9P$(%L,SLYBTZBR/N>'35,]\+)T&HGV8BD'>J_:T0@AVW94 +M+=*R\JDF^7QG.`GR1J"3FAV[@^H:[1(V'J1-FBSZP!)=M";XHM4#HE17VVR, +M]Q6[*#EFS(V=)(7T2;53"29`WQK0G +MQ?76!F$ADCTGU\W-NN1DB_I#8CE9VO6>M]C-X1[9W%TB;3>1J'113P+@$>CD +M';+!WS?X=5?7J&TRD*LV_L(BW#DAL9PL>;VW+BWVK-YK$7W=2X1Z$H!A`IW< +MT<7S"*HJN_[JUH>&0N6JS36M8BOL9,D=,Z3%;@Z4+MCA8D4E"BR*J5KO*[E'V">DG%X@93H*\,79,G +M%ZO6Z67,S]PQB77:>D];C3?72JC.MW54X"3(&T%.+BK$4'1U82-H`Q[::KCG3;3` +M6(D'%Y"`DR!O!->33)M>AXR1,J@W7*8"8TG`29`WQCM)>Z0SDEQ:/771*(LI +M!>&1@),@;XQQTAO=&+C1Z(HP@R"=P%AH3P(PG@GU9)F4V#2+=+59HVMMT]QH +MD>I`K.X0=9.N-4E?WL*7G`?&JAY:B[9:"[[`6*8=&*O75Y1Q57%J:RB1SPP5L5-1+1V +M]X`%QNIH.U2GR0(G0=X8XR2#UY(BTI4B(EU9+TM613.DH@.J?HC7179A1\F5,^2 +M<[?JY6,W$J7D3G"!*@^,I;N)W(',"Z03`DR!L3VI/;S*7A2%?\E4\M +MJ/2,%R;=J2<#`F-MDY7=/ZQJ"_MTT"%:A=^5-!1% +M7VG0Q8[5#&2KO2KN#-O"5'0>&(LG/VRR6Y$K++06[;'`6.J&'1BK8P?&6ECK +MJ%4S827A),@=$<:%#/>)&]P+MXMUJSX\7$HS,)8$G`1Y8PXG#\(-!+&?/I)F +M8"P).`GR1A0GY0N3';9YY[1C5BR>("3(&^$=K)L-0&;17=VP0C= +M$F2!L5H':0;&DH"3(&\@]@<`V0).`I`MX"0`V<+O9/OT,:,-)T'>(-.3``!2 +MQ%]/\IKE6/U%/0GR!MJ3`&0+.`E`MH"3`&0+.`E`MH"3`&0+.`E`MDC,R=?4 +M9M\VQD=OP4F0-^)TDJBF8A#%9.$&J-*?EKR\K6M:ZV!T19R/WH*3(&_$ZN2A +M",#38YE6MZ>D7C3('=I3`SL2P4EP3/UNHN&`MKBTW^'"WGF5L"A;BA +M8-=*9J>U1-M*7>E;@),@;B=63EE;\V5JK):)45]LLWKGSS"W! +M!GM,$`\FLJ]W&G2;%%MDB7;=!W#Y4\\*G`1Y(VXG6Y*3XME:.^(!6YK\S"U. +MO6]9R9P[('5*[VWO;I:Z4I3TH=0S`B=!WDBNGFSY7MAR[YE;-O5MPI[MHZO> +MDCON)B.I9P).@KR1Y+FK_,+J3S(:XG65/8/277['W*Q[3RZ()2`LG`1Y(RTG +M>3WINT>B\T=MZ9JW?)N=P[J;J*'NJ$P#3H*\D7![TN>D]\PMGJ#)7K6.U7(D +M6WR)H2/-]J3WS"V>0%NE.R7-JAI[FK;>*Y\^5,A@_S1QQ/2G +MGA4X"?)&O$ZR1VZU6/76Z!"C+9ZM52'D@!X8I'GH/:*+<6`:1"_Q\.B]BD9: +M2[2K:Y6R290-\>`N7^I9@9,@;V"L%@#9`DX"D"UB[8.>"/.5"4Z"O(%Z$H!L +M`2Z"$^!*42K61&]; +MM]J8!TK+FE+,/=/HIECF,@R3&Z6Z);+.054VZVU194"MI:"1I +M-U(KZDS`29`WPIR[[K"+K]O$JB,/28F.#%?.-'`2Y(U0[4D>BH,'LN*OGK1?A'X*D9?%&*\\*>`DR!M3VY-.=2@"/JHZ13T)0)*$/GU)OYB9 +M!DZ"O!':R:+6I+2ILKLB57)G<,<3,]/`29`W`IW<[U0):76*M-YA4:[ZA/37 +M:*^I*$T>TFJ@&,U#0A3V<(%*IN].PDF0/S!6"X!L`2N(&3(&^, +M=?+Q0H&]P4D`TF6$DVI,`I$JPD[5+'Z&VDW>? +M>^#VI9O6U,4KY\Y=L29N/G/.JCLOG+MF3=VX^XV[EY]+N>%1 +MZCAY^://72@\PVK.1VOTRO)CU#Z?%2^%CUY/M;B1@9,@;P0Z^;ISEFG7W/9D +MC9W`/E.PZLB+S$[9RTVIGB!DP#$ +M3)"3SUR^>_?:W=N%N]=JGI-"OW,%BGH2@"09WV=`NN[*7FY(]:3G9.:ORL)) +MD#>F.NGX=Z%PD=*;A0O6[.UEBGH2@(0([>3-Y2N47EEF=T4N%1YY^9'".0HG +M`8B?\4ZRZZY7;Q4*S]*7"H67KM.;5\[=8/M%5S#MP$N0-C)\$(%O`20"R!9P$(%O`20"R!9P$(%O`20"R11@GNYW, +M/_IU+'`2Y(U@)XOW^H:[=)%D_Y%V8X&3(&\$.KEB;JOR"C@)0&I,>R:L2(1S +M5P#2(IR3J"K*^SB1[9I+O5M,HW+W`2Y(TI3@H;^>NZN5GG +M$PLJ/;.>6@'G!$Z"O#&E/:FI/)&EXC8[9>5.;I#5_EIZ)9P/.`GRQI1ZB.SD@K:24%$2`4Z"O('8 +M'P!D"S@)0+:`DP!DBSF=W,AZ^"PX"?)&B!A9$]C*?/@L.`GR1J"3FRU_C*Q) +MV\-)`&(E5#R>2=O#20!B96XGT9X$(%8F.]G4M&TV8'*?]OHL*M9ATU0W:U2: +M8/5DAYBK:98Y"G`2Y(TI]61%MUZ:9(O2Q05*B^H6K9,5:8([N=Y,L<`1@9,@ +M;TR),W"&'-)&JU^A=&6=TA*+.J#HT@1SIT)'`GV+EK12LF76R13(:<`!.@KP1Z.2*&3I&EI<1ZDD`XF#>>#P675Y#PDD`8F%^)QM5;B.< +M!"`6)CNYUFZ9W06CL[/8-*H]RF)C*4JE)U8L]HU6C^[SF`.;E+2LA#Q-IH"3 +M(&],'C_9M73KK!X0I;K:9@-`BFJ3[C;5HEC1;1,6'4O4D,0XW2V1[12+'@HX +M"?+&M'-7HN_2':+N4JIJE&ZSP92'I&2OH"J+E47<<]>=[%U\A9,@;TQUTG1> +MV!+NH&2B2:CL9`8;E7`2Y(UP3K;L)<(YQ351."FNN[;F!:/QZO^ +MV!)=U),Z13T)0$),K2=Y]>?X5Y+:DT[=:0>6A),`Q$*T]F11:U+:5'M4JCNI +M0J(D96N4F,36J]'-`#0IJ'M-=4E*:E)`N.M4(W^;(5PVBU +MJ^P>99^0?L:"9<%)D#0/O.>=?^'/LHF?_2-?_IG_&IBD\3>_^/:/_^(/ +MCZ[XX?_Y2]_^Q;^Y&[C1?_V9+_^1GV43?_8OO/,K/S!;V>`DR!LQ./F/W_/M +M+_RQOV=-_.P/_L<7_LEO!B5I_.'?^TL?^MSS/S:ZYLMO_-R'_M*_^\.-H*U^ +MYI^\\!]_D$GY]_[8"]_^GG\\4^'@),@;\SOY*U___0]][EL_2>DO_-!W_^KG +M7OAR0)+&/_V]G_^E#WWH;9\:7?5C;_O0AW[I^7_W3X.D_/(+G_O5[_[B+U#Z +MD]_ZW(?^KZ__RBRE@Y,@;\SMY*_\Q+=;NGWK*_07_I=_],\L[P+JPL:_^7]> +M^-57OO*7WO:#H^L^]?POO?*7?O7C_\V_"9"2^?K+_^CW?H%^Y9];XO[^?_Z? +M9B@>G`1Y8UXG?_=/O_[#KWSE*[_UGA_XVL]]VIIX_E,C25[S#W_K71_^Y0]_ +M^,//?W%T^Q]\_L.,=_W6/QR5\E//6QE^^N>^]@-?^98U\>'7?_UWHY3?_$/7O\G?]GB6U__R1_]Q(>MB>='ZL+&J[[^^4]S'ORAT0Q^Z'FQ[N/_ +MWZM&I/S4\__LEW_YPY_XT9]\S__*]O$GW_<'?S%R`>$DR!OS.?G:'_F-3_SX +MIZT_;__*7_[$C[.I_W>X+MSY5W_PQF\3//@[HSG\SH.?$+SQ3_^K82F_^*"5 +MXX]_^A-_^;?>SO;QZ4_\QG?\WU%+""=!WIC'R<:[O_"F#WS;![[-^ON]+_"W +M;_O`<%W8>/=W//C)#WSR`];?3W[U:Z-Y?,]7/V#S\]_Q[AW_NB\^:&?ZPB?M +MB?_C"\-II@$G0=Z8Q\F_\>:'W_:]G_RD]?>3W^O\_>J0DZ_ZPMO?\8Z_8_VQ +M7E_]SM$\OO;JO^/P&U_X/O^ZWWF?G;>[D[<]_.:_$:V,=/0^>D;?O2%+WWI!>N/]?KB5T;S>.>;ONM+WV6M_"Z+'WV#?]WO +MO)KEZ&9M_?W@B]_YAM$\)@$G0=Z8T\G[7GS^\R]\_FV??\'Z^WDV]<3W#*7Y +MSN?#'(R?<\\?SGK3_L[_/#OGW/$V_[^-L^;N7Z@O5NO3W_XHLO_C2< +M!,><^]^.JO/OB^][WO34\\\:;W??7!%X?:C-_WYH??],2;GOC@ +M?8ROC^;QGA??]VKVY\7[[OOLFX?.7;_VP:]^]7VO?N*#KW[U^ZR)]UE)[OOL +M%W#N"HXY167\N&''[[/^7/?PT-MQIUW?^&S]SG\]F@>?_4^J_)CMEE* +M#E^_^=I]+[+<[_-R_^R;7X5K/."8,^>]D#=_Y\.E7[%5_Z#M^VDGSVJ@EA),@;\S99^"U;_ZY#S[QP0]^ +M\-^__PO_@4T\\<'W#">QI/RL=>K*_O[$:`8_(=8$U)*6DV_B>?^''WG_O_\@ +MX^>B*PDG0>Z8MV_=:[_P7U[_^@=?_XOO__,_]2>LB;>__G\826*=OG[W;[R) +M_?G,Z/:?$6N^.^C&XWO>]WHKRS_QF3___E^T=O'@?_E"="7A),@=<_=!?^TW +M?_WGW_C\G_HF?>]G?OWY-S[_QO]]-(DEY=M__D'KST^-KOLION+M@7T!?MO* +M[OE?_Y'WTH_]J>??^/-_^YLS*`DG0>Z8?ZS6:S_V_>]ZU]_Z)J7O_1%KXEU_ +M-2"))>7O?_R-;_S\^T=7O?F-'W_CQW__IP*[Y_RVE=VW/O->2K_YM][UKN^? +M24DX"7)'#&.:7_O-?_Z.=[+;&._]S*^]XS?_7%"2M7=_[/_\TI?^3("3[_\S +M7WK7]W\LN,? +M/_Y3_^GO!R;9^;Z/_=K?_=?_`D +M`-D"3@*0+>`D`-D"3@*0+>`D`-G"[V3[]#&C#2=!WB#3DP``4L1?3[**Y5C] +M/8UZ$N0-M"2/9>O*05/C[@IQSG9#A^#O54MQ[ +M=H"3(&\D?.ZZ3>K6ZZHNGYMN;I*EV'3=*EISORDFZ3+I%#:Z)CD&KCM&IT&B6E9>G;5Y3.F%QF!TZ" +MO)&TD_M&M:C5Y26E/;IFM-G4%KE#UW16AQ+3:E.J.U2/??]P$N2-Q.^%K!#% +M=P&GQMJ6385/-[5>A=O)G"1JC9Z)??=P$N2-Q)UL:&1?GM\@G$4VO:_JXK8( +M<[)/.N7X=P\G0=Y(OL^`:>_";)E6JY%6V+GJ:PQ1=YXFZZ(4UIK&@4$JP0\I +MF`,X"?)&>DX*&FJ#O54T]KIO-@W>UF3U)*7%OGT[,T;@),@;:3NY):P[0UAU +MN;"WIIK,4>:D=1:[P^K+>(&3(&^D[61?7,9I&):"[0J[]KI-[6L\93H@*W'O +M'4Z"O)&TD]T.(=4M=[9%3-:'IV@M;76(LD<7K-4[':*U:4>M*K$K"2=![LC& +MN)#D.(8?"1QSX"0`V2)9)TEDXBX!G`1Y`_4D`-D"3@*0+>`D`-D"3@*0+8[( +MR;=>>\OXE4_?>BJV'<%)D#?&./G8LS<*-YY]+$)&SYTKW#YW8_G6!-<\'KAT +M>#;"GB<")T'>"';RXO*MJ[6KMY:O1LFJ<)?2F[<*WYB>\MG+ +M`;;?O%%SIR\6WAIESQ.`DR!O!#I9.W>-^5&[)FDR'>8DO5FXY5OXW+71A(\5 +M'@_8_-&GI9DK-R+L>!)P$N2-0">?MBN[;Q2>'DX_@<(U[]6A=NGN:,)'"B^/ +M+KQZ3I[[2"&F)B6O\_;I5Z=U\YIREU85S3+6+5^XN/UNS%MVX +M^XV[EZ\5EI^EUU\JO&1OQ>O)BX4+;,-G[UZ[_,!-^MARP>)99T.;EPKVY-.W +M+MU8?L9>^#KKY>9+Y\[Q>O9J8%4Z`W`2Y(U`)R\OVQ/+;(*[QEX>6_Z(+4NA +M\-'KM+;,5KS\J+.UE:3V\K5+K*EXS6H//E1XU-G8VY!S[C)_J]VZ=M.M5\4Y +M[J7+URD_:WW,-7U.X"3(&X%.%IP3SKL%*CEY@1EZ[H:;X'%V#GKA.6=K5B7R +M6M):PY9RVWA*;T/.;7&:^DCA(6]?E_CUVMM6PM>)S`+:H;,`)T'>"*XG'7UN +ML!I-N&6]\!/1@JLIO6F=E=8\=ZR%U]_JUH97'Q$NL_7>ADY"QMW+WLPW'N"+ +M'B@\8%_JA9/@I#*F/2D:?#5^$=6M)PON91C;J@>6Z>N\JT!\X3.B*?K(W6>O +MNMM)&W+L>E(L%5F=$RK6+MPN/'J=[QE.@A-*H)./V%<]G^+775VWEF\["6UC +MGBJ\Y[CF^Z:.%J_*YJ[O,EW@Q%>Q*<6(+O +M3]ZXQ-\O+;/Z\K9SH>=1]P:%T^!GJMVPN_5<<6K(JX68>O+`29`W@OOQO'SYRF/TYA71C^=2X9&7'V%N7;R] +M_-3UY]S366I?Y7$0"Q^X8=6<-PI7'^.;T-N%B_*&G$>XC%:5>NVBU2:UMOJH +M(Z"5^"$N->Y/@A/+N/ZN%Y8O._U=7SYW^\K%0N&&-77K]O*5J_3J2X7"%7ZY +M]:;7ZGON1J%PSJKN;EZZ_,!CS]VX?.7BM<*YQ^CCMV]?^XBSHE5N@U +MJ?.YPU7T=P4GEK%.UBZ?NTJO3^GO>B%*?U@I;VE"'+RC$(,1=>WZS'D7]3.U*L#,;V_J1/]8'_R!E3OQ[!;%S@)\D9P/ +M!UEND<'\^1]H[F19[=0;]8X^1?5J:?Z]>L!)D#?&.TD'_'&MX>D&/619-YVI +MAMYB9Z4-4XGUY'0*I1LYP1.@KPQ +MQDEFXQJI4GK8--4#2GO;BKEG&EVZ=F!V6O?>SP)1;5)=YMJT;=0 +M4^T)77.6LY?A/?@75M4=JL_S^>`DR!MCG%1H8T-5=FB)B:0S*X18;?N&AK2<)15.NC5>*:@]N:-7^7M5Y5=R'&&']^!?V&1ZSA.' +M```!'4E$0537:2/=DAD"3H*\,:6>+!OJZEJWXR[JJ<9ZKWRZ-[2\Q;(QB-/T +M*VJ62TVU)^=$Z4!M%FFQJ?)^/%5R9W"'B3F\!]&'R%EH93G@%V5G!4Z"O!'D +MY&*+W>`0TX..H57JM-PGI,(6'58T4EVONF.U5HD +M6TGO8@@X"?)&NDXV-&40\V"L*0)P!`+(% +MG`0@6\!)`+(%G`0@6_B=;)\^9K3A),@;9'H2`$"*P$D`L@6Servers/Nodes [$navbar_servers_nodes] + + + [$img_with_map] +
+ [$description] +
+ +
Plots
[$navbar_plot] @@ -54,12 +62,6 @@ [$navbar_yaxis]
- - [$img_with_map] -
- [$description] -
- debian/patches/debian-changes0000644000000000000000000000451512063113764013400 0ustar Description: Debian source patch Author: Marc Haber Forwarded: no Upstream's Makefiles are kind of broken in a way that debian/rules clean cannot be repeatedly called. We cannot patch this via a quilt patch because the build process calls debian/rules clean even on a clean package tree. While the package is mainly patched via quilt, the Makefile patches had to be directly applied in the source tree. If you know of any way to do things more cleanly, please file a bug in the Debian BTS. --- dsc-statistics-201203250530.orig/collector/Makefile +++ dsc-statistics-201203250530/collector/Makefile @@ -1,3 +1,19 @@ -all clean install: +# this could be written with make -C +all: (cd dsc; test -s Makefile || ./configure ; $(MAKE) $@) (cd cron; $(MAKE) $@) + +install: all + (cd dsc; $(MAKE) $@) + (cd cron; $(MAKE) $@) + +clean: + (cd dsc; test -s Makefile && $(MAKE) clean || true) + (cd TmfBase/Hapy; test -s Makefile && $(MAKE) distclean || true) + rm -f dsc/config.h dsc/config.log dsc/config.status dsc/Makefile + # TmfBase/Hapy/config.log TmfBase/Hapy/_configs.sed \ + # TmfBase/Hapy/config.status + #rm -rf TmfBase/Hapy/doc/.deps + (cd cron; $(MAKE) $@) + +.PHONY: all install clean --- dsc-statistics-201203250530.orig/presenter/Makefile +++ dsc-statistics-201203250530/presenter/Makefile @@ -1,11 +1,13 @@ +#!/usr/bin/make + INSTALLDIR=/usr/local/dsc MKDIRS=data cache etc var var/log -all clean: +all: (cd cron; $(MAKE) $@) (cd extractor; $(MAKE) $@) (cd grapher; $(MAKE) $@) - (cd perllib; test -f Makefile || perl Makefile.PL ; $(MAKE) $@) + (cd perllib; test -f Makefile || perl Makefile.PL INSTALLDIRS=vendor; $(MAKE) $@ PREFIX=$(CURDIR)/../debian/dsc-statistics-presenter/usr) install: @for f in ${MKDIRS} ; do \ @@ -14,8 +16,15 @@ install: install -d -m 755 $(INSTALLDIR)/$$f/ ; \ fi \ done - (cd perllib; test -f Makefile || perl Makefile.PL ; $(MAKE) $@) + (cd perllib; test -f Makefile || perl Makefile.PL INSTALLDIRS=vendor ; $(MAKE) $@ PREFIX=$(CURDIR)/../debian/dsc-statistics-presenter/usr) (cd cron; $(MAKE) $@) (cd extractor; $(MAKE) $@) (cd grapher; $(MAKE) $@) +clean: + (cd cron; $(MAKE) $@) + (cd extractor; $(MAKE) $@) + (cd grapher; $(MAKE) $@) + (cd perllib; test -f Makefile || perl Makefile.PL ; $(MAKE) $@) + rm -f perllib/Makefile.old + \ No newline at end of file debian/patches/upload-prep0000664000000000000000000000276712063113746013011 0ustar Description: Patch upload-prep to work on Debian upload-prep comes with a lot of hard-coded paths and does things as root. pull-and-process-data can run as Debian-dsc-statistics, so we need to chown some files so that they can be deleted by that user. This should not hurt for the traditional mechanisms that are running as root anyway. Author: Marc Haber Forwarded: no --- a/collector/cron/upload-prep.pl +++ b/collector/cron/upload-prep.pl @@ -19,8 +19,9 @@ # sleep 3; +my ($uid,$gid)=(getpwnam("Debian-dsc-statistics"))[2,3]; -foreach my $conf () { +foreach my $conf () { next unless open (CONF, $conf); my $rundir = undef; while () { @@ -44,15 +45,24 @@ unless (-d "$upload/$yymmdd") { mkdir "$upload/$yymmdd" or die "mkdir $upload/$yymmdd: $!"; + chown "$uid", "$gid", "$upload/$yymmdd"; } my $new = "$upload/$yymmdd/$old"; link ($old, $new) or die "ln $old $new: $!"; + chown "$uid", "$gid", "$new"; # # the above link(2) could fail if the file was # previously linked but not yet unlinked. To # workaround we could do some stat(2)s and # ignore if they have the same inum? # + # kill all empty subdirs + foreach my $dir () { + if( -d "$dir" ) { + # this fails on a non-empty dir + rmdir "$dir"; + } + } } unlink $old or die "unlink $old: $!"; debian/patches/grapher-runtime-paths0000664000000000000000000000141212063113746014771 0ustar Description: Fix hard-coded non-FHS compliant paths in refile-and-grok.sh Author: Marc Haber Forwarded: no --- a/presenter/cron/refile-and-grok.sh +++ b/presenter/cron/refile-and-grok.sh @@ -1,7 +1,7 @@ #!/bin/sh set -e -cd /usr/local/dsc/data +cd /var/lib/dsc-statistics/data PROG=`basename $0` exec >$PROG.stdout @@ -9,7 +9,7 @@ #set -x date -EXECDIR=/usr/local/dsc/libexec +EXECDIR=/usr/share/dsc-statistics-presenter export EXECDIR SERVER NODE for SERVER in * ; do @@ -30,7 +30,7 @@ #test -d $NODE/incoming || continue; cd $NODE echo "$SERVER/$NODE:" - $EXECDIR/dsc-xml-extractor.pl >dsc-xml-extractor.out 2>&1 # & + $EXECDIR/dsc-xml-extractor >dsc-xml-extractor.out 2>&1 # & cd .. # NODE # sleep 1 done debian/patches/use-geo-ip0000664000000000000000000000232212063113746012516 0ustar Description: use Geo::IP instead of non-free unpackages IP::Country Original dsc uses IP::Country, which contains databases owned by the RIRs. I didn't bother packaging this. Instead, I patched the code to use the packages Geo::IP module. Its results are slightly worse and dsc loses its capability to decode the address to the RIR. Feel free to submit code that uses IP::Country if it is present and only falls back to Geo::IP in IP::Country's absence. Author: Marc Haber Forwarded: no --- a/presenter/perllib/DSC/grapher/plot.pm +++ b/presenter/perllib/DSC/grapher/plot.pm @@ -249,14 +249,12 @@ names => [ qw(Unknown IANA LACNIC APNIC RIPE ARIN) ], colors => [ qw(black red purple yellow blue brightgreen) ], label_func => sub { - use IP::Country; - my $l = new IP::Country::Fast; - $l->inet_atocc(shift) || '??'; + use Geo::IP; + my $l = Geo::IP->new(GEOIP_MEMORY_CACHE|GEOIP_CHECK_CACHE); + $l->country_code_by_addr(shift) || '??'; }, color_func => sub { - use IP::Authority; - my $l = new IP::Authority; - $l->inet_atoauth(shift) || '??'; + "??"; }, data_reader => \&DSC::extractor::read_data2, data_summer => \&DSC::grapher::data_summer_0d, debian/dsc-statistics-collector.dirs0000664000000000000000000000014612063113746015004 0ustar etc/dsc-statistics usr/share/doc/dsc-statistics-collector/examples usr/share/dsc-statistics-collector debian/dsc.pod0000664000000000000000000000156412063113746010456 0ustar =head1 NAME B - DNS Statistics Collector (collector daemon) =cut =head1 SYNOPSIS B [options] =cut =head1 DESCRIPTION dsc is the collector component of DSC. It uses pcap to listen on a network interface and dumps data in XML format. =cut =head1 OPTIONS =over 4 =item B<-d> Debug mode. Exits after first write. =item B<-f> Foreground mode. Don't become a daemon. =item B<-p> Don't put interface in promiscuous mode. =back =head1 AUTHOR Marc Haber based on work by Alexander Wirt . =head1 COPYRIGHT Copyright for this man page 2006, 2010 by Alexander Wirt Marc Haber This man page is licensed under the GNU General Public License v2. =head1 FILES /etc/init.d/dsc-statistics-collector /etc/default/dsc-statistics-collector debian/dsc-statistics-presenter.apache20000664000000000000000000000017012063113746015364 0ustar Alias /dsc /usr/share/dsc-statistics-presenter/html ScriptAlias /cgi-bin/dsc-statistics /usr/lib/cgi-bin/dsc-statistics debian/dsc-statistics-collector.manpages0000664000000000000000000000001412063113746015630 0ustar debian/dsc.8debian/dsc-rsync-pull0000775000000000000000000000175112063113746012004 0ustar #!/bin/bash PATH="/usr/sbin:/usr/bin:/sbin:/bin" me="$(basename $0)" PACKAGE="dsc-statistics" #set -x logecho() { PVALUE="$1" shift STR="$@" logger -p "$PVALUE" "$PACKAGE" -- "me: $STR" PRE="$(echo $PVALUE | sed 's/[^\.]*\.\(.*\)/\1/' | tr 'a-z' 'A-Z')" if tty -s || [ "$PRE" != "INFO" ] ; then echo >&2 "$PRE: $STR" fi } cmd() { logecho user.info "$@" "$@" } illegal-command() { logecho user.err "ignoring illegal command $SSH_ORIGINAL_COMMAND" exit 1 } dsc-rsync-pull() { if ! command -v rsync >/dev/null; then logecho user.err "rsync not found" else if echo "$SSH_ORIGINAL_COMMAND" | grep --quiet "^rsync --server --sender -v\?logDtpre\.iLs\?f\? \(--remove-source-files \)\?\. /var/lib/dsc-statistics/[^[:space:]]\+[[:space:]]*$"; then cmd $SSH_ORIGINAL_COMMAND else illegal-command fi fi } execute-all() { KEY="$KEY execute-all" case "$SSH_ORIGINAL_COMMAND" in *) cmd $SSH_ORIGINAL_COMMAND;; esac } dsc-rsync-pull debian/dsc-statistics-presenter.init.d0000664000000000000000000000246012063113746015252 0ustar #!/bin/bash # # Written by Hugo Haas for ippl. # Modified by Marc Haber . # Adapted for dsc-collector by Marc Haber ### BEGIN INIT INFO # Provides: dsc-statistics-presenter # Required-Start: $local_fs $remote_fs # Required-Stop: $local_fs $remote_fs # Should-Start: # Should-Stop: # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: dsc-statistics-presenter # Description: A DNS Statistics Collector - Presenter component ### END INIT INFO set -e if ! [ -x "/lib/lsb/init-functions" ]; then . /lib/lsb/init-functions else echo "E: /lib/lsb/init-functions not found, lsb-base (>= 3.0-6) needed" exit 1 fi if [ -n "$DSCDEBUG" ]; then echo "now debugging $0 $@" set -x fi LANG=C export LANG NAME="dsc-presenter" DESC="DNS Statistics Presenter" start() { log_daemon_msg "Starting $DESC" "$NAME" lRUNDIR="/var/run/dsc-statistics-presenter" [ -e $lRUNDIR ] || mkdir -p $lRUNDIR chown Debian-dsc-statistics $lRUNDIR ret=$? log_end_msg $ret return $ret } case "$1" in start) start ;; stop) ;; restart|force-reload) start ;; status) ;; *) log_failure_msg "Usage: $0 {start|restart|force-reload}" >&2 exit 1 ;; esac exit 0 debian/dsc-statistics-presenter.postrm0000664000000000000000000000172012063113746015407 0ustar #!/bin/sh set -e USERNAME="Debian-dsc-statistics" if [ -n "$DSCDEBUG" ]; then echo "now debugging $0 $@" set -x fi if [ "$1" = "purge" ] ; then rm -rf /var/lib/dsc-statistics /var/cache/dsc-statistics-presenter # if command -v deluser >/dev/null; then # echo >&2 'Removing system user' # RET=0 # deluser --remove-home --system $USERNAME || RET=$? # if [ "$RET" != "8" ]; then # exit $RET # fi # else # echo >&2 'Not removing system user, deluser not found' # fi fi if [ "$1" = "remove" ] || [ "$1" = "purge" ] ; then CONF="dsc-statistics-presenter" if [ -e /usr/share/apache2/apache2-maintscript-helper ] ; then . /usr/share/apache2/apache2-maintscript-helper apache2_invoke disconf $CONF elif dpkg-query -f '${Version}' -W 'apache2.2-common' > /dev/null 2>&1 ; then [ -L /etc/apache2/conf.d/$CONF.conf ] && rm /etc/apache2/conf.d/$CONF.conf fi fi #DEBHELPER# debian/dsc-statistics-collector.postinst0000664000000000000000000000052512063113746015727 0ustar #!/bin/bash -e # postinst USERNAME="Debian-dsc-statistics" HOMEDIR="/var/lib/dsc-statistics" [ -n "$DSCDEBUG" ] && set -x # Add user if [ "$1" = "configure" ]; then echo >&2 'Adding system user' adduser --system --group --home $HOMEDIR --shell /bin/bash \ --disabled-password --force-badname $USERNAME fi #DEBHELPER# debian/dsc-statistics-presenter.munin0000775000000000000000000000625112063113746015220 0ustar #!/usr/bin/perl # -*- perl -*- # # This has been mutated from munin_stats, originally by # Copyright (C) 2006-2009 Rodolphe Quiedeville # Modifiations: # Copyright (C) 2011 Marc Haber # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; version 2 dated June, # 1991. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # $Id: munin_stats.in 3263 2009-12-27 15:25:23Z lupe $ # # Magic markers (used by munin-node-configure and some installation scripts): #%# family=auto #%# capabilities=autoconf use strict; use warnings; use Munin::Plugin; my $logfile = ( $ENV{'MUNIN_SYSLOG'} || '/var/log/syslog'); my %logtext = ( 'lock' => 'lock obtained', 'rsync' => 'end rsync', 'refile-and-grok' => 'end refile-and-grok', ); if ($ARGV[0] and $ARGV[0] eq 'autoconf') { if( -e '/usr/share/dsc-statistics-presenter/pull-and-process-data' ) { print "yes\n"; } else { print "no\n"; } exit 0; } if ($ARGV[0] and $ARGV[0] eq "config") { print "graph_title dsc-statistics presenter processing time\n", "graph_info This graph shows the run time of the different steps of processes making up a dsc-statistics-presenter cron job run.\n", "graph_args --base 1000 -l 0\n", "graph_scale yes\n", "graph_vlabel seconds\n", "graph_category dsc\n"; foreach my $log (keys %logtext) { print "$log.label dsc-statistics-presenter $log\n"; print "$log.draw AREASTACK\n"; } print "lock.warning 30\n"; print "lock.critical 60\n"; print "rsync.warning 240\n"; print "rsync.critical 285\n"; print "refile-and-grok.warning 240\n"; print "refile-and-grok.critical 285\n"; exit 0; } my %positions = restore_state(); my %times; my %time; for my $log (keys %logtext) { $time{$log} = 'U'; } my $cannotread=0; if (! -r $logfile) { print "cannot read as $>\n"; $cannotread=1; } elsif (exists $positions{$logfile}) { my ($LOGFILE, undef) = tail_open($logfile, $positions{$logfile}); while (my $line = <$LOGFILE>) { chomp($line); for my $log (keys %logtext) { if( $line =~ /$logtext{$log}\s\(after\s+(\d+)\ssecs\)/ ) { $time{$log} = $1; } } } $positions{$logfile} = tail_close($LOGFILE); } else { # Do nothing on first run except find the current file end. $positions{$logfile} = (stat $logfile)[7]; } foreach my $log (keys %logtext) { if( $cannotread ) { print "$log.extinfo Can't open $logfile for reading\n"; print "$log.value $time{$log}\n"; } else { print "$log.value $time{$log}\n"; } } save_state(%positions); # vim: ft=perl : ts=4 : expandtab debian/dsc-statistics-presenter.install0000664000000000000000000000052112063113746015527 0ustar etc/dsc-grapher.cfg.sample usr/share/doc/dsc-statistics-presenter/examples/grapher/dsc-grapher.cfg share/html usr/share/dsc-statistics-presenter debian/pull-and-process-data usr/share/dsc-statistics-presenter debian/copy-local-and-process-data usr/share/dsc-statistics-presenter debian/refile-and-grok usr/share/dsc-statistics-presenter debian/refile-and-grok0000775000000000000000000000300412063113746012064 0ustar #!/bin/sh set -e set -u REFILE_AND_GROK_PARALLEL="1" if [ -e "/etc/default/dsc-statistics-presenter" ]; then . /etc/default/dsc-statistics-presenter fi usage() { cat <dsc-xml-extractor.out 2>&1 } ## Parse commandline TEMP=$(getopt -n refile-and-grok \ -l ,help,refile: -- \ +hR: "$@") if test "$?" != 0; then echo "Terminating..." >&2 exit 1 fi eval set -- ${TEMP} REFILE="" while test "$1" != "--"; do case $1 in -h|--help) usage exit 0 ;; -R|--refile) shift REFILE="$1" ;; esac shift done shift if [ -n "$REFILE" ]; then do_refile $REFILE exit 0 fi me="${me:-$0}" PROG=`basename $0` cd /var/lib/dsc-statistics/data exec >$PROG.stdout #exec 2>&1 #set -x date EXECDIR=/usr/share/dsc-statistics-presenter export EXECDIR SERVER NODE NODEDIRS="$(for SERVER in * ; do test -L $SERVER && continue; test -d $SERVER || continue; cd $SERVER for NODE in * ; do test -L $NODE && continue; test -d $NODE || continue; echo "$SERVER/$NODE" done cd .. # SERVER done)" echo me $me echo $NODEDIRS | xargs --no-run-if-empty --max-args=1 --max-procs=$REFILE_AND_GROK_PARALLEL $me --refile wait date debian/dsc-statistics-presenter.cron.daily0000775000000000000000000000064312063113746016133 0ustar #!/bin/bash DSCLIB="/var/lib/dsc-statistics" DSCCACHE="/var/cache/dsc-statistics" NUMDAYS=7 PATH="/sbin:/usr/sbin:/usr/local/sbin:/bin/:/usr/bin:/usr/local/bin" if [ -x /usr/share/dsc-statistics-presenter/remove-xmls ]; then find -L $DSCLIB | /usr/share/dsc-statistics-presenter/remove-xmls $NUMDAYS; fi if [ -d $DSCCACHE ]; then find -L $DSCCACHE -daystart -mtime +$NUMDAYS -type f | xargs --no-run-if-empty rm; fi debian/compat0000664000000000000000000000000212063113746010371 0ustar 7 debian/pull-and-process-data0000775000000000000000000000770712063113746013233 0ustar #!/bin/bash set -u set -e me="$0" PACKAGE="dsc-statistics" logecho() { PVALUE="$1" shift STR="$@" logger -p "$PVALUE" "$PACKAGE" -- "me: $STR" PRE="$(echo $PVALUE | sed 's/[^\.]*\.\(.*\)/\1/' | tr 'a-z' 'A-Z')" if tty -s || [ "$PRE" != "INFO" ] ; then echo >&2 "$PRE: $STR" fi } if ! command -v rsync >/dev/null; then logecho daemon.err "rsync not found" exit 1 fi RSYNC_PARALLEL="1" if [ -e "/etc/default/dsc-statistics-presenter" ]; then . /etc/default/dsc-statistics-presenter fi usage() { cat <&2 exit 1 fi eval set -- ${TEMP} RSYNC="" RSYNCOPTS="${RSYNCOPTS:-}" REMOVE_SOURCE_FILES="" SERIAL="" while test "$1" != "--"; do case $1 in -h|--help) usage exit 0 ;; -v|--verbose) verbose=yes ;; -r|--remove-source-files) REMOVE_SOURCE_FILES="--remove-source-files" ;; -R|--rsync) shift RSYNC="$1" ;; -s|--serial) SERIAL="1" ;; esac shift done shift if [ "$REMOVE_SOURCE_FILES" = "--remove-source-files" ]; then RSYNCOPTS="$RSYNCOPTS $REMOVE_SOURCE_FILES" fi if [ -n "$RSYNC" ]; then do_rsync $RSYNC exit 0 fi if [ "$REMOVE_SOURCE_FILES" != "--remove-source-files" ]; then logecho daemon.warning "WARN: test mode, will not remove source files" fi TIME0="$(date +%s)" LOCKFILE="/var/run/dsc-statistics-presenter/pull-and-process-data.lock" TIME1="$(date +%s)" if ! dotlockfile -p -l "$LOCKFILE"; then logecho daemon.err "lock not obtained (after $(( $TIME1 - $TIME0 )) ), aborting" exit 1 fi LOCKED=yes CONFFILE="/etc/dsc-statistics/dsc-grapher.cfg" BASEDIR="/var/lib/dsc-statistics" DATADIR="$BASEDIR/data" logecho daemon.info "lock obtained (after $(( $TIME1 - $TIME0 )) secs), start rsync" NODEDIRS="$(< $CONFFILE grep '^server' | while read dummy SERVER nodes; do SERVERDIR="$DATADIR/$SERVER" test -L $SERVERDIR && continue; test -d $SERVERDIR || continue; for NODE in $nodes; do NODEDIR="$SERVERDIR/$NODE" test -L $NODEDIR && continue; test -d $NODEDIR || continue; echo "$NODEDIR" done done)" export RSYNCOPTS if [ -n "$SERIAL" ]; then echo "serialized" for nodedir in $NODEDIRS; do echo $nodedir do_rsync $nodedir sleep 2 # allow for Ctrl-C done else echo $NODEDIRS | xargs --no-run-if-empty --max-args=1 --max-procs=$RSYNC_PARALLEL $me --rsync fi TIME2="$(date +%s)" logecho daemon.info "end rsync (after $(( $TIME2 - $TIME1 )) secs), starting refile-and-grok" # run refile-and-grok twice to slowly catch up after outages /usr/share/dsc-statistics-presenter/refile-and-grok /usr/share/dsc-statistics-presenter/refile-and-grok dotlockfile -u "$LOCKFILE" || true TIME3="$(date +%s)" logecho daemon.info "end refile-and-grok (after $(( $TIME3 - $TIME2 )) secs), end" exit 0 # EOF debian/dsc-statistics-presenter.dirs0000664000000000000000000000033712063113746015027 0ustar etc/apache2/conf-available etc/dsc-statistics usr/share/dsc-statistics-presenter usr/share/doc/dsc-statistics-presenter/examples usr/lib/cgi-bin/dsc-statistics var/lib/dsc-statistics/data var/cache/dsc-statistics-presenter debian/README.source0000664000000000000000000000230612063113746011353 0ustar This package is a 3.0 (quilt) format package. The Makefiles have been modified directly without using quilt. This was necessary since upstream's make clean is broken and fails if the package is already clean. The build process backs out quilt patches before invoking make clean, which will fail. Unfortunately, upstream did not package the LaTeX source code for the documentation in .pdf and .ps format with the release tarball. To comply with Debian policies, during Debian packaging, the documentation source (docsrc/dsc-manual.tex) has been pulled from upstream svn and is patched into the source tree by means of debian/patches/doc-sources. The build process then pdftotexts the .pdf file shipped in the upstream tarball and the .pfd file generated from dsc-manual.tex and aborts if relevant differences (measured by length of wdiff --no-common output) are found. We then proceed to ship the locally built .pdf in the .deb files. Upstream SVN URL: https://www.measurement-factory.com/svn/dsc/trunk/doc/dsc-manual.tex (Revision: 12842, Username: anonsvn, Passwort: anonsvn) The Makefile patches will end up in a debian/patches/debian-changes-$version file. Feel free to point out a way to do this in a cleaner way. debian/dsc-statistics-collector.init.d0000664000000000000000000001524612063113746015237 0ustar #!/bin/bash # # Written by Hugo Haas for ippl. # Modified by Marc Haber . # Adapted for dsc-collector by Marc Haber ### BEGIN INIT INFO # Provides: dsc-statistics-collector # Required-Start: $local_fs $remote_fs $syslog $network $time # Required-Stop: $local_fs $remote_fs $syslog $network # Should-Start: # Should-Stop: # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: dsc-statistics-collector # Description: A DNS Statistics Collector - Collector component ### END INIT INFO set -e if ! [ -x "/lib/lsb/init-functions" ]; then . /lib/lsb/init-functions else echo "E: /lib/lsb/init-functions not found, lsb-base (>= 3.0-6) needed" exit 1 fi if [ -n "$DSCDEBUG" ]; then echo "now debugging $0 $@" set -x fi LANG=C export LANG #read default file INTERFACE="lo" LOCAL_ADDRESS="127.0.0.1" OPTS="-p" [ -f /etc/default/dsc-statistics-collector ] && . /etc/default/dsc-statistics-collector PATH="/bin:/usr/bin:/sbin:/usr/sbin" INSTANCES="${2:-$INSTANCES}" LIBDIR="/var/lib/dsc-statistics" RUNDIR="/var/run/dsc-statistics-collector" PIDFILE="dsc.pid" CONFSRCFILE="/etc/dsc-statistics/dsc-collector.cfg" CONFFILE="dsc-collector" DSCCOMMENTS="no" shopt -s nullglob if [ -d "$EXTRAINSTANCEDIR" ]; then for INSTANCE in $EXTRAINSTANCEDIR/*; do INSTANCES="$INSTANCES $(basename $INSTANCE)" done fi INSTANCES="${INSTANCES:-default}" INTERFACE_default="${INTERFACE:-}" LOCAL_ADDRESS_default="${LOCAL_ADDRESS:-}" OPTS_default="${OPTS:-}" DAEMON="/usr/bin/dsc" NAME="dsc-collector" DESC="DNS Statistics Collector" test -f $DAEMON || exit 0 # this is from madduck on IRC, 2006-07-06 # There should be a better possibility to give daemon error messages # and/or to log things log() { case "$1" in [[:digit:]]*) success=$1; shift;; *) :;; esac log_action_begin_msg "$1"; shift log_action_end_msg ${success:-0} "$*" } removecomments() { if [ "x${DSCCOMMENTS}" = "xno" ] ; then grep -E -v '^[[:space:]]*#' | sed -e '/^$/N;/\n$/D' ; else cat fi } check_started () { INSTANCE="$1" lPIDFILE="${RUNDIR}/${INSTANCE}/${PIDFILE}" pidofproc -p $lPIDFILE $DAEMON > /dev/null } start_single_instance() { local lINTERFACE local lLOCAL_ADDRESS local lOPTS local lCONFFILE local lLIBDIR local lPIDFILE local gINTERFACE="$INTERFACE" local gLOCAL_ADDRESS="$LOCAL_ADDRESS" local gOPTS="$OPTS" local gBPF="$BPF" local INTERFACE local LOCAL_ADDRESS local OPTS local BPF INSTANCE="$1" lCONFFILE="" lLIBDIR="" lPIDFILE="" lBPF="" if [ -e "$EXTRAINSTANCEDIR/$INSTANCE" ]; then . "$EXTRAINSTANCEDIR/$INSTANCE" lINTERFACE="$INTERFACE" lLOCAL_ADDRESS="$LOCAL_ADDRESS" lOPTS="$OPTS" lBPF="$BPF" else eval lINTERFACE=\$INTERFACE_${INSTANCE} eval lLOCAL_ADDRESS=\$LOCAL_ADDRESS_${INSTANCE} eval lOPTS=\$OPTS_${INSTANCE} eval lBPF=\$BPF_${INSTANCE} fi if [ -n "$lBPF" ]; then lBPF="bpf_program \"$lBPF\";" fi lOPTS="${lOPTS:-$gOPTS}" lINTERFACE="${lINTERFACE:-$gINTERFACE}" lCONFFILE="${RUNDIR}/${CONFFILE}_$INSTANCE.cfg" lLIBDIR="${LIBDIR}/${INSTANCE}" lRUNDIR="${RUNDIR}/${INSTANCE}" lPIDFILE="${RUNDIR}/${INSTANCE}/${PIDFILE}" log_daemon_msg "Starting $DESC ($INSTANCE)" "$NAME" [ -e $lRUNDIR ] || \ install -d -oroot -groot -m755 $lRUNDIR [ -e $lLIBDIR ] || \ install -d -oroot -groot -m755 $lLIBDIR [ -e $lLIBDIR/upload ] || \ install -d -oroot -groot -m755 $lLIBDIR/upload [ -e $lLIBDIR/upload/default ] || \ install -d -oroot -groot -m755 $lLIBDIR/upload/default cat << EOF > ${lCONFFILE}.tmp ######### # WARNING WARNING WARNING # WARNING WARNING WARNING # WARNING WARNING WARNING # WARNING WARNING WARNING # WARNING WARNING WARNING # this file is generated dynamically from $CONFSRCFILE # Any changes you make here will be lost. # WARNING WARNING WARNING # WARNING WARNING WARNING # WARNING WARNING WARNING # WARNING WARNING WARNING # WARNING WARNING WARNING ######### EOF IFACELINE="" if [ "$lINTERFACE" == "all" ]; then lINTERFACE="$(ip --oneline link show | grep '[^_]UP[^_]' | awk '{print $2}' FS=":")" fi for iface in $lINTERFACE; do IFACELINE="$IFACELINE interface $iface;" done LADDRLINE="" if [ "$lLOCAL_ADDRESS" == "all" ]; then lLOCAL_ADDRESS="$(ip --oneline addr show | sed -n '/.*inet6\?[[:space:]]\+\([a-f0-9\.:]\+\).*/{s||\1|;p;}')" fi for laddr in $lLOCAL_ADDRESS; do LADDRLINE="$LADDRLINE local_address $laddr;" done cat ${CONFSRCFILE} 2>/dev/null | \ removecomments | \ sed \ -e "s|DSClibdirDSC|$lLIBDIR|g" \ -e "s|DSCpidfileDSC|$lPIDFILE|g" \ -e "s|DSCinterfaceDSC|$IFACELINE|g" \ -e "s|DSClocal_addressDSC|$LADDRLINE|g" \ -e "s|DSCbpf_programDSC|$lBPF|g" \ >> ${lCONFFILE}.tmp # test validity if called without -o # this is not currently possible with dsc, # but can be easily enabled with this (of course untested) example code #if [ "x${CONFFILE}" = "x${AUTOCONFIGFILE}" ] && \ # [ -x ${DAEMON} ] ; then # if ! ${DAEMON} --config "${CONFFILE}.tmp" > /dev/null ; then # log "Invalid new configfile ${CONFFILE}.tmp" # log "not installing ${CONFFILE}.tmp to ${CONFFILE}" # exit 1 # fi #fi mv -f ${lCONFFILE}.tmp ${lCONFFILE} if ! check_started $INSTANCE; then start_daemon -p $lPIDFILE $DAEMON $lOPTS $lCONFFILE ret=$? else log_failure_msg "already running!" ret=1 fi log_end_msg $ret return $ret } start () { for INSTANCE in $INSTANCES; do start_single_instance $INSTANCE done } stop_single_instance () { INSTANCE="$1" lPIDFILE="${RUNDIR}/${INSTANCE}/${PIDFILE}" log_daemon_msg "Stopping $DESC ($INSTANCE)" "$NAME" killproc -p $lPIDFILE $DAEMON ret=$? if [ $ret -eq 0 ]; then rm -f $lPIDFILE fi log_end_msg $ret return $ret } stop () { for INSTANCE in $INSTANCES; do stop_single_instance $INSTANCE done } status_single_instance() { INSTANCE="$1" lPIDFILE="${RUNDIR}/${INSTANCE}/${PIDFILE}" log_action_begin_msg "checking $DAEMON ($INSTANCE)" if check_started $INSTANCE; then log_action_end_msg 0 "running" else if [ -e "$lPIDFILE" ]; then log_action_end_msg 1 "$DAEMON ($INSTANCE) failed" return 1 else log_action_end_msg 0 "not running" return 3 fi fi } check_status () { ret=0 for INSTANCE in $INSTANCES; do iret=0 status_single_instance $INSTANCE || iret=$? if [ $ret -lt $iret ]; then ret=$iret fi done return $ret } case "$1" in start) start ;; stop) stop ;; restart|force-reload) stop if [ -z "$?" -o "$?" = "0" ]; then start fi ;; status) check_status ;; *) log_failure_msg "Usage: $0 {start|stop|restart|force-reload|status}" >&2 exit 1 ;; esac exit 0 debian/dsc-statistics-presenter.maintscript0000664000000000000000000000023312063113746016416 0ustar mv_conffile /etc/apache2/conf.d/dsc-statistics-presenter /etc/apache2/conf-available/dsc-statistics-presenter.conf 201106061022-4 dsc-statistics-presenter debian/dsc-statistics-collector.postrm0000664000000000000000000000110312063113746015361 0ustar #!/bin/sh set -e USERNAME="Debian-dsc-statistics" if [ -n "$DSCDEBUG" ]; then echo "now debugging $0 $@" set -x fi case "$1" in purge) rm -rf /var/lib/dsc-statistics /var/run/dsc-statistics-collector # if command -v deluser >/dev/null; then # echo >&2 'Removing system user' # RET=0 # deluser --remove-home --system $USERNAME || RET=$? # if [ "$RET" != "8" ]; then # exit $RET # fi # else # echo >&2 'Not removing system user, deluser not found' # fi ;; esac #DEBHELPER# debian/copyright0000664000000000000000000000400712063113746011127 0ustar This package was debianized by Marc Haber in September 2010. The DNS Statistics Collector (dsc-statistics) This software was downloaded on 2010-09-06 from http://dns.measurement-factory.com/tools/dsc/source.html Copyright 2007 by The Measurement Factory, Inc. and Internet Systems Consortium, Inc. info@measurement-factory.com, info@isc.org http://dns.measurement-factory.com/tools/dsc/ dsc is licensed under the BSD license. (http://dns.measurement-factory.com/tools/dsc/source.html) Copyright (c) 2007, The Measurement Factory, Inc and Internet Systems Consortium, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of The Measurement Factory nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. debian/source/0000775000000000000000000000000012063113746010473 5ustar debian/source/format0000664000000000000000000000001412063113746011701 0ustar 3.0 (quilt) debian/source/options0000664000000000000000000000002412063113746012105 0ustar single-debian-patch debian/source/patch-header0000664000000000000000000000101612063113746012741 0ustar Description: Debian source patch Author: Marc Haber Forwarded: no Upstream's Makefiles are kind of broken in a way that debian/rules clean cannot be repeatedly called. We cannot patch this via a quilt patch because the build process calls debian/rules clean even on a clean package tree. While the package is mainly patched via quilt, the Makefile patches had to be directly applied in the source tree. If you know of any way to do things more cleanly, please file a bug in the Debian BTS. debian/NEWS0000664000000000000000000000105412063113746007672 0ustar dsc-statistics (201203250530-2) unstable; urgency=low Unfortunately, our choice of /home/Debian-dsc-statistics has turned out as not acceptable for a Debian package according to Debian policy. I should have known this better. To fix the release critical bug report that has resulted from this maintainer error, the home directory of Debian-dsc-statistics is moved to /var/lib/dsc-statistics for new installs only. This should not break your current setup. -- Marc Haber Sat, 15 Dec 2012 16:11:23 +0100 debian/rules0000775000000000000000000000672512063113746010265 0ustar #!/usr/bin/make -f PACKAGENAME=dsc-statistics %: dh $@ override_dh_auto_build: cd collector && $(MAKE) cd presenter && $(MAKE) if [ -e docsrc/screenshot1.png.uu ]; then cd docsrc && uudecode screenshot1.png.uu && $(MAKE); fi override_dh_auto_clean: #cd collector/TmfBase/Hapy && $(MAKE) distclean cd collector && $(MAKE) clean cd presenter && $(MAKE) clean if [ -e docsrc/Makefile ]; then cd docsrc && $(MAKE) clean && rm -f screenshot1.png; fi rm -f doc/dsc-manual.txt rm -rf $(CURDIR)/debian/tmp rm -f debian/dsc.8 #$(CURDIR)/collector/TmfBase/Hapy/src/.deps \ # $(CURDIR)/collector/TmfBase/Hapy/tests/.deps binary-arch: dh --before dh_install $@ mkdir -p $(CURDIR)/debian/tmp chmod 755 debian/dsc-rsync-pull debian/pull-and-process-data debian/refile-and-grok cd collector && $(MAKE) install INSTALLDIR=$(CURDIR)/debian/tmp PREFIX=$(CURDIR)/debian/tmp mv debian/tmp/etc/dsc.conf.sample $(CURDIR)/debian/dsc-statistics-collector/usr/share/doc/dsc-statistics-collector/examples/dsc.cfg mv debian/tmp/libexec/upload-ssh.sh $(CURDIR)/debian/dsc-statistics-collector/usr/share/dsc-statistics-collector/upload-ssh mv debian/tmp/libexec/upload-x509.sh $(CURDIR)/debian/dsc-statistics-collector/usr/share/dsc-statistics-collector/upload-x509 mv debian/tmp/libexec/upload-rsync.sh $(CURDIR)/debian/dsc-statistics-collector/usr/share/dsc-statistics-collector/upload-rsync mv debian/tmp/libexec/upload-prep.pl $(CURDIR)/debian/dsc-statistics-collector/usr/share/dsc-statistics-collector/upload-prep cp debian/dsc-collector.cfg $(CURDIR)/debian/dsc-statistics-collector/etc/dsc-statistics /usr/bin/pod2man --section=8 --release="DSC $(PKG_VER)" --lax \ --center="Debian GNU/Linux" debian/dsc.pod > debian/dsc.8 pdftotext docsrc/dsc-manual.pdf docsrc/dsc-manual.txt pdftotext doc/dsc-manual.pdf doc/dsc-manual.txt if [ "$$(wdiff --no-common docsrc/dsc-manual.txt doc/dsc-manual.txt | wc -l)" -gt 8 ]; then \ echo "too many changes in docs since release, .orig.tar.gz repackaging needed"; \ exit 1; \ fi cp docsrc/dsc-manual.pdf $(CURDIR)/debian/dsc-statistics-collector/usr/share/doc/dsc-statistics-collector/dsc-manual.pdf dh_install -a dh --remaining $@ binary-indep: dh --before dh_install $@ cd presenter && $(MAKE) install INSTALLDIR=$(CURDIR)/debian/tmp PREFIX=$(CURDIR)/debian/tmp mv debian/tmp/libexec/dsc-grapher.pl $(CURDIR)/debian/dsc-statistics-presenter/usr/lib/cgi-bin/dsc-statistics/dsc-grapher mv debian/tmp/libexec/remove-xmls.pl $(CURDIR)/debian/dsc-statistics-presenter/usr/share/dsc-statistics-presenter/remove-xmls mv debian/tmp/libexec/dsc-grapher.pl.sample $(CURDIR)/debian/dsc-statistics-presenter/usr/share/doc/dsc-statistics-presenter/examples/dsc-grapher mv debian/tmp/libexec/refile-and-grok.sh $(CURDIR)/debian/dsc-statistics-presenter/usr/share/dsc-statistics-presenter/refile-and-grok mv debian/tmp/libexec/put-file.pl $(CURDIR)/debian/dsc-statistics-presenter/usr/share/dsc-statistics-presenter/put-file mv debian/tmp/libexec/dsc-xml-extractor.pl $(CURDIR)/debian/dsc-statistics-presenter/usr/share/dsc-statistics-presenter/dsc-xml-extractor cp debian/dsc-grapher.cfg $(CURDIR)/debian/dsc-statistics-presenter/etc/dsc-statistics cp debian/dsc-statistics-presenter.apache2 $(CURDIR)/debian/dsc-statistics-presenter/etc/apache2/conf-available/dsc-statistics-presenter.conf cp docsrc/dsc-manual.pdf $(CURDIR)/debian/dsc-statistics-presenter/usr/share/doc/dsc-statistics-presenter/dsc-manual.pdf dh_install -i dh --remaining $@ binary: binary-arch binary-indep debian/dsc-statistics-collector.install0000664000000000000000000000011112063113746015501 0ustar bin/dsc usr/bin debian/dsc-rsync-pull usr/share/dsc-statistics-collector debian/dsc-statistics-presenter.cron.d0000664000000000000000000000061612063113746015251 0ustar # /etc/cron.d/dsc-statistics-presenter: crontab entries for the dsc-presenter package SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 2,7,12,17,22,27,32,37,42,47,52,57 * * * * Debian-dsc-statistics test -x /usr/share/dsc-statistics-presenter/copy-local-and-process-data && /usr/share/dsc-statistics-presenter/copy-local-and-process-data --remove-source-files debian/dsc-grapher.cfg0000664000000000000000000000347212063113746012061 0ustar server localhost localhost trace_windows 1hour 4hour 1day 1week accum_windows 1day 2days 3days 1week embargo 0 timezone Europe/Berlin # # To update domain_list all_tlds: # dig @f.root-servers.net . axfr \ # | awk '$3=="IN" && $4=="NS" {print $1}' \ # | tr A-Z a-z \ # | sed -e 's/\.$//' \ # | grep . \ # | sort \ # | uniq \ # | fmt 50 \ # | sed -e 's/^/domain_list all_tlds /' domain_list all_tlds ac ad ae aero af ag ai al am an ao aq ar arpa as domain_list all_tlds asia at au aw ax az ba bb bd be bf bg bh bi biz bj domain_list all_tlds bm bn bo br bs bt bv bw by bz ca cat cc cd cf cg ch domain_list all_tlds ci ck cl cm cn co com coop cr cu cv cx cy cz de dj domain_list all_tlds dk dm do dz ec edu ee eg er es et eu fi fj fk fm fo domain_list all_tlds fr ga gb gd ge gf gg gh gi gl gm gn gov gp gq gr gs domain_list all_tlds gt gu gw gy hk hm hn hr ht hu id ie il im in info domain_list all_tlds int io iq ir is it je jm jo jobs jp ke kg kh ki km domain_list all_tlds kn kp kr kw ky kz la lb lc li lk lr ls lt lu lv ly domain_list all_tlds ma mc md me mg mh mil mk ml mm mn mo mobi mp mq mr domain_list all_tlds ms mt mu museum mv mw mx my mz na name nc ne net nf domain_list all_tlds ng ni nl no np nr nu nz om org pa pe pf pg ph pk pl domain_list all_tlds pm pn pr pro ps pt pw py qa re ro rs ru rw sa sb sc domain_list all_tlds sd se sg sh si sj sk sl sm sn so sr st su sv sy sz domain_list all_tlds tc td tel tf tg th tj tk tl tm tn to tp tr travel domain_list all_tlds tt tv tw tz ua ug uk us uy uz va vc ve vg vi vn vu domain_list all_tlds wf ws xn--0zwm56d xn--11b5bs3a9aj6g xn--80akhbyknj4f domain_list all_tlds xn--9t4b11yi5a xn--deba0ad xn--g6w251d xn--hgbk6aj7f53bba domain_list all_tlds xn--hlcj6aya9esc7a xn--jxalpdlp xn--kgbechtv xn--zckzah domain_list all_tlds ye yt yu za zm zw valid_domains f-root all_tlds