mirror of
https://gitlab.com/chrony/chrony.git
synced 2025-12-04 12:25:06 -05:00
Compare commits
112 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a4313c32b | ||
|
|
b32432c232 | ||
|
|
feb86e336a | ||
|
|
7817bef866 | ||
|
|
2dd9f3373b | ||
|
|
5b1a8705cf | ||
|
|
b49470117d | ||
|
|
84f8463f2a | ||
|
|
78f37e726a | ||
|
|
9d83369348 | ||
|
|
365834535e | ||
|
|
63ae72e009 | ||
|
|
4599e2b508 | ||
|
|
395c33208c | ||
|
|
ff423304ed | ||
|
|
00a77fca52 | ||
|
|
49bd8cfab3 | ||
|
|
6031b35a7a | ||
|
|
1f6e508a3d | ||
|
|
fb538c3947 | ||
|
|
6af87bd8f6 | ||
|
|
e248a57d00 | ||
|
|
41580fe589 | ||
|
|
1c128b0076 | ||
|
|
5a3d85b4ff | ||
|
|
0f9892fe7a | ||
|
|
19651dc767 | ||
|
|
e63c51c6c0 | ||
|
|
d1c7e1bb6c | ||
|
|
1a8514a1a8 | ||
|
|
7c53aca486 | ||
|
|
e9ae3d0a0b | ||
|
|
159a9519e8 | ||
|
|
5939fcb2eb | ||
|
|
0601540d41 | ||
|
|
b83861c7c2 | ||
|
|
4d6156b549 | ||
|
|
7eae35e15e | ||
|
|
a94380673b | ||
|
|
dce9607d6e | ||
|
|
e3234465e2 | ||
|
|
032838b1b0 | ||
|
|
dd5405a281 | ||
|
|
6d242a33f5 | ||
|
|
3bae6c3202 | ||
|
|
618f372e13 | ||
|
|
8f72155b43 | ||
|
|
bbb6c5d422 | ||
|
|
62fe343990 | ||
|
|
4097ab29c7 | ||
|
|
9c9530c688 | ||
|
|
0a86a8dd0b | ||
|
|
e08870c63c | ||
|
|
6b38523c9c | ||
|
|
77e79e8359 | ||
|
|
e88af337cd | ||
|
|
707b623ea8 | ||
|
|
9716a2ed7e | ||
|
|
fe2cfe1fae | ||
|
|
c6e2eaf7a9 | ||
|
|
a822bcfd67 | ||
|
|
6640993f20 | ||
|
|
f39dc68f84 | ||
|
|
27cfc02468 | ||
|
|
8e23110aec | ||
|
|
f7e08d0c30 | ||
|
|
f2f592fa0d | ||
|
|
465e580a39 | ||
|
|
b4069a4c3b | ||
|
|
352f03d487 | ||
|
|
8cd9e68246 | ||
|
|
5b4e07d658 | ||
|
|
48b6c2aa6b | ||
|
|
1570f97ee2 | ||
|
|
fbd20c429e | ||
|
|
a7892a1a15 | ||
|
|
8265ff2890 | ||
|
|
183d56fd40 | ||
|
|
d06f02be1c | ||
|
|
5a2b38378c | ||
|
|
19f3a6bca8 | ||
|
|
dd4fb511a5 | ||
|
|
3a9e13445f | ||
|
|
67c0f1c08c | ||
|
|
8de55124a8 | ||
|
|
0666d04ab2 | ||
|
|
d87cddd6a5 | ||
|
|
84cbeeadd1 | ||
|
|
eefb5c7552 | ||
|
|
8c0f3f4042 | ||
|
|
735811b2b9 | ||
|
|
923c58485f | ||
|
|
032d1db883 | ||
|
|
75330fdff5 | ||
|
|
ac30bb06ef | ||
|
|
ef3669fe1b | ||
|
|
9416a24f03 | ||
|
|
8b81bfe41d | ||
|
|
96759116e2 | ||
|
|
4aae133c4d | ||
|
|
35e662d810 | ||
|
|
cdc22df903 | ||
|
|
8f9c237010 | ||
|
|
0148ecaea0 | ||
|
|
fd2641bcb9 | ||
|
|
be42b4eeea | ||
|
|
8336f14680 | ||
|
|
bc0aaa9217 | ||
|
|
71aa36aa6e | ||
|
|
2f2446c7dc | ||
|
|
5331e1a146 | ||
|
|
eeac7b7ca0 |
30
COPYING
30
COPYING
@@ -1,8 +1,8 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
GNU GENERAL PUBLIC LICENSE
|
||||||
Version 2, June 1991
|
Version 2, June 1991
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
|
|||||||
General Public License applies to most of the Free Software
|
General Public License applies to most of the Free Software
|
||||||
Foundation's software and to any other program whose authors commit to
|
Foundation's software and to any other program whose authors commit to
|
||||||
using it. (Some other Free Software Foundation software is covered by
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
the GNU Library General Public License instead.) You can apply it to
|
the GNU Lesser General Public License instead.) You can apply it to
|
||||||
your programs, too.
|
your programs, too.
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
When we speak of free software, we are referring to freedom, not
|
||||||
@@ -55,7 +55,7 @@ patent must be licensed for everyone's free use or not licensed at all.
|
|||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
The precise terms and conditions for copying, distribution and
|
||||||
modification follow.
|
modification follow.
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
GNU GENERAL PUBLIC LICENSE
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
|
|||||||
License. (Exception: if the Program itself is interactive but
|
License. (Exception: if the Program itself is interactive but
|
||||||
does not normally print such an announcement, your work based on
|
does not normally print such an announcement, your work based on
|
||||||
the Program is not required to print an announcement.)
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
These requirements apply to the modified work as a whole. If
|
||||||
identifiable sections of that work are not derived from the Program,
|
identifiable sections of that work are not derived from the Program,
|
||||||
and can be reasonably considered independent and separate works in
|
and can be reasonably considered independent and separate works in
|
||||||
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
|
|||||||
access to copy the source code from the same place counts as
|
access to copy the source code from the same place counts as
|
||||||
distribution of the source code, even though third parties are not
|
distribution of the source code, even though third parties are not
|
||||||
compelled to copy the source along with the object code.
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
4. You may not copy, modify, sublicense, or distribute the Program
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
except as expressly provided under this License. Any attempt
|
except as expressly provided under this License. Any attempt
|
||||||
otherwise to copy, modify, sublicense or distribute the Program is
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
@@ -225,7 +225,7 @@ impose that choice.
|
|||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
This section is intended to make thoroughly clear what is believed to
|
||||||
be a consequence of the rest of this License.
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
8. If the distribution and/or use of the Program is restricted in
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
original copyright holder who places the Program under this License
|
original copyright holder who places the Program under this License
|
||||||
@@ -278,8 +278,8 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
|||||||
POSSIBILITY OF SUCH DAMAGES.
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
Appendix: How to Apply These Terms to Your New Programs
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
If you develop a new program, and you want it to be of the greatest
|
||||||
possible use to the public, the best way to achieve this is to make it
|
possible use to the public, the best way to achieve this is to make it
|
||||||
@@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
|
|||||||
the "copyright" line and a pointer to where the full notice is found.
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
Copyright (C) 19yy <name of author>
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -303,16 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License along
|
||||||
along with this program; if not, write to the Free Software
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
If the program is interactive, make it output a short notice like this
|
If the program is interactive, make it output a short notice like this
|
||||||
when it starts in an interactive mode:
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
This is free software, and you are welcome to redistribute it
|
This is free software, and you are welcome to redistribute it
|
||||||
under certain conditions; type `show c' for details.
|
under certain conditions; type `show c' for details.
|
||||||
@@ -335,5 +335,5 @@ necessary. Here is a sample; alter the names:
|
|||||||
This General Public License does not permit incorporating your program into
|
This General Public License does not permit incorporating your program into
|
||||||
proprietary programs. If your program is a subroutine library, you may
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
consider it more useful to permit linking proprietary applications with the
|
consider it more useful to permit linking proprietary applications with the
|
||||||
library. If this is what you want to do, use the GNU Library General
|
library. If this is what you want to do, use the GNU Lesser General
|
||||||
Public License instead of this License.
|
Public License instead of this License.
|
||||||
|
|||||||
22
INSTALL
22
INSTALL
@@ -32,13 +32,17 @@ for Bourne-family shells, or
|
|||||||
for C-family shells.
|
for C-family shells.
|
||||||
|
|
||||||
If the software cannot (yet) be built on your system, an error message
|
If the software cannot (yet) be built on your system, an error message
|
||||||
will be shown. Otherwise, the files `options.h' and `Makefile' will
|
will be shown. Otherwise, `Makefile' will be generated.
|
||||||
be generated.
|
|
||||||
|
|
||||||
By default, chronyc will be built to make use of the readline library. If you
|
If editline or readline library is available, chronyc will be built
|
||||||
don't want this, specify the --disable-readline flag to configure. If you have
|
with line editing support. If you don't want this, specify the
|
||||||
readline and/or ncurses installed in a non-standard location, please refer to
|
--disable-readline flag to configure. Please refer to the chrony.txt
|
||||||
the chrony.txt file for information.
|
file for more information.
|
||||||
|
|
||||||
|
If a `timepps.h' header is available, chronyd will be built with PPS
|
||||||
|
API reference clock driver. If the header is installed in a location
|
||||||
|
that isn't normally searched by the compiler, you can add it to the
|
||||||
|
searched locations by setting CPPFLAGS variable to -I/path/to/timepps.
|
||||||
|
|
||||||
Now type
|
Now type
|
||||||
|
|
||||||
@@ -67,11 +71,11 @@ If you want chrony to appear in the top level info directory listing, you need
|
|||||||
to run the install-info command manually after this step. install-info takes 2
|
to run the install-info command manually after this step. install-info takes 2
|
||||||
arguments. The first is the path to the chrony.info file you have just
|
arguments. The first is the path to the chrony.info file you have just
|
||||||
installed. This will be the argument you gave to --prefix when you configured
|
installed. This will be the argument you gave to --prefix when you configured
|
||||||
(/usr/local by default), with /info/chrony.info on the end. The second
|
(/usr/local by default), with /share/info/chrony.info on the end. The second
|
||||||
argument is the location of the file called 'dir'. This will typically be
|
argument is the location of the file called 'dir'. This will typically be
|
||||||
/usr/info/dir. So the typical command line would be
|
/usr/share/info/dir. So the typical command line would be
|
||||||
|
|
||||||
install-info /usr/local/info/chrony.info /usr/info/dir
|
install-info /usr/local/share/info/chrony.info /usr/share/info/dir
|
||||||
|
|
||||||
Now that the software is successfully installed, the next step is to
|
Now that the software is successfully installed, the next step is to
|
||||||
set up a configuration file. The contents of this depend on the
|
set up a configuration file. The contents of this depend on the
|
||||||
|
|||||||
90
Makefile.in
90
Makefile.in
@@ -19,19 +19,23 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License along
|
# 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.,
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#
|
#
|
||||||
# =======================================================================
|
# =======================================================================
|
||||||
#
|
#
|
||||||
# Makefile template
|
# Makefile template
|
||||||
|
|
||||||
INSTALL_PREFIX=@INSTALL_PREFIX@
|
SYSCONFDIR=@SYSCONFDIR@
|
||||||
|
BINDIR=@BINDIR@
|
||||||
|
SBINDIR=@SBINDIR@
|
||||||
MANDIR=@MANDIR@
|
MANDIR=@MANDIR@
|
||||||
INFODIR=@INFODIR@
|
INFODIR=@INFODIR@
|
||||||
|
DOCDIR=@DOCDIR@
|
||||||
|
|
||||||
CC = @CC@
|
CC = @CC@
|
||||||
CCWARNFLAGS = @CCWARNFLAGS@
|
CCWARNFLAGS = @CCWARNFLAGS@
|
||||||
OPTFLAGS = @CFLAGS@ @EXTRA_DEFS@
|
OPTFLAGS = @CFLAGS@
|
||||||
|
CPPFLAGS = @CPPFLAGS@ @SYSDEFS@ @EXTRA_DEFS@
|
||||||
|
|
||||||
DESTDIR=
|
DESTDIR=
|
||||||
|
|
||||||
@@ -41,25 +45,25 @@ OBJS = util.o sched.o regress.o local.o \
|
|||||||
logging.o conf.o cmdmon.o md5.o keys.o \
|
logging.o conf.o cmdmon.o md5.o keys.o \
|
||||||
nameserv.o acquire.o manual.o addrfilt.o \
|
nameserv.o acquire.o manual.o addrfilt.o \
|
||||||
cmdparse.o mkdirpp.o rtc.o pktlength.o clientlog.o \
|
cmdparse.o mkdirpp.o rtc.o pktlength.o clientlog.o \
|
||||||
broadcast.o
|
broadcast.o refclock.o refclock_shm.o refclock_sock.o \
|
||||||
|
refclock_pps.o
|
||||||
|
|
||||||
EXTRA_OBJS=@EXTRA_OBJECTS@
|
EXTRA_OBJS=@EXTRA_OBJECTS@
|
||||||
|
|
||||||
CLI_OBJS = client.o md5.o nameserv.o getdate.o cmdparse.o \
|
CLI_OBJS = client.o md5.o nameserv.o getdate.o cmdparse.o \
|
||||||
pktlength.o
|
pktlength.o util.o
|
||||||
|
|
||||||
SRCS = $(patsubst %.o,%.c,$(OBJS))
|
SRCS = $(patsubst %.o,%.c,$(OBJS))
|
||||||
EXTRA_SRCS = $(patsubst %.o,%.c,$(EXTRA_OBJS))
|
EXTRA_SRCS = $(patsubst %.o,%.c,$(EXTRA_OBJS))
|
||||||
|
|
||||||
CLI_SRCS = $(patsubst %.o,%.c,$(CLI_OBJS))
|
CLI_SRCS = $(patsubst %.o,%.c,$(CLI_OBJS))
|
||||||
|
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
LIBS = @LIBS@
|
LIBS = @LIBS@
|
||||||
|
|
||||||
EXTRA_LIBS=@EXTRA_LIBS@
|
EXTRA_LIBS=@EXTRA_LIBS@
|
||||||
EXTRA_CLI_LIBS=@EXTRA_CLI_LIBS@
|
EXTRA_CLI_LIBS=@EXTRA_CLI_LIBS@
|
||||||
|
|
||||||
DEFS=@SYSDEFS@
|
|
||||||
|
|
||||||
CFLAGS = $(CCWARNFLAGS) $(OPTFLAGS)
|
CFLAGS = $(CCWARNFLAGS) $(OPTFLAGS)
|
||||||
|
|
||||||
# Until we have a main procedure we can link, just build object files
|
# Until we have a main procedure we can link, just build object files
|
||||||
@@ -68,13 +72,16 @@ CFLAGS = $(CCWARNFLAGS) $(OPTFLAGS)
|
|||||||
all : chronyd chronyc
|
all : chronyd chronyc
|
||||||
|
|
||||||
chronyd : $(OBJS) $(EXTRA_OBJS)
|
chronyd : $(OBJS) $(EXTRA_OBJS)
|
||||||
$(CC) $(OPTFLAGS) -o chronyd $(OBJS) $(EXTRA_OBJS) $(LIBS) $(EXTRA_LIBS)
|
$(CC) $(OPTFLAGS) -o chronyd $(OBJS) $(EXTRA_OBJS) $(LDFLAGS) $(LIBS) $(EXTRA_LIBS)
|
||||||
|
|
||||||
chronyc : $(CLI_OBJS)
|
chronyc : $(CLI_OBJS)
|
||||||
$(CC) $(OPTFLAGS) -o chronyc $(CLI_OBJS) @READLINE_LINK@ $(LIBS) $(EXTRA_CLI_LIBS)
|
$(CC) $(OPTFLAGS) -o chronyc $(CLI_OBJS) $(LDFLAGS) @READLINE_LINK@ $(LIBS) $(EXTRA_CLI_LIBS)
|
||||||
|
|
||||||
|
conf.o : conf.c
|
||||||
|
$(CC) $(CFLAGS) $(CPPFLAGS) -DDEFAULT_CONF_DIR=\"$(SYSCONFDIR)\" -c $<
|
||||||
|
|
||||||
client.o : client.c
|
client.o : client.c
|
||||||
$(CC) $(CFLAGS) $(DEFS) @READLINE_COMPILE@ -c $<
|
$(CC) $(CFLAGS) $(CPPFLAGS) @READLINE_COMPILE@ -c $<
|
||||||
|
|
||||||
.depend :
|
.depend :
|
||||||
gcc -MM $(SRCS) $(EXTRA_SRCS) > .depend
|
gcc -MM $(SRCS) $(EXTRA_SRCS) > .depend
|
||||||
@@ -88,45 +95,47 @@ clean :
|
|||||||
version.h : version.txt
|
version.h : version.txt
|
||||||
./mkversion
|
./mkversion
|
||||||
|
|
||||||
|
getdate.c : ;
|
||||||
|
getdate :
|
||||||
|
bison -o getdate.c getdate.y
|
||||||
|
|
||||||
# For install, don't use the install command, because its switches
|
# For install, don't use the install command, because its switches
|
||||||
# seem to vary between systems.
|
# seem to vary between systems.
|
||||||
|
|
||||||
install: chronyd chronyc
|
install: chronyd chronyc
|
||||||
[ -d $(DESTDIR)$(INSTALL_PREFIX) ] || mkdir -p $(DESTDIR)$(INSTALL_PREFIX)
|
[ -d $(DESTDIR)$(SBINDIR) ] || mkdir -p $(DESTDIR)$(SBINDIR)
|
||||||
[ -d $(DESTDIR)$(INSTALL_PREFIX)/sbin ] || mkdir -p $(DESTDIR)$(INSTALL_PREFIX)/sbin
|
[ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR)
|
||||||
[ -d $(DESTDIR)$(INSTALL_PREFIX)/bin ] || mkdir -p $(DESTDIR)$(INSTALL_PREFIX)/bin
|
[ -d $(DESTDIR)$(DOCDIR) ] || mkdir -p $(DESTDIR)$(DOCDIR)
|
||||||
[ -d $(DESTDIR)$(INSTALL_PREFIX)/doc ] || mkdir -p $(DESTDIR)$(INSTALL_PREFIX)/doc
|
|
||||||
[ -d $(DESTDIR)$(MANDIR)/man1 ] || mkdir -p $(DESTDIR)$(MANDIR)/man1
|
[ -d $(DESTDIR)$(MANDIR)/man1 ] || mkdir -p $(DESTDIR)$(MANDIR)/man1
|
||||||
[ -d $(DESTDIR)$(MANDIR)/man5 ] || mkdir -p $(DESTDIR)$(MANDIR)/man5
|
[ -d $(DESTDIR)$(MANDIR)/man5 ] || mkdir -p $(DESTDIR)$(MANDIR)/man5
|
||||||
[ -d $(DESTDIR)$(MANDIR)/man8 ] || mkdir -p $(DESTDIR)$(MANDIR)/man8
|
[ -d $(DESTDIR)$(MANDIR)/man8 ] || mkdir -p $(DESTDIR)$(MANDIR)/man8
|
||||||
[ -d $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony ] || mkdir -p $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony
|
[ -d $(DESTDIR)$(DOCDIR) ] || mkdir -p $(DESTDIR)$(DOCDIR)
|
||||||
if [ -f $(DESTDIR)$(INSTALL_PREFIX)/sbin/chronyd ]; then rm -f $(DESTDIR)$(INSTALL_PREFIX)/sbin/chronyd ; fi
|
if [ -f $(DESTDIR)$(SBINDIR)/chronyd ]; then rm -f $(DESTDIR)$(SBINDIR)/chronyd ; fi
|
||||||
if [ -f $(DESTDIR)$(INSTALL_PREFIX)/bin/chronyc ]; then rm -f $(DESTDIR)$(INSTALL_PREFIX)/bin/chronyc ; fi
|
if [ -f $(DESTDIR)$(BINDIR)/chronyc ]; then rm -f $(DESTDIR)$(BINDIR)/chronyc ; fi
|
||||||
cp chronyd $(DESTDIR)$(INSTALL_PREFIX)/sbin/chronyd
|
cp chronyd $(DESTDIR)$(SBINDIR)/chronyd
|
||||||
chmod 555 $(DESTDIR)$(INSTALL_PREFIX)/sbin/chronyd
|
chmod 755 $(DESTDIR)$(SBINDIR)/chronyd
|
||||||
cp chronyc $(DESTDIR)$(INSTALL_PREFIX)/bin/chronyc
|
cp chronyc $(DESTDIR)$(BINDIR)/chronyc
|
||||||
chmod 555 $(DESTDIR)$(INSTALL_PREFIX)/bin/chronyc
|
chmod 755 $(DESTDIR)$(BINDIR)/chronyc
|
||||||
cp chrony.txt $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/chrony.txt
|
cp chrony.txt $(DESTDIR)$(DOCDIR)/chrony.txt
|
||||||
chmod 444 $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/chrony.txt
|
chmod 644 $(DESTDIR)$(DOCDIR)/chrony.txt
|
||||||
cp COPYING $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/COPYING
|
cp COPYING $(DESTDIR)$(DOCDIR)/COPYING
|
||||||
chmod 444 $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/COPYING
|
chmod 644 $(DESTDIR)$(DOCDIR)/COPYING
|
||||||
cp README $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/README
|
cp README $(DESTDIR)$(DOCDIR)/README
|
||||||
chmod 444 $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/README
|
chmod 644 $(DESTDIR)$(DOCDIR)/README
|
||||||
cp chrony.1 $(DESTDIR)$(MANDIR)/man1
|
cp chrony.1 $(DESTDIR)$(MANDIR)/man1
|
||||||
chmod 444 $(DESTDIR)$(MANDIR)/man1/chrony.1
|
chmod 644 $(DESTDIR)$(MANDIR)/man1/chrony.1
|
||||||
cp chronyc.1 $(DESTDIR)$(MANDIR)/man1
|
cp chronyc.1 $(DESTDIR)$(MANDIR)/man1
|
||||||
chmod 444 $(DESTDIR)$(MANDIR)/man1/chronyc.1
|
chmod 644 $(DESTDIR)$(MANDIR)/man1/chronyc.1
|
||||||
cp chronyd.8 $(DESTDIR)$(MANDIR)/man8
|
cp chronyd.8 $(DESTDIR)$(MANDIR)/man8
|
||||||
chmod 444 $(DESTDIR)$(MANDIR)/man8/chronyd.8
|
chmod 644 $(DESTDIR)$(MANDIR)/man8/chronyd.8
|
||||||
cp chrony.conf.5 $(DESTDIR)$(MANDIR)/man5
|
cp chrony.conf.5 $(DESTDIR)$(MANDIR)/man5
|
||||||
chmod 444 $(DESTDIR)$(MANDIR)/man5/chrony.conf.5
|
chmod 644 $(DESTDIR)$(MANDIR)/man5/chrony.conf.5
|
||||||
|
|
||||||
%.o : %.c
|
%.o : %.c
|
||||||
$(CC) $(CFLAGS) $(DEFS) -c $<
|
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
|
||||||
|
|
||||||
%.s : %.c
|
%.s : %.c
|
||||||
$(CC) $(CFLAGS) $(DEFS) -S $<
|
$(CC) $(CFLAGS) $(CPPFLAGS) -S $<
|
||||||
|
|
||||||
main.o logging.o client.o : version.h
|
main.o logging.o client.o : version.h
|
||||||
|
|
||||||
@@ -134,17 +143,14 @@ main.o logging.o client.o : version.h
|
|||||||
MAKEINFO:=makeinfo
|
MAKEINFO:=makeinfo
|
||||||
|
|
||||||
install-docs : docs
|
install-docs : docs
|
||||||
[ -d $(DESTDIR)$(INSTALL_PREFIX)/doc ] || mkdir -p $(DESTDIR)$(INSTALL_PREFIX)/doc
|
[ -d $(DESTDIR)$(DOCDIR) ] || mkdir -p $(DESTDIR)$(DOCDIR)
|
||||||
cp chrony.txt $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/chrony.txt
|
cp chrony.txt $(DESTDIR)$(DOCDIR)/chrony.txt
|
||||||
chown root $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/chrony.txt
|
chmod 644 $(DESTDIR)$(DOCDIR)/chrony.txt
|
||||||
chmod 444 $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/chrony.txt
|
cp chrony.html $(DESTDIR)$(DOCDIR)/chrony.html
|
||||||
cp chrony.html $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/chrony.html
|
chmod 644 $(DESTDIR)$(DOCDIR)/chrony.html
|
||||||
chown root $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/chrony.html
|
|
||||||
chmod 444 $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/chrony.html
|
|
||||||
[ -d $(DESTDIR)$(INFODIR) ] || mkdir -p $(DESTDIR)$(INFODIR)
|
[ -d $(DESTDIR)$(INFODIR) ] || mkdir -p $(DESTDIR)$(INFODIR)
|
||||||
cp chrony.info* $(DESTDIR)$(INFODIR)
|
cp chrony.info* $(DESTDIR)$(INFODIR)
|
||||||
chown root $(DESTDIR)$(INFODIR)/chrony.info*
|
chmod 644 $(DESTDIR)$(INFODIR)/chrony.info*
|
||||||
chmod 444 $(DESTDIR)$(INFODIR)/chrony.info*
|
|
||||||
|
|
||||||
docs : chrony.txt chrony.html chrony.info
|
docs : chrony.txt chrony.html chrony.info
|
||||||
|
|
||||||
|
|||||||
49
NEWS
49
NEWS
@@ -1,3 +1,52 @@
|
|||||||
|
New in version 1.24
|
||||||
|
===================
|
||||||
|
|
||||||
|
* Support for reference clocks (SHM, SOCK, PPS drivers)
|
||||||
|
* IPv6 support
|
||||||
|
* Linux capabilities support (to drop root privileges)
|
||||||
|
* Memory locking support on Linux
|
||||||
|
* Real-time scheduler support on Linux
|
||||||
|
* Leap second support on Linux
|
||||||
|
* Support for editline library
|
||||||
|
* Support for new Linux readonly adjtime
|
||||||
|
* NTP client support for KoD RATE
|
||||||
|
* Read kernel timestamps for received NTP packets
|
||||||
|
* Reply to NTP requests with correct address on multihomed hosts
|
||||||
|
* Add option to limit client log memory size
|
||||||
|
* Retry name resolving after temporary failure
|
||||||
|
* Avoid blocking read in Linux RTC driver
|
||||||
|
* Support for Linux on S/390 and PowerPC
|
||||||
|
* Fix various bugs on 64-bit systems
|
||||||
|
* Fix valgrind errors and compiler warnings
|
||||||
|
* Improve configure to support common options and variables
|
||||||
|
* Improve status checking and printing in chronyc
|
||||||
|
* Return non-zero exit code on errors in chronyc
|
||||||
|
* Reduce request timeout in chronyc
|
||||||
|
* Print estimated offset in sourcestats
|
||||||
|
* Changed chronyc protocol, incompatible with older versions
|
||||||
|
|
||||||
|
New in version 1.23
|
||||||
|
===================
|
||||||
|
|
||||||
|
* Support for MIPS, x86_64, sparc, alpha, arm, FreeBSD
|
||||||
|
* Fix serious sign-extension error in handling IP addresses
|
||||||
|
* RTC support can be excluded at compile time
|
||||||
|
* Make sources gcc-4 compatible
|
||||||
|
* Fix various compiler warnings
|
||||||
|
* Handle fluctuations in peer distance better.
|
||||||
|
* Fixed handling of stratum zero.
|
||||||
|
* Fix various problems for 64-bit systems
|
||||||
|
* Flush chronyc output streams after each command, to allow it to be driven
|
||||||
|
through pipes
|
||||||
|
* Manpage improvements
|
||||||
|
|
||||||
|
Version 1.22
|
||||||
|
============
|
||||||
|
|
||||||
|
This release number was claimed by a release that Mandriva made to patch
|
||||||
|
important bugs in 1.21. The official numbering has jumped to 1.23 as a
|
||||||
|
consequence.
|
||||||
|
|
||||||
New in version 1.21
|
New in version 1.21
|
||||||
===================
|
===================
|
||||||
|
|
||||||
|
|||||||
89
README
89
README
@@ -18,8 +18,8 @@ accordingly. It also works out the rate at which the system clock
|
|||||||
gains or loses time and uses this information to keep it accurate
|
gains or loses time and uses this information to keep it accurate
|
||||||
between measurements from the reference.
|
between measurements from the reference.
|
||||||
|
|
||||||
The reference time can be derived from either Network Time Protocol
|
The reference time can be derived from Network Time Protocol (NTP)
|
||||||
(NTP) servers (preferred), or wristwatch-and-keyboard (via chronyc).
|
servers, reference clocks, or wristwatch-and-keyboard (via chronyc).
|
||||||
The main source of information about the Network Time Protocol is
|
The main source of information about the Network Time Protocol is
|
||||||
http://www.eecis.udel.edu/~ntp.
|
http://www.eecis.udel.edu/~ntp.
|
||||||
|
|
||||||
@@ -28,9 +28,9 @@ intermittent access to reference sources, for example computers which
|
|||||||
use a dial-up account to access the Internet. Of course, it will work
|
use a dial-up account to access the Internet. Of course, it will work
|
||||||
on computers with permanent connections too.
|
on computers with permanent connections too.
|
||||||
|
|
||||||
In addition, the Linux 2.0.x (for x >= 32), 2.2.x and 2.3.x versions
|
In addition, on Linux it can monitor the system's real time clock
|
||||||
can monitor the system's real time clock performance, so the system
|
performance, so the system can maintain accurate time even across
|
||||||
can maintain accurate time even across reboots.
|
reboots.
|
||||||
|
|
||||||
Typical accuracies available between 2 machines are
|
Typical accuracies available between 2 machines are
|
||||||
|
|
||||||
@@ -38,6 +38,8 @@ On an ethernet LAN : 100-200 microseconds, often much better
|
|||||||
On a V32bis dial-up modem connection : 10's of milliseconds (from one
|
On a V32bis dial-up modem connection : 10's of milliseconds (from one
|
||||||
session to the next)
|
session to the next)
|
||||||
|
|
||||||
|
With a good reference clock the accuracy can reach one microsecond.
|
||||||
|
|
||||||
chronyd can also operate as an RFC1305-compatible NTP server and peer.
|
chronyd can also operate as an RFC1305-compatible NTP server and peer.
|
||||||
|
|
||||||
|
|
||||||
@@ -46,9 +48,10 @@ What will chrony run on?
|
|||||||
|
|
||||||
Chrony can be successfully built and run on
|
Chrony can be successfully built and run on
|
||||||
|
|
||||||
1. Linux v1.2.13, v2.0.x, 2.1.x (partially), 2.2.x, 2.3.x, 2.4.x (i386).
|
1. Linux v1.2.13, v2.0.x, 2.1.x (partially), 2.2.x, 2.3.x, 2.4.x, 2.6.x.
|
||||||
Real time clock support is limited to 2.0.32 onwards and to 2.2, 2.3 and
|
Real time clock support is limited to 2.0.32 onwards and to 2.2, 2.3,
|
||||||
2.4 series only. PowerPC is also known to be supported.
|
2.4 and 2.6 series only. i386, x86_64, PowerPC are known to be
|
||||||
|
supported.
|
||||||
|
|
||||||
2. Solaris 2.5/2.5.1/2.6/2.7/2.8 (various platforms)
|
2. Solaris 2.5/2.5.1/2.6/2.7/2.8 (various platforms)
|
||||||
|
|
||||||
@@ -69,8 +72,7 @@ How do I set it up?
|
|||||||
The file INSTALL gives instructions. On supported systems the
|
The file INSTALL gives instructions. On supported systems the
|
||||||
compilation process should be automatic.
|
compilation process should be automatic.
|
||||||
|
|
||||||
You will need an ANSI C compiler -- gcc is recommended. Versions
|
You will need an ANSI C compiler -- gcc is recommended.
|
||||||
2.7.2/2.7.2.2 are known to work.
|
|
||||||
|
|
||||||
The manual (in texinfo and text formats) describes how to set the
|
The manual (in texinfo and text formats) describes how to set the
|
||||||
software up for the less straightforward cases.
|
software up for the less straightforward cases.
|
||||||
@@ -84,29 +86,25 @@ ready-formatted plain text (chrony.txt) in the distribution.
|
|||||||
There is also information available on the chrony web pages, accessible
|
There is also information available on the chrony web pages, accessible
|
||||||
through the URL
|
through the URL
|
||||||
|
|
||||||
http://chrony.sunsite.dk/
|
http://chrony.tuxfamily.org/
|
||||||
|
|
||||||
What can chrony not do?
|
What can chrony not do?
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
Compared to the `reference' RFC1305 implementation xntpd, chronyd does
|
Compared to the `reference' RFC1305 implementation xntpd, chronyd does
|
||||||
not support hardware reference clocks, leap seconds or broadcast
|
not support broadcast modes.
|
||||||
modes.
|
|
||||||
|
|
||||||
Where are new versions announced?
|
Where are new versions announced?
|
||||||
=================================
|
=================================
|
||||||
|
|
||||||
There is a low volume mailing list where new versions and other
|
There is a low volume mailing list where new versions and other
|
||||||
important news relating to chrony is announced. You can join this list
|
important news relating to chrony is announced. You can join this list
|
||||||
by sending mail to
|
by sending mail with the subject "subscribe" to
|
||||||
|
|
||||||
chrony-announce-subscribe@sunsite.dk
|
chrony-announce-request@chrony.tuxfamily.org
|
||||||
|
|
||||||
These messages will be copied to chrony-users (see below). I also try
|
These messages will be copied to chrony-users (see below). New versions
|
||||||
to announce new versions on Freshmeat (http://freshmeat.net/).
|
are announced also on Freshmeat (http://freshmeat.net/).
|
||||||
|
|
||||||
I don't reliably announce via news any more - I don't tend to keep up
|
|
||||||
with news as I haven't enough time.
|
|
||||||
|
|
||||||
How can I get support for chrony?
|
How can I get support for chrony?
|
||||||
and where can I discuss new features, possible bugs etc?
|
and where can I discuss new features, possible bugs etc?
|
||||||
@@ -117,36 +115,28 @@ mentioned above. chrony-users is a users' discussion list, e.g. for
|
|||||||
general questions and answers about using chrony. chrony-dev is a more
|
general questions and answers about using chrony. chrony-dev is a more
|
||||||
technical list, e.g. for discussing how new features should be
|
technical list, e.g. for discussing how new features should be
|
||||||
implemented, exchange of information between developers etc. To
|
implemented, exchange of information between developers etc. To
|
||||||
subscribe to either of these lists, send an empty message to
|
subscribe to either of these lists, send a message with the subject
|
||||||
|
"subscribe" to
|
||||||
|
|
||||||
chrony-users-subscribe@sunsite.dk
|
chrony-users-request@chrony.tuxfamily.org
|
||||||
or
|
or
|
||||||
chrony-dev-subscribe@sunsite.dk
|
chrony-dev-request@chrony.tuxfamily.org
|
||||||
|
|
||||||
as applicable.
|
as applicable.
|
||||||
|
|
||||||
Note that due to family commitments (a 3 year-old and a 1 year-old), I
|
|
||||||
no longer have the time to give to supporting chrony that I once had.
|
|
||||||
Therefore, the chrony-users list should be your main route for support,
|
|
||||||
rather than mailing me directly. Even if it's me that responds to your
|
|
||||||
question on the list, at least *ALL* subscribers then benefit from
|
|
||||||
seeing the discussion, rather than me taking up lots of time on
|
|
||||||
supporting people on a one-to-one basis. If you do mail me directly,
|
|
||||||
don't be surprised if I cc: the response to the mailing list.
|
|
||||||
|
|
||||||
But how can I contact the author if I need to?
|
Author
|
||||||
==============================================
|
======
|
||||||
|
|
||||||
You can email me at <rc@rc0.org.uk>. If that fails, you could try to
|
Richard P. Curnow <rc@rc0.org.uk>
|
||||||
find me through one of the mailing lists. It would be nice if:
|
|
||||||
|
|
||||||
- you include the word 'chrony' in the subject line (so my mail reader
|
|
||||||
can sort my mail by topic)
|
|
||||||
|
|
||||||
- you don't send complete log files, encoded binaries etc, without
|
Maintainers
|
||||||
editing such material down to just the relevant bits - a few tens of
|
===========
|
||||||
lines at most. (My dial-up connection handles large messages rather
|
|
||||||
slowly ...).
|
John Hasler <john@dhh.gt.org>
|
||||||
|
Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
|
||||||
|
|
||||||
Acknowledgements
|
Acknowledgements
|
||||||
================
|
================
|
||||||
@@ -199,6 +189,8 @@ John Hasler <john@dhh.gt.org>
|
|||||||
sizeof(unsigned long) > 4)
|
sizeof(unsigned long) > 4)
|
||||||
Bug fix to initstepslew directive
|
Bug fix to initstepslew directive
|
||||||
Fix to remove potential buffer overrun errors.
|
Fix to remove potential buffer overrun errors.
|
||||||
|
Memory locking and real-time scheduler support
|
||||||
|
Fix fault where chronyd enters an endless loop
|
||||||
|
|
||||||
Liam Hatton <me@liamhatton.com>
|
Liam Hatton <me@liamhatton.com>
|
||||||
Advice on configuring for Linux on PPC
|
Advice on configuring for Linux on PPC
|
||||||
@@ -212,6 +204,13 @@ Jim Knoble <jmknoble@pobox.com>
|
|||||||
Antti Jrvinen <costello@iki.fi>
|
Antti Jrvinen <costello@iki.fi>
|
||||||
Advice on configuring for BSD/386
|
Advice on configuring for BSD/386
|
||||||
|
|
||||||
|
Miroslav Lichvar <mlichvar@redhat.com>
|
||||||
|
Reference clock support
|
||||||
|
IPv6 support
|
||||||
|
Linux capabilities support
|
||||||
|
Leap second support
|
||||||
|
Various bug fixes and improvements
|
||||||
|
|
||||||
Victor Moroz <vim@prv.adlum.ru>
|
Victor Moroz <vim@prv.adlum.ru>
|
||||||
Patch to support Linux with HZ!=100
|
Patch to support Linux with HZ!=100
|
||||||
|
|
||||||
@@ -224,6 +223,9 @@ Frank Otto <sandwichmacher@web.de>
|
|||||||
Andreas Piesk <apiesk@virbus.de>
|
Andreas Piesk <apiesk@virbus.de>
|
||||||
Patch to make chronyc use the readline library if available
|
Patch to make chronyc use the readline library if available
|
||||||
|
|
||||||
|
Timo Teras <timo.teras@iki.fi>
|
||||||
|
Patch to reply correctly on multihomed hosts
|
||||||
|
|
||||||
Wolfgang Weisselberg <weissel@netcologne.de>
|
Wolfgang Weisselberg <weissel@netcologne.de>
|
||||||
Entries in contrib directory
|
Entries in contrib directory
|
||||||
|
|
||||||
@@ -240,9 +242,4 @@ Doug Woodward <dougw@whistler.com>
|
|||||||
Many other people have contributed bug reports and suggestions. I'm
|
Many other people have contributed bug reports and suggestions. I'm
|
||||||
sorry I can't identify all of you individually.
|
sorry I can't identify all of you individually.
|
||||||
|
|
||||||
Version control information
|
|
||||||
===========================
|
|
||||||
|
|
||||||
$Header: /cvs/src/chrony/README,v 1.30 2003/09/21 23:11:06 richard Exp $
|
|
||||||
|
|
||||||
vim:tw=72
|
vim:tw=72
|
||||||
|
|||||||
174
acquire.c
174
acquire.c
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -65,7 +65,8 @@
|
|||||||
|
|
||||||
#define RETRANSMISSION_TIMEOUT (1.0)
|
#define RETRANSMISSION_TIMEOUT (1.0)
|
||||||
|
|
||||||
typedef struct { unsigned long ip_addr;
|
typedef struct {
|
||||||
|
IPAddr ip_addr; /* Address of the server */
|
||||||
int sanity; /* Flag indicating whether source
|
int sanity; /* Flag indicating whether source
|
||||||
looks sane or not */
|
looks sane or not */
|
||||||
int n_dead_probes; /* Number of probes sent to the server
|
int n_dead_probes; /* Number of probes sent to the server
|
||||||
@@ -93,7 +94,18 @@ static int n_completed_sources;
|
|||||||
|
|
||||||
static int init_slew_threshold = -1;
|
static int init_slew_threshold = -1;
|
||||||
|
|
||||||
static int sock_fd = -1;
|
union sockaddr_in46 {
|
||||||
|
struct sockaddr_in in4;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
struct sockaddr_in6 in6;
|
||||||
|
#endif
|
||||||
|
struct sockaddr u;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int sock_fd4 = -1;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
static int sock_fd6 = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
@@ -143,12 +155,14 @@ ACQ_Finalise(void)
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static void
|
static int
|
||||||
initialise_io(void)
|
prepare_socket(int family)
|
||||||
{
|
{
|
||||||
unsigned short port_number = CNF_GetAcquisitionPort();
|
unsigned short port_number = CNF_GetAcquisitionPort();
|
||||||
|
int sock_fd;
|
||||||
|
socklen_t addrlen;
|
||||||
|
|
||||||
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
sock_fd = socket(family, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
if (sock_fd < 0) {
|
if (sock_fd < 0) {
|
||||||
LOG_FATAL(LOGF_Acquire, "Could not open socket : %s", strerror(errno));
|
LOG_FATAL(LOGF_Acquire, "Could not open socket : %s", strerror(errno));
|
||||||
@@ -158,18 +172,50 @@ initialise_io(void)
|
|||||||
/* Don't bother binding this socket - we're not fussed what port
|
/* Don't bother binding this socket - we're not fussed what port
|
||||||
number it gets */
|
number it gets */
|
||||||
} else {
|
} else {
|
||||||
struct sockaddr_in my_addr;
|
union sockaddr_in46 my_addr;
|
||||||
my_addr.sin_family = AF_INET;
|
|
||||||
my_addr.sin_port = htons(port_number);
|
memset(&my_addr, 0, sizeof (my_addr));
|
||||||
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
||||||
if (bind(sock_fd, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0) {
|
switch (family) {
|
||||||
|
case AF_INET:
|
||||||
|
my_addr.in4.sin_family = family;
|
||||||
|
my_addr.in4.sin_port = htons(port_number);
|
||||||
|
my_addr.in4.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
addrlen = sizeof (my_addr.in4);
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
case AF_INET6:
|
||||||
|
my_addr.in6.sin6_family = family;
|
||||||
|
my_addr.in6.sin6_port = htons(port_number);
|
||||||
|
my_addr.in6.sin6_addr = in6addr_any;
|
||||||
|
addrlen = sizeof (my_addr.in6);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind(sock_fd, &my_addr.u, addrlen) < 0) {
|
||||||
LOG(LOGS_ERR, LOGF_Acquire, "Could not bind socket : %s\n", strerror(errno));
|
LOG(LOGS_ERR, LOGF_Acquire, "Could not bind socket : %s\n", strerror(errno));
|
||||||
/* but keep running */
|
/* but keep running */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SCH_AddInputFileHandler(sock_fd, read_from_socket, NULL);
|
SCH_AddInputFileHandler(sock_fd, read_from_socket, (void *)(long)sock_fd);
|
||||||
|
|
||||||
|
return sock_fd;
|
||||||
|
}
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
static void
|
||||||
|
initialise_io(int family)
|
||||||
|
{
|
||||||
|
if (family == IPADDR_INET4 || family == IPADDR_UNSPEC)
|
||||||
|
sock_fd4 = prepare_socket(AF_INET);
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
if (family == IPADDR_INET6 || family == IPADDR_UNSPEC)
|
||||||
|
sock_fd6 = prepare_socket(AF_INET6);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -177,10 +223,18 @@ initialise_io(void)
|
|||||||
static void
|
static void
|
||||||
finalise_io(void)
|
finalise_io(void)
|
||||||
{
|
{
|
||||||
if (sock_fd >= 0) {
|
if (sock_fd4 >= 0) {
|
||||||
SCH_RemoveInputFileHandler(sock_fd);
|
SCH_RemoveInputFileHandler(sock_fd4);
|
||||||
close(sock_fd);
|
close(sock_fd4);
|
||||||
}
|
}
|
||||||
|
sock_fd4 = -1;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
if (sock_fd6 >= 0) {
|
||||||
|
SCH_RemoveInputFileHandler(sock_fd6);
|
||||||
|
close(sock_fd6);
|
||||||
|
}
|
||||||
|
sock_fd6 = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -195,10 +249,12 @@ probe_source(SourceRecord *src)
|
|||||||
NTP_Mode my_mode = MODE_CLIENT;
|
NTP_Mode my_mode = MODE_CLIENT;
|
||||||
struct timeval cooked;
|
struct timeval cooked;
|
||||||
double local_time_err;
|
double local_time_err;
|
||||||
struct sockaddr_in his_addr;
|
union sockaddr_in46 his_addr;
|
||||||
|
int sock_fd;
|
||||||
|
socklen_t addrlen;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
printf("Sending probe to %08lx sent=%d samples=%d\n", src->ip_addr, src->n_probes_sent, src->n_samples);
|
printf("Sending probe to %s sent=%d samples=%d\n", UTI_IPToString(&src->ip_addr), src->n_probes_sent, src->n_samples);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pkt.lvm = (((LEAP_Unsynchronised << 6) & 0xc0) |
|
pkt.lvm = (((LEAP_Unsynchronised << 6) & 0xc0) |
|
||||||
@@ -219,18 +275,39 @@ probe_source(SourceRecord *src)
|
|||||||
pkt.receive_ts.lo = 0; /* Set to 0 */
|
pkt.receive_ts.lo = 0; /* Set to 0 */
|
||||||
|
|
||||||
/* And do transmission */
|
/* And do transmission */
|
||||||
his_addr.sin_addr.s_addr = htonl(src->ip_addr);
|
|
||||||
his_addr.sin_port = htons(123); /* Fixed for now */
|
memset(&his_addr, 0, sizeof (his_addr));
|
||||||
his_addr.sin_family = AF_INET;
|
switch (src->ip_addr.family) {
|
||||||
|
case IPADDR_INET4:
|
||||||
|
his_addr.in4.sin_addr.s_addr = htonl(src->ip_addr.addr.in4);
|
||||||
|
his_addr.in4.sin_port = htons(123); /* Fixed for now */
|
||||||
|
his_addr.in4.sin_family = AF_INET;
|
||||||
|
addrlen = sizeof (his_addr.in4);
|
||||||
|
sock_fd = sock_fd4;
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
case IPADDR_INET6:
|
||||||
|
memcpy(&his_addr.in6.sin6_addr.s6_addr, &src->ip_addr.addr.in6,
|
||||||
|
sizeof (his_addr.in6.sin6_addr.s6_addr));
|
||||||
|
his_addr.in6.sin6_port = htons(123); /* Fixed for now */
|
||||||
|
his_addr.in6.sin6_family = AF_INET6;
|
||||||
|
addrlen = sizeof (his_addr.in6);
|
||||||
|
sock_fd = sock_fd6;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
LCL_ReadCookedTime(&cooked, &local_time_err);
|
LCL_ReadCookedTime(&cooked, &local_time_err);
|
||||||
UTI_TimevalToInt64(&cooked, &pkt.transmit_ts);
|
UTI_TimevalToInt64(&cooked, &pkt.transmit_ts);
|
||||||
|
|
||||||
if (sendto(sock_fd, (void *) &pkt, NTP_NORMAL_PACKET_SIZE,
|
if (sendto(sock_fd, (void *) &pkt, NTP_NORMAL_PACKET_SIZE,
|
||||||
0,
|
0,
|
||||||
(struct sockaddr *) &his_addr, sizeof(his_addr)) < 0) {
|
&his_addr.u, addrlen) < 0) {
|
||||||
LOG(LOGS_WARN, LOGF_Acquire, "Could not send to %s : %s",
|
LOG(LOGS_WARN, LOGF_Acquire, "Could not send to %s : %s",
|
||||||
UTI_IPToDottedQuad(src->ip_addr),
|
UTI_IPToString(&src->ip_addr),
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,7 +330,7 @@ transmit_timeout(void *x)
|
|||||||
src->timer_running = 0;
|
src->timer_running = 0;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
printf("Timeout expired for server %08lx\n", src->ip_addr);
|
printf("Timeout expired for server %s\n", UTI_IPToString(&src->ip_addr));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (src->n_dead_probes < MAX_DEAD_PROBES) {
|
if (src->n_dead_probes < MAX_DEAD_PROBES) {
|
||||||
@@ -357,14 +434,14 @@ read_from_socket(void *anything)
|
|||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
ReceiveBuffer msg;
|
ReceiveBuffer msg;
|
||||||
struct sockaddr_in his_addr;
|
union sockaddr_in46 his_addr;
|
||||||
|
int sock_fd;
|
||||||
socklen_t his_addr_len;
|
socklen_t his_addr_len;
|
||||||
int flags;
|
int flags;
|
||||||
int message_length;
|
int message_length;
|
||||||
unsigned long remote_ip;
|
IPAddr remote_ip;
|
||||||
int i, ok;
|
int i, ok;
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
double local_time_err;
|
|
||||||
SourceRecord *src;
|
SourceRecord *src;
|
||||||
|
|
||||||
flags = 0;
|
flags = 0;
|
||||||
@@ -372,26 +449,41 @@ read_from_socket(void *anything)
|
|||||||
his_addr_len = sizeof(his_addr);
|
his_addr_len = sizeof(his_addr);
|
||||||
|
|
||||||
/* Get timestamp */
|
/* Get timestamp */
|
||||||
LCL_ReadCookedTime(&now, &local_time_err);
|
SCH_GetFileReadyTime(&now);
|
||||||
|
|
||||||
|
sock_fd = (long)anything;
|
||||||
status = recvfrom (sock_fd, (char *)&msg, message_length, flags,
|
status = recvfrom (sock_fd, (char *)&msg, message_length, flags,
|
||||||
(struct sockaddr *) &his_addr, &his_addr_len);
|
&his_addr.u, &his_addr_len);
|
||||||
|
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
LOG(LOGS_WARN, LOGF_Acquire, "Error reading from socket, %s", strerror(errno));
|
LOG(LOGS_WARN, LOGF_Acquire, "Error reading from socket, %s", strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
remote_ip = ntohl(his_addr.sin_addr.s_addr);
|
switch (his_addr.u.sa_family) {
|
||||||
|
case AF_INET:
|
||||||
|
remote_ip.family = IPADDR_INET4;
|
||||||
|
remote_ip.addr.in4 = ntohl(his_addr.in4.sin_addr.s_addr);
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
case AF_INET6:
|
||||||
|
remote_ip.family = IPADDR_INET6;
|
||||||
|
memcpy(&remote_ip.addr.in6, his_addr.in6.sin6_addr.s6_addr,
|
||||||
|
sizeof (remote_ip.addr.in6));
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
printf("Got message from %08lx\n", remote_ip);
|
printf("Got message from %s\n", UTI_IPToString(&remote_ip));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Find matching host */
|
/* Find matching host */
|
||||||
ok = 0;
|
ok = 0;
|
||||||
for (i=0; i<n_sources; i++) {
|
for (i=0; i<n_sources; i++) {
|
||||||
if (remote_ip == sources[i].ip_addr) {
|
if (UTI_CompareIPs(&remote_ip, &sources[i].ip_addr, NULL) == 0) {
|
||||||
ok = 1;
|
ok = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -418,7 +510,7 @@ read_from_socket(void *anything)
|
|||||||
(src->n_total_samples >= MAX_SAMPLES)) {
|
(src->n_total_samples >= MAX_SAMPLES)) {
|
||||||
++n_completed_sources;
|
++n_completed_sources;
|
||||||
#if 0
|
#if 0
|
||||||
printf("Source %08lx completed\n", src->ip_addr);
|
printf("Source %s completed\n", UTI_IPToString(&src->ip_addr));
|
||||||
#endif
|
#endif
|
||||||
if (n_completed_sources == n_sources) {
|
if (n_completed_sources == n_sources) {
|
||||||
wind_up_acquisition();
|
wind_up_acquisition();
|
||||||
@@ -440,7 +532,7 @@ start_next_source(void)
|
|||||||
{
|
{
|
||||||
probe_source(sources + n_started_sources);
|
probe_source(sources + n_started_sources);
|
||||||
#if 0
|
#if 0
|
||||||
printf("Trying to start source %08lx\n", sources[n_started_sources].ip_addr);
|
printf("Trying to start source %s\n", UTI_IPToString(&sources[n_started_sources].ip_addr));
|
||||||
#endif
|
#endif
|
||||||
n_started_sources++;
|
n_started_sources++;
|
||||||
|
|
||||||
@@ -552,10 +644,10 @@ process_measurements(void)
|
|||||||
for (i=0; i<2*n_sane_sources; i++) {
|
for (i=0; i<2*n_sane_sources; i++) {
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
fprintf(stderr, "Endpoint type %s source index %d [ip=%08lx] offset=%.6f\n",
|
fprintf(stderr, "Endpoint type %s source index %d [ip=%s] offset=%.6f\n",
|
||||||
(eps[i].type == LO) ? "LO" : "HIGH",
|
(eps[i].type == LO) ? "LO" : "HIGH",
|
||||||
eps[i].index,
|
eps[i].index,
|
||||||
sources[eps[i].index].ip_addr,
|
UTI_IPToString(&sources[eps[i].index].ip_addr),
|
||||||
eps[i].offset);
|
eps[i].offset);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -655,10 +747,10 @@ start_source_timeout_handler(void *not_used)
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
ACQ_StartAcquisition(int n, unsigned long *ip_addrs, int threshold, void (*after_hook)(void *), void *anything)
|
ACQ_StartAcquisition(int n, IPAddr *ip_addrs, int threshold, void (*after_hook)(void *), void *anything)
|
||||||
{
|
{
|
||||||
|
|
||||||
int i;
|
int i, ip4, ip6;
|
||||||
|
|
||||||
saved_after_hook = after_hook;
|
saved_after_hook = after_hook;
|
||||||
saved_after_hook_anything = anything;
|
saved_after_hook_anything = anything;
|
||||||
@@ -670,14 +762,18 @@ ACQ_StartAcquisition(int n, unsigned long *ip_addrs, int threshold, void (*after
|
|||||||
n_sources = n;
|
n_sources = n;
|
||||||
sources = MallocArray(SourceRecord, n);
|
sources = MallocArray(SourceRecord, n);
|
||||||
|
|
||||||
for (i=0; i<n; i++) {
|
for (i = ip4 = ip6 = 0; i < n; i++) {
|
||||||
sources[i].ip_addr = ip_addrs[i];
|
sources[i].ip_addr = ip_addrs[i];
|
||||||
sources[i].n_samples = 0;
|
sources[i].n_samples = 0;
|
||||||
sources[i].n_total_samples = 0;
|
sources[i].n_total_samples = 0;
|
||||||
sources[i].n_dead_probes = 0;
|
sources[i].n_dead_probes = 0;
|
||||||
|
if (ip_addrs[i].family == IPADDR_INET4)
|
||||||
|
ip4++;
|
||||||
|
else if (ip_addrs[i].family == IPADDR_INET6)
|
||||||
|
ip6++;
|
||||||
}
|
}
|
||||||
|
|
||||||
initialise_io();
|
initialise_io((ip4 && ip6) ? IPADDR_UNSPEC : (ip4 ? IPADDR_INET4 : IPADDR_INET6));
|
||||||
|
|
||||||
/* Start sampling first source */
|
/* Start sampling first source */
|
||||||
start_next_source();
|
start_next_source();
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -31,13 +31,15 @@
|
|||||||
#ifndef GOT_ACQUIRE_H
|
#ifndef GOT_ACQUIRE_H
|
||||||
#define GOT_ACQUIRE_H
|
#define GOT_ACQUIRE_H
|
||||||
|
|
||||||
|
#include "addressing.h"
|
||||||
|
|
||||||
typedef struct ACQ_SourceRecord *ACQ_Source;
|
typedef struct ACQ_SourceRecord *ACQ_Source;
|
||||||
|
|
||||||
extern void ACQ_Initialise(void);
|
extern void ACQ_Initialise(void);
|
||||||
|
|
||||||
extern void ACQ_Finalise(void);
|
extern void ACQ_Finalise(void);
|
||||||
|
|
||||||
extern void ACQ_StartAcquisition(int n, unsigned long *ip_addrs, int init_slew_threshold,
|
extern void ACQ_StartAcquisition(int n, IPAddr *ip_addrs, int init_slew_threshold,
|
||||||
void (*after_hook)(void *), void *anything);
|
void (*after_hook)(void *), void *anything);
|
||||||
|
|
||||||
extern void ACQ_AccumulateSample(ACQ_Source acq_source, double offset, double root_distance);
|
extern void ACQ_AccumulateSample(ACQ_Source acq_source, double offset, double root_distance);
|
||||||
|
|||||||
28
addressing.h
28
addressing.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -31,16 +31,28 @@
|
|||||||
#ifndef GOT_ADDRESSING_H
|
#ifndef GOT_ADDRESSING_H
|
||||||
#define GOT_ADDRESSING_H
|
#define GOT_ADDRESSING_H
|
||||||
|
|
||||||
/* This type is used to represent an IPv4 address and port
|
#include "sysincl.h"
|
||||||
number. Both parts are in HOST order, NOT network order. */
|
|
||||||
|
/* This type is used to represent an IPv4 address or IPv6 address.
|
||||||
|
All parts are in HOST order, NOT network order. */
|
||||||
|
|
||||||
|
#define IPADDR_UNSPEC 0
|
||||||
|
#define IPADDR_INET4 1
|
||||||
|
#define IPADDR_INET6 2
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned long ip_addr;
|
union {
|
||||||
|
uint32_t in4;
|
||||||
|
uint8_t in6[16];
|
||||||
|
} addr;
|
||||||
|
uint16_t family;
|
||||||
|
} IPAddr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
IPAddr ip_addr;
|
||||||
|
IPAddr local_ip_addr;
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
} NTP_Remote_Address;
|
} NTP_Remote_Address;
|
||||||
|
|
||||||
#if 0
|
|
||||||
unsigned long NTP_IP_Address;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* GOT_ADDRESSING_H */
|
#endif /* GOT_ADDRESSING_H */
|
||||||
|
|
||||||
|
|||||||
212
addrfilt.c
212
addrfilt.c
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
* Copyright (C) Richard P. Curnow 1997,1998,1999,2000,2001,2002,2005
|
* Copyright (C) Richard P. Curnow 1997,1998,1999,2000,2001,2002,2005
|
||||||
|
* Copyright (C) Miroslav Lichvar 2009
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of version 2 of the GNU General Public License as
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
@@ -19,7 +20,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -51,23 +52,35 @@ typedef struct _TableNode {
|
|||||||
} TableNode;
|
} TableNode;
|
||||||
|
|
||||||
struct ADF_AuthTableInst {
|
struct ADF_AuthTableInst {
|
||||||
TableNode base;
|
TableNode base4; /* IPv4 node */
|
||||||
|
TableNode base6; /* IPv6 node */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
inline static unsigned long
|
static void
|
||||||
get_subnet(unsigned long addr)
|
split_ip6(IPAddr *ip, uint32_t *dst)
|
||||||
{
|
{
|
||||||
return (addr >> (32-NBITS)) & ((1UL<<NBITS) - 1);
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
dst[i] = ip->addr.in6[i * 4 + 0] << 24 |
|
||||||
|
ip->addr.in6[i * 4 + 1] << 16 |
|
||||||
|
ip->addr.in6[i * 4 + 2] << 8 |
|
||||||
|
ip->addr.in6[i * 4 + 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
inline static unsigned long
|
inline static uint32_t
|
||||||
get_residual(unsigned long addr)
|
get_subnet(uint32_t *addr, unsigned int where)
|
||||||
{
|
{
|
||||||
return (addr << NBITS);
|
int off;
|
||||||
|
|
||||||
|
off = where / 32;
|
||||||
|
where %= 32;
|
||||||
|
|
||||||
|
return (addr[off] >> (32 - NBITS - where)) & ((1UL << NBITS) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -79,8 +92,10 @@ ADF_CreateTable(void)
|
|||||||
result = MallocNew(struct ADF_AuthTableInst);
|
result = MallocNew(struct ADF_AuthTableInst);
|
||||||
|
|
||||||
/* Default is that nothing is allowed */
|
/* Default is that nothing is allowed */
|
||||||
result->base.state = DENY;
|
result->base4.state = DENY;
|
||||||
result->base.extended = NULL;
|
result->base4.extended = NULL;
|
||||||
|
result->base6.state = DENY;
|
||||||
|
result->base6.extended = NULL;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -135,22 +150,22 @@ open_node(TableNode *node)
|
|||||||
|
|
||||||
static ADF_Status
|
static ADF_Status
|
||||||
set_subnet(TableNode *start_node,
|
set_subnet(TableNode *start_node,
|
||||||
unsigned long ip,
|
uint32_t *ip,
|
||||||
|
int ip_len,
|
||||||
int subnet_bits,
|
int subnet_bits,
|
||||||
State new_state,
|
State new_state,
|
||||||
int delete_children)
|
int delete_children)
|
||||||
{
|
{
|
||||||
int bits_to_go;
|
int bits_to_go, bits_consumed;
|
||||||
unsigned long residual;
|
uint32_t subnet;
|
||||||
unsigned long subnet;
|
|
||||||
TableNode *node;
|
TableNode *node;
|
||||||
|
|
||||||
|
bits_consumed = 0;
|
||||||
bits_to_go = subnet_bits;
|
bits_to_go = subnet_bits;
|
||||||
residual = ip;
|
|
||||||
node = start_node;
|
node = start_node;
|
||||||
|
|
||||||
if ((subnet_bits < 0) ||
|
if ((subnet_bits < 0) ||
|
||||||
(subnet_bits > 32)) {
|
(subnet_bits > 32 * ip_len)) {
|
||||||
|
|
||||||
return ADF_BADSUBNET;
|
return ADF_BADSUBNET;
|
||||||
|
|
||||||
@@ -159,13 +174,13 @@ set_subnet(TableNode *start_node,
|
|||||||
if ((bits_to_go & (NBITS-1)) == 0) {
|
if ((bits_to_go & (NBITS-1)) == 0) {
|
||||||
|
|
||||||
while (bits_to_go > 0) {
|
while (bits_to_go > 0) {
|
||||||
subnet = get_subnet(residual);
|
subnet = get_subnet(ip, bits_consumed);
|
||||||
residual = get_residual(residual);
|
|
||||||
if (!(node->extended)) {
|
if (!(node->extended)) {
|
||||||
open_node(node);
|
open_node(node);
|
||||||
}
|
}
|
||||||
node = &(node->extended[subnet]);
|
node = &(node->extended[subnet]);
|
||||||
bits_to_go -= NBITS;
|
bits_to_go -= NBITS;
|
||||||
|
bits_consumed += NBITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (delete_children) {
|
if (delete_children) {
|
||||||
@@ -178,18 +193,18 @@ set_subnet(TableNode *start_node,
|
|||||||
TableNode *this_node;
|
TableNode *this_node;
|
||||||
|
|
||||||
while (bits_to_go >= NBITS) {
|
while (bits_to_go >= NBITS) {
|
||||||
subnet = get_subnet(residual);
|
subnet = get_subnet(ip, bits_consumed);
|
||||||
residual = get_residual(residual);
|
|
||||||
if (!(node->extended)) {
|
if (!(node->extended)) {
|
||||||
open_node(node);
|
open_node(node);
|
||||||
}
|
}
|
||||||
node = &(node->extended[subnet]);
|
node = &(node->extended[subnet]);
|
||||||
bits_to_go -= NBITS;
|
bits_to_go -= NBITS;
|
||||||
|
bits_consumed += NBITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* How many subnet entries to set : 1->8, 2->4, 3->2 */
|
/* How many subnet entries to set : 1->8, 2->4, 3->2 */
|
||||||
N = 1 << (NBITS-bits_to_go);
|
N = 1 << (NBITS-bits_to_go);
|
||||||
subnet = get_subnet(residual);
|
subnet = get_subnet(ip, bits_consumed);
|
||||||
if (!(node->extended)) {
|
if (!(node->extended)) {
|
||||||
open_node(node);
|
open_node(node);
|
||||||
}
|
}
|
||||||
@@ -210,12 +225,41 @@ set_subnet(TableNode *start_node,
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
static ADF_Status
|
||||||
|
set_subnet_(ADF_AuthTable table,
|
||||||
|
IPAddr *ip_addr,
|
||||||
|
int subnet_bits,
|
||||||
|
State new_state,
|
||||||
|
int delete_children)
|
||||||
|
{
|
||||||
|
uint32_t ip6[4];
|
||||||
|
|
||||||
|
switch (ip_addr->family) {
|
||||||
|
case IPADDR_INET4:
|
||||||
|
return set_subnet(&table->base4, &ip_addr->addr.in4, 1, subnet_bits, new_state, delete_children);
|
||||||
|
case IPADDR_INET6:
|
||||||
|
split_ip6(ip_addr, ip6);
|
||||||
|
return set_subnet(&table->base6, ip6, 4, subnet_bits, new_state, delete_children);
|
||||||
|
case IPADDR_UNSPEC:
|
||||||
|
/* Apply to both, subnet_bits has to be 0 */
|
||||||
|
if (subnet_bits != 0)
|
||||||
|
return ADF_BADSUBNET;
|
||||||
|
memset(ip6, 0, sizeof (ip6));
|
||||||
|
if (set_subnet(&table->base4, ip6, 1, 0, new_state, delete_children) == ADF_SUCCESS &&
|
||||||
|
set_subnet(&table->base6, ip6, 4, 0, new_state, delete_children) == ADF_SUCCESS)
|
||||||
|
return ADF_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ADF_BADSUBNET;
|
||||||
|
}
|
||||||
|
|
||||||
ADF_Status
|
ADF_Status
|
||||||
ADF_Allow(ADF_AuthTable table,
|
ADF_Allow(ADF_AuthTable table,
|
||||||
unsigned long ip,
|
IPAddr *ip,
|
||||||
int subnet_bits)
|
int subnet_bits)
|
||||||
{
|
{
|
||||||
return set_subnet(&(table->base), ip, subnet_bits, ALLOW, 0);
|
return set_subnet_(table, ip, subnet_bits, ALLOW, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -223,30 +267,30 @@ ADF_Allow(ADF_AuthTable table,
|
|||||||
|
|
||||||
ADF_Status
|
ADF_Status
|
||||||
ADF_AllowAll(ADF_AuthTable table,
|
ADF_AllowAll(ADF_AuthTable table,
|
||||||
unsigned long ip,
|
IPAddr *ip,
|
||||||
int subnet_bits)
|
int subnet_bits)
|
||||||
{
|
{
|
||||||
return set_subnet(&(table->base), ip, subnet_bits, ALLOW, 1);
|
return set_subnet_(table, ip, subnet_bits, ALLOW, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
ADF_Status
|
ADF_Status
|
||||||
ADF_Deny(ADF_AuthTable table,
|
ADF_Deny(ADF_AuthTable table,
|
||||||
unsigned long ip,
|
IPAddr *ip,
|
||||||
int subnet_bits)
|
int subnet_bits)
|
||||||
{
|
{
|
||||||
return set_subnet(&(table->base), ip, subnet_bits, DENY, 0);
|
return set_subnet_(table, ip, subnet_bits, DENY, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
ADF_Status
|
ADF_Status
|
||||||
ADF_DenyAll(ADF_AuthTable table,
|
ADF_DenyAll(ADF_AuthTable table,
|
||||||
unsigned long ip,
|
IPAddr *ip,
|
||||||
int subnet_bits)
|
int subnet_bits)
|
||||||
{
|
{
|
||||||
return set_subnet(&(table->base), ip, subnet_bits, DENY, 1);
|
return set_subnet_(table, ip, subnet_bits, DENY, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -254,32 +298,33 @@ ADF_DenyAll(ADF_AuthTable table,
|
|||||||
void
|
void
|
||||||
ADF_DestroyTable(ADF_AuthTable table)
|
ADF_DestroyTable(ADF_AuthTable table)
|
||||||
{
|
{
|
||||||
close_node(&(table->base));
|
close_node(&table->base4);
|
||||||
|
close_node(&table->base6);
|
||||||
Free(table);
|
Free(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
check_ip_in_node(TableNode *start_node, unsigned long ip)
|
check_ip_in_node(TableNode *start_node, uint32_t *ip)
|
||||||
{
|
{
|
||||||
unsigned long residual, subnet;
|
uint32_t subnet;
|
||||||
|
int bits_consumed = 0;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
int finished = 0;
|
int finished = 0;
|
||||||
TableNode *node;
|
TableNode *node;
|
||||||
State state=DENY;
|
State state=DENY;
|
||||||
|
|
||||||
node = start_node;
|
node = start_node;
|
||||||
residual = ip;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (node->state != AS_PARENT) {
|
if (node->state != AS_PARENT) {
|
||||||
state = node->state;
|
state = node->state;
|
||||||
}
|
}
|
||||||
if (node->extended) {
|
if (node->extended) {
|
||||||
subnet = get_subnet(residual);
|
subnet = get_subnet(ip, bits_consumed);
|
||||||
residual = get_residual(residual);
|
|
||||||
node = &(node->extended[subnet]);
|
node = &(node->extended[subnet]);
|
||||||
|
bits_consumed += NBITS;
|
||||||
} else {
|
} else {
|
||||||
/* Make decision on this node */
|
/* Make decision on this node */
|
||||||
finished = 1;
|
finished = 1;
|
||||||
@@ -306,38 +351,63 @@ check_ip_in_node(TableNode *start_node, unsigned long ip)
|
|||||||
|
|
||||||
int
|
int
|
||||||
ADF_IsAllowed(ADF_AuthTable table,
|
ADF_IsAllowed(ADF_AuthTable table,
|
||||||
unsigned long ip)
|
IPAddr *ip_addr)
|
||||||
{
|
{
|
||||||
|
uint32_t ip6[4];
|
||||||
|
|
||||||
return check_ip_in_node(&(table->base), ip);
|
switch (ip_addr->family) {
|
||||||
|
case IPADDR_INET4:
|
||||||
|
return check_ip_in_node(&table->base4, &ip_addr->addr.in4);
|
||||||
|
case IPADDR_INET6:
|
||||||
|
split_ip6(ip_addr, ip6);
|
||||||
|
return check_ip_in_node(&table->base6, ip6);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
#if defined TEST
|
#if defined TEST
|
||||||
|
|
||||||
static void print_node(TableNode *node, unsigned long addr, int shift, int subnet_bits)
|
static void print_node(TableNode *node, uint32_t *addr, int ip_len, int shift, int subnet_bits)
|
||||||
{
|
{
|
||||||
unsigned long new_addr;
|
uint32_t new_addr[4];
|
||||||
int i;
|
int i;
|
||||||
TableNode *sub_node;
|
TableNode *sub_node;
|
||||||
|
|
||||||
for (i=0; i<subnet_bits; i++) putchar(' ');
|
for (i=0; i<subnet_bits; i++) putchar(' ');
|
||||||
|
|
||||||
printf("%d.%d.%d.%d/%d : %s\n",
|
if (ip_len == 1)
|
||||||
((addr >> 24) & 255),
|
printf("%d.%d.%d.%d",
|
||||||
((addr >> 16) & 255),
|
((addr[0] >> 24) & 255),
|
||||||
((addr >> 8) & 255),
|
((addr[0] >> 16) & 255),
|
||||||
((addr ) & 255),
|
((addr[0] >> 8) & 255),
|
||||||
|
((addr[0] ) & 255));
|
||||||
|
else {
|
||||||
|
for (i=0; i<4; i++) {
|
||||||
|
if (addr[i])
|
||||||
|
printf("%d.%d.%d.%d",
|
||||||
|
((addr[i] >> 24) & 255),
|
||||||
|
((addr[i] >> 16) & 255),
|
||||||
|
((addr[i] >> 8) & 255),
|
||||||
|
((addr[i] ) & 255));
|
||||||
|
putchar(i < 3 ? ':' : '\0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("/%d : %s\n",
|
||||||
subnet_bits,
|
subnet_bits,
|
||||||
(node->state == ALLOW) ? "allow" :
|
(node->state == ALLOW) ? "allow" :
|
||||||
(node->state == DENY) ? "deny" : "as parent");
|
(node->state == DENY) ? "deny" : "as parent");
|
||||||
if (node->extended) {
|
if (node->extended) {
|
||||||
for (i=0; i<16; i++) {
|
for (i=0; i<16; i++) {
|
||||||
sub_node = &((*(node->extended))[i]);
|
sub_node = &(node->extended[i]);
|
||||||
new_addr = addr | ((unsigned long) i << shift);
|
new_addr[0] = addr[0];
|
||||||
print_node(sub_node, new_addr, shift - 4, subnet_bits + 4);
|
new_addr[1] = addr[1];
|
||||||
|
new_addr[2] = addr[2];
|
||||||
|
new_addr[3] = addr[3];
|
||||||
|
new_addr[ip_len - 1 - shift / 32] |= ((uint32_t)i << (shift % 32));
|
||||||
|
print_node(sub_node, new_addr, ip_len, shift - 4, subnet_bits + 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -346,11 +416,15 @@ static void print_node(TableNode *node, unsigned long addr, int shift, int subne
|
|||||||
|
|
||||||
static void print_table(ADF_AuthTable table)
|
static void print_table(ADF_AuthTable table)
|
||||||
{
|
{
|
||||||
unsigned long addr = 0;
|
uint32_t addr[4];
|
||||||
int shift = 28;
|
|
||||||
int subnet_bits = 0;
|
|
||||||
|
|
||||||
print_node(&table->base, addr, shift, subnet_bits);
|
memset(addr, 0, sizeof (addr));
|
||||||
|
printf("IPv4 table:\n");
|
||||||
|
print_node(&table->base4, addr, 1, 28, 0);
|
||||||
|
|
||||||
|
memset(addr, 0, sizeof (addr));
|
||||||
|
printf("IPv6 table:\n");
|
||||||
|
print_node(&table->base6, addr, 4, 124, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,13 +432,41 @@ static void print_table(ADF_AuthTable table)
|
|||||||
|
|
||||||
int main (int argc, char **argv)
|
int main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
IPAddr ip;
|
||||||
ADF_AuthTable table;
|
ADF_AuthTable table;
|
||||||
table = ADF_CreateTable();
|
table = ADF_CreateTable();
|
||||||
|
|
||||||
ADF_Allow(table, 0x7e800000, 9);
|
ip.family = IPADDR_INET4;
|
||||||
ADF_Deny(table, 0x7ecc0000, 14);
|
|
||||||
/* ADF_Deny(table, 0x7f000001, 32); */
|
ip.addr.in4 = 0x7e800000;
|
||||||
/* ADF_Allow(table, 0x7f000000, 8); */
|
ADF_Allow(table, &ip, 9);
|
||||||
|
ip.addr.in4 = 0x7ecc0000;
|
||||||
|
ADF_Deny(table, &ip, 14);
|
||||||
|
#if 0
|
||||||
|
ip.addr.in4 = 0x7f000001;
|
||||||
|
ADF_Deny(table, &ip, 32);
|
||||||
|
ip.addr.in4 = 0x7f000000;
|
||||||
|
ADF_Allow(table, &ip, 8);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
printf("allowed: %d\n", ADF_IsAllowed(table, &ip));
|
||||||
|
ip.addr.in4 ^= 1;
|
||||||
|
printf("allowed: %d\n", ADF_IsAllowed(table, &ip));
|
||||||
|
|
||||||
|
ip.family = IPADDR_INET6;
|
||||||
|
|
||||||
|
memcpy(ip.addr.in6, "abcdefghijklmnop", 16);
|
||||||
|
ADF_Deny(table, &ip, 66);
|
||||||
|
ADF_Allow(table, &ip, 59);
|
||||||
|
|
||||||
|
memcpy(ip.addr.in6, "xbcdefghijklmnop", 16);
|
||||||
|
ADF_Deny(table, &ip, 128);
|
||||||
|
ip.addr.in6[15] ^= 3;
|
||||||
|
ADF_Allow(table, &ip, 127);
|
||||||
|
|
||||||
|
printf("allowed: %d\n", ADF_IsAllowed(table, &ip));
|
||||||
|
ip.addr.in4 ^= 1;
|
||||||
|
printf("allowed: %d\n", ADF_IsAllowed(table, &ip));
|
||||||
|
|
||||||
print_table(table);
|
print_table(table);
|
||||||
|
|
||||||
|
|||||||
14
addrfilt.h
14
addrfilt.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -31,6 +31,8 @@
|
|||||||
#ifndef GOT_ADDRFILT_H
|
#ifndef GOT_ADDRFILT_H
|
||||||
#define GOT_ADDRFILT_H
|
#define GOT_ADDRFILT_H
|
||||||
|
|
||||||
|
#include "addressing.h"
|
||||||
|
|
||||||
typedef struct ADF_AuthTableInst *ADF_AuthTable;
|
typedef struct ADF_AuthTableInst *ADF_AuthTable;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -45,25 +47,25 @@ extern ADF_AuthTable ADF_CreateTable(void);
|
|||||||
/* Allow anything in the supplied subnet, EXCEPT for any more specific
|
/* Allow anything in the supplied subnet, EXCEPT for any more specific
|
||||||
subnets that are already defined */
|
subnets that are already defined */
|
||||||
extern ADF_Status ADF_Allow(ADF_AuthTable table,
|
extern ADF_Status ADF_Allow(ADF_AuthTable table,
|
||||||
unsigned long ip,
|
IPAddr *ip,
|
||||||
int subnet_bits);
|
int subnet_bits);
|
||||||
|
|
||||||
/* Allow anything in the supplied subnet, overwriting existing
|
/* Allow anything in the supplied subnet, overwriting existing
|
||||||
definitions for any more specific subnets */
|
definitions for any more specific subnets */
|
||||||
extern ADF_Status ADF_AllowAll(ADF_AuthTable table,
|
extern ADF_Status ADF_AllowAll(ADF_AuthTable table,
|
||||||
unsigned long ip,
|
IPAddr *ip,
|
||||||
int subnet_bits);
|
int subnet_bits);
|
||||||
|
|
||||||
/* Deny anything in the supplied subnet, EXCEPT for any more specific
|
/* Deny anything in the supplied subnet, EXCEPT for any more specific
|
||||||
subnets that are already defined */
|
subnets that are already defined */
|
||||||
extern ADF_Status ADF_Deny(ADF_AuthTable table,
|
extern ADF_Status ADF_Deny(ADF_AuthTable table,
|
||||||
unsigned long ip,
|
IPAddr *ip,
|
||||||
int subnet_bits);
|
int subnet_bits);
|
||||||
|
|
||||||
/* Deny anything in the supplied subnet, overwriting existing
|
/* Deny anything in the supplied subnet, overwriting existing
|
||||||
definitions for any more specific subnets */
|
definitions for any more specific subnets */
|
||||||
extern ADF_Status ADF_DenyAll(ADF_AuthTable table,
|
extern ADF_Status ADF_DenyAll(ADF_AuthTable table,
|
||||||
unsigned long ip,
|
IPAddr *ip,
|
||||||
int subnet_bits);
|
int subnet_bits);
|
||||||
|
|
||||||
/* Clear up the table */
|
/* Clear up the table */
|
||||||
@@ -72,6 +74,6 @@ extern void ADF_DestroyTable(ADF_AuthTable table);
|
|||||||
/* Check whether a given IP address is allowed by the rules in
|
/* Check whether a given IP address is allowed by the rules in
|
||||||
the table */
|
the table */
|
||||||
extern int ADF_IsAllowed(ADF_AuthTable table,
|
extern int ADF_IsAllowed(ADF_AuthTable table,
|
||||||
unsigned long ip);
|
IPAddr *ip);
|
||||||
|
|
||||||
#endif /* GOT_ADDRFILT_H */
|
#endif /* GOT_ADDRFILT_H */
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ timeout_handler(void *arbitrary)
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
BRD_AddDestination(unsigned long addr, unsigned short port, int interval)
|
BRD_AddDestination(IPAddr *addr, unsigned short port, int interval)
|
||||||
{
|
{
|
||||||
if (max_destinations == n_destinations) {
|
if (max_destinations == n_destinations) {
|
||||||
/* Expand array */
|
/* Expand array */
|
||||||
@@ -144,7 +144,8 @@ BRD_AddDestination(unsigned long addr, unsigned short port, int interval)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
destinations[n_destinations].addr.ip_addr = addr;
|
destinations[n_destinations].addr.ip_addr = *addr;
|
||||||
|
destinations[n_destinations].addr.local_ip_addr.family = IPADDR_UNSPEC;
|
||||||
destinations[n_destinations].addr.port = port;
|
destinations[n_destinations].addr.port = port;
|
||||||
destinations[n_destinations].interval = interval;
|
destinations[n_destinations].interval = interval;
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -31,9 +31,11 @@
|
|||||||
#ifndef GOT_BROADCAST_H
|
#ifndef GOT_BROADCAST_H
|
||||||
#define GOT_BROADCAST_H
|
#define GOT_BROADCAST_H
|
||||||
|
|
||||||
|
#include "addressing.h"
|
||||||
|
|
||||||
extern void BRD_Initialise(void);
|
extern void BRD_Initialise(void);
|
||||||
extern void BRD_Finalise(void);
|
extern void BRD_Finalise(void);
|
||||||
extern void BRD_AddDestination(unsigned long addr, unsigned short port, int interval);
|
extern void BRD_AddDestination(IPAddr *addr, unsigned short port, int interval);
|
||||||
|
|
||||||
#endif /* GOT_BROADCAST_H */
|
#endif /* GOT_BROADCAST_H */
|
||||||
|
|
||||||
|
|||||||
160
candm.h
160
candm.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -34,6 +34,7 @@
|
|||||||
#define GOT_CANDM_H
|
#define GOT_CANDM_H
|
||||||
|
|
||||||
#include "sysincl.h"
|
#include "sysincl.h"
|
||||||
|
#include "addressing.h"
|
||||||
|
|
||||||
/* This is the default port to use for CANDM, if no alternative is
|
/* This is the default port to use for CANDM, if no alternative is
|
||||||
defined */
|
defined */
|
||||||
@@ -91,38 +92,55 @@
|
|||||||
password. (This time value has long since gone by) */
|
password. (This time value has long since gone by) */
|
||||||
#define SPECIAL_UTOKEN 0x10101010
|
#define SPECIAL_UTOKEN 0x10101010
|
||||||
|
|
||||||
|
/* Structure used to exchange timevals independent on size of time_t */
|
||||||
|
typedef struct {
|
||||||
|
uint32_t tv_sec_high;
|
||||||
|
uint32_t tv_sec_low;
|
||||||
|
uint32_t tv_nsec;
|
||||||
|
} Timeval;
|
||||||
|
|
||||||
|
/* This is used in tv_sec_high for 32-bit timestamps */
|
||||||
|
#define TV_NOHIGHSEC 0x7fffffff
|
||||||
|
|
||||||
|
/* 32-bit floating-point format consisting of 7-bit signed exponent
|
||||||
|
and 25-bit signed coefficient without hidden bit.
|
||||||
|
The result is calculated as: 2^(exp - 25) * coef */
|
||||||
|
typedef struct {
|
||||||
|
int32_t f;
|
||||||
|
} Float;
|
||||||
|
|
||||||
/* The EOR (end of record) fields are used by the offsetof operator in
|
/* The EOR (end of record) fields are used by the offsetof operator in
|
||||||
pktlength.c, to get the number of bytes that ought to be
|
pktlength.c, to get the number of bytes that ought to be
|
||||||
transmitted for each packet type. */
|
transmitted for each packet type. */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t mask;
|
IPAddr mask;
|
||||||
uint32_t address;
|
IPAddr address;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} REQ_Online;
|
} REQ_Online;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t mask;
|
IPAddr mask;
|
||||||
uint32_t address;
|
IPAddr address;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} REQ_Offline;
|
} REQ_Offline;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t mask;
|
IPAddr mask;
|
||||||
uint32_t address;
|
IPAddr address;
|
||||||
int32_t n_good_samples;
|
int32_t n_good_samples;
|
||||||
int32_t n_total_samples;
|
int32_t n_total_samples;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} REQ_Burst;
|
} REQ_Burst;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t address;
|
IPAddr address;
|
||||||
int32_t new_minpoll;
|
int32_t new_minpoll;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} REQ_Modify_Minpoll;
|
} REQ_Modify_Minpoll;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t address;
|
IPAddr address;
|
||||||
int32_t new_maxpoll;
|
int32_t new_maxpoll;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} REQ_Modify_Maxpoll;
|
} REQ_Modify_Maxpoll;
|
||||||
@@ -133,29 +151,29 @@ typedef struct {
|
|||||||
} REQ_Dump;
|
} REQ_Dump;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t address;
|
IPAddr address;
|
||||||
int32_t new_max_delay;
|
Float new_max_delay;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} REQ_Modify_Maxdelay;
|
} REQ_Modify_Maxdelay;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t address;
|
IPAddr address;
|
||||||
int32_t new_max_delay_ratio;
|
Float new_max_delay_ratio;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} REQ_Modify_Maxdelayratio;
|
} REQ_Modify_Maxdelayratio;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t new_max_update_skew;
|
Float new_max_update_skew;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} REQ_Modify_Maxupdateskew;
|
} REQ_Modify_Maxupdateskew;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct timeval ts;
|
Timeval ts;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} REQ_Logon;
|
} REQ_Logon;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct timeval ts;
|
Timeval ts;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} REQ_Settime;
|
} REQ_Settime;
|
||||||
|
|
||||||
@@ -184,32 +202,35 @@ typedef struct {
|
|||||||
} REQ_Rekey;
|
} REQ_Rekey;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t ip;
|
IPAddr ip;
|
||||||
int32_t subnet_bits;
|
int32_t subnet_bits;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} REQ_Allow_Deny;
|
} REQ_Allow_Deny;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t ip;
|
IPAddr ip;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} REQ_Ac_Check;
|
} REQ_Ac_Check;
|
||||||
|
|
||||||
|
/* Flags used in NTP source requests */
|
||||||
|
#define REQ_ADDSRC_ONLINE 0x1
|
||||||
|
#define REQ_ADDSRC_AUTOOFFLINE 0x2
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t ip_addr;
|
IPAddr ip_addr;
|
||||||
uint32_t port;
|
uint32_t port;
|
||||||
int32_t minpoll;
|
int32_t minpoll;
|
||||||
int32_t maxpoll;
|
int32_t maxpoll;
|
||||||
int32_t presend_minpoll;
|
int32_t presend_minpoll;
|
||||||
int32_t online;
|
|
||||||
int32_t auto_offline;
|
|
||||||
uint32_t authkey;
|
uint32_t authkey;
|
||||||
int32_t max_delay;
|
Float max_delay;
|
||||||
int32_t max_delay_ratio;
|
Float max_delay_ratio;
|
||||||
|
uint32_t flags;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} REQ_NTP_Source;
|
} REQ_NTP_Source;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t ip_addr;
|
IPAddr ip_addr;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} REQ_Del_Source;
|
} REQ_Del_Source;
|
||||||
|
|
||||||
@@ -218,7 +239,7 @@ typedef struct {
|
|||||||
} REQ_WriteRtc;
|
} REQ_WriteRtc;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t dfreq;
|
Float dfreq;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} REQ_Dfreq;
|
} REQ_Dfreq;
|
||||||
|
|
||||||
@@ -250,7 +271,7 @@ typedef struct {
|
|||||||
} REQ_CycleLogs;
|
} REQ_CycleLogs;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t ip;
|
IPAddr ip;
|
||||||
uint32_t bits_specd;
|
uint32_t bits_specd;
|
||||||
} REQ_SubnetsAccessed_Subnet;
|
} REQ_SubnetsAccessed_Subnet;
|
||||||
|
|
||||||
@@ -263,11 +284,11 @@ typedef struct {
|
|||||||
|
|
||||||
/* This is based on the response size rather than the
|
/* This is based on the response size rather than the
|
||||||
request size */
|
request size */
|
||||||
#define MAX_CLIENT_ACCESSES 16
|
#define MAX_CLIENT_ACCESSES 8
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t n_clients;
|
uint32_t n_clients;
|
||||||
uint32_t client_ips[MAX_CLIENT_ACCESSES];
|
IPAddr client_ips[MAX_CLIENT_ACCESSES];
|
||||||
} REQ_ClientAccesses;
|
} REQ_ClientAccesses;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -310,9 +331,18 @@ typedef struct {
|
|||||||
|
|
||||||
Version 3 : NTP_Source message lengthened (auto_offline)
|
Version 3 : NTP_Source message lengthened (auto_offline)
|
||||||
|
|
||||||
|
Version 4 : IPv6 addressing added, 64-bit time values, sourcestats
|
||||||
|
and tracking reports extended, added flags to NTP source request,
|
||||||
|
trimmed source report, replaced fixed-point format with floating-point
|
||||||
|
and used also instead of integer microseconds
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PROTO_VERSION_NUMBER 3
|
#define PROTO_VERSION_NUMBER 4
|
||||||
|
|
||||||
|
/* The oldest protocol version that is compatible enough with
|
||||||
|
the current version to report a version mismatch */
|
||||||
|
#define PROTO_VERSION_MISMATCH_COMPAT 4
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
@@ -377,13 +407,6 @@ typedef struct {
|
|||||||
#define PERMIT_LOCAL 1
|
#define PERMIT_LOCAL 1
|
||||||
#define PERMIT_AUTH 2
|
#define PERMIT_AUTH 2
|
||||||
|
|
||||||
/* ================================================== */
|
|
||||||
/* These conversion utilities are used to convert between the internal
|
|
||||||
and the 'wire' representation of real quantities */
|
|
||||||
|
|
||||||
#define WIRE2REAL(x) ((double) ((int32_t) ntohl(x)) / 65536.0)
|
|
||||||
#define REAL2WIRE(x) (htonl((int32_t)(0.5 + 65536.0 * (x))))
|
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
/* Reply codes */
|
/* Reply codes */
|
||||||
@@ -419,6 +442,9 @@ typedef struct {
|
|||||||
#define STT_BADRTCFILE 14
|
#define STT_BADRTCFILE 14
|
||||||
#define STT_INACTIVE 15
|
#define STT_INACTIVE 15
|
||||||
#define STT_BADSAMPLE 16
|
#define STT_BADSAMPLE 16
|
||||||
|
#define STT_INVALIDAF 17
|
||||||
|
#define STT_BADPKTVERSION 18
|
||||||
|
#define STT_BADPKTLENGTH 19
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
@@ -440,67 +466,65 @@ typedef struct {
|
|||||||
#define RPY_SD_ST_OTHER 4
|
#define RPY_SD_ST_OTHER 4
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t ip_addr;
|
IPAddr ip_addr;
|
||||||
uint16_t poll;
|
uint16_t poll;
|
||||||
uint16_t stratum;
|
uint16_t stratum;
|
||||||
uint16_t state;
|
uint16_t state;
|
||||||
uint16_t mode;
|
uint16_t mode;
|
||||||
uint32_t since_sample;
|
uint32_t since_sample;
|
||||||
int32_t orig_latest_meas;
|
Float orig_latest_meas;
|
||||||
int32_t latest_meas;
|
Float latest_meas;
|
||||||
uint32_t latest_meas_err;
|
Float latest_meas_err;
|
||||||
int32_t est_offset;
|
|
||||||
uint32_t est_offset_err;
|
|
||||||
int32_t resid_freq;
|
|
||||||
uint32_t resid_skew;
|
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} RPY_Source_Data;
|
} RPY_Source_Data;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t ref_id;
|
uint32_t ref_id;
|
||||||
|
IPAddr ip_addr;
|
||||||
uint32_t stratum;
|
uint32_t stratum;
|
||||||
uint32_t ref_time_s;
|
Timeval ref_time;
|
||||||
uint32_t ref_time_us;
|
Float current_correction;
|
||||||
uint32_t current_correction_s;
|
Float freq_ppm;
|
||||||
uint32_t current_correction_us;
|
Float resid_freq_ppm;
|
||||||
int32_t freq_ppm;
|
Float skew_ppm;
|
||||||
int32_t resid_freq_ppm;
|
Float root_delay;
|
||||||
int32_t skew_ppm;
|
Float root_dispersion;
|
||||||
int32_t root_delay;
|
|
||||||
int32_t root_dispersion;
|
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} RPY_Tracking;
|
} RPY_Tracking;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t ip_addr;
|
uint32_t ref_id;
|
||||||
|
IPAddr ip_addr;
|
||||||
uint32_t n_samples;
|
uint32_t n_samples;
|
||||||
uint32_t n_runs;
|
uint32_t n_runs;
|
||||||
uint32_t span_seconds;
|
uint32_t span_seconds;
|
||||||
uint32_t sd_us;
|
Float sd;
|
||||||
int32_t resid_freq_ppm;
|
Float resid_freq_ppm;
|
||||||
int32_t skew_ppm;
|
Float skew_ppm;
|
||||||
|
Float est_offset;
|
||||||
|
Float est_offset_err;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} RPY_Sourcestats;
|
} RPY_Sourcestats;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t ref_time;
|
Timeval ref_time;
|
||||||
uint16_t n_samples;
|
uint16_t n_samples;
|
||||||
uint16_t n_runs;
|
uint16_t n_runs;
|
||||||
uint32_t span_seconds;
|
uint32_t span_seconds;
|
||||||
int32_t rtc_seconds_fast;
|
Float rtc_seconds_fast;
|
||||||
int32_t rtc_gain_rate_ppm;
|
Float rtc_gain_rate_ppm;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} RPY_Rtc;
|
} RPY_Rtc;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t centiseconds;
|
uint32_t centiseconds;
|
||||||
int32_t dfreq_ppm;
|
Float dfreq_ppm;
|
||||||
int32_t new_afreq_ppm;
|
Float new_afreq_ppm;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} RPY_ManualTimestamp;
|
} RPY_ManualTimestamp;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t ip;
|
IPAddr ip;
|
||||||
uint32_t bits_specd;
|
uint32_t bits_specd;
|
||||||
uint32_t bitmap[8];
|
uint32_t bitmap[8];
|
||||||
} RPY_SubnetsAccessed_Subnet;
|
} RPY_SubnetsAccessed_Subnet;
|
||||||
@@ -511,7 +535,7 @@ typedef struct {
|
|||||||
} RPY_SubnetsAccessed;
|
} RPY_SubnetsAccessed;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t ip;
|
IPAddr ip;
|
||||||
uint32_t client_hits;
|
uint32_t client_hits;
|
||||||
uint32_t peer_hits;
|
uint32_t peer_hits;
|
||||||
uint32_t cmd_hits_auth;
|
uint32_t cmd_hits_auth;
|
||||||
@@ -536,10 +560,10 @@ typedef struct {
|
|||||||
#define MAX_MANUAL_LIST_SAMPLES 32
|
#define MAX_MANUAL_LIST_SAMPLES 32
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t when;
|
Timeval when;
|
||||||
int32_t slewed_offset;
|
Float slewed_offset;
|
||||||
int32_t orig_offset;
|
Float orig_offset;
|
||||||
int32_t residual;
|
Float residual;
|
||||||
} RPY_ManualListSample;
|
} RPY_ManualListSample;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
8
chrony.1
8
chrony.1
@@ -1,4 +1,4 @@
|
|||||||
.TH CHRONY 1 "August 10, 2001" chrony "User's Manual"
|
.TH CHRONY 1 "December 04, 2009" chrony "User's Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
chrony \- programs for keeping computer clocks accurate
|
chrony \- programs for keeping computer clocks accurate
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ gains or loses time and uses this information to keep it accurate
|
|||||||
between measurements from the reference.
|
between measurements from the reference.
|
||||||
|
|
||||||
The reference time can be derived from either Network Time Protocol
|
The reference time can be derived from either Network Time Protocol
|
||||||
(NTP) servers (preferred), or wristwatch-and-keyboard (via \fIchronyc\fR).
|
(NTP) servers, reference clocks, or wristwatch-and-keyboard (via \fIchronyc\fR).
|
||||||
The main source of information about the Network Time Protocol is
|
The main source of information about the Network Time Protocol is
|
||||||
\fIhttp://www.eecis.udel.edu/~ntp\fR.
|
\fIhttp://www.eecis.udel.edu/~ntp\fR.
|
||||||
|
|
||||||
@@ -49,13 +49,15 @@ On an ethernet LAN : 100-200 microseconds, often much better
|
|||||||
On a V32bis dial-up modem connection : 10's of milliseconds (from one
|
On a V32bis dial-up modem connection : 10's of milliseconds (from one
|
||||||
session to the next)
|
session to the next)
|
||||||
|
|
||||||
|
With a good reference clock the accuracy can reach one microsecond.
|
||||||
|
|
||||||
\fIchronyd\fR can also operate as an RFC1305-compatible NTP server and peer.
|
\fIchronyd\fR can also operate as an RFC1305-compatible NTP server and peer.
|
||||||
|
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.BR chronyc(1),
|
.BR chronyc(1),
|
||||||
.BR chrony(1)
|
.BR chrony(1)
|
||||||
|
|
||||||
.I http://chrony.sunsite.dk/
|
.I http://chrony.tuxfamily.org/
|
||||||
|
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Richard Curnow <rc@rc0.org.uk>
|
Richard Curnow <rc@rc0.org.uk>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.TH chrony.conf 5 "August 10, 2001" chrony "Configuration Files"
|
.TH chrony.conf 5 "December 04, 2009" chrony "Configuration Files"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
chrony.conf \- chronyd configuration file
|
chrony.conf \- chronyd configuration file
|
||||||
|
|
||||||
@@ -37,9 +37,9 @@ useful configuration file would look something like
|
|||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.BR chrony(1),
|
.BR chrony(1),
|
||||||
.BR chronyc(1),
|
.BR chronyc(1),
|
||||||
.BR chronyd(1)
|
.BR chronyd(8)
|
||||||
|
|
||||||
.I http://chrony.sunsite.dk/
|
.I http://chrony.tuxfamily.org/
|
||||||
|
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Richard Curnow <rc@rc0.org.uk>
|
Richard Curnow <rc@rc0.org.uk>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ Description: A pair of programs for keeping computer clocks accurate.
|
|||||||
Keywords: time NTP RFC1305 RTC adjtime
|
Keywords: time NTP RFC1305 RTC adjtime
|
||||||
Author: rc@rc0.org.uk (Richard Curnow)
|
Author: rc@rc0.org.uk (Richard Curnow)
|
||||||
Maintained-by: rc@rc0.org.uk (Richard Curnow)
|
Maintained-by: rc@rc0.org.uk (Richard Curnow)
|
||||||
Primary-site: sunsite.unc.edu /pub/Linux/system/admin/time
|
Primary-site: chrony.tuxfamily.org
|
||||||
295k chrony-1.18.tar.gz
|
295k chrony-1.18.tar.gz
|
||||||
2k chrony.lsm
|
2k chrony.lsm
|
||||||
Platforms: Linux 2.0/2.1/2.2/2.3/2.4 (x86, powerpc)
|
Platforms: Linux 2.0/2.1/2.2/2.3/2.4 (x86, powerpc)
|
||||||
|
|||||||
495
chrony.texi
495
chrony.texi
@@ -109,8 +109,8 @@ the RFC did not make absolutely clear. The core algorithms in
|
|||||||
|
|
||||||
@node Getting the software
|
@node Getting the software
|
||||||
@subsection Getting the software
|
@subsection Getting the software
|
||||||
Links on @uref{http://chrony.sunsite.dk/download.php, the
|
Links on @uref{http://chrony.tuxfamily.org, the chrony home page}
|
||||||
chrony home page} describe how to obtain the software.
|
describe how to obtain the software.
|
||||||
|
|
||||||
|
|
||||||
@node Platforms
|
@node Platforms
|
||||||
@@ -125,8 +125,9 @@ different quirks in its behaviour.
|
|||||||
|
|
||||||
The software is known to work in the following environments:
|
The software is known to work in the following environments:
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item Linux/i386 and Linux/ppc. The software is known to work on Linux 2.0.x,
|
@item Linux on i386, x86_64 and PowerPC architectures. The software is known
|
||||||
2.2.x and 2.4.x. Prior to 2.0.31, the real time clock can't be used.
|
to work on Linux 2.0.x and newer. Prior to 2.0.31, the real time clock can't
|
||||||
|
be used.
|
||||||
|
|
||||||
@item NetBSD
|
@item NetBSD
|
||||||
@item BSD/386
|
@item BSD/386
|
||||||
@@ -203,18 +204,10 @@ integrated into @code{chronyd}.
|
|||||||
Things @code{xntpd} can do that @code{chronyd} can't:
|
Things @code{xntpd} can do that @code{chronyd} can't:
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
|
||||||
@code{xntpd} supports a range of different hardware reference clocks
|
|
||||||
(GPS, atomic etc) that can be connected to a computer to provide a
|
|
||||||
`stratum-1' server. @code{chronyd} does not support any such hardware
|
|
||||||
@emph{yet}; I don't have access to any to do any development work.
|
|
||||||
However, the software architecture should allow such equipment to be
|
|
||||||
interfaced at a later date.
|
|
||||||
|
|
||||||
@item
|
@item
|
||||||
@code{xntpd} supports effectively all of RFC1305, including broadcast /
|
@code{xntpd} supports effectively all of RFC1305, including broadcast /
|
||||||
multicast clients, leap seconds, and extra encryption schemes for
|
multicast clients and extra encryption schemes for authenticating
|
||||||
authenticating data packets.
|
data packets.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
@code{xntpd} has been ported to more types of computer / operating
|
@code{xntpd} has been ported to more types of computer / operating
|
||||||
@@ -276,29 +269,19 @@ version 2, reproduced in @xref{GPL}.
|
|||||||
@node Bug reporting
|
@node Bug reporting
|
||||||
@section Bug reporting and suggestions
|
@section Bug reporting and suggestions
|
||||||
|
|
||||||
If you think you've found a bug in chrony, or have a suggestion, please let me
|
If you think you've found a bug in chrony, or have a suggestion, please let us
|
||||||
know. My primary current email address is @email{rc@@rc0.org.uk}. If that
|
know. You can join chrony users mailing list by sending a message with the
|
||||||
fails, you could try finding me through one of the chrony mailing lists, or by
|
subject subscribe to @email{chrony-users-request@@chrony.tuxfamily.org}. Only
|
||||||
looking up my name on a search engine.
|
subscribers can post to the list.
|
||||||
|
|
||||||
I can't promise a timescale to fix a bug; it depends a lot on the how complex
|
When you are reporting a bug, please send us all the information you can.
|
||||||
the bug is to track down, as I have a lot of other calls on my time : 2 young
|
|
||||||
children, my job, and indeed other free/open source software projects.
|
|
||||||
However, I do intend to look into problems when time allows.
|
|
||||||
|
|
||||||
Another source of information to try is the chrony users mailing list. You can
|
|
||||||
join this by sending an empty message to
|
|
||||||
@email{chrony-users-subscribe@@sunsite.dk}. Only subscribers can post to
|
|
||||||
the list.
|
|
||||||
|
|
||||||
When you are reporting a bug, please send me all the information you can.
|
|
||||||
Unfortunately, chrony has proven to be one of those programs where it is very
|
Unfortunately, chrony has proven to be one of those programs where it is very
|
||||||
difficult to reproduce bugs in a different environment. So I may have to
|
difficult to reproduce bugs in a different environment. So we may have to
|
||||||
interact with you quite a lot to obtain enough extra logging and tracing to
|
interact with you quite a lot to obtain enough extra logging and tracing to
|
||||||
pin-point the problem in some cases. Please be patient and plan for this!
|
pin-point the problem in some cases. Please be patient and plan for this!
|
||||||
|
|
||||||
Of course, if you can debug the problem yourself and send me a source code
|
Of course, if you can debug the problem yourself and send us a source code
|
||||||
patch to fix it, I will be very grateful!
|
patch to fix it, we will be very grateful!
|
||||||
|
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ S:Contributions
|
@c {{{ S:Contributions
|
||||||
@@ -309,7 +292,7 @@ Although chrony is now a fairly mature and established project, there are still
|
|||||||
areas that could be improved. If you can program in C and have some expertise
|
areas that could be improved. If you can program in C and have some expertise
|
||||||
in these areas, you might be able to fill the gaps.
|
in these areas, you might be able to fill the gaps.
|
||||||
|
|
||||||
Particular areas I know need addressing are :
|
Particular areas that need addressing are :
|
||||||
|
|
||||||
@enumerate
|
@enumerate
|
||||||
@item Porting to other Unices
|
@item Porting to other Unices
|
||||||
@@ -331,7 +314,7 @@ setsid() etc with so that chronyd can be automatically started in the system
|
|||||||
bootstrap.
|
bootstrap.
|
||||||
@end enumerate
|
@end enumerate
|
||||||
|
|
||||||
@item Hardware clock support
|
@item More drivers for reference clock support
|
||||||
|
|
||||||
@item Automation of the trimrtc and writertc mechanisms
|
@item Automation of the trimrtc and writertc mechanisms
|
||||||
|
|
||||||
@@ -394,13 +377,16 @@ setenv CFLAGS -O
|
|||||||
for C-family shells.
|
for C-family shells.
|
||||||
|
|
||||||
If the software cannot (yet) be built on your system, an error message
|
If the software cannot (yet) be built on your system, an error message
|
||||||
will be shown. Otherwise, the files @file{options.h} and
|
will be shown. Otherwise, @file{Makefile} will be generated.
|
||||||
@file{Makefile} will be generated.
|
|
||||||
|
|
||||||
By default, chronyc will be built to make use of the readline library. If you
|
If editline or readline library is available, chronyc will be built with line
|
||||||
don't want this, specify the --disable-readline flag to configure. If you have
|
editing support. If you don't want this, specify the --disable-readline flag
|
||||||
readline and/or ncurses installed in a non-standard location, please refer to
|
to configure. Please refer to @pxref{line editing support} for more information.
|
||||||
@pxref{readline support} for information.
|
|
||||||
|
If a @file{timepps.h} header is available, chronyd will be built with PPS API
|
||||||
|
reference clock driver. If the header is installed in a location that isn't
|
||||||
|
normally searched by the compiler, you can add it to the searched locations by
|
||||||
|
setting @code{CPPFLAGS} variable to @code{-I/path/to/timepps}.
|
||||||
|
|
||||||
Now type
|
Now type
|
||||||
|
|
||||||
@@ -438,12 +424,12 @@ to run the @command{install-info} command manually after this step.
|
|||||||
@command{install-info} takes 2 arguments. The first is the path to the
|
@command{install-info} takes 2 arguments. The first is the path to the
|
||||||
@file{chrony.info} file you have just installed. This will be the argument you
|
@file{chrony.info} file you have just installed. This will be the argument you
|
||||||
gave to --prefix when you configured (@file{/usr/local} by default), with
|
gave to --prefix when you configured (@file{/usr/local} by default), with
|
||||||
@file{/info/chrony.info} on the end. The second argument is the location of
|
@file{/share/info/chrony.info} on the end. The second argument is the location of
|
||||||
the file called @file{dir}. This will typically be @file{/usr/info/dir}. So
|
the file called @file{dir}. This will typically be @file{/usr/share/info/dir}. So
|
||||||
the typical command line would be
|
the typical command line would be
|
||||||
|
|
||||||
@example
|
@example
|
||||||
install-info /usr/local/info/chrony.info /usr/info/dir
|
install-info /usr/local/share/info/chrony.info /usr/share/info/dir
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
Now that the software is successfully installed, the next step is to
|
Now that the software is successfully installed, the next step is to
|
||||||
@@ -452,32 +438,43 @@ network environment in which the computer operates. Typical scenarios
|
|||||||
are described in the following section of the document.
|
are described in the following section of the document.
|
||||||
@c }}}
|
@c }}}
|
||||||
@menu
|
@menu
|
||||||
* readline support:: If readline or ncurses in in a non-standard place
|
* line editing support:: If libraries are in a non-standard place
|
||||||
* package builders:: Extra options useful to package builders
|
* package builders:: Extra options useful to package builders
|
||||||
@end menu
|
@end menu
|
||||||
@c {{{ readline support
|
@c {{{ line editing support
|
||||||
@node readline support
|
@node line editing support
|
||||||
@section Support for the readline library
|
@section Support for line editing libraries
|
||||||
By default, chronyc is built to make use of the readline library. This allows
|
Chronyc can be built with support for line editing, this allows you to use the
|
||||||
you to use the cursor keys to replay and edit old commands. If you don't want
|
cursor keys to replay and edit old commands. Two libraries are supported which
|
||||||
to use readline (in which case chronyc will use a minimal command line
|
provide such functionality, editline and GNU readline.
|
||||||
interface), invoke configure like this:
|
|
||||||
|
Please note that readline since version 6.0 is licensed under GPLv3+ which is
|
||||||
|
incompatible with chrony's license GPLv2. You should use editline instead if
|
||||||
|
you don't want to use older readline versions.
|
||||||
|
|
||||||
|
The configure script will automatically enable the line editing support if one
|
||||||
|
of the supported libraries is available. If they are both available, the
|
||||||
|
editline library will be used.
|
||||||
|
|
||||||
|
If you don't want to use it (in which case chronyc will use a minimal command
|
||||||
|
line interface), invoke configure like this:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
./configure --disable-readline other-options...
|
./configure --disable-readline other-options...
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
If you have readline and/or ncurses installed in locations that aren't normally searched by the compiler and linker, you need extra options if you want readline to be used:
|
If you have editline, readline or ncurses installed in locations that aren't
|
||||||
|
normally searched by the compiler and linker, you need to use extra options:
|
||||||
|
|
||||||
@table @samp
|
@table @samp
|
||||||
@item --with-readline-includes=directory_name
|
@item --with-readline-includes=directory_name
|
||||||
This defines the name of the directory above the one where @file{readline.h}
|
This defines the name of the directory above the one where @file{readline.h}
|
||||||
is. @file{readline.h} is assumed to be in a @file{readline} subdirectory of
|
is. @file{readline.h} is assumed to be in @file{editline} or @file{readline}
|
||||||
the named directory.
|
subdirectory of the named directory.
|
||||||
|
|
||||||
@item --with-readline-library=directory_name
|
@item --with-readline-library=directory_name
|
||||||
This defines the directory containing the @file{libreadline.a} or
|
This defines the directory containing the @file{libedit.a} or @file{libedit.so}
|
||||||
@file{libreadline.so} file.
|
file, or @file{libreadline.a} or @file{libreadline.so} file.
|
||||||
|
|
||||||
@item --with-ncurses-library=directory_name
|
@item --with-ncurses-library=directory_name
|
||||||
This defines the directory containing the @file{libncurses.a} or
|
This defines the directory containing the @file{libncurses.a} or
|
||||||
@@ -491,7 +488,7 @@ This defines the directory containing the @file{libncurses.a} or
|
|||||||
The configure and make procedures have some extra options that may be useful if
|
The configure and make procedures have some extra options that may be useful if
|
||||||
you are building a distribution package for chrony.
|
you are building a distribution package for chrony.
|
||||||
|
|
||||||
The --infodir=DIR option to configure specifies a different install directory
|
The --infodir=DIR option to configure specifies an install directory
|
||||||
for the info files. This overrides the @file{info} subdirectory of the
|
for the info files. This overrides the @file{info} subdirectory of the
|
||||||
argument to the --prefix option. For example, you might use
|
argument to the --prefix option. For example, you might use
|
||||||
|
|
||||||
@@ -499,7 +496,7 @@ argument to the --prefix option. For example, you might use
|
|||||||
./configure --prefix=/usr --infodir=/usr/share/info
|
./configure --prefix=/usr --infodir=/usr/share/info
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
The --mandir=DIR option to configure specifies a different install directory
|
The --mandir=DIR option to configure specifies an install directory
|
||||||
for the man pages. This overrides the @file{man} subdirectory of the
|
for the man pages. This overrides the @file{man} subdirectory of the
|
||||||
argument to the --prefix option.
|
argument to the --prefix option.
|
||||||
|
|
||||||
@@ -1088,10 +1085,23 @@ useful for dial-up systems that are shut down when not in use. For this
|
|||||||
to work well, it relies on @code{chronyd} having been able to determine
|
to work well, it relies on @code{chronyd} having been able to determine
|
||||||
accurate statistics for the difference between the real time clock and
|
accurate statistics for the difference between the real time clock and
|
||||||
system clock last time the computer was on.
|
system clock last time the computer was on.
|
||||||
|
@item -u <user>
|
||||||
|
When this option is used, chronyd will drop root privileges to the specified
|
||||||
|
user. So far, it works only on Linux when compiled with capabilities support.
|
||||||
@item -v
|
@item -v
|
||||||
This option displays @code{chronyd's} version number to the terminal and
|
This option displays @code{chronyd's} version number to the terminal and
|
||||||
exits.
|
exits.
|
||||||
|
@item -P <priority>
|
||||||
|
This option will select the SCHED_FIFO real-time scheduler at the
|
||||||
|
specified priority (which must be between 0 and 100). This mode is
|
||||||
|
supported only on Linux.
|
||||||
|
@item -m
|
||||||
|
This option will lock chronyd into RAM so that it will never be paged
|
||||||
|
out. This mode is only supported on Linux.
|
||||||
|
@item -4
|
||||||
|
With this option hostnames will be resolved only to IPv4 addresses.
|
||||||
|
@item -6
|
||||||
|
With this option hostnames will be resolved only to IPv6 addresses.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
On systems that support an @file{/etc/rc.local} file for starting
|
On systems that support an @file{/etc/rc.local} file for starting
|
||||||
@@ -1177,13 +1187,18 @@ directives can occur in any order in the file.
|
|||||||
* manual directive:: Allow manual entry using chronyc's settime cmd.
|
* manual directive:: Allow manual entry using chronyc's settime cmd.
|
||||||
* maxupdateskew directive:: Stop bad estimates upsetting machine clock
|
* maxupdateskew directive:: Stop bad estimates upsetting machine clock
|
||||||
* noclientlog directive:: Prevent chronyd from gathering data about clients
|
* noclientlog directive:: Prevent chronyd from gathering data about clients
|
||||||
|
* clientloglimit directive:: Set client log memory limit
|
||||||
* peer directive:: Specify an NTP peer
|
* peer directive:: Specify an NTP peer
|
||||||
* pidfile directive:: Specify the file where chronyd's pid is written
|
* pidfile directive:: Specify the file where chronyd's pid is written
|
||||||
* port directive:: Set port to use for NTP packets
|
* port directive:: Set port to use for NTP packets
|
||||||
|
* refclock directive:: Specify a reference clock
|
||||||
* rtcdevice directive:: Specify name of enhanced RTC device (if not /dev/rtc)
|
* rtcdevice directive:: Specify name of enhanced RTC device (if not /dev/rtc)
|
||||||
* rtcfile directive:: Specify the file where real-time clock data is stored
|
* rtcfile directive:: Specify the file where real-time clock data is stored
|
||||||
* rtconutc directive:: Specify that the real time clock keeps UTC not local time
|
* rtconutc directive:: Specify that the real time clock keeps UTC not local time
|
||||||
* server directive:: Specify an NTP server
|
* server directive:: Specify an NTP server
|
||||||
|
* sched_priority directive:: Require real-time scheduling and specify a priority for it.
|
||||||
|
* lock_all directive:: Require that chronyd be locked into RAM.
|
||||||
|
|
||||||
@end menu
|
@end menu
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ comments in config file
|
@c {{{ comments in config file
|
||||||
@@ -1241,18 +1256,22 @@ allow 1.2
|
|||||||
allow 3.4.5
|
allow 3.4.5
|
||||||
allow 6.7.8/22
|
allow 6.7.8/22
|
||||||
allow 6.7.8.9/22
|
allow 6.7.8.9/22
|
||||||
|
allow 2001:db8::/32
|
||||||
|
allow 0/0
|
||||||
|
allow ::/0
|
||||||
allow
|
allow
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
The first command allows the named node to be an NTP client of this computer.
|
The first command allows the named node to be an NTP client of this computer.
|
||||||
The second command allows any node with an IP address of the form 1.2.x.y (with
|
The second command allows any node with an IPv4 address of the form 1.2.x.y (with
|
||||||
x and y arbitrary) to be an NTP client of this computer. Likewise, the third
|
x and y arbitrary) to be an NTP client of this computer. Likewise, the third
|
||||||
command allows any node with an IP address of the form 3.4.5.x to have client
|
command allows any node with an IPv4 address of the form 3.4.5.x to have client
|
||||||
NTP access. The fourth and fifth forms allow access from any node with an IP
|
NTP access. The fourth and fifth forms allow access from any node with an IPv4
|
||||||
address of the form 6.7.8.x, 6.7.9.x, 6.7.10.x or 6.7.11.x (with x arbitrary),
|
address of the form 6.7.8.x, 6.7.9.x, 6.7.10.x or 6.7.11.x (with x arbitrary),
|
||||||
i.e. the value 22 is the number of bits defining the specified subnet. (In the
|
i.e. the value 22 is the number of bits defining the specified subnet. (In the
|
||||||
fifth form, the final byte is ignored). The sixth form allows access by any
|
fifth form, the final byte is ignored). The sixth form is used for IPv6
|
||||||
node on the entire Internet.
|
addresses. The seventh and eighth forms allow access by any IPv4 and IPv6 node
|
||||||
|
respectively. The ninth forms allows access by any node (IPv4 or IPv6).
|
||||||
|
|
||||||
A second form of the directive, @code{allow all}, has a greater effect,
|
A second form of the directive, @code{allow all}, has a greater effect,
|
||||||
depending on the ordering of directives in the configuration file. To
|
depending on the ordering of directives in the configuration file. To
|
||||||
@@ -1318,6 +1337,9 @@ firewalls). It is, therefore, not particularly useful. Use of the
|
|||||||
@code{allow} and @code{deny} directives together with a network firewall is
|
@code{allow} and @code{deny} directives together with a network firewall is
|
||||||
more likely to be successful.
|
more likely to be successful.
|
||||||
|
|
||||||
|
For each of IPv4 and IPv6 protocols, only one @code{bindaddress}
|
||||||
|
directive can be specified.
|
||||||
|
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ bindcmdaddress
|
@c {{{ bindcmdaddress
|
||||||
@node bindcmdaddress directive
|
@node bindcmdaddress directive
|
||||||
@@ -1342,6 +1364,9 @@ interfaces. It is, therefore, not particularly useful. Use of the
|
|||||||
@code{cmdallow} and @code{cmddeny} directives together with a network firewall
|
@code{cmdallow} and @code{cmddeny} directives together with a network firewall
|
||||||
is more likely to be successful.
|
is more likely to be successful.
|
||||||
|
|
||||||
|
For each of IPv4 and IPv6 protocols, only one @code{bindcmdaddress}
|
||||||
|
directive can be specified.
|
||||||
|
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ broadcast directive
|
@c {{{ broadcast directive
|
||||||
@node broadcast directive
|
@node broadcast directive
|
||||||
@@ -1356,6 +1381,7 @@ The syntax is as follows
|
|||||||
@example
|
@example
|
||||||
broadcast 30 192.168.1.255
|
broadcast 30 192.168.1.255
|
||||||
broadcast 60 192.168.2.255 12123
|
broadcast 60 192.168.2.255 12123
|
||||||
|
broadcast 60 ff02::101
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
In the first example, the destination port defaults to 123/udp (the normal NTP
|
In the first example, the destination port defaults to 123/udp (the normal NTP
|
||||||
@@ -1525,8 +1551,9 @@ An example of the command is
|
|||||||
dumpdir /var/log/chrony
|
dumpdir /var/log/chrony
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
A source whose IP address is 1.2.3.4 would have its measurement
|
A source whose reference id (the IP address for IPv4 sources) is
|
||||||
history saved in the file @file{/var/log/chrony/1.2.3.4.dat}.
|
1.2.3.4 would have its measurement history saved in the file
|
||||||
|
@file{/var/log/chrony/1.2.3.4.dat}.
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ dumponexit
|
@c {{{ dumponexit
|
||||||
@node dumponexit directive
|
@node dumponexit directive
|
||||||
@@ -1729,6 +1756,10 @@ rate, and any slews made, to a file called tracking.log.
|
|||||||
|
|
||||||
@item rtc
|
@item rtc
|
||||||
This option logs information about the system's real-time clock.
|
This option logs information about the system's real-time clock.
|
||||||
|
|
||||||
|
@item refclocks
|
||||||
|
This option logs the raw reference clock measurements to a file
|
||||||
|
called refclocks.log.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
The files are written to the directory specified by the logdir
|
The files are written to the directory specified by the logdir
|
||||||
@@ -1745,6 +1776,7 @@ log measurements statistics tracking
|
|||||||
* statistics log:: The format of the statistics log
|
* statistics log:: The format of the statistics log
|
||||||
* tracking log:: The format of the tracking log
|
* tracking log:: The format of the tracking log
|
||||||
* RTC log:: The format of the RTC log
|
* RTC log:: The format of the RTC log
|
||||||
|
* refclocks log:: The format of the refclocks log
|
||||||
@end menu
|
@end menu
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ measurements.log
|
@c {{{ measurements.log
|
||||||
@@ -1771,8 +1803,8 @@ expressed in UTC, not the local time zone.
|
|||||||
@item
|
@item
|
||||||
IP address of server/peer from which measurement comes [158.152.1.76]
|
IP address of server/peer from which measurement comes [158.152.1.76]
|
||||||
@item
|
@item
|
||||||
Leap status (@code{N} means normal, @code{-} means that the last minute
|
Leap status (@code{N} means normal, @code{+} means that the last minute
|
||||||
of today has 61 seconds, @code{+} means that the last minute of the day
|
of today has 61 seconds, @code{-} means that the last minute of the day
|
||||||
has 59 seconds, @code{?} means the remote computer is not currently
|
has 59 seconds, @code{?} means the remote computer is not currently
|
||||||
synchronised.) [N]
|
synchronised.) [N]
|
||||||
@item
|
@item
|
||||||
@@ -1958,6 +1990,47 @@ The measurement interval used prior to the measurement being made (in
|
|||||||
seconds). [120]
|
seconds). [120]
|
||||||
@end enumerate
|
@end enumerate
|
||||||
|
|
||||||
|
A banner is periodically written to the log file to indicate the
|
||||||
|
meanings of the columns.
|
||||||
|
@c }}}
|
||||||
|
@c {{{ refclocks.log
|
||||||
|
@node refclocks log
|
||||||
|
@subsubsection Refclocks log file format
|
||||||
|
|
||||||
|
An example line (which actually appears as a single line in the file)
|
||||||
|
from the refclocks log file is shown below.
|
||||||
|
|
||||||
|
@example
|
||||||
|
2009-11-30 14:33:27.000000 PPS2 7 N 1 4.900000e-07 -6.741777e-07
|
||||||
|
@end example
|
||||||
|
|
||||||
|
The columns are as follows (the quantities in square brackets are the
|
||||||
|
values from the example line above) :
|
||||||
|
|
||||||
|
@enumerate 1
|
||||||
|
@item
|
||||||
|
Date [2009-11-30]
|
||||||
|
@item
|
||||||
|
Hour:Minute:Second.Microsecond [14:33:27.000000]. Note that the
|
||||||
|
date/time pair is expressed in UTC, not the local time zone.
|
||||||
|
@item
|
||||||
|
Reference ID of refclock from which measurement comes. [PPS2]
|
||||||
|
@item
|
||||||
|
Sequence number of driver poll within one polling interval. [7]
|
||||||
|
@item
|
||||||
|
Leap status (@code{N} means normal, @code{+} means that the last minute
|
||||||
|
of today has 61 seconds, @code{-} means that the last minute of the day
|
||||||
|
has 59 seconds). [N]
|
||||||
|
@item
|
||||||
|
Flag indicating whether the sample comes from PPS source. (1 for yes,
|
||||||
|
0 for no). [1]
|
||||||
|
@item
|
||||||
|
Local clock error measured by refclock driver. [4.900000e-07]
|
||||||
|
@item
|
||||||
|
Local clock error with applied corrections. Positive indicates
|
||||||
|
that the local clock is slow. [-6.741777e-07]
|
||||||
|
@end enumerate
|
||||||
|
|
||||||
A banner is periodically written to the log file to indicate the
|
A banner is periodically written to the log file to indicate the
|
||||||
meanings of the columns.
|
meanings of the columns.
|
||||||
@c }}}
|
@c }}}
|
||||||
@@ -2066,6 +2139,21 @@ This directive, which takes no arguments, specifies that client accesses
|
|||||||
are not to be logged. Normally they are logged, allowing statistics to
|
are not to be logged. Normally they are logged, allowing statistics to
|
||||||
be reported using the @code{clients} command in @code{chronyc}.
|
be reported using the @code{clients} command in @code{chronyc}.
|
||||||
@c }}}
|
@c }}}
|
||||||
|
@c {{{ clientloglimit
|
||||||
|
@node clientloglimit directive
|
||||||
|
@subsection clientloglimit
|
||||||
|
This directive specifies the maximum size of the memory allocated to
|
||||||
|
log client accesses. When the limit is reached, only information for
|
||||||
|
clients that have already been logged will be updated. If 0 is
|
||||||
|
specified, the memory size will be unlimited. The default is 524288
|
||||||
|
bytes.
|
||||||
|
|
||||||
|
An example of the use of this directive is
|
||||||
|
|
||||||
|
@example
|
||||||
|
clientloglimit 1048576
|
||||||
|
@end example
|
||||||
|
@c }}}
|
||||||
@c {{{ peer
|
@c {{{ peer
|
||||||
@node peer directive
|
@node peer directive
|
||||||
@subsection peer
|
@subsection peer
|
||||||
@@ -2101,6 +2189,91 @@ port 11123
|
|||||||
|
|
||||||
This would change the NTP port served by chronyd on the computer to
|
This would change the NTP port served by chronyd on the computer to
|
||||||
udp/11123.
|
udp/11123.
|
||||||
|
@c }}}
|
||||||
|
@c {{{ refclock
|
||||||
|
@node refclock directive
|
||||||
|
@subsection refclock
|
||||||
|
The @code{refclock} directive allows reference clocks to be specified.
|
||||||
|
The directive is immediately followed by a refclock driver name and
|
||||||
|
its parameter.
|
||||||
|
|
||||||
|
There are currently three drivers implemented:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item PPS
|
||||||
|
Pulse per second (PPS) API driver. The parameter is a path to the PPS
|
||||||
|
device. Assert events are used by default. The path can have
|
||||||
|
:1 appended to use clear events instead.
|
||||||
|
|
||||||
|
PPS refclock needs another source (NTP or non-PPS refclock) or local
|
||||||
|
directive (@pxref{local directive}) enabled to function. For example:
|
||||||
|
|
||||||
|
@example
|
||||||
|
refclock SHM 0 offset 0.5 delay 0.1
|
||||||
|
refclock PPS /dev/pps0
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@item SHM
|
||||||
|
NTP shared memory driver. The parameter is the number of the
|
||||||
|
shared memory segment that should be used to read timestamps, usually
|
||||||
|
0, 1, 2 or 3. For example:
|
||||||
|
|
||||||
|
@example
|
||||||
|
refclock SHM 1 poll 3 refid GPS1
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Software that can be used as a source of timestamps includes
|
||||||
|
@code{gpsd} and @code{shmpps}.
|
||||||
|
@item SOCK
|
||||||
|
Unix domain socket driver. The parameter is a path to the socket
|
||||||
|
which is used as the source of timestamps. This is as a better
|
||||||
|
alternative to SHM, it does not require polling, the offset
|
||||||
|
resolution is not limited to microsecond and it supports PPS.
|
||||||
|
The format for messages sent over the socket is declared in file
|
||||||
|
@code{refclock_sock.c}.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
The @code{refclock} command also supports a number of subfields (which
|
||||||
|
may be defined in any order):
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item poll
|
||||||
|
Timestamps produced by refclock drivers are not used immediately, but
|
||||||
|
they are stored and processed by a median filter in intervals
|
||||||
|
specified by this option. This is defined as a power of 2. The
|
||||||
|
default is 4 (16 seconds). A shorter interval allows @code{chronyd}
|
||||||
|
to react faster to frequency changes, but it may increase noise.
|
||||||
|
@item dpoll
|
||||||
|
Some drivers are not controlled by external events and thus require
|
||||||
|
polling. Again this is defined as a power of 2 and can be negative
|
||||||
|
for sub-second intervals. The default is 0 (1 second).
|
||||||
|
@item refid
|
||||||
|
This option is used to specify a reference id of the refclock, as up
|
||||||
|
to four ASCII characters. By default, first three characters from
|
||||||
|
driver name and the number of the refclock are used as refid. Each
|
||||||
|
refclock has to use an unique refid.
|
||||||
|
@item filter
|
||||||
|
This option sets the length of the median filter which is used to
|
||||||
|
reduce noise. With each poll about half of the stored samples are
|
||||||
|
discarded and one final sample is calculated as average of the
|
||||||
|
remaining samples. The default is 15.
|
||||||
|
@item rate
|
||||||
|
PPS signal frequency (in Hz). This option only controls how the
|
||||||
|
received pulses are aligned. To actually receive more than one
|
||||||
|
pulse per second, a negative @code{dpoll} has to be specified (-3 for
|
||||||
|
5Hz signal). The default is 1.
|
||||||
|
@item offset
|
||||||
|
This option can be used to compensate a constant error. The specified
|
||||||
|
offset (in seconds) is applied to all samples produced by the
|
||||||
|
refclock. The default is 0.0.
|
||||||
|
@item delay
|
||||||
|
This option is used to specify how the refclock is assumed
|
||||||
|
to be inaccurate (in seconds). Increasing the value is useful to
|
||||||
|
avoid having no majority in the source selection algorithm or to make
|
||||||
|
the algorithm prefer other refclocks. The default is 1e-9 (1
|
||||||
|
nanosecond).
|
||||||
|
@end table
|
||||||
|
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ rtcdevice
|
@c {{{ rtcdevice
|
||||||
@node rtcdevice directive
|
@node rtcdevice directive
|
||||||
@@ -2174,6 +2347,37 @@ If the @code{rtconutc} directive appears, it means the RTC is required
|
|||||||
to keep UTC. The directive takes no arguments. It is equivalent to
|
to keep UTC. The directive takes no arguments. It is equivalent to
|
||||||
specifying the @code{-u} switch to the Linux @file{/sbin/clock} program.
|
specifying the @code{-u} switch to the Linux @file{/sbin/clock} program.
|
||||||
@c }}}
|
@c }}}
|
||||||
|
@c {{{ sched_priority
|
||||||
|
@node sched_priority directive
|
||||||
|
@subsection sched_priority
|
||||||
|
|
||||||
|
The @code{sched_priority} directive will select the SCHED_FIFO real-time
|
||||||
|
scheduler at the specified priority (which must be between 0 and 100).
|
||||||
|
This mode is supported only on Linux.
|
||||||
|
|
||||||
|
This directive uses the Linux sched_setscheduler() system call to
|
||||||
|
instruct the kernel to use the SCHED_FIFO first-in, first-out
|
||||||
|
real-time scheduling policy for Chronyd with the specified priority.
|
||||||
|
This means that whenever Chronyd is ready to run it will run,
|
||||||
|
interrupting whatever else is running unless it is a higher priority
|
||||||
|
real-time process. This should not impact performance as Chronyd's
|
||||||
|
resource requirements are modest, but it should result in lower and
|
||||||
|
more consistent latency since Chronyd will not need to wait for the
|
||||||
|
scheduler to get around to running it. You should not use this unless
|
||||||
|
you really need it. The sched_setscheduler man page has more details.
|
||||||
|
@c }}}
|
||||||
|
@c {{{ lock_all
|
||||||
|
@node lock_all directive
|
||||||
|
@subsection lock_all
|
||||||
|
|
||||||
|
The @code{lock_all} directive will lock chronyd into RAM so that it
|
||||||
|
will never be paged out. This mode is only supported on Linux. This
|
||||||
|
directive uses the Linux mlockall() system call to prevent Chronyd
|
||||||
|
from ever being swapped out. This should result in lower and more
|
||||||
|
consistent latency. It should not have significant impact on
|
||||||
|
performance as Chronyd's memory usage is modest. The mlockall man
|
||||||
|
page has more details.
|
||||||
|
@c }}}
|
||||||
@c {{{ server
|
@c {{{ server
|
||||||
@node server directive
|
@node server directive
|
||||||
@subsection server
|
@subsection server
|
||||||
@@ -2183,9 +2387,8 @@ synchronise its system time to that of the server, but the server's
|
|||||||
system time will never be influenced by that of a client.
|
system time will never be influenced by that of a client.
|
||||||
|
|
||||||
The @code{server} directive is immediately followed by either the name
|
The @code{server} directive is immediately followed by either the name
|
||||||
of the server, or its IP address in dotted-quad notation. The server
|
of the server, or its IP address. The server command also supports a
|
||||||
command also supports a number of subfields (which may be defined in any
|
number of subfields (which may be defined in any order):
|
||||||
order):
|
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
@item port
|
@item port
|
||||||
@@ -2341,6 +2544,12 @@ This option allows the user to specify the UDP port number which the
|
|||||||
target @code{chronyd} is using for its command & monitoring connections.
|
target @code{chronyd} is using for its command & monitoring connections.
|
||||||
This defaults to the compiled-in default; there would rarely be a need
|
This defaults to the compiled-in default; there would rarely be a need
|
||||||
to change this.
|
to change this.
|
||||||
|
@item -n
|
||||||
|
This option disables resolving IP addresses to hostnames.
|
||||||
|
@item -4
|
||||||
|
With this option hostnames will be resolved only to IPv4 addresses.
|
||||||
|
@item -6
|
||||||
|
With this option hostnames will be resolved only to IPv6 addresses.
|
||||||
@end table
|
@end table
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ SS:Security with chronyc
|
@c {{{ SS:Security with chronyc
|
||||||
@@ -2377,6 +2586,7 @@ Only the following commands can be used @emph{without} providing a
|
|||||||
password:
|
password:
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
|
@item @code{dns}
|
||||||
@item @code{exit}
|
@item @code{exit}
|
||||||
@item @code{help}
|
@item @code{help}
|
||||||
@item @code{password}
|
@item @code{password}
|
||||||
@@ -2416,6 +2626,7 @@ interface.
|
|||||||
* delete command:: Remove an NTP server or peer
|
* delete command:: Remove an NTP server or peer
|
||||||
* deny command :: Denying NTP client access
|
* deny command :: Denying NTP client access
|
||||||
* deny all command:: Denying NTP client access
|
* deny all command:: Denying NTP client access
|
||||||
|
* dns command:: Configure how are hostnames and IP addresses resolved
|
||||||
* dump command:: Dump measurement histories to files
|
* dump command:: Dump measurement histories to files
|
||||||
* exit command:: Exit from chronyc
|
* exit command:: Exit from chronyc
|
||||||
* help command:: Generate help summary
|
* help command:: Generate help summary
|
||||||
@@ -2452,6 +2663,7 @@ follows:
|
|||||||
@example
|
@example
|
||||||
accheck a.b.c
|
accheck a.b.c
|
||||||
accheck 1.2.3.4
|
accheck 1.2.3.4
|
||||||
|
accheck 2001:db8::1
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
This command can be used to examine the effect of a series of
|
This command can be used to examine the effect of a series of
|
||||||
@@ -2526,6 +2738,9 @@ allow 1.2
|
|||||||
allow 3.4.5
|
allow 3.4.5
|
||||||
allow 6.7.8/22
|
allow 6.7.8/22
|
||||||
allow 6.7.8.9/22
|
allow 6.7.8.9/22
|
||||||
|
allow 2001:db8:789a::/48
|
||||||
|
allow 0/0
|
||||||
|
allow ::/0
|
||||||
allow
|
allow
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@@ -2542,7 +2757,7 @@ directive in the configuration file (@pxref{allow directive}).
|
|||||||
@node burst command
|
@node burst command
|
||||||
@subsubsection burst
|
@subsubsection burst
|
||||||
The @code{burst} command tells @code{chronyd} to make a set of measurements to
|
The @code{burst} command tells @code{chronyd} to make a set of measurements to
|
||||||
each of its sources over a short duration (rather than the usual
|
each of its NTP sources over a short duration (rather than the usual
|
||||||
periodic measurements that it makes). After such a burst, @code{chronyd} will
|
periodic measurements that it makes). After such a burst, @code{chronyd} will
|
||||||
revert to the previous state for each source. This might be either
|
revert to the previous state for each source. This might be either
|
||||||
online, if the source was being periodically measured in the normal way,
|
online, if the source was being periodically measured in the normal way,
|
||||||
@@ -2554,6 +2769,7 @@ The syntax of the burst command is as follows
|
|||||||
|
|
||||||
@example
|
@example
|
||||||
burst <n-good-measurements>/<max-measurements> [<mask>/<masked-address>]
|
burst <n-good-measurements>/<max-measurements> [<mask>/<masked-address>]
|
||||||
|
burst <n-good-measurements>/<max-measurements> [<masked-address>/<masked-bits>]
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
The mask and masked-address arguments are optional, in which case
|
The mask and masked-address arguments are optional, in which case
|
||||||
@@ -2575,18 +2791,21 @@ attempt to make, even if the required number of good measurements has
|
|||||||
not been obtained.
|
not been obtained.
|
||||||
|
|
||||||
@item mask
|
@item mask
|
||||||
This is a dotted quad argument (e.g. @code{255.255.255.0}) with which
|
This is an IP address with which the IP address of each of @code{chronyd}'s
|
||||||
the IP address of each of @code{chronyd}'s sources is to be masked.
|
sources is to be masked.
|
||||||
|
|
||||||
@item masked-address
|
@item masked-address
|
||||||
This is a dotted quad argument (e.g. @code{1.2.3.0}). If the masked IP
|
This is an IP address. If the masked IP address of a source matches this value
|
||||||
address of a source matches this value then the burst command is applied
|
then the burst command is applied to that source.
|
||||||
to that source.
|
|
||||||
|
@item masked-bits
|
||||||
|
This can be used with @code{masked-address} for CIDR notation, which is a
|
||||||
|
shorter alternative to the form with mask.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
If no mask or masked address arguments are provided, the default is
|
If no mask or masked address arguments are provided, every source will
|
||||||
@code{0.0.0.0} and @code{0.0.0.0} respectively, which will match every
|
be matched.
|
||||||
source.
|
|
||||||
|
|
||||||
An example of the two-argument form of the command is
|
An example of the two-argument form of the command is
|
||||||
|
|
||||||
@@ -2598,15 +2817,17 @@ This will cause @code{chronyd} to attempt to get two good measurements from
|
|||||||
each source, stopping after two have been obtained, but in no event will
|
each source, stopping after two have been obtained, but in no event will
|
||||||
it try more than ten probes to the source.
|
it try more than ten probes to the source.
|
||||||
|
|
||||||
An example of the four-argument form of the command is
|
Examples of the four-argument form of the command are
|
||||||
|
|
||||||
@example
|
@example
|
||||||
burst 2/10 255.255.0.0/1.2.0.0
|
burst 2/10 255.255.0.0/1.2.0.0
|
||||||
|
burst 2/10 2001:db8:789a::/48
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
In this case, the two out of ten sampling will only be applied to
|
In the first case, the two out of ten sampling will only be applied to
|
||||||
sources whose IP addresses are of the form @code{1.2.x.y}, where x and y
|
sources whose IPv4 addresses are of the form @code{1.2.x.y}, where x and y
|
||||||
are arbitrary.
|
are arbitrary. In the second case, the sampling will be applied to sources
|
||||||
|
whose IPv6 addresses have first 48 bits equal to @code{2001:db8:789a}.
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ clients
|
@c {{{ clients
|
||||||
@node clients command
|
@node clients command
|
||||||
@@ -2671,6 +2892,7 @@ Examples of use are as follows:
|
|||||||
@example
|
@example
|
||||||
cmdaccheck a.b.c
|
cmdaccheck a.b.c
|
||||||
cmdaccheck 1.2.3.4
|
cmdaccheck 1.2.3.4
|
||||||
|
cmdaccheck 2001:db8::1
|
||||||
@end example
|
@end example
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ cmdallow
|
@c {{{ cmdallow
|
||||||
@@ -2733,6 +2955,7 @@ The syntax is illustrated in the examples below.
|
|||||||
@example
|
@example
|
||||||
delete foo.bar.com
|
delete foo.bar.com
|
||||||
delete 1.2.3.4
|
delete 1.2.3.4
|
||||||
|
delete 2001:db8::1
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
There is one parameter, the name or IP address of the server or peer to
|
There is one parameter, the name or IP address of the server or peer to
|
||||||
@@ -2752,6 +2975,9 @@ deny 1.2
|
|||||||
deny 3.4.5
|
deny 3.4.5
|
||||||
deny 6.7.8/22
|
deny 6.7.8/22
|
||||||
deny 6.7.8.9/22
|
deny 6.7.8.9/22
|
||||||
|
deny 2001:db8:789a::/48
|
||||||
|
deny 0/0
|
||||||
|
deny ::/0
|
||||||
deny
|
deny
|
||||||
@end example
|
@end example
|
||||||
@c }}}
|
@c }}}
|
||||||
@@ -2761,6 +2987,32 @@ deny
|
|||||||
The effect of the allow command is identical to the @code{deny all}
|
The effect of the allow command is identical to the @code{deny all}
|
||||||
directive in the configuration file (@pxref{deny directive}).
|
directive in the configuration file (@pxref{deny directive}).
|
||||||
@c }}}
|
@c }}}
|
||||||
|
@c {{{ dns
|
||||||
|
@node dns command
|
||||||
|
@subsubsection dns
|
||||||
|
The @code{dns} command configures how are hostnames and IP addresses resolved in
|
||||||
|
@code{chronyc}. IP addresses can be resolved to hostnames when printing results
|
||||||
|
of @code{sources}, @code{sourcestats}, @code{tracking} and @code{clients}
|
||||||
|
commands. Hostnames are resolved in commands that take an address as argument.
|
||||||
|
|
||||||
|
There are five forms of the command:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item dns -n
|
||||||
|
Disables resolving IP addresses to hostnames. Raw IP addresses will be
|
||||||
|
displayed.
|
||||||
|
@item dns +n
|
||||||
|
Enables resolving IP addresses to hostnames. This is the default unless
|
||||||
|
@code{chronyc} was started with @code{-n} option.
|
||||||
|
@item dns -4
|
||||||
|
Resolves hostnames only to IPv4 addresses.
|
||||||
|
@item dns -6
|
||||||
|
Resolves hostnames only to IPv6 addresses.
|
||||||
|
@item dns -46
|
||||||
|
Resolves hostnames to both address families. This is the default unless
|
||||||
|
@code{chronyc} was started with @code{-4} or @code{-6} option.
|
||||||
|
@end table
|
||||||
|
@c }}}
|
||||||
@c {{{ dump
|
@c {{{ dump
|
||||||
@node dump command
|
@node dump command
|
||||||
@subsubsection dump
|
@subsubsection dump
|
||||||
@@ -2904,12 +3156,14 @@ The following examples illustrate the syntax
|
|||||||
@example
|
@example
|
||||||
maxdelay foo.bar.com 0.3
|
maxdelay foo.bar.com 0.3
|
||||||
maxdelay 1.2.3.4 0.0015
|
maxdelay 1.2.3.4 0.0015
|
||||||
|
maxdelay 2001:db8::1 0.0015
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
The first example sets the maximum network delay allowed for a
|
The first example sets the maximum network delay allowed for a
|
||||||
measurement to the host @code{foo.bar.com} to 0.3 seconds. The second
|
measurement to the host @code{foo.bar.com} to 0.3 seconds. The second
|
||||||
example sets the maximum network delay for a measurement to the host
|
and third examples set the maximum network delay for a measurement to
|
||||||
with IP address @code{1.2.3.4} to 1.5 milliseconds.
|
the host with IPv4 address @code{1.2.3.4} and the host with IPv6 address
|
||||||
|
@code{2001:db8::1} to 1.5 milliseconds.
|
||||||
|
|
||||||
(Any measurement whose network delay exceeds the specified value is
|
(Any measurement whose network delay exceeds the specified value is
|
||||||
discarded.)
|
discarded.)
|
||||||
@@ -2927,13 +3181,15 @@ The following examples illustrate the syntax
|
|||||||
@example
|
@example
|
||||||
maxdelayratio foo.bar.com 1.5
|
maxdelayratio foo.bar.com 1.5
|
||||||
maxdelayratio 1.2.3.4 2.0
|
maxdelayratio 1.2.3.4 2.0
|
||||||
|
maxdelayratio 2001:db8::1 2.0
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
The first example sets the maximum network delay for a measurement to
|
The first example sets the maximum network delay for a measurement to
|
||||||
the host @code{foo.bar.com} to be 1.5 times the minimum delay found
|
the host @code{foo.bar.com} to be 1.5 times the minimum delay found
|
||||||
amongst the previous measurements that have been retained. The second
|
amongst the previous measurements that have been retained. The second
|
||||||
example sets the maximum network delay for a measurement to the host
|
and third examples set the maximum network delay for a measurement to
|
||||||
with IP address @code{1.2.3.4} to be double the retained minimum.
|
the host with IPv4 address @code{1.2.3.4} and the host with IPv6
|
||||||
|
address @code{2001:db8::1} to be double the retained minimum.
|
||||||
|
|
||||||
As for @code{maxdelay}, any measurement whose network delay is too large
|
As for @code{maxdelay}, any measurement whose network delay is too large
|
||||||
will be discarded.
|
will be discarded.
|
||||||
@@ -2952,7 +3208,7 @@ The syntax is as follows
|
|||||||
maxpoll <host> <new-maxpoll>
|
maxpoll <host> <new-maxpoll>
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
where the host can be specified as either a machine name or dotted-quad
|
where the host can be specified as either a machine name or
|
||||||
IP address. The new minimum poll is specified as a base-2 logarithm of
|
IP address. The new minimum poll is specified as a base-2 logarithm of
|
||||||
the number of seconds between polls (e.g. specify 6 for 64 second
|
the number of seconds between polls (e.g. specify 6 for 64 second
|
||||||
sampling).
|
sampling).
|
||||||
@@ -2989,7 +3245,7 @@ The syntax is as follows
|
|||||||
minpoll <host> <new-minpoll>
|
minpoll <host> <new-minpoll>
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
where the host can be specified as either a machine name or dotted-quad
|
where the host can be specified as either a machine name or
|
||||||
IP address. The new minimum poll is specified as a base-2 logarithm of
|
IP address. The new minimum poll is specified as a base-2 logarithm of
|
||||||
the number of seconds between polls (e.g. specify 6 for 64 second
|
the number of seconds between polls (e.g. specify 6 for 64 second
|
||||||
sampling).
|
sampling).
|
||||||
@@ -3056,24 +3312,29 @@ the @code{offline} command being used, @code{chronyd} would assume that the
|
|||||||
source had failed and would attempt to pick another synchronisation
|
source had failed and would attempt to pick another synchronisation
|
||||||
source.
|
source.
|
||||||
|
|
||||||
There are two forms of the @code{offline} command. The first form is a
|
There are three forms of the @code{offline} command. The first form is a
|
||||||
wildcard, meaning all sources. The second form allows a IP address mask
|
wildcard, meaning all sources. The second form allows a IP address mask
|
||||||
and a masked address to be specified. These forms are illustrated below.
|
and a masked address to be specified. The third form uses the CIDR
|
||||||
|
notation. These forms are illustrated below.
|
||||||
|
|
||||||
@example
|
@example
|
||||||
offline
|
offline
|
||||||
offline 255.255.255.0/1.2.3.0
|
offline 255.255.255.0/1.2.3.0
|
||||||
|
offline 2001:db8:789a::/48
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
The second form means that the @code{offline} command is to be applied
|
The second form means that the @code{offline} command is to be applied
|
||||||
to any source whose IP address is in the 1.2.3 subnet. (The host's
|
to any source whose IPv4 address is in the @code{1.2.3} subnet. (The host's
|
||||||
address is logically and-ed with the mask, and if the result matches the
|
address is logically and-ed with the mask, and if the result matches the
|
||||||
masked-address the host is processed).
|
masked-address the host is processed). The third form means that the
|
||||||
|
command is to be applied to all sources whose IPv6 addresses have first
|
||||||
|
48 bits equal to @code{2001:db8:789a}.
|
||||||
|
|
||||||
The wildcard form of the address is actually equivalent to
|
The wildcard form of the address is actually equivalent to
|
||||||
|
|
||||||
@example
|
@example
|
||||||
offline 0.0.0.0/0.0.0.0
|
offline 0.0.0.0/0.0.0.0
|
||||||
|
offline ::/0
|
||||||
@end example
|
@end example
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ online
|
@c {{{ online
|
||||||
@@ -3240,8 +3501,7 @@ The columns are as follows:
|
|||||||
@item M
|
@item M
|
||||||
This indicates the mode of the source. @code{^} means a server,
|
This indicates the mode of the source. @code{^} means a server,
|
||||||
@code{=} means a peer and @code{#} indicates a locally connected
|
@code{=} means a peer and @code{#} indicates a locally connected
|
||||||
reference clock@footnote{In the current version this will never be
|
reference clock.
|
||||||
shown, because @code{chronyd} has no support for reference clocks yet.}.
|
|
||||||
|
|
||||||
@item S
|
@item S
|
||||||
This column indicates the state of the sources. @code{*} indicates the
|
This column indicates the state of the sources. @code{*} indicates the
|
||||||
@@ -3254,7 +3514,8 @@ appears to have too much variability. The @code{~} condition is also
|
|||||||
shown at start-up, until at least 3 samples have been gathered from it.
|
shown at start-up, until at least 3 samples have been gathered from it.
|
||||||
|
|
||||||
@item Name/IP address
|
@item Name/IP address
|
||||||
This shows the name or the IP address of the source.
|
This shows the name or the IP address of the source, or refid for
|
||||||
|
reference clocks.
|
||||||
|
|
||||||
@item Stratum
|
@item Stratum
|
||||||
This shows the stratum of the source, as reported in its most recently
|
This shows the stratum of the source, as reported in its most recently
|
||||||
@@ -3279,7 +3540,8 @@ source. This is normally in seconds. The letters @code{m}, @code{h},
|
|||||||
@item Last sample
|
@item Last sample
|
||||||
This column shows the offset between the local clock and the source at
|
This column shows the offset between the local clock and the source at
|
||||||
the last measurement. The number in the square brackets shows the
|
the last measurement. The number in the square brackets shows the
|
||||||
actual measured offset. This may be suffixed by @code{us} (indicating
|
actual measured offset. This may be suffixed by @code{ns} (indicating
|
||||||
|
nanoseconds), @code{us} (indicating
|
||||||
microseconds), @code{ms} (indicating milliseconds), or @code{s}
|
microseconds), @code{ms} (indicating milliseconds), or @code{s}
|
||||||
(indicating seconds). The number to the left of the square brackets
|
(indicating seconds). The number to the left of the square brackets
|
||||||
shows the original measurement, adjusted to allow for any slews applied
|
shows the original measurement, adjusted to allow for any slews applied
|
||||||
@@ -3307,9 +3569,9 @@ An example report is
|
|||||||
@example
|
@example
|
||||||
@group
|
@group
|
||||||
210 Number of sources = 1
|
210 Number of sources = 1
|
||||||
Name/IP Address NP NR Span Frequency Freq Skew Std Dev
|
Name/IP Address NP NR Span Frequency Freq Skew Offset Std Dev
|
||||||
========================================================================
|
===============================================================================
|
||||||
abc.def.ghi 11 5 46m -0.001 0.045 25us
|
abc.def.ghi 11 5 46m -0.001 0.045 1us 25us
|
||||||
@end group
|
@end group
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@@ -3317,8 +3579,8 @@ The columns are as follows
|
|||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
@item Name/IP Address
|
@item Name/IP Address
|
||||||
This is the name or dotted-quad IP address of the NTP server (or peer)
|
This is the name or IP address of the NTP server (or peer) or refid of
|
||||||
to which the rest of the line relates.
|
the refclock to which the rest of the line relates.
|
||||||
|
|
||||||
@item NP
|
@item NP
|
||||||
This is the number of sample points currently being retained for the
|
This is the number of sample points currently being retained for the
|
||||||
@@ -3347,6 +3609,9 @@ million. In this case, the computer's clock is estimated to be running
|
|||||||
This is the estimated error bounds on @code{Freq} (again in parts per
|
This is the estimated error bounds on @code{Freq} (again in parts per
|
||||||
million).
|
million).
|
||||||
|
|
||||||
|
@item Offset
|
||||||
|
This is the estimated offset of the source.
|
||||||
|
|
||||||
@item Std Dev
|
@item Std Dev
|
||||||
This is the estimated sample standard deviation.
|
This is the estimated sample standard deviation.
|
||||||
|
|
||||||
@@ -3362,7 +3627,7 @@ performance. An example of the output is shown below.
|
|||||||
Reference ID : 1.2.3.4 (a.b.c)
|
Reference ID : 1.2.3.4 (a.b.c)
|
||||||
Stratum : 3
|
Stratum : 3
|
||||||
Ref time (UTC) : Sun May 17 06:13:11 1998
|
Ref time (UTC) : Sun May 17 06:13:11 1998
|
||||||
System time : 0.000000 seconds fast of NTP time
|
System time : 0.000000000 seconds fast of NTP time
|
||||||
Frequency : 331.898 ppm fast
|
Frequency : 331.898 ppm fast
|
||||||
Residual freq : 0.004 ppm
|
Residual freq : 0.004 ppm
|
||||||
Skew : 0.154 ppm
|
Skew : 0.154 ppm
|
||||||
@@ -3374,7 +3639,7 @@ The fields are explained as follows.
|
|||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
@item Reference ID
|
@item Reference ID
|
||||||
This is the IP address, and name if available, of the server to which
|
This is the refid and name (or IP address) if available, of the server to which
|
||||||
the computer is currently synchronised. If this is @code{127.127.1.1}
|
the computer is currently synchronised. If this is @code{127.127.1.1}
|
||||||
it means the computer is not synchronised to any external source and
|
it means the computer is not synchronised to any external source and
|
||||||
that you have the `local' mode operating (via the @code{local} command
|
that you have the `local' mode operating (via the @code{local} command
|
||||||
@@ -3640,8 +3905,8 @@ the system clock is periodically reset to the real-time clock.
|
|||||||
@center GNU GENERAL PUBLIC LICENSE
|
@center GNU GENERAL PUBLIC LICENSE
|
||||||
@center Version 2, June 1991
|
@center Version 2, June 1991
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
@@ -3654,7 +3919,7 @@ software--to make sure the software is free for all its users. This
|
|||||||
General Public License applies to most of the Free Software
|
General Public License applies to most of the Free Software
|
||||||
Foundation's software and to any other program whose authors commit to
|
Foundation's software and to any other program whose authors commit to
|
||||||
using it. (Some other Free Software Foundation software is covered by
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
the GNU Library General Public License instead.) You can apply it to
|
the GNU Lesser General Public License instead.) You can apply it to
|
||||||
your programs, too.
|
your programs, too.
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
When we speak of free software, we are referring to freedom, not
|
||||||
@@ -3918,7 +4183,7 @@ POSSIBILITY OF SUCH DAMAGES.
|
|||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
Appendix: How to Apply These Terms to Your New Programs
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
If you develop a new program, and you want it to be of the greatest
|
||||||
possible use to the public, the best way to achieve this is to make it
|
possible use to the public, the best way to achieve this is to make it
|
||||||
@@ -3930,7 +4195,7 @@ convey the exclusion of warranty; and each file should have at least
|
|||||||
the "copyright" line and a pointer to where the full notice is found.
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
Copyright (C) 19yy <name of author>
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -3942,16 +4207,16 @@ the "copyright" line and a pointer to where the full notice is found.
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License along
|
||||||
along with this program; if not, write to the Free Software
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
If the program is interactive, make it output a short notice like this
|
If the program is interactive, make it output a short notice like this
|
||||||
when it starts in an interactive mode:
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
This is free software, and you are welcome to redistribute it
|
This is free software, and you are welcome to redistribute it
|
||||||
under certain conditions; type `show c' for details.
|
under certain conditions; type `show c' for details.
|
||||||
@@ -3974,7 +4239,7 @@ necessary. Here is a sample; alter the names:
|
|||||||
This General Public License does not permit incorporating your program into
|
This General Public License does not permit incorporating your program into
|
||||||
proprietary programs. If your program is a subroutine library, you may
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
consider it more useful to permit linking proprietary applications with the
|
consider it more useful to permit linking proprietary applications with the
|
||||||
library. If this is what you want to do, use the GNU Library General
|
library. If this is what you want to do, use the GNU Lesser General
|
||||||
Public License instead of this License.
|
Public License instead of this License.
|
||||||
@c }}}
|
@c }}}
|
||||||
@contents
|
@contents
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ struct timex {
|
|||||||
#define ADJ_STATUS 0x0010 /* clock status */
|
#define ADJ_STATUS 0x0010 /* clock status */
|
||||||
#define ADJ_TICK 0x4000 /* tick value */
|
#define ADJ_TICK 0x4000 /* tick value */
|
||||||
#define ADJ_OFFSET_SINGLESHOT 0x8001 /* old-fashioned adjtime */
|
#define ADJ_OFFSET_SINGLESHOT 0x8001 /* old-fashioned adjtime */
|
||||||
|
#define ADJ_OFFSET_SS_READ 0xa001 /* read-only adjtime */
|
||||||
|
|
||||||
#define SHIFT_USEC 16 /* frequency offset scale (shift) */
|
#define SHIFT_USEC 16 /* frequency offset scale (shift) */
|
||||||
|
|
||||||
|
|||||||
17
chronyc.1
17
chronyc.1
@@ -1,4 +1,4 @@
|
|||||||
.TH CHRONYC 1 "August 10, 2001" chrony "User's Manual"
|
.TH CHRONYC 1 "December 04, 2009" chrony "User's Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
chronyc \- command-line interface for chronyd
|
chronyc \- command-line interface for chronyd
|
||||||
|
|
||||||
@@ -31,22 +31,29 @@ specify port-number
|
|||||||
.TP
|
.TP
|
||||||
\fB\-n\fR
|
\fB\-n\fR
|
||||||
display raw IP addresses (don't attempt to look up hostnames)
|
display raw IP addresses (don't attempt to look up hostnames)
|
||||||
.TP \fIcommand\fR
|
.TP
|
||||||
|
\fB\-4\fR
|
||||||
|
resolve hostnames only to IPv4 addresses
|
||||||
|
.TP
|
||||||
|
\fB\-6\fR
|
||||||
|
resolve hostnames only to IPv6 addresses
|
||||||
|
.TP
|
||||||
|
\fIcommand\fR
|
||||||
specify command. If no command is given, chronyc will read commands
|
specify command. If no command is given, chronyc will read commands
|
||||||
interactively.
|
interactively.
|
||||||
|
|
||||||
|
|
||||||
.SH VERSION
|
.SH VERSION
|
||||||
1.17
|
1.24
|
||||||
|
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
To report bugs, please contact the author and/or visit \fIhttp://chrony.sunsite.dk/\fR
|
To report bugs, please visit \fIhttp://chrony.tuxfamily.org\fR
|
||||||
|
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.BR chronyd(8),
|
.BR chronyd(8),
|
||||||
.BR chrony(1)
|
.BR chrony(1)
|
||||||
|
|
||||||
.I http://chrony.sunsite.dk/
|
.I http://chrony.tuxfamily.org/
|
||||||
|
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Richard Curnow <rc@rc0.org.uk>
|
Richard Curnow <rc@rc0.org.uk>
|
||||||
|
|||||||
25
chronyd.8
25
chronyd.8
@@ -1,4 +1,4 @@
|
|||||||
.TH CHRONYD 8 "August 10, 2001" chrony "System Administration"
|
.TH CHRONYD 8 "December 04, 2009" chrony "System Administration"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
chronyd \- chrony background daemon
|
chronyd \- chrony background daemon
|
||||||
|
|
||||||
@@ -35,6 +35,15 @@ Information messages and warnings will be logged to syslog.
|
|||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
A summary of the options supported by \fBchronyd\fR is included below.
|
A summary of the options supported by \fBchronyd\fR is included below.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fB\-P\fR \fIpriority\fR
|
||||||
|
This option will select the SCHED_FIFO real-time scheduler at the specified
|
||||||
|
priority (which must be between 0 and 100). This mode is supported only on
|
||||||
|
Linux.
|
||||||
|
.TP
|
||||||
|
.B \-m
|
||||||
|
This option will lock chronyd into RAM so that it will never be paged out.
|
||||||
|
This mode is only supported on Linux.
|
||||||
.TP
|
.TP
|
||||||
.B \-d
|
.B \-d
|
||||||
When run in this mode, the program will not detach itself from the
|
When run in this mode, the program will not detach itself from the
|
||||||
@@ -79,17 +88,27 @@ been able to determine accurate statistics for the difference
|
|||||||
between the real time clock and system clock last time the
|
between the real time clock and system clock last time the
|
||||||
computer was on.
|
computer was on.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-u\fR \fIuser\fR
|
||||||
|
When this option is used, chronyd will drop root privileges to the specified
|
||||||
|
user. So far, it works only on Linux when compiled with capabilities support.
|
||||||
|
.TP
|
||||||
.B \-v
|
.B \-v
|
||||||
This option displays \fBchronyd\fR's version number to the terminal and exits
|
This option displays \fBchronyd\fR's version number to the terminal and exits
|
||||||
|
.TP
|
||||||
|
.B \-4
|
||||||
|
Resolve hostnames only to IPv4 addresses.
|
||||||
|
.TP
|
||||||
|
.B \-6
|
||||||
|
Resolve hostnames only to IPv6 addresses.
|
||||||
|
|
||||||
.SH FILES
|
.SH FILES
|
||||||
\fI/etc/chrony.conf\fR
|
\fI/etc/chrony.conf\fR
|
||||||
|
|
||||||
.SH VERSION
|
.SH VERSION
|
||||||
Version 1.17
|
Version 1.24
|
||||||
|
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
To report bugs, please contact the author and/or visit \fIhttp://chrony.sunsite.dk/\fR
|
To report bugs, please visit \fIhttp://chrony.tuxfamily.org/\fR
|
||||||
|
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
\fBchronyd\fR is documented in detail in the documentation supplied with the
|
\fBchronyd\fR is documented in detail in the documentation supplied with the
|
||||||
|
|||||||
235
clientlog.c
235
clientlog.c
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
* Copyright (C) Richard P. Curnow 1997-2003
|
* Copyright (C) Richard P. Curnow 1997-2003
|
||||||
|
* Copyright (C) Miroslav Lichvar 2009
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of version 2 of the GNU General Public License as
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
@@ -19,7 +20,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -40,6 +41,7 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "reports.h"
|
#include "reports.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "logging.h"
|
||||||
|
|
||||||
/* Number of bits of address per layer of the table. This value has
|
/* Number of bits of address per layer of the table. This value has
|
||||||
been chosen on the basis that a server will predominantly be serving
|
been chosen on the basis that a server will predominantly be serving
|
||||||
@@ -52,7 +54,7 @@
|
|||||||
#define TABLE_SIZE (1UL<<NBITS)
|
#define TABLE_SIZE (1UL<<NBITS)
|
||||||
|
|
||||||
typedef struct _Node {
|
typedef struct _Node {
|
||||||
unsigned long ip_addr;
|
IPAddr ip_addr;
|
||||||
unsigned long client_hits;
|
unsigned long client_hits;
|
||||||
unsigned long peer_hits;
|
unsigned long peer_hits;
|
||||||
unsigned long cmd_hits_bad;
|
unsigned long cmd_hits_bad;
|
||||||
@@ -68,8 +70,10 @@ typedef struct _Subnet {
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
/* Table for the class A subnet */
|
/* Table for the IPv4 class A subnet */
|
||||||
static Subnet top_subnet;
|
static Subnet top_subnet4;
|
||||||
|
/* Table for IPv6 */
|
||||||
|
static Subnet top_subnet6;
|
||||||
|
|
||||||
/* Table containing pointers directly to all nodes that have been
|
/* Table containing pointers directly to all nodes that have been
|
||||||
allocated. */
|
allocated. */
|
||||||
@@ -81,13 +85,46 @@ static int n_nodes = 0;
|
|||||||
/* Number of entries for which the table has been sized. */
|
/* Number of entries for which the table has been sized. */
|
||||||
static int max_nodes = 0;
|
static int max_nodes = 0;
|
||||||
|
|
||||||
#define NODE_TABLE_INCREMENT 4
|
|
||||||
|
|
||||||
/* Flag indicating whether facility is turned on or not */
|
/* Flag indicating whether facility is turned on or not */
|
||||||
static int active = 0;
|
static int active = 0;
|
||||||
|
|
||||||
|
/* Flag indicating whether memory allocation limit has been reached
|
||||||
|
and no new nodes or subnets should be allocated */
|
||||||
|
static int alloc_limit_reached;
|
||||||
|
|
||||||
|
static unsigned long alloc_limit;
|
||||||
|
static unsigned long alloced;
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
static void
|
||||||
|
split_ip6(IPAddr *ip, uint32_t *dst)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
dst[i] = ip->addr.in6[i * 4 + 0] << 24 |
|
||||||
|
ip->addr.in6[i * 4 + 1] << 16 |
|
||||||
|
ip->addr.in6[i * 4 + 2] << 8 |
|
||||||
|
ip->addr.in6[i * 4 + 3];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
inline static uint32_t
|
||||||
|
get_subnet(uint32_t *addr, unsigned int where)
|
||||||
|
{
|
||||||
|
int off;
|
||||||
|
|
||||||
|
off = where / 32;
|
||||||
|
where %= 32;
|
||||||
|
|
||||||
|
return (addr[off] >> (32 - NBITS - where)) & ((1UL << NBITS) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clear_subnet(Subnet *subnet)
|
clear_subnet(Subnet *subnet)
|
||||||
{
|
{
|
||||||
@@ -117,7 +154,8 @@ clear_node(Node *node)
|
|||||||
void
|
void
|
||||||
CLG_Initialise(void)
|
CLG_Initialise(void)
|
||||||
{
|
{
|
||||||
clear_subnet(&top_subnet);
|
clear_subnet(&top_subnet4);
|
||||||
|
clear_subnet(&top_subnet6);
|
||||||
if (CNF_GetNoClientLog()) {
|
if (CNF_GetNoClientLog()) {
|
||||||
active = 0;
|
active = 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -128,6 +166,9 @@ CLG_Initialise(void)
|
|||||||
max_nodes = 0;
|
max_nodes = 0;
|
||||||
n_nodes = 0;
|
n_nodes = 0;
|
||||||
|
|
||||||
|
alloced = 0;
|
||||||
|
alloc_limit = CNF_GetClientLogLimit();
|
||||||
|
alloc_limit_reached = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -140,11 +181,25 @@ CLG_Finalise(void)
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
static void check_alloc_limit() {
|
||||||
|
if (alloc_limit_reached)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (alloced >= alloc_limit) {
|
||||||
|
LOG(LOGS_WARN, LOGF_ClientLog, "Client log memory limit reached");
|
||||||
|
alloc_limit_reached = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
create_subnet(Subnet *parent_subnet, int the_entry)
|
create_subnet(Subnet *parent_subnet, int the_entry)
|
||||||
{
|
{
|
||||||
parent_subnet->entry[the_entry] = (void *) MallocNew(Subnet);
|
parent_subnet->entry[the_entry] = (void *) MallocNew(Subnet);
|
||||||
clear_subnet((Subnet *) parent_subnet->entry[the_entry]);
|
clear_subnet((Subnet *) parent_subnet->entry[the_entry]);
|
||||||
|
alloced += sizeof (Subnet);
|
||||||
|
check_alloc_limit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -157,19 +212,22 @@ create_node(Subnet *parent_subnet, int the_entry)
|
|||||||
parent_subnet->entry[the_entry] = (void *) new_node;
|
parent_subnet->entry[the_entry] = (void *) new_node;
|
||||||
clear_node(new_node);
|
clear_node(new_node);
|
||||||
|
|
||||||
|
alloced += sizeof (Node);
|
||||||
|
|
||||||
if (n_nodes == max_nodes) {
|
if (n_nodes == max_nodes) {
|
||||||
if (nodes) {
|
if (nodes) {
|
||||||
max_nodes += NODE_TABLE_INCREMENT;
|
assert(max_nodes > 0);
|
||||||
|
max_nodes *= 2;
|
||||||
nodes = ReallocArray(Node *, max_nodes, nodes);
|
nodes = ReallocArray(Node *, max_nodes, nodes);
|
||||||
} else {
|
} else {
|
||||||
if (max_nodes != 0) {
|
assert(max_nodes == 0);
|
||||||
CROAK("max_nodes should be 0");
|
max_nodes = 16;
|
||||||
}
|
|
||||||
max_nodes = NODE_TABLE_INCREMENT;
|
|
||||||
nodes = MallocArray(Node *, max_nodes);
|
nodes = MallocArray(Node *, max_nodes);
|
||||||
}
|
}
|
||||||
|
alloced += sizeof (Node *) * (max_nodes - n_nodes);
|
||||||
}
|
}
|
||||||
nodes[n_nodes++] = (Node *) new_node;
|
nodes[n_nodes++] = (Node *) new_node;
|
||||||
|
check_alloc_limit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -177,29 +235,24 @@ create_node(Subnet *parent_subnet, int the_entry)
|
|||||||
expanding subnet tables and node entries as we go if necessary. */
|
expanding subnet tables and node entries as we go if necessary. */
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
find_subnet(Subnet *subnet, CLG_IP_Addr addr, int bits_left)
|
find_subnet(Subnet *subnet, uint32_t *addr, int addr_len, int bits_consumed)
|
||||||
{
|
{
|
||||||
unsigned long this_subnet, new_subnet, mask, shift;
|
uint32_t this_subnet;
|
||||||
unsigned long new_bits_left;
|
|
||||||
|
|
||||||
shift = 32 - NBITS;
|
|
||||||
mask = (1UL<<shift) - 1;
|
|
||||||
this_subnet = addr >> shift;
|
|
||||||
new_subnet = (addr & mask) << NBITS;
|
|
||||||
new_bits_left = bits_left - NBITS;
|
|
||||||
|
|
||||||
#if 0
|
this_subnet = get_subnet(addr, bits_consumed);
|
||||||
fprintf(stderr, "fs addr=%08lx bl=%d ma=%08lx this=%08lx newsn=%08lx nbl=%d\n",
|
bits_consumed += NBITS;
|
||||||
addr, bits_left, mask, this_subnet, new_subnet, new_bits_left);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (new_bits_left > 0) {
|
if (bits_consumed < 32 * addr_len) {
|
||||||
if (!subnet->entry[this_subnet]) {
|
if (!subnet->entry[this_subnet]) {
|
||||||
|
if (alloc_limit_reached)
|
||||||
|
return NULL;
|
||||||
create_subnet(subnet, this_subnet);
|
create_subnet(subnet, this_subnet);
|
||||||
}
|
}
|
||||||
return find_subnet((Subnet *) subnet->entry[this_subnet], new_subnet, new_bits_left);
|
return find_subnet((Subnet *) subnet->entry[this_subnet], addr, addr_len, bits_consumed);
|
||||||
} else {
|
} else {
|
||||||
if (!subnet->entry[this_subnet]) {
|
if (!subnet->entry[this_subnet]) {
|
||||||
|
if (alloc_limit_reached)
|
||||||
|
return NULL;
|
||||||
create_node(subnet, this_subnet);
|
create_node(subnet, this_subnet);
|
||||||
}
|
}
|
||||||
return subnet->entry[this_subnet];
|
return subnet->entry[this_subnet];
|
||||||
@@ -212,30 +265,21 @@ find_subnet(Subnet *subnet, CLG_IP_Addr addr, int bits_left)
|
|||||||
one of the parents does not exist - never open a node out */
|
one of the parents does not exist - never open a node out */
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
find_subnet_dont_open(Subnet *subnet, CLG_IP_Addr addr, int bits_left)
|
find_subnet_dont_open(Subnet *subnet, uint32_t *addr, int addr_len, int bits_consumed)
|
||||||
{
|
{
|
||||||
unsigned long this_subnet, new_subnet, mask, shift;
|
uint32_t this_subnet;
|
||||||
unsigned long new_bits_left;
|
|
||||||
|
|
||||||
if (bits_left == 0) {
|
if (bits_consumed >= 32 * addr_len) {
|
||||||
return subnet;
|
return subnet;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
shift = 32 - NBITS;
|
this_subnet = get_subnet(addr, bits_consumed);
|
||||||
mask = (1UL<<shift) - 1;
|
bits_consumed += NBITS;
|
||||||
this_subnet = addr >> shift;
|
|
||||||
new_subnet = (addr & mask) << NBITS;
|
|
||||||
new_bits_left = bits_left - NBITS;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
fprintf(stderr, "fsdo addr=%08lx bl=%d this=%08lx newsn=%08lx nbl=%d\n",
|
|
||||||
addr, bits_left, this_subnet, new_subnet, new_bits_left);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!subnet->entry[this_subnet]) {
|
if (!subnet->entry[this_subnet]) {
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
return find_subnet_dont_open((Subnet *) subnet->entry[this_subnet], new_subnet, new_bits_left);
|
return find_subnet_dont_open((Subnet *) subnet->entry[this_subnet], addr, addr_len, bits_consumed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -243,12 +287,28 @@ find_subnet_dont_open(Subnet *subnet, CLG_IP_Addr addr, int bits_left)
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
CLG_LogNTPClientAccess (CLG_IP_Addr client, time_t now)
|
CLG_LogNTPClientAccess (IPAddr *client, time_t now)
|
||||||
{
|
{
|
||||||
|
uint32_t ip6[4];
|
||||||
Node *node;
|
Node *node;
|
||||||
|
|
||||||
if (active) {
|
if (active) {
|
||||||
node = (Node *) find_subnet(&top_subnet, client, 32);
|
switch (client->family) {
|
||||||
node->ip_addr = client;
|
case IPADDR_INET4:
|
||||||
|
node = (Node *) find_subnet(&top_subnet4, &client->addr.in4, 1, 0);
|
||||||
|
break;
|
||||||
|
case IPADDR_INET6:
|
||||||
|
split_ip6(client, ip6);
|
||||||
|
node = (Node *) find_subnet(&top_subnet6, ip6, 4, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
node->ip_addr = *client;
|
||||||
++node->client_hits;
|
++node->client_hits;
|
||||||
node->last_ntp_hit = now;
|
node->last_ntp_hit = now;
|
||||||
}
|
}
|
||||||
@@ -257,12 +317,28 @@ CLG_LogNTPClientAccess (CLG_IP_Addr client, time_t now)
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
CLG_LogNTPPeerAccess(CLG_IP_Addr client, time_t now)
|
CLG_LogNTPPeerAccess(IPAddr *client, time_t now)
|
||||||
{
|
{
|
||||||
|
uint32_t ip6[4];
|
||||||
Node *node;
|
Node *node;
|
||||||
|
|
||||||
if (active) {
|
if (active) {
|
||||||
node = (Node *) find_subnet(&top_subnet, client, 32);
|
switch (client->family) {
|
||||||
node->ip_addr = client;
|
case IPADDR_INET4:
|
||||||
|
node = (Node *) find_subnet(&top_subnet4, &client->addr.in4, 1, 0);
|
||||||
|
break;
|
||||||
|
case IPADDR_INET6:
|
||||||
|
split_ip6(client, ip6);
|
||||||
|
node = (Node *) find_subnet(&top_subnet6, ip6, 4, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
node->ip_addr = *client;
|
||||||
++node->peer_hits;
|
++node->peer_hits;
|
||||||
node->last_ntp_hit = now;
|
node->last_ntp_hit = now;
|
||||||
}
|
}
|
||||||
@@ -271,12 +347,28 @@ CLG_LogNTPPeerAccess(CLG_IP_Addr client, time_t now)
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
CLG_LogCommandAccess(CLG_IP_Addr client, CLG_Command_Type type, time_t now)
|
CLG_LogCommandAccess(IPAddr *client, CLG_Command_Type type, time_t now)
|
||||||
{
|
{
|
||||||
|
uint32_t ip6[4];
|
||||||
Node *node;
|
Node *node;
|
||||||
|
|
||||||
if (active) {
|
if (active) {
|
||||||
node = (Node *) find_subnet(&top_subnet, client, 32);
|
switch (client->family) {
|
||||||
node->ip_addr = client;
|
case IPADDR_INET4:
|
||||||
|
node = (Node *) find_subnet(&top_subnet4, &client->addr.in4, 1, 0);
|
||||||
|
break;
|
||||||
|
case IPADDR_INET6:
|
||||||
|
split_ip6(client, ip6);
|
||||||
|
node = (Node *) find_subnet(&top_subnet6, ip6, 4, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
node->ip_addr = *client;
|
||||||
node->last_cmd_hit = now;
|
node->last_cmd_hit = now;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case CLG_CMD_AUTH:
|
case CLG_CMD_AUTH:
|
||||||
@@ -289,7 +381,7 @@ CLG_LogCommandAccess(CLG_IP_Addr client, CLG_Command_Type type, time_t now)
|
|||||||
++node->cmd_hits_bad;
|
++node->cmd_hits_bad;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
CROAK("Impossible");
|
assert(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -298,16 +390,32 @@ CLG_LogCommandAccess(CLG_IP_Addr client, CLG_Command_Type type, time_t now)
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
CLG_Status
|
CLG_Status
|
||||||
CLG_GetSubnetBitmap(CLG_IP_Addr subnet, int bits, CLG_Bitmap result)
|
CLG_GetSubnetBitmap(IPAddr *subnet, int bits, CLG_Bitmap result)
|
||||||
{
|
{
|
||||||
Subnet *s;
|
Subnet *s;
|
||||||
|
uint32_t ip6[4];
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
unsigned long word, bit, mask;
|
unsigned long word, bit, mask;
|
||||||
|
|
||||||
if ((bits == 0) || (bits == 8) || (bits == 16) || (bits == 24)) {
|
if (bits >= 0 && bits % 8 == 0) {
|
||||||
memset (result, 0, TABLE_SIZE/8);
|
memset (result, 0, TABLE_SIZE/8);
|
||||||
if (active) {
|
if (active) {
|
||||||
s = find_subnet_dont_open(&top_subnet, subnet, bits);
|
switch (subnet->family) {
|
||||||
|
case IPADDR_INET4:
|
||||||
|
if (bits >= 32)
|
||||||
|
return CLG_BADSUBNET;
|
||||||
|
s = find_subnet_dont_open(&top_subnet4, &subnet->addr.in4, 1, 32 - bits);
|
||||||
|
break;
|
||||||
|
case IPADDR_INET6:
|
||||||
|
if (bits >= 128)
|
||||||
|
return CLG_BADSUBNET;
|
||||||
|
split_ip6(subnet, ip6);
|
||||||
|
s = find_subnet_dont_open(&top_subnet6, ip6, 4, 128 - bits);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return CLG_BADSUBNET;
|
||||||
|
}
|
||||||
|
|
||||||
if (s) {
|
if (s) {
|
||||||
for (i=0; i<256; i++) {
|
for (i=0; i<256; i++) {
|
||||||
if (s->entry[i]) {
|
if (s->entry[i]) {
|
||||||
@@ -332,15 +440,26 @@ CLG_GetSubnetBitmap(CLG_IP_Addr subnet, int bits, CLG_Bitmap result)
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
CLG_Status
|
CLG_Status
|
||||||
CLG_GetClientAccessReportByIP(unsigned long ip, RPT_ClientAccess_Report *report, time_t now)
|
CLG_GetClientAccessReportByIP(IPAddr *ip, RPT_ClientAccess_Report *report, time_t now)
|
||||||
{
|
{
|
||||||
|
uint32_t ip6[4];
|
||||||
Node *node;
|
Node *node;
|
||||||
|
|
||||||
if (!active) {
|
if (!active) {
|
||||||
return CLG_INACTIVE;
|
return CLG_INACTIVE;
|
||||||
} else {
|
} else {
|
||||||
node = (Node *) find_subnet_dont_open(&top_subnet, ip, 32);
|
switch (ip->family) {
|
||||||
|
case IPADDR_INET4:
|
||||||
|
node = (Node *) find_subnet_dont_open(&top_subnet4, &ip->addr.in4, 1, 0);
|
||||||
|
break;
|
||||||
|
case IPADDR_INET6:
|
||||||
|
split_ip6(ip, ip6);
|
||||||
|
node = (Node *) find_subnet_dont_open(&top_subnet6, ip6, 4, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return CLG_EMPTYSUBNET;
|
||||||
|
}
|
||||||
|
|
||||||
if (!node) {
|
if (!node) {
|
||||||
return CLG_EMPTYSUBNET;
|
return CLG_EMPTYSUBNET;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
16
clientlog.h
16
clientlog.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -35,15 +35,13 @@
|
|||||||
#include "sysincl.h"
|
#include "sysincl.h"
|
||||||
#include "reports.h"
|
#include "reports.h"
|
||||||
|
|
||||||
typedef unsigned long CLG_IP_Addr;
|
|
||||||
|
|
||||||
/* Enough to hold flags for 256 hosts in a class C */
|
/* Enough to hold flags for 256 hosts in a class C */
|
||||||
typedef uint32_t CLG_Bitmap[8];
|
typedef uint32_t CLG_Bitmap[8];
|
||||||
|
|
||||||
extern void CLG_Initialise(void);
|
extern void CLG_Initialise(void);
|
||||||
extern void CLG_Finalise(void);
|
extern void CLG_Finalise(void);
|
||||||
extern void CLG_LogNTPClientAccess(CLG_IP_Addr client, time_t now);
|
extern void CLG_LogNTPClientAccess(IPAddr *client, time_t now);
|
||||||
extern void CLG_LogNTPPeerAccess(CLG_IP_Addr client, time_t now);
|
extern void CLG_LogNTPPeerAccess(IPAddr *client, time_t now);
|
||||||
|
|
||||||
/* When logging command packets, there are several subtypes */
|
/* When logging command packets, there are several subtypes */
|
||||||
|
|
||||||
@@ -53,7 +51,7 @@ typedef enum {
|
|||||||
CLG_CMD_BAD_PKT /* bad version or packet length */
|
CLG_CMD_BAD_PKT /* bad version or packet length */
|
||||||
} CLG_Command_Type;
|
} CLG_Command_Type;
|
||||||
|
|
||||||
extern void CLG_LogCommandAccess(CLG_IP_Addr client, CLG_Command_Type type, time_t now);
|
extern void CLG_LogCommandAccess(IPAddr *client, CLG_Command_Type type, time_t now);
|
||||||
|
|
||||||
/* And some reporting functions, for use by chronyc. */
|
/* And some reporting functions, for use by chronyc. */
|
||||||
/* TBD */
|
/* TBD */
|
||||||
@@ -70,10 +68,10 @@ typedef enum {
|
|||||||
known. For bits=24, flag which hosts in that subnet are known.
|
known. For bits=24, flag which hosts in that subnet are known.
|
||||||
Other values, return 0 (failed) */
|
Other values, return 0 (failed) */
|
||||||
|
|
||||||
extern CLG_Status CLG_GetSubnetBitmap(CLG_IP_Addr subnet, int bits, CLG_Bitmap result);
|
extern CLG_Status CLG_GetSubnetBitmap(IPAddr *subnet, int bits, CLG_Bitmap result);
|
||||||
|
|
||||||
extern CLG_Status
|
extern CLG_Status
|
||||||
CLG_GetClientAccessReportByIP(unsigned long ip, RPT_ClientAccess_Report *report, time_t now);
|
CLG_GetClientAccessReportByIP(IPAddr *ip, RPT_ClientAccess_Report *report, time_t now);
|
||||||
|
|
||||||
CLG_Status
|
CLG_Status
|
||||||
CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *report,
|
CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *report,
|
||||||
@@ -83,7 +81,7 @@ CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *repo
|
|||||||
that has accessed us since 'since'. */
|
that has accessed us since 'since'. */
|
||||||
|
|
||||||
extern void CLG_IterateNTPClients
|
extern void CLG_IterateNTPClients
|
||||||
(void (*fn)(CLG_IP_Addr client, void *arb),
|
(void (*fn)(IPAddr *client, void *arb),
|
||||||
void *arb,
|
void *arb,
|
||||||
time_t since);
|
time_t since);
|
||||||
|
|
||||||
|
|||||||
8
cmdmon.h
8
cmdmon.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -31,11 +31,13 @@
|
|||||||
#ifndef GOT_CMDMON_H
|
#ifndef GOT_CMDMON_H
|
||||||
#define GOT_CMDMON_H
|
#define GOT_CMDMON_H
|
||||||
|
|
||||||
|
#include "addressing.h"
|
||||||
|
|
||||||
extern void CAM_Initialise(void);
|
extern void CAM_Initialise(void);
|
||||||
|
|
||||||
extern void CAM_Finalise(void);
|
extern void CAM_Finalise(void);
|
||||||
|
|
||||||
extern int CAM_AddAccessRestriction(unsigned long ip_addr, int subnet_bits, int allow, int all);
|
extern int CAM_AddAccessRestriction(IPAddr *ip_addr, int subnet_bits, int allow, int all);
|
||||||
extern int CAM_CheckAccessRestriction(unsigned long ip_addr);
|
extern int CAM_CheckAccessRestriction(IPAddr *ip_addr);
|
||||||
|
|
||||||
#endif /* GOT_CMDMON_H */
|
#endif /* GOT_CMDMON_H */
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -61,8 +61,7 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src)
|
|||||||
|
|
||||||
ok = 0;
|
ok = 0;
|
||||||
if (sscanf(line, "%" SMAXLEN "s%n", hostname, &n) == 1) {
|
if (sscanf(line, "%" SMAXLEN "s%n", hostname, &n) == 1) {
|
||||||
src->ip_addr = DNS_Name2IPAddress(hostname);
|
if (DNS_Name2IPAddress(hostname, &src->ip_addr, 1)) {
|
||||||
if (src->ip_addr != DNS_Failed_Address) {
|
|
||||||
ok = 1;
|
ok = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
#define GOT_CMDPARSE_H
|
#define GOT_CMDPARSE_H
|
||||||
|
|
||||||
#include "srcparams.h"
|
#include "srcparams.h"
|
||||||
|
#include "addressing.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CPS_Success,
|
CPS_Success,
|
||||||
@@ -47,7 +48,7 @@ typedef enum {
|
|||||||
} CPS_Status;
|
} CPS_Status;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned long ip_addr;
|
IPAddr ip_addr;
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
SourceParameters params;
|
SourceParameters params;
|
||||||
} CPS_NTP_Source;
|
} CPS_NTP_Source;
|
||||||
|
|||||||
387
conf.c
387
conf.c
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
* Copyright (C) Richard P. Curnow 1997-2003
|
* Copyright (C) Richard P. Curnow 1997-2003
|
||||||
|
* Copyright (C) Miroslav Lichvar 2009
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of version 2 of the GNU General Public License as
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
@@ -19,7 +20,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -44,6 +45,7 @@
|
|||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "ntp_sources.h"
|
#include "ntp_sources.h"
|
||||||
#include "ntp_core.h"
|
#include "ntp_core.h"
|
||||||
|
#include "refclock.h"
|
||||||
#include "cmdmon.h"
|
#include "cmdmon.h"
|
||||||
#include "srcparams.h"
|
#include "srcparams.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
@@ -52,10 +54,15 @@
|
|||||||
#include "acquire.h"
|
#include "acquire.h"
|
||||||
#include "cmdparse.h"
|
#include "cmdparse.h"
|
||||||
#include "broadcast.h"
|
#include "broadcast.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
#define DEFAULT_CONF_FILE "/etc/chrony.conf"
|
#ifndef DEFAULT_CONF_DIR
|
||||||
|
#define DEFAULT_CONF_DIR "/etc"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DEFAULT_CONF_FILE DEFAULT_CONF_DIR"/chrony.conf"
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
/* Forward prototypes */
|
/* Forward prototypes */
|
||||||
@@ -73,6 +80,7 @@ static void parse_peer(const char *);
|
|||||||
static void parse_acquisitionport(const char *);
|
static void parse_acquisitionport(const char *);
|
||||||
static void parse_port(const char *);
|
static void parse_port(const char *);
|
||||||
static void parse_server(const char *);
|
static void parse_server(const char *);
|
||||||
|
static void parse_refclock(const char *);
|
||||||
static void parse_local(const char *);
|
static void parse_local(const char *);
|
||||||
static void parse_manual(const char *);
|
static void parse_manual(const char *);
|
||||||
static void parse_initstepslew(const char *);
|
static void parse_initstepslew(const char *);
|
||||||
@@ -83,6 +91,7 @@ static void parse_cmddeny(const char *);
|
|||||||
static void parse_cmdport(const char *);
|
static void parse_cmdport(const char *);
|
||||||
static void parse_rtconutc(const char *);
|
static void parse_rtconutc(const char *);
|
||||||
static void parse_noclientlog(const char *);
|
static void parse_noclientlog(const char *);
|
||||||
|
static void parse_clientloglimit(const char *);
|
||||||
static void parse_logchange(const char *);
|
static void parse_logchange(const char *);
|
||||||
static void parse_mailonchange(const char *);
|
static void parse_mailonchange(const char *);
|
||||||
static void parse_bindaddress(const char *);
|
static void parse_bindaddress(const char *);
|
||||||
@@ -92,6 +101,8 @@ static void parse_pidfile(const char *);
|
|||||||
static void parse_broadcast(const char *);
|
static void parse_broadcast(const char *);
|
||||||
static void parse_linux_hz(const char *);
|
static void parse_linux_hz(const char *);
|
||||||
static void parse_linux_freq_scale(const char *);
|
static void parse_linux_freq_scale(const char *);
|
||||||
|
static void parse_sched_priority(const char *);
|
||||||
|
static void parse_lockall(const char *);
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
/* Configuration variables */
|
/* Configuration variables */
|
||||||
@@ -111,6 +122,7 @@ static int do_log_measurements = 0;
|
|||||||
static int do_log_statistics = 0;
|
static int do_log_statistics = 0;
|
||||||
static int do_log_tracking = 0;
|
static int do_log_tracking = 0;
|
||||||
static int do_log_rtc = 0;
|
static int do_log_rtc = 0;
|
||||||
|
static int do_log_refclocks = 0;
|
||||||
static int do_dump_on_exit = 0;
|
static int do_dump_on_exit = 0;
|
||||||
static char *logdir = ".";
|
static char *logdir = ".";
|
||||||
static char *dumpdir = ".";
|
static char *dumpdir = ".";
|
||||||
@@ -126,7 +138,7 @@ static int n_init_srcs;
|
|||||||
than this, slew instead of stepping */
|
than this, slew instead of stepping */
|
||||||
static int init_slew_threshold = -1;
|
static int init_slew_threshold = -1;
|
||||||
#define MAX_INIT_SRCS 8
|
#define MAX_INIT_SRCS 8
|
||||||
static unsigned long init_srcs_ip[MAX_INIT_SRCS];
|
static IPAddr init_srcs_ip[MAX_INIT_SRCS];
|
||||||
|
|
||||||
static int enable_manual=0;
|
static int enable_manual=0;
|
||||||
|
|
||||||
@@ -146,13 +158,16 @@ static double mail_change_threshold = 0.0;
|
|||||||
memory */
|
memory */
|
||||||
static int no_client_log = 0;
|
static int no_client_log = 0;
|
||||||
|
|
||||||
/* IP address (host order) for binding the NTP socket to. 0 means INADDR_ANY
|
/* Limit memory allocated for the clients log */
|
||||||
will be used */
|
static unsigned long client_log_limit = 524288;
|
||||||
static unsigned long bind_address = 0UL;
|
|
||||||
|
|
||||||
/* IP address (host order) for binding the command socket to. 0 means
|
/* IP addresses for binding the NTP socket to. UNSPEC family means INADDR_ANY
|
||||||
|
will be used */
|
||||||
|
static IPAddr bind_address4, bind_address6;
|
||||||
|
|
||||||
|
/* IP addresses for binding the command socket to. UNSPEC family means
|
||||||
use the value of bind_address */
|
use the value of bind_address */
|
||||||
static unsigned long bind_cmd_address = 0UL;
|
static IPAddr bind_cmd_address4, bind_cmd_address6;
|
||||||
|
|
||||||
/* Filename to use for storing pid of running chronyd, to prevent multiple
|
/* Filename to use for storing pid of running chronyd, to prevent multiple
|
||||||
* chronyds being started. */
|
* chronyds being started. */
|
||||||
@@ -168,6 +183,9 @@ static int linux_hz;
|
|||||||
static int set_linux_freq_scale = 0;
|
static int set_linux_freq_scale = 0;
|
||||||
static double linux_freq_scale;
|
static double linux_freq_scale;
|
||||||
|
|
||||||
|
static int sched_priority = 0;
|
||||||
|
static int lock_memory = 0;
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -179,6 +197,7 @@ typedef struct {
|
|||||||
static const Command commands[] = {
|
static const Command commands[] = {
|
||||||
{"server", 6, parse_server},
|
{"server", 6, parse_server},
|
||||||
{"peer", 4, parse_peer},
|
{"peer", 4, parse_peer},
|
||||||
|
{"refclock", 8, parse_refclock},
|
||||||
{"acquisitionport", 15, parse_acquisitionport},
|
{"acquisitionport", 15, parse_acquisitionport},
|
||||||
{"port", 4, parse_port},
|
{"port", 4, parse_port},
|
||||||
{"driftfile", 9, parse_driftfile},
|
{"driftfile", 9, parse_driftfile},
|
||||||
@@ -200,6 +219,7 @@ static const Command commands[] = {
|
|||||||
{"cmdport", 7, parse_cmdport},
|
{"cmdport", 7, parse_cmdport},
|
||||||
{"rtconutc", 8, parse_rtconutc},
|
{"rtconutc", 8, parse_rtconutc},
|
||||||
{"noclientlog", 11, parse_noclientlog},
|
{"noclientlog", 11, parse_noclientlog},
|
||||||
|
{"clientloglimit", 14, parse_clientloglimit},
|
||||||
{"logchange", 9, parse_logchange},
|
{"logchange", 9, parse_logchange},
|
||||||
{"mailonchange", 12, parse_mailonchange},
|
{"mailonchange", 12, parse_mailonchange},
|
||||||
{"bindaddress", 11, parse_bindaddress},
|
{"bindaddress", 11, parse_bindaddress},
|
||||||
@@ -208,7 +228,9 @@ static const Command commands[] = {
|
|||||||
{"pidfile", 7, parse_pidfile},
|
{"pidfile", 7, parse_pidfile},
|
||||||
{"broadcast", 9, parse_broadcast},
|
{"broadcast", 9, parse_broadcast},
|
||||||
{"linux_hz", 8, parse_linux_hz},
|
{"linux_hz", 8, parse_linux_hz},
|
||||||
{"linux_freq_scale", 16, parse_linux_freq_scale}
|
{"linux_freq_scale", 16, parse_linux_freq_scale},
|
||||||
|
{"sched_priority", 14, parse_sched_priority},
|
||||||
|
{"lock_all", 8, parse_lockall}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int n_commands = (sizeof(commands) / sizeof(commands[0]));
|
static int n_commands = (sizeof(commands) / sizeof(commands[0]));
|
||||||
@@ -224,7 +246,7 @@ typedef enum {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NTP_Source_Type type;
|
NTP_Source_Type type;
|
||||||
unsigned long ip_addr;
|
IPAddr ip_addr;
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
SourceParameters params;
|
SourceParameters params;
|
||||||
} NTP_Source;
|
} NTP_Source;
|
||||||
@@ -234,12 +256,17 @@ typedef struct {
|
|||||||
static NTP_Source ntp_sources[MAX_NTP_SOURCES];
|
static NTP_Source ntp_sources[MAX_NTP_SOURCES];
|
||||||
static int n_ntp_sources = 0;
|
static int n_ntp_sources = 0;
|
||||||
|
|
||||||
|
#define MAX_RCL_SOURCES 8
|
||||||
|
|
||||||
|
static RefclockParameters refclock_sources[MAX_RCL_SOURCES];
|
||||||
|
static int n_refclock_sources = 0;
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
typedef struct _AllowDeny {
|
typedef struct _AllowDeny {
|
||||||
struct _AllowDeny *next;
|
struct _AllowDeny *next;
|
||||||
struct _AllowDeny *prev;
|
struct _AllowDeny *prev;
|
||||||
unsigned long ip;
|
IPAddr ip;
|
||||||
int subnet_bits;
|
int subnet_bits;
|
||||||
int all; /* 1 to override existing more specific defns */
|
int all; /* 1 to override existing more specific defns */
|
||||||
int allow; /* 0 for deny, 1 for allow */
|
int allow; /* 0 for deny, 1 for allow */
|
||||||
@@ -365,6 +392,24 @@ parse_source(const char *line, NTP_Source_Type type)
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_sched_priority(const char *line)
|
||||||
|
{
|
||||||
|
if (sscanf(line, "%d", &sched_priority) != 1) {
|
||||||
|
LOG(LOGS_WARN, LOGF_Configure, "Could not read scheduling priority at line %d", line_number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_lockall(const char *line)
|
||||||
|
{
|
||||||
|
lock_memory = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_server(const char *line)
|
parse_server(const char *line)
|
||||||
{
|
{
|
||||||
@@ -381,6 +426,98 @@ parse_peer(const char *line)
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_refclock(const char *line)
|
||||||
|
{
|
||||||
|
int i, n, poll, dpoll, filter_length, pps_rate;
|
||||||
|
unsigned long ref_id;
|
||||||
|
double offset, delay;
|
||||||
|
const char *tmp;
|
||||||
|
char name[5], cmd[10 + 1], *param;
|
||||||
|
unsigned char ref[5];
|
||||||
|
|
||||||
|
i = n_refclock_sources;
|
||||||
|
if (i >= MAX_RCL_SOURCES)
|
||||||
|
return;
|
||||||
|
|
||||||
|
poll = 4;
|
||||||
|
dpoll = 0;
|
||||||
|
filter_length = 15;
|
||||||
|
pps_rate = 0;
|
||||||
|
offset = 0.0;
|
||||||
|
delay = 1e-9;
|
||||||
|
ref_id = 0;
|
||||||
|
|
||||||
|
if (sscanf(line, "%4s%n", name, &n) != 1) {
|
||||||
|
LOG(LOGS_WARN, LOGF_Configure, "Could not read refclock driver name at line %d", line_number);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
line += n;
|
||||||
|
|
||||||
|
while (isspace(line[0]))
|
||||||
|
line++;
|
||||||
|
tmp = line;
|
||||||
|
while (line[0] != '\0' && !isspace(line[0]))
|
||||||
|
line++;
|
||||||
|
|
||||||
|
if (line == tmp) {
|
||||||
|
LOG(LOGS_WARN, LOGF_Configure, "Could not read refclock parameter at line %d", line_number);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
param = MallocArray(char, 1 + line - tmp);
|
||||||
|
strncpy(param, tmp, line - tmp);
|
||||||
|
param[line - tmp] = '\0';
|
||||||
|
|
||||||
|
while (sscanf(line, "%10s%n", cmd, &n) == 1) {
|
||||||
|
line += n;
|
||||||
|
if (!strncasecmp(cmd, "refid", 5)) {
|
||||||
|
if (sscanf(line, "%4s%n", (char *)ref, &n) != 1)
|
||||||
|
break;
|
||||||
|
ref_id = ref[0] << 24 | ref[1] << 16 | ref[2] << 8 | ref[3];
|
||||||
|
} else if (!strncasecmp(cmd, "poll", 4)) {
|
||||||
|
if (sscanf(line, "%d%n", &poll, &n) != 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (!strncasecmp(cmd, "dpoll", 5)) {
|
||||||
|
if (sscanf(line, "%d%n", &dpoll, &n) != 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (!strncasecmp(cmd, "filter", 6)) {
|
||||||
|
if (sscanf(line, "%d%n", &filter_length, &n) != 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (!strncasecmp(cmd, "rate", 4)) {
|
||||||
|
if (sscanf(line, "%d%n", &pps_rate, &n) != 1)
|
||||||
|
break;
|
||||||
|
} else if (!strncasecmp(cmd, "offset", 6)) {
|
||||||
|
if (sscanf(line, "%lf%n", &offset, &n) != 1)
|
||||||
|
break;
|
||||||
|
} else if (!strncasecmp(cmd, "delay", 5)) {
|
||||||
|
if (sscanf(line, "%lf%n", &delay, &n) != 1)
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
LOG(LOGS_WARN, LOGF_Configure, "Unknown refclock parameter %s at line %d", cmd, line_number);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
line += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(refclock_sources[i].driver_name, name, 4);
|
||||||
|
refclock_sources[i].driver_parameter = param;
|
||||||
|
refclock_sources[i].driver_poll = dpoll;
|
||||||
|
refclock_sources[i].poll = poll;
|
||||||
|
refclock_sources[i].filter_length = filter_length;
|
||||||
|
refclock_sources[i].pps_rate = pps_rate;
|
||||||
|
refclock_sources[i].offset = offset;
|
||||||
|
refclock_sources[i].delay = delay;
|
||||||
|
refclock_sources[i].ref_id = ref_id;
|
||||||
|
|
||||||
|
n_refclock_sources++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_some_port(const char *line, int *portvar)
|
parse_some_port(const char *line, int *portvar)
|
||||||
{
|
{
|
||||||
@@ -516,6 +653,9 @@ parse_log(const char *line)
|
|||||||
} else if (!strncmp(line, "rtc", 3)) {
|
} else if (!strncmp(line, "rtc", 3)) {
|
||||||
do_log_rtc = 1;
|
do_log_rtc = 1;
|
||||||
line += 3;
|
line += 3;
|
||||||
|
} else if (!strncmp(line, "refclocks", 9)) {
|
||||||
|
do_log_refclocks = 1;
|
||||||
|
line += 9;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -571,7 +711,7 @@ parse_initstepslew(const char *line)
|
|||||||
char hostname[HOSTNAME_LEN+1];
|
char hostname[HOSTNAME_LEN+1];
|
||||||
int n;
|
int n;
|
||||||
int threshold;
|
int threshold;
|
||||||
unsigned long ip_addr;
|
IPAddr ip_addr;
|
||||||
|
|
||||||
n_init_srcs = 0;
|
n_init_srcs = 0;
|
||||||
p = line;
|
p = line;
|
||||||
@@ -584,8 +724,7 @@ parse_initstepslew(const char *line)
|
|||||||
}
|
}
|
||||||
while (*p) {
|
while (*p) {
|
||||||
if (sscanf(p, "%" SHOSTNAME_LEN "s%n", hostname, &n) == 1) {
|
if (sscanf(p, "%" SHOSTNAME_LEN "s%n", hostname, &n) == 1) {
|
||||||
ip_addr = DNS_Name2IPAddress(hostname);
|
if (DNS_Name2IPAddress(hostname, &ip_addr, 1)) {
|
||||||
if (ip_addr != DNS_Failed_Address) {
|
|
||||||
init_srcs_ip[n_init_srcs] = ip_addr;
|
init_srcs_ip[n_init_srcs] = ip_addr;
|
||||||
++n_init_srcs;
|
++n_init_srcs;
|
||||||
}
|
}
|
||||||
@@ -634,6 +773,21 @@ parse_noclientlog(const char *line)
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_clientloglimit(const char *line)
|
||||||
|
{
|
||||||
|
if (sscanf(line, "%lu", &client_log_limit) != 1) {
|
||||||
|
LOG(LOGS_WARN, LOGF_Configure, "Could not read clientlog memory limit at line %d", line_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client_log_limit == 0) {
|
||||||
|
/* unlimited */
|
||||||
|
client_log_limit = (unsigned long)-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_logchange(const char *line)
|
parse_logchange(const char *line)
|
||||||
{
|
{
|
||||||
@@ -677,7 +831,7 @@ parse_allow_deny(const char *line, AllowDeny *list, int allow)
|
|||||||
unsigned long a, b, c, d, n;
|
unsigned long a, b, c, d, n;
|
||||||
int all = 0;
|
int all = 0;
|
||||||
AllowDeny *new_node = NULL;
|
AllowDeny *new_node = NULL;
|
||||||
unsigned long ip_addr;
|
IPAddr ip_addr;
|
||||||
|
|
||||||
p = line;
|
p = line;
|
||||||
|
|
||||||
@@ -694,45 +848,54 @@ parse_allow_deny(const char *line, AllowDeny *list, int allow)
|
|||||||
new_node = MallocNew(AllowDeny);
|
new_node = MallocNew(AllowDeny);
|
||||||
new_node->allow = allow;
|
new_node->allow = allow;
|
||||||
new_node->all = all;
|
new_node->all = all;
|
||||||
new_node->ip = 0UL;
|
new_node->ip.family = IPADDR_UNSPEC;
|
||||||
new_node->subnet_bits = 0;
|
new_node->subnet_bits = 0;
|
||||||
} else {
|
} else {
|
||||||
char *slashpos;
|
char *slashpos;
|
||||||
slashpos = strchr(p, '/');
|
slashpos = strchr(p, '/');
|
||||||
if (slashpos) *slashpos = 0;
|
if (slashpos) *slashpos = 0;
|
||||||
|
|
||||||
n = sscanf(p, "%lu.%lu.%lu.%lu", &a, &b, &c, &d);
|
n = 0;
|
||||||
|
if (UTI_StringToIP(p, &ip_addr) ||
|
||||||
if (n >= 1) {
|
(n = sscanf(p, "%lu.%lu.%lu.%lu", &a, &b, &c, &d)) >= 1) {
|
||||||
new_node = MallocNew(AllowDeny);
|
new_node = MallocNew(AllowDeny);
|
||||||
new_node->allow = allow;
|
new_node->allow = allow;
|
||||||
new_node->all = all;
|
new_node->all = all;
|
||||||
|
|
||||||
a &= 0xff;
|
if (n == 0) {
|
||||||
b &= 0xff;
|
new_node->ip = ip_addr;
|
||||||
c &= 0xff;
|
if (ip_addr.family == IPADDR_INET6)
|
||||||
d &= 0xff;
|
new_node->subnet_bits = 128;
|
||||||
|
else
|
||||||
switch (n) {
|
|
||||||
case 1:
|
|
||||||
new_node->ip = (a<<24);
|
|
||||||
new_node->subnet_bits = 8;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
new_node->ip = (a<<24) | (b<<16);
|
|
||||||
new_node->subnet_bits = 16;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
new_node->ip = (a<<24) | (b<<16) | (c<<8);
|
|
||||||
new_node->subnet_bits = 24;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
new_node->ip = (a<<24) | (b<<16) | (c<<8) | d;
|
|
||||||
new_node->subnet_bits = 32;
|
new_node->subnet_bits = 32;
|
||||||
break;
|
} else {
|
||||||
default:
|
new_node->ip.family = IPADDR_INET4;
|
||||||
assert(0);
|
|
||||||
|
a &= 0xff;
|
||||||
|
b &= 0xff;
|
||||||
|
c &= 0xff;
|
||||||
|
d &= 0xff;
|
||||||
|
|
||||||
|
switch (n) {
|
||||||
|
case 1:
|
||||||
|
new_node->ip.addr.in4 = (a<<24);
|
||||||
|
new_node->subnet_bits = 8;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
new_node->ip.addr.in4 = (a<<24) | (b<<16);
|
||||||
|
new_node->subnet_bits = 16;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
new_node->ip.addr.in4 = (a<<24) | (b<<16) | (c<<8);
|
||||||
|
new_node->subnet_bits = 24;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
new_node->ip.addr.in4 = (a<<24) | (b<<16) | (c<<8) | d;
|
||||||
|
new_node->subnet_bits = 32;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slashpos) {
|
if (slashpos) {
|
||||||
@@ -746,13 +909,15 @@ parse_allow_deny(const char *line, AllowDeny *list, int allow)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ip_addr = DNS_Name2IPAddress(p);
|
if (DNS_Name2IPAddress(p, &ip_addr, 1)) {
|
||||||
if (ip_addr != DNS_Failed_Address) {
|
|
||||||
new_node = MallocNew(AllowDeny);
|
new_node = MallocNew(AllowDeny);
|
||||||
new_node->allow = allow;
|
new_node->allow = allow;
|
||||||
new_node->all = all;
|
new_node->all = all;
|
||||||
new_node->ip = ip_addr;
|
new_node->ip = ip_addr;
|
||||||
new_node->subnet_bits = 32;
|
if (ip_addr.family == IPADDR_INET6)
|
||||||
|
new_node->subnet_bits = 128;
|
||||||
|
else
|
||||||
|
new_node->subnet_bits = 32;
|
||||||
} else {
|
} else {
|
||||||
LOG(LOGS_WARN, LOGF_Configure, "Could not read address at line %d", line_number);
|
LOG(LOGS_WARN, LOGF_Configure, "Could not read address at line %d", line_number);
|
||||||
}
|
}
|
||||||
@@ -805,27 +970,20 @@ parse_cmddeny(const char *line)
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static unsigned long
|
|
||||||
parse_an_address(const char *line, const char *errmsg)
|
|
||||||
{
|
|
||||||
unsigned long a, b, c, d;
|
|
||||||
int n;
|
|
||||||
n = sscanf(line, "%lu.%lu.%lu.%lu", &a, &b, &c, &d);
|
|
||||||
if (n == 4) {
|
|
||||||
return (((a&0xff)<<24) | ((b&0xff)<<16) |
|
|
||||||
((c&0xff)<<8) | (d&0xff));
|
|
||||||
} else {
|
|
||||||
LOG(LOGS_WARN, LOGF_Configure, errmsg, line_number);
|
|
||||||
return 0UL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ================================================== */
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_bindaddress(const char *line)
|
parse_bindaddress(const char *line)
|
||||||
{
|
{
|
||||||
bind_address = parse_an_address(line, "Could not read bind address at line %d\n");
|
IPAddr ip;
|
||||||
|
char addr[51];
|
||||||
|
|
||||||
|
if (sscanf(line, "%50s", addr) == 1 && UTI_StringToIP(addr, &ip)) {
|
||||||
|
if (ip.family == IPADDR_INET4)
|
||||||
|
bind_address4 = ip;
|
||||||
|
else if (ip.family == IPADDR_INET6)
|
||||||
|
bind_address6 = ip;
|
||||||
|
} else {
|
||||||
|
LOG(LOGS_WARN, LOGF_Configure, "Could not read bind address at line %d\n", line_number);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -833,7 +991,17 @@ parse_bindaddress(const char *line)
|
|||||||
static void
|
static void
|
||||||
parse_bindcmdaddress(const char *line)
|
parse_bindcmdaddress(const char *line)
|
||||||
{
|
{
|
||||||
bind_cmd_address = parse_an_address(line, "Could not read bind command address at line %d\n");
|
IPAddr ip;
|
||||||
|
char addr[51];
|
||||||
|
|
||||||
|
if (sscanf(line, "%50s", addr) == 1 && UTI_StringToIP(addr, &ip)) {
|
||||||
|
if (ip.family == IPADDR_INET4)
|
||||||
|
bind_cmd_address4 = ip;
|
||||||
|
else if (ip.family == IPADDR_INET6)
|
||||||
|
bind_cmd_address6 = ip;
|
||||||
|
} else {
|
||||||
|
LOG(LOGS_WARN, LOGF_Configure, "Could not read bind command address at line %d\n", line_number);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -850,7 +1018,7 @@ parse_pidfile(const char *line)
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* Both in host (not necessarily network) order */
|
/* Both in host (not necessarily network) order */
|
||||||
unsigned long addr;
|
IPAddr addr;
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
int interval;
|
int interval;
|
||||||
} NTP_Broadcast_Destination;
|
} NTP_Broadcast_Destination;
|
||||||
@@ -866,27 +1034,22 @@ parse_broadcast(const char *line)
|
|||||||
{
|
{
|
||||||
/* Syntax : broadcast <interval> <broadcast-IP-addr> [<port>] */
|
/* Syntax : broadcast <interval> <broadcast-IP-addr> [<port>] */
|
||||||
int port;
|
int port;
|
||||||
unsigned int a, b, c, d;
|
|
||||||
int n;
|
int n;
|
||||||
int interval;
|
int interval;
|
||||||
unsigned long addr;
|
char addr[51];
|
||||||
|
IPAddr ip;
|
||||||
|
|
||||||
n = sscanf(line, "%d %u.%u.%u.%u %d", &interval, &a, &b, &c, &d, &port);
|
n = sscanf(line, "%d %50s %d", &interval, addr, &port);
|
||||||
if (n < 5) {
|
if (n < 2 || !UTI_StringToIP(addr, &ip)) {
|
||||||
LOG(LOGS_WARN, LOGF_Configure, "Could not parse broadcast directive at line %d", line_number);
|
LOG(LOGS_WARN, LOGF_Configure, "Could not parse broadcast directive at line %d", line_number);
|
||||||
return;
|
return;
|
||||||
} else if (n == 5) {
|
} else if (n == 2) {
|
||||||
/* default port */
|
/* default port */
|
||||||
port = 123;
|
port = 123;
|
||||||
} else if (n > 6) {
|
} else if (n > 3) {
|
||||||
LOG(LOGS_WARN, LOGF_Configure, "Too many fields in broadcast directive at line %d", line_number);
|
LOG(LOGS_WARN, LOGF_Configure, "Too many fields in broadcast directive at line %d", line_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = ((unsigned long) a << 24) |
|
|
||||||
((unsigned long) b << 16) |
|
|
||||||
((unsigned long) c << 8) |
|
|
||||||
((unsigned long) d );
|
|
||||||
|
|
||||||
if (max_broadcasts == n_broadcasts) {
|
if (max_broadcasts == n_broadcasts) {
|
||||||
/* Expand array */
|
/* Expand array */
|
||||||
max_broadcasts += 8;
|
max_broadcasts += 8;
|
||||||
@@ -897,7 +1060,7 @@ parse_broadcast(const char *line)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
broadcasts[n_broadcasts].addr = addr;
|
broadcasts[n_broadcasts].addr = ip;
|
||||||
broadcasts[n_broadcasts].port = port;
|
broadcasts[n_broadcasts].port = port;
|
||||||
broadcasts[n_broadcasts].interval = interval;
|
broadcasts[n_broadcasts].interval = interval;
|
||||||
++n_broadcasts;
|
++n_broadcasts;
|
||||||
@@ -948,6 +1111,7 @@ CNF_AddSources(void) {
|
|||||||
|
|
||||||
for (i=0; i<n_ntp_sources; i++) {
|
for (i=0; i<n_ntp_sources; i++) {
|
||||||
server.ip_addr = ntp_sources[i].ip_addr;
|
server.ip_addr = ntp_sources[i].ip_addr;
|
||||||
|
memset(&server.local_ip_addr, 0, sizeof (server.local_ip_addr));
|
||||||
server.port = ntp_sources[i].port;
|
server.port = ntp_sources[i].port;
|
||||||
|
|
||||||
switch (ntp_sources[i].type) {
|
switch (ntp_sources[i].type) {
|
||||||
@@ -968,12 +1132,23 @@ CNF_AddSources(void) {
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
void
|
||||||
|
CNF_AddRefclocks(void) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0; i<n_refclock_sources; i++) {
|
||||||
|
RCL_AddRefclock(&refclock_sources[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
CNF_AddBroadcasts(void)
|
CNF_AddBroadcasts(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<n_broadcasts; i++) {
|
for (i=0; i<n_broadcasts; i++) {
|
||||||
BRD_AddDestination(broadcasts[i].addr,
|
BRD_AddDestination(&broadcasts[i].addr,
|
||||||
broadcasts[i].port,
|
broadcasts[i].port,
|
||||||
broadcasts[i].interval);
|
broadcasts[i].interval);
|
||||||
}
|
}
|
||||||
@@ -1051,6 +1226,13 @@ CNF_GetLogRtc(void)
|
|||||||
return do_log_rtc;
|
return do_log_rtc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
int
|
||||||
|
CNF_GetLogRefclocks(void)
|
||||||
|
{
|
||||||
|
return do_log_refclocks;
|
||||||
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
char *
|
char *
|
||||||
@@ -1169,14 +1351,14 @@ CNF_SetupAccessRestrictions(void)
|
|||||||
int status;
|
int status;
|
||||||
|
|
||||||
for (node = ntp_auth_list.next; node != &ntp_auth_list; node = node->next) {
|
for (node = ntp_auth_list.next; node != &ntp_auth_list; node = node->next) {
|
||||||
status = NCR_AddAccessRestriction(node->ip, node->subnet_bits, node->allow, node->all);
|
status = NCR_AddAccessRestriction(&node->ip, node->subnet_bits, node->allow, node->all);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
LOG(LOGS_WARN, LOGF_Configure, "Bad subnet for %08lx", node->ip);
|
LOG(LOGS_WARN, LOGF_Configure, "Bad subnet for %08lx", node->ip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (node = cmd_auth_list.next; node != &cmd_auth_list; node = node->next) {
|
for (node = cmd_auth_list.next; node != &cmd_auth_list; node = node->next) {
|
||||||
status = CAM_AddAccessRestriction(node->ip, node->subnet_bits, node->allow, node->all);
|
status = CAM_AddAccessRestriction(&node->ip, node->subnet_bits, node->allow, node->all);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
LOG(LOGS_WARN, LOGF_Configure, "Bad subnet for %08lx", node->ip);
|
LOG(LOGS_WARN, LOGF_Configure, "Bad subnet for %08lx", node->ip);
|
||||||
}
|
}
|
||||||
@@ -1195,18 +1377,36 @@ CNF_GetNoClientLog(void)
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
unsigned long
|
||||||
CNF_GetBindAddress(unsigned long *addr)
|
CNF_GetClientLogLimit(void)
|
||||||
{
|
{
|
||||||
*addr = bind_address;
|
return client_log_limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
CNF_GetBindCommandAddress(unsigned long *addr)
|
CNF_GetBindAddress(int family, IPAddr *addr)
|
||||||
{
|
{
|
||||||
*addr = bind_cmd_address ? bind_cmd_address : bind_address;
|
if (family == IPADDR_INET4)
|
||||||
|
*addr = bind_address4;
|
||||||
|
else if (family == IPADDR_INET6)
|
||||||
|
*addr = bind_address6;
|
||||||
|
else
|
||||||
|
addr->family = IPADDR_UNSPEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
void
|
||||||
|
CNF_GetBindCommandAddress(int family, IPAddr *addr)
|
||||||
|
{
|
||||||
|
if (family == IPADDR_INET4)
|
||||||
|
*addr = bind_cmd_address4.family != IPADDR_UNSPEC ? bind_cmd_address4 : bind_address4;
|
||||||
|
else if (family == IPADDR_INET6)
|
||||||
|
*addr = bind_cmd_address6.family != IPADDR_UNSPEC ? bind_cmd_address6 : bind_address6;
|
||||||
|
else
|
||||||
|
addr->family = IPADDR_UNSPEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -1235,3 +1435,18 @@ CNF_GetLinuxFreqScale(int *set, double *freq_scale)
|
|||||||
*freq_scale = linux_freq_scale ;
|
*freq_scale = linux_freq_scale ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
int
|
||||||
|
CNF_GetSchedPriority(void)
|
||||||
|
{
|
||||||
|
return sched_priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
int
|
||||||
|
CNF_GetLockMemory(void)
|
||||||
|
{
|
||||||
|
return lock_memory;
|
||||||
|
}
|
||||||
|
|||||||
14
conf.h
14
conf.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -31,12 +31,15 @@
|
|||||||
#ifndef GOT_CONF_H
|
#ifndef GOT_CONF_H
|
||||||
#define GOT_CONF_H
|
#define GOT_CONF_H
|
||||||
|
|
||||||
|
#include "addressing.h"
|
||||||
|
|
||||||
extern char *CNF_GetRtcDevice(void);
|
extern char *CNF_GetRtcDevice(void);
|
||||||
|
|
||||||
extern void CNF_ReadFile(const char *filename);
|
extern void CNF_ReadFile(const char *filename);
|
||||||
|
|
||||||
extern void CNF_AddSources(void);
|
extern void CNF_AddSources(void);
|
||||||
extern void CNF_AddBroadcasts(void);
|
extern void CNF_AddBroadcasts(void);
|
||||||
|
extern void CNF_AddRefclocks(void);
|
||||||
|
|
||||||
extern void CNF_ProcessInitStepSlew(void (*after_hook)(void *), void *anything);
|
extern void CNF_ProcessInitStepSlew(void (*after_hook)(void *), void *anything);
|
||||||
|
|
||||||
@@ -49,6 +52,7 @@ extern int CNF_GetLogMeasurements(void);
|
|||||||
extern int CNF_GetLogStatistics(void);
|
extern int CNF_GetLogStatistics(void);
|
||||||
extern int CNF_GetLogTracking(void);
|
extern int CNF_GetLogTracking(void);
|
||||||
extern int CNF_GetLogRtc(void);
|
extern int CNF_GetLogRtc(void);
|
||||||
|
extern int CNF_GetLogRefclocks(void);
|
||||||
extern char *CNF_GetKeysFile(void);
|
extern char *CNF_GetKeysFile(void);
|
||||||
extern char *CNF_GetRtcFile(void);
|
extern char *CNF_GetRtcFile(void);
|
||||||
extern unsigned long CNF_GetCommandKey(void);
|
extern unsigned long CNF_GetCommandKey(void);
|
||||||
@@ -59,8 +63,9 @@ extern int CNF_GetRTCOnUTC(void);
|
|||||||
extern void CNF_GetLogChange(int *enabled, double *threshold);
|
extern void CNF_GetLogChange(int *enabled, double *threshold);
|
||||||
extern void CNF_GetMailOnChange(int *enabled, double *threshold, char **user);
|
extern void CNF_GetMailOnChange(int *enabled, double *threshold, char **user);
|
||||||
extern int CNF_GetNoClientLog(void);
|
extern int CNF_GetNoClientLog(void);
|
||||||
extern void CNF_GetBindAddress(unsigned long *addr);
|
extern unsigned long CNF_GetClientLogLimit(void);
|
||||||
extern void CNF_GetBindCommandAddress(unsigned long *addr);
|
extern void CNF_GetBindAddress(int family, IPAddr *addr);
|
||||||
|
extern void CNF_GetBindCommandAddress(int family, IPAddr *addr);
|
||||||
extern char *CNF_GetPidFile(void);
|
extern char *CNF_GetPidFile(void);
|
||||||
extern void CNF_GetLinuxHz(int *set, int *hz);
|
extern void CNF_GetLinuxHz(int *set, int *hz);
|
||||||
extern void CNF_GetLinuxFreqScale(int *set, double *freq_scale);
|
extern void CNF_GetLinuxFreqScale(int *set, double *freq_scale);
|
||||||
@@ -71,4 +76,7 @@ extern int CNF_AllowLocalReference(int *stratum);
|
|||||||
|
|
||||||
extern void CNF_SetupAccessRestrictions(void);
|
extern void CNF_SetupAccessRestrictions(void);
|
||||||
|
|
||||||
|
extern int CNF_GetSchedPriority(void);
|
||||||
|
extern int CNF_GetLockMemory(void);
|
||||||
|
|
||||||
#endif /* GOT_CONF_H */
|
#endif /* GOT_CONF_H */
|
||||||
|
|||||||
370
configure
vendored
370
configure
vendored
@@ -1,7 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
|
||||||
# $Header: /cvs/src/chrony/configure,v 1.30 2003/09/22 21:53:57 richard Exp $
|
|
||||||
#
|
|
||||||
# =======================================================================
|
# =======================================================================
|
||||||
#
|
#
|
||||||
# chronyd/chronyc - Programs for keeping computer clocks accurate.
|
# chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||||
@@ -24,86 +21,47 @@ else
|
|||||||
MYCFLAGS="${CFLAGS}"
|
MYCFLAGS="${CFLAGS}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
MYCPPFLAGS="${CPPFLAGS}"
|
||||||
|
|
||||||
|
if [ "x${MYCC}" = "xgcc" ]; then
|
||||||
|
CCWARNFLAGS="-Wmissing-prototypes -Wall"
|
||||||
|
else
|
||||||
|
CCWARNFLAGS=""
|
||||||
|
fi
|
||||||
|
|
||||||
# ======================================================================
|
# ======================================================================
|
||||||
# FUNCTIONS
|
# FUNCTIONS
|
||||||
|
|
||||||
#{{{ test_for_sqrt
|
#{{{ test_code
|
||||||
test_for_sqrt () {
|
test_code () {
|
||||||
# 0 : doesn't need -lm
|
name=$1
|
||||||
# 1 : needs -lm
|
headers=$2
|
||||||
# 2 : doesn't even link with -lm
|
cflags=$3
|
||||||
|
ldflags=$4
|
||||||
|
code=$5
|
||||||
|
|
||||||
cat >docheck.c <<EOF;
|
printf "Checking for $name : "
|
||||||
#include <math.h>
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
return (int) sqrt((double)argc);
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
${MYCC} ${MYCFLAGS} -c -o docheck.o docheck.c >/dev/null 2>&1
|
(
|
||||||
if [ $? -eq 0 ]
|
for h in $headers; do
|
||||||
then
|
echo "#include <$h>"
|
||||||
${MYCC} ${MYCFLAGS} -o docheck docheck.o >/dev/null 2>&1
|
done
|
||||||
if [ $? -eq 0 ]
|
echo "int main(int argc, char **argv) {"
|
||||||
then
|
echo "$code"
|
||||||
result=0
|
echo "return 0; }"
|
||||||
else
|
) > docheck.c
|
||||||
${MYCC} ${MYCFLAGS} -o docheck docheck.o -lm >/dev/null 2>&1
|
|
||||||
if [ $? -eq 0 ]
|
${MYCC} ${MYCFLAGS} ${MYCPPFLAGS} $cflags -o docheck docheck.c $ldflags >/dev/null 2>&1
|
||||||
then
|
|
||||||
result=1
|
|
||||||
else
|
|
||||||
result=2
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
result=2
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -f docheck.c docheck.o docheck
|
|
||||||
echo $result
|
|
||||||
}
|
|
||||||
#}}}
|
|
||||||
#{{{ test_for_stdint_h
|
|
||||||
test_for_stdint_h () {
|
|
||||||
cat >docheck.c <<EOF;
|
|
||||||
#include <stdint.h>
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
${MYCC} ${MYCFLAGS} -c -o docheck.o docheck.c >/dev/null 2>&1
|
|
||||||
if [ $? -eq 0 ]
|
if [ $? -eq 0 ]
|
||||||
then
|
then
|
||||||
|
printf "Yes\n"
|
||||||
result=0
|
result=0
|
||||||
else
|
else
|
||||||
|
printf "No\n"
|
||||||
result=1
|
result=1
|
||||||
fi
|
fi
|
||||||
|
rm -f docheck.c docheck
|
||||||
rm -f docheck.c docheck.o
|
return $result
|
||||||
echo $result
|
|
||||||
}
|
|
||||||
#}}}
|
|
||||||
#{{{ test_for_inttypes_h
|
|
||||||
test_for_inttypes_h () {
|
|
||||||
cat >docheck.c <<EOF;
|
|
||||||
#include <inttypes.h>
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
${MYCC} ${MYCFLAGS} -c -o docheck.o docheck.c >/dev/null 2>&1
|
|
||||||
if [ $? -eq 0 ]
|
|
||||||
then
|
|
||||||
result=0
|
|
||||||
else
|
|
||||||
result=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -f docheck.c docheck.o
|
|
||||||
echo $result
|
|
||||||
}
|
}
|
||||||
#}}}
|
#}}}
|
||||||
#{{{ usage
|
#{{{ usage
|
||||||
@@ -121,6 +79,8 @@ Configuration:
|
|||||||
Installation directories:
|
Installation directories:
|
||||||
--prefix=PREFIX install architecture-independent files in PREFIX
|
--prefix=PREFIX install architecture-independent files in PREFIX
|
||||||
[/usr/local]
|
[/usr/local]
|
||||||
|
--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
|
||||||
|
[PREFIX]
|
||||||
|
|
||||||
By default, \`make install' will install all the files in
|
By default, \`make install' will install all the files in
|
||||||
\`/usr/local/bin', \`/usr/local/lib' etc. You can specify
|
\`/usr/local/bin', \`/usr/local/lib' etc. You can specify
|
||||||
@@ -128,27 +88,43 @@ an installation prefix other than \`/usr/local' using \`--prefix',
|
|||||||
for instance \`--prefix=$HOME'.
|
for instance \`--prefix=$HOME'.
|
||||||
|
|
||||||
For better control, use the options below.
|
For better control, use the options below.
|
||||||
--disable-readline Don't try to use GNU readline
|
--disable-readline Disable line editing support
|
||||||
|
--without-readline Don't use GNU readline even if it is available
|
||||||
|
--without-editline Don't use editline even if it is available
|
||||||
--readline-dir=DIR Specify parent of readline include and lib directories
|
--readline-dir=DIR Specify parent of readline include and lib directories
|
||||||
--readline-inc-dir=DIR Specify where readline include directory is
|
--readline-inc-dir=DIR Specify where readline include directory is
|
||||||
--readline-lib-dir=DIR Specify where readline lib directory is
|
--readline-lib-dir=DIR Specify where readline lib directory is
|
||||||
--with-ncurses-library=DIR Specify where ncurses lib directory is
|
--with-ncurses-library=DIR Specify where ncurses lib directory is
|
||||||
|
--disable-ipv6 Disable IPv6 support
|
||||||
|
--disable-pps Disable PPS API support
|
||||||
--disable-rtc Don't include RTC even on Linux
|
--disable-rtc Don't include RTC even on Linux
|
||||||
|
--disable-linuxcaps Disable Linux capabilities support
|
||||||
|
|
||||||
Fine tuning of the installation directories:
|
Fine tuning of the installation directories:
|
||||||
--infodir=DIR info documentation [PREFIX/info]
|
--sysconfdir=DIR chrony.conf location [/etc]
|
||||||
--mandir=DIR man documentation [PREFIX/man]
|
--bindir=DIR user executables [EPREFIX/bin]
|
||||||
|
--sbindir=DIR system admin executables [EPREFIX/sbin]
|
||||||
|
--datarootdir=DIR data root [PREFIX/share]
|
||||||
|
--infodir=DIR info documentation [DATAROOTDIR/info]
|
||||||
|
--mandir=DIR man documentation [DATAROOTDIR/man]
|
||||||
|
--docdir=DIR documentation root [DATAROOTDIR/doc/chrony]
|
||||||
|
|
||||||
|
Overriding system detection when cross-compiling:
|
||||||
|
--host-system=OS Specify system name (uname -s)
|
||||||
|
--host-release=REL Specify system release (uname -r)
|
||||||
|
--host-machine=CPU Specify machine (uname -m)
|
||||||
|
|
||||||
Some influential environment variables:
|
Some influential environment variables:
|
||||||
CC C compiler command
|
CC C compiler command
|
||||||
CFLAGS C compiler flags
|
CFLAGS C compiler flags
|
||||||
|
CPPFLAGS C preprocessor flags, e.g. -I<include dir> if you have
|
||||||
|
headers in a nonstandard directory <include dir>
|
||||||
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
|
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
|
||||||
nonstandard directory <lib dir>
|
nonstandard directory <lib dir>
|
||||||
|
|
||||||
Use these variables to override the choices made by \`configure' or to help
|
Use these variables to override the choices made by \`configure' or to help
|
||||||
it to find libraries and programs with nonstandard names/locations.
|
it to find libraries and programs with nonstandard names/locations.
|
||||||
|
|
||||||
Report bugs to <rc@rc0.org.uk>.
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -162,37 +138,42 @@ OPERATINGSYSTEM=`uname -s`
|
|||||||
VERSION=`uname -r`
|
VERSION=`uname -r`
|
||||||
MACHINE=`uname -m`
|
MACHINE=`uname -m`
|
||||||
|
|
||||||
SYSTEM=${OPERATINGSYSTEM}-${MACHINE}
|
|
||||||
|
|
||||||
EXTRA_LIBS=""
|
EXTRA_LIBS=""
|
||||||
EXTRA_CLI_LIBS=""
|
EXTRA_CLI_LIBS=""
|
||||||
EXTRA_OBJECTS=""
|
EXTRA_OBJECTS=""
|
||||||
EXTRA_DEFS=""
|
EXTRA_DEFS=""
|
||||||
INSTALL_PREFIX=/usr/local
|
|
||||||
SYSDEFS=""
|
SYSDEFS=""
|
||||||
|
|
||||||
# Support for readline (on by default)
|
# Support for readline (on by default)
|
||||||
feat_readline=1
|
feat_readline=1
|
||||||
|
try_readline=1
|
||||||
|
try_editline=1
|
||||||
feat_rtc=1
|
feat_rtc=1
|
||||||
|
feat_linuxcaps=1
|
||||||
|
try_linuxcaps=0
|
||||||
readline_lib=""
|
readline_lib=""
|
||||||
readline_inc=""
|
readline_inc=""
|
||||||
ncurses_lib=""
|
ncurses_lib=""
|
||||||
|
feat_ipv6=1
|
||||||
SETINFODIR=""
|
feat_pps=1
|
||||||
SETMANDIR=""
|
try_setsched=0
|
||||||
|
try_lockmem=0
|
||||||
|
|
||||||
for option
|
for option
|
||||||
do
|
do
|
||||||
case "$option" in
|
case "$option" in
|
||||||
--prefix=* | --install_prefix=* )
|
|
||||||
INSTALL_PREFIX=`echo $option | sed -e 's/[^=]*=//;'`
|
|
||||||
;;
|
|
||||||
--trace )
|
--trace )
|
||||||
EXTRA_DEFS="-DTRACEON"
|
EXTRA_DEFS="-DTRACEON"
|
||||||
;;
|
;;
|
||||||
--disable-readline )
|
--disable-readline )
|
||||||
feat_readline=0
|
feat_readline=0
|
||||||
;;
|
;;
|
||||||
|
--without-readline )
|
||||||
|
try_readline=0
|
||||||
|
;;
|
||||||
|
--without-editline )
|
||||||
|
try_editline=0
|
||||||
|
;;
|
||||||
--with-readline-library=* )
|
--with-readline-library=* )
|
||||||
readline_lib=-L`echo $option | sed -e 's/^.*=//;'`
|
readline_lib=-L`echo $option | sed -e 's/^.*=//;'`
|
||||||
;;
|
;;
|
||||||
@@ -202,15 +183,54 @@ do
|
|||||||
--with-ncurses-library=* )
|
--with-ncurses-library=* )
|
||||||
ncurses_lib=-L`echo $option | sed -e 's/^.*=//;'`
|
ncurses_lib=-L`echo $option | sed -e 's/^.*=//;'`
|
||||||
;;
|
;;
|
||||||
|
--prefix=* | --install_prefix=* )
|
||||||
|
SETPREFIX=`echo $option | sed -e 's/[^=]*=//;'`
|
||||||
|
;;
|
||||||
|
--exec-prefix=* )
|
||||||
|
SETEPREFIX=`echo $option | sed -e 's/[^=]*=//;'`
|
||||||
|
;;
|
||||||
|
--sysconfdir=* )
|
||||||
|
SETSYSCONFDIR=`echo $option | sed -e 's/^.*=//;'`
|
||||||
|
;;
|
||||||
|
--bindir=* )
|
||||||
|
SETBINDIR=`echo $option | sed -e 's/^.*=//;'`
|
||||||
|
;;
|
||||||
|
--sbindir=* )
|
||||||
|
SETSBINDIR=`echo $option | sed -e 's/^.*=//;'`
|
||||||
|
;;
|
||||||
|
--datarootdir=* )
|
||||||
|
SETDATAROOTDIR=`echo $option | sed -e 's/^.*=//;'`
|
||||||
|
;;
|
||||||
--infodir=* )
|
--infodir=* )
|
||||||
SETINFODIR=`echo $option | sed -e 's/^.*=//;'`
|
SETINFODIR=`echo $option | sed -e 's/^.*=//;'`
|
||||||
;;
|
;;
|
||||||
--mandir=* )
|
--mandir=* )
|
||||||
SETMANDIR=`echo $option | sed -e 's/^.*=//;'`
|
SETMANDIR=`echo $option | sed -e 's/^.*=//;'`
|
||||||
;;
|
;;
|
||||||
|
--docdir=* )
|
||||||
|
SETDOCDIR=`echo $option | sed -e 's/^.*=//;'`
|
||||||
|
;;
|
||||||
--disable-rtc)
|
--disable-rtc)
|
||||||
feat_rtc=0
|
feat_rtc=0
|
||||||
;;
|
;;
|
||||||
|
--disable-ipv6)
|
||||||
|
feat_ipv6=0
|
||||||
|
;;
|
||||||
|
--disable-pps)
|
||||||
|
feat_pps=0
|
||||||
|
;;
|
||||||
|
--disable-linuxcaps)
|
||||||
|
feat_linuxcaps=0
|
||||||
|
;;
|
||||||
|
--host-system=* )
|
||||||
|
OPERATINGSYSTEM=`echo $option | sed -e 's/^.*=//;'`
|
||||||
|
;;
|
||||||
|
--host-release=* )
|
||||||
|
VERSION=`echo $option | sed -e 's/^.*=//;'`
|
||||||
|
;;
|
||||||
|
--host-machine=* )
|
||||||
|
MACHINE=`echo $option | sed -e 's/^.*=//;'`
|
||||||
|
;;
|
||||||
--help | -h )
|
--help | -h )
|
||||||
usage
|
usage
|
||||||
exit 0
|
exit 0
|
||||||
@@ -220,6 +240,8 @@ do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
|
SYSTEM=${OPERATINGSYSTEM}-${MACHINE}
|
||||||
|
|
||||||
case $SYSTEM in
|
case $SYSTEM in
|
||||||
SunOS-sun4* )
|
SunOS-sun4* )
|
||||||
case $VERSION in
|
case $VERSION in
|
||||||
@@ -245,9 +267,12 @@ case $SYSTEM in
|
|||||||
Linux* )
|
Linux* )
|
||||||
EXTRA_OBJECTS="sys_linux.o wrap_adjtimex.o"
|
EXTRA_OBJECTS="sys_linux.o wrap_adjtimex.o"
|
||||||
if [ $feat_rtc -eq 1 ] ; then
|
if [ $feat_rtc -eq 1 ] ; then
|
||||||
EXTRA_OBJECTS+=" rtc_linux.o"
|
EXTRA_OBJECTS="$EXTRA_OBJECTS rtc_linux.o"
|
||||||
EXTRA_DEFS+=" -DFEAT_RTC=1"
|
EXTRA_DEFS="$EXTRA_DEFS -DFEAT_RTC=1"
|
||||||
fi
|
fi
|
||||||
|
try_linuxcaps=1
|
||||||
|
try_setsched=1
|
||||||
|
try_lockmem=1
|
||||||
SYSDEFS="-DLINUX"
|
SYSDEFS="-DLINUX"
|
||||||
echo "Configuring for " $SYSTEM
|
echo "Configuring for " $SYSTEM
|
||||||
if [ "${MACHINE}" = "alpha" ]; then
|
if [ "${MACHINE}" = "alpha" ]; then
|
||||||
@@ -257,13 +282,13 @@ case $SYSTEM in
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
|
||||||
BSD/386-i[3456]86|FreeBSD-i386 )
|
BSD/386-i[3456]86|FreeBSD-i386|FreeBSD-amd64 )
|
||||||
# Antti Jrvinen <costello@iki.fi> reported that this system can
|
# Antti Jrvinen <costello@iki.fi> reported that this system can
|
||||||
# be supported with the SunOS 4.x driver files.
|
# be supported with the SunOS 4.x driver files.
|
||||||
EXTRA_OBJECTS="sys_sunos.o strerror.o"
|
EXTRA_OBJECTS="sys_sunos.o strerror.o"
|
||||||
EXTRA_LIBS="-lkvm"
|
EXTRA_LIBS="-lkvm"
|
||||||
SYSDEFS="-DSUNOS"
|
SYSDEFS="-DSUNOS"
|
||||||
echo "Configuring for BSD/386 (using SunOS driver)"
|
echo "Configuring for $SYSTEM (using SunOS driver)"
|
||||||
;;
|
;;
|
||||||
NetBSD-* )
|
NetBSD-* )
|
||||||
EXTRA_OBJECTS="sys_netbsd.o"
|
EXTRA_OBJECTS="sys_netbsd.o"
|
||||||
@@ -292,74 +317,165 @@ case $SYSTEM in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
printf "Checking if sqrt() needs -lm : "
|
MATHCODE='return (int) pow(2.0, log(sqrt((double)argc)));'
|
||||||
case `test_for_sqrt`
|
if test_code 'math' 'math.h' '' '' "$MATHCODE"; then
|
||||||
in
|
|
||||||
0)
|
|
||||||
printf "No\n"
|
|
||||||
LIBS=""
|
LIBS=""
|
||||||
;;
|
else
|
||||||
1)
|
if test_code 'math in -lm' 'math.h' '' '-lm' "$MATHCODE"; then
|
||||||
printf "Yes\n"
|
LIBS="-lm"
|
||||||
LIBS="-lm"
|
else
|
||||||
;;
|
printf "Can't compile/link a program which uses sqrt(), log(), pow(), bailing out\n"
|
||||||
*)
|
exit 1
|
||||||
printf "\nCan't compile/link a program which uses sqrt(), bailing out\n"
|
fi
|
||||||
exit 1
|
fi
|
||||||
;;
|
|
||||||
esac
|
if test_code '<stdint.h>' 'stdint.h' '' '' ''; then
|
||||||
|
|
||||||
printf "Checking for <stdint.h> : "
|
|
||||||
if [ `test_for_stdint_h` -eq 0 ]; then
|
|
||||||
printf "Yes\n"
|
|
||||||
SYSDEFS="${SYSDEFS} -DHAS_STDINT_H"
|
SYSDEFS="${SYSDEFS} -DHAS_STDINT_H"
|
||||||
else
|
|
||||||
printf "No\n"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printf "Checking for <inttypes.h> : "
|
if test_code '<inttypes.h>' 'inttypes.h' '' '' ''; then
|
||||||
if [ `test_for_inttypes_h` -eq 0 ]; then
|
|
||||||
printf "Yes\n"
|
|
||||||
SYSDEFS="${SYSDEFS} -DHAS_INTTYPES_H"
|
SYSDEFS="${SYSDEFS} -DHAS_INTTYPES_H"
|
||||||
else
|
|
||||||
printf "No\n"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "x${MYCC}" = "xgcc" ]; then
|
if [ $feat_ipv6 = "1" ] && \
|
||||||
CCWARNFLAGS="-Wmissing-prototypes -Wall"
|
test_code 'IPv6 support' 'arpa/inet.h sys/socket.h netinet/in.h' '' '' '
|
||||||
else
|
struct sockaddr_in6 n;
|
||||||
CCWARNFLAGS=""
|
char p[100];
|
||||||
|
n.sin6_addr = in6addr_any;
|
||||||
|
return !inet_ntop(AF_INET6, &n.sin6_addr.s6_addr, p, sizeof(p));'
|
||||||
|
then
|
||||||
|
SYSDEFS="${SYSDEFS} -DHAVE_IPV6"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ $feat_pps = "1" ] && \
|
||||||
|
test_code 'PPS API' 'timepps.h' '' '' '
|
||||||
|
pps_handle_t h;
|
||||||
|
pps_info_t i;
|
||||||
|
struct timespec ts;
|
||||||
|
return time_pps_fetch(&h, PPS_TSFMT_TSPEC, &i, &ts);'
|
||||||
|
then
|
||||||
|
SYSDEFS="${SYSDEFS} -DHAVE_PPSAPI"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $feat_linuxcaps = "1" ] && [ $try_linuxcaps = "1" ] && \
|
||||||
|
test_code \
|
||||||
|
linuxcaps \
|
||||||
|
'sys/types.h pwd.h sys/prctl.h sys/capability.h grp.h' \
|
||||||
|
'' '-lcap' \
|
||||||
|
'prctl(PR_SET_KEEPCAPS, 1);cap_set_proc(cap_from_text("cap_sys_time=ep"));'
|
||||||
|
then
|
||||||
|
EXTRA_DEFS="${EXTRA_DEFS} -DFEAT_LINUXCAPS=1"
|
||||||
|
EXTRA_LIBS="-lcap"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $try_setsched = "1" ] && \
|
||||||
|
test_code \
|
||||||
|
'sched_setscheduler()' \
|
||||||
|
'sched.h' '' '' '
|
||||||
|
struct sched_param sched;
|
||||||
|
sched_get_priority_max(SCHED_FIFO);
|
||||||
|
sched_setscheduler(0, SCHED_FIFO, &sched);'
|
||||||
|
then
|
||||||
|
SYSDEFS="${SYSDEFS} -DHAVE_SCHED_SETSCHEDULER"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $try_lockmem = "1" ] && \
|
||||||
|
test_code \
|
||||||
|
'mlockall()' \
|
||||||
|
'sys/mman.h sys/resource.h' '' '' '
|
||||||
|
struct rlimit rlim;
|
||||||
|
setrlimit(RLIMIT_MEMLOCK, &rlim);
|
||||||
|
mlockall(MCL_CURRENT|MCL_FUTURE);'
|
||||||
|
then
|
||||||
|
SYSDEFS="${SYSDEFS} -DHAVE_MLOCKALL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
READLINE_COMPILE=""
|
||||||
|
READLINE_LINK=""
|
||||||
if [ $feat_readline = "1" ]; then
|
if [ $feat_readline = "1" ]; then
|
||||||
READLINE_COMPILE="-DFEAT_READLINE=1 $readline_inc"
|
if [ $try_editline = "1" ]; then
|
||||||
READLINE_LINK="$readline_lib $ncurses_lib -lreadline -lncurses"
|
if test_code editline 'stdio.h editline/readline.h' \
|
||||||
else
|
"$readline_inc" "$readline_lib -ledit" \
|
||||||
READLINE_COMPILE=""
|
'add_history(readline("prompt"));'
|
||||||
READLINE_LINK=""
|
then
|
||||||
|
READLINE_COMPILE="-DFEAT_READLINE=1 -DUSE_EDITLINE=1 $readline_inc"
|
||||||
|
READLINE_LINK="$readline_lib -ledit"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "x$READLINE_LINK" = "x" ] && [ $try_readline = "1" ]; then
|
||||||
|
if test_code readline 'stdio.h readline/readline.h readline/history.h' \
|
||||||
|
"$readline_inc" "$readline_lib $ncurses_lib -lreadline -lncurses" \
|
||||||
|
'add_history(readline("prompt"));'
|
||||||
|
then
|
||||||
|
READLINE_COMPILE="-DFEAT_READLINE=1 $readline_inc"
|
||||||
|
READLINE_LINK="$readline_lib $ncurses_lib -lreadline -lncurses"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
MANDIR=${INSTALL_PREFIX}/man
|
SYSCONFDIR=/etc
|
||||||
INFODIR=${INSTALL_PREFIX}/info
|
if [ "x$SETSYSCONFDIR" != "x" ]; then
|
||||||
|
SYSCONFDIR=$SETSYSCONFDIR
|
||||||
|
fi
|
||||||
|
|
||||||
|
PREFIX=/usr/local
|
||||||
|
if [ "x$SETPREFIX" != "x" ]; then
|
||||||
|
PREFIX=$SETPREFIX
|
||||||
|
fi
|
||||||
|
|
||||||
|
EPREFIX=${PREFIX}
|
||||||
|
if [ "x$SETEPREFIX" != "x" ]; then
|
||||||
|
EPREFIX=$SETEPREFIX
|
||||||
|
fi
|
||||||
|
|
||||||
|
BINDIR=${EPREFIX}/bin
|
||||||
|
if [ "x$SETBINDIR" != "x" ]; then
|
||||||
|
BINDIR=$SETBINDIR
|
||||||
|
fi
|
||||||
|
|
||||||
|
SBINDIR=${EPREFIX}/sbin
|
||||||
|
if [ "x$SETSBINDIR" != "x" ]; then
|
||||||
|
SBINDIR=$SETSBINDIR
|
||||||
|
fi
|
||||||
|
|
||||||
|
DATAROOTDIR=${PREFIX}/share
|
||||||
|
if [ "x$SETDATAROOTDIR" != "x" ]; then
|
||||||
|
DATAROOTDIR=$SETDATAROOTDIR
|
||||||
|
fi
|
||||||
|
|
||||||
|
INFODIR=${DATAROOTDIR}/info
|
||||||
if [ "x$SETINFODIR" != "x" ]; then
|
if [ "x$SETINFODIR" != "x" ]; then
|
||||||
INFODIR=$SETINFODIR
|
INFODIR=$SETINFODIR
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
MANDIR=${DATAROOTDIR}/man
|
||||||
if [ "x$SETMANDIR" != "x" ]; then
|
if [ "x$SETMANDIR" != "x" ]; then
|
||||||
MANDIR=$SETMANDIR
|
MANDIR=$SETMANDIR
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
DOCDIR=${DATAROOTDIR}/doc/chrony
|
||||||
|
if [ "x$SETDOCDIR" != "x" ]; then
|
||||||
|
DOCDIR=$SETDOCDIR
|
||||||
|
fi
|
||||||
|
|
||||||
sed -e "s%@EXTRA_OBJECTS@%${EXTRA_OBJECTS}%;\
|
sed -e "s%@EXTRA_OBJECTS@%${EXTRA_OBJECTS}%;\
|
||||||
s%@CC@%${MYCC}%;\
|
s%@CC@%${MYCC}%;\
|
||||||
s%@CFLAGS@%${MYCFLAGS}%;\
|
s%@CFLAGS@%${MYCFLAGS}%;\
|
||||||
s%@CCWARNFLAGS@%${CCWARNFLAGS}%;\
|
s%@CCWARNFLAGS@%${CCWARNFLAGS}%;\
|
||||||
|
s%@CPPFLAGS@%${CPPFLAGS}%;\
|
||||||
s%@LIBS@%${LIBS}%;\
|
s%@LIBS@%${LIBS}%;\
|
||||||
|
s%@LDFLAGS@%${LDFLAGS}%;\
|
||||||
s%@EXTRA_LIBS@%${EXTRA_LIBS}%;\
|
s%@EXTRA_LIBS@%${EXTRA_LIBS}%;\
|
||||||
s%@SYSDEFS@%${SYSDEFS}%;\
|
s%@SYSDEFS@%${SYSDEFS}%;\
|
||||||
s%@EXTRA_DEFS@%${EXTRA_DEFS}%;\
|
s%@EXTRA_DEFS@%${EXTRA_DEFS}%;\
|
||||||
s%@EXTRA_CLI_LIBS@%${EXTRA_CLI_LIBS}%;\
|
s%@EXTRA_CLI_LIBS@%${EXTRA_CLI_LIBS}%;\
|
||||||
s%@READLINE_COMPILE@%${READLINE_COMPILE}%;\
|
s%@READLINE_COMPILE@%${READLINE_COMPILE}%;\
|
||||||
s%@READLINE_LINK@%${READLINE_LINK}%;\
|
s%@READLINE_LINK@%${READLINE_LINK}%;\
|
||||||
s%@INSTALL_PREFIX@%${INSTALL_PREFIX}%;\
|
s%@SYSCONFDIR@%${SYSCONFDIR}%;\
|
||||||
|
s%@BINDIR@%${BINDIR}%;\
|
||||||
|
s%@SBINDIR@%${SBINDIR}%;\
|
||||||
|
s%@DOCDIR@%${DOCDIR}%;\
|
||||||
s%@MANDIR@%${MANDIR}%;\
|
s%@MANDIR@%${MANDIR}%;\
|
||||||
s%@INFODIR@%${INFODIR}%;"\
|
s%@INFODIR@%${INFODIR}%;"\
|
||||||
< Makefile.in > Makefile
|
< Makefile.in > Makefile
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
GNU GENERAL PUBLIC LICENSE
|
||||||
Version 2, June 1991
|
Version 2, June 1991
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
|
|||||||
General Public License applies to most of the Free Software
|
General Public License applies to most of the Free Software
|
||||||
Foundation's software and to any other program whose authors commit to
|
Foundation's software and to any other program whose authors commit to
|
||||||
using it. (Some other Free Software Foundation software is covered by
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
the GNU Library General Public License instead.) You can apply it to
|
the GNU Lesser General Public License instead.) You can apply it to
|
||||||
your programs, too.
|
your programs, too.
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
When we speak of free software, we are referring to freedom, not
|
||||||
@@ -55,7 +55,7 @@ patent must be licensed for everyone's free use or not licensed at all.
|
|||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
The precise terms and conditions for copying, distribution and
|
||||||
modification follow.
|
modification follow.
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
GNU GENERAL PUBLIC LICENSE
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
|
|||||||
License. (Exception: if the Program itself is interactive but
|
License. (Exception: if the Program itself is interactive but
|
||||||
does not normally print such an announcement, your work based on
|
does not normally print such an announcement, your work based on
|
||||||
the Program is not required to print an announcement.)
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
These requirements apply to the modified work as a whole. If
|
||||||
identifiable sections of that work are not derived from the Program,
|
identifiable sections of that work are not derived from the Program,
|
||||||
and can be reasonably considered independent and separate works in
|
and can be reasonably considered independent and separate works in
|
||||||
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
|
|||||||
access to copy the source code from the same place counts as
|
access to copy the source code from the same place counts as
|
||||||
distribution of the source code, even though third parties are not
|
distribution of the source code, even though third parties are not
|
||||||
compelled to copy the source along with the object code.
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
4. You may not copy, modify, sublicense, or distribute the Program
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
except as expressly provided under this License. Any attempt
|
except as expressly provided under this License. Any attempt
|
||||||
otherwise to copy, modify, sublicense or distribute the Program is
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
@@ -225,7 +225,7 @@ impose that choice.
|
|||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
This section is intended to make thoroughly clear what is believed to
|
||||||
be a consequence of the rest of this License.
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
8. If the distribution and/or use of the Program is restricted in
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
original copyright holder who places the Program under this License
|
original copyright holder who places the Program under this License
|
||||||
@@ -278,8 +278,8 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
|||||||
POSSIBILITY OF SUCH DAMAGES.
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
Appendix: How to Apply These Terms to Your New Programs
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
If you develop a new program, and you want it to be of the greatest
|
||||||
possible use to the public, the best way to achieve this is to make it
|
possible use to the public, the best way to achieve this is to make it
|
||||||
@@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
|
|||||||
the "copyright" line and a pointer to where the full notice is found.
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
Copyright (C) 19yy <name of author>
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -303,16 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License along
|
||||||
along with this program; if not, write to the Free Software
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
If the program is interactive, make it output a short notice like this
|
If the program is interactive, make it output a short notice like this
|
||||||
when it starts in an interactive mode:
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
This is free software, and you are welcome to redistribute it
|
This is free software, and you are welcome to redistribute it
|
||||||
under certain conditions; type `show c' for details.
|
under certain conditions; type `show c' for details.
|
||||||
@@ -335,5 +335,5 @@ necessary. Here is a sample; alter the names:
|
|||||||
This General Public License does not permit incorporating your program into
|
This General Public License does not permit incorporating your program into
|
||||||
proprietary programs. If your program is a subroutine library, you may
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
consider it more useful to permit linking proprietary applications with the
|
consider it more useful to permit linking proprietary applications with the
|
||||||
library. If this is what you want to do, use the GNU Library General
|
library. If this is what you want to do, use the GNU Lesser General
|
||||||
Public License instead of this License.
|
Public License instead of this License.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ my($copyrighttext) = <<'EOF';
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
# SEE COPYING FOR DETAILS
|
# SEE COPYING FOR DETAILS
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|||||||
@@ -162,5 +162,5 @@ DNSchrony.pl is covered by the GPL
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
# SEE COPYING FOR DETAILS
|
# SEE COPYING FOR DETAILS
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
#######################################################################
|
#######################################################################
|
||||||
# $Header: /cvs/src/chrony/examples/chrony.conf.example,v 1.2 2002/02/03 21:46:29 richard Exp $
|
|
||||||
#
|
#
|
||||||
# This is an example chrony configuration file. You should copy it to
|
# This is an example chrony configuration file. You should copy it to
|
||||||
# /etc/chrony.conf after uncommenting and editing the options that you
|
# /etc/chrony.conf after uncommenting and editing the options that you
|
||||||
# want to enable. I have not included the more obscure options. Refer
|
# want to enable. The more obscure options are not included. Refer
|
||||||
# to the documentation for these.
|
# to the documentation for these.
|
||||||
#
|
#
|
||||||
# Copyright 2002 Richard P. Curnow
|
# Copyright 2002 Richard P. Curnow
|
||||||
@@ -19,7 +18,7 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License along
|
# 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.,
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
#######################################################################
|
#######################################################################
|
||||||
@@ -157,8 +156,8 @@ commandkey 1
|
|||||||
! logdir /var/log/chrony
|
! logdir /var/log/chrony
|
||||||
! log measurements statistics tracking
|
! log measurements statistics tracking
|
||||||
|
|
||||||
If you have real time clock support enabled (see below), you might want
|
# If you have real time clock support enabled (see below), you might want
|
||||||
this line instead:
|
# this line instead:
|
||||||
|
|
||||||
! log measurements statistics tracking rtc
|
! log measurements statistics tracking rtc
|
||||||
|
|
||||||
@@ -209,6 +208,12 @@ this line instead:
|
|||||||
|
|
||||||
! noclientlog
|
! noclientlog
|
||||||
|
|
||||||
|
# The clientlog size is limited to 512KB by default. If you have many
|
||||||
|
# clients, especially in many different subnets, you might want to
|
||||||
|
# increase the limit.
|
||||||
|
|
||||||
|
! clientloglimit 4194304
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
### REPORTING BIG CLOCK CHANGES
|
### REPORTING BIG CLOCK CHANGES
|
||||||
# Perhaps you want to know if chronyd suddenly detects any large error
|
# Perhaps you want to know if chronyd suddenly detects any large error
|
||||||
@@ -287,3 +292,21 @@ cmdallow 127.0.0.1
|
|||||||
! rtcdevice /dev/misc/rtc
|
! rtcdevice /dev/misc/rtc
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
|
### REAL TIME SCHEDULER
|
||||||
|
# This directive tells chronyd to use the real-time FIFO scheduler with the
|
||||||
|
# specified priority (which must be between 0 and 100). This should result
|
||||||
|
# in reduced latency. You don't need it unless you really have a requirement
|
||||||
|
# for extreme clock stability. Works only on Linux. Note that the "-P"
|
||||||
|
# command-line switch will override this.
|
||||||
|
|
||||||
|
! sched_priority 1
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
### LOCKING CHRONYD INTO RAM
|
||||||
|
# This directive tells chronyd to use the mlockall() syscall to lock itself
|
||||||
|
# into RAM so that it will never be paged out. This should result in reduced
|
||||||
|
# latency. You don't need it unless you really have a requirement
|
||||||
|
# for extreme clock stability. Works only on Linux. Note that the "-m"
|
||||||
|
# command-line switch will also enable this feature.
|
||||||
|
|
||||||
|
! lock_all
|
||||||
|
|||||||
67
faq.txt
67
faq.txt
@@ -19,18 +19,12 @@
|
|||||||
<p>
|
<p>
|
||||||
This is a set of questions and answers to common problems and issues.
|
This is a set of questions and answers to common problems and issues.
|
||||||
<p>
|
<p>
|
||||||
As I receive more emails about the software, I will add new questions
|
As we receive more emails about the software, we will add new questions
|
||||||
to this page.
|
to this page.
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<p>
|
<p>
|
||||||
The author can be reached by email
|
The developers can be reached via the chrony-dev mailing list. See
|
||||||
<a href="mailto:rc@rc0.org.uk">
|
<a href="#question_1.4">question 1.4.</a> for details.
|
||||||
</a>
|
|
||||||
<p>
|
|
||||||
<b>PLEASE</b>
|
|
||||||
include the word "chrony" in your subject line if possible (so that my
|
|
||||||
mail reader can keep my mail sorted by topic)!
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<br clear=all>
|
<br clear=all>
|
||||||
@@ -38,39 +32,34 @@ mail reader can keep my mail sorted by topic)!
|
|||||||
S: Administrative issues
|
S: Administrative issues
|
||||||
|
|
||||||
Q: Where can I get chrony source code?
|
Q: Where can I get chrony source code?
|
||||||
Via the home page, see below.
|
Tarballs are available via the <b>Download</b> link on the Chrony
|
||||||
|
Web site. For the current development from the developers' version control
|
||||||
|
system see the <b>Git</b> link on the Web site.
|
||||||
|
|
||||||
Q: Are there any packaged versions of chrony?
|
Q: Are there any packaged versions of chrony?
|
||||||
I am aware of packages for Debian, Mandrake and Redhat. I am not personally
|
We are aware of packages for Debian, Fedora, Gentoo, Mandriva, Slackware,
|
||||||
involved with how these are built or distributed.
|
and Ubuntu. We are not involved with how these are built or distributed.
|
||||||
|
|
||||||
Q: Where is the home page?
|
Q: Where is the home page?
|
||||||
It is currently at <a href="http://chrony.sunsite.dk/">http://chrony.sunsite.dk/</a>.
|
It is currently at <a href="http://chrony.tuxfamily.org/">http://chrony.tuxfamily.org/</a>.
|
||||||
|
|
||||||
Q: Is there a mailing list?
|
Q: Is there a mailing list?
|
||||||
Yes, it's currently at chrony-users@sunsite.dk. There is a low-volume
|
Yes, it's currently at chrony-users@chrony.tuxfamily.org. There is a low-volume
|
||||||
list called chrony-announce which is just for announcements of new releases or
|
list called chrony-announce which is just for announcements of new releases or
|
||||||
similar matters of high importance. You can join the lists by sending a
|
similar matters of high importance. You can join the lists by sending a
|
||||||
message to <a href="mailto:chrony-users-subscribe@sunsite.dk">chrony-users-subscribe@sunsite.dk</a> or
|
message with the subject subscribe to <a href="mailto:chrony-users-request@chrony.tuxfamily.org">chrony-users-request@chrony.tuxfamily.org</a> or
|
||||||
<a href="mailto:chrony-announce-subscribe@sunsite.dk">chrony-announce-subscribe@sunsite.dk</a> respectively.
|
<a href="mailto:chrony-announce-request@chrony.tuxfamily.org">chrony-announce-request@chrony.tuxfamily.org</a> respectively.
|
||||||
|
|
||||||
For those who want to contribute to the development of chrony, there is a
|
For those who want to contribute to the development of chrony, there is a
|
||||||
developers' mailing list. You can subscribe by sending mail to
|
developers' mailing list. You can subscribe by sending mail with the
|
||||||
<a href="mailto:chrony-dev-subscribe@sunsite.dk">chrony-dev-subscribe@sunsite.dk</a>.
|
subject subscribe to
|
||||||
|
<a href="mailto:chrony-dev-request@chrony.tuxfamily.org">chrony-dev-request@chrony.tuxfamily.org</a>.
|
||||||
|
|
||||||
Q: What licence is applied to chrony?
|
Q: What licence is applied to chrony?
|
||||||
Starting from version 1.15, chrony is licensed under the GNU General Public
|
Starting from version 1.15, chrony is licensed under the GNU General Public
|
||||||
License. Versions prior to 1.15 were licensed under a custom BSD-like
|
License, Version 2. Versions prior to 1.15 were licensed under a custom BSD-like
|
||||||
license.
|
license.
|
||||||
|
|
||||||
If you want to use parts of chrony in non-free software, you will need to use
|
|
||||||
older versions of the source code. Alternatively, contact me - I may be
|
|
||||||
prepared to licence parts of the source code to suit your purposes. I am quite
|
|
||||||
sympathetic to projects licensed under other free/open-source (but non-GPL)
|
|
||||||
licences, as well as to commercial projects which are of a single-customer
|
|
||||||
"turnkey" nature (as opposed to mass-market "shrink-wrap" or "floating-licence"
|
|
||||||
products).
|
|
||||||
|
|
||||||
S: Chrony compared to other programs
|
S: Chrony compared to other programs
|
||||||
Q: How does chrony compare to xntpd?
|
Q: How does chrony compare to xntpd?
|
||||||
If your computer is permenently connected, or connected for long periods (that
|
If your computer is permenently connected, or connected for long periods (that
|
||||||
@@ -109,7 +98,7 @@ added some automated support in chrony to deal with this.
|
|||||||
|
|
||||||
S: Compilation issues
|
S: Compilation issues
|
||||||
Q:How do I apply source patches?
|
Q:How do I apply source patches?
|
||||||
Sometimes I release source patches rather than a full version when I need to
|
Sometimes we release source patches rather than a full version when we need to
|
||||||
provide a fix for small problems. Supposing you have chrony-1.X.tar.gz and a
|
provide a fix for small problems. Supposing you have chrony-1.X.tar.gz and a
|
||||||
source patch chrony-1.X-1.X.1.gz. The steps required are:
|
source patch chrony-1.X-1.X.1.gz. The steps required are:
|
||||||
|
|
||||||
@@ -221,12 +210,6 @@ files when chrony was compiled. The chrony.conf file can include options to
|
|||||||
modify the HZ value (see the discussion of linux_hz and linux_freq_scale in the
|
modify the HZ value (see the discussion of linux_hz and linux_freq_scale in the
|
||||||
documentation), however the problem is to find the value of HZ being used.
|
documentation), however the problem is to find the value of HZ being used.
|
||||||
|
|
||||||
At the end of the chrony v1.18 section of the <a href="./download.php">download page</a>
|
|
||||||
you'll find instructions on how to do this.
|
|
||||||
|
|
||||||
This will be fixed in version 1.19, by getting chronyd to auto-detect the
|
|
||||||
kernel's value rather than relying on the compiled-in default.
|
|
||||||
|
|
||||||
S: Issues with chronyc
|
S: Issues with chronyc
|
||||||
|
|
||||||
Q: I keep getting the error '510 No command access from this host --- Reply not authenticated'.
|
Q: I keep getting the error '510 No command access from this host --- Reply not authenticated'.
|
||||||
@@ -303,13 +286,11 @@ system-dependent. It needs adapting to work with Windows' equivalent of the
|
|||||||
adjtimex() call, and it needs to be made to work as an NT service.
|
adjtimex() call, and it needs to be made to work as an NT service.
|
||||||
|
|
||||||
Q: Are there any plans to support Windows?
|
Q: Are there any plans to support Windows?
|
||||||
I have no personal plans to do this. I have neither the time nor the
|
We have no plans to do this. Anyone is welcome to pick this work up and
|
||||||
Windows programming expertise. Some time ago I did start work on a port which
|
|
||||||
I was developing under Cygwin. Anyone is welcome to pick this work up and
|
|
||||||
contribute it back to the project.
|
contribute it back to the project.
|
||||||
|
|
||||||
Q: What alternative NTP clients are there for Windows?
|
Q: What alternative NTP clients are there for Windows?
|
||||||
Some of the names I've seen mentioned are
|
Some of the names we've seen mentioned are
|
||||||
- Automachron
|
- Automachron
|
||||||
- NetTime (nettime.sourceforge.net)
|
- NetTime (nettime.sourceforge.net)
|
||||||
|
|
||||||
@@ -345,12 +326,10 @@ useful to avoid this situation.
|
|||||||
|
|
||||||
S: Development
|
S: Development
|
||||||
|
|
||||||
Q: Can I get the source via CVS from anywhere?
|
Q: Can I get the source via git from anywhere?
|
||||||
Yes. See <a href="http://chrony.sunsite.dk/cvs.php">http://chrony.sunsite.dk/cvs.php</a> for information. Currently there is
|
Yes. See the Git link at <a
|
||||||
only anonymous read-only access. I keep the master copy on my own PC, which is
|
href="http://chrony.tuxfamily.org/">http://chrony.tuxfamily.org</a> for
|
||||||
more convenient for me because I don't have to connect to the Internet to do
|
information.
|
||||||
CVS operations on the files. So for now, there is no read-write access for
|
|
||||||
other developers. Please email me your patches + documentation instead.
|
|
||||||
|
|
||||||
S: Linux-specific issues
|
S: Linux-specific issues
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
/* Modified from the original to add stdlib.h and string.h */
|
/* Modified from the original to add stdlib.h and string.h */
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
|
|
||||||
/* Hmm. These constants vary a bit between systems. */
|
/* Hmm. These constants vary a bit between systems. */
|
||||||
/* (__sh__ includes both sh and sh64) */
|
/* (__sh__ includes both sh and sh64) */
|
||||||
#if defined(__i386__) || defined(__sh__) || defined(__arm__)
|
/* (__s390__ includes both s390 and s390x) */
|
||||||
|
#if defined(__i386__) || defined(__sh__) || defined(__arm__) || defined(__x86_64__) || defined(__s390__)
|
||||||
#define CHRONY_IOC_NRBITS 8
|
#define CHRONY_IOC_NRBITS 8
|
||||||
#define CHRONY_IOC_TYPEBITS 8
|
#define CHRONY_IOC_TYPEBITS 8
|
||||||
#define CHRONY_IOC_SIZEBITS 14
|
#define CHRONY_IOC_SIZEBITS 14
|
||||||
@@ -26,7 +27,7 @@
|
|||||||
#define CHRONY_IOC_READ 2U
|
#define CHRONY_IOC_READ 2U
|
||||||
#define CHRONY_IOC_WRITE 4U
|
#define CHRONY_IOC_WRITE 4U
|
||||||
|
|
||||||
#elif defined(__mips__) || defined(__mips32__)
|
#elif defined(__mips__) || defined(__mips32__) || defined(__powerpc__)
|
||||||
#define CHRONY_IOC_NRBITS 8
|
#define CHRONY_IOC_NRBITS 8
|
||||||
#define CHRONY_IOC_TYPEBITS 8
|
#define CHRONY_IOC_TYPEBITS 8
|
||||||
#define CHRONY_IOC_SIZEBITS 13
|
#define CHRONY_IOC_SIZEBITS 13
|
||||||
|
|||||||
2
keys.c
2
keys.c
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
2
keys.h
2
keys.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
19
local.c
19
local.c
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -54,6 +54,7 @@ static lcl_AccrueOffsetDriver drv_accrue_offset;
|
|||||||
static lcl_ApplyStepOffsetDriver drv_apply_step_offset;
|
static lcl_ApplyStepOffsetDriver drv_apply_step_offset;
|
||||||
static lcl_OffsetCorrectionDriver drv_offset_convert;
|
static lcl_OffsetCorrectionDriver drv_offset_convert;
|
||||||
static lcl_ImmediateStepDriver drv_immediate_step;
|
static lcl_ImmediateStepDriver drv_immediate_step;
|
||||||
|
static lcl_SetLeapDriver drv_set_leap;
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
@@ -535,7 +536,8 @@ lcl_RegisterSystemDrivers(lcl_ReadFrequencyDriver read_freq,
|
|||||||
lcl_AccrueOffsetDriver accrue_offset,
|
lcl_AccrueOffsetDriver accrue_offset,
|
||||||
lcl_ApplyStepOffsetDriver apply_step_offset,
|
lcl_ApplyStepOffsetDriver apply_step_offset,
|
||||||
lcl_OffsetCorrectionDriver offset_convert,
|
lcl_OffsetCorrectionDriver offset_convert,
|
||||||
lcl_ImmediateStepDriver immediate_step)
|
lcl_ImmediateStepDriver immediate_step,
|
||||||
|
lcl_SetLeapDriver set_leap)
|
||||||
{
|
{
|
||||||
drv_read_freq = read_freq;
|
drv_read_freq = read_freq;
|
||||||
drv_set_freq = set_freq;
|
drv_set_freq = set_freq;
|
||||||
@@ -543,6 +545,7 @@ lcl_RegisterSystemDrivers(lcl_ReadFrequencyDriver read_freq,
|
|||||||
drv_apply_step_offset = apply_step_offset;
|
drv_apply_step_offset = apply_step_offset;
|
||||||
drv_offset_convert = offset_convert;
|
drv_offset_convert = offset_convert;
|
||||||
drv_immediate_step = immediate_step;
|
drv_immediate_step = immediate_step;
|
||||||
|
drv_set_leap = set_leap;
|
||||||
|
|
||||||
current_freq_ppm = (*drv_read_freq)();
|
current_freq_ppm = (*drv_read_freq)();
|
||||||
|
|
||||||
@@ -572,3 +575,15 @@ LCL_MakeStep(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
void
|
||||||
|
LCL_SetLeap(int leap)
|
||||||
|
{
|
||||||
|
if (drv_set_leap) {
|
||||||
|
(drv_set_leap)(leap);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|||||||
7
local.h
7
local.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -181,4 +181,9 @@ extern void LCL_Finalise(void);
|
|||||||
to a timezone problem. */
|
to a timezone problem. */
|
||||||
extern int LCL_MakeStep(void);
|
extern int LCL_MakeStep(void);
|
||||||
|
|
||||||
|
/* Routine to schedule a leap second. Leap second will be inserted
|
||||||
|
at the end of the day if argument is positive, deleted if negative,
|
||||||
|
and zero cancels scheduled leap second. */
|
||||||
|
extern void LCL_SetLeap(int leap);
|
||||||
|
|
||||||
#endif /* GOT_LOCAL_H */
|
#endif /* GOT_LOCAL_H */
|
||||||
|
|||||||
8
localp.h
8
localp.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -60,6 +60,9 @@ typedef void (*lcl_OffsetCorrectionDriver)(struct timeval *raw, double *corr);
|
|||||||
as an immediate step instead */
|
as an immediate step instead */
|
||||||
typedef void (*lcl_ImmediateStepDriver)(void);
|
typedef void (*lcl_ImmediateStepDriver)(void);
|
||||||
|
|
||||||
|
/* System driver to schedule leap second */
|
||||||
|
typedef void (*lcl_SetLeapDriver)(int leap);
|
||||||
|
|
||||||
extern void lcl_InvokeDispersionNotifyHandlers(double dispersion);
|
extern void lcl_InvokeDispersionNotifyHandlers(double dispersion);
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
@@ -68,6 +71,7 @@ lcl_RegisterSystemDrivers(lcl_ReadFrequencyDriver read_freq,
|
|||||||
lcl_AccrueOffsetDriver accrue_offset,
|
lcl_AccrueOffsetDriver accrue_offset,
|
||||||
lcl_ApplyStepOffsetDriver apply_step_offset,
|
lcl_ApplyStepOffsetDriver apply_step_offset,
|
||||||
lcl_OffsetCorrectionDriver offset_convert,
|
lcl_OffsetCorrectionDriver offset_convert,
|
||||||
lcl_ImmediateStepDriver immediate_step_driver);
|
lcl_ImmediateStepDriver immediate_step_driver,
|
||||||
|
lcl_SetLeapDriver set_leap);
|
||||||
|
|
||||||
#endif /* GOT_LOCALP_H */
|
#endif /* GOT_LOCALP_H */
|
||||||
|
|||||||
18
logging.c
18
logging.c
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -214,3 +214,19 @@ LOG_GoDaemon(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
/* Force a core dump and exit without doing abort() or assert(0).
|
||||||
|
These do funny things with the call stack in the core file that is
|
||||||
|
generated, which makes diagnosis difficult. */
|
||||||
|
|
||||||
|
int
|
||||||
|
croak(const char *file, int line, const char *msg)
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
LOG(LOGS_ERR, LOGF_Util, "Unexpected condition [%s] at %s:%d, core dumped",
|
||||||
|
msg, file, line);
|
||||||
|
a = * (int *) 0;
|
||||||
|
return a; /* Can't happen - this stops the optimiser optimising the
|
||||||
|
line above */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|||||||
16
logging.h
16
logging.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -53,6 +53,7 @@ typedef enum {
|
|||||||
LOGF_Local,
|
LOGF_Local,
|
||||||
LOGF_Util,
|
LOGF_Util,
|
||||||
LOGF_Main,
|
LOGF_Main,
|
||||||
|
LOGF_ClientLog,
|
||||||
LOGF_Configure,
|
LOGF_Configure,
|
||||||
LOGF_CmdMon,
|
LOGF_CmdMon,
|
||||||
LOGF_Acquire,
|
LOGF_Acquire,
|
||||||
@@ -60,11 +61,13 @@ typedef enum {
|
|||||||
LOGF_Logging,
|
LOGF_Logging,
|
||||||
LOGF_Rtc,
|
LOGF_Rtc,
|
||||||
LOGF_Regress,
|
LOGF_Regress,
|
||||||
|
LOGF_Sys,
|
||||||
LOGF_SysLinux,
|
LOGF_SysLinux,
|
||||||
LOGF_SysSolaris,
|
LOGF_SysSolaris,
|
||||||
LOGF_SysSunOS,
|
LOGF_SysSunOS,
|
||||||
LOGF_SysWinnt,
|
LOGF_SysWinnt,
|
||||||
LOGF_RtcLinux
|
LOGF_RtcLinux,
|
||||||
|
LOGF_Refclock
|
||||||
} LOG_Facility;
|
} LOG_Facility;
|
||||||
|
|
||||||
/* Init function */
|
/* Init function */
|
||||||
@@ -94,4 +97,13 @@ extern void LOG_GoDaemon(void);
|
|||||||
#define LOG_FATAL LOG_Position(__FILE__, __LINE__, ""); LOG_Fatal_Function
|
#define LOG_FATAL LOG_Position(__FILE__, __LINE__, ""); LOG_Fatal_Function
|
||||||
#endif /* defined (__GNUC__) */
|
#endif /* defined (__GNUC__) */
|
||||||
|
|
||||||
|
/* Like assert(0) */
|
||||||
|
|
||||||
|
#if defined(LINUX) && defined(__alpha__)
|
||||||
|
#define CROAK(message) assert(0) /* Added JGH Feb 24 2001 FIXME */
|
||||||
|
#else
|
||||||
|
extern int croak(const char *file, int line, const char *msg);
|
||||||
|
#define CROAK(message) croak(__FILE__, __LINE__, message);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* GOT_LOGGING_H */
|
#endif /* GOT_LOGGING_H */
|
||||||
|
|||||||
60
main.c
60
main.c
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
* Copyright (C) Richard P. Curnow 1997-2003
|
* Copyright (C) Richard P. Curnow 1997-2003
|
||||||
|
* Copyright (C) John G. Hasler 2009
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of version 2 of the GNU General Public License as
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
@@ -19,7 +20,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -48,8 +49,10 @@
|
|||||||
#include "manual.h"
|
#include "manual.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "rtc.h"
|
#include "rtc.h"
|
||||||
|
#include "refclock.h"
|
||||||
#include "clientlog.h"
|
#include "clientlog.h"
|
||||||
#include "broadcast.h"
|
#include "broadcast.h"
|
||||||
|
#include "nameserv.h"
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
@@ -83,19 +86,20 @@ MAI_CleanupAndExit(void)
|
|||||||
SRC_DumpSources();
|
SRC_DumpSources();
|
||||||
}
|
}
|
||||||
|
|
||||||
RTC_Finalise();
|
|
||||||
MNL_Finalise();
|
MNL_Finalise();
|
||||||
ACQ_Finalise();
|
ACQ_Finalise();
|
||||||
CAM_Finalise();
|
|
||||||
KEY_Finalise();
|
KEY_Finalise();
|
||||||
CLG_Finalise();
|
CLG_Finalise();
|
||||||
NIO_Finalise();
|
|
||||||
NSR_Finalise();
|
NSR_Finalise();
|
||||||
NCR_Finalise();
|
NCR_Finalise();
|
||||||
BRD_Finalise();
|
BRD_Finalise();
|
||||||
SRC_Finalise();
|
SRC_Finalise();
|
||||||
SST_Finalise();
|
SST_Finalise();
|
||||||
REF_Finalise();
|
REF_Finalise();
|
||||||
|
RCL_Finalise();
|
||||||
|
RTC_Finalise();
|
||||||
|
CAM_Finalise();
|
||||||
|
NIO_Finalise();
|
||||||
SYS_Finalise();
|
SYS_Finalise();
|
||||||
SCH_Finalise();
|
SCH_Finalise();
|
||||||
LCL_Finalise();
|
LCL_Finalise();
|
||||||
@@ -113,7 +117,8 @@ static void
|
|||||||
signal_cleanup(int x)
|
signal_cleanup(int x)
|
||||||
{
|
{
|
||||||
LOG(LOGS_WARN, LOGF_Main, "chronyd exiting on signal");
|
LOG(LOGS_WARN, LOGF_Main, "chronyd exiting on signal");
|
||||||
MAI_CleanupAndExit();
|
if (!initialised) exit(0);
|
||||||
|
SCH_QuitProgram();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -134,6 +139,7 @@ post_acquire_hook(void *anything)
|
|||||||
CNF_SetupAccessRestrictions();
|
CNF_SetupAccessRestrictions();
|
||||||
|
|
||||||
RTC_StartMeasurements();
|
RTC_StartMeasurements();
|
||||||
|
RCL_StartRefclocks();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -206,9 +212,11 @@ int main
|
|||||||
(int argc, char **argv)
|
(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char *conf_file = NULL;
|
char *conf_file = NULL;
|
||||||
|
char *user = NULL;
|
||||||
int debug = 0;
|
int debug = 0;
|
||||||
int do_init_rtc = 0;
|
int do_init_rtc = 0;
|
||||||
int other_pid;
|
int other_pid;
|
||||||
|
int lock_memory = 0, sched_priority = 0;
|
||||||
|
|
||||||
LOG_Initialise();
|
LOG_Initialise();
|
||||||
|
|
||||||
@@ -218,8 +226,22 @@ int main
|
|||||||
if (!strcmp("-f", *argv)) {
|
if (!strcmp("-f", *argv)) {
|
||||||
++argv, --argc;
|
++argv, --argc;
|
||||||
conf_file = *argv;
|
conf_file = *argv;
|
||||||
|
} else if (!strcmp("-P", *argv)) {
|
||||||
|
++argv, --argc;
|
||||||
|
if (argc == 0 || sscanf(*argv, "%d", &sched_priority) != 1) {
|
||||||
|
LOG_FATAL(LOGF_Main, "Bad scheduler priority");
|
||||||
|
}
|
||||||
|
} else if (!strcmp("-m", *argv)) {
|
||||||
|
lock_memory = 1;
|
||||||
} else if (!strcmp("-r", *argv)) {
|
} else if (!strcmp("-r", *argv)) {
|
||||||
reload = 1;
|
reload = 1;
|
||||||
|
} else if (!strcmp("-u", *argv)) {
|
||||||
|
++argv, --argc;
|
||||||
|
if (argc == 0) {
|
||||||
|
LOG_FATAL(LOGF_Main, "Missing user name");
|
||||||
|
} else {
|
||||||
|
user = *argv;
|
||||||
|
}
|
||||||
} else if (!strcmp("-s", *argv)) {
|
} else if (!strcmp("-s", *argv)) {
|
||||||
do_init_rtc = 1;
|
do_init_rtc = 1;
|
||||||
} else if (!strcmp("-v", *argv) || !strcmp("--version",*argv)) {
|
} else if (!strcmp("-v", *argv) || !strcmp("--version",*argv)) {
|
||||||
@@ -228,6 +250,10 @@ int main
|
|||||||
exit(0);
|
exit(0);
|
||||||
} else if (!strcmp("-d", *argv)) {
|
} else if (!strcmp("-d", *argv)) {
|
||||||
debug = 1;
|
debug = 1;
|
||||||
|
} else if (!strcmp("-4", *argv)) {
|
||||||
|
DNS_SetAddressFamily(IPADDR_INET4);
|
||||||
|
} else if (!strcmp("-6", *argv)) {
|
||||||
|
DNS_SetAddressFamily(IPADDR_INET6);
|
||||||
} else {
|
} else {
|
||||||
LOG(LOGS_WARN, LOGF_Main, "Unrecognized command line option [%s]", *argv);
|
LOG(LOGS_WARN, LOGF_Main, "Unrecognized command line option [%s]", *argv);
|
||||||
}
|
}
|
||||||
@@ -269,19 +295,37 @@ int main
|
|||||||
LCL_Initialise();
|
LCL_Initialise();
|
||||||
SCH_Initialise();
|
SCH_Initialise();
|
||||||
SYS_Initialise();
|
SYS_Initialise();
|
||||||
|
NIO_Initialise();
|
||||||
|
CAM_Initialise();
|
||||||
|
RTC_Initialise();
|
||||||
|
RCL_Initialise();
|
||||||
|
|
||||||
|
/* Command-line switch must have priority */
|
||||||
|
if (!sched_priority) {
|
||||||
|
sched_priority = CNF_GetSchedPriority();
|
||||||
|
}
|
||||||
|
if (sched_priority) {
|
||||||
|
SYS_SetScheduler(sched_priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lock_memory || CNF_GetLockMemory()) {
|
||||||
|
SYS_LockMemory();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
SYS_DropRoot(user);
|
||||||
|
}
|
||||||
|
|
||||||
REF_Initialise();
|
REF_Initialise();
|
||||||
SST_Initialise();
|
SST_Initialise();
|
||||||
SRC_Initialise();
|
SRC_Initialise();
|
||||||
BRD_Initialise();
|
BRD_Initialise();
|
||||||
NCR_Initialise();
|
NCR_Initialise();
|
||||||
NSR_Initialise();
|
NSR_Initialise();
|
||||||
NIO_Initialise();
|
|
||||||
CLG_Initialise();
|
CLG_Initialise();
|
||||||
KEY_Initialise();
|
KEY_Initialise();
|
||||||
CAM_Initialise();
|
|
||||||
ACQ_Initialise();
|
ACQ_Initialise();
|
||||||
MNL_Initialise();
|
MNL_Initialise();
|
||||||
RTC_Initialise();
|
|
||||||
|
|
||||||
/* From now on, it is safe to do finalisation on exit */
|
/* From now on, it is safe to do finalisation on exit */
|
||||||
initialised = 1;
|
initialised = 1;
|
||||||
|
|||||||
2
main.h
2
main.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ unless (-d "RELEASES") {
|
|||||||
mkdir "RELEASES", 0755;
|
mkdir "RELEASES", 0755;
|
||||||
}
|
}
|
||||||
|
|
||||||
system ("git-tag -s $version");
|
system ("git tag -s $version");
|
||||||
die "git-tag failed" if ($? != 0);
|
die "git-tag failed" if ($? != 0);
|
||||||
if (-d "RELEASES/$subdir") {
|
if (-d "RELEASES/$subdir") {
|
||||||
system ("rm -rf RELEASES/$subdir");
|
system ("rm -rf RELEASES/$subdir");
|
||||||
}
|
}
|
||||||
|
|
||||||
system ("git-archive --format=tar --prefix=RELEASES/${subdir}/ $version | tar xf -");
|
system ("git archive --format=tar --prefix=RELEASES/${subdir}/ $version | tar xf -");
|
||||||
die "git-tar-tree failed" if ($? != 0);
|
die "git-tar-tree failed" if ($? != 0);
|
||||||
|
|
||||||
chdir "RELEASES";
|
chdir "RELEASES";
|
||||||
|
|||||||
4
manual.c
4
manual.c
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -287,7 +287,7 @@ MNL_ReportSamples(RPT_ManualSamplesReport *report, int max, int *n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<n_samples && i<max; i++) {
|
for (i=0; i<n_samples && i<max; i++) {
|
||||||
report[i].when = samples[i].when.tv_sec;
|
report[i].when = samples[i].when;
|
||||||
report[i].slewed_offset = samples[i].offset;
|
report[i].slewed_offset = samples[i].offset;
|
||||||
report[i].orig_offset = samples[i].orig_offset;
|
report[i].orig_offset = samples[i].orig_offset;
|
||||||
report[i].residual = samples[i].residual;
|
report[i].residual = samples[i].residual;
|
||||||
|
|||||||
2
manual.h
2
manual.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
2
memory.h
2
memory.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
177
nameserv.c
177
nameserv.c
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
* Copyright (C) Richard P. Curnow 1997-2003
|
* Copyright (C) Richard P. Curnow 1997-2003
|
||||||
|
* Copyright (C) Miroslav Lichvar 2009
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of version 2 of the GNU General Public License as
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
@@ -19,7 +20,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -32,60 +33,146 @@
|
|||||||
#include "sysincl.h"
|
#include "sysincl.h"
|
||||||
|
|
||||||
#include "nameserv.h"
|
#include "nameserv.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include <resolv.h>
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
unsigned long
|
#define MAXRETRIES 10
|
||||||
DNS_Name2IPAddress(const char *name)
|
static unsigned int retries = 0;
|
||||||
|
|
||||||
|
static int address_family = IPADDR_UNSPEC;
|
||||||
|
|
||||||
|
void
|
||||||
|
DNS_SetAddressFamily(int family)
|
||||||
{
|
{
|
||||||
struct hostent *host;
|
address_family = family;
|
||||||
unsigned char *address0;
|
|
||||||
unsigned long result;
|
|
||||||
|
|
||||||
host = gethostbyname(name);
|
|
||||||
if (host == NULL) {
|
|
||||||
result = DNS_Failed_Address;
|
|
||||||
} else {
|
|
||||||
address0 = host->h_addr_list[0];
|
|
||||||
result = ((((unsigned long)address0[0])<<24) |
|
|
||||||
(((unsigned long)address0[1])<<16) |
|
|
||||||
(((unsigned long)address0[2])<<8) |
|
|
||||||
(((unsigned long)address0[3])));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
int
|
||||||
|
DNS_Name2IPAddress(const char *name, IPAddr *addr, int retry)
|
||||||
const char *
|
|
||||||
DNS_IPAddress2Name(unsigned long ip_addr)
|
|
||||||
{
|
{
|
||||||
struct hostent *host;
|
#ifdef HAVE_IPV6
|
||||||
static char buffer[16];
|
struct addrinfo hints, *res, *ai;
|
||||||
unsigned int a, b, c, d;
|
int result;
|
||||||
unsigned long addr;
|
|
||||||
|
memset(&hints, 0, sizeof (hints));
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
#ifdef AI_ADDRCONFIG
|
||||||
|
hints.ai_flags = AI_ADDRCONFIG;
|
||||||
|
#endif
|
||||||
|
|
||||||
addr = htonl(ip_addr);
|
try_again:
|
||||||
if (addr == 0UL) {
|
result = getaddrinfo(name, NULL, &hints, &res);
|
||||||
/* Catch this as a special case that will never resolve to
|
|
||||||
anything */
|
if (result) {
|
||||||
strcpy(buffer, "0.0.0.0");
|
if (retry && result == EAI_AGAIN && retries < MAXRETRIES) {
|
||||||
return buffer;
|
sleep(2 << retries);
|
||||||
} else {
|
retries++;
|
||||||
host = gethostbyaddr((const char *) &addr, sizeof(ip_addr), AF_INET);
|
res_init();
|
||||||
if (!host) {
|
goto try_again;
|
||||||
a = (ip_addr >> 24) & 0xff;
|
|
||||||
b = (ip_addr >> 16) & 0xff;
|
|
||||||
c = (ip_addr >> 8) & 0xff;
|
|
||||||
d = (ip_addr) & 0xff;
|
|
||||||
snprintf(buffer, sizeof(buffer), "%u.%u.%u.%u", a, b, c, d);
|
|
||||||
return buffer;
|
|
||||||
} else {
|
|
||||||
return host->h_name;
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (ai = res; !result && ai != NULL; ai = ai->ai_next) {
|
||||||
|
switch (ai->ai_family) {
|
||||||
|
case AF_INET:
|
||||||
|
addr->family = IPADDR_INET4;
|
||||||
|
addr->addr.in4 = ntohl(((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr);
|
||||||
|
result = 1;
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
case AF_INET6:
|
||||||
|
addr->family = IPADDR_INET6;
|
||||||
|
memcpy(&addr->addr.in6, &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr.s6_addr, sizeof (addr->addr.in6));
|
||||||
|
result = 1;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (result && address_family != IPADDR_UNSPEC && address_family != addr->family)
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
freeaddrinfo(res);
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
|
struct hostent *host;
|
||||||
|
char *address0;
|
||||||
|
|
||||||
|
try_again:
|
||||||
|
host = gethostbyname(name);
|
||||||
|
|
||||||
|
if (host == NULL) {
|
||||||
|
if (retry && h_errno == TRY_AGAIN && retries < MAXRETRIES) {
|
||||||
|
sleep(2 << retries);
|
||||||
|
retries++;
|
||||||
|
res_init();
|
||||||
|
goto try_again;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
addr->family = IPADDR_INET4;
|
||||||
|
address0 = host->h_addr_list[0];
|
||||||
|
addr->addr.in4 = ((((unsigned long)address0[0])<<24) |
|
||||||
|
(((unsigned long)address0[1])<<16) |
|
||||||
|
(((unsigned long)address0[2])<<8) |
|
||||||
|
(((unsigned long)address0[3])));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
void
|
||||||
|
DNS_IPAddress2Name(IPAddr *ip_addr, char *name, int len)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
int result;
|
||||||
|
struct sockaddr_in in4;
|
||||||
|
struct sockaddr_in6 in6;
|
||||||
|
|
||||||
|
switch (ip_addr->family) {
|
||||||
|
case IPADDR_INET4:
|
||||||
|
memset(&in4, 0, sizeof (in4));
|
||||||
|
in4.sin_family = AF_INET;
|
||||||
|
in4.sin_addr.s_addr = htonl(ip_addr->addr.in4);
|
||||||
|
result = getnameinfo((const struct sockaddr *)&in4, sizeof (in4), name, len, NULL, 0, 0);
|
||||||
|
break;
|
||||||
|
case IPADDR_INET6:
|
||||||
|
memset(&in6, 0, sizeof (in6));
|
||||||
|
in6.sin6_family = AF_INET6;
|
||||||
|
memcpy(&in6.sin6_addr.s6_addr, ip_addr->addr.in6, sizeof (in6.sin6_addr.s6_addr));
|
||||||
|
result = getnameinfo((const struct sockaddr *)&in6, sizeof (in6), name, len, NULL, 0, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
snprintf(name, len, "%s", UTI_IPToString(ip_addr));
|
||||||
|
#else
|
||||||
|
struct hostent *host;
|
||||||
|
uint32_t addr;
|
||||||
|
|
||||||
|
switch (ip_addr->family) {
|
||||||
|
case IPADDR_INET4:
|
||||||
|
addr = htonl(ip_addr->addr.in4);
|
||||||
|
host = gethostbyaddr((const char *) &addr, sizeof (ip_addr), AF_INET);
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
case IPADDR_INET6:
|
||||||
|
host = gethostbyaddr((const void *) ip_addr->addr.in6, sizeof (ip_addr->addr.in6), AF_INET6);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
host = NULL;
|
||||||
|
}
|
||||||
|
snprintf(name, len, "%s", host ? host->h_name : UTI_IPToString(ip_addr));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|||||||
11
nameserv.h
11
nameserv.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -32,11 +32,14 @@
|
|||||||
#ifndef GOT_NAMESERV_H
|
#ifndef GOT_NAMESERV_H
|
||||||
#define GOT_NAMESERV_H
|
#define GOT_NAMESERV_H
|
||||||
|
|
||||||
static const unsigned long DNS_Failed_Address = 0x0UL;
|
#include "addressing.h"
|
||||||
|
|
||||||
extern unsigned long DNS_Name2IPAddress(const char *name);
|
/* Resolve names only to selected address family */
|
||||||
|
extern void DNS_SetAddressFamily(int family);
|
||||||
|
|
||||||
const char *DNS_IPAddress2Name(unsigned long ip_addr);
|
extern int DNS_Name2IPAddress(const char *name, IPAddr *addr, int retry);
|
||||||
|
|
||||||
|
extern void DNS_IPAddress2Name(IPAddr *ip_addr, char *name, int len);
|
||||||
|
|
||||||
#endif /* GOT_NAMESERV_H */
|
#endif /* GOT_NAMESERV_H */
|
||||||
|
|
||||||
|
|||||||
2
ntp.h
2
ntp.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
101
ntp_core.c
101
ntp_core.c
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
* Copyright (C) Richard P. Curnow 1997-2003
|
* Copyright (C) Richard P. Curnow 1997-2003
|
||||||
|
* Copyright (C) Miroslav Lichvar 2009
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of version 2 of the GNU General Public License as
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
@@ -19,7 +20,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -300,6 +301,9 @@ create_instance(NTP_Remote_Address *remote_addr, NTP_Mode mode, SourceParameters
|
|||||||
|
|
||||||
result->tx_count = 0;
|
result->tx_count = 0;
|
||||||
|
|
||||||
|
result->remote_orig.hi = 0;
|
||||||
|
result->remote_orig.lo = 0;
|
||||||
|
|
||||||
result->score = 0;
|
result->score = 0;
|
||||||
|
|
||||||
if (params->online) {
|
if (params->online) {
|
||||||
@@ -316,10 +320,12 @@ create_instance(NTP_Remote_Address *remote_addr, NTP_Mode mode, SourceParameters
|
|||||||
result->local_poll = params->minpoll;
|
result->local_poll = params->minpoll;
|
||||||
|
|
||||||
/* Create a source instance for this NTP source */
|
/* Create a source instance for this NTP source */
|
||||||
result->source = SRC_CreateNewInstance(remote_addr->ip_addr); /* Will need extra params eventually */
|
result->source = SRC_CreateNewInstance(UTI_IPToRefid(&remote_addr->ip_addr), SRC_NTP, &result->remote_addr.ip_addr);
|
||||||
|
|
||||||
result->local_rx.tv_sec = 0;
|
result->local_rx.tv_sec = 0;
|
||||||
result->local_rx.tv_usec = 0;
|
result->local_rx.tv_usec = 0;
|
||||||
|
result->local_tx.tv_sec = 0;
|
||||||
|
result->local_tx.tv_usec = 0;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@@ -621,7 +627,7 @@ transmit_timeout(void *arg)
|
|||||||
|
|
||||||
#ifdef TRACEON
|
#ifdef TRACEON
|
||||||
LOG(LOGS_INFO, LOGF_NtpCore, "Transmit timeout for [%s:%d]",
|
LOG(LOGS_INFO, LOGF_NtpCore, "Transmit timeout for [%s:%d]",
|
||||||
UTI_IPToDottedQuad(inst->remote_addr.ip_addr), inst->remote_addr.port);
|
UTI_IPToString(&inst->remote_addr.ip_addr), inst->remote_addr.port);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Check whether we need to 'warm up' the link to the other end by
|
/* Check whether we need to 'warm up' the link to the other end by
|
||||||
@@ -809,8 +815,12 @@ receive_packet(NTP_Packet *message, struct timeval *now, NCR_Instance inst, int
|
|||||||
int valid_data;
|
int valid_data;
|
||||||
int valid_header;
|
int valid_header;
|
||||||
|
|
||||||
|
/* Kiss-of-Death packets */
|
||||||
|
int kod_rate = 0;
|
||||||
|
int valid_kod;
|
||||||
|
|
||||||
/* Variables used for doing logging */
|
/* Variables used for doing logging */
|
||||||
static char sync_stats[4] = {'N', '-', '+', '?'};
|
static char sync_stats[4] = {'N', '+', '-', '?'};
|
||||||
|
|
||||||
/* The estimated offset predicted from previous samples. The
|
/* The estimated offset predicted from previous samples. The
|
||||||
convention here is that positive means local clock FAST of
|
convention here is that positive means local clock FAST of
|
||||||
@@ -1015,6 +1025,14 @@ receive_packet(NTP_Packet *message, struct timeval *now, NCR_Instance inst, int
|
|||||||
test8 = 1;
|
test8 = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check for Kiss-of-Death */
|
||||||
|
if (message->stratum > NTP_MAX_STRATUM && !source_is_synchronized) {
|
||||||
|
if (!memcmp(&message->reference_id, "RATE", 4))
|
||||||
|
kod_rate = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
valid_kod = test1 && test2 && test5;
|
||||||
|
|
||||||
valid_data = test1 && test2 && test3 && test4 && test4a && test4b;
|
valid_data = test1 && test2 && test3 && test4 && test4a && test4b;
|
||||||
valid_header = test5 && test6 && test7 && test8;
|
valid_header = test5 && test6 && test7 && test8;
|
||||||
|
|
||||||
@@ -1026,8 +1044,8 @@ receive_packet(NTP_Packet *message, struct timeval *now, NCR_Instance inst, int
|
|||||||
message->lvm, message->stratum, message->poll, message->precision);
|
message->lvm, message->stratum, message->poll, message->precision);
|
||||||
LOG(LOGS_INFO, LOGF_NtpCore, "Root delay=%08lx (%f), dispersion=%08lx (%f)",
|
LOG(LOGS_INFO, LOGF_NtpCore, "Root delay=%08lx (%f), dispersion=%08lx (%f)",
|
||||||
message->root_delay, pkt_root_delay, message->root_dispersion, pkt_root_dispersion);
|
message->root_delay, pkt_root_delay, message->root_dispersion, pkt_root_dispersion);
|
||||||
LOG(LOGS_INFO, LOGF_NtpCore, "Ref id=[%s], ref_time=%08lx.%08lx [%s]",
|
LOG(LOGS_INFO, LOGF_NtpCore, "Ref id=[%lx], ref_time=%08lx.%08lx [%s]",
|
||||||
UTI_IPToDottedQuad(ntohl(message->reference_id)),
|
ntohl(message->reference_id),
|
||||||
message->reference_ts.hi, message->reference_ts.lo,
|
message->reference_ts.hi, message->reference_ts.lo,
|
||||||
UTI_TimestampToString(&message->reference_ts));
|
UTI_TimestampToString(&message->reference_ts));
|
||||||
LOG(LOGS_INFO, LOGF_NtpCore, "Originate=%08lx.%08lx [%s]",
|
LOG(LOGS_INFO, LOGF_NtpCore, "Originate=%08lx.%08lx [%s]",
|
||||||
@@ -1049,9 +1067,11 @@ receive_packet(NTP_Packet *message, struct timeval *now, NCR_Instance inst, int
|
|||||||
|
|
||||||
LOG(LOGS_INFO, LOGF_NtpCore, "test5=%d test6=%d test7=%d test8=%d valid_header=%d",
|
LOG(LOGS_INFO, LOGF_NtpCore, "test5=%d test6=%d test7=%d test8=%d valid_header=%d",
|
||||||
test5, test6, test7, test8, valid_header);
|
test5, test6, test7, test8, valid_header);
|
||||||
|
|
||||||
|
LOG(LOGS_INFO, LOGF_NtpCore, "kod_rate=%d valid_kod=%d", kod_rate, valid_kod);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (valid_header) {
|
if (valid_header && valid_data) {
|
||||||
inst->tx_count = 0;
|
inst->tx_count = 0;
|
||||||
SRC_SetReachable(inst->source);
|
SRC_SetReachable(inst->source);
|
||||||
}
|
}
|
||||||
@@ -1216,6 +1236,19 @@ receive_packet(NTP_Packet *message, struct timeval *now, NCR_Instance inst, int
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reduce polling if KoD RATE was received */
|
||||||
|
if (kod_rate && valid_kod) {
|
||||||
|
if (inst->remote_poll > inst->minpoll) {
|
||||||
|
inst->minpoll = inst->remote_poll;
|
||||||
|
if (inst->minpoll > inst->maxpoll)
|
||||||
|
inst->maxpoll = inst->minpoll;
|
||||||
|
if (inst->minpoll > inst->local_poll)
|
||||||
|
inst->local_poll = inst->minpoll;
|
||||||
|
LOG(LOGS_INFO, LOGF_NtpCore, "Received KoD RATE from %s, minpoll set to %d", UTI_IPToString(&inst->remote_addr.ip_addr), inst->minpoll);
|
||||||
|
}
|
||||||
|
/* Back off for a while */
|
||||||
|
delay_time += (double) (4 * (1UL << inst->minpoll));
|
||||||
|
}
|
||||||
|
|
||||||
if (requeue_transmit) {
|
if (requeue_transmit) {
|
||||||
/* Get rid of old timeout and start a new one */
|
/* Get rid of old timeout and start a new one */
|
||||||
@@ -1236,7 +1269,7 @@ receive_packet(NTP_Packet *message, struct timeval *now, NCR_Instance inst, int
|
|||||||
|
|
||||||
fprintf(logfile, "%s %-15s %1c %2d %1d%1d%1d%1d %1d%1d %1d%1d%1d%1d %2d %2d %2d %10.3e %10.3e %10.3e %10.3e %10.3e\n",
|
fprintf(logfile, "%s %-15s %1c %2d %1d%1d%1d%1d %1d%1d %1d%1d%1d%1d %2d %2d %2d %10.3e %10.3e %10.3e %10.3e %10.3e\n",
|
||||||
UTI_TimeToLogForm(sample_time.tv_sec),
|
UTI_TimeToLogForm(sample_time.tv_sec),
|
||||||
UTI_IPToDottedQuad(inst->remote_addr.ip_addr),
|
UTI_IPToString(&inst->remote_addr.ip_addr),
|
||||||
sync_stats[pkt_leap],
|
sync_stats[pkt_leap],
|
||||||
message->stratum,
|
message->stratum,
|
||||||
test1, test2, test3, test4,
|
test1, test2, test3, test4,
|
||||||
@@ -1325,9 +1358,9 @@ process_known
|
|||||||
one of the secondaries to flywheel it. The behaviour coded here
|
one of the secondaries to flywheel it. The behaviour coded here
|
||||||
is required in the secondaries to make this possible. */
|
is required in the secondaries to make this possible. */
|
||||||
|
|
||||||
if (ADF_IsAllowed(access_auth_table, inst->remote_addr.ip_addr)) {
|
if (ADF_IsAllowed(access_auth_table, &inst->remote_addr.ip_addr)) {
|
||||||
|
|
||||||
CLG_LogNTPClientAccess(inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
CLG_LogNTPClientAccess(&inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
||||||
|
|
||||||
if (do_auth) {
|
if (do_auth) {
|
||||||
auth_key_id = ntohl(message->auth_keyid);
|
auth_key_id = ntohl(message->auth_keyid);
|
||||||
@@ -1360,7 +1393,7 @@ process_known
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
LOG(LOGS_WARN, LOGF_NtpCore, "NTP packet received from unauthorised host %s port %d",
|
LOG(LOGS_WARN, LOGF_NtpCore, "NTP packet received from unauthorised host %s port %d",
|
||||||
UTI_IPToDottedQuad(inst->remote_addr.ip_addr),
|
UTI_IPToString(&inst->remote_addr.ip_addr),
|
||||||
inst->remote_addr.port);
|
inst->remote_addr.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1371,7 +1404,7 @@ process_known
|
|||||||
switch(inst->mode) {
|
switch(inst->mode) {
|
||||||
case MODE_ACTIVE:
|
case MODE_ACTIVE:
|
||||||
/* Ordinary symmetric peering */
|
/* Ordinary symmetric peering */
|
||||||
CLG_LogNTPPeerAccess(inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
CLG_LogNTPPeerAccess(&inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
||||||
receive_packet(message, now, inst, do_auth);
|
receive_packet(message, now, inst, do_auth);
|
||||||
break;
|
break;
|
||||||
case MODE_PASSIVE:
|
case MODE_PASSIVE:
|
||||||
@@ -1381,7 +1414,7 @@ process_known
|
|||||||
case MODE_CLIENT:
|
case MODE_CLIENT:
|
||||||
/* This is where we have the remote configured as a server and he has
|
/* This is where we have the remote configured as a server and he has
|
||||||
us configured as a peer - fair enough. */
|
us configured as a peer - fair enough. */
|
||||||
CLG_LogNTPPeerAccess(inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
CLG_LogNTPPeerAccess(&inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
||||||
receive_packet(message, now, inst, do_auth);
|
receive_packet(message, now, inst, do_auth);
|
||||||
break;
|
break;
|
||||||
case MODE_SERVER:
|
case MODE_SERVER:
|
||||||
@@ -1402,7 +1435,7 @@ process_known
|
|||||||
switch(inst->mode) {
|
switch(inst->mode) {
|
||||||
case MODE_ACTIVE:
|
case MODE_ACTIVE:
|
||||||
/* Slightly bizarre combination, but we can still process it */
|
/* Slightly bizarre combination, but we can still process it */
|
||||||
CLG_LogNTPPeerAccess(inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
CLG_LogNTPPeerAccess(&inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
||||||
receive_packet(message, now, inst, do_auth);
|
receive_packet(message, now, inst, do_auth);
|
||||||
break;
|
break;
|
||||||
case MODE_PASSIVE:
|
case MODE_PASSIVE:
|
||||||
@@ -1430,7 +1463,7 @@ process_known
|
|||||||
case MODE_ACTIVE:
|
case MODE_ACTIVE:
|
||||||
/* This would arise if we have the remote configured as a peer and
|
/* This would arise if we have the remote configured as a peer and
|
||||||
he does not have us configured */
|
he does not have us configured */
|
||||||
CLG_LogNTPPeerAccess(inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
CLG_LogNTPPeerAccess(&inst->remote_addr.ip_addr, (time_t) now->tv_sec);
|
||||||
receive_packet(message, now, inst, do_auth);
|
receive_packet(message, now, inst, do_auth);
|
||||||
break;
|
break;
|
||||||
case MODE_PASSIVE:
|
case MODE_PASSIVE:
|
||||||
@@ -1492,19 +1525,19 @@ NCR_ProcessNoauthUnknown(NTP_Packet *message, struct timeval *now, NTP_Remote_Ad
|
|||||||
NTP_Mode my_mode;
|
NTP_Mode my_mode;
|
||||||
int my_poll;
|
int my_poll;
|
||||||
|
|
||||||
if (ADF_IsAllowed(access_auth_table, remote_addr->ip_addr)) {
|
if (ADF_IsAllowed(access_auth_table, &remote_addr->ip_addr)) {
|
||||||
|
|
||||||
his_mode = message->lvm & 0x07;
|
his_mode = message->lvm & 0x07;
|
||||||
|
|
||||||
if (his_mode == MODE_CLIENT) {
|
if (his_mode == MODE_CLIENT) {
|
||||||
/* We are server */
|
/* We are server */
|
||||||
my_mode = MODE_SERVER;
|
my_mode = MODE_SERVER;
|
||||||
CLG_LogNTPClientAccess(remote_addr->ip_addr, (time_t) now->tv_sec);
|
CLG_LogNTPClientAccess(&remote_addr->ip_addr, (time_t) now->tv_sec);
|
||||||
|
|
||||||
} else if (his_mode == MODE_ACTIVE) {
|
} else if (his_mode == MODE_ACTIVE) {
|
||||||
/* We are symmetric passive, even though we don't ever lock to him */
|
/* We are symmetric passive, even though we don't ever lock to him */
|
||||||
my_mode = MODE_PASSIVE;
|
my_mode = MODE_PASSIVE;
|
||||||
CLG_LogNTPPeerAccess(remote_addr->ip_addr, (time_t) now->tv_sec);
|
CLG_LogNTPPeerAccess(&remote_addr->ip_addr, (time_t) now->tv_sec);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
my_mode = MODE_UNDEFINED;
|
my_mode = MODE_UNDEFINED;
|
||||||
@@ -1528,7 +1561,7 @@ NCR_ProcessNoauthUnknown(NTP_Packet *message, struct timeval *now, NTP_Remote_Ad
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG(LOGS_WARN, LOGF_NtpCore, "NTP packet received from unauthorised host %s port %d",
|
LOG(LOGS_WARN, LOGF_NtpCore, "NTP packet received from unauthorised host %s port %d",
|
||||||
UTI_IPToDottedQuad(remote_addr->ip_addr),
|
UTI_IPToString(&remote_addr->ip_addr),
|
||||||
remote_addr->port);
|
remote_addr->port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1562,19 +1595,19 @@ NCR_ProcessAuthUnknown(NTP_Packet *message, struct timeval *now, NTP_Remote_Addr
|
|||||||
int valid_key, valid_auth;
|
int valid_key, valid_auth;
|
||||||
unsigned long key_id;
|
unsigned long key_id;
|
||||||
|
|
||||||
if (ADF_IsAllowed(access_auth_table, remote_addr->ip_addr)) {
|
if (ADF_IsAllowed(access_auth_table, &remote_addr->ip_addr)) {
|
||||||
|
|
||||||
his_mode = message->lvm & 0x07;
|
his_mode = message->lvm & 0x07;
|
||||||
|
|
||||||
if (his_mode == MODE_CLIENT) {
|
if (his_mode == MODE_CLIENT) {
|
||||||
/* We are server */
|
/* We are server */
|
||||||
my_mode = MODE_SERVER;
|
my_mode = MODE_SERVER;
|
||||||
CLG_LogNTPClientAccess(remote_addr->ip_addr, (time_t) now->tv_sec);
|
CLG_LogNTPClientAccess(&remote_addr->ip_addr, (time_t) now->tv_sec);
|
||||||
|
|
||||||
} else if (his_mode == MODE_ACTIVE) {
|
} else if (his_mode == MODE_ACTIVE) {
|
||||||
/* We are symmetric passive, even though we don't ever lock to him */
|
/* We are symmetric passive, even though we don't ever lock to him */
|
||||||
my_mode = MODE_PASSIVE;
|
my_mode = MODE_PASSIVE;
|
||||||
CLG_LogNTPPeerAccess(remote_addr->ip_addr, (time_t) now->tv_sec);
|
CLG_LogNTPPeerAccess(&remote_addr->ip_addr, (time_t) now->tv_sec);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
my_mode = MODE_UNDEFINED;
|
my_mode = MODE_UNDEFINED;
|
||||||
@@ -1646,7 +1679,7 @@ NCR_TakeSourceOnline(NCR_Instance inst)
|
|||||||
case MD_OFFLINE:
|
case MD_OFFLINE:
|
||||||
if (!inst->timer_running) {
|
if (!inst->timer_running) {
|
||||||
/* We are not already actively polling it */
|
/* We are not already actively polling it */
|
||||||
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s online", UTI_IPToDottedQuad(inst->remote_addr.ip_addr));
|
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s online", UTI_IPToString(&inst->remote_addr.ip_addr));
|
||||||
inst->local_poll = inst->minpoll;
|
inst->local_poll = inst->minpoll;
|
||||||
inst->score = (ZONE_WIDTH >> 1);
|
inst->score = (ZONE_WIDTH >> 1);
|
||||||
inst->opmode = MD_ONLINE;
|
inst->opmode = MD_ONLINE;
|
||||||
@@ -1670,7 +1703,7 @@ NCR_TakeSourceOffline(NCR_Instance inst)
|
|||||||
switch (inst->opmode) {
|
switch (inst->opmode) {
|
||||||
case MD_ONLINE:
|
case MD_ONLINE:
|
||||||
if (inst->timer_running) {
|
if (inst->timer_running) {
|
||||||
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s offline", UTI_IPToDottedQuad(inst->remote_addr.ip_addr));
|
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s offline", UTI_IPToString(&inst->remote_addr.ip_addr));
|
||||||
SCH_RemoveTimeout(inst->timeout_id);
|
SCH_RemoveTimeout(inst->timeout_id);
|
||||||
inst->timer_running = 0;
|
inst->timer_running = 0;
|
||||||
inst->opmode = MD_OFFLINE;
|
inst->opmode = MD_OFFLINE;
|
||||||
@@ -1693,7 +1726,7 @@ void
|
|||||||
NCR_ModifyMinpoll(NCR_Instance inst, int new_minpoll)
|
NCR_ModifyMinpoll(NCR_Instance inst, int new_minpoll)
|
||||||
{
|
{
|
||||||
inst->minpoll = new_minpoll;
|
inst->minpoll = new_minpoll;
|
||||||
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s new minpoll %d", UTI_IPToDottedQuad(inst->remote_addr.ip_addr), new_minpoll);
|
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s new minpoll %d", UTI_IPToString(&inst->remote_addr.ip_addr), new_minpoll);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -1702,7 +1735,7 @@ void
|
|||||||
NCR_ModifyMaxpoll(NCR_Instance inst, int new_maxpoll)
|
NCR_ModifyMaxpoll(NCR_Instance inst, int new_maxpoll)
|
||||||
{
|
{
|
||||||
inst->maxpoll = new_maxpoll;
|
inst->maxpoll = new_maxpoll;
|
||||||
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s new maxpoll %d", UTI_IPToDottedQuad(inst->remote_addr.ip_addr), new_maxpoll);
|
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s new maxpoll %d", UTI_IPToString(&inst->remote_addr.ip_addr), new_maxpoll);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -1712,7 +1745,7 @@ NCR_ModifyMaxdelay(NCR_Instance inst, double new_max_delay)
|
|||||||
{
|
{
|
||||||
inst->max_delay = new_max_delay;
|
inst->max_delay = new_max_delay;
|
||||||
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s new max delay %f",
|
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s new max delay %f",
|
||||||
UTI_IPToDottedQuad(inst->remote_addr.ip_addr), new_max_delay);
|
UTI_IPToString(&inst->remote_addr.ip_addr), new_max_delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -1722,7 +1755,7 @@ NCR_ModifyMaxdelayratio(NCR_Instance inst, double new_max_delay_ratio)
|
|||||||
{
|
{
|
||||||
inst->max_delay_ratio = new_max_delay_ratio;
|
inst->max_delay_ratio = new_max_delay_ratio;
|
||||||
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s new max delay ratio %f",
|
LOG(LOGS_INFO, LOGF_NtpCore, "Source %s new max delay ratio %f",
|
||||||
UTI_IPToDottedQuad(inst->remote_addr.ip_addr), new_max_delay_ratio);
|
UTI_IPToString(&inst->remote_addr.ip_addr), new_max_delay_ratio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -1804,7 +1837,7 @@ NCR_ReportSource(NCR_Instance inst, RPT_SourceReport *report, struct timeval *no
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
int
|
int
|
||||||
NCR_AddAccessRestriction(unsigned long ip_addr, int subnet_bits, int allow, int all)
|
NCR_AddAccessRestriction(IPAddr *ip_addr, int subnet_bits, int allow, int all)
|
||||||
{
|
{
|
||||||
ADF_Status status;
|
ADF_Status status;
|
||||||
|
|
||||||
@@ -1834,7 +1867,7 @@ NCR_AddAccessRestriction(unsigned long ip_addr, int subnet_bits, int allow, int
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
int
|
int
|
||||||
NCR_CheckAccessRestriction(unsigned long ip_addr)
|
NCR_CheckAccessRestriction(IPAddr *ip_addr)
|
||||||
{
|
{
|
||||||
return ADF_IsAllowed(access_auth_table, ip_addr);
|
return ADF_IsAllowed(access_auth_table, ip_addr);
|
||||||
}
|
}
|
||||||
@@ -1880,3 +1913,11 @@ NCR_IncrementActivityCounters(NCR_Instance inst, int *online, int *offline,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
NTP_Remote_Address *
|
||||||
|
NCR_GetRemoteAddress(NCR_Instance inst)
|
||||||
|
{
|
||||||
|
return &inst->remote_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -94,12 +94,14 @@ extern void NCR_InitiateSampleBurst(NCR_Instance inst, int n_good_samples, int n
|
|||||||
|
|
||||||
extern void NCR_ReportSource(NCR_Instance inst, RPT_SourceReport *report, struct timeval *now);
|
extern void NCR_ReportSource(NCR_Instance inst, RPT_SourceReport *report, struct timeval *now);
|
||||||
|
|
||||||
extern int NCR_AddAccessRestriction(unsigned long ip_addr, int subnet_bits, int allow, int all);
|
extern int NCR_AddAccessRestriction(IPAddr *ip_addr, int subnet_bits, int allow, int all);
|
||||||
extern int NCR_CheckAccessRestriction(unsigned long ip_addr);
|
extern int NCR_CheckAccessRestriction(IPAddr *ip_addr);
|
||||||
|
|
||||||
extern void NCR_CycleLogFile(void);
|
extern void NCR_CycleLogFile(void);
|
||||||
|
|
||||||
extern void NCR_IncrementActivityCounters(NCR_Instance inst, int *online, int *offline,
|
extern void NCR_IncrementActivityCounters(NCR_Instance inst, int *online, int *offline,
|
||||||
int *burst_online, int *burst_offline);
|
int *burst_online, int *burst_offline);
|
||||||
|
|
||||||
|
extern NTP_Remote_Address *NCR_GetRemoteAddress(NCR_Instance instance);
|
||||||
|
|
||||||
#endif /* GOT_NTP_CORE_H */
|
#endif /* GOT_NTP_CORE_H */
|
||||||
|
|||||||
367
ntp_io.c
367
ntp_io.c
@@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
* Copyright (C) Richard P. Curnow 1997-2003
|
* Copyright (C) Richard P. Curnow 1997-2003
|
||||||
|
* Copyright (C) Timo Teras 2009
|
||||||
|
* Copyright (C) Miroslav Lichvar 2009
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of version 2 of the GNU General Public License as
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
@@ -19,7 +21,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -41,8 +43,19 @@
|
|||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
/* The file descriptor for the socket */
|
union sockaddr_in46 {
|
||||||
static int sock_fd;
|
struct sockaddr_in in4;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
struct sockaddr_in6 in6;
|
||||||
|
#endif
|
||||||
|
struct sockaddr u;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The file descriptors for the IPv4 and IPv6 sockets */
|
||||||
|
static int sock_fd4;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
static int sock_fd6;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Flag indicating that we have been initialised */
|
/* Flag indicating that we have been initialised */
|
||||||
static int initialised=0;
|
static int initialised=0;
|
||||||
@@ -50,6 +63,7 @@ static int initialised=0;
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
/* Forward prototypes */
|
/* Forward prototypes */
|
||||||
|
static int prepare_socket(int family);
|
||||||
static void read_from_socket(void *anything);
|
static void read_from_socket(void *anything);
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -81,30 +95,30 @@ do_size_checks(void)
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
static int
|
||||||
NIO_Initialise(void)
|
prepare_socket(int family)
|
||||||
{
|
{
|
||||||
struct sockaddr_in my_addr;
|
union sockaddr_in46 my_addr;
|
||||||
|
socklen_t my_addr_len;
|
||||||
|
int sock_fd;
|
||||||
unsigned short port_number;
|
unsigned short port_number;
|
||||||
unsigned long bind_address;
|
IPAddr bind_address;
|
||||||
int on_off = 1;
|
int on_off = 1;
|
||||||
|
|
||||||
assert(!initialised);
|
|
||||||
initialised = 1;
|
|
||||||
|
|
||||||
do_size_checks();
|
|
||||||
|
|
||||||
port_number = CNF_GetNTPPort();
|
port_number = CNF_GetNTPPort();
|
||||||
|
|
||||||
/* Open Internet domain UDP socket for NTP message transmissions */
|
/* Open Internet domain UDP socket for NTP message transmissions */
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
sock_fd = socket(family, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
#else
|
#else
|
||||||
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
sock_fd = socket(family, SOCK_DGRAM, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (sock_fd < 0) {
|
if (sock_fd < 0) {
|
||||||
LOG_FATAL(LOGF_NtpIO, "Could not open socket : %s", strerror(errno));
|
LOG(LOGS_ERR, LOGF_NtpIO, "Could not open %s NTP socket : %s",
|
||||||
|
family == AF_INET ? "IPv4" : "IPv6", strerror(errno));
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make the socket capable of re-using an old address */
|
/* Make the socket capable of re-using an old address */
|
||||||
@@ -119,28 +133,80 @@ NIO_Initialise(void)
|
|||||||
/* Don't quit - we might survive anyway */
|
/* Don't quit - we might survive anyway */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SO_TIMESTAMP
|
||||||
|
/* Enable receiving of timestamp control messages */
|
||||||
|
if (setsockopt(sock_fd, SOL_SOCKET, SO_TIMESTAMP, (char *)&on_off, sizeof(on_off)) < 0) {
|
||||||
|
LOG(LOGS_ERR, LOGF_NtpIO, "Could not set timestamp socket options");
|
||||||
|
/* Don't quit - we might survive anyway */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (family == AF_INET) {
|
||||||
|
#ifdef IP_PKTINFO
|
||||||
|
/* We want the local IP info too */
|
||||||
|
if (setsockopt(sock_fd, IPPROTO_IP, IP_PKTINFO, (char *)&on_off, sizeof(on_off)) < 0) {
|
||||||
|
LOG(LOGS_ERR, LOGF_NtpIO, "Could not request packet info using socket option");
|
||||||
|
/* Don't quit - we might survive anyway */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
else if (family == AF_INET6) {
|
||||||
|
#ifdef IPV6_V6ONLY
|
||||||
|
/* Receive IPv6 packets only */
|
||||||
|
if (setsockopt(sock_fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&on_off, sizeof(on_off)) < 0) {
|
||||||
|
LOG(LOGS_ERR, LOGF_NtpIO, "Could not request IPV6_V6ONLY socket option");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Bind the port */
|
/* Bind the port */
|
||||||
my_addr.sin_family = AF_INET;
|
memset(&my_addr, 0, sizeof (my_addr));
|
||||||
my_addr.sin_port = htons(port_number);
|
|
||||||
|
|
||||||
CNF_GetBindAddress(&bind_address);
|
switch (family) {
|
||||||
|
case AF_INET:
|
||||||
|
my_addr_len = sizeof (my_addr.in4);
|
||||||
|
my_addr.in4.sin_family = family;
|
||||||
|
my_addr.in4.sin_port = htons(port_number);
|
||||||
|
|
||||||
if (bind_address != 0UL) {
|
CNF_GetBindAddress(IPADDR_INET4, &bind_address);
|
||||||
my_addr.sin_addr.s_addr = htonl(bind_address);
|
|
||||||
} else {
|
if (bind_address.family == IPADDR_INET4)
|
||||||
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
my_addr.in4.sin_addr.s_addr = htonl(bind_address.addr.in4);
|
||||||
|
else
|
||||||
|
my_addr.in4.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
case AF_INET6:
|
||||||
|
my_addr_len = sizeof (my_addr.in6);
|
||||||
|
my_addr.in6.sin6_family = family;
|
||||||
|
my_addr.in6.sin6_port = htons(port_number);
|
||||||
|
|
||||||
|
CNF_GetBindAddress(IPADDR_INET6, &bind_address);
|
||||||
|
|
||||||
|
if (bind_address.family == IPADDR_INET6)
|
||||||
|
memcpy(my_addr.in6.sin6_addr.s6_addr, bind_address.addr.in6,
|
||||||
|
sizeof (my_addr.in6.sin6_addr.s6_addr));
|
||||||
|
else
|
||||||
|
my_addr.in6.sin6_addr = in6addr_any;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
LOG(LOGS_INFO, LOGF_NtpIO, "Initialising, socket fd=%d", sock_fd);
|
LOG(LOGS_INFO, LOGF_NtpIO, "Initialising, socket fd=%d", sock_fd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (bind(sock_fd, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0) {
|
if (bind(sock_fd, &my_addr.u, my_addr_len) < 0) {
|
||||||
LOG_FATAL(LOGF_NtpIO, "Could not bind socket : %s", strerror(errno));
|
LOG_FATAL(LOGF_NtpIO, "Could not bind %s NTP socket : %s",
|
||||||
|
family == AF_INET ? "IPv4" : "IPv6", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register handler for read events on the socket */
|
/* Register handler for read events on the socket */
|
||||||
SCH_AddInputFileHandler(sock_fd, read_from_socket, NULL);
|
SCH_AddInputFileHandler(sock_fd, read_from_socket, (void *)(long)sock_fd);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (fcntl(sock_fd, F_SETFL, O_NONBLOCK | O_NDELAY) < 0) {
|
if (fcntl(sock_fd, F_SETFL, O_NONBLOCK | O_NDELAY) < 0) {
|
||||||
@@ -151,6 +217,29 @@ NIO_Initialise(void)
|
|||||||
LOG(LOGS_ERR, LOGF_NtpIO, "Could not enable signal");
|
LOG(LOGS_ERR, LOGF_NtpIO, "Could not enable signal");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return sock_fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NIO_Initialise(void)
|
||||||
|
{
|
||||||
|
assert(!initialised);
|
||||||
|
initialised = 1;
|
||||||
|
|
||||||
|
do_size_checks();
|
||||||
|
|
||||||
|
sock_fd4 = prepare_socket(AF_INET);
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
sock_fd6 = prepare_socket(AF_INET6);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (sock_fd4 < 0
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
&& sock_fd6 < 0
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
LOG_FATAL(LOGF_NtpIO, "Could not open any NTP socket");
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -160,11 +249,18 @@ NIO_Initialise(void)
|
|||||||
void
|
void
|
||||||
NIO_Finalise(void)
|
NIO_Finalise(void)
|
||||||
{
|
{
|
||||||
if (sock_fd >= 0) {
|
if (sock_fd4 >= 0) {
|
||||||
SCH_RemoveInputFileHandler(sock_fd);
|
SCH_RemoveInputFileHandler(sock_fd4);
|
||||||
close(sock_fd);
|
close(sock_fd4);
|
||||||
}
|
}
|
||||||
sock_fd = -1;
|
sock_fd4 = -1;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
if (sock_fd6 >= 0) {
|
||||||
|
SCH_RemoveInputFileHandler(sock_fd6);
|
||||||
|
close(sock_fd6);
|
||||||
|
}
|
||||||
|
sock_fd6 = -1;
|
||||||
|
#endif
|
||||||
initialised = 0;
|
initialised = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -180,24 +276,33 @@ read_from_socket(void *anything)
|
|||||||
/* This should only be called when there is something
|
/* This should only be called when there is something
|
||||||
to read, otherwise it will block. */
|
to read, otherwise it will block. */
|
||||||
|
|
||||||
int status;
|
int status, sock_fd;
|
||||||
ReceiveBuffer message;
|
ReceiveBuffer message;
|
||||||
int message_length;
|
union sockaddr_in46 where_from;
|
||||||
struct sockaddr_in where_from;
|
|
||||||
socklen_t from_length;
|
|
||||||
unsigned int flags = 0;
|
unsigned int flags = 0;
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
NTP_Remote_Address remote_addr;
|
NTP_Remote_Address remote_addr;
|
||||||
double local_clock_err;
|
char cmsgbuf[256];
|
||||||
|
struct msghdr msg;
|
||||||
|
struct iovec iov;
|
||||||
|
struct cmsghdr *cmsg;
|
||||||
|
|
||||||
assert(initialised);
|
assert(initialised);
|
||||||
|
|
||||||
from_length = sizeof(where_from);
|
SCH_GetFileReadyTime(&now);
|
||||||
message_length = sizeof(message);
|
|
||||||
|
|
||||||
LCL_ReadCookedTime(&now, &local_clock_err);
|
iov.iov_base = message.arbitrary;
|
||||||
status = recvfrom(sock_fd, (char *)&message, message_length, flags,
|
iov.iov_len = sizeof(message);
|
||||||
(struct sockaddr *)&where_from, &from_length);
|
msg.msg_name = &where_from;
|
||||||
|
msg.msg_namelen = sizeof(where_from);
|
||||||
|
msg.msg_iov = &iov;
|
||||||
|
msg.msg_iovlen = 1;
|
||||||
|
msg.msg_control = (void *) cmsgbuf;
|
||||||
|
msg.msg_controllen = sizeof(cmsgbuf);
|
||||||
|
msg.msg_flags = 0;
|
||||||
|
|
||||||
|
sock_fd = (long)anything;
|
||||||
|
status = recvmsg(sock_fd, &msg, flags);
|
||||||
|
|
||||||
/* Don't bother checking if read failed or why if it did. More
|
/* Don't bother checking if read failed or why if it did. More
|
||||||
likely than not, it will be connection refused, resulting from a
|
likely than not, it will be connection refused, resulting from a
|
||||||
@@ -207,8 +312,53 @@ read_from_socket(void *anything)
|
|||||||
reponse on a subsequent recvfrom). */
|
reponse on a subsequent recvfrom). */
|
||||||
|
|
||||||
if (status > 0) {
|
if (status > 0) {
|
||||||
remote_addr.ip_addr = ntohl(where_from.sin_addr.s_addr);
|
memset(&remote_addr, 0, sizeof (remote_addr));
|
||||||
remote_addr.port = ntohs(where_from.sin_port);
|
|
||||||
|
switch (where_from.u.sa_family) {
|
||||||
|
case AF_INET:
|
||||||
|
remote_addr.ip_addr.family = IPADDR_INET4;
|
||||||
|
remote_addr.ip_addr.addr.in4 = ntohl(where_from.in4.sin_addr.s_addr);
|
||||||
|
remote_addr.port = ntohs(where_from.in4.sin_port);
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
case AF_INET6:
|
||||||
|
remote_addr.ip_addr.family = IPADDR_INET6;
|
||||||
|
memcpy(&remote_addr.ip_addr.addr.in6, where_from.in6.sin6_addr.s6_addr,
|
||||||
|
sizeof (remote_addr.ip_addr.addr.in6));
|
||||||
|
remote_addr.port = ntohs(where_from.in6.sin6_port);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||||
|
#ifdef IP_PKTINFO
|
||||||
|
if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) {
|
||||||
|
struct in_pktinfo ipi;
|
||||||
|
|
||||||
|
memcpy(&ipi, CMSG_DATA(cmsg), sizeof(ipi));
|
||||||
|
remote_addr.local_ip_addr.addr.in4 = ntohl(ipi.ipi_spec_dst.s_addr);
|
||||||
|
remote_addr.local_ip_addr.family = IPADDR_INET4;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SO_TIMESTAMP
|
||||||
|
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMP) {
|
||||||
|
struct timeval tv;
|
||||||
|
double correction;
|
||||||
|
|
||||||
|
memcpy(&tv, CMSG_DATA(cmsg), sizeof(tv));
|
||||||
|
correction = LCL_GetOffsetCorrection(&tv);
|
||||||
|
UTI_AddDoubleToTimeval(&tv, correction, &tv);
|
||||||
|
#if 0
|
||||||
|
UTI_DiffTimevalsToDouble(&correction, &now, &tv);
|
||||||
|
LOG(LOGS_INFO, LOGF_NtpIO, "timestamp diff: %f", correction);
|
||||||
|
#endif
|
||||||
|
now = tv;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (status == NTP_NORMAL_PACKET_SIZE) {
|
if (status == NTP_NORMAL_PACKET_SIZE) {
|
||||||
|
|
||||||
@@ -228,27 +378,103 @@ read_from_socket(void *anything)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
/* Send a packet to given address */
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_packet(void *packet, int packetlen, NTP_Remote_Address *remote_addr)
|
||||||
|
{
|
||||||
|
union sockaddr_in46 remote;
|
||||||
|
struct msghdr msg;
|
||||||
|
struct iovec iov;
|
||||||
|
char cmsgbuf[256];
|
||||||
|
int cmsglen;
|
||||||
|
int sock_fd;
|
||||||
|
socklen_t addrlen;
|
||||||
|
|
||||||
|
assert(initialised);
|
||||||
|
|
||||||
|
switch (remote_addr->ip_addr.family) {
|
||||||
|
case IPADDR_INET4:
|
||||||
|
memset(&remote.in4, 0, sizeof (remote.in4));
|
||||||
|
addrlen = sizeof (remote.in4);
|
||||||
|
remote.in4.sin_family = AF_INET;
|
||||||
|
remote.in4.sin_port = htons(remote_addr->port);
|
||||||
|
remote.in4.sin_addr.s_addr = htonl(remote_addr->ip_addr.addr.in4);
|
||||||
|
sock_fd = sock_fd4;
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
case IPADDR_INET6:
|
||||||
|
memset(&remote.in6, 0, sizeof (remote.in6));
|
||||||
|
addrlen = sizeof (remote.in6);
|
||||||
|
remote.in6.sin6_family = AF_INET6;
|
||||||
|
remote.in6.sin6_port = htons(remote_addr->port);
|
||||||
|
memcpy(&remote.in6.sin6_addr.s6_addr, &remote_addr->ip_addr.addr.in6,
|
||||||
|
sizeof (remote.in6.sin6_addr.s6_addr));
|
||||||
|
sock_fd = sock_fd6;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock_fd < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
iov.iov_base = packet;
|
||||||
|
iov.iov_len = packetlen;
|
||||||
|
msg.msg_name = &remote.u;
|
||||||
|
msg.msg_namelen = addrlen;
|
||||||
|
msg.msg_iov = &iov;
|
||||||
|
msg.msg_iovlen = 1;
|
||||||
|
msg.msg_control = cmsgbuf;
|
||||||
|
msg.msg_controllen = sizeof(cmsgbuf);
|
||||||
|
msg.msg_flags = 0;
|
||||||
|
cmsglen = 0;
|
||||||
|
|
||||||
|
#ifdef IP_PKTINFO
|
||||||
|
if (remote_addr->local_ip_addr.family == IPADDR_INET4) {
|
||||||
|
struct cmsghdr *cmsg;
|
||||||
|
struct in_pktinfo *ipi;
|
||||||
|
|
||||||
|
cmsg = CMSG_FIRSTHDR(&msg);
|
||||||
|
memset(cmsg, 0, CMSG_SPACE(sizeof(struct in_pktinfo)));
|
||||||
|
cmsglen += CMSG_SPACE(sizeof(struct in_pktinfo));
|
||||||
|
|
||||||
|
cmsg->cmsg_level = IPPROTO_IP;
|
||||||
|
cmsg->cmsg_type = IP_PKTINFO;
|
||||||
|
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
|
||||||
|
|
||||||
|
ipi = (struct in_pktinfo *) CMSG_DATA(cmsg);
|
||||||
|
ipi->ipi_spec_dst.s_addr = htonl(remote_addr->local_ip_addr.addr.in4);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
LOG(LOGS_INFO, LOGF_NtpIO, "sending to %s:%d from %s",
|
||||||
|
UTI_IPToString(&remote_addr->ip_addr), remote_addr->port, UTI_IPToString(&remote_addr->local_ip_addr));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
msg.msg_controllen = cmsglen;
|
||||||
|
/* This is apparently required on some systems */
|
||||||
|
if (!cmsglen)
|
||||||
|
msg.msg_control = NULL;
|
||||||
|
|
||||||
|
if (sendmsg(sock_fd, &msg, 0) < 0) {
|
||||||
|
LOG(LOGS_WARN, LOGF_NtpIO, "Could not send to %s:%d : %s",
|
||||||
|
UTI_IPToString(&remote_addr->ip_addr), remote_addr->port, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
/* Send an unauthenticated packet to a given address */
|
/* Send an unauthenticated packet to a given address */
|
||||||
|
|
||||||
void
|
void
|
||||||
NIO_SendNormalPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr)
|
NIO_SendNormalPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr)
|
||||||
{
|
{
|
||||||
struct sockaddr_in remote;
|
send_packet((void *) packet, NTP_NORMAL_PACKET_SIZE, remote_addr);
|
||||||
|
|
||||||
assert(initialised);
|
|
||||||
|
|
||||||
remote.sin_family = AF_INET;
|
|
||||||
remote.sin_port = htons(remote_addr->port);
|
|
||||||
remote.sin_addr.s_addr = htonl(remote_addr->ip_addr);
|
|
||||||
|
|
||||||
if (sendto(sock_fd, (void *) packet, NTP_NORMAL_PACKET_SIZE, 0,
|
|
||||||
(struct sockaddr *) &remote, sizeof(remote)) < 0) {
|
|
||||||
LOG(LOGS_WARN, LOGF_NtpIO, "Could not send to %s:%d : %s",
|
|
||||||
UTI_IPToDottedQuad(remote_addr->ip_addr), remote_addr->port, strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -257,21 +483,7 @@ NIO_SendNormalPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr)
|
|||||||
void
|
void
|
||||||
NIO_SendAuthenticatedPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr)
|
NIO_SendAuthenticatedPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr)
|
||||||
{
|
{
|
||||||
struct sockaddr_in remote;
|
send_packet((void *) packet, sizeof(NTP_Packet), remote_addr);
|
||||||
|
|
||||||
assert(initialised);
|
|
||||||
|
|
||||||
remote.sin_family = AF_INET;
|
|
||||||
remote.sin_port = htons(remote_addr->port);
|
|
||||||
remote.sin_addr.s_addr = htonl(remote_addr->ip_addr);
|
|
||||||
|
|
||||||
if (sendto(sock_fd, (void *) packet, sizeof(NTP_Packet), 0,
|
|
||||||
(struct sockaddr *) &remote, sizeof(remote)) < 0) {
|
|
||||||
LOG(LOGS_WARN, LOGF_NtpIO, "Could not send to %s:%d : %s",
|
|
||||||
UTI_IPToDottedQuad(remote_addr->ip_addr), remote_addr->port, strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -283,15 +495,10 @@ void
|
|||||||
NIO_SendEcho(NTP_Remote_Address *remote_addr)
|
NIO_SendEcho(NTP_Remote_Address *remote_addr)
|
||||||
{
|
{
|
||||||
unsigned long magic_message = 0xbe7ab1e7UL;
|
unsigned long magic_message = 0xbe7ab1e7UL;
|
||||||
struct sockaddr_in addr;
|
NTP_Remote_Address addr;
|
||||||
|
|
||||||
addr.sin_family = AF_INET;
|
|
||||||
addr.sin_port = htons(ECHO_PORT);
|
|
||||||
addr.sin_addr.s_addr = htonl(remote_addr->ip_addr);
|
|
||||||
|
|
||||||
/* Just ignore error status on send - this is not a big deal anyway */
|
|
||||||
sendto(sock_fd, (void *) &magic_message, sizeof(unsigned long), 0,
|
|
||||||
(struct sockaddr *) &addr, sizeof(addr));
|
|
||||||
|
|
||||||
|
addr = *remote_addr;
|
||||||
|
addr.port = ECHO_PORT;
|
||||||
|
|
||||||
|
send_packet((void *) &magic_message, sizeof(unsigned long), &addr);
|
||||||
}
|
}
|
||||||
|
|||||||
2
ntp_io.h
2
ntp_io.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
108
ntp_sources.c
108
ntp_sources.c
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -43,8 +43,8 @@
|
|||||||
/* Record type private to this file, used to store information about
|
/* Record type private to this file, used to store information about
|
||||||
particular sources */
|
particular sources */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NTP_Remote_Address remote_addr; /* The address of this source */
|
NTP_Remote_Address *remote_addr; /* The address of this source, non-NULL
|
||||||
int in_use; /* Whether this slot in the table is in use */
|
means this slot in table is in use */
|
||||||
NCR_Instance data; /* Data for the protocol engine for this source */
|
NCR_Instance data; /* Data for the protocol engine for this source */
|
||||||
} SourceRecord;
|
} SourceRecord;
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ NSR_Initialise(void)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<N_RECORDS; i++) {
|
for (i=0; i<N_RECORDS; i++) {
|
||||||
records[i].in_use = 0;
|
records[i].remote_addr = NULL;
|
||||||
}
|
}
|
||||||
n_sources = 0;
|
n_sources = 0;
|
||||||
initialised = 1;
|
initialised = 1;
|
||||||
@@ -120,23 +120,42 @@ static void
|
|||||||
find_slot(NTP_Remote_Address *remote_addr, int *slot, int *found)
|
find_slot(NTP_Remote_Address *remote_addr, int *slot, int *found)
|
||||||
{
|
{
|
||||||
unsigned long hash;
|
unsigned long hash;
|
||||||
unsigned long ip = remote_addr->ip_addr;
|
unsigned long ip;
|
||||||
unsigned short port = remote_addr->port;
|
unsigned short port;
|
||||||
|
uint8_t *ip6;
|
||||||
|
|
||||||
assert(N_RECORDS == 256);
|
assert(N_RECORDS == 256);
|
||||||
|
|
||||||
|
switch (remote_addr->ip_addr.family) {
|
||||||
|
case IPADDR_INET6:
|
||||||
|
ip6 = remote_addr->ip_addr.addr.in6;
|
||||||
|
ip = (ip6[0] ^ ip6[4] ^ ip6[8] ^ ip6[12]) |
|
||||||
|
(ip6[1] ^ ip6[5] ^ ip6[9] ^ ip6[13]) << 8 |
|
||||||
|
(ip6[2] ^ ip6[6] ^ ip6[10] ^ ip6[14]) << 16 |
|
||||||
|
(ip6[3] ^ ip6[7] ^ ip6[11] ^ ip6[15]) << 24;
|
||||||
|
break;
|
||||||
|
case IPADDR_INET4:
|
||||||
|
ip = remote_addr->ip_addr.addr.in4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*found = *slot = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
port = remote_addr->port;
|
||||||
/* Compute hash value just by xor'ing the 4 bytes of the address together */
|
/* Compute hash value just by xor'ing the 4 bytes of the address together */
|
||||||
hash = ip ^ (ip >> 16);
|
hash = ip ^ (ip >> 16);
|
||||||
hash = (hash ^ (hash >> 8)) & 0xff;
|
hash = (hash ^ (hash >> 8)) & 0xff;
|
||||||
|
|
||||||
while ((records[hash].in_use) &&
|
while (records[hash].remote_addr &&
|
||||||
(records[hash].remote_addr.ip_addr != ip)) {
|
UTI_CompareIPs(&records[hash].remote_addr->ip_addr,
|
||||||
|
&remote_addr->ip_addr, NULL)) {
|
||||||
hash++;
|
hash++;
|
||||||
if (hash == 256) hash = 0;
|
if (hash == 256) hash = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (records[hash].in_use) {
|
if (records[hash].remote_addr) {
|
||||||
if (records[hash].remote_addr.port == port) {
|
if (records[hash].remote_addr->port == port) {
|
||||||
*found = 2;
|
*found = 2;
|
||||||
} else {
|
} else {
|
||||||
*found = 1;
|
*found = 1;
|
||||||
@@ -162,7 +181,7 @@ NSR_AddServer(NTP_Remote_Address *remote_addr, SourceParameters *params)
|
|||||||
assert(initialised);
|
assert(initialised);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
LOG(LOGS_INFO, LOGF_NtpSources, "IP=%08lx port=%d", (unsigned long)remote_addr->ip_addr, remote_addr->port);
|
LOG(LOGS_INFO, LOGF_NtpSources, "IP=%s port=%d", UTI_IPToString(&remote_addr->ip_addr), remote_addr->port);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Find empty bin & check that we don't have the address already */
|
/* Find empty bin & check that we don't have the address already */
|
||||||
@@ -172,11 +191,13 @@ NSR_AddServer(NTP_Remote_Address *remote_addr, SourceParameters *params)
|
|||||||
} else {
|
} else {
|
||||||
if (n_sources == MAX_SOURCES) {
|
if (n_sources == MAX_SOURCES) {
|
||||||
return NSR_TooManySources;
|
return NSR_TooManySources;
|
||||||
|
} else if (remote_addr->ip_addr.family != IPADDR_INET4 &&
|
||||||
|
remote_addr->ip_addr.family != IPADDR_INET6) {
|
||||||
|
return NSR_InvalidAF;
|
||||||
} else {
|
} else {
|
||||||
n_sources++;
|
n_sources++;
|
||||||
records[slot].remote_addr = *remote_addr;
|
|
||||||
records[slot].in_use = 1;
|
|
||||||
records[slot].data = NCR_GetServerInstance(remote_addr, params); /* Will need params passing through */
|
records[slot].data = NCR_GetServerInstance(remote_addr, params); /* Will need params passing through */
|
||||||
|
records[slot].remote_addr = NCR_GetRemoteAddress(records[slot].data);
|
||||||
return NSR_Success;
|
return NSR_Success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,7 +214,7 @@ NSR_AddPeer(NTP_Remote_Address *remote_addr, SourceParameters *params)
|
|||||||
assert(initialised);
|
assert(initialised);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
LOG(LOGS_INFO, LOGF_NtpSources, "IP=%08lx port=%d", (unsigned long) remote_addr->ip_addr, remote_addr->port);
|
LOG(LOGS_INFO, LOGF_NtpSources, "IP=%s port=%d", UTI_IPToString(&remote_addr->ip_addr), remote_addr->port);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Find empty bin & check that we don't have the address already */
|
/* Find empty bin & check that we don't have the address already */
|
||||||
@@ -203,11 +224,13 @@ NSR_AddPeer(NTP_Remote_Address *remote_addr, SourceParameters *params)
|
|||||||
} else {
|
} else {
|
||||||
if (n_sources == MAX_SOURCES) {
|
if (n_sources == MAX_SOURCES) {
|
||||||
return NSR_TooManySources;
|
return NSR_TooManySources;
|
||||||
|
} else if (remote_addr->ip_addr.family != IPADDR_INET4 &&
|
||||||
|
remote_addr->ip_addr.family != IPADDR_INET6) {
|
||||||
|
return NSR_InvalidAF;
|
||||||
} else {
|
} else {
|
||||||
n_sources++;
|
n_sources++;
|
||||||
records[slot].remote_addr = *remote_addr;
|
|
||||||
records[slot].in_use = 1;
|
|
||||||
records[slot].data = NCR_GetPeerInstance(remote_addr, params); /* Will need params passing through */
|
records[slot].data = NCR_GetPeerInstance(remote_addr, params); /* Will need params passing through */
|
||||||
|
records[slot].remote_addr = NCR_GetRemoteAddress(records[slot].data);
|
||||||
return NSR_Success;
|
return NSR_Success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -231,7 +254,7 @@ NSR_RemoveSource(NTP_Remote_Address *remote_addr)
|
|||||||
return NSR_NoSuchSource;
|
return NSR_NoSuchSource;
|
||||||
} else {
|
} else {
|
||||||
n_sources--;
|
n_sources--;
|
||||||
records[slot].in_use = 0;
|
records[slot].remote_addr = NULL;
|
||||||
NCR_DestroyInstance(records[slot].data);
|
NCR_DestroyInstance(records[slot].data);
|
||||||
return NSR_Success;
|
return NSR_Success;
|
||||||
}
|
}
|
||||||
@@ -249,7 +272,7 @@ NSR_ProcessReceive(NTP_Packet *message, struct timeval *now, NTP_Remote_Address
|
|||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
LOG(LOGS_INFO, LOGF_NtpSources, "from (%s,%d) at %s",
|
LOG(LOGS_INFO, LOGF_NtpSources, "from (%s,%d) at %s",
|
||||||
UTI_IPToDottedQuad(remote_addr->ip_addr),
|
UTI_IPToString(&remote_addr->ip_addr),
|
||||||
remote_addr->port, UTI_TimevalToString(now));
|
remote_addr->port, UTI_TimevalToString(now));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -293,10 +316,10 @@ slew_sources(struct timeval *raw,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<N_RECORDS; i++) {
|
for (i=0; i<N_RECORDS; i++) {
|
||||||
if (records[i].in_use) {
|
if (records[i].remote_addr) {
|
||||||
#if 0
|
#if 0
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "IP=%s dfreq=%f doff=%f",
|
LOG(LOGS_INFO, LOGF_Sources, "IP=%s dfreq=%f doff=%f",
|
||||||
UTI_IPToDottedQuad(records[i].remote_addr.ip_addr), dfreq, doffset);
|
UTI_IPToString(&records[i].remote_addr->ip_addr), dfreq, doffset);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NCR_SlewTimes(records[i].data, cooked, dfreq, doffset);
|
NCR_SlewTimes(records[i].data, cooked, dfreq, doffset);
|
||||||
@@ -308,17 +331,16 @@ slew_sources(struct timeval *raw,
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
int
|
int
|
||||||
NSR_TakeSourcesOnline(unsigned long mask, unsigned long address)
|
NSR_TakeSourcesOnline(IPAddr *mask, IPAddr *address)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int any;
|
int any;
|
||||||
unsigned long ip;
|
|
||||||
|
|
||||||
any = 0;
|
any = 0;
|
||||||
for (i=0; i<N_RECORDS; i++) {
|
for (i=0; i<N_RECORDS; i++) {
|
||||||
if (records[i].in_use) {
|
if (records[i].remote_addr) {
|
||||||
ip = records[i].remote_addr.ip_addr;
|
if (address->family == IPADDR_UNSPEC ||
|
||||||
if ((ip & mask) == address) {
|
!UTI_CompareIPs(&records[i].remote_addr->ip_addr, address, mask)) {
|
||||||
any = 1;
|
any = 1;
|
||||||
NCR_TakeSourceOnline(records[i].data);
|
NCR_TakeSourceOnline(records[i].data);
|
||||||
}
|
}
|
||||||
@@ -331,17 +353,16 @@ NSR_TakeSourcesOnline(unsigned long mask, unsigned long address)
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
int
|
int
|
||||||
NSR_TakeSourcesOffline(unsigned long mask, unsigned long address)
|
NSR_TakeSourcesOffline(IPAddr *mask, IPAddr *address)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int any;
|
int any;
|
||||||
unsigned long ip;
|
|
||||||
|
|
||||||
any = 0;
|
any = 0;
|
||||||
for (i=0; i<N_RECORDS; i++) {
|
for (i=0; i<N_RECORDS; i++) {
|
||||||
if (records[i].in_use) {
|
if (records[i].remote_addr) {
|
||||||
ip = records[i].remote_addr.ip_addr;
|
if (address->family == IPADDR_UNSPEC ||
|
||||||
if ((ip & mask) == address) {
|
!UTI_CompareIPs(&records[i].remote_addr->ip_addr, address, mask)) {
|
||||||
any = 1;
|
any = 1;
|
||||||
NCR_TakeSourceOffline(records[i].data);
|
NCR_TakeSourceOffline(records[i].data);
|
||||||
}
|
}
|
||||||
@@ -354,11 +375,11 @@ NSR_TakeSourcesOffline(unsigned long mask, unsigned long address)
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
int
|
int
|
||||||
NSR_ModifyMinpoll(unsigned long address, int new_minpoll)
|
NSR_ModifyMinpoll(IPAddr *address, int new_minpoll)
|
||||||
{
|
{
|
||||||
int slot, found;
|
int slot, found;
|
||||||
NTP_Remote_Address addr;
|
NTP_Remote_Address addr;
|
||||||
addr.ip_addr = address;
|
addr.ip_addr = *address;
|
||||||
addr.port = 0;
|
addr.port = 0;
|
||||||
|
|
||||||
find_slot(&addr, &slot, &found);
|
find_slot(&addr, &slot, &found);
|
||||||
@@ -373,11 +394,11 @@ NSR_ModifyMinpoll(unsigned long address, int new_minpoll)
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
int
|
int
|
||||||
NSR_ModifyMaxpoll(unsigned long address, int new_maxpoll)
|
NSR_ModifyMaxpoll(IPAddr *address, int new_maxpoll)
|
||||||
{
|
{
|
||||||
int slot, found;
|
int slot, found;
|
||||||
NTP_Remote_Address addr;
|
NTP_Remote_Address addr;
|
||||||
addr.ip_addr = address;
|
addr.ip_addr = *address;
|
||||||
addr.port = 0;
|
addr.port = 0;
|
||||||
|
|
||||||
find_slot(&addr, &slot, &found);
|
find_slot(&addr, &slot, &found);
|
||||||
@@ -392,11 +413,11 @@ NSR_ModifyMaxpoll(unsigned long address, int new_maxpoll)
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
int
|
int
|
||||||
NSR_ModifyMaxdelay(unsigned long address, double new_max_delay)
|
NSR_ModifyMaxdelay(IPAddr *address, double new_max_delay)
|
||||||
{
|
{
|
||||||
int slot, found;
|
int slot, found;
|
||||||
NTP_Remote_Address addr;
|
NTP_Remote_Address addr;
|
||||||
addr.ip_addr = address;
|
addr.ip_addr = *address;
|
||||||
addr.port = 0;
|
addr.port = 0;
|
||||||
|
|
||||||
find_slot(&addr, &slot, &found);
|
find_slot(&addr, &slot, &found);
|
||||||
@@ -411,11 +432,11 @@ NSR_ModifyMaxdelay(unsigned long address, double new_max_delay)
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
int
|
int
|
||||||
NSR_ModifyMaxdelayratio(unsigned long address, double new_max_delay_ratio)
|
NSR_ModifyMaxdelayratio(IPAddr *address, double new_max_delay_ratio)
|
||||||
{
|
{
|
||||||
int slot, found;
|
int slot, found;
|
||||||
NTP_Remote_Address addr;
|
NTP_Remote_Address addr;
|
||||||
addr.ip_addr = address;
|
addr.ip_addr = *address;
|
||||||
addr.port = 0;
|
addr.port = 0;
|
||||||
|
|
||||||
find_slot(&addr, &slot, &found);
|
find_slot(&addr, &slot, &found);
|
||||||
@@ -431,17 +452,16 @@ NSR_ModifyMaxdelayratio(unsigned long address, double new_max_delay_ratio)
|
|||||||
|
|
||||||
int
|
int
|
||||||
NSR_InitiateSampleBurst(int n_good_samples, int n_total_samples,
|
NSR_InitiateSampleBurst(int n_good_samples, int n_total_samples,
|
||||||
unsigned long mask, unsigned long address)
|
IPAddr *mask, IPAddr *address)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int any;
|
int any;
|
||||||
unsigned long ip;
|
|
||||||
|
|
||||||
any = 0;
|
any = 0;
|
||||||
for (i=0; i<N_RECORDS; i++) {
|
for (i=0; i<N_RECORDS; i++) {
|
||||||
if (records[i].in_use) {
|
if (records[i].remote_addr) {
|
||||||
ip = records[i].remote_addr.ip_addr;
|
if (address->family == IPADDR_UNSPEC ||
|
||||||
if ((ip & mask) == address) {
|
!UTI_CompareIPs(&records[i].remote_addr->ip_addr, address, mask)) {
|
||||||
any = 1;
|
any = 1;
|
||||||
NCR_InitiateSampleBurst(records[i].data, n_good_samples, n_total_samples);
|
NCR_InitiateSampleBurst(records[i].data, n_good_samples, n_total_samples);
|
||||||
}
|
}
|
||||||
@@ -486,7 +506,7 @@ NSR_GetActivityReport(RPT_ActivityReport *report)
|
|||||||
report->burst_offline = 0;
|
report->burst_offline = 0;
|
||||||
|
|
||||||
for (i=0; i<N_RECORDS; i++) {
|
for (i=0; i<N_RECORDS; i++) {
|
||||||
if (records[i].in_use) {
|
if (records[i].remote_addr) {
|
||||||
NCR_IncrementActivityCounters(records[i].data, &report->online, &report->offline,
|
NCR_IncrementActivityCounters(records[i].data, &report->online, &report->offline,
|
||||||
&report->burst_online, &report->burst_offline);
|
&report->burst_online, &report->burst_offline);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -46,7 +46,8 @@ typedef enum {
|
|||||||
NSR_Success, /* Operation successful */
|
NSR_Success, /* Operation successful */
|
||||||
NSR_NoSuchSource, /* Remove - attempt to remove a source that is not known */
|
NSR_NoSuchSource, /* Remove - attempt to remove a source that is not known */
|
||||||
NSR_AlreadyInUse, /* AddServer, AddPeer - attempt to add a source that is already known */
|
NSR_AlreadyInUse, /* AddServer, AddPeer - attempt to add a source that is already known */
|
||||||
NSR_TooManySources /* AddServer, AddPeer - too many sources already present */
|
NSR_TooManySources, /* AddServer, AddPeer - too many sources already present */
|
||||||
|
NSR_InvalidAF /* AddServer, AddPeer - attempt to add a source with invalid address family */
|
||||||
} NSR_Status;
|
} NSR_Status;
|
||||||
|
|
||||||
/* Procedure to add a new server source (to which this machine will be
|
/* Procedure to add a new server source (to which this machine will be
|
||||||
@@ -75,22 +76,22 @@ extern void NSR_Finalise(void);
|
|||||||
/* This routine is used to indicate that sources whose IP addresses
|
/* This routine is used to indicate that sources whose IP addresses
|
||||||
match a particular subnet should be set online again. Returns a
|
match a particular subnet should be set online again. Returns a
|
||||||
flag indicating whether any hosts matched the address */
|
flag indicating whether any hosts matched the address */
|
||||||
extern int NSR_TakeSourcesOnline(unsigned long mask, unsigned long address);
|
extern int NSR_TakeSourcesOnline(IPAddr *mask, IPAddr *address);
|
||||||
|
|
||||||
/* This routine is used to indicate that sources whose IP addresses
|
/* This routine is used to indicate that sources whose IP addresses
|
||||||
match a particular subnet should be set offline. Returns a flag
|
match a particular subnet should be set offline. Returns a flag
|
||||||
indicating whether any hosts matched the address */
|
indicating whether any hosts matched the address */
|
||||||
extern int NSR_TakeSourcesOffline(unsigned long mask, unsigned long address);
|
extern int NSR_TakeSourcesOffline(IPAddr *mask, IPAddr *address);
|
||||||
|
|
||||||
extern int NSR_ModifyMinpoll(unsigned long address, int new_minpoll);
|
extern int NSR_ModifyMinpoll(IPAddr *address, int new_minpoll);
|
||||||
|
|
||||||
extern int NSR_ModifyMaxpoll(unsigned long address, int new_maxpoll);
|
extern int NSR_ModifyMaxpoll(IPAddr *address, int new_maxpoll);
|
||||||
|
|
||||||
extern int NSR_ModifyMaxdelay(unsigned long address, double new_max_delay);
|
extern int NSR_ModifyMaxdelay(IPAddr *address, double new_max_delay);
|
||||||
|
|
||||||
extern int NSR_ModifyMaxdelayratio(unsigned long address, double new_max_delay_ratio);
|
extern int NSR_ModifyMaxdelayratio(IPAddr *address, double new_max_delay_ratio);
|
||||||
|
|
||||||
extern int NSR_InitiateSampleBurst(int n_good_samples, int n_total_samples, unsigned long mask, unsigned long address);
|
extern int NSR_InitiateSampleBurst(int n_good_samples, int n_total_samples, IPAddr *mask, IPAddr *address);
|
||||||
|
|
||||||
extern void NSR_ReportSource(RPT_SourceReport *report, struct timeval *now);
|
extern void NSR_ReportSource(RPT_SourceReport *report, struct timeval *now);
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
627
refclock.c
Normal file
627
refclock.c
Normal file
@@ -0,0 +1,627 @@
|
|||||||
|
/*
|
||||||
|
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||||
|
|
||||||
|
**********************************************************************
|
||||||
|
* Copyright (C) Miroslav Lichvar 2009
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Routines implementing reference clocks.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "refclock.h"
|
||||||
|
#include "reference.h"
|
||||||
|
#include "conf.h"
|
||||||
|
#include "local.h"
|
||||||
|
#include "memory.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "sources.h"
|
||||||
|
#include "logging.h"
|
||||||
|
#include "sched.h"
|
||||||
|
#include "mkdirpp.h"
|
||||||
|
|
||||||
|
/* list of refclock drivers */
|
||||||
|
extern RefclockDriver RCL_SHM_driver;
|
||||||
|
extern RefclockDriver RCL_SOCK_driver;
|
||||||
|
extern RefclockDriver RCL_PPS_driver;
|
||||||
|
|
||||||
|
struct FilterSample {
|
||||||
|
double offset;
|
||||||
|
struct timeval sample_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MedianFilter {
|
||||||
|
int length;
|
||||||
|
int index;
|
||||||
|
int used;
|
||||||
|
struct FilterSample *samples;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RCL_Instance_Record {
|
||||||
|
RefclockDriver *driver;
|
||||||
|
void *data;
|
||||||
|
char *driver_parameter;
|
||||||
|
int driver_poll;
|
||||||
|
int driver_polled;
|
||||||
|
int poll;
|
||||||
|
int missed_samples;
|
||||||
|
int leap_status;
|
||||||
|
int pps_rate;
|
||||||
|
struct MedianFilter filter;
|
||||||
|
unsigned long ref_id;
|
||||||
|
double offset;
|
||||||
|
double delay;
|
||||||
|
SCH_TimeoutID timeout_id;
|
||||||
|
SRC_Instance source;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_RCL_SOURCES 8
|
||||||
|
|
||||||
|
static struct RCL_Instance_Record refclocks[MAX_RCL_SOURCES];
|
||||||
|
static int n_sources = 0;
|
||||||
|
|
||||||
|
#define REFCLOCKS_LOG "refclocks.log"
|
||||||
|
static FILE *logfile = NULL;
|
||||||
|
static char *logfilename = NULL;
|
||||||
|
static unsigned long logwrites = 0;
|
||||||
|
|
||||||
|
static int valid_sample_time(RCL_Instance instance, struct timeval *tv);
|
||||||
|
static int pps_stratum(RCL_Instance instance, struct timeval *tv);
|
||||||
|
static void poll_timeout(void *arg);
|
||||||
|
static void slew_samples(struct timeval *raw, struct timeval *cooked, double dfreq, double afreq,
|
||||||
|
double doffset, int is_step_change, void *anything);
|
||||||
|
static void log_sample(RCL_Instance instance, struct timeval *sample_time, int pulse, double raw_offset, double cooked_offset);
|
||||||
|
|
||||||
|
static void filter_init(struct MedianFilter *filter, int length);
|
||||||
|
static void filter_fini(struct MedianFilter *filter);
|
||||||
|
static void filter_reset(struct MedianFilter *filter);
|
||||||
|
static void filter_add_sample(struct MedianFilter *filter, struct timeval *sample_time, double offset);
|
||||||
|
static int filter_get_sample(struct MedianFilter *filter, struct timeval *sample_time, double *offset, double *dispersion);
|
||||||
|
static void filter_slew_samples(struct MedianFilter *filter, struct timeval *when, double dfreq, double doffset);
|
||||||
|
|
||||||
|
void
|
||||||
|
RCL_Initialise(void)
|
||||||
|
{
|
||||||
|
CNF_AddRefclocks();
|
||||||
|
|
||||||
|
if (CNF_GetLogRefclocks()) {
|
||||||
|
char *logdir = CNF_GetLogDir();
|
||||||
|
if (!mkdir_and_parents(logdir)) {
|
||||||
|
LOG(LOGS_ERR, LOGF_Refclock, "Could not create directory %s", logdir);
|
||||||
|
} else {
|
||||||
|
logfilename = MallocArray(char, 2 + strlen(logdir) + strlen(REFCLOCKS_LOG));
|
||||||
|
strcpy(logfilename, logdir);
|
||||||
|
strcat(logfilename, "/");
|
||||||
|
strcat(logfilename, REFCLOCKS_LOG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RCL_Finalise(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < n_sources; i++) {
|
||||||
|
RCL_Instance inst = (RCL_Instance)&refclocks[i];
|
||||||
|
|
||||||
|
if (inst->driver->fini)
|
||||||
|
inst->driver->fini(inst);
|
||||||
|
|
||||||
|
filter_fini(&inst->filter);
|
||||||
|
Free(inst->driver_parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n_sources > 0)
|
||||||
|
LCL_RemoveParameterChangeHandler(slew_samples, NULL);
|
||||||
|
|
||||||
|
if (logfile)
|
||||||
|
fclose(logfile);
|
||||||
|
Free(logfilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
RCL_AddRefclock(RefclockParameters *params)
|
||||||
|
{
|
||||||
|
int pps_source = 0;
|
||||||
|
|
||||||
|
RCL_Instance inst = &refclocks[n_sources];
|
||||||
|
|
||||||
|
if (n_sources == MAX_RCL_SOURCES)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (strncmp(params->driver_name, "SHM", 4) == 0) {
|
||||||
|
inst->driver = &RCL_SHM_driver;
|
||||||
|
} else if (strncmp(params->driver_name, "SOCK", 4) == 0) {
|
||||||
|
inst->driver = &RCL_SOCK_driver;
|
||||||
|
pps_source = 1;
|
||||||
|
} else if (strncmp(params->driver_name, "PPS", 4) == 0) {
|
||||||
|
inst->driver = &RCL_PPS_driver;
|
||||||
|
pps_source = 1;
|
||||||
|
} else {
|
||||||
|
LOG_FATAL(LOGF_Refclock, "unknown refclock driver %s", params->driver_name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inst->driver->init && !inst->driver->poll) {
|
||||||
|
LOG_FATAL(LOGF_Refclock, "refclock driver %s is not compiled in", params->driver_name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inst->data = NULL;
|
||||||
|
inst->driver_parameter = params->driver_parameter;
|
||||||
|
inst->driver_poll = params->driver_poll;
|
||||||
|
inst->poll = params->poll;
|
||||||
|
inst->missed_samples = 0;
|
||||||
|
inst->driver_polled = 0;
|
||||||
|
inst->leap_status = 0;
|
||||||
|
inst->pps_rate = params->pps_rate;
|
||||||
|
inst->offset = params->offset;
|
||||||
|
inst->delay = params->delay;
|
||||||
|
inst->timeout_id = -1;
|
||||||
|
inst->source = NULL;
|
||||||
|
|
||||||
|
if (pps_source) {
|
||||||
|
if (inst->pps_rate < 1)
|
||||||
|
inst->pps_rate = 1;
|
||||||
|
} else {
|
||||||
|
inst->pps_rate = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inst->driver_poll > inst->poll)
|
||||||
|
inst->driver_poll = inst->poll;
|
||||||
|
|
||||||
|
if (params->ref_id)
|
||||||
|
inst->ref_id = params->ref_id;
|
||||||
|
else {
|
||||||
|
unsigned char ref[5] = { 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
snprintf((char *)ref, 5, "%3s%d", params->driver_name, n_sources % 10);
|
||||||
|
inst->ref_id = ref[0] << 24 | ref[1] << 16 | ref[2] << 8 | ref[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inst->driver->init)
|
||||||
|
if (!inst->driver->init(inst)) {
|
||||||
|
LOG_FATAL(LOGF_Refclock, "refclock %s initialisation failed", params->driver_name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
filter_init(&inst->filter, params->filter_length);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
LOG(LOGS_INFO, LOGF_Refclock, "refclock added poll=%d dpoll=%d filter=%d",
|
||||||
|
inst->poll, inst->driver_poll, params->filter_length);
|
||||||
|
#endif
|
||||||
|
n_sources++;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RCL_StartRefclocks(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < n_sources; i++) {
|
||||||
|
RCL_Instance inst = &refclocks[i];
|
||||||
|
|
||||||
|
inst->source = SRC_CreateNewInstance(inst->ref_id, SRC_REFCLOCK, NULL);
|
||||||
|
inst->timeout_id = SCH_AddTimeoutByDelay(0.0, poll_timeout, (void *)inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n_sources > 0)
|
||||||
|
LCL_AddParameterChangeHandler(slew_samples, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RCL_ReportSource(RPT_SourceReport *report, struct timeval *now)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned long ref_id;
|
||||||
|
|
||||||
|
assert(report->ip_addr.family == IPADDR_INET4);
|
||||||
|
ref_id = report->ip_addr.addr.in4;
|
||||||
|
|
||||||
|
for (i = 0; i < n_sources; i++) {
|
||||||
|
RCL_Instance inst = &refclocks[i];
|
||||||
|
if (inst->ref_id == ref_id) {
|
||||||
|
report->poll = inst->poll;
|
||||||
|
report->mode = RPT_LOCAL_REFERENCE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RCL_SetDriverData(RCL_Instance instance, void *data)
|
||||||
|
{
|
||||||
|
instance->data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
RCL_GetDriverData(RCL_Instance instance)
|
||||||
|
{
|
||||||
|
return instance->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
RCL_GetDriverParameter(RCL_Instance instance)
|
||||||
|
{
|
||||||
|
return instance->driver_parameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
RCL_AddSample(RCL_Instance instance, struct timeval *sample_time, double offset, NTP_Leap leap_status)
|
||||||
|
{
|
||||||
|
double correction;
|
||||||
|
struct timeval cooked_time;
|
||||||
|
|
||||||
|
correction = LCL_GetOffsetCorrection(sample_time);
|
||||||
|
UTI_AddDoubleToTimeval(sample_time, correction, &cooked_time);
|
||||||
|
|
||||||
|
if (!valid_sample_time(instance, sample_time))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
LOG(LOGS_INFO, LOGF_Refclock, "refclock sample offset=%.9f cooked=%.9f",
|
||||||
|
offset, offset - correction + instance->offset);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
filter_add_sample(&instance->filter, &cooked_time, offset - correction + instance->offset);
|
||||||
|
instance->leap_status = leap_status;
|
||||||
|
|
||||||
|
log_sample(instance, &cooked_time, 0, offset, offset - correction + instance->offset);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
RCL_AddPulse(RCL_Instance instance, struct timeval *pulse_time, double second)
|
||||||
|
{
|
||||||
|
double correction, offset;
|
||||||
|
struct timeval cooked_time;
|
||||||
|
int rate;
|
||||||
|
|
||||||
|
struct timeval ref_time;
|
||||||
|
int is_synchronised, stratum;
|
||||||
|
double root_delay, root_dispersion, distance;
|
||||||
|
NTP_Leap leap;
|
||||||
|
unsigned long ref_id;
|
||||||
|
|
||||||
|
correction = LCL_GetOffsetCorrection(pulse_time);
|
||||||
|
UTI_AddDoubleToTimeval(pulse_time, correction, &cooked_time);
|
||||||
|
|
||||||
|
if (!valid_sample_time(instance, pulse_time))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rate = instance->pps_rate;
|
||||||
|
assert(rate > 0);
|
||||||
|
|
||||||
|
/* Ignore the pulse if we are not well synchronized */
|
||||||
|
|
||||||
|
REF_GetReferenceParams(&cooked_time, &is_synchronised, &leap, &stratum,
|
||||||
|
&ref_id, &ref_time, &root_delay, &root_dispersion);
|
||||||
|
distance = fabs(root_delay) / 2 + root_dispersion;
|
||||||
|
|
||||||
|
if (!is_synchronised || distance >= 0.5 / rate) {
|
||||||
|
#if 0
|
||||||
|
LOG(LOGS_INFO, LOGF_Refclock, "refclock pulse dropped second=%.9f sync=%d dist=%.9f",
|
||||||
|
second, is_synchronised, distance);
|
||||||
|
#endif
|
||||||
|
/* Drop also all stored samples */
|
||||||
|
filter_reset(&instance->filter);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = -second - correction + instance->offset;
|
||||||
|
|
||||||
|
/* Adjust the offset to [-0.5/rate, 0.5/rate) interval */
|
||||||
|
offset -= (long)(offset * rate) / (double)rate;
|
||||||
|
if (offset < -0.5 / rate)
|
||||||
|
offset += 1.0 / rate;
|
||||||
|
else if (offset >= 0.5 / rate)
|
||||||
|
offset -= 1.0 / rate;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
LOG(LOGS_INFO, LOGF_Refclock, "refclock pulse second=%.9f offset=%.9f",
|
||||||
|
second, offset + instance->offset);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
filter_add_sample(&instance->filter, &cooked_time, offset);
|
||||||
|
instance->leap_status = LEAP_Normal;
|
||||||
|
|
||||||
|
log_sample(instance, &cooked_time, 1, second, offset);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RCL_CycleLogFile(void)
|
||||||
|
{
|
||||||
|
if (logfile) {
|
||||||
|
fclose(logfile);
|
||||||
|
logfile = NULL;
|
||||||
|
logwrites = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
valid_sample_time(RCL_Instance instance, struct timeval *tv)
|
||||||
|
{
|
||||||
|
struct timeval raw_time;
|
||||||
|
double diff;
|
||||||
|
|
||||||
|
LCL_ReadRawTime(&raw_time);
|
||||||
|
UTI_DiffTimevalsToDouble(&diff, &raw_time, tv);
|
||||||
|
if (diff < 0.0 || diff > 1 << (instance->poll + 1))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pps_stratum(RCL_Instance instance, struct timeval *tv)
|
||||||
|
{
|
||||||
|
struct timeval ref_time;
|
||||||
|
int is_synchronised, stratum, i;
|
||||||
|
double root_delay, root_dispersion;
|
||||||
|
NTP_Leap leap;
|
||||||
|
unsigned long ref_id;
|
||||||
|
|
||||||
|
REF_GetReferenceParams(tv, &is_synchronised, &leap, &stratum,
|
||||||
|
&ref_id, &ref_time, &root_delay, &root_dispersion);
|
||||||
|
|
||||||
|
/* Don't change our stratum if local stratum is active
|
||||||
|
or this is the current source */
|
||||||
|
if (ref_id == instance->ref_id || REF_IsLocalActive())
|
||||||
|
return stratum - 1;
|
||||||
|
|
||||||
|
/* Or the current source is another PPS refclock */
|
||||||
|
for (i = 0; i < n_sources; i++) {
|
||||||
|
if (refclocks[i].ref_id == ref_id && refclocks[i].pps_rate)
|
||||||
|
return stratum - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
poll_timeout(void *arg)
|
||||||
|
{
|
||||||
|
double next;
|
||||||
|
int poll;
|
||||||
|
|
||||||
|
RCL_Instance inst = (RCL_Instance)arg;
|
||||||
|
|
||||||
|
poll = inst->poll;
|
||||||
|
|
||||||
|
if (inst->driver->poll) {
|
||||||
|
poll = inst->driver_poll;
|
||||||
|
inst->driver->poll(inst);
|
||||||
|
inst->driver_polled++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(inst->driver->poll && inst->driver_polled < (1 << (inst->poll - inst->driver_poll)))) {
|
||||||
|
double offset, dispersion;
|
||||||
|
struct timeval sample_time;
|
||||||
|
int sample_ok, stratum;
|
||||||
|
|
||||||
|
sample_ok = filter_get_sample(&inst->filter, &sample_time, &offset, &dispersion);
|
||||||
|
filter_reset(&inst->filter);
|
||||||
|
inst->driver_polled = 0;
|
||||||
|
|
||||||
|
if (sample_ok) {
|
||||||
|
#if 0
|
||||||
|
LOG(LOGS_INFO, LOGF_Refclock, "refclock filtered sample: offset=%.9f dispersion=%.9f [%s]",
|
||||||
|
offset, dispersion, UTI_TimevalToString(&sample_time));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (inst->pps_rate)
|
||||||
|
/* Handle special case when PPS is used with local stratum */
|
||||||
|
stratum = pps_stratum(inst, &sample_time);
|
||||||
|
else
|
||||||
|
stratum = 0;
|
||||||
|
|
||||||
|
SRC_SetReachable(inst->source);
|
||||||
|
SRC_AccumulateSample(inst->source, &sample_time, offset,
|
||||||
|
inst->delay, dispersion, inst->delay, dispersion, stratum, inst->leap_status);
|
||||||
|
inst->missed_samples = 0;
|
||||||
|
} else {
|
||||||
|
inst->missed_samples++;
|
||||||
|
if (inst->missed_samples > 9)
|
||||||
|
SRC_UnsetReachable(inst->source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (poll >= 0)
|
||||||
|
next = 1 << poll;
|
||||||
|
else
|
||||||
|
next = 1.0 / (1 << -poll);
|
||||||
|
|
||||||
|
inst->timeout_id = SCH_AddTimeoutByDelay(next, poll_timeout, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
slew_samples(struct timeval *raw, struct timeval *cooked, double dfreq, double afreq,
|
||||||
|
double doffset, int is_step_change, void *anything)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < n_sources; i++)
|
||||||
|
filter_slew_samples(&refclocks[i].filter, cooked, dfreq, doffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
log_sample(RCL_Instance instance, struct timeval *sample_time, int pulse, double raw_offset, double cooked_offset)
|
||||||
|
{
|
||||||
|
char sync_stats[4] = {'N', '+', '-', '?'};
|
||||||
|
|
||||||
|
if (!logfilename)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!logfile) {
|
||||||
|
logfile = fopen(logfilename, "a");
|
||||||
|
if (!logfile) {
|
||||||
|
LOG(LOGS_WARN, LOGF_Refclock, "Couldn't open logfile %s for update", logfilename);
|
||||||
|
Free(logfilename);
|
||||||
|
logfilename = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((logwrites++) % 32) == 0) {
|
||||||
|
fprintf(logfile,
|
||||||
|
"====================================================================\n"
|
||||||
|
" Date (UTC) Time Refid DP L P Raw offset Cooked offset\n"
|
||||||
|
"====================================================================\n");
|
||||||
|
}
|
||||||
|
fprintf(logfile, "%s.%06d %-5s %3d %1c %1d %13.6e %13.6e\n",
|
||||||
|
UTI_TimeToLogForm(sample_time->tv_sec),
|
||||||
|
(int)sample_time->tv_usec,
|
||||||
|
UTI_RefidToString(instance->ref_id),
|
||||||
|
instance->driver_polled,
|
||||||
|
sync_stats[instance->leap_status],
|
||||||
|
pulse,
|
||||||
|
raw_offset,
|
||||||
|
cooked_offset);
|
||||||
|
fflush(logfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
filter_init(struct MedianFilter *filter, int length)
|
||||||
|
{
|
||||||
|
if (length < 1)
|
||||||
|
length = 1;
|
||||||
|
|
||||||
|
filter->length = length;
|
||||||
|
filter->index = -1;
|
||||||
|
filter->used = 0;
|
||||||
|
filter->samples = MallocArray(struct FilterSample, filter->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
filter_fini(struct MedianFilter *filter)
|
||||||
|
{
|
||||||
|
Free(filter->samples);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
filter_reset(struct MedianFilter *filter)
|
||||||
|
{
|
||||||
|
filter->index = -1;
|
||||||
|
filter->used = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
filter_add_sample(struct MedianFilter *filter, struct timeval *sample_time, double offset)
|
||||||
|
{
|
||||||
|
filter->index++;
|
||||||
|
filter->index %= filter->length;
|
||||||
|
if (filter->used < filter->length)
|
||||||
|
filter->used++;
|
||||||
|
|
||||||
|
filter->samples[filter->index].sample_time = *sample_time;
|
||||||
|
filter->samples[filter->index].offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sample_compare(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const struct FilterSample *s1 = a, *s2 = b;
|
||||||
|
|
||||||
|
if (s1->offset < s2->offset)
|
||||||
|
return -1;
|
||||||
|
else if (s1->offset > s2->offset)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
filter_get_sample(struct MedianFilter *filter, struct timeval *sample_time, double *offset, double *dispersion)
|
||||||
|
{
|
||||||
|
if (filter->used == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (filter->used == 1) {
|
||||||
|
*sample_time = filter->samples[filter->index].sample_time;
|
||||||
|
*offset = filter->samples[filter->index].offset;
|
||||||
|
*dispersion = 0.0;
|
||||||
|
} else {
|
||||||
|
int i, from, to;
|
||||||
|
double x, x1, y, d;
|
||||||
|
|
||||||
|
/* sort samples by offset */
|
||||||
|
qsort(filter->samples, filter->used, sizeof (struct FilterSample), sample_compare);
|
||||||
|
|
||||||
|
/* average the half of the samples closest to the median */
|
||||||
|
if (filter->used > 2) {
|
||||||
|
from = (filter->used + 2) / 4;
|
||||||
|
to = filter->used - from;
|
||||||
|
} else {
|
||||||
|
from = 0;
|
||||||
|
to = filter->used;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = from, x = y = 0.0; i < to; i++) {
|
||||||
|
#if 0
|
||||||
|
LOG(LOGS_INFO, LOGF_Refclock, "refclock averaging offset %.9f [%s]",
|
||||||
|
filter->samples[i].offset, UTI_TimevalToString(&filter->samples[i].sample_time));
|
||||||
|
#endif
|
||||||
|
UTI_DiffTimevalsToDouble(&x1, &filter->samples[i].sample_time, &filter->samples[0].sample_time);
|
||||||
|
x += x1;
|
||||||
|
y += filter->samples[i].offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
x /= to - from;
|
||||||
|
y /= to - from;
|
||||||
|
|
||||||
|
for (i = from, d = 0.0; i < to; i++)
|
||||||
|
d += (filter->samples[i].offset - y) * (filter->samples[i].offset - y);
|
||||||
|
|
||||||
|
d = sqrt(d / (to - from));
|
||||||
|
|
||||||
|
UTI_AddDoubleToTimeval(&filter->samples[0].sample_time, x, sample_time);
|
||||||
|
*offset = y;
|
||||||
|
*dispersion = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
filter_slew_samples(struct MedianFilter *filter, struct timeval *when, double dfreq, double doffset)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
double elapsed, delta_time, prev_offset;
|
||||||
|
struct timeval *sample;
|
||||||
|
|
||||||
|
for (i = 0; i < filter->used; i++) {
|
||||||
|
sample = &filter->samples[i].sample_time;
|
||||||
|
|
||||||
|
UTI_DiffTimevalsToDouble(&elapsed, when, sample);
|
||||||
|
delta_time = elapsed * dfreq - doffset;
|
||||||
|
UTI_AddDoubleToTimeval(sample, delta_time, sample);
|
||||||
|
|
||||||
|
prev_offset = filter->samples[i].offset;
|
||||||
|
filter->samples[i].offset -= delta_time;
|
||||||
|
#if 0
|
||||||
|
LOG(LOGS_INFO, LOGF_Refclock, "i=%d old_off=%.9f new_off=%.9f",
|
||||||
|
i, prev_offset, filter->samples[i].offset);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
69
refclock.h
Normal file
69
refclock.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||||
|
|
||||||
|
**********************************************************************
|
||||||
|
* Copyright (C) Miroslav Lichvar 2009
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Header file for refclocks.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GOT_REFCLOCK_H
|
||||||
|
#define GOT_REFCLOCK_H
|
||||||
|
|
||||||
|
#include "srcparams.h"
|
||||||
|
#include "sources.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char driver_name[4];
|
||||||
|
char *driver_parameter;
|
||||||
|
int driver_poll;
|
||||||
|
int poll;
|
||||||
|
int filter_length;
|
||||||
|
int pps_rate;
|
||||||
|
unsigned long ref_id;
|
||||||
|
double offset;
|
||||||
|
double delay;
|
||||||
|
} RefclockParameters;
|
||||||
|
|
||||||
|
typedef struct RCL_Instance_Record *RCL_Instance;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int (*init)(RCL_Instance instance);
|
||||||
|
void (*fini)(RCL_Instance instance);
|
||||||
|
int (*poll)(RCL_Instance instance);
|
||||||
|
} RefclockDriver;
|
||||||
|
|
||||||
|
extern void RCL_Initialise(void);
|
||||||
|
extern void RCL_Finalise(void);
|
||||||
|
extern int RCL_AddRefclock(RefclockParameters *params);
|
||||||
|
extern void RCL_StartRefclocks(void);
|
||||||
|
extern void RCL_StartRefclocks(void);
|
||||||
|
extern void RCL_ReportSource(RPT_SourceReport *report, struct timeval *now);
|
||||||
|
extern void RCL_CycleLogFile(void);
|
||||||
|
|
||||||
|
/* functions used by drivers */
|
||||||
|
extern void RCL_SetDriverData(RCL_Instance instance, void *data);
|
||||||
|
extern void *RCL_GetDriverData(RCL_Instance instance);
|
||||||
|
extern char *RCL_GetDriverParameter(RCL_Instance instance);
|
||||||
|
extern int RCL_AddSample(RCL_Instance instance, struct timeval *sample_time, double offset, NTP_Leap leap_status);
|
||||||
|
extern int RCL_AddPulse(RCL_Instance instance, struct timeval *pulse_time, double second);
|
||||||
|
|
||||||
|
#endif
|
||||||
168
refclock_pps.c
Normal file
168
refclock_pps.c
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||||
|
|
||||||
|
**********************************************************************
|
||||||
|
* Copyright (C) Miroslav Lichvar 2009
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
PPSAPI refclock driver.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "refclock.h"
|
||||||
|
|
||||||
|
#if HAVE_PPSAPI
|
||||||
|
|
||||||
|
#include <timepps.h>
|
||||||
|
|
||||||
|
#include "logging.h"
|
||||||
|
#include "memory.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
struct pps_instance {
|
||||||
|
pps_handle_t handle;
|
||||||
|
pps_seq_t last_seq;
|
||||||
|
int edge_clear;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int pps_initialise(RCL_Instance instance) {
|
||||||
|
pps_handle_t handle;
|
||||||
|
pps_params_t params;
|
||||||
|
struct pps_instance *pps;
|
||||||
|
int fd, edge_clear, mode;
|
||||||
|
char *path, *s;
|
||||||
|
|
||||||
|
path = RCL_GetDriverParameter(instance);
|
||||||
|
|
||||||
|
edge_clear = 0;
|
||||||
|
if ((s = strrchr(path, ':')) != NULL) {
|
||||||
|
*s = '\0';
|
||||||
|
edge_clear = atoi(s + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = open(path, O_RDWR);
|
||||||
|
if (fd < 0) {
|
||||||
|
LOG_FATAL(LOGF_Refclock, "open() failed on %s", path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (time_pps_create(fd, &handle) < 0) {
|
||||||
|
LOG_FATAL(LOGF_Refclock, "time_pps_create() failed on %s", path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (time_pps_getcap(handle, &mode) < 0) {
|
||||||
|
LOG_FATAL(LOGF_Refclock, "time_pps_getcap() failed on %s", path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (time_pps_getparams(handle, ¶ms) < 0) {
|
||||||
|
LOG_FATAL(LOGF_Refclock, "time_pps_getparams() failed on %s", path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!edge_clear) {
|
||||||
|
if (!(mode & PPS_CAPTUREASSERT)) {
|
||||||
|
LOG_FATAL(LOGF_Refclock, "CAPTUREASSERT not supported on %s", path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
params.mode |= PPS_CAPTUREASSERT;
|
||||||
|
params.mode &= ~PPS_CAPTURECLEAR;
|
||||||
|
} else {
|
||||||
|
if (!(mode & PPS_CAPTURECLEAR)) {
|
||||||
|
LOG_FATAL(LOGF_Refclock, "CAPTURECLEAR not supported on %s", path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
params.mode |= PPS_CAPTURECLEAR;
|
||||||
|
params.mode &= ~PPS_CAPTUREASSERT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (time_pps_setparams(handle, ¶ms) < 0) {
|
||||||
|
LOG_FATAL(LOGF_Refclock, "time_pps_setparams() failed on %s", path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pps = MallocNew(struct pps_instance);
|
||||||
|
pps->handle = handle;
|
||||||
|
pps->last_seq = 0;
|
||||||
|
pps->edge_clear = edge_clear;
|
||||||
|
|
||||||
|
RCL_SetDriverData(instance, pps);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pps_finalise(RCL_Instance instance)
|
||||||
|
{
|
||||||
|
struct pps_instance *pps;
|
||||||
|
|
||||||
|
pps = (struct pps_instance *)RCL_GetDriverData(instance);
|
||||||
|
time_pps_destroy(pps->handle);
|
||||||
|
Free(pps);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pps_poll(RCL_Instance instance)
|
||||||
|
{
|
||||||
|
struct pps_instance *pps;
|
||||||
|
struct timespec ts;
|
||||||
|
struct timeval tv;
|
||||||
|
pps_info_t pps_info;
|
||||||
|
pps_seq_t seq;
|
||||||
|
|
||||||
|
pps = (struct pps_instance *)RCL_GetDriverData(instance);
|
||||||
|
|
||||||
|
ts.tv_sec = 0;
|
||||||
|
ts.tv_nsec = 0;
|
||||||
|
|
||||||
|
if (time_pps_fetch(pps->handle, PPS_TSFMT_TSPEC, &pps_info, &ts) < 0) {
|
||||||
|
#if 0
|
||||||
|
LOG(LOGS_INFO, LOGF_Refclock, "time_pps_fetch error");
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pps->edge_clear) {
|
||||||
|
seq = pps_info.assert_sequence;
|
||||||
|
ts = pps_info.assert_timestamp;
|
||||||
|
} else {
|
||||||
|
seq = pps_info.clear_sequence;
|
||||||
|
ts = pps_info.clear_timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seq == pps->last_seq || (ts.tv_sec == 0 && ts.tv_nsec == 0)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pps->last_seq = seq;
|
||||||
|
tv.tv_sec = ts.tv_sec;
|
||||||
|
tv.tv_usec = ts.tv_nsec / 1000;
|
||||||
|
|
||||||
|
return RCL_AddPulse(instance, &tv, ts.tv_nsec / 1e9);
|
||||||
|
}
|
||||||
|
|
||||||
|
RefclockDriver RCL_PPS_driver = {
|
||||||
|
pps_initialise,
|
||||||
|
pps_finalise,
|
||||||
|
pps_poll
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
RefclockDriver RCL_PPS_driver = { NULL, NULL, NULL };
|
||||||
|
|
||||||
|
#endif
|
||||||
118
refclock_shm.c
Normal file
118
refclock_shm.c
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||||
|
|
||||||
|
**********************************************************************
|
||||||
|
* Copyright (C) Miroslav Lichvar 2009
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
SHM refclock driver.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "refclock.h"
|
||||||
|
#include "logging.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/shm.h>
|
||||||
|
|
||||||
|
#define SHMKEY 0x4e545030
|
||||||
|
|
||||||
|
struct shmTime {
|
||||||
|
int mode; /* 0 - if valid set
|
||||||
|
* use values,
|
||||||
|
* clear valid
|
||||||
|
* 1 - if valid set
|
||||||
|
* if count before and after read of values is equal,
|
||||||
|
* use values
|
||||||
|
* clear valid
|
||||||
|
*/
|
||||||
|
int count;
|
||||||
|
time_t clockTimeStampSec;
|
||||||
|
int clockTimeStampUSec;
|
||||||
|
time_t receiveTimeStampSec;
|
||||||
|
int receiveTimeStampUSec;
|
||||||
|
int leap;
|
||||||
|
int precision;
|
||||||
|
int nsamples;
|
||||||
|
int valid;
|
||||||
|
int dummy[10];
|
||||||
|
};
|
||||||
|
|
||||||
|
static int shm_initialise(RCL_Instance instance) {
|
||||||
|
int id, param;
|
||||||
|
struct shmTime *shm;
|
||||||
|
|
||||||
|
param = atoi(RCL_GetDriverParameter(instance));
|
||||||
|
|
||||||
|
id = shmget(SHMKEY + param, sizeof (struct shmTime), IPC_CREAT | 0700);
|
||||||
|
if (id == -1) {
|
||||||
|
LOG_FATAL(LOGF_Refclock, "shmget() failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
shm = (struct shmTime *)shmat(id, 0, 0);
|
||||||
|
if ((long)shm == -1) {
|
||||||
|
LOG_FATAL(LOGF_Refclock, "shmat() failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RCL_SetDriverData(instance, shm);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shm_finalise(RCL_Instance instance)
|
||||||
|
{
|
||||||
|
shmdt(RCL_GetDriverData(instance));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int shm_poll(RCL_Instance instance)
|
||||||
|
{
|
||||||
|
struct timeval tv1, tv2;
|
||||||
|
struct shmTime t, *shm;
|
||||||
|
double offset;
|
||||||
|
|
||||||
|
shm = (struct shmTime *)RCL_GetDriverData(instance);
|
||||||
|
|
||||||
|
t = *shm;
|
||||||
|
|
||||||
|
if ((t.mode == 1 && t.count != shm->count) ||
|
||||||
|
!(t.mode == 0 || t.mode == 1) || !t.valid) {
|
||||||
|
#if 0
|
||||||
|
LOG(LOGS_INFO, LOGF_Refclock, "sample ignored mode: %d count: %d valid: %d", t.mode, t.count, t.valid);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
shm->valid = 0;
|
||||||
|
|
||||||
|
tv1.tv_sec = t.receiveTimeStampSec;
|
||||||
|
tv1.tv_usec = t.receiveTimeStampUSec;
|
||||||
|
tv2.tv_sec = t.clockTimeStampSec;
|
||||||
|
tv2.tv_usec = t.clockTimeStampUSec;
|
||||||
|
|
||||||
|
UTI_DiffTimevalsToDouble(&offset, &tv2, &tv1);
|
||||||
|
return RCL_AddSample(instance, &tv1, offset, t.leap);
|
||||||
|
}
|
||||||
|
|
||||||
|
RefclockDriver RCL_SHM_driver = {
|
||||||
|
shm_initialise,
|
||||||
|
shm_finalise,
|
||||||
|
shm_poll
|
||||||
|
};
|
||||||
132
refclock_sock.c
Normal file
132
refclock_sock.c
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||||
|
|
||||||
|
**********************************************************************
|
||||||
|
* Copyright (C) Miroslav Lichvar 2009
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Unix domain socket refclock driver.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "refclock.h"
|
||||||
|
#include "logging.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "sched.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define SOCK_MAGIC 0x534f434b
|
||||||
|
|
||||||
|
struct sock_sample {
|
||||||
|
struct timeval tv;
|
||||||
|
double offset;
|
||||||
|
int pulse;
|
||||||
|
int leap;
|
||||||
|
int _pad;
|
||||||
|
int magic;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void read_sample(void *anything)
|
||||||
|
{
|
||||||
|
struct sock_sample sample;
|
||||||
|
RCL_Instance instance;
|
||||||
|
int sockfd, s;
|
||||||
|
|
||||||
|
instance = (RCL_Instance)anything;
|
||||||
|
sockfd = (long)RCL_GetDriverData(instance);
|
||||||
|
|
||||||
|
s = recv(sockfd, &sample, sizeof (sample), 0);
|
||||||
|
|
||||||
|
if (s < 0) {
|
||||||
|
#if 0
|
||||||
|
LOG(LOGS_INFO, LOGF_Refclock, "Error reading from SOCK socket : %s", strerror(errno));
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s != sizeof (sample)) {
|
||||||
|
#if 0
|
||||||
|
LOG(LOGS_INFO, LOGF_Refclock, "Unexpected length of SOCK sample : %d != %d", s, sizeof (sample));
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sample.magic != SOCK_MAGIC) {
|
||||||
|
#if 0
|
||||||
|
LOG(LOGS_INFO, LOGF_Refclock, "Unexpected magic number in SOCK sample : %x != %x", sample.magic, SOCK_MAGIC);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sample.pulse) {
|
||||||
|
RCL_AddPulse(instance, &sample.tv, sample.offset);
|
||||||
|
} else {
|
||||||
|
RCL_AddSample(instance, &sample.tv, sample.offset, sample.leap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sock_initialise(RCL_Instance instance)
|
||||||
|
{
|
||||||
|
struct sockaddr_un s;
|
||||||
|
int sockfd;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
path = RCL_GetDriverParameter(instance);
|
||||||
|
|
||||||
|
s.sun_family = AF_UNIX;
|
||||||
|
if (snprintf(s.sun_path, sizeof (s.sun_path), "%s", path) >= sizeof (s.sun_path)) {
|
||||||
|
LOG_FATAL(LOGF_Refclock, "path %s is too long", path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
|
||||||
|
if (sockfd < 0) {
|
||||||
|
LOG_FATAL(LOGF_Refclock, "socket() failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlink(path);
|
||||||
|
if (bind(sockfd, (struct sockaddr *)&s, sizeof (s)) < 0) {
|
||||||
|
LOG_FATAL(LOGF_Refclock, "bind() failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RCL_SetDriverData(instance, (void *)(long)sockfd);
|
||||||
|
SCH_AddInputFileHandler(sockfd, read_sample, instance);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sock_finalise(RCL_Instance instance)
|
||||||
|
{
|
||||||
|
int sockfd;
|
||||||
|
|
||||||
|
sockfd = (long)RCL_GetDriverData(instance);
|
||||||
|
SCH_RemoveInputFileHandler(sockfd);
|
||||||
|
close(sockfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
RefclockDriver RCL_SOCK_driver = {
|
||||||
|
sock_initialise,
|
||||||
|
sock_finalise,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
85
reference.c
85
reference.c
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
* Copyright (C) Richard P. Curnow 1997-2003
|
* Copyright (C) Richard P. Curnow 1997-2003
|
||||||
|
* Copyright (C) Miroslav Lichvar 2009
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of version 2 of the GNU General Public License as
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
@@ -19,7 +20,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -44,8 +45,10 @@ static int are_we_synchronised;
|
|||||||
static int enable_local_stratum;
|
static int enable_local_stratum;
|
||||||
static int local_stratum;
|
static int local_stratum;
|
||||||
static NTP_Leap our_leap_status;
|
static NTP_Leap our_leap_status;
|
||||||
|
static int our_leap_sec;
|
||||||
static int our_stratum;
|
static int our_stratum;
|
||||||
static unsigned long our_ref_id;
|
static unsigned long our_ref_id;
|
||||||
|
static IPAddr our_ref_ip;
|
||||||
struct timeval our_ref_time; /* Stored relative to reference, NOT local time */
|
struct timeval our_ref_time; /* Stored relative to reference, NOT local time */
|
||||||
static double our_offset;
|
static double our_offset;
|
||||||
static double our_skew;
|
static double our_skew;
|
||||||
@@ -102,7 +105,8 @@ REF_Initialise(void)
|
|||||||
double our_frequency_ppm;
|
double our_frequency_ppm;
|
||||||
|
|
||||||
are_we_synchronised = 0;
|
are_we_synchronised = 0;
|
||||||
our_leap_status = LEAP_Normal;
|
our_leap_status = LEAP_Unsynchronised;
|
||||||
|
our_leap_sec = 0;
|
||||||
initialised = 1;
|
initialised = 1;
|
||||||
our_root_dispersion = 1.0;
|
our_root_dispersion = 1.0;
|
||||||
our_root_delay = 1.0;
|
our_root_delay = 1.0;
|
||||||
@@ -176,6 +180,10 @@ REF_Initialise(void)
|
|||||||
void
|
void
|
||||||
REF_Finalise(void)
|
REF_Finalise(void)
|
||||||
{
|
{
|
||||||
|
if (our_leap_sec) {
|
||||||
|
LCL_SetLeap(0);
|
||||||
|
}
|
||||||
|
|
||||||
if (logfile) {
|
if (logfile) {
|
||||||
fclose(logfile);
|
fclose(logfile);
|
||||||
}
|
}
|
||||||
@@ -311,11 +319,50 @@ maybe_log_offset(double offset)
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_leap_status(NTP_Leap leap)
|
||||||
|
{
|
||||||
|
time_t now;
|
||||||
|
struct tm stm;
|
||||||
|
int leap_sec;
|
||||||
|
|
||||||
|
leap_sec = 0;
|
||||||
|
|
||||||
|
if (leap == LEAP_InsertSecond || leap == LEAP_DeleteSecond) {
|
||||||
|
/* Insert/delete leap second only on June 30 or December 31
|
||||||
|
and in other months ignore the leap status completely */
|
||||||
|
|
||||||
|
now = time(NULL);
|
||||||
|
stm = *gmtime(&now);
|
||||||
|
|
||||||
|
if (stm.tm_mon != 5 && stm.tm_mon != 11) {
|
||||||
|
leap = LEAP_Normal;
|
||||||
|
} else if ((stm.tm_mon == 5 && stm.tm_mday == 30) ||
|
||||||
|
(stm.tm_mon == 11 && stm.tm_mday == 31)) {
|
||||||
|
if (leap == LEAP_InsertSecond) {
|
||||||
|
leap_sec = 1;
|
||||||
|
} else {
|
||||||
|
leap_sec = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leap_sec != our_leap_sec) {
|
||||||
|
LCL_SetLeap(leap_sec);
|
||||||
|
our_leap_sec = leap_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
our_leap_status = leap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
REF_SetReference(int stratum,
|
REF_SetReference(int stratum,
|
||||||
NTP_Leap leap,
|
NTP_Leap leap,
|
||||||
unsigned long ref_id,
|
unsigned long ref_id,
|
||||||
|
IPAddr *ref_ip,
|
||||||
struct timeval *ref_time,
|
struct timeval *ref_time,
|
||||||
double offset,
|
double offset,
|
||||||
double frequency,
|
double frequency,
|
||||||
@@ -335,6 +382,12 @@ REF_SetReference(int stratum,
|
|||||||
|
|
||||||
assert(initialised);
|
assert(initialised);
|
||||||
|
|
||||||
|
/* Avoid getting NaNs */
|
||||||
|
if (skew == 0.0)
|
||||||
|
skew = 1e-10;
|
||||||
|
if (our_skew == 0.0)
|
||||||
|
our_skew = 1e-10;
|
||||||
|
|
||||||
/* If we get a serious rounding error in the source stats regression
|
/* If we get a serious rounding error in the source stats regression
|
||||||
processing, there is a remote chance that the skew argument is a
|
processing, there is a remote chance that the skew argument is a
|
||||||
'not a number'. If such a quantity gets propagated into the
|
'not a number'. If such a quantity gets propagated into the
|
||||||
@@ -356,13 +409,18 @@ REF_SetReference(int stratum,
|
|||||||
|
|
||||||
are_we_synchronised = 1;
|
are_we_synchronised = 1;
|
||||||
our_stratum = stratum + 1;
|
our_stratum = stratum + 1;
|
||||||
our_leap_status = leap;
|
|
||||||
our_ref_id = ref_id;
|
our_ref_id = ref_id;
|
||||||
|
if (ref_ip)
|
||||||
|
our_ref_ip = *ref_ip;
|
||||||
|
else
|
||||||
|
our_ref_ip.family = IPADDR_UNSPEC;
|
||||||
our_ref_time = *ref_time;
|
our_ref_time = *ref_time;
|
||||||
our_offset = offset;
|
our_offset = offset;
|
||||||
our_root_delay = root_delay;
|
our_root_delay = root_delay;
|
||||||
our_root_dispersion = root_dispersion;
|
our_root_dispersion = root_dispersion;
|
||||||
|
|
||||||
|
update_leap_status(leap);
|
||||||
|
|
||||||
/* Eliminate updates that are based on totally unreliable frequency
|
/* Eliminate updates that are based on totally unreliable frequency
|
||||||
information */
|
information */
|
||||||
|
|
||||||
@@ -423,7 +481,7 @@ REF_SetReference(int stratum,
|
|||||||
|
|
||||||
fprintf(logfile, "%s %-15s %2d %10.3f %10.3f %10.3e\n",
|
fprintf(logfile, "%s %-15s %2d %10.3f %10.3f %10.3e\n",
|
||||||
UTI_TimeToLogForm(ref_time->tv_sec),
|
UTI_TimeToLogForm(ref_time->tv_sec),
|
||||||
UTI_IPToDottedQuad(our_ref_id),
|
our_ref_ip.family != IPADDR_UNSPEC ? UTI_IPToString(&our_ref_ip) : UTI_RefidToString(our_ref_id),
|
||||||
our_stratum,
|
our_stratum,
|
||||||
abs_freq_ppm,
|
abs_freq_ppm,
|
||||||
1.0e6*our_skew,
|
1.0e6*our_skew,
|
||||||
@@ -517,6 +575,8 @@ REF_SetUnsynchronised(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
are_we_synchronised = 0;
|
are_we_synchronised = 0;
|
||||||
|
|
||||||
|
update_leap_status(LEAP_Unsynchronised);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -636,6 +696,14 @@ REF_DisableLocal(void)
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
int
|
||||||
|
REF_IsLocalActive(void)
|
||||||
|
{
|
||||||
|
return !are_we_synchronised && enable_local_stratum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
REF_GetTrackingReport(RPT_TrackingReport *rep)
|
REF_GetTrackingReport(RPT_TrackingReport *rep)
|
||||||
{
|
{
|
||||||
@@ -654,9 +722,10 @@ REF_GetTrackingReport(RPT_TrackingReport *rep)
|
|||||||
extra_dispersion = (our_skew + fabs(our_residual_freq)) * elapsed;
|
extra_dispersion = (our_skew + fabs(our_residual_freq)) * elapsed;
|
||||||
|
|
||||||
rep->ref_id = our_ref_id;
|
rep->ref_id = our_ref_id;
|
||||||
|
rep->ip_addr = our_ref_ip;
|
||||||
rep->stratum = our_stratum;
|
rep->stratum = our_stratum;
|
||||||
rep->ref_time = our_ref_time;
|
rep->ref_time = our_ref_time;
|
||||||
UTI_DoubleToTimeval(correction, &rep->current_correction);
|
rep->current_correction = correction;
|
||||||
rep->freq_ppm = LCL_ReadAbsoluteFrequency();
|
rep->freq_ppm = LCL_ReadAbsoluteFrequency();
|
||||||
rep->resid_freq_ppm = 1.0e6 * our_residual_freq;
|
rep->resid_freq_ppm = 1.0e6 * our_residual_freq;
|
||||||
rep->skew_ppm = 1.0e6 * our_skew;
|
rep->skew_ppm = 1.0e6 * our_skew;
|
||||||
@@ -666,9 +735,10 @@ REF_GetTrackingReport(RPT_TrackingReport *rep)
|
|||||||
} else if (enable_local_stratum) {
|
} else if (enable_local_stratum) {
|
||||||
|
|
||||||
rep->ref_id = LOCAL_REFERENCE_ID;
|
rep->ref_id = LOCAL_REFERENCE_ID;
|
||||||
|
rep->ip_addr.family = IPADDR_UNSPEC;
|
||||||
rep->stratum = local_stratum;
|
rep->stratum = local_stratum;
|
||||||
rep->ref_time = now_cooked;
|
rep->ref_time = now_cooked;
|
||||||
UTI_DoubleToTimeval(correction, &rep->current_correction);
|
rep->current_correction = correction;
|
||||||
rep->freq_ppm = LCL_ReadAbsoluteFrequency();
|
rep->freq_ppm = LCL_ReadAbsoluteFrequency();
|
||||||
rep->resid_freq_ppm = 0.0;
|
rep->resid_freq_ppm = 0.0;
|
||||||
rep->skew_ppm = 0.0;
|
rep->skew_ppm = 0.0;
|
||||||
@@ -678,10 +748,11 @@ REF_GetTrackingReport(RPT_TrackingReport *rep)
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
rep->ref_id = 0UL;
|
rep->ref_id = 0UL;
|
||||||
|
rep->ip_addr.family = IPADDR_UNSPEC;
|
||||||
rep->stratum = 0;
|
rep->stratum = 0;
|
||||||
rep->ref_time.tv_sec = 0;
|
rep->ref_time.tv_sec = 0;
|
||||||
rep->ref_time.tv_usec = 0;
|
rep->ref_time.tv_usec = 0;
|
||||||
UTI_DoubleToTimeval(correction, &rep->current_correction);
|
rep->current_correction = correction;
|
||||||
rep->freq_ppm = LCL_ReadAbsoluteFrequency();
|
rep->freq_ppm = LCL_ReadAbsoluteFrequency();
|
||||||
rep->resid_freq_ppm = 0.0;
|
rep->resid_freq_ppm = 0.0;
|
||||||
rep->skew_ppm = 0.0;
|
rep->skew_ppm = 0.0;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -110,6 +110,7 @@ extern void REF_SetReference
|
|||||||
int stratum,
|
int stratum,
|
||||||
NTP_Leap leap,
|
NTP_Leap leap,
|
||||||
unsigned long ref_id,
|
unsigned long ref_id,
|
||||||
|
IPAddr *ref_ip,
|
||||||
struct timeval *ref_time,
|
struct timeval *ref_time,
|
||||||
double offset,
|
double offset,
|
||||||
double frequency,
|
double frequency,
|
||||||
@@ -139,6 +140,7 @@ extern void REF_ModifyMaxupdateskew(double new_max_update_skew);
|
|||||||
|
|
||||||
extern void REF_EnableLocal(int stratum);
|
extern void REF_EnableLocal(int stratum);
|
||||||
extern void REF_DisableLocal(void);
|
extern void REF_DisableLocal(void);
|
||||||
|
extern int REF_IsLocalActive(void);
|
||||||
|
|
||||||
extern void REF_GetTrackingReport(RPT_TrackingReport *rep);
|
extern void REF_GetTrackingReport(RPT_TrackingReport *rep);
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -363,7 +363,7 @@ find_ordered_entry_with_flags(double *x, int n, int index, int *flags)
|
|||||||
l = u + 1;
|
l = u + 1;
|
||||||
r = v;
|
r = v;
|
||||||
do {
|
do {
|
||||||
while (x[l] < piv) l++;
|
while (x[l] < piv && l < v) l++;
|
||||||
while (x[r] > piv) r--;
|
while (x[r] > piv) r--;
|
||||||
if (r <= l) break;
|
if (r <= l) break;
|
||||||
EXCH(x[l], x[r]);
|
EXCH(x[l], x[r]);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
31
reports.h
31
reports.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -32,31 +32,29 @@
|
|||||||
#define GOT_REPORTS_H
|
#define GOT_REPORTS_H
|
||||||
|
|
||||||
#include "sysincl.h"
|
#include "sysincl.h"
|
||||||
|
#include "addressing.h"
|
||||||
|
|
||||||
#define REPORT_INVALID_OFFSET 0x80000000
|
#define REPORT_INVALID_OFFSET 0x80000000
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned long ip_addr;
|
IPAddr ip_addr;
|
||||||
int stratum;
|
int stratum;
|
||||||
int poll;
|
int poll;
|
||||||
enum {RPT_NTP_CLIENT, RPT_NTP_PEER, RPT_LOCAL_REFERENCE} mode;
|
enum {RPT_NTP_CLIENT, RPT_NTP_PEER, RPT_LOCAL_REFERENCE} mode;
|
||||||
enum {RPT_SYNC, RPT_UNREACH, RPT_FALSETICKER, RPT_JITTERY, RPT_OTHER} state;
|
enum {RPT_SYNC, RPT_UNREACH, RPT_FALSETICKER, RPT_JITTERY, RPT_OTHER} state;
|
||||||
|
|
||||||
unsigned long latest_meas_ago; /* seconds */
|
unsigned long latest_meas_ago; /* seconds */
|
||||||
long orig_latest_meas; /* microseconds (us) */
|
double orig_latest_meas; /* seconds */
|
||||||
long latest_meas; /* us */
|
double latest_meas; /* seconds */
|
||||||
unsigned long latest_meas_err; /* us */
|
double latest_meas_err; /* seconds */
|
||||||
long est_offset; /* us */
|
|
||||||
unsigned long est_offset_err; /* us */
|
|
||||||
long resid_freq; /* ppm * 1000 */
|
|
||||||
unsigned long resid_skew; /* ppm * 1000 */
|
|
||||||
} RPT_SourceReport ;
|
} RPT_SourceReport ;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned long ref_id;
|
unsigned long ref_id;
|
||||||
|
IPAddr ip_addr;
|
||||||
unsigned long stratum;
|
unsigned long stratum;
|
||||||
struct timeval ref_time;
|
struct timeval ref_time;
|
||||||
struct timeval current_correction;
|
double current_correction;
|
||||||
double freq_ppm;
|
double freq_ppm;
|
||||||
double resid_freq_ppm;
|
double resid_freq_ppm;
|
||||||
double skew_ppm;
|
double skew_ppm;
|
||||||
@@ -65,17 +63,20 @@ typedef struct {
|
|||||||
} RPT_TrackingReport;
|
} RPT_TrackingReport;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned long ip_addr;
|
unsigned long ref_id;
|
||||||
|
IPAddr ip_addr;
|
||||||
unsigned long n_samples;
|
unsigned long n_samples;
|
||||||
unsigned long n_runs;
|
unsigned long n_runs;
|
||||||
unsigned long span_seconds;
|
unsigned long span_seconds;
|
||||||
double resid_freq_ppm;
|
double resid_freq_ppm;
|
||||||
double skew_ppm;
|
double skew_ppm;
|
||||||
double sd_us;
|
double sd;
|
||||||
|
double est_offset;
|
||||||
|
double est_offset_err;
|
||||||
} RPT_SourcestatsReport;
|
} RPT_SourcestatsReport;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned long ref_time;
|
struct timeval ref_time;
|
||||||
unsigned short n_samples;
|
unsigned short n_samples;
|
||||||
unsigned short n_runs;
|
unsigned short n_runs;
|
||||||
unsigned long span_seconds;
|
unsigned long span_seconds;
|
||||||
@@ -94,7 +95,7 @@ typedef struct {
|
|||||||
} RPT_ClientAccess_Report;
|
} RPT_ClientAccess_Report;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned long ip_addr;
|
IPAddr ip_addr;
|
||||||
unsigned long client_hits;
|
unsigned long client_hits;
|
||||||
unsigned long peer_hits;
|
unsigned long peer_hits;
|
||||||
unsigned long cmd_hits_auth;
|
unsigned long cmd_hits_auth;
|
||||||
@@ -105,7 +106,7 @@ typedef struct {
|
|||||||
} RPT_ClientAccessByIndex_Report;
|
} RPT_ClientAccessByIndex_Report;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
time_t when;
|
struct timeval when;
|
||||||
double slewed_offset;
|
double slewed_offset;
|
||||||
double orig_offset;
|
double orig_offset;
|
||||||
double residual;
|
double residual;
|
||||||
|
|||||||
2
rtc.c
2
rtc.c
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
2
rtc.h
2
rtc.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
46
rtc_linux.c
46
rtc_linux.c
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -107,6 +107,8 @@ static int measurement_period = LOWEST_MEASUREMENT_PERIOD;
|
|||||||
static int timeout_running = 0;
|
static int timeout_running = 0;
|
||||||
static SCH_TimeoutID timeout_id;
|
static SCH_TimeoutID timeout_id;
|
||||||
|
|
||||||
|
static int skip_interrupts;
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
/* Maximum number of samples held */
|
/* Maximum number of samples held */
|
||||||
@@ -627,16 +629,11 @@ RTC_Linux_Initialise(void)
|
|||||||
direc = CNF_GetLogDir();
|
direc = CNF_GetLogDir();
|
||||||
if (!mkdir_and_parents(direc)) {
|
if (!mkdir_and_parents(direc)) {
|
||||||
LOG(LOGS_ERR, LOGF_RtcLinux, "Could not create directory %s", direc);
|
LOG(LOGS_ERR, LOGF_RtcLinux, "Could not create directory %s", direc);
|
||||||
logfile = NULL;
|
|
||||||
} else {
|
} else {
|
||||||
logfilename = MallocArray(char, 2 + strlen(direc) + strlen(RTC_LOG));
|
logfilename = MallocArray(char, 2 + strlen(direc) + strlen(RTC_LOG));
|
||||||
strcpy(logfilename, direc);
|
strcpy(logfilename, direc);
|
||||||
strcat(logfilename, "/");
|
strcat(logfilename, "/");
|
||||||
strcat(logfilename, RTC_LOG);
|
strcat(logfilename, RTC_LOG);
|
||||||
logfile = fopen(logfilename, "a");
|
|
||||||
if (!logfile) {
|
|
||||||
LOG(LOGS_WARN, LOGF_RtcLinux, "Couldn't open logfile %s for update", logfilename);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -666,7 +663,7 @@ RTC_Linux_Finalise(void)
|
|||||||
if (logfile) {
|
if (logfile) {
|
||||||
fclose(logfile);
|
fclose(logfile);
|
||||||
}
|
}
|
||||||
|
Free(logfilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -682,6 +679,7 @@ switch_interrupts(int onoff)
|
|||||||
LOG(LOGS_ERR, LOGF_RtcLinux, "Could not start measurement : %s", strerror(errno));
|
LOG(LOGS_ERR, LOGF_RtcLinux, "Could not start measurement : %s", strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
skip_interrupts = 1;
|
||||||
} else {
|
} else {
|
||||||
status = ioctl(fd, RTC_UIE_OFF, 0);
|
status = ioctl(fd, RTC_UIE_OFF, 0);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
@@ -837,7 +835,17 @@ process_reading(time_t rtc_time, struct timeval *system_time)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (logfile) {
|
if (logfilename) {
|
||||||
|
if (!logfile) {
|
||||||
|
logfile = fopen(logfilename, "a");
|
||||||
|
if (!logfile) {
|
||||||
|
LOG(LOGS_WARN, LOGF_RtcLinux, "Couldn't open logfile %s for update", logfilename);
|
||||||
|
Free(logfilename);
|
||||||
|
logfilename = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rtc_fast = (double)(rtc_time - system_time->tv_sec) - 1.0e-6 * (double) system_time->tv_usec;
|
rtc_fast = (double)(rtc_time - system_time->tv_sec) - 1.0e-6 * (double) system_time->tv_usec;
|
||||||
|
|
||||||
if (((logwrites++) % 32) == 0) {
|
if (((logwrites++) % 32) == 0) {
|
||||||
@@ -869,12 +877,10 @@ read_from_device(void *any)
|
|||||||
struct rtc_time rtc_raw;
|
struct rtc_time rtc_raw;
|
||||||
struct tm rtc_tm;
|
struct tm rtc_tm;
|
||||||
time_t rtc_t;
|
time_t rtc_t;
|
||||||
double read_err;
|
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
status = read(fd, &data, sizeof(data));
|
status = read(fd, &data, sizeof(data));
|
||||||
if (operating_mode == OM_NORMAL)
|
|
||||||
status = read(fd, &data, sizeof(data));
|
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
/* This looks like a bad error : the file descriptor was indicating it was
|
/* This looks like a bad error : the file descriptor was indicating it was
|
||||||
* ready to read but we couldn't read anything. Give up. */
|
* ready to read but we couldn't read anything. Give up. */
|
||||||
@@ -891,13 +897,19 @@ read_from_device(void *any)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (skip_interrupts > 0) {
|
||||||
|
/* Wait for the next interrupt, this one may be bogus */
|
||||||
|
skip_interrupts--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((data & RTC_UIE) == RTC_UIE) {
|
if ((data & RTC_UIE) == RTC_UIE) {
|
||||||
/* Update interrupt detected */
|
/* Update interrupt detected */
|
||||||
|
|
||||||
/* Read RTC time, sandwiched between two polls of the system clock
|
/* Read RTC time, sandwiched between two polls of the system clock
|
||||||
so we can bound any error. */
|
so we can bound any error. */
|
||||||
|
|
||||||
LCL_ReadCookedTime(&sys_time, &read_err);
|
SCH_GetFileReadyTime(&sys_time);
|
||||||
|
|
||||||
status = ioctl(fd, RTC_RD_TIME, &rtc_raw);
|
status = ioctl(fd, RTC_RD_TIME, &rtc_raw);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
@@ -1104,7 +1116,8 @@ RTC_Linux_TimePreInit(void)
|
|||||||
int
|
int
|
||||||
RTC_Linux_GetReport(RPT_RTC_Report *report)
|
RTC_Linux_GetReport(RPT_RTC_Report *report)
|
||||||
{
|
{
|
||||||
report->ref_time = (unsigned long) coef_ref_time;
|
report->ref_time.tv_sec = coef_ref_time;
|
||||||
|
report->ref_time.tv_usec = 0;
|
||||||
report->n_samples = n_samples;
|
report->n_samples = n_samples;
|
||||||
report->n_runs = n_runs;
|
report->n_runs = n_runs;
|
||||||
if (n_samples > 1) {
|
if (n_samples > 1) {
|
||||||
@@ -1169,12 +1182,9 @@ RTC_Linux_Trim(void)
|
|||||||
void
|
void
|
||||||
RTC_Linux_CycleLogFile(void)
|
RTC_Linux_CycleLogFile(void)
|
||||||
{
|
{
|
||||||
if (logfile && logfilename) {
|
if (logfile) {
|
||||||
fclose(logfile);
|
fclose(logfile);
|
||||||
logfile = fopen(logfilename, "a");
|
logfile = NULL;
|
||||||
if (!logfile) {
|
|
||||||
LOG(LOGS_WARN, LOGF_RtcLinux, "Could not reopen logfile %s", logfilename);
|
|
||||||
}
|
|
||||||
logwrites = 0;
|
logwrites = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
27
sched.c
27
sched.c
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -71,6 +71,9 @@ typedef struct {
|
|||||||
|
|
||||||
static FileHandlerEntry file_handlers[FD_SET_SIZE];
|
static FileHandlerEntry file_handlers[FD_SET_SIZE];
|
||||||
|
|
||||||
|
/* Last timestamp when a file descriptor became readable */
|
||||||
|
static struct timeval last_fdready;
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
/* Variables to handler the timer queue */
|
/* Variables to handler the timer queue */
|
||||||
@@ -225,6 +228,14 @@ SCH_RemoveInputFileHandler(int fd)
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
void
|
||||||
|
SCH_GetFileReadyTime(struct timeval *tv)
|
||||||
|
{
|
||||||
|
*tv = last_fdready;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
#define TQE_ALLOC_QUANTUM 32
|
#define TQE_ALLOC_QUANTUM 32
|
||||||
|
|
||||||
static TimerQueueEntry *
|
static TimerQueueEntry *
|
||||||
@@ -510,10 +521,11 @@ handle_slew(struct timeval *raw,
|
|||||||
void
|
void
|
||||||
SCH_MainLoop(void)
|
SCH_MainLoop(void)
|
||||||
{
|
{
|
||||||
fd_set rd, wr, ex;
|
fd_set rd;
|
||||||
int status;
|
int status;
|
||||||
struct timeval tv, *ptv;
|
struct timeval tv, *ptv;
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
|
double err;
|
||||||
|
|
||||||
if (!initialised) {
|
if (!initialised) {
|
||||||
CROAK("Should be initialised");
|
CROAK("Should be initialised");
|
||||||
@@ -524,11 +536,6 @@ SCH_MainLoop(void)
|
|||||||
/* Copy current set of read file descriptors */
|
/* Copy current set of read file descriptors */
|
||||||
memcpy((void *) &rd, (void *) &read_fds, sizeof(fd_set));
|
memcpy((void *) &rd, (void *) &read_fds, sizeof(fd_set));
|
||||||
|
|
||||||
/* Blank the write and exception descriptors - we aren't very
|
|
||||||
interested */
|
|
||||||
FD_ZERO(&wr);
|
|
||||||
FD_ZERO(&ex);
|
|
||||||
|
|
||||||
/* Try to dispatch any timeouts that have already gone by, and
|
/* Try to dispatch any timeouts that have already gone by, and
|
||||||
keep going until all are done. (The earlier ones may take so
|
keep going until all are done. (The earlier ones may take so
|
||||||
long to do that the later ones come around by the time they are
|
long to do that the later ones come around by the time they are
|
||||||
@@ -555,13 +562,15 @@ SCH_MainLoop(void)
|
|||||||
LOG_FATAL(LOGF_Scheduler, "No descriptors or timeout to wait for");
|
LOG_FATAL(LOGF_Scheduler, "No descriptors or timeout to wait for");
|
||||||
}
|
}
|
||||||
|
|
||||||
status = select(one_highest_fd, &rd, &wr, &ex, ptv);
|
status = select(one_highest_fd, &rd, NULL, NULL, ptv);
|
||||||
|
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
CROAK("Status < 0 after select");
|
if (!need_to_exit)
|
||||||
|
CROAK("Status < 0 after select");
|
||||||
} else if (status > 0) {
|
} else if (status > 0) {
|
||||||
/* A file descriptor is ready to read */
|
/* A file descriptor is ready to read */
|
||||||
|
|
||||||
|
LCL_ReadCookedTime(&last_fdready, &err);
|
||||||
dispatch_filehandlers(status, &rd);
|
dispatch_filehandlers(status, &rd);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
6
sched.h
6
sched.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -60,6 +60,10 @@ extern void SCH_AddInputFileHandler
|
|||||||
);
|
);
|
||||||
extern void SCH_RemoveInputFileHandler(int fd);
|
extern void SCH_RemoveInputFileHandler(int fd);
|
||||||
|
|
||||||
|
/* Get the time (cooked) when file descriptor became ready, intended for use
|
||||||
|
in file handlers */
|
||||||
|
extern void SCH_GetFileReadyTime(struct timeval *tv);
|
||||||
|
|
||||||
/* This queues a timeout to elapse at a given (raw) local time */
|
/* This queues a timeout to elapse at a given (raw) local time */
|
||||||
extern SCH_TimeoutID SCH_AddTimeout(struct timeval *tv, SCH_TimeoutHandler, SCH_ArbitraryArgument);
|
extern SCH_TimeoutID SCH_AddTimeout(struct timeval *tv, SCH_TimeoutHandler, SCH_ArbitraryArgument);
|
||||||
|
|
||||||
|
|||||||
128
sources.c
128
sources.c
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -88,6 +88,7 @@ struct SRC_Instance_Record {
|
|||||||
unsigned long ref_id; /* The reference ID of this source
|
unsigned long ref_id; /* The reference ID of this source
|
||||||
(i.e. its IP address, NOT the
|
(i.e. its IP address, NOT the
|
||||||
reference _it_ is sync'd to) */
|
reference _it_ is sync'd to) */
|
||||||
|
IPAddr *ip_addr; /* Its IP address if NTP source */
|
||||||
|
|
||||||
/* Flag indicating that we are receiving packets with valid headers
|
/* Flag indicating that we are receiving packets with valid headers
|
||||||
from this source and can use it as a reference */
|
from this source and can use it as a reference */
|
||||||
@@ -96,6 +97,9 @@ struct SRC_Instance_Record {
|
|||||||
/* Flag indicating the status of the source */
|
/* Flag indicating the status of the source */
|
||||||
SRC_Status status;
|
SRC_Status status;
|
||||||
|
|
||||||
|
/* Type of the source */
|
||||||
|
SRC_Type type;
|
||||||
|
|
||||||
struct SelectInfo sel_info;
|
struct SelectInfo sel_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -126,6 +130,8 @@ static int selected_source_index; /* Which source index is currently
|
|||||||
static void
|
static void
|
||||||
slew_sources(struct timeval *raw, struct timeval *cooked, double dfreq, double afreq,
|
slew_sources(struct timeval *raw, struct timeval *cooked, double dfreq, double afreq,
|
||||||
double doffset, int is_step_change, void *anything);
|
double doffset, int is_step_change, void *anything);
|
||||||
|
static char *
|
||||||
|
source_to_string(SRC_Instance inst);
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
/* Initialisation function */
|
/* Initialisation function */
|
||||||
@@ -155,7 +161,7 @@ void SRC_Finalise(void)
|
|||||||
/* Function to create a new instance. This would be called by one of
|
/* Function to create a new instance. This would be called by one of
|
||||||
the individual source-type instance creation routines. */
|
the individual source-type instance creation routines. */
|
||||||
|
|
||||||
SRC_Instance SRC_CreateNewInstance(unsigned long ref_id)
|
SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type, IPAddr *addr)
|
||||||
{
|
{
|
||||||
SRC_Instance result;
|
SRC_Instance result;
|
||||||
|
|
||||||
@@ -164,7 +170,7 @@ SRC_Instance SRC_CreateNewInstance(unsigned long ref_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = MallocNew(struct SRC_Instance_Record);
|
result = MallocNew(struct SRC_Instance_Record);
|
||||||
result->stats = SST_CreateInstance(ref_id);
|
result->stats = SST_CreateInstance(ref_id, addr);
|
||||||
|
|
||||||
if (n_sources == max_n_sources) {
|
if (n_sources == max_n_sources) {
|
||||||
/* Reallocate memory */
|
/* Reallocate memory */
|
||||||
@@ -184,8 +190,10 @@ SRC_Instance SRC_CreateNewInstance(unsigned long ref_id)
|
|||||||
result->index = n_sources;
|
result->index = n_sources;
|
||||||
result->leap_status = LEAP_Normal;
|
result->leap_status = LEAP_Normal;
|
||||||
result->ref_id = ref_id;
|
result->ref_id = ref_id;
|
||||||
|
result->ip_addr = addr;
|
||||||
result->reachable = 0;
|
result->reachable = 0;
|
||||||
result->status = SRC_BAD_STATS;
|
result->status = SRC_BAD_STATS;
|
||||||
|
result->type = type;
|
||||||
|
|
||||||
n_sources++;
|
n_sources++;
|
||||||
|
|
||||||
@@ -280,7 +288,7 @@ void SRC_AccumulateSample
|
|||||||
|
|
||||||
#ifdef TRACEON
|
#ifdef TRACEON
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "ip=[%s] t=%s ofs=%f del=%f disp=%f str=%d",
|
LOG(LOGS_INFO, LOGF_Sources, "ip=[%s] t=%s ofs=%f del=%f disp=%f str=%d",
|
||||||
UTI_IPToDottedQuad(inst->ref_id), UTI_TimevalToString(sample_time), -offset, root_delay, root_dispersion, stratum);
|
source_to_string(inst), UTI_TimevalToString(sample_time), -offset, root_delay, root_dispersion, stratum);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* WE HAVE TO NEGATE OFFSET IN THIS CALL, IT IS HERE THAT THE SENSE OF OFFSET
|
/* WE HAVE TO NEGATE OFFSET IN THIS CALL, IT IS HERE THAT THE SENSE OF OFFSET
|
||||||
@@ -301,7 +309,7 @@ SRC_SetReachable(SRC_Instance inst)
|
|||||||
inst->reachable = 1;
|
inst->reachable = 1;
|
||||||
|
|
||||||
#ifdef TRACEON
|
#ifdef TRACEON
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "%s", UTI_IPToDottedQuad(inst->ref_id));
|
LOG(LOGS_INFO, LOGF_Sources, "%s", source_to_string(inst));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Don't do selection at this point, though - that will come about
|
/* Don't do selection at this point, though - that will come about
|
||||||
@@ -316,7 +324,7 @@ SRC_UnsetReachable(SRC_Instance inst)
|
|||||||
inst->reachable = 0;
|
inst->reachable = 0;
|
||||||
|
|
||||||
#ifdef TRACEON
|
#ifdef TRACEON
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "%s%s", UTI_IPToDottedQuad(inst->ref_id),
|
LOG(LOGS_INFO, LOGF_Sources, "%s%s", source_to_string(inst),
|
||||||
(inst->index == selected_source_index) ? "(REF)":"");
|
(inst->index == selected_source_index) ? "(REF)":"");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -349,6 +357,22 @@ compare_sort_elements(const void *a, const void *b)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
static char *
|
||||||
|
source_to_string(SRC_Instance inst)
|
||||||
|
{
|
||||||
|
switch (inst->type) {
|
||||||
|
case SRC_NTP:
|
||||||
|
return UTI_IPToString(inst->ip_addr);
|
||||||
|
case SRC_REFCLOCK:
|
||||||
|
return UTI_RefidToString(inst->ref_id);
|
||||||
|
default:
|
||||||
|
CROAK("Unknown source type");
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
/* This function selects the current reference from amongst the pool
|
/* This function selects the current reference from amongst the pool
|
||||||
of sources we are holding.
|
of sources we are holding.
|
||||||
@@ -418,7 +442,7 @@ SRC_SelectSource(unsigned long match_addr)
|
|||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "%s off=%f dist=%f lo=%f hi=%f",
|
LOG(LOGS_INFO, LOGF_Sources, "%s off=%f dist=%f lo=%f hi=%f",
|
||||||
UTI_IPToDottedQuad(sources[i]->ref_id),
|
source_to_string(sources[i]),
|
||||||
si->best_offset, si->root_distance,
|
si->best_offset, si->root_distance,
|
||||||
si->lo_limit, si->hi_limit);
|
si->lo_limit, si->hi_limit);
|
||||||
#endif
|
#endif
|
||||||
@@ -491,7 +515,7 @@ SRC_SelectSource(unsigned long match_addr)
|
|||||||
for (i=0; i<n_endpoints; i++) {
|
for (i=0; i<n_endpoints; i++) {
|
||||||
#if 0
|
#if 0
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "i=%d t=%f tag=%d addr=%s", i, sort_list[i].offset, sort_list[i].tag,
|
LOG(LOGS_INFO, LOGF_Sources, "i=%d t=%f tag=%d addr=%s", i, sort_list[i].offset, sort_list[i].tag,
|
||||||
UTI_IPToDottedQuad(sources[sort_list[i].index]->ref_id));
|
source_to_string(sources[sort_list[i].index]));
|
||||||
#endif
|
#endif
|
||||||
switch(sort_list[i].tag) {
|
switch(sort_list[i].tag) {
|
||||||
case LOW:
|
case LOW:
|
||||||
@@ -565,12 +589,12 @@ SRC_SelectSource(unsigned long match_addr)
|
|||||||
|
|
||||||
sel_sources[n_sel_sources++] = i;
|
sel_sources[n_sel_sources++] = i;
|
||||||
#if 0
|
#if 0
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "i=%d addr=%s is valid", i, UTI_IPToDottedQuad(sources[i]->ref_id));
|
LOG(LOGS_INFO, LOGF_Sources, "i=%d addr=%s is valid", i, source_to_string(sources[i]));
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
sources[i]->status = SRC_FALSETICKER;
|
sources[i]->status = SRC_FALSETICKER;
|
||||||
#if 0
|
#if 0
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "i=%d addr=%s is a falseticker", i, UTI_IPToDottedQuad(sources[i]->ref_id));
|
LOG(LOGS_INFO, LOGF_Sources, "i=%d addr=%s is a falseticker", i, source_to_string(sources[i]));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -603,7 +627,7 @@ SRC_SelectSource(unsigned long match_addr)
|
|||||||
sel_sources[i] = INVALID_SOURCE;
|
sel_sources[i] = INVALID_SOURCE;
|
||||||
sources[index]->status = SRC_JITTERY;
|
sources[index]->status = SRC_JITTERY;
|
||||||
#if 0
|
#if 0
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "i=%d addr=%s has too much variance", i, UTI_IPToDottedQuad(sources[i]->ref_id));
|
LOG(LOGS_INFO, LOGF_Sources, "i=%d addr=%s has too much variance", i, source_to_string(sources[i]));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -632,33 +656,36 @@ SRC_SelectSource(unsigned long match_addr)
|
|||||||
if (stratum < min_stratum) min_stratum = stratum;
|
if (stratum < min_stratum) min_stratum = stratum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find the best source with minimum stratum */
|
||||||
|
min_distance_index = INVALID_SOURCE;
|
||||||
|
for (i=0; i<n_sel_sources; i++) {
|
||||||
|
index = sel_sources[i];
|
||||||
|
if (sources[index]->sel_info.stratum == min_stratum) {
|
||||||
|
if ((min_distance_index == INVALID_SOURCE) ||
|
||||||
|
(sources[index]->sel_info.root_distance < min_distance)) {
|
||||||
|
min_distance = sources[index]->sel_info.root_distance;
|
||||||
|
min_distance_index = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "min_stratum=%d", min_stratum);
|
LOG(LOGS_INFO, LOGF_Sources, "min_stratum=%d", min_stratum);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Does the current source have this stratum and is it still a
|
/* Does the current source have this stratum, doesn't have distance
|
||||||
survivor? */
|
much worse than the best source and is it still a survivor? */
|
||||||
|
|
||||||
if ((selected_source_index == INVALID_SOURCE) ||
|
if ((selected_source_index == INVALID_SOURCE) ||
|
||||||
(sources[selected_source_index]->status != SRC_SELECTABLE) ||
|
(sources[selected_source_index]->status != SRC_SELECTABLE) ||
|
||||||
(sources[selected_source_index]->sel_info.stratum > min_stratum)) {
|
(sources[selected_source_index]->sel_info.stratum > min_stratum) ||
|
||||||
|
(sources[selected_source_index]->sel_info.root_distance > 10 * min_distance)) {
|
||||||
|
|
||||||
/* We have to elect a new synchronisation source */
|
/* We have to elect a new synchronisation source */
|
||||||
min_distance_index = INVALID_SOURCE;
|
|
||||||
for (i=0; i<n_sel_sources; i++) {
|
|
||||||
index = sel_sources[i];
|
|
||||||
if (sources[index]->sel_info.stratum == min_stratum) {
|
|
||||||
if ((min_distance_index == INVALID_SOURCE) ||
|
|
||||||
(sources[index]->sel_info.root_distance < min_distance)) {
|
|
||||||
min_distance = sources[index]->sel_info.root_distance;
|
|
||||||
min_distance_index = index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
selected_source_index = min_distance_index;
|
selected_source_index = min_distance_index;
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "Selected source %s",
|
LOG(LOGS_INFO, LOGF_Sources, "Selected source %s",
|
||||||
UTI_IPToDottedQuad(sources[selected_source_index]->ref_id));
|
source_to_string(sources[selected_source_index]));
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@@ -687,11 +714,29 @@ SRC_SelectSource(unsigned long match_addr)
|
|||||||
total_root_dispersion = (src_accrued_dispersion +
|
total_root_dispersion = (src_accrued_dispersion +
|
||||||
sources[selected_source_index]->sel_info.root_dispersion);
|
sources[selected_source_index]->sel_info.root_dispersion);
|
||||||
|
|
||||||
|
/* Accept leap second status if more than half of selectable sources agree */
|
||||||
|
|
||||||
|
for (i=j1=j2=0; i<n_sel_sources; i++) {
|
||||||
|
index = sel_sources[i];
|
||||||
|
if (sources[index]->leap_status == LEAP_InsertSecond) {
|
||||||
|
j1++;
|
||||||
|
} else if (sources[index]->leap_status == LEAP_DeleteSecond) {
|
||||||
|
j2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j1 > n_sel_sources / 2) {
|
||||||
|
leap_status = LEAP_InsertSecond;
|
||||||
|
} else if (j2 > n_sel_sources / 2) {
|
||||||
|
leap_status = LEAP_DeleteSecond;
|
||||||
|
}
|
||||||
|
|
||||||
if ((match_addr == 0) ||
|
if ((match_addr == 0) ||
|
||||||
(match_addr == sources[selected_source_index]->ref_id)) {
|
(match_addr == sources[selected_source_index]->ref_id)) {
|
||||||
|
|
||||||
REF_SetReference(min_stratum, leap_status,
|
REF_SetReference(min_stratum, leap_status,
|
||||||
sources[selected_source_index]->ref_id,
|
sources[selected_source_index]->ref_id,
|
||||||
|
sources[selected_source_index]->ip_addr,
|
||||||
&now,
|
&now,
|
||||||
src_offset,
|
src_offset,
|
||||||
src_frequency,
|
src_frequency,
|
||||||
@@ -873,7 +918,16 @@ SRC_ReportSource(int index, RPT_SourceReport *report, struct timeval *now)
|
|||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
src = sources[index];
|
src = sources[index];
|
||||||
report->ip_addr = src->ref_id;
|
|
||||||
|
memset(&report->ip_addr, 0, sizeof (report->ip_addr));
|
||||||
|
if (src->ip_addr)
|
||||||
|
report->ip_addr = *src->ip_addr;
|
||||||
|
else {
|
||||||
|
/* Use refid as an address */
|
||||||
|
report->ip_addr.addr.in4 = src->ref_id;
|
||||||
|
report->ip_addr.family = IPADDR_INET4;
|
||||||
|
}
|
||||||
|
|
||||||
switch (src->status) {
|
switch (src->status) {
|
||||||
case SRC_SYNC:
|
case SRC_SYNC:
|
||||||
report->state = RPT_SYNC;
|
report->state = RPT_SYNC;
|
||||||
@@ -902,7 +956,7 @@ SRC_ReportSource(int index, RPT_SourceReport *report, struct timeval *now)
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
int
|
int
|
||||||
SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report)
|
SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report, struct timeval *now)
|
||||||
{
|
{
|
||||||
SRC_Instance src;
|
SRC_Instance src;
|
||||||
|
|
||||||
@@ -910,14 +964,28 @@ SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report)
|
|||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
src = sources[index];
|
src = sources[index];
|
||||||
report->ip_addr = src->ref_id;
|
report->ref_id = src->ref_id;
|
||||||
SST_DoSourcestatsReport(src->stats, report);
|
if (src->ip_addr)
|
||||||
|
report->ip_addr = *src->ip_addr;
|
||||||
|
else
|
||||||
|
report->ip_addr.family = IPADDR_UNSPEC;
|
||||||
|
SST_DoSourcestatsReport(src->stats, report, now);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
SRC_Type
|
||||||
|
SRC_GetType(int index)
|
||||||
|
{
|
||||||
|
if ((index >= n_sources) || (index < 0))
|
||||||
|
return -1;
|
||||||
|
return sources[index]->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
SRC_Skew_Direction SRC_LastSkewChange(SRC_Instance inst)
|
SRC_Skew_Direction SRC_LastSkewChange(SRC_Instance inst)
|
||||||
{
|
{
|
||||||
SRC_Skew_Direction result = SRC_Skew_Nochange;
|
SRC_Skew_Direction result = SRC_Skew_Nochange;
|
||||||
|
|||||||
13
sources.h
13
sources.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -50,10 +50,15 @@ extern void SRC_Initialise(void);
|
|||||||
/* Finalisation function */
|
/* Finalisation function */
|
||||||
extern void SRC_Finalise(void);
|
extern void SRC_Finalise(void);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SRC_NTP, /* NTP client/peer */
|
||||||
|
SRC_REFCLOCK /* Rerefence clock */
|
||||||
|
} SRC_Type;
|
||||||
|
|
||||||
/* Function to create a new instance. This would be called by one of
|
/* Function to create a new instance. This would be called by one of
|
||||||
the individual source-type instance creation routines. */
|
the individual source-type instance creation routines. */
|
||||||
|
|
||||||
extern SRC_Instance SRC_CreateNewInstance(unsigned long ref_id);
|
extern SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type, IPAddr *addr);
|
||||||
|
|
||||||
/* Function to get rid of a source when it is being unconfigured.
|
/* Function to get rid of a source when it is being unconfigured.
|
||||||
This may cause the current reference source to be reselected, if this
|
This may cause the current reference source to be reselected, if this
|
||||||
@@ -141,7 +146,9 @@ extern int SRC_IsSyncPeer(SRC_Instance inst);
|
|||||||
extern int SRC_ReadNumberOfSources(void);
|
extern int SRC_ReadNumberOfSources(void);
|
||||||
extern int SRC_ReportSource(int index, RPT_SourceReport *report, struct timeval *now);
|
extern int SRC_ReportSource(int index, RPT_SourceReport *report, struct timeval *now);
|
||||||
|
|
||||||
extern int SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report);
|
extern int SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report, struct timeval *now);
|
||||||
|
|
||||||
|
extern SRC_Type SRC_GetType(int index);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SRC_Skew_Decrease,
|
SRC_Skew_Decrease,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -66,8 +66,9 @@ static unsigned long logwrites = 0;
|
|||||||
|
|
||||||
struct SST_Stats_Record {
|
struct SST_Stats_Record {
|
||||||
|
|
||||||
/* Reference ID of source, used for logging to statistics log */
|
/* Reference ID and IP address of source, used for logging to statistics log */
|
||||||
unsigned long refid;
|
unsigned long refid;
|
||||||
|
IPAddr *ip_addr;
|
||||||
|
|
||||||
/* Number of samples currently stored. sample[n_samples-1] is the
|
/* Number of samples currently stored. sample[n_samples-1] is the
|
||||||
newest. The samples are expected to be sorted in order, but that
|
newest. The samples are expected to be sorted in order, but that
|
||||||
@@ -187,17 +188,20 @@ SST_Finalise(void)
|
|||||||
/* This function creates a new instance of the statistics handler */
|
/* This function creates a new instance of the statistics handler */
|
||||||
|
|
||||||
SST_Stats
|
SST_Stats
|
||||||
SST_CreateInstance(unsigned long refid)
|
SST_CreateInstance(unsigned long refid, IPAddr *addr)
|
||||||
{
|
{
|
||||||
SST_Stats inst;
|
SST_Stats inst;
|
||||||
inst = MallocNew(struct SST_Stats_Record);
|
inst = MallocNew(struct SST_Stats_Record);
|
||||||
inst->refid = refid;
|
inst->refid = refid;
|
||||||
|
inst->ip_addr = addr;
|
||||||
inst->n_samples = 0;
|
inst->n_samples = 0;
|
||||||
inst->estimated_frequency = 0;
|
inst->estimated_frequency = 0;
|
||||||
inst->skew = 2000.0e-6;
|
inst->skew = 2000.0e-6;
|
||||||
inst->skew_dirn = SST_Skew_Nochange;
|
inst->skew_dirn = SST_Skew_Nochange;
|
||||||
inst->estimated_offset = 0.0;
|
inst->estimated_offset = 0.0;
|
||||||
inst->estimated_offset_sd = 86400.0; /* Assume it's at least within a day! */
|
inst->estimated_offset_sd = 86400.0; /* Assume it's at least within a day! */
|
||||||
|
inst->offset_time.tv_sec = 0;
|
||||||
|
inst->offset_time.tv_usec = 0;
|
||||||
inst->variance = 16.0;
|
inst->variance = 16.0;
|
||||||
inst->nruns = 0;
|
inst->nruns = 0;
|
||||||
return inst;
|
return inst;
|
||||||
@@ -471,7 +475,7 @@ SST_DoNewRegression(SST_Stats inst)
|
|||||||
|
|
||||||
fprintf(logfile, "%s %-15s %10.3e %10.3e %10.3e %10.3e %10.3e %7.1e %3d %3d %3d\n",
|
fprintf(logfile, "%s %-15s %10.3e %10.3e %10.3e %10.3e %10.3e %7.1e %3d %3d %3d\n",
|
||||||
UTI_TimeToLogForm(inst->offset_time.tv_sec),
|
UTI_TimeToLogForm(inst->offset_time.tv_sec),
|
||||||
UTI_IPToDottedQuad(inst->refid),
|
inst->ip_addr ? UTI_IPToString(inst->ip_addr) : UTI_RefidToString(inst->refid),
|
||||||
sqrt(inst->variance),
|
sqrt(inst->variance),
|
||||||
inst->estimated_offset,
|
inst->estimated_offset,
|
||||||
inst->estimated_offset_sd,
|
inst->estimated_offset_sd,
|
||||||
@@ -721,8 +725,12 @@ SST_PredictOffset(SST_Stats inst, struct timeval *when)
|
|||||||
if (inst->n_samples < 3) {
|
if (inst->n_samples < 3) {
|
||||||
/* We don't have any useful statistics, and presumably the poll
|
/* We don't have any useful statistics, and presumably the poll
|
||||||
interval is minimal. We can't do any useful prediction other
|
interval is minimal. We can't do any useful prediction other
|
||||||
than use the latest sample */
|
than use the latest sample or zero if we don't have any samples */
|
||||||
return inst->offsets[inst->n_samples - 1];
|
if (inst->n_samples > 0) {
|
||||||
|
return inst->offsets[inst->n_samples - 1];
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
UTI_DiffTimevalsToDouble(&elapsed, when, &inst->offset_time);
|
UTI_DiffTimevalsToDouble(&elapsed, when, &inst->offset_time);
|
||||||
return inst->estimated_offset + elapsed * inst->estimated_frequency;
|
return inst->estimated_offset + elapsed * inst->estimated_frequency;
|
||||||
@@ -837,47 +845,24 @@ SST_LoadFromFile(SST_Stats inst, FILE *in)
|
|||||||
void
|
void
|
||||||
SST_DoSourceReport(SST_Stats inst, RPT_SourceReport *report, struct timeval *now)
|
SST_DoSourceReport(SST_Stats inst, RPT_SourceReport *report, struct timeval *now)
|
||||||
{
|
{
|
||||||
int n, nb;
|
int n;
|
||||||
double est_offset, est_err, elapsed, sample_elapsed;
|
|
||||||
struct timeval ago;
|
struct timeval ago;
|
||||||
|
|
||||||
if (inst->n_samples > 0) {
|
if (inst->n_samples > 0) {
|
||||||
n = inst->n_samples - 1;
|
n = inst->n_samples - 1;
|
||||||
report->orig_latest_meas = (long)(0.5 + 1.0e6 * inst->orig_offsets[n]);
|
report->orig_latest_meas = inst->orig_offsets[n];
|
||||||
report->latest_meas = (long)(0.5 + 1.0e6 * inst->offsets[n]);
|
report->latest_meas = inst->offsets[n];
|
||||||
report->latest_meas_err = (unsigned long)(0.5 + 1.0e6 * (0.5*inst->root_delays[n] + inst->root_dispersions[n]));
|
report->latest_meas_err = 0.5*inst->root_delays[n] + inst->root_dispersions[n];
|
||||||
report->stratum = inst->strata[n];
|
report->stratum = inst->strata[n];
|
||||||
|
|
||||||
UTI_DiffTimevals(&ago, now, &inst->sample_times[n]);
|
UTI_DiffTimevals(&ago, now, &inst->sample_times[n]);
|
||||||
report->latest_meas_ago = ago.tv_sec;
|
report->latest_meas_ago = ago.tv_sec;
|
||||||
|
|
||||||
if (inst->n_samples > 3) {
|
|
||||||
UTI_DiffTimevalsToDouble(&elapsed, now, &inst->offset_time);
|
|
||||||
nb = inst->best_single_sample;
|
|
||||||
UTI_DiffTimevalsToDouble(&sample_elapsed, now, &(inst->sample_times[nb]));
|
|
||||||
est_offset = inst->estimated_offset + elapsed * inst->estimated_frequency;
|
|
||||||
est_err = (inst->estimated_offset_sd +
|
|
||||||
sample_elapsed * inst->skew +
|
|
||||||
(0.5*inst->root_delays[nb] + inst->root_dispersions[nb]));
|
|
||||||
report->est_offset = (long)(0.5 + 1.0e6 * est_offset);
|
|
||||||
report->est_offset_err = (unsigned long) (0.5 + 1.0e6 * est_err);
|
|
||||||
report->resid_freq = (long) (0.5 * 1.0e9 * inst->estimated_frequency);
|
|
||||||
report->resid_skew = (unsigned long) (0.5 + 1.0e9 * inst->skew);
|
|
||||||
} else {
|
|
||||||
report->est_offset = report->latest_meas;
|
|
||||||
report->est_offset_err = report->latest_meas_err;
|
|
||||||
report->resid_freq = 0;
|
|
||||||
report->resid_skew = 0;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
report->latest_meas_ago = 86400 * 365 * 10;
|
||||||
report->orig_latest_meas = 0;
|
report->orig_latest_meas = 0;
|
||||||
report->latest_meas = 0;
|
report->latest_meas = 0;
|
||||||
report->latest_meas_err = 0;
|
report->latest_meas_err = 0;
|
||||||
report->stratum = 0;
|
report->stratum = 0;
|
||||||
report->est_offset = 0;
|
|
||||||
report->est_offset_err = 0;
|
|
||||||
report->resid_freq = 0;
|
|
||||||
report->resid_skew = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -892,10 +877,11 @@ SST_Skew_Direction SST_LastSkewChange(SST_Stats inst)
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
SST_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *report)
|
SST_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *report, struct timeval *now)
|
||||||
{
|
{
|
||||||
double dspan;
|
double dspan;
|
||||||
int n;
|
double elapsed, sample_elapsed;
|
||||||
|
int n, nb;
|
||||||
|
|
||||||
report->n_samples = inst->n_samples;
|
report->n_samples = inst->n_samples;
|
||||||
report->n_runs = inst->nruns;
|
report->n_runs = inst->nruns;
|
||||||
@@ -904,13 +890,28 @@ SST_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *report)
|
|||||||
n = inst->n_samples - 1;
|
n = inst->n_samples - 1;
|
||||||
UTI_DiffTimevalsToDouble(&dspan, &inst->sample_times[n], &inst->sample_times[0]);
|
UTI_DiffTimevalsToDouble(&dspan, &inst->sample_times[n], &inst->sample_times[0]);
|
||||||
report->span_seconds = (unsigned long) (dspan + 0.5);
|
report->span_seconds = (unsigned long) (dspan + 0.5);
|
||||||
|
|
||||||
|
if (inst->n_samples > 3) {
|
||||||
|
UTI_DiffTimevalsToDouble(&elapsed, now, &inst->offset_time);
|
||||||
|
nb = inst->best_single_sample;
|
||||||
|
UTI_DiffTimevalsToDouble(&sample_elapsed, now, &(inst->sample_times[nb]));
|
||||||
|
report->est_offset = inst->estimated_offset + elapsed * inst->estimated_frequency;
|
||||||
|
report->est_offset_err = (inst->estimated_offset_sd +
|
||||||
|
sample_elapsed * inst->skew +
|
||||||
|
(0.5*inst->root_delays[nb] + inst->root_dispersions[nb]));
|
||||||
|
} else {
|
||||||
|
report->est_offset = inst->offsets[n];
|
||||||
|
report->est_offset_err = 0.5*inst->root_delays[n] + inst->root_dispersions[n];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
report->span_seconds = 0;
|
report->span_seconds = 0;
|
||||||
|
report->est_offset = 0;
|
||||||
|
report->est_offset_err = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
report->resid_freq_ppm = 1.0e6 * inst->estimated_frequency;
|
report->resid_freq_ppm = 1.0e6 * inst->estimated_frequency;
|
||||||
report->skew_ppm = 1.0e6 * inst->skew;
|
report->skew_ppm = 1.0e6 * inst->skew;
|
||||||
report->sd_us = 1.0e6 * sqrt(inst->variance);
|
report->sd = sqrt(inst->variance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ extern void SST_Initialise(void);
|
|||||||
extern void SST_Finalise(void);
|
extern void SST_Finalise(void);
|
||||||
|
|
||||||
/* This function creates a new instance of the statistics handler */
|
/* This function creates a new instance of the statistics handler */
|
||||||
extern SST_Stats SST_CreateInstance(unsigned long refid);
|
extern SST_Stats SST_CreateInstance(unsigned long refid, IPAddr *addr);
|
||||||
|
|
||||||
/* This function deletes an instance of the statistics handler. */
|
/* This function deletes an instance of the statistics handler. */
|
||||||
extern void SST_DeleteInstance(SST_Stats inst);
|
extern void SST_DeleteInstance(SST_Stats inst);
|
||||||
@@ -140,7 +140,7 @@ extern int SST_LoadFromFile(SST_Stats inst, FILE *in);
|
|||||||
|
|
||||||
extern void SST_DoSourceReport(SST_Stats inst, RPT_SourceReport *report, struct timeval *now);
|
extern void SST_DoSourceReport(SST_Stats inst, RPT_SourceReport *report, struct timeval *now);
|
||||||
|
|
||||||
extern void SST_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *report);
|
extern void SST_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *report, struct timeval *now);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SST_Skew_Decrease,
|
SST_Skew_Decrease,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
39
sys.c
39
sys.c
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
|
#include "logging.h"
|
||||||
|
|
||||||
#if defined (LINUX)
|
#if defined (LINUX)
|
||||||
#include "sys_linux.h"
|
#include "sys_linux.h"
|
||||||
@@ -97,8 +98,42 @@ SYS_Finalise(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
/* ================================================== */
|
|
||||||
|
void SYS_DropRoot(char *user)
|
||||||
|
{
|
||||||
|
#if defined(LINUX) && defined (FEAT_LINUXCAPS)
|
||||||
|
SYS_Linux_DropRoot(user);
|
||||||
|
#else
|
||||||
|
LOG_FATAL(LOGF_Sys, "dropping root privileges not supported");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
void SYS_SetScheduler(int SchedPriority)
|
||||||
|
{
|
||||||
|
#if defined(LINUX) && defined(HAVE_SCHED_SETSCHEDULER)
|
||||||
|
SYS_Linux_SetScheduler(SchedPriority);
|
||||||
|
#else
|
||||||
|
LOG_FATAL(LOGF_Sys, "scheduler priority setting not supported");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
void SYS_LockMemory(void)
|
||||||
|
{
|
||||||
|
#if defined(LINUX) && defined(HAVE_MLOCKALL)
|
||||||
|
SYS_Linux_MemLockAll(1);
|
||||||
|
#else
|
||||||
|
LOG_FATAL(LOGF_Sys, "memory locking not supported");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|||||||
8
sys.h
8
sys.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -39,4 +39,10 @@ extern void SYS_Initialise(void);
|
|||||||
/* Called at the end of the run to do final clean-up */
|
/* Called at the end of the run to do final clean-up */
|
||||||
extern void SYS_Finalise(void);
|
extern void SYS_Finalise(void);
|
||||||
|
|
||||||
|
/* Drop root privileges to the specified user */
|
||||||
|
extern void SYS_DropRoot(char *user);
|
||||||
|
|
||||||
|
extern void SYS_SetScheduler(int SchedPriority);
|
||||||
|
extern void SYS_LockMemory(void);
|
||||||
|
|
||||||
#endif /* GOT_SYS_H */
|
#endif /* GOT_SYS_H */
|
||||||
|
|||||||
259
sys_linux.c
259
sys_linux.c
@@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
* Copyright (C) Richard P. Curnow 1997-2003
|
* Copyright (C) Richard P. Curnow 1997-2003
|
||||||
|
* Copyright (C) John G. Hasler 2009
|
||||||
|
* Copyright (C) Miroslav Lichvar 2009
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of version 2 of the GNU General Public License as
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
@@ -19,7 +21,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -39,6 +41,25 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
|
#if defined(HAVE_SCHED_SETSCHEDULER)
|
||||||
|
# include <sched.h>
|
||||||
|
int SchedPriority = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_MLOCKALL)
|
||||||
|
# include <sys/mman.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
int LockAll = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FEAT_LINUXCAPS
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <sys/prctl.h>
|
||||||
|
#include <sys/capability.h>
|
||||||
|
#include <grp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "localp.h"
|
#include "localp.h"
|
||||||
#include "sys_linux.h"
|
#include "sys_linux.h"
|
||||||
#include "sched.h"
|
#include "sched.h"
|
||||||
@@ -84,10 +105,11 @@ static int version_major;
|
|||||||
static int version_minor;
|
static int version_minor;
|
||||||
static int version_patchlevel;
|
static int version_patchlevel;
|
||||||
|
|
||||||
/* Flag indicating whether adjtimex() with txc.modes equal to zero
|
/* Flag indicating whether adjtimex() returns the remaining time adjustment
|
||||||
returns the remaining time adjustment or not. If not we have to read
|
or not. If not we have to read the outstanding adjustment by setting it to
|
||||||
the outstanding adjustment by setting it to zero, examining the return
|
zero, examining the return value and setting the outstanding adjustment back
|
||||||
value and setting the outstanding adjustment back again. */
|
again. If 1, txc.modes equal to zero is used to read the time. If 2,
|
||||||
|
txc.modes is set to ADJ_OFFSET_SS_READ. */
|
||||||
|
|
||||||
static int have_readonly_adjtime;
|
static int have_readonly_adjtime;
|
||||||
|
|
||||||
@@ -106,10 +128,24 @@ our_round(double x) {
|
|||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static long
|
||||||
|
our_lround(double x) {
|
||||||
|
int y;
|
||||||
|
|
||||||
|
if (x > 0.0)
|
||||||
|
y = x + 0.5;
|
||||||
|
else
|
||||||
|
y = x - 0.5;
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
/* Amount of outstanding offset to process */
|
/* Amount of outstanding offset to process */
|
||||||
static double offset_register;
|
static double offset_register;
|
||||||
|
|
||||||
|
/* Flag set true if an adjtime slew was started and still may be running */
|
||||||
|
static int slow_slewing;
|
||||||
|
|
||||||
/* Flag set true if a fast slew (one done by altering tick) is being
|
/* Flag set true if a fast slew (one done by altering tick) is being
|
||||||
run at the moment */
|
run at the moment */
|
||||||
static int fast_slewing;
|
static int fast_slewing;
|
||||||
@@ -233,16 +269,28 @@ initiate_slew(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cancel any standard adjtime that is running */
|
||||||
|
if (slow_slewing) {
|
||||||
|
offset = 0;
|
||||||
|
if (TMX_ApplyOffset(&offset) < 0) {
|
||||||
|
CROAK("adjtimex() failed in accrue_offset");
|
||||||
|
}
|
||||||
|
offset_register -= (double) offset / 1.0e6;
|
||||||
|
slow_slewing = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (fabs(offset_register) < MAX_ADJUST_WITH_ADJTIME) {
|
if (fabs(offset_register) < MAX_ADJUST_WITH_ADJTIME) {
|
||||||
/* Use adjtime to do the shift */
|
/* Use adjtime to do the shift */
|
||||||
offset = (long)(0.5 + 1.0e6*(-offset_register));
|
offset = our_lround(1.0e6 * -offset_register);
|
||||||
|
|
||||||
if (TMX_ApplyOffset(&offset) < 0) {
|
offset_register += offset * 1e-6;
|
||||||
CROAK("adjtimex() failed in initiate_slew");
|
|
||||||
|
if (offset != 0) {
|
||||||
|
if (TMX_ApplyOffset(&offset) < 0) {
|
||||||
|
CROAK("adjtimex() failed in initiate_slew");
|
||||||
|
}
|
||||||
|
slow_slewing = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset_register = 0.0;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* If the system clock has a high drift rate, the combination of
|
/* If the system clock has a high drift rate, the combination of
|
||||||
@@ -353,19 +401,9 @@ abort_slew(void)
|
|||||||
static void
|
static void
|
||||||
accrue_offset(double offset)
|
accrue_offset(double offset)
|
||||||
{
|
{
|
||||||
long toffset;
|
|
||||||
|
|
||||||
/* Add the new offset to the register */
|
/* Add the new offset to the register */
|
||||||
offset_register += offset;
|
offset_register += offset;
|
||||||
|
|
||||||
/* Cancel any standard adjtime that is running */
|
|
||||||
toffset = 0;
|
|
||||||
if (TMX_ApplyOffset(&toffset) < 0) {
|
|
||||||
CROAK("adjtimex() failed in accrue_offset");
|
|
||||||
}
|
|
||||||
|
|
||||||
offset_register -= (double) toffset / 1.0e6;
|
|
||||||
|
|
||||||
if (!fast_slewing) {
|
if (!fast_slewing) {
|
||||||
initiate_slew();
|
initiate_slew();
|
||||||
} /* Otherwise, when the fast slew completes, any other stuff
|
} /* Otherwise, when the fast slew completes, any other stuff
|
||||||
@@ -511,28 +549,47 @@ get_offset_correction(struct timeval *raw,
|
|||||||
double fast_slew_duration;
|
double fast_slew_duration;
|
||||||
double fast_slew_achieved;
|
double fast_slew_achieved;
|
||||||
double fast_slew_remaining;
|
double fast_slew_remaining;
|
||||||
long offset;
|
long offset, toffset;
|
||||||
|
|
||||||
if (have_readonly_adjtime) {
|
if (!slow_slewing) {
|
||||||
if (TMX_GetOffsetLeft(&offset) < 0) {
|
|
||||||
CROAK("adjtimex() failed in get_offset_correction");
|
|
||||||
}
|
|
||||||
|
|
||||||
adjtime_left = (double)offset / 1.0e6;
|
|
||||||
} else {
|
|
||||||
offset = 0;
|
offset = 0;
|
||||||
if (TMX_ApplyOffset(&offset) < 0) {
|
} else {
|
||||||
CROAK("adjtimex() failed in get_offset_correction");
|
again:
|
||||||
|
switch (have_readonly_adjtime) {
|
||||||
|
case 2:
|
||||||
|
if (TMX_GetOffsetLeft(&offset) < 0) {
|
||||||
|
LOG(LOGS_INFO, LOGF_SysLinux, "adjtimex() doesn't support ADJ_OFFSET_SS_READ");
|
||||||
|
have_readonly_adjtime = 0;
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
toffset = 0;
|
||||||
|
if (TMX_ApplyOffset(&toffset) < 0) {
|
||||||
|
CROAK("adjtimex() failed in get_offset_correction");
|
||||||
|
}
|
||||||
|
offset = toffset;
|
||||||
|
if (TMX_ApplyOffset(&toffset) < 0) {
|
||||||
|
CROAK("adjtimex() failed in get_offset_correction");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (TMX_GetOffsetLeftOld(&offset) < 0) {
|
||||||
|
CROAK("adjtimex() failed in get_offset_correction");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
adjtime_left = (double)offset / 1.0e6;
|
|
||||||
|
|
||||||
/* txc.offset still set from return value of last call */
|
if (offset == 0) {
|
||||||
if (TMX_ApplyOffset(&offset) < 0) {
|
/* adjtime slew has finished */
|
||||||
CROAK("adjtimex() failed in get_offset_correction");
|
slow_slewing = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adjtime_left = (double)offset / 1.0e6;
|
||||||
|
|
||||||
if (fast_slewing) {
|
if (fast_slewing) {
|
||||||
UTI_DiffTimevalsToDouble(&fast_slew_duration, raw, &slew_start_tv);
|
UTI_DiffTimevalsToDouble(&fast_slew_duration, raw, &slew_start_tv);
|
||||||
fast_slew_achieved = delta_total_tick * fast_slew_duration /
|
fast_slew_achieved = delta_total_tick * fast_slew_duration /
|
||||||
@@ -566,6 +623,7 @@ immediate_step(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
offset_register -= (double) offset / 1.0e6;
|
offset_register -= (double) offset / 1.0e6;
|
||||||
|
slow_slewing = 0;
|
||||||
|
|
||||||
if (gettimeofday(&old_time, &tz) < 0) {
|
if (gettimeofday(&old_time, &tz) < 0) {
|
||||||
CROAK("gettimeofday() failed in immediate_step");
|
CROAK("gettimeofday() failed in immediate_step");
|
||||||
@@ -584,6 +642,21 @@ immediate_step(void)
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_leap(int leap)
|
||||||
|
{
|
||||||
|
if (TMX_SetLeap(leap) < 0) {
|
||||||
|
LOG_FATAL(LOGF_SysLinux, "adjtimex() failed in set_leap");
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(LOGS_INFO, LOGF_SysLinux, "System clock status set to %s leap second",
|
||||||
|
leap ? (leap > 0 ? "insert" : "delete") : "not insert/delete");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
/* Estimate the value of HZ given the value of txc.tick that chronyd finds when
|
/* Estimate the value of HZ given the value of txc.tick that chronyd finds when
|
||||||
* it starts. The only credible values are 100 (Linux/x86) or powers of 2.
|
* it starts. The only credible values are 100 (Linux/x86) or powers of 2.
|
||||||
* Also, the bounds checking inside the kernel's adjtimex system call enforces
|
* Also, the bounds checking inside the kernel's adjtimex system call enforces
|
||||||
@@ -762,13 +835,19 @@ get_version_specific_details(void)
|
|||||||
case 4:
|
case 4:
|
||||||
case 5:
|
case 5:
|
||||||
case 6:
|
case 6:
|
||||||
|
if (minor < 6 || patch < 27) {
|
||||||
|
/* These seem to be like 2.0.32 */
|
||||||
|
freq_scale = (hz==100) ? (128.0 / 128.125) : basic_freq_scale;
|
||||||
|
have_readonly_adjtime = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
/* Let's be optimistic that these will be the same until proven
|
/* Let's be optimistic that these will be the same until proven
|
||||||
otherwise :-) */
|
otherwise :-) */
|
||||||
case 7:
|
case 7:
|
||||||
case 8:
|
case 8:
|
||||||
/* These seem to be like 2.0.32 */
|
/* These don't need scaling */
|
||||||
freq_scale = (hz==100) ? (128.0 / 128.125) : basic_freq_scale;
|
freq_scale = 1.0;
|
||||||
have_readonly_adjtime = 0;
|
have_readonly_adjtime = 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_FATAL(LOGF_SysLinux, "Kernel version not supported yet, sorry.");
|
LOG_FATAL(LOGF_SysLinux, "Kernel version not supported yet, sorry.");
|
||||||
@@ -805,7 +884,7 @@ SYS_Linux_Initialise(void)
|
|||||||
|
|
||||||
lcl_RegisterSystemDrivers(read_frequency, set_frequency,
|
lcl_RegisterSystemDrivers(read_frequency, set_frequency,
|
||||||
accrue_offset, apply_step_offset,
|
accrue_offset, apply_step_offset,
|
||||||
get_offset_correction, immediate_step);
|
get_offset_correction, immediate_step, set_leap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -831,6 +910,106 @@ SYS_Linux_GetKernelVersion(int *major, int *minor, int *patchlevel)
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
#ifdef FEAT_LINUXCAPS
|
||||||
|
void
|
||||||
|
SYS_Linux_DropRoot(char *user)
|
||||||
|
{
|
||||||
|
struct passwd *pw;
|
||||||
|
cap_t cap;
|
||||||
|
|
||||||
|
if (user == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((pw = getpwnam(user)) == NULL) {
|
||||||
|
LOG_FATAL(LOGF_SysLinux, "getpwnam(%s) failed", user);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prctl(PR_SET_KEEPCAPS, 1)) {
|
||||||
|
LOG_FATAL(LOGF_SysLinux, "prcap() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setgroups(0, NULL)) {
|
||||||
|
LOG_FATAL(LOGF_SysLinux, "setgroups() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setgid(pw->pw_gid)) {
|
||||||
|
LOG_FATAL(LOGF_SysLinux, "setgid(%d) failed", pw->pw_gid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setuid(pw->pw_uid)) {
|
||||||
|
LOG_FATAL(LOGF_SysLinux, "setuid(%d) failed", pw->pw_uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((cap = cap_from_text("cap_sys_time=ep")) == NULL) {
|
||||||
|
LOG_FATAL(LOGF_SysLinux, "cap_from_text() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cap_set_proc(cap)) {
|
||||||
|
LOG_FATAL(LOGF_SysLinux, "cap_set_proc() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
cap_free(cap);
|
||||||
|
|
||||||
|
LOG(LOGS_INFO, LOGF_SysLinux, "Privileges dropped to user %s", user);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
#if defined(HAVE_SCHED_SETSCHEDULER)
|
||||||
|
/* Install SCHED_FIFO real-time scheduler with specified priority */
|
||||||
|
void SYS_Linux_SetScheduler(int SchedPriority)
|
||||||
|
{
|
||||||
|
int pmax, pmin;
|
||||||
|
struct sched_param sched;
|
||||||
|
|
||||||
|
if (SchedPriority < 1 || SchedPriority > 99) {
|
||||||
|
LOG_FATAL(LOGF_SysLinux, "Bad scheduler priority: %d", SchedPriority);
|
||||||
|
} else {
|
||||||
|
sched.sched_priority = SchedPriority;
|
||||||
|
pmax = sched_get_priority_max(SCHED_FIFO);
|
||||||
|
pmin = sched_get_priority_min(SCHED_FIFO);
|
||||||
|
if ( SchedPriority > pmax ) {
|
||||||
|
sched.sched_priority = pmax;
|
||||||
|
}
|
||||||
|
else if ( SchedPriority < pmin ) {
|
||||||
|
sched.sched_priority = pmin;
|
||||||
|
}
|
||||||
|
if ( sched_setscheduler(0, SCHED_FIFO, &sched) == -1 ) {
|
||||||
|
LOG(LOGS_ERR, LOGF_SysLinux, "sched_setscheduler() failed");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG(LOGS_INFO, LOGF_SysLinux, "Enabled SCHED_FIFO with priority %d", sched.sched_priority);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SCHED_SETSCHEDULER */
|
||||||
|
|
||||||
|
#if defined(HAVE_MLOCKALL)
|
||||||
|
/* Lock the process into RAM so that it will never be swapped out */
|
||||||
|
void SYS_Linux_MemLockAll(int LockAll)
|
||||||
|
{
|
||||||
|
struct rlimit rlim;
|
||||||
|
if (LockAll == 1 ) {
|
||||||
|
/* Make sure that we will be able to lock all the memory we need */
|
||||||
|
/* even after dropping privileges. This does not actually reaerve any memory */
|
||||||
|
rlim.rlim_max = RLIM_INFINITY;
|
||||||
|
rlim.rlim_cur = RLIM_INFINITY;
|
||||||
|
if (setrlimit(RLIMIT_MEMLOCK, &rlim) < 0) {
|
||||||
|
LOG(LOGS_ERR, LOGF_SysLinux, "setrlimit() failed: not locking into RAM");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) {
|
||||||
|
LOG(LOGS_ERR, LOGF_SysLinux, "mlockall() failed");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG(LOGS_INFO, LOGF_SysLinux, "Successfully locked into RAM");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* HAVE_MLOCKALL */
|
||||||
|
|
||||||
#endif /* LINUX */
|
#endif /* LINUX */
|
||||||
|
|
||||||
/* vim:ts=8
|
/* vim:ts=8
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -37,4 +37,10 @@ extern void SYS_Linux_Finalise(void);
|
|||||||
|
|
||||||
extern void SYS_Linux_GetKernelVersion(int *major, int *minor, int *patchlevel);
|
extern void SYS_Linux_GetKernelVersion(int *major, int *minor, int *patchlevel);
|
||||||
|
|
||||||
|
extern void SYS_Linux_DropRoot(char *user);
|
||||||
|
|
||||||
|
extern void SYS_Linux_MemLockAll(int LockAll);
|
||||||
|
|
||||||
|
extern void SYS_Linux_SetScheduler(int SchedPriority);
|
||||||
|
|
||||||
#endif /* GOT_SYS_LINUX_H */
|
#endif /* GOT_SYS_LINUX_H */
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -308,7 +308,8 @@ SYS_NetBSD_Initialise(void)
|
|||||||
|
|
||||||
lcl_RegisterSystemDrivers(read_frequency, set_frequency,
|
lcl_RegisterSystemDrivers(read_frequency, set_frequency,
|
||||||
accrue_offset, apply_step_offset,
|
accrue_offset, apply_step_offset,
|
||||||
get_offset_correction, NULL /* immediate_step */);
|
get_offset_correction, NULL /* immediate_step */,
|
||||||
|
NULL /* set_leap */);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -444,7 +444,8 @@ SYS_Solaris_Initialise(void)
|
|||||||
|
|
||||||
lcl_RegisterSystemDrivers(read_frequency, set_frequency,
|
lcl_RegisterSystemDrivers(read_frequency, set_frequency,
|
||||||
accrue_offset, apply_step_offset,
|
accrue_offset, apply_step_offset,
|
||||||
get_offset_correction, NULL /* immediate_step */);
|
get_offset_correction, NULL /* immediate_step */,
|
||||||
|
NULL /* set_leap */);
|
||||||
|
|
||||||
/* Turn off the kernel switch that keeps the system clock in step
|
/* Turn off the kernel switch that keeps the system clock in step
|
||||||
with the non-volatile clock */
|
with the non-volatile clock */
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -368,7 +368,7 @@ setup_kernel(unsigned long on_off)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (kvm_write(kt, nl[2].n_value,
|
if (kvm_write(kt, nl[2].n_value,
|
||||||
(char *)(&(on_off ? default_tickadj : our_tickadj)),
|
(char *)(on_off ? &default_tickadj : &our_tickadj),
|
||||||
sizeof(unsigned long)) < 0) {
|
sizeof(unsigned long)) < 0) {
|
||||||
LOG(LOGS_ERR, LOGF_SysSunOS, "Cannot write to _tickadj");
|
LOG(LOGS_ERR, LOGF_SysSunOS, "Cannot write to _tickadj");
|
||||||
kvm_close(kt);
|
kvm_close(kt);
|
||||||
@@ -395,7 +395,8 @@ SYS_SunOS_Initialise(void)
|
|||||||
|
|
||||||
lcl_RegisterSystemDrivers(read_frequency, set_frequency,
|
lcl_RegisterSystemDrivers(read_frequency, set_frequency,
|
||||||
accrue_offset, apply_step_offset,
|
accrue_offset, apply_step_offset,
|
||||||
get_offset_correction, NULL /* immediate_step */);
|
get_offset_correction, NULL /* immediate_step */,
|
||||||
|
NULL /* set_leap */);
|
||||||
|
|
||||||
/* Turn off the kernel switch that keeps the system clock in step
|
/* Turn off the kernel switch that keeps the system clock in step
|
||||||
with the non-volatile clock */
|
with the non-volatile clock */
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -79,6 +79,11 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
/* For inet_ntop() */
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined (SOLARIS) || defined(SUNOS)
|
#if defined (SOLARIS) || defined(SUNOS)
|
||||||
/* Only needed on these platforms, and doesn't exist on some Linux
|
/* Only needed on these platforms, and doesn't exist on some Linux
|
||||||
versions. */
|
versions. */
|
||||||
|
|||||||
342
util.c
342
util.c
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
* Copyright (C) Richard P. Curnow 1997-2003
|
* Copyright (C) Richard P. Curnow 1997-2003
|
||||||
|
* Copyright (C) Miroslav Lichvar 2009
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of version 2 of the GNU General Public License as
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
@@ -19,7 +20,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -31,7 +32,7 @@
|
|||||||
#include "sysincl.h"
|
#include "sysincl.h"
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "logging.h"
|
#include "md5.h"
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
@@ -65,21 +66,14 @@ UTI_CompareTimevals(struct timeval *a, struct timeval *b)
|
|||||||
} else if (a->tv_sec > b->tv_sec) {
|
} else if (a->tv_sec > b->tv_sec) {
|
||||||
return +1;
|
return +1;
|
||||||
} else {
|
} else {
|
||||||
if (a->tv_sec != b->tv_sec) {
|
|
||||||
CROAK("a->tv_sec != b->tv_sec");
|
|
||||||
}
|
|
||||||
if (a->tv_usec < b->tv_usec) {
|
if (a->tv_usec < b->tv_usec) {
|
||||||
return -1;
|
return -1;
|
||||||
} else if (a->tv_usec > b->tv_usec) {
|
} else if (a->tv_usec > b->tv_usec) {
|
||||||
return +1;
|
return +1;
|
||||||
} else {
|
} else {
|
||||||
if (a->tv_usec != b->tv_usec) {
|
|
||||||
CROAK("a->tv_usec != b->tv_usec");
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CROAK("Impossible"); /* Shouldn't be able to fall through. */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -87,15 +81,17 @@ UTI_CompareTimevals(struct timeval *a, struct timeval *b)
|
|||||||
INLINE_STATIC void
|
INLINE_STATIC void
|
||||||
UTI_NormaliseTimeval(struct timeval *x)
|
UTI_NormaliseTimeval(struct timeval *x)
|
||||||
{
|
{
|
||||||
while (x->tv_usec >= 1000000) {
|
/* Reduce tv_usec to within +-1000000 of zero. JGH */
|
||||||
++x->tv_sec;
|
if ((x->tv_usec >= 1000000) || (x->tv_usec <= -1000000)) {
|
||||||
x->tv_usec -= 1000000;
|
x->tv_sec += x->tv_usec/1000000;
|
||||||
|
x->tv_usec = x->tv_usec%1000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (x->tv_usec < 0) {
|
/* Make tv_usec positive. JGH */
|
||||||
|
if (x->tv_usec < 0) {
|
||||||
--x->tv_sec;
|
--x->tv_sec;
|
||||||
x->tv_usec += 1000000;
|
x->tv_usec += 1000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,17 +106,9 @@ UTI_DiffTimevals(struct timeval *result,
|
|||||||
result->tv_usec = a->tv_usec - b->tv_usec;
|
result->tv_usec = a->tv_usec - b->tv_usec;
|
||||||
|
|
||||||
/* Correct microseconds field to bring it into the range
|
/* Correct microseconds field to bring it into the range
|
||||||
[0,1000000) */
|
(0,1000000) */
|
||||||
|
|
||||||
while (result->tv_usec < 0) {
|
UTI_NormaliseTimeval(result); /* JGH */
|
||||||
result->tv_usec += 1000000;
|
|
||||||
--result->tv_sec;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (result->tv_usec > 999999) {
|
|
||||||
result->tv_usec -= 1000000;
|
|
||||||
++result->tv_sec;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -191,7 +179,7 @@ UTI_AverageDiffTimevals (struct timeval *earlier,
|
|||||||
}
|
}
|
||||||
|
|
||||||
tvhalf.tv_sec = tvdiff.tv_sec / 2;
|
tvhalf.tv_sec = tvdiff.tv_sec / 2;
|
||||||
tvhalf.tv_usec = tvdiff.tv_usec / 2 + (tvdiff.tv_sec % 2);
|
tvhalf.tv_usec = tvdiff.tv_usec / 2 + (tvdiff.tv_sec % 2) * 500000; /* JGH */
|
||||||
|
|
||||||
average->tv_sec = earlier->tv_sec + tvhalf.tv_sec;
|
average->tv_sec = earlier->tv_sec + tvhalf.tv_sec;
|
||||||
average->tv_usec = earlier->tv_usec + tvhalf.tv_usec;
|
average->tv_usec = earlier->tv_usec + tvhalf.tv_usec;
|
||||||
@@ -199,17 +187,7 @@ UTI_AverageDiffTimevals (struct timeval *earlier,
|
|||||||
/* Bring into range */
|
/* Bring into range */
|
||||||
UTI_NormaliseTimeval(average);
|
UTI_NormaliseTimeval(average);
|
||||||
|
|
||||||
while (average->tv_usec >= 1000000) {
|
}
|
||||||
++average->tv_sec;
|
|
||||||
average->tv_usec -= 1000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (average->tv_usec < 0) {
|
|
||||||
--average->tv_sec;
|
|
||||||
average->tv_usec += 1000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
@@ -264,21 +242,184 @@ UTI_TimestampToString(NTP_int64 *ts)
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
char *
|
char *
|
||||||
UTI_IPToDottedQuad(unsigned long ip)
|
UTI_RefidToString(unsigned long ref_id)
|
||||||
{
|
{
|
||||||
unsigned long a, b, c, d;
|
unsigned int a, b, c, d;
|
||||||
char *result;
|
char *result;
|
||||||
a = (ip>>24) & 0xff;
|
a = (ref_id>>24) & 0xff;
|
||||||
b = (ip>>16) & 0xff;
|
b = (ref_id>>16) & 0xff;
|
||||||
c = (ip>> 8) & 0xff;
|
c = (ref_id>> 8) & 0xff;
|
||||||
d = (ip>> 0) & 0xff;
|
d = (ref_id>> 0) & 0xff;
|
||||||
result = NEXT_BUFFER;
|
result = NEXT_BUFFER;
|
||||||
snprintf(result, BUFFER_LENGTH, "%ld.%ld.%ld.%ld", a, b, c, d);
|
snprintf(result, BUFFER_LENGTH, "%c%c%c%c", a, b, c, d);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
char *
|
||||||
|
UTI_IPToString(IPAddr *addr)
|
||||||
|
{
|
||||||
|
unsigned long a, b, c, d, ip;
|
||||||
|
uint8_t *ip6;
|
||||||
|
char *result;
|
||||||
|
|
||||||
|
result = NEXT_BUFFER;
|
||||||
|
switch (addr->family) {
|
||||||
|
case IPADDR_UNSPEC:
|
||||||
|
snprintf(result, BUFFER_LENGTH, "[UNSPEC]");
|
||||||
|
break;
|
||||||
|
case IPADDR_INET4:
|
||||||
|
ip = addr->addr.in4;
|
||||||
|
a = (ip>>24) & 0xff;
|
||||||
|
b = (ip>>16) & 0xff;
|
||||||
|
c = (ip>> 8) & 0xff;
|
||||||
|
d = (ip>> 0) & 0xff;
|
||||||
|
snprintf(result, BUFFER_LENGTH, "%ld.%ld.%ld.%ld", a, b, c, d);
|
||||||
|
break;
|
||||||
|
case IPADDR_INET6:
|
||||||
|
ip6 = addr->addr.in6;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
inet_ntop(AF_INET6, ip6, result, BUFFER_LENGTH);
|
||||||
|
#else
|
||||||
|
snprintf(result, BUFFER_LENGTH, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
|
||||||
|
ip6[0], ip6[1], ip6[2], ip6[3], ip6[4], ip6[5], ip6[6], ip6[7],
|
||||||
|
ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
snprintf(result, BUFFER_LENGTH, "[UNKNOWN]");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
int
|
||||||
|
UTI_StringToIP(const char *addr, IPAddr *ip)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
struct in_addr in4;
|
||||||
|
struct in6_addr in6;
|
||||||
|
|
||||||
|
if (inet_pton(AF_INET, addr, &in4) > 0) {
|
||||||
|
ip->family = IPADDR_INET4;
|
||||||
|
ip->addr.in4 = ntohl(in4.s_addr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inet_pton(AF_INET6, addr, &in6) > 0) {
|
||||||
|
ip->family = IPADDR_INET6;
|
||||||
|
memcpy(ip->addr.in6, in6.s6_addr, sizeof (ip->addr.in6));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
unsigned long a, b, c, d, n;
|
||||||
|
|
||||||
|
n = sscanf(addr, "%lu.%lu.%lu.%lu", &a, &b, &c, &d);
|
||||||
|
if (n == 4) {
|
||||||
|
ip->family = IPADDR_INET4;
|
||||||
|
ip->addr.in4 = ((a & 0xff) << 24) | ((b & 0xff) << 16) |
|
||||||
|
((c & 0xff) << 8) | (d & 0xff);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
unsigned long
|
||||||
|
UTI_IPToRefid(IPAddr *ip)
|
||||||
|
{
|
||||||
|
MD5_CTX ctx;
|
||||||
|
|
||||||
|
switch (ip->family) {
|
||||||
|
case IPADDR_INET4:
|
||||||
|
return ip->addr.in4;
|
||||||
|
case IPADDR_INET6:
|
||||||
|
MD5Init(&ctx);
|
||||||
|
MD5Update(&ctx, (unsigned const char *) ip->addr.in6, sizeof (ip->addr.in6));
|
||||||
|
MD5Final(&ctx);
|
||||||
|
return ctx.digest[0] << 24 | ctx.digest[1] << 16 | ctx.digest[2] << 8 | ctx.digest[3];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
void
|
||||||
|
UTI_IPHostToNetwork(IPAddr *src, IPAddr *dest)
|
||||||
|
{
|
||||||
|
/* Don't send uninitialized bytes over network */
|
||||||
|
memset(dest, 0, sizeof (IPAddr));
|
||||||
|
|
||||||
|
dest->family = htons(src->family);
|
||||||
|
|
||||||
|
switch (src->family) {
|
||||||
|
case IPADDR_INET4:
|
||||||
|
dest->addr.in4 = htonl(src->addr.in4);
|
||||||
|
break;
|
||||||
|
case IPADDR_INET6:
|
||||||
|
memcpy(dest->addr.in6, src->addr.in6, sizeof (dest->addr.in6));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
void
|
||||||
|
UTI_IPNetworkToHost(IPAddr *src, IPAddr *dest)
|
||||||
|
{
|
||||||
|
dest->family = ntohs(src->family);
|
||||||
|
|
||||||
|
switch (dest->family) {
|
||||||
|
case IPADDR_INET4:
|
||||||
|
dest->addr.in4 = ntohl(src->addr.in4);
|
||||||
|
break;
|
||||||
|
case IPADDR_INET6:
|
||||||
|
memcpy(dest->addr.in6, src->addr.in6, sizeof (dest->addr.in6));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
int
|
||||||
|
UTI_CompareIPs(IPAddr *a, IPAddr *b, IPAddr *mask)
|
||||||
|
{
|
||||||
|
int i, d;
|
||||||
|
|
||||||
|
if (a->family != b->family)
|
||||||
|
return a->family - b->family;
|
||||||
|
|
||||||
|
if (mask && mask->family != b->family)
|
||||||
|
mask = NULL;
|
||||||
|
|
||||||
|
switch (a->family) {
|
||||||
|
case IPADDR_UNSPEC:
|
||||||
|
return 0;
|
||||||
|
case IPADDR_INET4:
|
||||||
|
if (mask)
|
||||||
|
return (a->addr.in4 & mask->addr.in4) - (b->addr.in4 & mask->addr.in4);
|
||||||
|
else
|
||||||
|
return a->addr.in4 - b->addr.in4;
|
||||||
|
case IPADDR_INET6:
|
||||||
|
for (i = 0, d = 0; !d && i < 16; i++) {
|
||||||
|
if (mask)
|
||||||
|
d = (a->addr.in6[i] & mask->addr.in6[i]) -
|
||||||
|
(b->addr.in6[i] & mask->addr.in6[i]);
|
||||||
|
else
|
||||||
|
d = a->addr.in6[i] - b->addr.in6[i];
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
char *
|
char *
|
||||||
UTI_TimeToLogForm(time_t t)
|
UTI_TimeToLogForm(time_t t)
|
||||||
{
|
{
|
||||||
@@ -346,19 +487,112 @@ UTI_Int64ToTimeval(NTP_int64 *src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
/* Force a core dump and exit without doing abort() or assert(0).
|
|
||||||
These do funny things with the call stack in the core file that is
|
|
||||||
generated, which makes diagnosis difficult. */
|
|
||||||
|
|
||||||
int
|
void
|
||||||
croak(const char *file, int line, const char *msg)
|
UTI_TimevalNetworkToHost(Timeval *src, struct timeval *dest)
|
||||||
{
|
{
|
||||||
int a;
|
uint32_t sec_low, sec_high;
|
||||||
LOG(LOGS_ERR, LOGF_Util, "Unexpected condition [%s] at %s:%d, core dumped",
|
|
||||||
msg, file, line);
|
dest->tv_usec = ntohl(src->tv_nsec) / 1000;
|
||||||
a = * (int *) 0;
|
sec_high = ntohl(src->tv_sec_high);
|
||||||
return a; /* Can't happen - this stops the optimiser optimising the
|
sec_low = ntohl(src->tv_sec_low);
|
||||||
line above */
|
|
||||||
|
/* get the missing bits from current time when received timestamp
|
||||||
|
is only 32-bit */
|
||||||
|
if (sizeof (time_t) > 4 && sec_high == TV_NOHIGHSEC) {
|
||||||
|
struct timeval now;
|
||||||
|
struct timezone tz;
|
||||||
|
|
||||||
|
gettimeofday(&now, &tz);
|
||||||
|
sec_high = now.tv_sec >> 16 >> 16;
|
||||||
|
}
|
||||||
|
dest->tv_sec = (time_t)sec_high << 16 << 16 | sec_low;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
void
|
||||||
|
UTI_TimevalHostToNetwork(struct timeval *src, Timeval *dest)
|
||||||
|
{
|
||||||
|
dest->tv_nsec = htonl(src->tv_usec * 1000);
|
||||||
|
if (sizeof (time_t) > 4)
|
||||||
|
dest->tv_sec_high = htonl(src->tv_sec >> 16 >> 16);
|
||||||
|
else
|
||||||
|
dest->tv_sec_high = htonl(TV_NOHIGHSEC);
|
||||||
|
dest->tv_sec_low = htonl(src->tv_sec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
#define FLOAT_EXP_BITS 7
|
||||||
|
#define FLOAT_EXP_MIN (-(1 << (FLOAT_EXP_BITS - 1)))
|
||||||
|
#define FLOAT_EXP_MAX (-FLOAT_EXP_MIN - 1)
|
||||||
|
#define FLOAT_COEF_BITS ((int)sizeof (int32_t) * 8 - FLOAT_EXP_BITS)
|
||||||
|
#define FLOAT_COEF_MIN (-(1 << (FLOAT_COEF_BITS - 1)))
|
||||||
|
#define FLOAT_COEF_MAX (-FLOAT_COEF_MIN - 1)
|
||||||
|
|
||||||
|
double
|
||||||
|
UTI_FloatNetworkToHost(Float f)
|
||||||
|
{
|
||||||
|
int32_t exp, coef, x;
|
||||||
|
|
||||||
|
x = ntohl(f.f);
|
||||||
|
exp = (x >> FLOAT_COEF_BITS) - FLOAT_COEF_BITS;
|
||||||
|
coef = x << FLOAT_EXP_BITS >> FLOAT_EXP_BITS;
|
||||||
|
return coef * pow(2.0, exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
Float
|
||||||
|
UTI_FloatHostToNetwork(double x)
|
||||||
|
{
|
||||||
|
int32_t exp, coef, neg;
|
||||||
|
Float f;
|
||||||
|
|
||||||
|
if (x < 0.0) {
|
||||||
|
x = -x;
|
||||||
|
neg = 1;
|
||||||
|
} else {
|
||||||
|
neg = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x < 1.0e-100) {
|
||||||
|
exp = coef = 0;
|
||||||
|
} else if (x > 1.0e100) {
|
||||||
|
exp = FLOAT_EXP_MAX;
|
||||||
|
coef = FLOAT_COEF_MAX + neg;
|
||||||
|
} else {
|
||||||
|
exp = log(x) / log(2) + 1;
|
||||||
|
coef = x * pow(2.0, -exp + FLOAT_COEF_BITS) + 0.5;
|
||||||
|
|
||||||
|
assert(coef > 0);
|
||||||
|
|
||||||
|
/* we may need to shift up to two bits down */
|
||||||
|
while (coef > FLOAT_COEF_MAX + neg) {
|
||||||
|
coef >>= 1;
|
||||||
|
exp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exp > FLOAT_EXP_MAX) {
|
||||||
|
/* overflow */
|
||||||
|
exp = FLOAT_EXP_MAX;
|
||||||
|
coef = FLOAT_COEF_MAX + neg;
|
||||||
|
} else if (exp < FLOAT_EXP_MIN) {
|
||||||
|
/* underflow */
|
||||||
|
if (exp + FLOAT_COEF_BITS >= FLOAT_EXP_MIN) {
|
||||||
|
coef >>= FLOAT_EXP_MIN - exp;
|
||||||
|
exp = FLOAT_EXP_MIN;
|
||||||
|
} else {
|
||||||
|
exp = coef = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* negate back */
|
||||||
|
if (neg)
|
||||||
|
coef = (uint32_t)-coef << FLOAT_EXP_BITS >> FLOAT_EXP_BITS;
|
||||||
|
|
||||||
|
f.f = htonl(exp << FLOAT_COEF_BITS | coef);
|
||||||
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|||||||
28
util.h
28
util.h
@@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* 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.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
@@ -33,7 +33,9 @@
|
|||||||
|
|
||||||
#include "sysincl.h"
|
#include "sysincl.h"
|
||||||
|
|
||||||
|
#include "addressing.h"
|
||||||
#include "ntp.h"
|
#include "ntp.h"
|
||||||
|
#include "candm.h"
|
||||||
|
|
||||||
/* Convert a timeval into a floating point number of seconds */
|
/* Convert a timeval into a floating point number of seconds */
|
||||||
extern void UTI_TimevalToDouble(struct timeval *a, double *b);
|
extern void UTI_TimevalToDouble(struct timeval *a, double *b);
|
||||||
@@ -72,8 +74,17 @@ extern char *UTI_TimevalToString(struct timeval *tv);
|
|||||||
diagnostic display */
|
diagnostic display */
|
||||||
extern char *UTI_TimestampToString(NTP_int64 *ts);
|
extern char *UTI_TimestampToString(NTP_int64 *ts);
|
||||||
|
|
||||||
/* Convert an IP address to dotted quad notation, for diagnostics */
|
/* Convert ref_id into a temporary string, for diagnostics */
|
||||||
extern char *UTI_IPToDottedQuad(unsigned long ip);
|
extern char *UTI_RefidToString(unsigned long ref_id);
|
||||||
|
|
||||||
|
/* Convert an IP address to string, for diagnostics */
|
||||||
|
extern char *UTI_IPToString(IPAddr *ip);
|
||||||
|
|
||||||
|
extern int UTI_StringToIP(const char *addr, IPAddr *ip);
|
||||||
|
extern unsigned long UTI_IPToRefid(IPAddr *ip);
|
||||||
|
extern void UTI_IPHostToNetwork(IPAddr *src, IPAddr *dest);
|
||||||
|
extern void UTI_IPNetworkToHost(IPAddr *src, IPAddr *dest);
|
||||||
|
extern int UTI_CompareIPs(IPAddr *a, IPAddr *b, IPAddr *mask);
|
||||||
|
|
||||||
extern char *UTI_TimeToLogForm(time_t t);
|
extern char *UTI_TimeToLogForm(time_t t);
|
||||||
|
|
||||||
@@ -85,14 +96,11 @@ extern void UTI_TimevalToInt64(struct timeval *src, NTP_int64 *dest);
|
|||||||
|
|
||||||
extern void UTI_Int64ToTimeval(NTP_int64 *src, struct timeval *dest);
|
extern void UTI_Int64ToTimeval(NTP_int64 *src, struct timeval *dest);
|
||||||
|
|
||||||
/* Like assert(0) */
|
extern void UTI_TimevalNetworkToHost(Timeval *src, struct timeval *dest);
|
||||||
|
extern void UTI_TimevalHostToNetwork(struct timeval *src, Timeval *dest);
|
||||||
|
|
||||||
#if defined(LINUX) && defined(__alpha__)
|
extern double UTI_FloatNetworkToHost(Float x);
|
||||||
#define CROAK(message) assert(0) /* Added JGH Feb 24 2001 FIXME */
|
extern Float UTI_FloatHostToNetwork(double x);
|
||||||
#else
|
|
||||||
extern int croak(const char *file, int line, const char *msg);
|
|
||||||
#define CROAK(message) croak(__FILE__, __LINE__, message);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (INLINE_UTILITIES)
|
#if defined (INLINE_UTILITIES)
|
||||||
#define INLINE_STATIC inline static
|
#define INLINE_STATIC inline static
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user