mirror of
https://gitlab.com/chrony/chrony.git
synced 2025-12-03 18:35:06 -05:00
Compare commits
482 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5658f4d9c | ||
|
|
ad58baa13b | ||
|
|
c6fdeeb6bb | ||
|
|
7712455d9a | ||
|
|
a9a5f98406 | ||
|
|
9ac8f64d89 | ||
|
|
0da5cf9163 | ||
|
|
f6a39d75a7 | ||
|
|
25aa9f5b42 | ||
|
|
829b3adac3 | ||
|
|
4847a3a259 | ||
|
|
551541d9c8 | ||
|
|
f996f4c9fb | ||
|
|
ac78ad60f3 | ||
|
|
42d7cf8922 | ||
|
|
e811ba7b4c | ||
|
|
cb464cac4d | ||
|
|
fa409ddc8f | ||
|
|
821226e473 | ||
|
|
0e298bedf6 | ||
|
|
aa76760268 | ||
|
|
8bf87bbfde | ||
|
|
38e889c85c | ||
|
|
d5b737cce8 | ||
|
|
6ba764b5be | ||
|
|
707b857b68 | ||
|
|
f8d609fee5 | ||
|
|
01f797ac05 | ||
|
|
6fa11a853a | ||
|
|
9c78ad708b | ||
|
|
57f8160d6c | ||
|
|
8d80ce444f | ||
|
|
95c3acf67e | ||
|
|
561f7a66dd | ||
|
|
0193688671 | ||
|
|
6d7605a3d0 | ||
|
|
e0171f6e96 | ||
|
|
4ef1c6f2c8 | ||
|
|
f7e2d7c2ec | ||
|
|
3d1be1cd75 | ||
|
|
2d509eb8bd | ||
|
|
6ca73bf670 | ||
|
|
f7802f0111 | ||
|
|
2f3ef235a1 | ||
|
|
1ad22e9a02 | ||
|
|
6d2fb9f782 | ||
|
|
22e5ed44c2 | ||
|
|
9666831818 | ||
|
|
ff8e04f9ba | ||
|
|
52272f4dc5 | ||
|
|
18a66a2ba8 | ||
|
|
8aa9eb19c8 | ||
|
|
62027f1b47 | ||
|
|
41805d572f | ||
|
|
58f768928a | ||
|
|
0074135097 | ||
|
|
8eb7ce8581 | ||
|
|
2ceb3c89ca | ||
|
|
d46e2a69a1 | ||
|
|
20f9454be3 | ||
|
|
8092366897 | ||
|
|
066254b6c8 | ||
|
|
79811bf3e2 | ||
|
|
32bf32e7d5 | ||
|
|
df968ca47c | ||
|
|
cce7a5f15e | ||
|
|
288043c13b | ||
|
|
78ae4ebfaa | ||
|
|
cf700a0084 | ||
|
|
60a25f6e71 | ||
|
|
3eff836b2e | ||
|
|
2b9fe764d5 | ||
|
|
030e3b2dab | ||
|
|
5079f6bbff | ||
|
|
afceb9d24e | ||
|
|
a2656a20bc | ||
|
|
359d444343 | ||
|
|
d510154ba2 | ||
|
|
1c901b82dc | ||
|
|
ea3672df4e | ||
|
|
72d0b3c913 | ||
|
|
51a2d8dfd8 | ||
|
|
bc25380950 | ||
|
|
ae1e3bf73c | ||
|
|
9673a2726c | ||
|
|
02524397c1 | ||
|
|
5e5dde1a67 | ||
|
|
0f8def4ca4 | ||
|
|
182ec04e24 | ||
|
|
ebae435398 | ||
|
|
52657945d8 | ||
|
|
12166f8a47 | ||
|
|
c5f1dd8615 | ||
|
|
10e67e3c1d | ||
|
|
4e8ceaae86 | ||
|
|
73d4eaafbb | ||
|
|
cf00179964 | ||
|
|
edda0c60b3 | ||
|
|
f2eb6b165a | ||
|
|
4933c216b2 | ||
|
|
0655def57f | ||
|
|
6eafff2450 | ||
|
|
0bb772c575 | ||
|
|
b261693095 | ||
|
|
129db63e30 | ||
|
|
1759d89d8a | ||
|
|
0540b17fb9 | ||
|
|
8893dda350 | ||
|
|
b14689d59b | ||
|
|
1ca844af98 | ||
|
|
3059747c35 | ||
|
|
bbbb3633a7 | ||
|
|
df6c2a432f | ||
|
|
d0acfc2652 | ||
|
|
711cda6aed | ||
|
|
0c738d84af | ||
|
|
be1e1dc441 | ||
|
|
2a305d8e16 | ||
|
|
15b6ab77ea | ||
|
|
6199822783 | ||
|
|
0b72b2940a | ||
|
|
d4ce3f19c3 | ||
|
|
824e86a82f | ||
|
|
2a5c045c3d | ||
|
|
f7c65a4b88 | ||
|
|
a8956f2f56 | ||
|
|
91c9f84a01 | ||
|
|
2be89bc6f2 | ||
|
|
d6c447a445 | ||
|
|
a60586eaad | ||
|
|
d77356837a | ||
|
|
d6842301dd | ||
|
|
19b3c5be26 | ||
|
|
5fb5a89f02 | ||
|
|
9367e7b9af | ||
|
|
6673cadfa2 | ||
|
|
b485051b65 | ||
|
|
9a01ccc07f | ||
|
|
1b8deaf354 | ||
|
|
c7d0232bb1 | ||
|
|
79e5f2be13 | ||
|
|
9ab181eb9c | ||
|
|
3cc6021e03 | ||
|
|
375389fa1e | ||
|
|
777303f130 | ||
|
|
6015f99d98 | ||
|
|
78fc17c661 | ||
|
|
d42addf746 | ||
|
|
f570eb76b3 | ||
|
|
cc3f5962b8 | ||
|
|
6ab3d1daa3 | ||
|
|
b088b70f82 | ||
|
|
fbbb6bbc00 | ||
|
|
5c36342958 | ||
|
|
f1a0cacc5a | ||
|
|
1d2a0856b4 | ||
|
|
7fb50d9a3e | ||
|
|
919b5b5a7d | ||
|
|
1e35b26826 | ||
|
|
27b0b5824a | ||
|
|
1d72d22bc5 | ||
|
|
e0c9ed44f9 | ||
|
|
411f4da340 | ||
|
|
4fac84098e | ||
|
|
21b2063a6f | ||
|
|
917c191650 | ||
|
|
2bfce03d29 | ||
|
|
1cb8167be0 | ||
|
|
40d33cc64d | ||
|
|
95433e9639 | ||
|
|
bbe1a09e7e | ||
|
|
dce2366b3a | ||
|
|
bab7ba22cf | ||
|
|
d6a91057ae | ||
|
|
c6e9065498 | ||
|
|
22fda21eae | ||
|
|
103a520aa6 | ||
|
|
86531a51a7 | ||
|
|
2b7e4d645f | ||
|
|
a5f63180fc | ||
|
|
934d4e04b5 | ||
|
|
1b8547059a | ||
|
|
91279a0f28 | ||
|
|
31ba3144c8 | ||
|
|
0bf34725e3 | ||
|
|
91749ebb2b | ||
|
|
4ba3dd66ad | ||
|
|
d40696f7f3 | ||
|
|
4a401a9e83 | ||
|
|
6a2a837ede | ||
|
|
eca08a281c | ||
|
|
9fd8f76fa0 | ||
|
|
50de930730 | ||
|
|
da1097095c | ||
|
|
ec7d302a6c | ||
|
|
8cc7ebffa9 | ||
|
|
de4d14843f | ||
|
|
18605795a7 | ||
|
|
da2c8d9076 | ||
|
|
3120f8adb6 | ||
|
|
2dcc16169b | ||
|
|
a8efd8c398 | ||
|
|
bb40f4aff4 | ||
|
|
66c7ac4d24 | ||
|
|
7f12919fea | ||
|
|
55e0c6a0a1 | ||
|
|
20f306602b | ||
|
|
70735d8d79 | ||
|
|
165e6805ab | ||
|
|
2a0c35646c | ||
|
|
28710e0449 | ||
|
|
c5587b60b2 | ||
|
|
bb95c39356 | ||
|
|
20a43409c6 | ||
|
|
4699f7ca0b | ||
|
|
bc7586b3f4 | ||
|
|
8d3d45ea1a | ||
|
|
21ba1d3761 | ||
|
|
e79584bb9e | ||
|
|
bca7819247 | ||
|
|
0ecabae2c3 | ||
|
|
598c04eea2 | ||
|
|
faec23f6bd | ||
|
|
896dad9224 | ||
|
|
680612cf09 | ||
|
|
3fbd4bb15f | ||
|
|
cb9055072d | ||
|
|
0fc9b555f1 | ||
|
|
6ed58628f5 | ||
|
|
efff149988 | ||
|
|
b02d4092f1 | ||
|
|
9dc7ea7c62 | ||
|
|
546a3cdd50 | ||
|
|
e8c5d15690 | ||
|
|
e63cba05b2 | ||
|
|
e8fe1dc415 | ||
|
|
9cf08fc780 | ||
|
|
b712b3a979 | ||
|
|
a931b2eece | ||
|
|
2e74beebbf | ||
|
|
db510a9558 | ||
|
|
222198acf3 | ||
|
|
bc4d5df94e | ||
|
|
9d35b5deac | ||
|
|
59c68d240c | ||
|
|
930a41b845 | ||
|
|
323f0d187e | ||
|
|
0078705bbe | ||
|
|
3b3ca4afdc | ||
|
|
1d6b94b458 | ||
|
|
30c038c3c3 | ||
|
|
05e002cd42 | ||
|
|
7f6ed73145 | ||
|
|
0c4968ec51 | ||
|
|
ff69e86559 | ||
|
|
98f79404d6 | ||
|
|
eec438a614 | ||
|
|
c88801065f | ||
|
|
833022b745 | ||
|
|
d1b820e7e3 | ||
|
|
4373918a2f | ||
|
|
6e96b4ba33 | ||
|
|
2d326bfc48 | ||
|
|
a6988b2a79 | ||
|
|
8b93e1a780 | ||
|
|
4e318c1abc | ||
|
|
3cb6840d2d | ||
|
|
6ed5a65064 | ||
|
|
b977c95be4 | ||
|
|
feb8811f37 | ||
|
|
0de82a70a6 | ||
|
|
cc3a8918f0 | ||
|
|
63ef2badd6 | ||
|
|
e98080b8bb | ||
|
|
bed5b72cbe | ||
|
|
7ab2c0e4a5 | ||
|
|
7a6ee1d729 | ||
|
|
d9596334c3 | ||
|
|
16676ae726 | ||
|
|
fd3702f973 | ||
|
|
d674d23b45 | ||
|
|
5b8835f46b | ||
|
|
ddb2cf3b8b | ||
|
|
f924862e89 | ||
|
|
061d497df0 | ||
|
|
3a222336d7 | ||
|
|
78300d018a | ||
|
|
e95676f65f | ||
|
|
c8fe69c956 | ||
|
|
fe4b661fe7 | ||
|
|
5344028c40 | ||
|
|
e591e3622b | ||
|
|
d8fc5fee0a | ||
|
|
eeb73b3670 | ||
|
|
2f2e524bc6 | ||
|
|
6b0198c2d7 | ||
|
|
2a64b75893 | ||
|
|
034e172033 | ||
|
|
1faeb45063 | ||
|
|
fa84496423 | ||
|
|
a3d47ffc81 | ||
|
|
d841c86a6e | ||
|
|
3b4e4b785d | ||
|
|
7ba6b617a1 | ||
|
|
100f732e20 | ||
|
|
cb28aeeacc | ||
|
|
7994b31de4 | ||
|
|
6dcf3238f6 | ||
|
|
f6320e7050 | ||
|
|
597bb80d18 | ||
|
|
9775f3a030 | ||
|
|
a080d00352 | ||
|
|
5fb0a9d53b | ||
|
|
40d82675bd | ||
|
|
f851e1f90e | ||
|
|
73d775c8b4 | ||
|
|
97f3e9404a | ||
|
|
83da131e99 | ||
|
|
7973aef7b7 | ||
|
|
9a3bdcc20b | ||
|
|
aa91c608f4 | ||
|
|
3d260d41b3 | ||
|
|
2458325c09 | ||
|
|
ab68a9d1d3 | ||
|
|
93b5b08bed | ||
|
|
be4369936b | ||
|
|
1a7415a6ab | ||
|
|
c15db71f9e | ||
|
|
74cb1c877c | ||
|
|
a949ab6935 | ||
|
|
f0fd7099c0 | ||
|
|
e0009f9f40 | ||
|
|
14d2576924 | ||
|
|
c386d11765 | ||
|
|
f12bc10917 | ||
|
|
99d18abf59 | ||
|
|
bc29c84610 | ||
|
|
e78e65ef22 | ||
|
|
f9103531c4 | ||
|
|
2ea87490f4 | ||
|
|
5fb5551c36 | ||
|
|
b9b0326d15 | ||
|
|
97f2f16fd6 | ||
|
|
fc1514db04 | ||
|
|
7fb0598b50 | ||
|
|
fd375ca55b | ||
|
|
0f70959d8e | ||
|
|
8cb6fcad7e | ||
|
|
20d898d182 | ||
|
|
10c9a7d4b7 | ||
|
|
441e42c276 | ||
|
|
fe2dbfb6cb | ||
|
|
032ac800aa | ||
|
|
5e86eeacfb | ||
|
|
75b7d33fb7 | ||
|
|
a6e532442b | ||
|
|
a123a12f59 | ||
|
|
f261251a9b | ||
|
|
a0e1154bfb | ||
|
|
e261278a5c | ||
|
|
dbb550e6db | ||
|
|
27a9b0e7b1 | ||
|
|
8a00758cf5 | ||
|
|
15e154c09d | ||
|
|
52d0c9a057 | ||
|
|
4593471ad5 | ||
|
|
a3288d4284 | ||
|
|
22f0da4da6 | ||
|
|
baa977a3ed | ||
|
|
b4b2491015 | ||
|
|
902ed3c694 | ||
|
|
4a9205b341 | ||
|
|
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 |
15
.gitignore
vendored
15
.gitignore
vendored
@@ -1,6 +1,19 @@
|
||||
*.swp
|
||||
.deps
|
||||
.vimrc
|
||||
*.o
|
||||
*.swp
|
||||
RELEASES
|
||||
Makefile
|
||||
chrony.conf.5
|
||||
chrony.info
|
||||
chrony.html
|
||||
chrony.texi
|
||||
chrony.txt
|
||||
chronyc
|
||||
chronyc.1
|
||||
chronyd
|
||||
chronyd.8
|
||||
config.h
|
||||
config.log
|
||||
tags
|
||||
version.h
|
||||
|
||||
30
COPYING
30
COPYING
@@ -1,8 +1,8 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
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
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
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.
|
||||
|
||||
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
|
||||
modification follow.
|
||||
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
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
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
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
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
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
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
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.
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
<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
|
||||
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
|
||||
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
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.
|
||||
|
||||
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
|
||||
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'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
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
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
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.
|
||||
|
||||
34
INSTALL
34
INSTALL
@@ -32,13 +32,17 @@ for Bourne-family shells, or
|
||||
for C-family shells.
|
||||
|
||||
If the software cannot (yet) be built on your system, an error message
|
||||
will be shown. Otherwise, the files `options.h' and `Makefile' will
|
||||
be generated.
|
||||
will be shown. Otherwise, `Makefile' will be generated.
|
||||
|
||||
By default, chronyc will be built to make use of the readline library. If you
|
||||
don't want this, specify the --disable-readline flag to configure. If you have
|
||||
readline and/or ncurses installed in a non-standard location, please refer to
|
||||
the chrony.txt file for information.
|
||||
If editline or readline library is available, chronyc will be built
|
||||
with line editing support. If you don't want this, specify the
|
||||
--disable-readline flag to configure. Please refer to the chrony.txt
|
||||
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
|
||||
|
||||
@@ -67,22 +71,24 @@ 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
|
||||
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
|
||||
(/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
|
||||
/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
|
||||
set up a configuration file. The contents of this depend on the
|
||||
network environment in which the computer operates. Typical scenarios
|
||||
are described in the manual. The simplest case is for a computer with
|
||||
a permanent Internet connection - suppose you want to use the NTP
|
||||
server ntp1.foobar.com as your time reference. You would create an
|
||||
/etc/chrony.conf file containing
|
||||
a permanent Internet connection - suppose you want to use public NTP
|
||||
servers from the pool.ntp.org project as your time reference. You would
|
||||
create an /etc/chrony.conf file containing
|
||||
|
||||
server ntp1.foobar.com
|
||||
driftfile /etc/chrony.drift
|
||||
server 0.pool.ntp.org
|
||||
server 1.pool.ntp.org
|
||||
server 2.pool.ntp.org
|
||||
driftfile /var/lib/chrony/drift
|
||||
|
||||
and then run /usr/local/sbin/chronyd.
|
||||
|
||||
|
||||
143
Makefile.in
143
Makefile.in
@@ -1,9 +1,5 @@
|
||||
##################################################
|
||||
#
|
||||
# $Header: /cvs/src/chrony/Makefile.in,v 1.48 2003/09/19 22:48:26 richard Exp $
|
||||
#
|
||||
# =======================================================================
|
||||
#
|
||||
# chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
#
|
||||
# Copyright (C) Richard P. Curnow 1997-2003
|
||||
@@ -19,145 +15,150 @@
|
||||
#
|
||||
# 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.,
|
||||
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# =======================================================================
|
||||
#
|
||||
# Makefile template
|
||||
|
||||
INSTALL_PREFIX=@INSTALL_PREFIX@
|
||||
SYSCONFDIR=@SYSCONFDIR@
|
||||
BINDIR=@BINDIR@
|
||||
SBINDIR=@SBINDIR@
|
||||
MANDIR=@MANDIR@
|
||||
INFODIR=@INFODIR@
|
||||
DOCDIR=@DOCDIR@
|
||||
LOCALSTATEDIR=@LOCALSTATEDIR@
|
||||
CHRONYVARDIR=@CHRONYVARDIR@
|
||||
|
||||
CC = @CC@
|
||||
CCWARNFLAGS = @CCWARNFLAGS@
|
||||
OPTFLAGS = @CFLAGS@ @EXTRA_DEFS@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
|
||||
DESTDIR=
|
||||
|
||||
HASH_OBJ = @HASH_OBJ@
|
||||
|
||||
OBJS = util.o sched.o regress.o local.o \
|
||||
sys.o main.o ntp_io.o ntp_core.o ntp_sources.o \
|
||||
sources.o sourcestats.o reference.o \
|
||||
logging.o conf.o cmdmon.o md5.o keys.o \
|
||||
logging.o conf.o cmdmon.o keys.o \
|
||||
nameserv.o acquire.o manual.o addrfilt.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 tempcomp.o $(HASH_OBJ)
|
||||
|
||||
EXTRA_OBJS=@EXTRA_OBJECTS@
|
||||
|
||||
CLI_OBJS = client.o md5.o nameserv.o getdate.o cmdparse.o \
|
||||
pktlength.o
|
||||
CLI_OBJS = client.o nameserv.o getdate.o cmdparse.o \
|
||||
pktlength.o util.o $(HASH_OBJ)
|
||||
|
||||
SRCS = $(patsubst %.o,%.c,$(OBJS))
|
||||
EXTRA_SRCS = $(patsubst %.o,%.c,$(EXTRA_OBJS))
|
||||
|
||||
CLI_SRCS = $(patsubst %.o,%.c,$(CLI_OBJS))
|
||||
ALL_OBJS = $(OBJS) $(EXTRA_OBJS) $(CLI_OBJS)
|
||||
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
|
||||
EXTRA_LIBS=@EXTRA_LIBS@
|
||||
EXTRA_CLI_LIBS=@EXTRA_CLI_LIBS@
|
||||
|
||||
DEFS=@SYSDEFS@
|
||||
|
||||
CFLAGS = $(CCWARNFLAGS) $(OPTFLAGS)
|
||||
|
||||
# Until we have a main procedure we can link, just build object files
|
||||
# to test compilation
|
||||
|
||||
all : chronyd chronyc
|
||||
|
||||
chronyd : $(OBJS) $(EXTRA_OBJS)
|
||||
$(CC) $(OPTFLAGS) -o chronyd $(OBJS) $(EXTRA_OBJS) $(LIBS) $(EXTRA_LIBS)
|
||||
$(CC) $(CFLAGS) -o chronyd $(OBJS) $(EXTRA_OBJS) $(LDFLAGS) @HASH_LINK@ $(LIBS) $(EXTRA_LIBS)
|
||||
|
||||
chronyc : $(CLI_OBJS)
|
||||
$(CC) $(OPTFLAGS) -o chronyc $(CLI_OBJS) @READLINE_LINK@ $(LIBS) $(EXTRA_CLI_LIBS)
|
||||
$(CC) $(CFLAGS) -o chronyc $(CLI_OBJS) $(LDFLAGS) @READLINE_LINK@ @HASH_LINK@ $(LIBS) $(EXTRA_CLI_LIBS)
|
||||
|
||||
client.o : client.c
|
||||
$(CC) $(CFLAGS) $(DEFS) @READLINE_COMPILE@ -c $<
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) @READLINE_COMPILE@ -c $<
|
||||
|
||||
.depend :
|
||||
gcc -MM $(SRCS) $(EXTRA_SRCS) > .depend
|
||||
$(HASH_OBJ) : $(patsubst %.o,%.c,$(HASH_OBJ))
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) @HASH_COMPILE@ -c $<
|
||||
|
||||
distclean :
|
||||
-rm -f *.o *.s chronyc chronyd core options.h Makefile *~
|
||||
distclean : clean
|
||||
-rm -f Makefile
|
||||
-rm -f chrony.conf.5 chrony.texi chronyc.1 chronyd.8
|
||||
|
||||
clean :
|
||||
-rm -f *.o *.s chronyc chronyd core *~
|
||||
|
||||
version.h : version.txt
|
||||
./mkversion
|
||||
-rm -f *.o *.s chronyc chronyd core *~ chrony.info chrony.html chrony.txt
|
||||
-rm -rf .deps
|
||||
|
||||
getdate.c : ;
|
||||
getdate :
|
||||
bison -o getdate.c getdate.y
|
||||
|
||||
# For install, don't use the install command, because its switches
|
||||
# seem to vary between systems.
|
||||
|
||||
install: chronyd chronyc
|
||||
[ -d $(DESTDIR)$(INSTALL_PREFIX) ] || mkdir -p $(DESTDIR)$(INSTALL_PREFIX)
|
||||
[ -d $(DESTDIR)$(INSTALL_PREFIX)/sbin ] || mkdir -p $(DESTDIR)$(INSTALL_PREFIX)/sbin
|
||||
[ -d $(DESTDIR)$(INSTALL_PREFIX)/bin ] || mkdir -p $(DESTDIR)$(INSTALL_PREFIX)/bin
|
||||
[ -d $(DESTDIR)$(INSTALL_PREFIX)/doc ] || mkdir -p $(DESTDIR)$(INSTALL_PREFIX)/doc
|
||||
[ -d $(DESTDIR)$(SYSCONFDIR) ] || mkdir -p $(DESTDIR)$(SYSCONFDIR)
|
||||
[ -d $(DESTDIR)$(SBINDIR) ] || mkdir -p $(DESTDIR)$(SBINDIR)
|
||||
[ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR)
|
||||
[ -d $(DESTDIR)$(DOCDIR) ] || mkdir -p $(DESTDIR)$(DOCDIR)
|
||||
[ -d $(DESTDIR)$(MANDIR)/man1 ] || mkdir -p $(DESTDIR)$(MANDIR)/man1
|
||||
[ -d $(DESTDIR)$(MANDIR)/man5 ] || mkdir -p $(DESTDIR)$(MANDIR)/man5
|
||||
[ -d $(DESTDIR)$(MANDIR)/man8 ] || mkdir -p $(DESTDIR)$(MANDIR)/man8
|
||||
[ -d $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony ] || mkdir -p $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony
|
||||
if [ -f $(DESTDIR)$(INSTALL_PREFIX)/sbin/chronyd ]; then rm -f $(DESTDIR)$(INSTALL_PREFIX)/sbin/chronyd ; fi
|
||||
if [ -f $(DESTDIR)$(INSTALL_PREFIX)/bin/chronyc ]; then rm -f $(DESTDIR)$(INSTALL_PREFIX)/bin/chronyc ; fi
|
||||
cp chronyd $(DESTDIR)$(INSTALL_PREFIX)/sbin/chronyd
|
||||
chmod 555 $(DESTDIR)$(INSTALL_PREFIX)/sbin/chronyd
|
||||
cp chronyc $(DESTDIR)$(INSTALL_PREFIX)/bin/chronyc
|
||||
chmod 555 $(DESTDIR)$(INSTALL_PREFIX)/bin/chronyc
|
||||
cp chrony.txt $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/chrony.txt
|
||||
chmod 444 $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/chrony.txt
|
||||
cp COPYING $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/COPYING
|
||||
chmod 444 $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/COPYING
|
||||
cp README $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/README
|
||||
chmod 444 $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/README
|
||||
[ -d $(DESTDIR)$(DOCDIR) ] || mkdir -p $(DESTDIR)$(DOCDIR)
|
||||
[ -d $(DESTDIR)$(CHRONYVARDIR) ] || mkdir -p $(DESTDIR)$(CHRONYVARDIR)
|
||||
if [ -f $(DESTDIR)$(SBINDIR)/chronyd ]; then rm -f $(DESTDIR)$(SBINDIR)/chronyd ; fi
|
||||
if [ -f $(DESTDIR)$(BINDIR)/chronyc ]; then rm -f $(DESTDIR)$(BINDIR)/chronyc ; fi
|
||||
cp chronyd $(DESTDIR)$(SBINDIR)/chronyd
|
||||
chmod 755 $(DESTDIR)$(SBINDIR)/chronyd
|
||||
cp chronyc $(DESTDIR)$(BINDIR)/chronyc
|
||||
chmod 755 $(DESTDIR)$(BINDIR)/chronyc
|
||||
cp chrony.txt $(DESTDIR)$(DOCDIR)/chrony.txt
|
||||
chmod 644 $(DESTDIR)$(DOCDIR)/chrony.txt
|
||||
cp COPYING $(DESTDIR)$(DOCDIR)/COPYING
|
||||
chmod 644 $(DESTDIR)$(DOCDIR)/COPYING
|
||||
cp README $(DESTDIR)$(DOCDIR)/README
|
||||
chmod 644 $(DESTDIR)$(DOCDIR)/README
|
||||
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
|
||||
chmod 444 $(DESTDIR)$(MANDIR)/man1/chronyc.1
|
||||
chmod 644 $(DESTDIR)$(MANDIR)/man1/chronyc.1
|
||||
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
|
||||
chmod 444 $(DESTDIR)$(MANDIR)/man5/chrony.conf.5
|
||||
chmod 644 $(DESTDIR)$(MANDIR)/man5/chrony.conf.5
|
||||
|
||||
%.o : %.c
|
||||
$(CC) $(CFLAGS) $(DEFS) -c $<
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
|
||||
|
||||
%.s : %.c
|
||||
$(CC) $(CFLAGS) $(DEFS) -S $<
|
||||
|
||||
main.o logging.o client.o : version.h
|
||||
|
||||
# makeinfo v4 required to generate plain text and html
|
||||
MAKEINFO:=makeinfo
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -S $<
|
||||
|
||||
install-docs : docs
|
||||
[ -d $(DESTDIR)$(INSTALL_PREFIX)/doc ] || mkdir -p $(DESTDIR)$(INSTALL_PREFIX)/doc
|
||||
cp chrony.txt $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/chrony.txt
|
||||
chown root $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/chrony.txt
|
||||
chmod 444 $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/chrony.txt
|
||||
cp chrony.html $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/chrony.html
|
||||
chown root $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/chrony.html
|
||||
chmod 444 $(DESTDIR)$(INSTALL_PREFIX)/doc/chrony/chrony.html
|
||||
[ -d $(DESTDIR)$(DOCDIR) ] || mkdir -p $(DESTDIR)$(DOCDIR)
|
||||
cp chrony.txt $(DESTDIR)$(DOCDIR)/chrony.txt
|
||||
chmod 644 $(DESTDIR)$(DOCDIR)/chrony.txt
|
||||
cp chrony.html $(DESTDIR)$(DOCDIR)/chrony.html
|
||||
chmod 644 $(DESTDIR)$(DOCDIR)/chrony.html
|
||||
[ -d $(DESTDIR)$(INFODIR) ] || mkdir -p $(DESTDIR)$(INFODIR)
|
||||
cp chrony.info* $(DESTDIR)$(INFODIR)
|
||||
chown root $(DESTDIR)$(INFODIR)/chrony.info*
|
||||
chmod 444 $(DESTDIR)$(INFODIR)/chrony.info*
|
||||
chmod 644 $(DESTDIR)$(INFODIR)/chrony.info*
|
||||
|
||||
docs : chrony.txt chrony.html chrony.info
|
||||
|
||||
chrony.txt : chrony.texi
|
||||
$(MAKEINFO) --no-headers --number-sections -o chrony.txt chrony.texi
|
||||
makeinfo --no-headers --number-sections -o chrony.txt chrony.texi
|
||||
|
||||
chrony.html : chrony.texi
|
||||
$(MAKEINFO) --no-split --html --number-sections -o chrony.html chrony.texi
|
||||
command -v texi2html > /dev/null 2>&1 && texi2html chrony.texi || \
|
||||
makeinfo --no-split --html --number-sections -o chrony.html chrony.texi
|
||||
|
||||
chrony.info : chrony.texi
|
||||
$(MAKEINFO) chrony.texi
|
||||
makeinfo chrony.texi
|
||||
|
||||
# This is only relevant if you're maintaining the website!
|
||||
faq.php : faq.txt faqgen.pl
|
||||
perl faqgen.pl < faq.txt > faq.php
|
||||
|
||||
.deps:
|
||||
@mkdir .deps
|
||||
|
||||
.deps/%.d: %.c | .deps
|
||||
@$(CC) -MM $(CPPFLAGS) -MT '$(<:%.c=%.o) $@' $< -o $@
|
||||
|
||||
-include $(ALL_OBJS:%.o=.deps/%.d)
|
||||
|
||||
139
NEWS
139
NEWS
@@ -1,3 +1,142 @@
|
||||
New in version 1.29
|
||||
===================
|
||||
|
||||
Security fixes
|
||||
--------------
|
||||
* Fix crash when processing crafted commands (CVE-2012-4502)
|
||||
(possible with IP addresses allowed by cmdallow and localhost)
|
||||
* Don't send uninitialized data in SUBNETS_ACCESSED and CLIENT_ACCESSES
|
||||
replies (CVE-2012-4503) (not used by chronyc)
|
||||
|
||||
Other changes
|
||||
-------------
|
||||
* Drop support for SUBNETS_ACCESSED and CLIENT_ACCESSES commands
|
||||
|
||||
New in version 1.28
|
||||
===================
|
||||
|
||||
* Combine sources to improve accuracy
|
||||
* Make config and command parser strict
|
||||
* Add -a option to chronyc to authenticate automatically
|
||||
* Add -R option to ignore initstepslew and makestep directives
|
||||
* Add generatecommandkey, minsamples, maxsamples and user directives
|
||||
* Improve compatibility with NTPv1 and NTPv2 clients
|
||||
* Create sockets only in selected family with -4/-6 option
|
||||
* Treat address bind errors as non-fatal
|
||||
* Extend tracking log
|
||||
* Accept float values as initstepslew threshold
|
||||
* Allow hostnames in offline, online and burst commands
|
||||
* Fix and improve peer polling
|
||||
* Fix crash in config parsing with too many servers
|
||||
* Fix crash with duplicated initstepslew address
|
||||
* Fix delta calculation with extreme frequency offsets
|
||||
* Set local stratum correctly
|
||||
* Remove unnecessary adjtimex calls
|
||||
* Set paths in documentation by configure
|
||||
* Update chrony.spec
|
||||
|
||||
New in version 1.27
|
||||
===================
|
||||
|
||||
* Support for stronger keys via NSS or libtomcrypt library
|
||||
* Support reading leap second data from tz database
|
||||
* Support for precise clock stepping on Linux
|
||||
* Support for nanoseconds in SHM refclock
|
||||
* Make offset corrections smoother on Linux
|
||||
* Make transmit timestamps random below clock precision
|
||||
* Add corrtimeratio and maxchange directives
|
||||
* Extend tracking, sources and activity reports
|
||||
* Wait in foreground process until daemon is fully initialized
|
||||
* Fix crash with slow name resolving
|
||||
* Fix iburst with jittery sources
|
||||
* Fix offset stored in rtc data right after trimrtc
|
||||
* Fix crash and hang with RTC or manual samples
|
||||
* Don't use readonly adjtime on Linux kernels before 2.6.28
|
||||
* Changed chronyc protocol, incompatible with older versions
|
||||
|
||||
New in version 1.26
|
||||
===================
|
||||
|
||||
* Add compatibility with Linux 3.0 and later
|
||||
* Use proper source address in NTP replies on multihomed IPv6 hosts
|
||||
* Accept NTP packets with versions 4, 3 and 2
|
||||
* Cope with unexpected backward time jumps
|
||||
* Don't reset kernel frequency on start without drift file
|
||||
* Retry on permanent DNS error by default
|
||||
* Add waitsync command
|
||||
|
||||
New in version 1.25
|
||||
===================
|
||||
|
||||
* Improve accuracy with NTP sources
|
||||
* Improve accuracy with reference clocks
|
||||
* Improve polling interval adjustment
|
||||
* Improve stability with temporary asymmetric delays
|
||||
* Improve source selection
|
||||
* Improve initial synchronisation
|
||||
* Add delayed server name resolving
|
||||
* Add temperature compensation
|
||||
* Add nanosecond slewing to Linux driver
|
||||
* Add fallback drifts
|
||||
* Add iburst, minstratum, maxdelaydevratio, polltarget,
|
||||
prefer, noselect options
|
||||
* Add rtcsync directive to enable Linux 11-minute mode
|
||||
* Add reselectdist, stratumweight, logbanner, maxclockerror,
|
||||
include directives
|
||||
* Add -n option to not detach daemon from terminal
|
||||
* Fix pidfile directive
|
||||
* Fix name resolving with disabled IPv6 support
|
||||
* Fix reloading sample histories with reference clocks
|
||||
* Fix crash with auto_offline option
|
||||
* Fix online command on auto_offline sources
|
||||
* Fix file descriptor leaks
|
||||
* Increase burst polling interval and stop on KoD RATE
|
||||
* Set maxupdateskew to 1000 ppm by default
|
||||
* Require password for clients command
|
||||
* Update drift file at most once per hour
|
||||
* Use system headers for Linux RTC support
|
||||
* Reduce default chronyc timeout and make it configurable
|
||||
* Avoid large values in chronyc sources and sourcestats output
|
||||
* Add reselect command to force reselecting best source
|
||||
* Add -m option to allow multiple commands on command line
|
||||
|
||||
New in version 1.24
|
||||
===================
|
||||
|
||||
Security fixes
|
||||
--------------
|
||||
* Don't reply to invalid cmdmon packets (CVE-2010-0292)
|
||||
* Limit client log memory size (CVE-2010-0293)
|
||||
* Limit rate of syslog messages (CVE-2010-0294)
|
||||
|
||||
Bug fixes/Enhancements
|
||||
----------------------
|
||||
* 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
|
||||
* Retry name resolving after temporary failure
|
||||
* Fix makestep command, make it available on all systems
|
||||
* Add makestep directive for automatic clock stepping
|
||||
* Don't require _bigadj kernel symbol on NetBSD
|
||||
* 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
|
||||
===================
|
||||
|
||||
|
||||
111
README
111
README
@@ -10,7 +10,7 @@ time. This does most of the work.
|
||||
|
||||
chronyc is a command-line interface program which can be used to
|
||||
monitor chronyd's performance and to change various operating
|
||||
parateters whilst it is running.
|
||||
parameters whilst it is running.
|
||||
|
||||
chronyd's main function is to obtain measurements of the true (UTC)
|
||||
time from one of several sources, and correct the system clock
|
||||
@@ -18,19 +18,19 @@ accordingly. It also works out the rate at which the system clock
|
||||
gains or loses time and uses this information to keep it accurate
|
||||
between measurements from the reference.
|
||||
|
||||
The reference time can be derived from either Network Time Protocol
|
||||
(NTP) servers (preferred), or wristwatch-and-keyboard (via chronyc).
|
||||
The reference time can be derived from Network Time Protocol (NTP)
|
||||
servers, reference clocks, or wristwatch-and-keyboard (via chronyc).
|
||||
The main source of information about the Network Time Protocol is
|
||||
http://www.eecis.udel.edu/~ntp.
|
||||
http://www.ntp.org.
|
||||
|
||||
It is designed so that it can work on computers which only have
|
||||
intermittent access to reference sources, for example computers which
|
||||
use a dial-up account to access the Internet. Of course, it will work
|
||||
on computers with permanent connections too.
|
||||
use a dial-up account to access the Internet or laptops. Of course, it
|
||||
will work well on computers with permanent connections too.
|
||||
|
||||
In addition, the Linux 2.0.x (for x >= 32), 2.2.x and 2.3.x versions
|
||||
can monitor the system's real time clock performance, so the system
|
||||
can maintain accurate time even across reboots.
|
||||
In addition, on Linux it can monitor the system's real time clock
|
||||
performance, so the system can maintain accurate time even across
|
||||
reboots.
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
|
||||
@@ -46,9 +48,7 @@ What will chrony 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).
|
||||
Real time clock support is limited to 2.0.32 onwards and to 2.2, 2.3 and
|
||||
2.4 series only. PowerPC is also known to be supported.
|
||||
1. Linux 2.2.x, 2.3.x, 2.4.x, 2.6.x, 3.x
|
||||
|
||||
2. Solaris 2.5/2.5.1/2.6/2.7/2.8 (various platforms)
|
||||
|
||||
@@ -69,8 +69,7 @@ How do I set it up?
|
||||
The file INSTALL gives instructions. On supported systems the
|
||||
compilation process should be automatic.
|
||||
|
||||
You will need an ANSI C compiler -- gcc is recommended. Versions
|
||||
2.7.2/2.7.2.2 are known to work.
|
||||
You will need an ANSI C compiler -- gcc is recommended.
|
||||
|
||||
The manual (in texinfo and text formats) describes how to set the
|
||||
software up for the less straightforward cases.
|
||||
@@ -84,29 +83,19 @@ ready-formatted plain text (chrony.txt) in the distribution.
|
||||
There is also information available on the chrony web pages, accessible
|
||||
through the URL
|
||||
|
||||
http://chrony.sunsite.dk/
|
||||
|
||||
What can chrony not do?
|
||||
=======================
|
||||
|
||||
Compared to the `reference' RFC1305 implementation xntpd, chronyd does
|
||||
not support hardware reference clocks, leap seconds or broadcast
|
||||
modes.
|
||||
http://chrony.tuxfamily.org/
|
||||
|
||||
Where are new versions announced?
|
||||
=================================
|
||||
|
||||
There is a low volume mailing list where new versions and other
|
||||
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
|
||||
to announce new versions 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.
|
||||
These messages will be copied to chrony-users (see below). New versions
|
||||
are announced also on Freshmeat (http://freshmeat.net/).
|
||||
|
||||
How can I get support for chrony?
|
||||
and where can I discuss new features, possible bugs etc?
|
||||
@@ -117,36 +106,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
|
||||
technical list, e.g. for discussing how new features should be
|
||||
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
|
||||
chrony-dev-subscribe@sunsite.dk
|
||||
chrony-dev-request@chrony.tuxfamily.org
|
||||
|
||||
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
|
||||
find me through one of the mailing lists. It would be nice if:
|
||||
Richard P. Curnow <rc@rc0.org.uk>
|
||||
|
||||
- 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
|
||||
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 ...).
|
||||
Maintainers
|
||||
===========
|
||||
|
||||
John Hasler <john@dhh.gt.org>
|
||||
Miroslav Lichvar <mlichvar@redhat.com>
|
||||
|
||||
|
||||
Acknowledgements
|
||||
================
|
||||
@@ -154,6 +135,9 @@ Acknowledgements
|
||||
The following people have provided patches and other major contributions
|
||||
to the program :
|
||||
|
||||
Benny Lyne Amorsen <benny@amorsen.dk>
|
||||
Patch to add minstratum option
|
||||
|
||||
Andrew Bishop <amb@gedanken.demon.co.uk>
|
||||
Fixes for bugs in logging when in daemon mode
|
||||
Fixes for compiler warnings
|
||||
@@ -199,6 +183,8 @@ John Hasler <john@dhh.gt.org>
|
||||
sizeof(unsigned long) > 4)
|
||||
Bug fix to initstepslew directive
|
||||
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>
|
||||
Advice on configuring for Linux on PPC
|
||||
@@ -206,12 +192,27 @@ Liam Hatton <me@liamhatton.com>
|
||||
Jachym Holecek <jakym@volny.cz>
|
||||
Patch to make Linux real time clock work with devfs
|
||||
|
||||
Håkan Johansson <f96hajo@chalmers.se>
|
||||
Patch to avoid large values in sources and sourcestats output
|
||||
|
||||
Jim Knoble <jmknoble@pobox.com>
|
||||
Fixes for compiler warnings
|
||||
|
||||
Antti Jrvinen <costello@iki.fi>
|
||||
Advice on configuring for BSD/386
|
||||
|
||||
Miroslav Lichvar <mlichvar@redhat.com>
|
||||
Reference clock support
|
||||
IPv6 support
|
||||
Linux capabilities support
|
||||
Leap second support
|
||||
Improved source selection
|
||||
Improved sample history trimming
|
||||
Improved polling interval adjustment
|
||||
Improved stability with temporary asymmetric delays
|
||||
Temperature compensation
|
||||
Many other bug fixes and improvements
|
||||
|
||||
Victor Moroz <vim@prv.adlum.ru>
|
||||
Patch to support Linux with HZ!=100
|
||||
|
||||
@@ -224,6 +225,9 @@ Frank Otto <sandwichmacher@web.de>
|
||||
Andreas Piesk <apiesk@virbus.de>
|
||||
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>
|
||||
Entries in contrib directory
|
||||
|
||||
@@ -239,10 +243,3 @@ Doug Woodward <dougw@whistler.com>
|
||||
|
||||
Many other people have contributed bug reports and suggestions. I'm
|
||||
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
|
||||
|
||||
248
acquire.c
248
acquire.c
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/acquire.c,v 1.24 2003/09/22 21:22:30 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -41,6 +37,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "acquire.h"
|
||||
@@ -65,7 +63,12 @@
|
||||
|
||||
#define RETRANSMISSION_TIMEOUT (1.0)
|
||||
|
||||
typedef struct { unsigned long ip_addr;
|
||||
#define NTP_VERSION 3
|
||||
#define NTP_MAX_COMPAT_VERSION 4
|
||||
#define NTP_MIN_COMPAT_VERSION 2
|
||||
|
||||
typedef struct {
|
||||
IPAddr ip_addr; /* Address of the server */
|
||||
int sanity; /* Flag indicating whether source
|
||||
looks sane or not */
|
||||
int n_dead_probes; /* Number of probes sent to the server
|
||||
@@ -91,9 +94,20 @@ static int n_sources;
|
||||
static int n_started_sources;
|
||||
static int n_completed_sources;
|
||||
|
||||
static int init_slew_threshold = -1;
|
||||
static double init_slew_threshold;
|
||||
|
||||
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
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
@@ -129,7 +143,6 @@ static SCH_TimeoutID source_start_timeout_id;
|
||||
void
|
||||
ACQ_Initialise(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -138,38 +151,74 @@ ACQ_Initialise(void)
|
||||
void
|
||||
ACQ_Finalise(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
initialise_io(void)
|
||||
static int
|
||||
prepare_socket(int family)
|
||||
{
|
||||
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) {
|
||||
LOG_FATAL(LOGF_Acquire, "Could not open socket : %s", strerror(errno));
|
||||
}
|
||||
|
||||
/* Close on exec */
|
||||
UTI_FdSetCloexec(sock_fd);
|
||||
|
||||
if (port_number == 0) {
|
||||
/* Don't bother binding this socket - we're not fussed what port
|
||||
number it gets */
|
||||
} else {
|
||||
struct sockaddr_in my_addr;
|
||||
my_addr.sin_family = AF_INET;
|
||||
my_addr.sin_port = htons(port_number);
|
||||
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
if (bind(sock_fd, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0) {
|
||||
LOG(LOGS_ERR, LOGF_Acquire, "Could not bind socket : %s\n", strerror(errno));
|
||||
union sockaddr_in46 my_addr;
|
||||
|
||||
memset(&my_addr, 0, sizeof (my_addr));
|
||||
|
||||
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", strerror(errno));
|
||||
/* 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,12 +226,18 @@ initialise_io(void)
|
||||
static void
|
||||
finalise_io(void)
|
||||
{
|
||||
if (sock_fd >= 0) {
|
||||
SCH_RemoveInputFileHandler(sock_fd);
|
||||
close(sock_fd);
|
||||
if (sock_fd4 >= 0) {
|
||||
SCH_RemoveInputFileHandler(sock_fd4);
|
||||
close(sock_fd4);
|
||||
}
|
||||
|
||||
return;
|
||||
sock_fd4 = -1;
|
||||
#ifdef HAVE_IPV6
|
||||
if (sock_fd6 >= 0) {
|
||||
SCH_RemoveInputFileHandler(sock_fd6);
|
||||
close(sock_fd6);
|
||||
}
|
||||
sock_fd6 = -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -191,14 +246,16 @@ static void
|
||||
probe_source(SourceRecord *src)
|
||||
{
|
||||
NTP_Packet pkt;
|
||||
int version = 3;
|
||||
int version = NTP_VERSION;
|
||||
NTP_Mode my_mode = MODE_CLIENT;
|
||||
struct timeval cooked;
|
||||
double local_time_err;
|
||||
struct sockaddr_in his_addr;
|
||||
union sockaddr_in46 his_addr;
|
||||
int sock_fd;
|
||||
socklen_t addrlen;
|
||||
uint32_t ts_fuzz;
|
||||
|
||||
#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
|
||||
|
||||
pkt.lvm = (((LEAP_Unsynchronised << 6) & 0xc0) |
|
||||
@@ -208,9 +265,9 @@ probe_source(SourceRecord *src)
|
||||
pkt.stratum = 0;
|
||||
pkt.poll = 4;
|
||||
pkt.precision = -6; /* as ntpdate */
|
||||
pkt.root_delay = double_to_int32(1.0); /* 1 second */
|
||||
pkt.root_dispersion = double_to_int32(1.0); /* likewise */
|
||||
pkt.reference_id = 0UL;
|
||||
pkt.root_delay = UTI_DoubleToInt32(1.0); /* 1 second */
|
||||
pkt.root_dispersion = UTI_DoubleToInt32(1.0); /* likewise */
|
||||
pkt.reference_id = 0;
|
||||
pkt.reference_ts.hi = 0; /* Set to 0 */
|
||||
pkt.reference_ts.lo = 0; /* Set to 0 */
|
||||
pkt.originate_ts.hi = 0; /* Set to 0 */
|
||||
@@ -219,18 +276,40 @@ probe_source(SourceRecord *src)
|
||||
pkt.receive_ts.lo = 0; /* Set to 0 */
|
||||
|
||||
/* And do transmission */
|
||||
his_addr.sin_addr.s_addr = htonl(src->ip_addr);
|
||||
his_addr.sin_port = htons(123); /* Fixed for now */
|
||||
his_addr.sin_family = AF_INET;
|
||||
|
||||
LCL_ReadCookedTime(&cooked, &local_time_err);
|
||||
UTI_TimevalToInt64(&cooked, &pkt.transmit_ts);
|
||||
memset(&his_addr, 0, sizeof (his_addr));
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
ts_fuzz = UTI_GetNTPTsFuzz(LCL_GetSysPrecisionAsLog());
|
||||
LCL_ReadCookedTime(&cooked, NULL);
|
||||
UTI_TimevalToInt64(&cooked, &pkt.transmit_ts, ts_fuzz);
|
||||
|
||||
if (sendto(sock_fd, (void *) &pkt, NTP_NORMAL_PACKET_SIZE,
|
||||
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",
|
||||
UTI_IPToDottedQuad(src->ip_addr),
|
||||
UTI_IPToString(&src->ip_addr),
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
@@ -239,8 +318,6 @@ probe_source(SourceRecord *src)
|
||||
++(src->n_dead_probes);
|
||||
src->timer_running = 1;
|
||||
src->timeout_id = SCH_AddTimeoutByDelay(RETRANSMISSION_TIMEOUT, transmit_timeout, (void *) src);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -253,7 +330,7 @@ transmit_timeout(void *x)
|
||||
src->timer_running = 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
|
||||
|
||||
if (src->n_dead_probes < MAX_DEAD_PROBES) {
|
||||
@@ -295,7 +372,7 @@ process_receive(NTP_Packet *msg, SourceRecord *src, struct timeval *now)
|
||||
mode = lvm & 0x7;
|
||||
|
||||
if ((leap == LEAP_Unsynchronised) ||
|
||||
(version != 3) ||
|
||||
(version < NTP_MIN_COMPAT_VERSION || version > NTP_MAX_COMPAT_VERSION) ||
|
||||
(mode != MODE_SERVER && mode != MODE_PASSIVE)) {
|
||||
return;
|
||||
}
|
||||
@@ -316,8 +393,8 @@ process_receive(NTP_Packet *msg, SourceRecord *src, struct timeval *now)
|
||||
return;
|
||||
}
|
||||
|
||||
root_delay = int32_to_double(msg->root_delay);
|
||||
root_dispersion = int32_to_double(msg->root_dispersion);
|
||||
root_delay = UTI_Int32ToDouble(msg->root_delay);
|
||||
root_dispersion = UTI_Int32ToDouble(msg->root_dispersion);
|
||||
|
||||
UTI_Int64ToTimeval(&src->last_tx, &local_orig);
|
||||
UTI_Int64ToTimeval(&msg->receive_ts, &remote_rx);
|
||||
@@ -357,14 +434,14 @@ read_from_socket(void *anything)
|
||||
{
|
||||
int status;
|
||||
ReceiveBuffer msg;
|
||||
struct sockaddr_in his_addr;
|
||||
union sockaddr_in46 his_addr;
|
||||
int sock_fd;
|
||||
socklen_t his_addr_len;
|
||||
int flags;
|
||||
int message_length;
|
||||
unsigned long remote_ip;
|
||||
IPAddr remote_ip;
|
||||
int i, ok;
|
||||
struct timeval now;
|
||||
double local_time_err;
|
||||
SourceRecord *src;
|
||||
|
||||
flags = 0;
|
||||
@@ -372,26 +449,41 @@ read_from_socket(void *anything)
|
||||
his_addr_len = sizeof(his_addr);
|
||||
|
||||
/* Get timestamp */
|
||||
LCL_ReadCookedTime(&now, &local_time_err);
|
||||
SCH_GetLastEventTime(&now, NULL, NULL);
|
||||
|
||||
sock_fd = (long)anything;
|
||||
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) {
|
||||
LOG(LOGS_WARN, LOGF_Acquire, "Error reading from socket, %s", strerror(errno));
|
||||
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
|
||||
printf("Got message from %08lx\n", remote_ip);
|
||||
printf("Got message from %s\n", UTI_IPToString(&remote_ip));
|
||||
#endif
|
||||
|
||||
/* Find matching host */
|
||||
ok = 0;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
@@ -418,7 +510,7 @@ read_from_socket(void *anything)
|
||||
(src->n_total_samples >= MAX_SAMPLES)) {
|
||||
++n_completed_sources;
|
||||
#if 0
|
||||
printf("Source %08lx completed\n", src->ip_addr);
|
||||
printf("Source %s completed\n", UTI_IPToString(&src->ip_addr));
|
||||
#endif
|
||||
if (n_completed_sources == n_sources) {
|
||||
wind_up_acquisition();
|
||||
@@ -440,7 +532,7 @@ start_next_source(void)
|
||||
{
|
||||
probe_source(sources + n_started_sources);
|
||||
#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
|
||||
n_started_sources++;
|
||||
|
||||
@@ -552,10 +644,10 @@ process_measurements(void)
|
||||
for (i=0; i<2*n_sane_sources; i++) {
|
||||
|
||||
#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].index,
|
||||
sources[eps[i].index].ip_addr,
|
||||
UTI_IPToString(&sources[eps[i].index].ip_addr),
|
||||
eps[i].offset);
|
||||
#endif
|
||||
|
||||
@@ -603,7 +695,7 @@ process_measurements(void)
|
||||
the system clock is fast of the reference, i.e. it needs to be
|
||||
stepped backwards. */
|
||||
|
||||
if (fabs(estimated_offset) > (double) init_slew_threshold) {
|
||||
if (fabs(estimated_offset) > init_slew_threshold) {
|
||||
LOG(LOGS_INFO, LOGF_Acquire, "System's initial offset : %.6f seconds %s of true (step)",
|
||||
fabs(estimated_offset),
|
||||
(estimated_offset >= 0) ? "fast" : "slow");
|
||||
@@ -612,7 +704,7 @@ process_measurements(void)
|
||||
LOG(LOGS_INFO, LOGF_Acquire, "System's initial offset : %.6f seconds %s of true (slew)",
|
||||
fabs(estimated_offset),
|
||||
(estimated_offset >= 0) ? "fast" : "slow");
|
||||
LCL_AccumulateOffset(estimated_offset);
|
||||
LCL_AccumulateOffset(estimated_offset, 0.0);
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -655,10 +747,11 @@ start_source_timeout_handler(void *not_used)
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
ACQ_StartAcquisition(int n, unsigned long *ip_addrs, int threshold, void (*after_hook)(void *), void *anything)
|
||||
ACQ_StartAcquisition(int n, IPAddr *ip_addrs, double threshold, void (*after_hook)(void *), void *anything)
|
||||
{
|
||||
|
||||
int i;
|
||||
int i, ip4, ip6;
|
||||
int k, duplicate_ip;
|
||||
|
||||
saved_after_hook = after_hook;
|
||||
saved_after_hook_anything = anything;
|
||||
@@ -667,22 +760,37 @@ ACQ_StartAcquisition(int n, unsigned long *ip_addrs, int threshold, void (*after
|
||||
|
||||
n_started_sources = 0;
|
||||
n_completed_sources = 0;
|
||||
n_sources = n;
|
||||
n_sources = 0;
|
||||
sources = MallocArray(SourceRecord, n);
|
||||
|
||||
for (i=0; i<n; i++) {
|
||||
sources[i].ip_addr = ip_addrs[i];
|
||||
sources[i].n_samples = 0;
|
||||
sources[i].n_total_samples = 0;
|
||||
sources[i].n_dead_probes = 0;
|
||||
for (i = ip4 = ip6 = 0; i < n; i++) {
|
||||
/* check for duplicate IP addresses and ignore them */
|
||||
duplicate_ip = 0;
|
||||
for (k = 0; k < i; k++) {
|
||||
duplicate_ip |= UTI_CompareIPs(&(sources[k].ip_addr),
|
||||
&ip_addrs[i],
|
||||
NULL) == 0;
|
||||
}
|
||||
if (!duplicate_ip) {
|
||||
sources[n_sources].ip_addr = ip_addrs[i];
|
||||
sources[n_sources].n_samples = 0;
|
||||
sources[n_sources].n_total_samples = 0;
|
||||
sources[n_sources].n_dead_probes = 0;
|
||||
if (ip_addrs[i].family == IPADDR_INET4)
|
||||
ip4++;
|
||||
else if (ip_addrs[i].family == IPADDR_INET6)
|
||||
ip6++;
|
||||
n_sources++;
|
||||
} else {
|
||||
LOG(LOGS_WARN, LOGF_Acquire, "Ignoring duplicate source: %s",
|
||||
UTI_IPToString(&ip_addrs[i]));
|
||||
}
|
||||
}
|
||||
|
||||
initialise_io();
|
||||
initialise_io((ip4 && ip6) ? IPADDR_UNSPEC : (ip4 ? IPADDR_INET4 : IPADDR_INET6));
|
||||
|
||||
/* Start sampling first source */
|
||||
start_next_source();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
10
acquire.h
10
acquire.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/acquire.h,v 1.9 2002/02/28 23:27:07 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -31,13 +27,15 @@
|
||||
#ifndef GOT_ACQUIRE_H
|
||||
#define GOT_ACQUIRE_H
|
||||
|
||||
#include "addressing.h"
|
||||
|
||||
typedef struct ACQ_SourceRecord *ACQ_Source;
|
||||
|
||||
extern void ACQ_Initialise(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, double init_slew_threshold,
|
||||
void (*after_hook)(void *), void *anything);
|
||||
|
||||
extern void ACQ_AccumulateSample(ACQ_Source acq_source, double offset, double root_distance);
|
||||
|
||||
32
addressing.h
32
addressing.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/addressing.h,v 1.7 2002/02/28 23:27:08 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -31,16 +27,28 @@
|
||||
#ifndef GOT_ADDRESSING_H
|
||||
#define GOT_ADDRESSING_H
|
||||
|
||||
/* This type is used to represent an IPv4 address and port
|
||||
number. Both parts are in HOST order, NOT network order. */
|
||||
#include "sysincl.h"
|
||||
|
||||
/* 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 {
|
||||
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;
|
||||
} NTP_Remote_Address;
|
||||
|
||||
#if 0
|
||||
unsigned long NTP_IP_Address;
|
||||
#endif
|
||||
|
||||
#endif /* GOT_ADDRESSING_H */
|
||||
|
||||
|
||||
223
addrfilt.c
223
addrfilt.c
@@ -1,12 +1,9 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/addrfilt.c,v 1.8 2002/02/28 23:27:08 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* 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
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@@ -19,7 +16,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -31,6 +28,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "addrfilt.h"
|
||||
@@ -51,23 +50,35 @@ typedef struct _TableNode {
|
||||
} TableNode;
|
||||
|
||||
struct ADF_AuthTableInst {
|
||||
TableNode base;
|
||||
TableNode base4; /* IPv4 node */
|
||||
TableNode base6; /* IPv6 node */
|
||||
};
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
inline static unsigned long
|
||||
get_subnet(unsigned long addr)
|
||||
static void
|
||||
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
|
||||
get_residual(unsigned long addr)
|
||||
inline static uint32_t
|
||||
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 +90,10 @@ ADF_CreateTable(void)
|
||||
result = MallocNew(struct ADF_AuthTableInst);
|
||||
|
||||
/* Default is that nothing is allowed */
|
||||
result->base.state = DENY;
|
||||
result->base.extended = NULL;
|
||||
result->base4.state = DENY;
|
||||
result->base4.extended = NULL;
|
||||
result->base6.state = DENY;
|
||||
result->base6.extended = NULL;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -103,8 +116,6 @@ close_node(TableNode *node)
|
||||
Free(node->extended);
|
||||
node->extended = NULL;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -128,29 +139,28 @@ open_node(TableNode *node)
|
||||
child_node->extended = NULL;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static ADF_Status
|
||||
set_subnet(TableNode *start_node,
|
||||
unsigned long ip,
|
||||
uint32_t *ip,
|
||||
int ip_len,
|
||||
int subnet_bits,
|
||||
State new_state,
|
||||
int delete_children)
|
||||
{
|
||||
int bits_to_go;
|
||||
unsigned long residual;
|
||||
unsigned long subnet;
|
||||
int bits_to_go, bits_consumed;
|
||||
uint32_t subnet;
|
||||
TableNode *node;
|
||||
|
||||
bits_consumed = 0;
|
||||
bits_to_go = subnet_bits;
|
||||
residual = ip;
|
||||
node = start_node;
|
||||
|
||||
if ((subnet_bits < 0) ||
|
||||
(subnet_bits > 32)) {
|
||||
(subnet_bits > 32 * ip_len)) {
|
||||
|
||||
return ADF_BADSUBNET;
|
||||
|
||||
@@ -159,13 +169,13 @@ set_subnet(TableNode *start_node,
|
||||
if ((bits_to_go & (NBITS-1)) == 0) {
|
||||
|
||||
while (bits_to_go > 0) {
|
||||
subnet = get_subnet(residual);
|
||||
residual = get_residual(residual);
|
||||
subnet = get_subnet(ip, bits_consumed);
|
||||
if (!(node->extended)) {
|
||||
open_node(node);
|
||||
}
|
||||
node = &(node->extended[subnet]);
|
||||
bits_to_go -= NBITS;
|
||||
bits_consumed += NBITS;
|
||||
}
|
||||
|
||||
if (delete_children) {
|
||||
@@ -178,18 +188,18 @@ set_subnet(TableNode *start_node,
|
||||
TableNode *this_node;
|
||||
|
||||
while (bits_to_go >= NBITS) {
|
||||
subnet = get_subnet(residual);
|
||||
residual = get_residual(residual);
|
||||
subnet = get_subnet(ip, bits_consumed);
|
||||
if (!(node->extended)) {
|
||||
open_node(node);
|
||||
}
|
||||
node = &(node->extended[subnet]);
|
||||
bits_to_go -= NBITS;
|
||||
bits_consumed += NBITS;
|
||||
}
|
||||
|
||||
/* How many subnet entries to set : 1->8, 2->4, 3->2 */
|
||||
N = 1 << (NBITS-bits_to_go);
|
||||
subnet = get_subnet(residual);
|
||||
subnet = get_subnet(ip, bits_consumed);
|
||||
if (!(node->extended)) {
|
||||
open_node(node);
|
||||
}
|
||||
@@ -210,12 +220,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_Allow(ADF_AuthTable table,
|
||||
unsigned long ip,
|
||||
IPAddr *ip,
|
||||
int subnet_bits)
|
||||
{
|
||||
return set_subnet(&(table->base), ip, subnet_bits, ALLOW, 0);
|
||||
return set_subnet_(table, ip, subnet_bits, ALLOW, 0);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -223,30 +262,30 @@ ADF_Allow(ADF_AuthTable table,
|
||||
|
||||
ADF_Status
|
||||
ADF_AllowAll(ADF_AuthTable table,
|
||||
unsigned long ip,
|
||||
IPAddr *ip,
|
||||
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_Deny(ADF_AuthTable table,
|
||||
unsigned long ip,
|
||||
IPAddr *ip,
|
||||
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_DenyAll(ADF_AuthTable table,
|
||||
unsigned long ip,
|
||||
IPAddr *ip,
|
||||
int subnet_bits)
|
||||
{
|
||||
return set_subnet(&(table->base), ip, subnet_bits, DENY, 1);
|
||||
return set_subnet_(table, ip, subnet_bits, DENY, 1);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -254,32 +293,33 @@ ADF_DenyAll(ADF_AuthTable table,
|
||||
void
|
||||
ADF_DestroyTable(ADF_AuthTable table)
|
||||
{
|
||||
close_node(&(table->base));
|
||||
close_node(&table->base4);
|
||||
close_node(&table->base6);
|
||||
Free(table);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
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 finished = 0;
|
||||
TableNode *node;
|
||||
State state=DENY;
|
||||
|
||||
node = start_node;
|
||||
residual = ip;
|
||||
|
||||
do {
|
||||
if (node->state != AS_PARENT) {
|
||||
state = node->state;
|
||||
}
|
||||
if (node->extended) {
|
||||
subnet = get_subnet(residual);
|
||||
residual = get_residual(residual);
|
||||
subnet = get_subnet(ip, bits_consumed);
|
||||
node = &(node->extended[subnet]);
|
||||
bits_consumed += NBITS;
|
||||
} else {
|
||||
/* Make decision on this node */
|
||||
finished = 1;
|
||||
@@ -306,65 +346,120 @@ check_ip_in_node(TableNode *start_node, unsigned long ip)
|
||||
|
||||
int
|
||||
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
|
||||
|
||||
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;
|
||||
TableNode *sub_node;
|
||||
|
||||
for (i=0; i<subnet_bits; i++) putchar(' ');
|
||||
|
||||
printf("%d.%d.%d.%d/%d : %s\n",
|
||||
((addr >> 24) & 255),
|
||||
((addr >> 16) & 255),
|
||||
((addr >> 8) & 255),
|
||||
((addr ) & 255),
|
||||
if (ip_len == 1)
|
||||
printf("%d.%d.%d.%d",
|
||||
((addr[0] >> 24) & 255),
|
||||
((addr[0] >> 16) & 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,
|
||||
(node->state == ALLOW) ? "allow" :
|
||||
(node->state == DENY) ? "deny" : "as parent");
|
||||
if (node->extended) {
|
||||
for (i=0; i<16; i++) {
|
||||
sub_node = &((*(node->extended))[i]);
|
||||
new_addr = addr | ((unsigned long) i << shift);
|
||||
print_node(sub_node, new_addr, shift - 4, subnet_bits + 4);
|
||||
sub_node = &(node->extended[i]);
|
||||
new_addr[0] = addr[0];
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
static void print_table(ADF_AuthTable table)
|
||||
{
|
||||
unsigned long addr = 0;
|
||||
int shift = 28;
|
||||
int subnet_bits = 0;
|
||||
uint32_t addr[4];
|
||||
|
||||
print_node(&table->base, addr, shift, subnet_bits);
|
||||
return;
|
||||
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);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
IPAddr ip;
|
||||
ADF_AuthTable table;
|
||||
table = ADF_CreateTable();
|
||||
|
||||
ADF_Allow(table, 0x7e800000, 9);
|
||||
ADF_Deny(table, 0x7ecc0000, 14);
|
||||
/* ADF_Deny(table, 0x7f000001, 32); */
|
||||
/* ADF_Allow(table, 0x7f000000, 8); */
|
||||
ip.family = IPADDR_INET4;
|
||||
|
||||
ip.addr.in4 = 0x7e800000;
|
||||
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);
|
||||
|
||||
|
||||
18
addrfilt.h
18
addrfilt.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/addrfilt.h,v 1.6 2002/02/28 23:27:08 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -31,6 +27,8 @@
|
||||
#ifndef GOT_ADDRFILT_H
|
||||
#define GOT_ADDRFILT_H
|
||||
|
||||
#include "addressing.h"
|
||||
|
||||
typedef struct ADF_AuthTableInst *ADF_AuthTable;
|
||||
|
||||
typedef enum {
|
||||
@@ -45,25 +43,25 @@ extern ADF_AuthTable ADF_CreateTable(void);
|
||||
/* Allow anything in the supplied subnet, EXCEPT for any more specific
|
||||
subnets that are already defined */
|
||||
extern ADF_Status ADF_Allow(ADF_AuthTable table,
|
||||
unsigned long ip,
|
||||
IPAddr *ip,
|
||||
int subnet_bits);
|
||||
|
||||
/* Allow anything in the supplied subnet, overwriting existing
|
||||
definitions for any more specific subnets */
|
||||
extern ADF_Status ADF_AllowAll(ADF_AuthTable table,
|
||||
unsigned long ip,
|
||||
IPAddr *ip,
|
||||
int subnet_bits);
|
||||
|
||||
/* Deny anything in the supplied subnet, EXCEPT for any more specific
|
||||
subnets that are already defined */
|
||||
extern ADF_Status ADF_Deny(ADF_AuthTable table,
|
||||
unsigned long ip,
|
||||
IPAddr *ip,
|
||||
int subnet_bits);
|
||||
|
||||
/* Deny anything in the supplied subnet, overwriting existing
|
||||
definitions for any more specific subnets */
|
||||
extern ADF_Status ADF_DenyAll(ADF_AuthTable table,
|
||||
unsigned long ip,
|
||||
IPAddr *ip,
|
||||
int subnet_bits);
|
||||
|
||||
/* Clear up the table */
|
||||
@@ -72,6 +70,6 @@ extern void ADF_DestroyTable(ADF_AuthTable table);
|
||||
/* Check whether a given IP address is allowed by the rules in
|
||||
the table */
|
||||
extern int ADF_IsAllowed(ADF_AuthTable table,
|
||||
unsigned long ip);
|
||||
IPAddr *ip);
|
||||
|
||||
#endif /* GOT_ADDRFILT_H */
|
||||
|
||||
37
broadcast.c
37
broadcast.c
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/broadcast.c,v 1.3 2002/02/28 23:27:08 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -28,6 +24,8 @@
|
||||
Deal with broadcast server functions.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
#include "memory.h"
|
||||
|
||||
@@ -51,7 +49,6 @@ static int max_destinations = 0;
|
||||
void
|
||||
BRD_Initialise(void)
|
||||
{
|
||||
return; /* Nothing to do */
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -59,7 +56,6 @@ BRD_Initialise(void)
|
||||
void
|
||||
BRD_Finalise(void)
|
||||
{
|
||||
return; /* Nothing to do */
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -75,15 +71,14 @@ timeout_handler(void *arbitrary)
|
||||
int leap;
|
||||
int are_we_synchronised, our_stratum;
|
||||
NTP_Leap leap_status;
|
||||
unsigned long our_ref_id;
|
||||
uint32_t our_ref_id, ts_fuzz;
|
||||
struct timeval our_ref_time;
|
||||
double our_root_delay, our_root_dispersion;
|
||||
double local_time_err;
|
||||
struct timeval local_transmit;
|
||||
|
||||
version = 3;
|
||||
|
||||
LCL_ReadCookedTime(&local_transmit, &local_time_err);
|
||||
LCL_ReadCookedTime(&local_transmit, NULL);
|
||||
REF_GetReferenceParams(&local_transmit,
|
||||
&are_we_synchronised, &leap_status,
|
||||
&our_stratum,
|
||||
@@ -94,7 +89,7 @@ timeout_handler(void *arbitrary)
|
||||
if (are_we_synchronised) {
|
||||
leap = (int) leap_status;
|
||||
} else {
|
||||
leap = 3;
|
||||
leap = LEAP_Unsynchronised;
|
||||
}
|
||||
|
||||
message.lvm = ((leap << 6) &0xc0) | ((version << 3) & 0x38) | (MODE_BROADCAST & 0x07);
|
||||
@@ -104,25 +99,26 @@ timeout_handler(void *arbitrary)
|
||||
|
||||
/* If we're sending a client mode packet and we aren't synchronized yet,
|
||||
we might have to set up artificial values for some of these parameters */
|
||||
message.root_delay = double_to_int32(our_root_delay);
|
||||
message.root_dispersion = double_to_int32(our_root_dispersion);
|
||||
message.root_delay = UTI_DoubleToInt32(our_root_delay);
|
||||
message.root_dispersion = UTI_DoubleToInt32(our_root_dispersion);
|
||||
|
||||
message.reference_id = htonl((NTP_int32) our_ref_id);
|
||||
|
||||
/* Now fill in timestamps */
|
||||
UTI_TimevalToInt64(&our_ref_time, &message.reference_ts);
|
||||
UTI_TimevalToInt64(&our_ref_time, &message.reference_ts, 0);
|
||||
message.originate_ts.hi = 0UL;
|
||||
message.originate_ts.lo = 0UL;
|
||||
message.receive_ts.hi = 0UL;
|
||||
message.receive_ts.lo = 0UL;
|
||||
|
||||
LCL_ReadCookedTime(&local_transmit, &local_time_err);
|
||||
UTI_TimevalToInt64(&local_transmit, &message.transmit_ts);
|
||||
ts_fuzz = UTI_GetNTPTsFuzz(message.precision);
|
||||
LCL_ReadCookedTime(&local_transmit, NULL);
|
||||
UTI_TimevalToInt64(&local_transmit, &message.transmit_ts, ts_fuzz);
|
||||
NIO_SendNormalPacket(&message, &d->addr);
|
||||
|
||||
/* Requeue timeout. Don't care if interval drifts gradually, so just do it
|
||||
* at the end. */
|
||||
SCH_AddTimeoutInClass((double) d->interval, 1.0,
|
||||
SCH_AddTimeoutInClass((double) d->interval, 1.0, 0.02,
|
||||
SCH_NtpBroadcastClass,
|
||||
timeout_handler, (void *) d);
|
||||
|
||||
@@ -132,7 +128,7 @@ timeout_handler(void *arbitrary)
|
||||
/* ================================================== */
|
||||
|
||||
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) {
|
||||
/* Expand array */
|
||||
@@ -144,11 +140,12 @@ 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].interval = interval;
|
||||
|
||||
SCH_AddTimeoutInClass((double) interval, 1.0,
|
||||
SCH_AddTimeoutInClass((double) interval, 1.0, 0.0,
|
||||
SCH_NtpBroadcastClass,
|
||||
timeout_handler, (void *)(destinations + n_destinations));
|
||||
|
||||
|
||||
10
broadcast.h
10
broadcast.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/broadcast.h,v 1.2 2002/02/28 23:27:08 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -31,9 +27,11 @@
|
||||
#ifndef GOT_BROADCAST_H
|
||||
#define GOT_BROADCAST_H
|
||||
|
||||
#include "addressing.h"
|
||||
|
||||
extern void BRD_Initialise(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 */
|
||||
|
||||
|
||||
261
candm.h
261
candm.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/candm.h,v 1.40 2003/09/22 21:22:30 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -34,6 +30,8 @@
|
||||
#define GOT_CANDM_H
|
||||
|
||||
#include "sysincl.h"
|
||||
#include "addressing.h"
|
||||
#include "hash.h"
|
||||
|
||||
/* This is the default port to use for CANDM, if no alternative is
|
||||
defined */
|
||||
@@ -85,44 +83,66 @@
|
||||
#define REQ_MANUAL_DELETE 42
|
||||
#define REQ_MAKESTEP 43
|
||||
#define REQ_ACTIVITY 44
|
||||
#define N_REQUEST_TYPES 45
|
||||
#define REQ_MODIFY_MINSTRATUM 45
|
||||
#define REQ_MODIFY_POLLTARGET 46
|
||||
#define REQ_MODIFY_MAXDELAYDEVRATIO 47
|
||||
#define REQ_RESELECT 48
|
||||
#define REQ_RESELECTDISTANCE 49
|
||||
#define N_REQUEST_TYPES 50
|
||||
|
||||
/* Special utoken value used to log on with first exchange being the
|
||||
password. (This time value has long since gone by) */
|
||||
#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
|
||||
pktlength.c, to get the number of bytes that ought to be
|
||||
transmitted for each packet type. */
|
||||
|
||||
typedef struct {
|
||||
uint32_t mask;
|
||||
uint32_t address;
|
||||
IPAddr mask;
|
||||
IPAddr address;
|
||||
int32_t EOR;
|
||||
} REQ_Online;
|
||||
|
||||
typedef struct {
|
||||
uint32_t mask;
|
||||
uint32_t address;
|
||||
IPAddr mask;
|
||||
IPAddr address;
|
||||
int32_t EOR;
|
||||
} REQ_Offline;
|
||||
|
||||
typedef struct {
|
||||
uint32_t mask;
|
||||
uint32_t address;
|
||||
IPAddr mask;
|
||||
IPAddr address;
|
||||
int32_t n_good_samples;
|
||||
int32_t n_total_samples;
|
||||
int32_t EOR;
|
||||
} REQ_Burst;
|
||||
|
||||
typedef struct {
|
||||
uint32_t address;
|
||||
IPAddr address;
|
||||
int32_t new_minpoll;
|
||||
int32_t EOR;
|
||||
} REQ_Modify_Minpoll;
|
||||
|
||||
typedef struct {
|
||||
uint32_t address;
|
||||
IPAddr address;
|
||||
int32_t new_maxpoll;
|
||||
int32_t EOR;
|
||||
} REQ_Modify_Maxpoll;
|
||||
@@ -133,29 +153,47 @@ typedef struct {
|
||||
} REQ_Dump;
|
||||
|
||||
typedef struct {
|
||||
uint32_t address;
|
||||
int32_t new_max_delay;
|
||||
IPAddr address;
|
||||
Float new_max_delay;
|
||||
int32_t EOR;
|
||||
} REQ_Modify_Maxdelay;
|
||||
|
||||
typedef struct {
|
||||
uint32_t address;
|
||||
int32_t new_max_delay_ratio;
|
||||
IPAddr address;
|
||||
Float new_max_delay_ratio;
|
||||
int32_t EOR;
|
||||
} REQ_Modify_Maxdelayratio;
|
||||
|
||||
typedef struct {
|
||||
int32_t new_max_update_skew;
|
||||
IPAddr address;
|
||||
Float new_max_delay_dev_ratio;
|
||||
int32_t EOR;
|
||||
} REQ_Modify_Maxdelaydevratio;
|
||||
|
||||
typedef struct {
|
||||
IPAddr address;
|
||||
int32_t new_min_stratum;
|
||||
int32_t EOR;
|
||||
} REQ_Modify_Minstratum;
|
||||
|
||||
typedef struct {
|
||||
IPAddr address;
|
||||
int32_t new_poll_target;
|
||||
int32_t EOR;
|
||||
} REQ_Modify_Polltarget;
|
||||
|
||||
typedef struct {
|
||||
Float new_max_update_skew;
|
||||
int32_t EOR;
|
||||
} REQ_Modify_Maxupdateskew;
|
||||
|
||||
typedef struct {
|
||||
struct timeval ts;
|
||||
Timeval ts;
|
||||
int32_t EOR;
|
||||
} REQ_Logon;
|
||||
|
||||
typedef struct {
|
||||
struct timeval ts;
|
||||
Timeval ts;
|
||||
int32_t EOR;
|
||||
} REQ_Settime;
|
||||
|
||||
@@ -184,32 +222,38 @@ typedef struct {
|
||||
} REQ_Rekey;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ip;
|
||||
IPAddr ip;
|
||||
int32_t subnet_bits;
|
||||
int32_t EOR;
|
||||
} REQ_Allow_Deny;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ip;
|
||||
IPAddr ip;
|
||||
int32_t EOR;
|
||||
} REQ_Ac_Check;
|
||||
|
||||
/* Flags used in NTP source requests */
|
||||
#define REQ_ADDSRC_ONLINE 0x1
|
||||
#define REQ_ADDSRC_AUTOOFFLINE 0x2
|
||||
#define REQ_ADDSRC_IBURST 0x4
|
||||
#define REQ_ADDSRC_PREFER 0x8
|
||||
#define REQ_ADDSRC_NOSELECT 0x10
|
||||
|
||||
typedef struct {
|
||||
uint32_t ip_addr;
|
||||
IPAddr ip_addr;
|
||||
uint32_t port;
|
||||
int32_t minpoll;
|
||||
int32_t maxpoll;
|
||||
int32_t presend_minpoll;
|
||||
int32_t online;
|
||||
int32_t auto_offline;
|
||||
uint32_t authkey;
|
||||
int32_t max_delay;
|
||||
int32_t max_delay_ratio;
|
||||
Float max_delay;
|
||||
Float max_delay_ratio;
|
||||
uint32_t flags;
|
||||
int32_t EOR;
|
||||
} REQ_NTP_Source;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ip_addr;
|
||||
IPAddr ip_addr;
|
||||
int32_t EOR;
|
||||
} REQ_Del_Source;
|
||||
|
||||
@@ -218,7 +262,7 @@ typedef struct {
|
||||
} REQ_WriteRtc;
|
||||
|
||||
typedef struct {
|
||||
int32_t dfreq;
|
||||
Float dfreq;
|
||||
int32_t EOR;
|
||||
} REQ_Dfreq;
|
||||
|
||||
@@ -250,25 +294,13 @@ typedef struct {
|
||||
} REQ_CycleLogs;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ip;
|
||||
IPAddr ip;
|
||||
uint32_t bits_specd;
|
||||
} REQ_SubnetsAccessed_Subnet;
|
||||
|
||||
#define MAX_SUBNETS_ACCESSED 8
|
||||
|
||||
typedef struct {
|
||||
uint32_t n_subnets;
|
||||
REQ_SubnetsAccessed_Subnet subnets[MAX_SUBNETS_ACCESSED];
|
||||
} REQ_SubnetsAccessed;
|
||||
|
||||
/* This is based on the response size rather than the
|
||||
request size */
|
||||
#define MAX_CLIENT_ACCESSES 16
|
||||
|
||||
typedef struct {
|
||||
uint32_t n_clients;
|
||||
uint32_t client_ips[MAX_CLIENT_ACCESSES];
|
||||
} REQ_ClientAccesses;
|
||||
#define MAX_CLIENT_ACCESSES 8
|
||||
|
||||
typedef struct {
|
||||
uint32_t first_index;
|
||||
@@ -293,6 +325,15 @@ typedef struct {
|
||||
int32_t EOR;
|
||||
} REQ_Activity;
|
||||
|
||||
typedef struct {
|
||||
int32_t EOR;
|
||||
} REQ_Reselect;
|
||||
|
||||
typedef struct {
|
||||
Float distance;
|
||||
int32_t EOR;
|
||||
} REQ_ReselectDistance;
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
#define PKT_TYPE_CMD_REQUEST 1
|
||||
@@ -310,9 +351,22 @@ typedef struct {
|
||||
|
||||
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, new commands: modify stratum,
|
||||
modify polltarget, modify maxdelaydevratio, reselect, reselectdistance
|
||||
|
||||
Version 5 : auth data moved to the end of the packet to allow hashes with
|
||||
different sizes, extended sources, tracking and activity reports, dropped
|
||||
subnets accessed and client accesses
|
||||
*/
|
||||
|
||||
#define PROTO_VERSION_NUMBER 3
|
||||
#define PROTO_VERSION_NUMBER 5
|
||||
|
||||
/* The oldest protocol version that is compatible enough with
|
||||
the current version to report a version mismatch */
|
||||
#define PROTO_VERSION_MISMATCH_COMPAT 4
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
@@ -328,7 +382,6 @@ typedef struct {
|
||||
uint32_t sequence; /* Client's sequence number */
|
||||
uint32_t utoken; /* Unique token per incarnation of daemon */
|
||||
uint32_t token; /* Command token (to prevent replay attack) */
|
||||
uint32_t auth[4]; /* MD5 authentication of the packet */
|
||||
|
||||
union {
|
||||
REQ_Online online;
|
||||
@@ -339,6 +392,9 @@ typedef struct {
|
||||
REQ_Dump dump;
|
||||
REQ_Modify_Maxdelay modify_maxdelay;
|
||||
REQ_Modify_Maxdelayratio modify_maxdelayratio;
|
||||
REQ_Modify_Maxdelaydevratio modify_maxdelaydevratio;
|
||||
REQ_Modify_Minstratum modify_minstratum;
|
||||
REQ_Modify_Polltarget modify_polltarget;
|
||||
REQ_Modify_Maxupdateskew modify_maxupdateskew;
|
||||
REQ_Logon logon;
|
||||
REQ_Settime settime;
|
||||
@@ -359,15 +415,19 @@ typedef struct {
|
||||
REQ_RTCReport rtcreport;
|
||||
REQ_TrimRTC trimrtc;
|
||||
REQ_CycleLogs cyclelogs;
|
||||
REQ_SubnetsAccessed subnets_accessed;
|
||||
REQ_ClientAccesses client_accesses;
|
||||
REQ_ClientAccessesByIndex client_accesses_by_index;
|
||||
REQ_ManualList manual_list;
|
||||
REQ_ManualDelete manual_delete;
|
||||
REQ_MakeStep make_step;
|
||||
REQ_Activity activity;
|
||||
REQ_Reselect reselect;
|
||||
REQ_ReselectDistance reselect_distance;
|
||||
} data; /* Command specific parameters */
|
||||
|
||||
/* authentication of the packet, there is no hole after the actual data
|
||||
from the data union, this field only sets the maximum auth size */
|
||||
uint8_t auth[MAX_HASH_LENGTH];
|
||||
|
||||
} CMD_Request;
|
||||
|
||||
/* ================================================== */
|
||||
@@ -377,13 +437,6 @@ typedef struct {
|
||||
#define PERMIT_LOCAL 1
|
||||
#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 */
|
||||
@@ -419,6 +472,9 @@ typedef struct {
|
||||
#define STT_BADRTCFILE 14
|
||||
#define STT_INACTIVE 15
|
||||
#define STT_BADSAMPLE 16
|
||||
#define STT_INVALIDAF 17
|
||||
#define STT_BADPKTVERSION 18
|
||||
#define STT_BADPKTLENGTH 19
|
||||
|
||||
typedef struct {
|
||||
int32_t EOR;
|
||||
@@ -437,81 +493,84 @@ typedef struct {
|
||||
#define RPY_SD_ST_UNREACH 1
|
||||
#define RPY_SD_ST_FALSETICKER 2
|
||||
#define RPY_SD_ST_JITTERY 3
|
||||
#define RPY_SD_ST_OTHER 4
|
||||
#define RPY_SD_ST_CANDIDATE 4
|
||||
#define RPY_SD_ST_OUTLIER 5
|
||||
|
||||
#define RPY_SD_FLAG_NOSELECT 0x1
|
||||
#define RPY_SD_FLAG_PREFER 0x2
|
||||
|
||||
typedef struct {
|
||||
uint32_t ip_addr;
|
||||
IPAddr ip_addr;
|
||||
uint16_t poll;
|
||||
uint16_t stratum;
|
||||
uint16_t state;
|
||||
uint16_t mode;
|
||||
uint16_t flags;
|
||||
uint16_t reachability;
|
||||
uint32_t since_sample;
|
||||
int32_t orig_latest_meas;
|
||||
int32_t latest_meas;
|
||||
uint32_t latest_meas_err;
|
||||
int32_t est_offset;
|
||||
uint32_t est_offset_err;
|
||||
int32_t resid_freq;
|
||||
uint32_t resid_skew;
|
||||
Float orig_latest_meas;
|
||||
Float latest_meas;
|
||||
Float latest_meas_err;
|
||||
int32_t EOR;
|
||||
} RPY_Source_Data;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ref_id;
|
||||
uint32_t stratum;
|
||||
uint32_t ref_time_s;
|
||||
uint32_t ref_time_us;
|
||||
uint32_t current_correction_s;
|
||||
uint32_t current_correction_us;
|
||||
int32_t freq_ppm;
|
||||
int32_t resid_freq_ppm;
|
||||
int32_t skew_ppm;
|
||||
int32_t root_delay;
|
||||
int32_t root_dispersion;
|
||||
IPAddr ip_addr;
|
||||
uint16_t stratum;
|
||||
uint16_t leap_status;
|
||||
Timeval ref_time;
|
||||
Float current_correction;
|
||||
Float last_offset;
|
||||
Float rms_offset;
|
||||
Float freq_ppm;
|
||||
Float resid_freq_ppm;
|
||||
Float skew_ppm;
|
||||
Float root_delay;
|
||||
Float root_dispersion;
|
||||
Float last_update_interval;
|
||||
int32_t EOR;
|
||||
} RPY_Tracking;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ip_addr;
|
||||
uint32_t ref_id;
|
||||
IPAddr ip_addr;
|
||||
uint32_t n_samples;
|
||||
uint32_t n_runs;
|
||||
uint32_t span_seconds;
|
||||
uint32_t sd_us;
|
||||
int32_t resid_freq_ppm;
|
||||
int32_t skew_ppm;
|
||||
Float sd;
|
||||
Float resid_freq_ppm;
|
||||
Float skew_ppm;
|
||||
Float est_offset;
|
||||
Float est_offset_err;
|
||||
int32_t EOR;
|
||||
} RPY_Sourcestats;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ref_time;
|
||||
Timeval ref_time;
|
||||
uint16_t n_samples;
|
||||
uint16_t n_runs;
|
||||
uint32_t span_seconds;
|
||||
int32_t rtc_seconds_fast;
|
||||
int32_t rtc_gain_rate_ppm;
|
||||
Float rtc_seconds_fast;
|
||||
Float rtc_gain_rate_ppm;
|
||||
int32_t EOR;
|
||||
} RPY_Rtc;
|
||||
|
||||
typedef struct {
|
||||
uint32_t centiseconds;
|
||||
int32_t dfreq_ppm;
|
||||
int32_t new_afreq_ppm;
|
||||
Float dfreq_ppm;
|
||||
Float new_afreq_ppm;
|
||||
int32_t EOR;
|
||||
} RPY_ManualTimestamp;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ip;
|
||||
IPAddr ip;
|
||||
uint32_t bits_specd;
|
||||
uint32_t bitmap[8];
|
||||
} RPY_SubnetsAccessed_Subnet;
|
||||
|
||||
typedef struct {
|
||||
uint32_t n_subnets;
|
||||
RPY_SubnetsAccessed_Subnet subnets[MAX_SUBNETS_ACCESSED];
|
||||
} RPY_SubnetsAccessed;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ip;
|
||||
IPAddr ip;
|
||||
uint32_t client_hits;
|
||||
uint32_t peer_hits;
|
||||
uint32_t cmd_hits_auth;
|
||||
@@ -521,11 +580,6 @@ typedef struct {
|
||||
uint32_t last_cmd_hit_ago;
|
||||
} RPY_ClientAccesses_Client;
|
||||
|
||||
typedef struct {
|
||||
uint32_t n_clients;
|
||||
RPY_ClientAccesses_Client clients[MAX_CLIENT_ACCESSES];
|
||||
} RPY_ClientAccesses;
|
||||
|
||||
typedef struct {
|
||||
uint32_t n_indices; /* how many indices there are in the server's table */
|
||||
uint32_t next_index; /* the index 1 beyond those processed on this call */
|
||||
@@ -536,10 +590,10 @@ typedef struct {
|
||||
#define MAX_MANUAL_LIST_SAMPLES 32
|
||||
|
||||
typedef struct {
|
||||
uint32_t when;
|
||||
int32_t slewed_offset;
|
||||
int32_t orig_offset;
|
||||
int32_t residual;
|
||||
Timeval when;
|
||||
Float slewed_offset;
|
||||
Float orig_offset;
|
||||
Float residual;
|
||||
} RPY_ManualListSample;
|
||||
|
||||
typedef struct {
|
||||
@@ -552,6 +606,7 @@ typedef struct {
|
||||
int32_t offline;
|
||||
int32_t burst_online;
|
||||
int32_t burst_offline;
|
||||
int32_t unresolved;
|
||||
int32_t EOR;
|
||||
} RPY_Activity;
|
||||
|
||||
@@ -570,8 +625,6 @@ typedef struct {
|
||||
uint32_t utoken; /* Unique token per incarnation of daemon */
|
||||
uint32_t token; /* New command token (only if command was successfully
|
||||
authenticated) */
|
||||
uint32_t auth[4]; /* MD5 authentication of the packet */
|
||||
|
||||
union {
|
||||
RPY_Null null;
|
||||
RPY_N_Sources n_sources;
|
||||
@@ -580,13 +633,15 @@ typedef struct {
|
||||
RPY_Tracking tracking;
|
||||
RPY_Sourcestats sourcestats;
|
||||
RPY_Rtc rtc;
|
||||
RPY_SubnetsAccessed subnets_accessed;
|
||||
RPY_ClientAccesses client_accesses;
|
||||
RPY_ClientAccessesByIndex client_accesses_by_index;
|
||||
RPY_ManualList manual_list;
|
||||
RPY_Activity activity;
|
||||
} data; /* Reply specific parameters */
|
||||
|
||||
/* authentication of the packet, there is no hole after the actual data
|
||||
from the data union, this field only sets the maximum auth size */
|
||||
uint8_t auth[MAX_HASH_LENGTH];
|
||||
|
||||
} CMD_Reply;
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
22
chrony.1
22
chrony.1
@@ -1,4 +1,4 @@
|
||||
.TH CHRONY 1 "August 10, 2001" chrony "User's Manual"
|
||||
.TH CHRONY 1 "@MAN_DATE@" "chrony @VERSION@" "User's Manual"
|
||||
.SH NAME
|
||||
chrony \- programs for keeping computer clocks accurate
|
||||
|
||||
@@ -21,7 +21,7 @@ to the Internet, and it can also act as an RFC1305-compatible NTP server.
|
||||
.SH USAGE
|
||||
\fIchronyc\fR is a command-line interface program which can be used to
|
||||
monitor \fIchronyd\fR's performance and to change various operating
|
||||
parateters whilst it is running.
|
||||
parameters whilst it is running.
|
||||
|
||||
\fIchronyd\fR's main function is to obtain measurements of the true (UTC)
|
||||
time from one of several sources, and correct the system clock
|
||||
@@ -30,18 +30,18 @@ gains or loses time and uses this information to keep it accurate
|
||||
between measurements from the reference.
|
||||
|
||||
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
|
||||
\fIhttp://www.eecis.udel.edu/~ntp\fR.
|
||||
\fIhttp://www.ntp.org\fR.
|
||||
|
||||
It is designed so that it can work on computers which only have
|
||||
intermittent access to reference sources, for example computers which
|
||||
use a dial-up account to access the Internet. Of course, it will work
|
||||
on computers with permanent connections too.
|
||||
use a dial-up account to access the Internet or laptops. Of course, it
|
||||
will work well on computers with permanent connections too.
|
||||
|
||||
In addition, for Linux 2.0.x (for x >= 32) or 2.2 onwards, chronyd can monitor
|
||||
the system's real time clock performance, so the system can maintain accurate
|
||||
time even across reboots.
|
||||
In addition, on Linux it can monitor the system's real time clock
|
||||
performance, so the system can maintain accurate time even across
|
||||
reboots.
|
||||
|
||||
Typical accuracies available between 2 machines are
|
||||
|
||||
@@ -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
|
||||
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.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR chronyc(1),
|
||||
.BR chrony(1)
|
||||
|
||||
.I http://chrony.sunsite.dk/
|
||||
.I http://chrony.tuxfamily.org/
|
||||
|
||||
.SH AUTHOR
|
||||
Richard Curnow <rc@rc0.org.uk>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
.TH chrony.conf 5 "August 10, 2001" chrony "Configuration Files"
|
||||
.TH chrony.conf 5 "@MAN_DATE@" "chrony @VERSION@" "Configuration Files"
|
||||
.SH NAME
|
||||
chrony.conf \- chronyd configuration file
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B /etc/chrony.conf
|
||||
.B @SYSCONFDIR@/chrony.conf
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fIchrony\fR is a pair of programs for maintaining the accuracy of computer
|
||||
@@ -12,7 +12,7 @@ boot time.
|
||||
|
||||
Assuming that you have found some servers, you need to set up a
|
||||
configuration file to run \fIchrony\fR. The (compiled-in) default location
|
||||
for this file is \fB/etc/chrony.conf\fR. Assuming that your ntp servers
|
||||
for this file is \fB@SYSCONFDIR@/chrony.conf\fR. Assuming that your ntp servers
|
||||
are called `a.b.c' and `d.e.f', your \fBchrony.conf\fR file could contain
|
||||
as a minimum
|
||||
|
||||
@@ -29,17 +29,17 @@ useful configuration file would look something like
|
||||
server a.b.c
|
||||
server d.e.f
|
||||
server g.h.i
|
||||
keyfile /etc/chrony.keys
|
||||
keyfile @SYSCONFDIR@/chrony.keys
|
||||
commandkey 1
|
||||
driftfile /etc/chrony.drift
|
||||
driftfile @CHRONYVARDIR@/drift
|
||||
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR chrony(1),
|
||||
.BR chronyc(1),
|
||||
.BR chronyd(1)
|
||||
.BR chronyd(8)
|
||||
|
||||
.I http://chrony.sunsite.dk/
|
||||
.I http://chrony.tuxfamily.org/
|
||||
|
||||
.SH AUTHOR
|
||||
Richard Curnow <rc@rc0.org.uk>
|
||||
29
chrony.lsm
29
chrony.lsm
@@ -1,29 +0,0 @@
|
||||
Begin3
|
||||
Title: chrony
|
||||
Version: 1.18
|
||||
Entered-date: 01APR02
|
||||
Description: A pair of programs for keeping computer clocks accurate.
|
||||
chronyd is a background (daemon) program and chronyc is a
|
||||
command-line interface to it. Time reference sources for
|
||||
chronyd can be RFC1305 NTP servers, human (via keyboard and
|
||||
chronyc), and the computer's real-time clock at boot time
|
||||
(Linux only). chronyd can determine the rate at which the
|
||||
computer gains or loses time and compensate for it whilst no
|
||||
external reference is present. chronyd's use of NTP servers
|
||||
can be switched on and off (through chronyc) to support
|
||||
computers with dial-up/intermittent access to the
|
||||
Internet. chronyd can also act as an RFC1305-compatible NTP
|
||||
server.
|
||||
Keywords: time NTP RFC1305 RTC adjtime
|
||||
Author: rc@rc0.org.uk (Richard Curnow)
|
||||
Maintained-by: rc@rc0.org.uk (Richard Curnow)
|
||||
Primary-site: sunsite.unc.edu /pub/Linux/system/admin/time
|
||||
295k chrony-1.18.tar.gz
|
||||
2k chrony.lsm
|
||||
Platforms: Linux 2.0/2.1/2.2/2.3/2.4 (x86, powerpc)
|
||||
Solaris 2.5/6/7/8, SunOS 4.1.4. (Sparc)
|
||||
BSDI/386.
|
||||
NetBSD
|
||||
Solaris 2.8 (x86)
|
||||
Copying-policy: GPL
|
||||
End
|
||||
@@ -1,38 +1,43 @@
|
||||
%global chrony_version @@VERSION@@
|
||||
%if 0%(echo %{chrony_version} | grep -q pre && echo 1)
|
||||
%global prerelease %(echo %{chrony_version} | sed 's/.*-//')
|
||||
%endif
|
||||
Summary: An NTP client/server
|
||||
Name: chrony
|
||||
Version: @@VERSION@@
|
||||
Release: 1
|
||||
Source: chrony-%{version}.tar.gz
|
||||
Copyright: GPL
|
||||
Version: %(echo %{chrony_version} | sed 's/-.*//')
|
||||
Release: %{!?prerelease:1}%{?prerelease:0.1.%{prerelease}}
|
||||
Source: chrony-%{version}%{?prerelease:-%{prerelease}}.tar.gz
|
||||
License: GPLv2
|
||||
Group: Applications/Utilities
|
||||
Packager: Richard P. Curnow <rc@rc0.org.uk>
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-root-%(id -u -n)
|
||||
Requires: info
|
||||
|
||||
%description
|
||||
A pair of programs for keeping computer clocks accurate. chronyd is a
|
||||
background (daemon) program and chronyc is a command-line interface to it.
|
||||
Time reference sources for chronyd can be RFC1305 NTP servers, human (via
|
||||
keyboard and chronyc), and the computer's real-time clock at boot time (Linux
|
||||
only). chronyd can determine the rate at which the computer gains or loses
|
||||
time and compensate for it whilst no external reference is present. chronyd's
|
||||
use of NTP servers can be switched on and off (through chronyc) to support
|
||||
computers with dial-up/intermittent access to the Internet. chronyd can also
|
||||
act as an RFC1305-compatible NTP server.
|
||||
chrony is a client and server for the Network Time Protocol (NTP).
|
||||
This program keeps your computer's clock accurate. It was specially
|
||||
designed to support systems with intermittent Internet connections,
|
||||
but it also works well in permanently connected environments. It can
|
||||
also use hardware reference clocks, the system real-time clock, or
|
||||
manual input as time references.
|
||||
|
||||
%prep
|
||||
%setup
|
||||
%setup -q -n %{name}-%{version}%{?prerelease:-%{prerelease}}
|
||||
|
||||
%build
|
||||
./configure --prefix=%{_prefix} --mandir=%{_mandir}
|
||||
make CC=gcc CFLAGS=-O2 prefix=%{_prefix}
|
||||
make chrony.txt prefix=%{_prefix}
|
||||
make chrony.info prefix=%{_prefix}
|
||||
./configure \
|
||||
--prefix=%{_prefix} \
|
||||
--bindir=%{_bindir} \
|
||||
--sbindir=%{_sbindir} \
|
||||
--infodir=%{_infodir} \
|
||||
--mandir=%{_mandir}
|
||||
make
|
||||
make chrony.txt
|
||||
make chrony.info
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
cd $RPM_BUILD_DIR/chrony-%{version}
|
||||
make install DESTDIR=$RPM_BUILD_ROOT prefix=%{_prefix}
|
||||
make install DESTDIR=$RPM_BUILD_ROOT
|
||||
rm -rf $RPM_BUILD_ROOT%{_docdir}
|
||||
mkdir -p $RPM_BUILD_ROOT%{_infodir}
|
||||
cp chrony.info* $RPM_BUILD_ROOT%{_infodir}
|
||||
|
||||
@@ -47,6 +52,6 @@ cp chrony.info* $RPM_BUILD_ROOT%{_infodir}
|
||||
%doc README
|
||||
%doc chrony.txt
|
||||
%doc COPYING
|
||||
%doc examples/chrony.conf.example
|
||||
%doc examples/chrony.conf.example*
|
||||
%doc examples/chrony.keys.example
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -35,10 +35,16 @@ struct timex {
|
||||
int :32; int :32; int :32; int :32;
|
||||
};
|
||||
|
||||
#define ADJ_OFFSET 0x0001 /* time offset */
|
||||
#define ADJ_FREQUENCY 0x0002 /* frequency offset */
|
||||
#define ADJ_MAXERROR 0x0004 /* maximum time error */
|
||||
#define ADJ_STATUS 0x0010 /* clock status */
|
||||
#define ADJ_TIMECONST 0x0020 /* pll time constant */
|
||||
#define ADJ_SETOFFSET 0x0100 /* add 'time' to current time */
|
||||
#define ADJ_NANO 0x2000 /* select nanosecond resolution */
|
||||
#define ADJ_TICK 0x4000 /* tick value */
|
||||
#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) */
|
||||
|
||||
@@ -58,6 +64,7 @@ struct timex {
|
||||
#define STA_PPSERROR 0x0800 /* PPS signal calibration error (ro) */
|
||||
|
||||
#define STA_CLOCKERR 0x1000 /* clock hardware fault (ro) */
|
||||
#define STA_NANO 0x2000 /* resolution (0 = us, 1 = ns) (ro) */
|
||||
|
||||
/* This doesn't seem to be in any include files !! */
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH CHRONYC 1 "August 10, 2001" chrony "User's Manual"
|
||||
.TH CHRONYC 1 "@MAN_DATE@" "chrony @VERSION@" "User's Manual"
|
||||
.SH NAME
|
||||
chronyc \- command-line interface for chronyd
|
||||
|
||||
@@ -12,7 +12,7 @@ clocks.
|
||||
|
||||
\fBchronyc\fR is a command-line interface program which can be used to
|
||||
monitor \fIchronyd\fR's performance and to change various operating
|
||||
parateters whilst it is running.
|
||||
parameters whilst it is running.
|
||||
|
||||
.SH USAGE
|
||||
A detailed description of all commands supported by \fBchronyc\fR is available
|
||||
@@ -31,22 +31,39 @@ specify port-number
|
||||
.TP
|
||||
\fB\-n\fR
|
||||
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
|
||||
\fB\-m\fR
|
||||
allow multiple commands to be specified on the command line. Each argument
|
||||
will be interpreted as a whole command.
|
||||
.TP
|
||||
\fB\-f\fR \fIconf-file\fR
|
||||
This option can be used to specify an alternate location for the
|
||||
configuration file (default \fI@SYSCONFDIR@/chrony.conf\fR). The configuration file is
|
||||
needed for the \fB-a\fR option.
|
||||
.TP
|
||||
\fB\-a\fR
|
||||
With this option chronyc will try to authenticate automatically on
|
||||
start. It will read the configuration file, read the command key from the
|
||||
keyfile and run the authhash and password commands.
|
||||
.TP
|
||||
\fIcommand\fR
|
||||
specify command. If no command is given, chronyc will read commands
|
||||
interactively.
|
||||
|
||||
|
||||
.SH VERSION
|
||||
1.17
|
||||
|
||||
.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"
|
||||
.BR chronyd(8),
|
||||
.BR chrony(1)
|
||||
|
||||
.I http://chrony.sunsite.dk/
|
||||
.I http://chrony.tuxfamily.org/
|
||||
|
||||
.SH AUTHOR
|
||||
Richard Curnow <rc@rc0.org.uk>
|
||||
@@ -56,4 +73,3 @@ Man Pages Project". Please see \fIhttp://www.netmeister.org/misc/m2p2/index.htm
|
||||
for details.
|
||||
|
||||
The complete chrony documentation is supplied in texinfo format.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH CHRONYD 8 "August 10, 2001" chrony "System Administration"
|
||||
.TH CHRONYD 8 "@MAN_DATE@" "chrony @VERSION@" "System Administration"
|
||||
.SH NAME
|
||||
chronyd \- chrony background daemon
|
||||
|
||||
@@ -21,13 +21,13 @@ gains or loses time, and compensates for this.
|
||||
|
||||
.SH USAGE
|
||||
\fBchronyd\fR is usually started at boot-time and requires superuser
|
||||
priviliges.
|
||||
privileges.
|
||||
|
||||
If \fBchronyd\fR has been installed to its default location
|
||||
\fI/usr/local/sbin/chronyd\fR, starting it is simply a matter of entering the
|
||||
\fI@SBINDIR@/chronyd\fR, starting it is simply a matter of entering the
|
||||
command:
|
||||
|
||||
\fI/usr/local/sbin/chronyd\fR
|
||||
\fI@SBINDIR@/chronyd\fR
|
||||
|
||||
Information messages and warnings will be logged to syslog.
|
||||
|
||||
@@ -35,6 +35,19 @@ Information messages and warnings will be logged to syslog.
|
||||
.SH OPTIONS
|
||||
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
|
||||
.B \-n
|
||||
When run in this mode, the program will not detach itself from the
|
||||
terminal.
|
||||
.TP
|
||||
.B \-d
|
||||
When run in this mode, the program will not detach itself from the
|
||||
@@ -43,7 +56,7 @@ to syslog.
|
||||
.TP
|
||||
\fB\-f\fR \fIconf-file\fR
|
||||
This option can be used to specify an alternate location for the
|
||||
configuration file (default \fI/etc/chrony.conf\fR).
|
||||
configuration file (default \fI@SYSCONFDIR@/chrony.conf\fR).
|
||||
.TP
|
||||
.B \-r
|
||||
This option will reload sample histories for each of the servers being used.
|
||||
@@ -56,6 +69,12 @@ systems where the kernel can maintain clock compensation whilst not under
|
||||
On systems where this is not the case, e.g. Solaris and SunOS the option
|
||||
should not be used.
|
||||
.TP
|
||||
.B \-R
|
||||
When this option is used, the \fIinitstepslew\fR directive and the
|
||||
\fImakestep\fR directive used with a positive limit will be ignored. This
|
||||
option is useful when restarting \fBchronyd\fR and can be used in conjuction
|
||||
with the \fB-r\fR option.
|
||||
.TP
|
||||
.B \-s
|
||||
This option will set the system clock from the computer's real-time
|
||||
clock. This is analogous to supplying the \fI-s\fR flag to the
|
||||
@@ -79,17 +98,24 @@ been able to determine accurate statistics for the difference
|
||||
between the real time clock and system clock last time the
|
||||
computer was on.
|
||||
.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
|
||||
This option displays \fBchronyd\fR's version number to the terminal and exits
|
||||
.TP
|
||||
.B \-4
|
||||
Resolve hostnames only to IPv4 addresses and create only IPv4 sockets.
|
||||
.TP
|
||||
.B \-6
|
||||
Resolve hostnames only to IPv6 addresses and create only IPv6 sockets.
|
||||
|
||||
.SH FILES
|
||||
\fI/etc/chrony.conf\fR
|
||||
|
||||
.SH VERSION
|
||||
Version 1.17
|
||||
\fI@SYSCONFDIR@/chrony.conf\fR
|
||||
|
||||
.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"
|
||||
\fBchronyd\fR is documented in detail in the documentation supplied with the
|
||||
@@ -99,8 +125,7 @@ from \fIhttp://go.to/chrony\fR
|
||||
.BR chrony(1),
|
||||
.BR chronyc(1),
|
||||
.BR chrony.conf(5),
|
||||
.BR clock(8),
|
||||
.BR xntpd(8),
|
||||
.BR hwclock(8),
|
||||
.BR ntpd(8)
|
||||
|
||||
.SH AUTHOR
|
||||
242
clientlog.c
242
clientlog.c
@@ -1,12 +1,9 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/clientlog.c,v 1.11 2003/09/22 21:22:30 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* 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
|
||||
@@ -19,7 +16,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -34,12 +31,15 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
#include "clientlog.h"
|
||||
#include "conf.h"
|
||||
#include "memory.h"
|
||||
#include "reports.h"
|
||||
#include "util.h"
|
||||
#include "logging.h"
|
||||
|
||||
/* 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
|
||||
@@ -52,7 +52,7 @@
|
||||
#define TABLE_SIZE (1UL<<NBITS)
|
||||
|
||||
typedef struct _Node {
|
||||
unsigned long ip_addr;
|
||||
IPAddr ip_addr;
|
||||
unsigned long client_hits;
|
||||
unsigned long peer_hits;
|
||||
unsigned long cmd_hits_bad;
|
||||
@@ -68,8 +68,10 @@ typedef struct _Subnet {
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
/* Table for the class A subnet */
|
||||
static Subnet top_subnet;
|
||||
/* Table for the IPv4 class A subnet */
|
||||
static Subnet top_subnet4;
|
||||
/* Table for IPv6 */
|
||||
static Subnet top_subnet6;
|
||||
|
||||
/* Table containing pointers directly to all nodes that have been
|
||||
allocated. */
|
||||
@@ -81,13 +83,46 @@ static int n_nodes = 0;
|
||||
/* Number of entries for which the table has been sized. */
|
||||
static int max_nodes = 0;
|
||||
|
||||
#define NODE_TABLE_INCREMENT 4
|
||||
|
||||
/* Flag indicating whether facility is turned on or not */
|
||||
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
|
||||
clear_subnet(Subnet *subnet)
|
||||
{
|
||||
@@ -117,7 +152,8 @@ clear_node(Node *node)
|
||||
void
|
||||
CLG_Initialise(void)
|
||||
{
|
||||
clear_subnet(&top_subnet);
|
||||
clear_subnet(&top_subnet4);
|
||||
clear_subnet(&top_subnet6);
|
||||
if (CNF_GetNoClientLog()) {
|
||||
active = 0;
|
||||
} else {
|
||||
@@ -128,6 +164,9 @@ CLG_Initialise(void)
|
||||
max_nodes = 0;
|
||||
n_nodes = 0;
|
||||
|
||||
alloced = 0;
|
||||
alloc_limit = CNF_GetClientLogLimit();
|
||||
alloc_limit_reached = 0;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -135,7 +174,18 @@ CLG_Initialise(void)
|
||||
void
|
||||
CLG_Finalise(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -145,6 +195,8 @@ create_subnet(Subnet *parent_subnet, int the_entry)
|
||||
{
|
||||
parent_subnet->entry[the_entry] = (void *) MallocNew(Subnet);
|
||||
clear_subnet((Subnet *) parent_subnet->entry[the_entry]);
|
||||
alloced += sizeof (Subnet);
|
||||
check_alloc_limit();
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -157,19 +209,22 @@ create_node(Subnet *parent_subnet, int the_entry)
|
||||
parent_subnet->entry[the_entry] = (void *) new_node;
|
||||
clear_node(new_node);
|
||||
|
||||
alloced += sizeof (Node);
|
||||
|
||||
if (n_nodes == max_nodes) {
|
||||
if (nodes) {
|
||||
max_nodes += NODE_TABLE_INCREMENT;
|
||||
assert(max_nodes > 0);
|
||||
max_nodes *= 2;
|
||||
nodes = ReallocArray(Node *, max_nodes, nodes);
|
||||
} else {
|
||||
if (max_nodes != 0) {
|
||||
CROAK("max_nodes should be 0");
|
||||
}
|
||||
max_nodes = NODE_TABLE_INCREMENT;
|
||||
assert(max_nodes == 0);
|
||||
max_nodes = 16;
|
||||
nodes = MallocArray(Node *, max_nodes);
|
||||
}
|
||||
alloced += sizeof (Node *) * (max_nodes - n_nodes);
|
||||
}
|
||||
nodes[n_nodes++] = (Node *) new_node;
|
||||
check_alloc_limit();
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -177,29 +232,24 @@ create_node(Subnet *parent_subnet, int the_entry)
|
||||
expanding subnet tables and node entries as we go if necessary. */
|
||||
|
||||
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;
|
||||
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;
|
||||
uint32_t this_subnet;
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "fs addr=%08lx bl=%d ma=%08lx this=%08lx newsn=%08lx nbl=%d\n",
|
||||
addr, bits_left, mask, this_subnet, new_subnet, new_bits_left);
|
||||
#endif
|
||||
this_subnet = get_subnet(addr, bits_consumed);
|
||||
bits_consumed += NBITS;
|
||||
|
||||
if (new_bits_left > 0) {
|
||||
if (bits_consumed < 32 * addr_len) {
|
||||
if (!subnet->entry[this_subnet]) {
|
||||
if (alloc_limit_reached)
|
||||
return NULL;
|
||||
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 {
|
||||
if (!subnet->entry[this_subnet]) {
|
||||
if (alloc_limit_reached)
|
||||
return NULL;
|
||||
create_node(subnet, this_subnet);
|
||||
}
|
||||
return subnet->entry[this_subnet];
|
||||
@@ -212,30 +262,21 @@ find_subnet(Subnet *subnet, CLG_IP_Addr addr, int bits_left)
|
||||
one of the parents does not exist - never open a node out */
|
||||
|
||||
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;
|
||||
unsigned long new_bits_left;
|
||||
uint32_t this_subnet;
|
||||
|
||||
if (bits_left == 0) {
|
||||
if (bits_consumed >= 32 * addr_len) {
|
||||
return subnet;
|
||||
} else {
|
||||
|
||||
shift = 32 - NBITS;
|
||||
mask = (1UL<<shift) - 1;
|
||||
this_subnet = addr >> shift;
|
||||
new_subnet = (addr & mask) << NBITS;
|
||||
new_bits_left = bits_left - NBITS;
|
||||
this_subnet = get_subnet(addr, bits_consumed);
|
||||
bits_consumed += 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]) {
|
||||
return NULL;
|
||||
} 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 +284,28 @@ find_subnet_dont_open(Subnet *subnet, CLG_IP_Addr addr, int bits_left)
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
CLG_LogNTPClientAccess (CLG_IP_Addr client, time_t now)
|
||||
CLG_LogNTPClientAccess (IPAddr *client, time_t now)
|
||||
{
|
||||
uint32_t ip6[4];
|
||||
Node *node;
|
||||
|
||||
if (active) {
|
||||
node = (Node *) find_subnet(&top_subnet, client, 32);
|
||||
node->ip_addr = client;
|
||||
switch (client->family) {
|
||||
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->last_ntp_hit = now;
|
||||
}
|
||||
@@ -257,12 +314,28 @@ CLG_LogNTPClientAccess (CLG_IP_Addr client, time_t now)
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
CLG_LogNTPPeerAccess(CLG_IP_Addr client, time_t now)
|
||||
CLG_LogNTPPeerAccess(IPAddr *client, time_t now)
|
||||
{
|
||||
uint32_t ip6[4];
|
||||
Node *node;
|
||||
|
||||
if (active) {
|
||||
node = (Node *) find_subnet(&top_subnet, client, 32);
|
||||
node->ip_addr = client;
|
||||
switch (client->family) {
|
||||
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->last_ntp_hit = now;
|
||||
}
|
||||
@@ -271,12 +344,28 @@ CLG_LogNTPPeerAccess(CLG_IP_Addr client, time_t now)
|
||||
/* ================================================== */
|
||||
|
||||
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;
|
||||
|
||||
if (active) {
|
||||
node = (Node *) find_subnet(&top_subnet, client, 32);
|
||||
node->ip_addr = client;
|
||||
switch (client->family) {
|
||||
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;
|
||||
switch (type) {
|
||||
case CLG_CMD_AUTH:
|
||||
@@ -289,7 +378,7 @@ CLG_LogCommandAccess(CLG_IP_Addr client, CLG_Command_Type type, time_t now)
|
||||
++node->cmd_hits_bad;
|
||||
break;
|
||||
default:
|
||||
CROAK("Impossible");
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -298,16 +387,32 @@ CLG_LogCommandAccess(CLG_IP_Addr client, CLG_Command_Type type, time_t now)
|
||||
/* ================================================== */
|
||||
|
||||
CLG_Status
|
||||
CLG_GetSubnetBitmap(CLG_IP_Addr subnet, int bits, CLG_Bitmap result)
|
||||
CLG_GetSubnetBitmap(IPAddr *subnet, int bits, CLG_Bitmap result)
|
||||
{
|
||||
Subnet *s;
|
||||
uint32_t ip6[4];
|
||||
unsigned long i;
|
||||
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);
|
||||
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) {
|
||||
for (i=0; i<256; i++) {
|
||||
if (s->entry[i]) {
|
||||
@@ -332,15 +437,26 @@ CLG_GetSubnetBitmap(CLG_IP_Addr subnet, int bits, CLG_Bitmap result)
|
||||
/* ================================================== */
|
||||
|
||||
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;
|
||||
|
||||
if (!active) {
|
||||
return CLG_INACTIVE;
|
||||
} 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) {
|
||||
return CLG_EMPTYSUBNET;
|
||||
} else {
|
||||
|
||||
20
clientlog.h
20
clientlog.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/clientlog.h,v 1.9 2003/09/22 21:22:30 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -35,15 +31,13 @@
|
||||
#include "sysincl.h"
|
||||
#include "reports.h"
|
||||
|
||||
typedef unsigned long CLG_IP_Addr;
|
||||
|
||||
/* Enough to hold flags for 256 hosts in a class C */
|
||||
typedef uint32_t CLG_Bitmap[8];
|
||||
|
||||
extern void CLG_Initialise(void);
|
||||
extern void CLG_Finalise(void);
|
||||
extern void CLG_LogNTPClientAccess(CLG_IP_Addr client, time_t now);
|
||||
extern void CLG_LogNTPPeerAccess(CLG_IP_Addr client, time_t now);
|
||||
extern void CLG_LogNTPClientAccess(IPAddr *client, time_t now);
|
||||
extern void CLG_LogNTPPeerAccess(IPAddr *client, time_t now);
|
||||
|
||||
/* When logging command packets, there are several subtypes */
|
||||
|
||||
@@ -53,7 +47,7 @@ typedef enum {
|
||||
CLG_CMD_BAD_PKT /* bad version or packet length */
|
||||
} 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. */
|
||||
/* TBD */
|
||||
@@ -70,10 +64,10 @@ typedef enum {
|
||||
known. For bits=24, flag which hosts in that subnet are known.
|
||||
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
|
||||
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_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *report,
|
||||
@@ -83,7 +77,7 @@ CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *repo
|
||||
that has accessed us since 'since'. */
|
||||
|
||||
extern void CLG_IterateNTPClients
|
||||
(void (*fn)(CLG_IP_Addr client, void *arb),
|
||||
(void (*fn)(IPAddr *client, void *arb),
|
||||
void *arb,
|
||||
time_t since);
|
||||
|
||||
|
||||
14
cmdmon.h
14
cmdmon.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/cmdmon.h,v 1.8 2002/02/28 23:27:09 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -31,11 +27,13 @@
|
||||
#ifndef GOT_CMDMON_H
|
||||
#define GOT_CMDMON_H
|
||||
|
||||
extern void CAM_Initialise(void);
|
||||
#include "addressing.h"
|
||||
|
||||
extern void CAM_Initialise(int family);
|
||||
|
||||
extern void CAM_Finalise(void);
|
||||
|
||||
extern int CAM_AddAccessRestriction(unsigned long ip_addr, int subnet_bits, int allow, int all);
|
||||
extern int CAM_CheckAccessRestriction(unsigned long ip_addr);
|
||||
extern int CAM_AddAccessRestriction(IPAddr *ip_addr, int subnet_bits, int allow, int all);
|
||||
extern int CAM_CheckAccessRestriction(IPAddr *ip_addr);
|
||||
|
||||
#endif /* GOT_CMDMON_H */
|
||||
|
||||
200
cmdparse.c
200
cmdparse.c
@@ -1,12 +1,9 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/cmdparse.c,v 1.12 2003/09/22 21:22:30 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Miroslav Lichvar 2013
|
||||
*
|
||||
* 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
|
||||
@@ -19,7 +16,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -30,58 +27,57 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "cmdparse.h"
|
||||
#include "memory.h"
|
||||
#include "nameserv.h"
|
||||
|
||||
#define MAXLEN 2047
|
||||
#define SMAXLEN "2047"
|
||||
#include "util.h"
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
CPS_Status
|
||||
CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src)
|
||||
CPS_ParseNTPSourceAdd(char *line, CPS_NTP_Source *src)
|
||||
{
|
||||
char *hostname, *cmd;
|
||||
int ok, n, done;
|
||||
char cmd[MAXLEN+1], hostname[MAXLEN+1];
|
||||
CPS_Status result;
|
||||
|
||||
src->port = 123;
|
||||
src->params.minpoll = 6;
|
||||
src->params.maxpoll = 10;
|
||||
src->params.presend_minpoll = 0;
|
||||
src->port = SRC_DEFAULT_PORT;
|
||||
src->params.minpoll = SRC_DEFAULT_MINPOLL;
|
||||
src->params.maxpoll = SRC_DEFAULT_MAXPOLL;
|
||||
src->params.presend_minpoll = SRC_DEFAULT_PRESEND_MINPOLL;
|
||||
src->params.authkey = INACTIVE_AUTHKEY;
|
||||
src->params.max_delay = 16.0;
|
||||
src->params.max_delay_ratio = 16384.0;
|
||||
src->params.max_delay = SRC_DEFAULT_MAXDELAY;
|
||||
src->params.max_delay_ratio = SRC_DEFAULT_MAXDELAYRATIO;
|
||||
src->params.max_delay_dev_ratio = SRC_DEFAULT_MAXDELAYDEVRATIO;
|
||||
src->params.online = 1;
|
||||
src->params.auto_offline = 0;
|
||||
src->params.iburst = 0;
|
||||
src->params.min_stratum = SRC_DEFAULT_MINSTRATUM;
|
||||
src->params.poll_target = SRC_DEFAULT_POLLTARGET;
|
||||
src->params.sel_option = SRC_SelectNormal;
|
||||
|
||||
result = CPS_Success;
|
||||
|
||||
ok = 0;
|
||||
if (sscanf(line, "%" SMAXLEN "s%n", hostname, &n) == 1) {
|
||||
src->ip_addr = DNS_Name2IPAddress(hostname);
|
||||
if (src->ip_addr != DNS_Failed_Address) {
|
||||
ok = 1;
|
||||
}
|
||||
}
|
||||
hostname = line;
|
||||
line = CPS_SplitWord(line);
|
||||
|
||||
if (!ok) {
|
||||
if (!*hostname) {
|
||||
result = CPS_BadHost;
|
||||
ok = 0;
|
||||
} else {
|
||||
|
||||
line += n;
|
||||
|
||||
/* Parse subfields */
|
||||
ok = 1;
|
||||
done = 0;
|
||||
do {
|
||||
if (sscanf(line, "%" SMAXLEN "s%n", cmd, &n) == 1) {
|
||||
|
||||
line += n;
|
||||
|
||||
if (!strncasecmp(cmd, "port", 4)) {
|
||||
cmd = line;
|
||||
line = CPS_SplitWord(line);
|
||||
|
||||
if (*cmd) {
|
||||
if (!strcasecmp(cmd, "port")) {
|
||||
if (sscanf(line, "%hu%n", &src->port, &n) != 1) {
|
||||
result = CPS_BadPort;
|
||||
ok = 0;
|
||||
@@ -89,7 +85,7 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src)
|
||||
} else {
|
||||
line += n;
|
||||
}
|
||||
} else if (!strncasecmp(cmd, "minpoll", 7)) {
|
||||
} else if (!strcasecmp(cmd, "minpoll")) {
|
||||
if (sscanf(line, "%d%n", &src->params.minpoll, &n) != 1) {
|
||||
result = CPS_BadMinpoll;
|
||||
ok = 0;
|
||||
@@ -97,7 +93,7 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src)
|
||||
} else {
|
||||
line += n;
|
||||
}
|
||||
} else if (!strncasecmp(cmd, "maxpoll", 7)) {
|
||||
} else if (!strcasecmp(cmd, "maxpoll")) {
|
||||
if (sscanf(line, "%d%n", &src->params.maxpoll, &n) != 1) {
|
||||
result = CPS_BadMaxpoll;
|
||||
ok = 0;
|
||||
@@ -105,7 +101,7 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src)
|
||||
} else {
|
||||
line += n;
|
||||
}
|
||||
} else if (!strncasecmp(cmd, "presend", 7)) {
|
||||
} else if (!strcasecmp(cmd, "presend")) {
|
||||
if (sscanf(line, "%d%n", &src->params.presend_minpoll, &n) != 1) {
|
||||
result = CPS_BadPresend;
|
||||
ok = 0;
|
||||
@@ -113,8 +109,15 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src)
|
||||
} else {
|
||||
line += n;
|
||||
}
|
||||
/* This MUST come before the following one ! */
|
||||
} else if (!strncasecmp(cmd, "maxdelayratio", 13)) {
|
||||
} else if (!strcasecmp(cmd, "maxdelaydevratio")) {
|
||||
if (sscanf(line, "%lf%n", &src->params.max_delay_dev_ratio, &n) != 1) {
|
||||
result = CPS_BadMaxdelaydevratio;
|
||||
ok = 0;
|
||||
done = 1;
|
||||
} else {
|
||||
line += n;
|
||||
}
|
||||
} else if (!strcasecmp(cmd, "maxdelayratio")) {
|
||||
if (sscanf(line, "%lf%n", &src->params.max_delay_ratio, &n) != 1) {
|
||||
result = CPS_BadMaxdelayratio;
|
||||
ok = 0;
|
||||
@@ -122,7 +125,7 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src)
|
||||
} else {
|
||||
line += n;
|
||||
}
|
||||
} else if (!strncasecmp(cmd, "maxdelay", 8)) {
|
||||
} else if (!strcasecmp(cmd, "maxdelay")) {
|
||||
if (sscanf(line, "%lf%n", &src->params.max_delay, &n) != 1) {
|
||||
result = CPS_BadMaxdelay;
|
||||
ok = 0;
|
||||
@@ -130,7 +133,7 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src)
|
||||
} else {
|
||||
line += n;
|
||||
}
|
||||
} else if (!strncasecmp(cmd, "key", 3)) {
|
||||
} else if (!strcasecmp(cmd, "key")) {
|
||||
if (sscanf(line, "%lu%n", &src->params.authkey, &n) != 1) {
|
||||
result = CPS_BadKey;
|
||||
ok = 0;
|
||||
@@ -138,12 +141,39 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src)
|
||||
} else {
|
||||
line += n;
|
||||
}
|
||||
} else if (!strncasecmp(cmd, "offline", 7)) {
|
||||
} else if (!strcasecmp(cmd, "offline")) {
|
||||
src->params.online = 0;
|
||||
|
||||
} else if (!strncasecmp(cmd, "auto_offline", 12)) {
|
||||
} else if (!strcasecmp(cmd, "auto_offline")) {
|
||||
src->params.auto_offline = 1;
|
||||
|
||||
} else if (!strcasecmp(cmd, "iburst")) {
|
||||
src->params.iburst = 1;
|
||||
|
||||
} else if (!strcasecmp(cmd, "minstratum")) {
|
||||
if (sscanf(line, "%d%n", &src->params.min_stratum, &n) != 1) {
|
||||
result = CPS_BadMinstratum;
|
||||
ok = 0;
|
||||
done = 1;
|
||||
} else {
|
||||
line += n;
|
||||
}
|
||||
|
||||
} else if (!strcasecmp(cmd, "polltarget")) {
|
||||
if (sscanf(line, "%d%n", &src->params.poll_target, &n) != 1) {
|
||||
result = CPS_BadPolltarget;
|
||||
ok = 0;
|
||||
done = 1;
|
||||
} else {
|
||||
line += n;
|
||||
}
|
||||
|
||||
} else if (!strcasecmp(cmd, "noselect")) {
|
||||
src->params.sel_option = SRC_SelectNoselect;
|
||||
|
||||
} else if (!strcasecmp(cmd, "prefer")) {
|
||||
src->params.sel_option = SRC_SelectPrefer;
|
||||
|
||||
} else {
|
||||
result = CPS_BadOption;
|
||||
ok = 0;
|
||||
@@ -155,9 +185,97 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src)
|
||||
} while (!done);
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
src->name = strdup(hostname);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
CPS_NormalizeLine(char *line)
|
||||
{
|
||||
char *p, *q;
|
||||
int space = 1, first = 1;
|
||||
|
||||
/* Remove white-space at beginning and replace white-spaces with space char */
|
||||
for (p = q = line; *p; p++) {
|
||||
if (isspace(*p)) {
|
||||
if (!space)
|
||||
*q++ = ' ';
|
||||
space = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Discard comment lines */
|
||||
if (first && strchr("!;#%", *p))
|
||||
break;
|
||||
|
||||
*q++ = *p;
|
||||
space = first = 0;
|
||||
}
|
||||
|
||||
/* Strip trailing space */
|
||||
if (q > line && q[-1] == ' ')
|
||||
q--;
|
||||
|
||||
*q = '\0';
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
char *
|
||||
CPS_SplitWord(char *line)
|
||||
{
|
||||
char *p = line, *q = line;
|
||||
|
||||
/* Skip white-space before the word */
|
||||
while (*q && isspace(*q))
|
||||
q++;
|
||||
|
||||
/* Move the word to the beginning */
|
||||
while (*q && !isspace(*q))
|
||||
*p++ = *q++;
|
||||
|
||||
/* Find the next word */
|
||||
while (*q && isspace(*q))
|
||||
q++;
|
||||
|
||||
*p = '\0';
|
||||
|
||||
/* Return pointer to the next word or NUL */
|
||||
return q;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
CPS_ParseKey(char *line, unsigned long *id, const char **hash, char **key)
|
||||
{
|
||||
char *s1, *s2, *s3, *s4;
|
||||
|
||||
s1 = line;
|
||||
s2 = CPS_SplitWord(s1);
|
||||
s3 = CPS_SplitWord(s2);
|
||||
s4 = CPS_SplitWord(s3);
|
||||
|
||||
/* Require two or three words */
|
||||
if (!*s2 || *s4)
|
||||
return 0;
|
||||
|
||||
if (sscanf(s1, "%lu", id) != 1)
|
||||
return 0;
|
||||
|
||||
if (*s3) {
|
||||
*hash = s2;
|
||||
*key = s3;
|
||||
} else {
|
||||
*hash = "MD5";
|
||||
*key = s2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
23
cmdparse.h
23
cmdparse.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/cmdparse.h,v 1.7 2002/02/28 23:27:09 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -32,6 +28,7 @@
|
||||
#define GOT_CMDPARSE_H
|
||||
|
||||
#include "srcparams.h"
|
||||
#include "addressing.h"
|
||||
|
||||
typedef enum {
|
||||
CPS_Success,
|
||||
@@ -41,20 +38,30 @@ typedef enum {
|
||||
CPS_BadMinpoll,
|
||||
CPS_BadMaxpoll,
|
||||
CPS_BadPresend,
|
||||
CPS_BadMaxdelaydevratio,
|
||||
CPS_BadMaxdelayratio,
|
||||
CPS_BadMaxdelay,
|
||||
CPS_BadKey
|
||||
CPS_BadKey,
|
||||
CPS_BadMinstratum,
|
||||
CPS_BadPolltarget
|
||||
} CPS_Status;
|
||||
|
||||
typedef struct {
|
||||
unsigned long ip_addr;
|
||||
char *name;
|
||||
unsigned short port;
|
||||
SourceParameters params;
|
||||
} CPS_NTP_Source;
|
||||
|
||||
/* Parse a command to add an NTP server or peer */
|
||||
extern CPS_Status CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src);
|
||||
extern CPS_Status CPS_ParseNTPSourceAdd(char *line, CPS_NTP_Source *src);
|
||||
|
||||
/* Remove extra white-space and comments */
|
||||
extern void CPS_NormalizeLine(char *line);
|
||||
|
||||
/* Terminate first word and return pointer to the next word */
|
||||
extern char *CPS_SplitWord(char *line);
|
||||
|
||||
/* Parse a key from keyfile */
|
||||
extern int CPS_ParseKey(char *line, unsigned long *id, const char **hash, char **key);
|
||||
|
||||
#endif /* GOT_CMDPARSE_H */
|
||||
|
||||
42
conf.h
42
conf.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/conf.h,v 1.25 2003/09/22 21:22:30 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -31,12 +27,17 @@
|
||||
#ifndef GOT_CONF_H
|
||||
#define GOT_CONF_H
|
||||
|
||||
#include "addressing.h"
|
||||
|
||||
extern void CNF_SetRestarted(int);
|
||||
|
||||
extern char *CNF_GetRtcDevice(void);
|
||||
|
||||
extern void CNF_ReadFile(const char *filename);
|
||||
|
||||
extern void CNF_AddSources(void);
|
||||
extern void CNF_AddBroadcasts(void);
|
||||
extern void CNF_AddRefclocks(void);
|
||||
|
||||
extern void CNF_ProcessInitStepSlew(void (*after_hook)(void *), void *anything);
|
||||
|
||||
@@ -45,30 +46,57 @@ extern unsigned short CNF_GetNTPPort(void);
|
||||
extern char *CNF_GetDriftFile(void);
|
||||
extern char *CNF_GetLogDir(void);
|
||||
extern char *CNF_GetDumpDir(void);
|
||||
extern int CNF_GetLogBanner(void);
|
||||
extern int CNF_GetLogMeasurements(void);
|
||||
extern int CNF_GetLogStatistics(void);
|
||||
extern int CNF_GetLogTracking(void);
|
||||
extern int CNF_GetLogRtc(void);
|
||||
extern int CNF_GetLogRefclocks(void);
|
||||
extern int CNF_GetLogTempComp(void);
|
||||
extern char *CNF_GetKeysFile(void);
|
||||
extern char *CNF_GetRtcFile(void);
|
||||
extern unsigned long CNF_GetCommandKey(void);
|
||||
extern int CNF_GetGenerateCommandKey(void);
|
||||
extern int CNF_GetDumpOnExit(void);
|
||||
extern int CNF_GetManualEnabled(void);
|
||||
extern int CNF_GetCommandPort(void);
|
||||
extern int CNF_GetRTCOnUTC(void);
|
||||
extern int CNF_GetRTCSync(void);
|
||||
extern void CNF_GetMakeStep(int *limit, double *threshold);
|
||||
extern void CNF_GetMaxChange(int *delay, int *ignore, double *offset);
|
||||
extern void CNF_GetLogChange(int *enabled, double *threshold);
|
||||
extern void CNF_GetMailOnChange(int *enabled, double *threshold, char **user);
|
||||
extern int CNF_GetNoClientLog(void);
|
||||
extern void CNF_GetBindAddress(unsigned long *addr);
|
||||
extern void CNF_GetBindCommandAddress(unsigned long *addr);
|
||||
extern unsigned long CNF_GetClientLogLimit(void);
|
||||
extern void CNF_GetFallbackDrifts(int *min, int *max);
|
||||
extern void CNF_GetBindAddress(int family, IPAddr *addr);
|
||||
extern void CNF_GetBindCommandAddress(int family, IPAddr *addr);
|
||||
extern char *CNF_GetPidFile(void);
|
||||
extern char *CNF_GetLeapSecTimezone(void);
|
||||
extern void CNF_GetLinuxHz(int *set, int *hz);
|
||||
extern void CNF_GetLinuxFreqScale(int *set, double *freq_scale);
|
||||
|
||||
/* Value returned in ppm, as read from file */
|
||||
extern double CNF_GetMaxUpdateSkew(void);
|
||||
extern double CNF_GetMaxClockError(void);
|
||||
extern double CNF_GetCorrectionTimeRatio(void);
|
||||
|
||||
extern double CNF_GetReselectDistance(void);
|
||||
extern double CNF_GetStratumWeight(void);
|
||||
extern double CNF_GetCombineLimit(void);
|
||||
|
||||
extern int CNF_AllowLocalReference(int *stratum);
|
||||
|
||||
extern void CNF_SetupAccessRestrictions(void);
|
||||
|
||||
extern int CNF_GetSchedPriority(void);
|
||||
extern int CNF_GetLockMemory(void);
|
||||
|
||||
extern void CNF_GetTempComp(char **file, double *interval, double *T0, double *k0, double *k1, double *k2);
|
||||
|
||||
extern char *CNF_GetUser(void);
|
||||
|
||||
extern int CNF_GetMaxSamples(void);
|
||||
extern int CNF_GetMinSamples(void);
|
||||
|
||||
#endif /* GOT_CONF_H */
|
||||
|
||||
583
configure
vendored
583
configure
vendored
@@ -1,15 +1,15 @@
|
||||
#!/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.
|
||||
#
|
||||
# Copyright (C) Richard P. Curnow 1997-2003
|
||||
# Copyright (C) Miroslav Lichvar 2009, 2012
|
||||
#
|
||||
# =======================================================================
|
||||
|
||||
rm -f config.h config.log
|
||||
|
||||
# This configure script determines the operating system type and version
|
||||
|
||||
if [ "x${CC}" = "x" ]; then
|
||||
@@ -24,92 +24,60 @@ else
|
||||
MYCFLAGS="${CFLAGS}"
|
||||
fi
|
||||
|
||||
MYCPPFLAGS="${CPPFLAGS}"
|
||||
|
||||
if [ "x${MYCC}" = "xgcc" ]; then
|
||||
MYCFLAGS="${MYCFLAGS} -Wmissing-prototypes -Wall"
|
||||
fi
|
||||
|
||||
MYLDFLAGS="${LDFLAGS}"
|
||||
|
||||
# ======================================================================
|
||||
# FUNCTIONS
|
||||
|
||||
#{{{ test_for_sqrt
|
||||
test_for_sqrt () {
|
||||
# 0 : doesn't need -lm
|
||||
# 1 : needs -lm
|
||||
# 2 : doesn't even link with -lm
|
||||
#{{{ test_code
|
||||
test_code () {
|
||||
name=$1
|
||||
headers=$2
|
||||
cflags=$3
|
||||
ldflags=$4
|
||||
code=$5
|
||||
|
||||
cat >docheck.c <<EOF;
|
||||
#include <math.h>
|
||||
int main(int argc, char **argv) {
|
||||
return (int) sqrt((double)argc);
|
||||
}
|
||||
EOF
|
||||
echo -n "Checking for $name : "
|
||||
|
||||
(
|
||||
for h in $headers; do
|
||||
echo "#include <$h>"
|
||||
done
|
||||
echo "int main(int argc, char **argv) {"
|
||||
echo "$code"
|
||||
echo "return 0; }"
|
||||
) > docheck.c
|
||||
|
||||
echo "docheck.c:" >> config.log
|
||||
cat docheck.c >> config.log
|
||||
echo $MYCC $MYCFLAGS $MYCPPFLAGS $cflags -o docheck docheck.c $ldflags \
|
||||
$MYLDFLAGS >> config.log
|
||||
$MYCC $MYCFLAGS $MYCPPFLAGS $cflags -o docheck docheck.c $ldflags \
|
||||
$MYLDFLAGS >> config.log 2>&1
|
||||
|
||||
${MYCC} ${MYCFLAGS} -c -o docheck.o docheck.c >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
${MYCC} ${MYCFLAGS} -o docheck docheck.o >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
result=0
|
||||
else
|
||||
${MYCC} ${MYCFLAGS} -o docheck docheck.o -lm >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]
|
||||
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 ]
|
||||
then
|
||||
echo "Yes"
|
||||
result=0
|
||||
else
|
||||
echo "No"
|
||||
result=1
|
||||
fi
|
||||
|
||||
rm -f docheck.c docheck.o
|
||||
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
|
||||
rm -f docheck.c docheck
|
||||
echo >> config.log
|
||||
return $result
|
||||
}
|
||||
#}}}
|
||||
#{{{ usage
|
||||
usage () {
|
||||
cat <<EOF;
|
||||
\`configure' configures tdl to adapt to many kinds of systems.
|
||||
cat <<EOF
|
||||
\`configure' configures this package to adapt to many kinds of systems.
|
||||
|
||||
Usage: ./configure [OPTION]...
|
||||
|
||||
@@ -121,6 +89,8 @@ Configuration:
|
||||
Installation directories:
|
||||
--prefix=PREFIX install architecture-independent files in PREFIX
|
||||
[/usr/local]
|
||||
--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
|
||||
[PREFIX]
|
||||
|
||||
By default, \`make install' will install all the files in
|
||||
\`/usr/local/bin', \`/usr/local/lib' etc. You can specify
|
||||
@@ -128,31 +98,63 @@ an installation prefix other than \`/usr/local' using \`--prefix',
|
||||
for instance \`--prefix=$HOME'.
|
||||
|
||||
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-inc-dir=DIR Specify where readline include directory is
|
||||
--readline-lib-dir=DIR Specify where readline lib directory is
|
||||
--with-ncurses-library=DIR Specify where ncurses lib directory is
|
||||
--without-nss Don't use NSS even if it is available
|
||||
--without-tomcrypt Don't use libtomcrypt even if it is available
|
||||
--disable-ipv6 Disable IPv6 support
|
||||
--disable-pps Disable PPS API support
|
||||
--disable-rtc Don't include RTC even on Linux
|
||||
--disable-linuxcaps Disable Linux capabilities support
|
||||
--disable-forcednsretry Don't retry on permanent DNS error
|
||||
--with-sendmail=PATH Path to sendmail binary [/usr/lib/sendmail]
|
||||
--enable-trace Enable tracing
|
||||
|
||||
Fine tuning of the installation directories:
|
||||
--infodir=DIR info documentation [PREFIX/info]
|
||||
--mandir=DIR man documentation [PREFIX/man]
|
||||
--sysconfdir=DIR chrony.conf location [/etc]
|
||||
--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]
|
||||
--localstatedir=DIR modifiable single-machine data [/var]
|
||||
--chronyvardir=DIR location for chrony data [LOCALSTATEDIR/lib/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:
|
||||
CC C compiler command
|
||||
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
|
||||
nonstandard directory <lib dir>
|
||||
|
||||
Use these variables to override the choices made by \`configure' or to help
|
||||
it to find libraries and programs with nonstandard names/locations.
|
||||
|
||||
Report bugs to <rc@rc0.org.uk>.
|
||||
EOF
|
||||
|
||||
}
|
||||
#}}}
|
||||
#{{{
|
||||
add_def () {
|
||||
if [ "x$2" = "x" ]; then
|
||||
echo "#define $1 1" >> config.h
|
||||
else
|
||||
echo "#define $1 $2" >> config.h
|
||||
fi
|
||||
}
|
||||
#}}}
|
||||
|
||||
# ======================================================================
|
||||
|
||||
@@ -162,37 +164,47 @@ OPERATINGSYSTEM=`uname -s`
|
||||
VERSION=`uname -r`
|
||||
MACHINE=`uname -m`
|
||||
|
||||
SYSTEM=${OPERATINGSYSTEM}-${MACHINE}
|
||||
|
||||
EXTRA_LIBS=""
|
||||
EXTRA_CLI_LIBS=""
|
||||
EXTRA_OBJECTS=""
|
||||
EXTRA_DEFS=""
|
||||
INSTALL_PREFIX=/usr/local
|
||||
SYSDEFS=""
|
||||
|
||||
# Support for readline (on by default)
|
||||
feat_readline=1
|
||||
try_readline=1
|
||||
try_editline=1
|
||||
try_nss=1
|
||||
try_tomcrypt=1
|
||||
feat_rtc=1
|
||||
try_rtc=0
|
||||
feat_linuxcaps=1
|
||||
try_linuxcaps=0
|
||||
readline_lib=""
|
||||
readline_inc=""
|
||||
ncurses_lib=""
|
||||
|
||||
SETINFODIR=""
|
||||
SETMANDIR=""
|
||||
feat_ipv6=1
|
||||
feat_pps=1
|
||||
try_setsched=0
|
||||
try_lockmem=0
|
||||
feat_forcednsretry=1
|
||||
mail_program="/usr/lib/sendmail"
|
||||
|
||||
for option
|
||||
do
|
||||
case "$option" in
|
||||
--prefix=* | --install_prefix=* )
|
||||
INSTALL_PREFIX=`echo $option | sed -e 's/[^=]*=//;'`
|
||||
;;
|
||||
--trace )
|
||||
EXTRA_DEFS="-DTRACEON"
|
||||
--enable-trace )
|
||||
add_def TRACEON
|
||||
;;
|
||||
--disable-readline )
|
||||
feat_readline=0
|
||||
;;
|
||||
--without-readline )
|
||||
try_readline=0
|
||||
;;
|
||||
--without-editline )
|
||||
try_editline=0
|
||||
;;
|
||||
--with-readline-library=* )
|
||||
readline_lib=-L`echo $option | sed -e 's/^.*=//;'`
|
||||
;;
|
||||
@@ -202,15 +214,72 @@ do
|
||||
--with-ncurses-library=* )
|
||||
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=* )
|
||||
SETINFODIR=`echo $option | sed -e 's/^.*=//;'`
|
||||
;;
|
||||
--mandir=* )
|
||||
SETMANDIR=`echo $option | sed -e 's/^.*=//;'`
|
||||
;;
|
||||
--docdir=* )
|
||||
SETDOCDIR=`echo $option | sed -e 's/^.*=//;'`
|
||||
;;
|
||||
--localstatedir=* )
|
||||
SETLOCALSTATEDIR=`echo $option | sed -e 's/^.*=//;'`
|
||||
;;
|
||||
--chronyvardir=* )
|
||||
SETCHRONYVARDIR=`echo $option | sed -e 's/^.*=//;'`
|
||||
;;
|
||||
--disable-rtc)
|
||||
feat_rtc=0
|
||||
;;
|
||||
--disable-ipv6)
|
||||
feat_ipv6=0
|
||||
;;
|
||||
--disable-pps)
|
||||
feat_pps=0
|
||||
;;
|
||||
--disable-linuxcaps)
|
||||
feat_linuxcaps=0
|
||||
;;
|
||||
--disable-forcednsretry)
|
||||
feat_forcednsretry=0
|
||||
;;
|
||||
--with-sendmail=* )
|
||||
mail_program=`echo $option | sed -e 's/^.*=//;'`
|
||||
;;
|
||||
--without-nss )
|
||||
try_nss=0
|
||||
;;
|
||||
--without-tomcrypt )
|
||||
try_tomcrypt=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 )
|
||||
usage
|
||||
exit 0
|
||||
@@ -220,50 +289,48 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
SYSTEM=${OPERATINGSYSTEM}-${MACHINE}
|
||||
|
||||
case $SYSTEM in
|
||||
SunOS-sun4* )
|
||||
case $VERSION in
|
||||
4.* )
|
||||
EXTRA_OBJECTS="sys_sunos.o strerror.o"
|
||||
EXTRA_LIBS="-lkvm"
|
||||
SYSDEFS="-DSUNOS"
|
||||
add_def SUNOS
|
||||
echo "Configuring for SunOS (" $SYSTEM "version" $VERSION ")"
|
||||
;;
|
||||
5.* )
|
||||
EXTRA_OBJECTS="sys_solaris.o"
|
||||
EXTRA_LIBS="-lsocket -lnsl -lkvm -lelf"
|
||||
EXTRA_CLI_LIBS="-lsocket -lnsl"
|
||||
SYSDEFS="-DSOLARIS"
|
||||
add_def SOLARIS
|
||||
echo "Configuring for Solaris (" $SYSTEM "SunOS version" $VERSION ")"
|
||||
if [ $VERSION = "5.3" ]; then
|
||||
SYSDEFS="$SYSDEFS -DHAS_NO_BZERO"
|
||||
echo "Using memset() instead of bzero()"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
Linux* )
|
||||
EXTRA_OBJECTS="sys_linux.o wrap_adjtimex.o"
|
||||
if [ $feat_rtc -eq 1 ] ; then
|
||||
EXTRA_OBJECTS+=" rtc_linux.o"
|
||||
EXTRA_DEFS+=" -DFEAT_RTC=1"
|
||||
fi
|
||||
SYSDEFS="-DLINUX"
|
||||
try_linuxcaps=1
|
||||
try_rtc=1
|
||||
try_setsched=1
|
||||
try_lockmem=1
|
||||
add_def LINUX
|
||||
echo "Configuring for " $SYSTEM
|
||||
if [ "${MACHINE}" = "alpha" ]; then
|
||||
echo "Enabling -mieee"
|
||||
# FIXME: Should really test for GCC
|
||||
SYSDEFS="$SYSDEFS -mieee -DALPHA"
|
||||
MYCFLAGS="$MYCFLAGS -mieee"
|
||||
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
|
||||
# be supported with the SunOS 4.x driver files.
|
||||
EXTRA_OBJECTS="sys_sunos.o strerror.o"
|
||||
EXTRA_LIBS="-lkvm"
|
||||
SYSDEFS="-DSUNOS"
|
||||
echo "Configuring for BSD/386 (using SunOS driver)"
|
||||
add_def SUNOS
|
||||
echo "Configuring for $SYSTEM (using SunOS driver)"
|
||||
;;
|
||||
NetBSD-* )
|
||||
EXTRA_OBJECTS="sys_netbsd.o"
|
||||
@@ -277,13 +344,13 @@ case $SYSTEM in
|
||||
EXTRA_OBJECTS="sys_solaris.o"
|
||||
EXTRA_LIBS="-lsocket -lnsl -lkvm -lelf"
|
||||
EXTRA_CLI_LIBS="-lsocket -lnsl"
|
||||
SYSDEFS="-DSOLARIS"
|
||||
add_def SOLARIS
|
||||
echo "Configuring for Solaris (" $SYSTEM "SunOS version" $VERSION ")"
|
||||
;;
|
||||
CYGWIN32_NT-i[3456]86 )
|
||||
EXTRA_OBJECTS="sys_winnt.o"
|
||||
EXTRA_LIBS=""
|
||||
SYSDEFS="-DWINNT"
|
||||
add_def WINNT
|
||||
echo "Configuring for Windows NT (Cygwin32)"
|
||||
;;
|
||||
* )
|
||||
@@ -292,77 +359,275 @@ case $SYSTEM in
|
||||
;;
|
||||
esac
|
||||
|
||||
printf "Checking if sqrt() needs -lm : "
|
||||
case `test_for_sqrt`
|
||||
in
|
||||
0)
|
||||
printf "No\n"
|
||||
MATHCODE='return (int) pow(2.0, log(sqrt((double)argc)));'
|
||||
if test_code 'math' 'math.h' '' '' "$MATHCODE"; then
|
||||
LIBS=""
|
||||
;;
|
||||
1)
|
||||
printf "Yes\n"
|
||||
LIBS="-lm"
|
||||
;;
|
||||
*)
|
||||
printf "\nCan't compile/link a program which uses sqrt(), bailing out\n"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
printf "Checking for <stdint.h> : "
|
||||
if [ `test_for_stdint_h` -eq 0 ]; then
|
||||
printf "Yes\n"
|
||||
SYSDEFS="${SYSDEFS} -DHAS_STDINT_H"
|
||||
else
|
||||
printf "No\n"
|
||||
if test_code 'math in -lm' 'math.h' '' '-lm' "$MATHCODE"; then
|
||||
LIBS="-lm"
|
||||
else
|
||||
echo "Can't compile/link a program which uses sqrt(), log(), pow(), bailing out"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test_code '<stdint.h>' 'stdint.h' '' '' ''; then
|
||||
add_def HAS_STDINT_H
|
||||
fi
|
||||
|
||||
printf "Checking for <inttypes.h> : "
|
||||
if [ `test_for_inttypes_h` -eq 0 ]; then
|
||||
printf "Yes\n"
|
||||
SYSDEFS="${SYSDEFS} -DHAS_INTTYPES_H"
|
||||
else
|
||||
printf "No\n"
|
||||
if test_code '<inttypes.h>' 'inttypes.h' '' '' ''; then
|
||||
add_def HAS_INTTYPES_H
|
||||
fi
|
||||
|
||||
if [ "x${MYCC}" = "xgcc" ]; then
|
||||
CCWARNFLAGS="-Wmissing-prototypes -Wall"
|
||||
else
|
||||
CCWARNFLAGS=""
|
||||
if [ $feat_ipv6 = "1" ] && \
|
||||
test_code 'IPv6 support' 'arpa/inet.h sys/socket.h netinet/in.h' '' '' '
|
||||
struct sockaddr_in6 n;
|
||||
char p[100];
|
||||
n.sin6_addr = in6addr_any;
|
||||
return !inet_ntop(AF_INET6, &n.sin6_addr.s6_addr, p, sizeof(p));'
|
||||
then
|
||||
add_def HAVE_IPV6
|
||||
if test_code 'in6_pktinfo' 'sys/socket.h netinet/in.h' '' '' '
|
||||
return sizeof(struct in6_pktinfo);'
|
||||
then
|
||||
add_def HAVE_IN6_PKTINFO
|
||||
else
|
||||
if test_code 'in6_pktinfo with _GNU_SOURCE' 'sys/socket.h netinet/in.h' \
|
||||
'-D_GNU_SOURCE' '' 'return sizeof(struct in6_pktinfo);'
|
||||
then
|
||||
add_def _GNU_SOURCE
|
||||
add_def HAVE_IN6_PKTINFO
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
timepps_h=""
|
||||
if [ $feat_pps = "1" ]; then
|
||||
if test_code '<sys/timepps.h>' 'sys/timepps.h' '' '' ''; then
|
||||
timepps_h="sys/timepps.h"
|
||||
add_def HAVE_SYS_TIMEPPS_H
|
||||
else
|
||||
if test_code '<timepps.h>' 'timepps.h' '' '' ''; then
|
||||
timepps_h="timepps.h"
|
||||
add_def HAVE_TIMEPPS_H
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "x$timepps_h" != "x" ] && \
|
||||
test_code 'PPSAPI' "string.h $timepps_h" '' '' '
|
||||
pps_handle_t h;
|
||||
pps_info_t i;
|
||||
struct timespec ts;
|
||||
return time_pps_fetch(h, PPS_TSFMT_TSPEC, &i, &ts);'
|
||||
then
|
||||
add_def HAVE_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
|
||||
add_def FEAT_LINUXCAPS
|
||||
EXTRA_LIBS="-lcap"
|
||||
fi
|
||||
|
||||
if [ $feat_rtc = "1" ] && [ $try_rtc = "1" ] && \
|
||||
test_code '<linux/rtc.h>' 'sys/ioctl.h linux/rtc.h' '' '' \
|
||||
'ioctl(1, RTC_UIE_ON&RTC_UIE_OFF&RTC_RD_TIME&RTC_SET_TIME, 0&RTC_UF);'
|
||||
then
|
||||
EXTRA_OBJECTS="$EXTRA_OBJECTS rtc_linux.o"
|
||||
add_def FEAT_RTC
|
||||
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
|
||||
add_def HAVE_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
|
||||
add_def HAVE_MLOCKALL
|
||||
fi
|
||||
|
||||
if [ $feat_forcednsretry = "1" ]
|
||||
then
|
||||
add_def FORCE_DNSRETRY
|
||||
fi
|
||||
|
||||
READLINE_COMPILE=""
|
||||
READLINE_LINK=""
|
||||
if [ $feat_readline = "1" ]; then
|
||||
READLINE_COMPILE="-DFEAT_READLINE=1 $readline_inc"
|
||||
READLINE_LINK="$readline_lib $ncurses_lib -lreadline -lncurses"
|
||||
else
|
||||
READLINE_COMPILE=""
|
||||
READLINE_LINK=""
|
||||
if [ $try_editline = "1" ]; then
|
||||
if test_code editline 'stdio.h editline/readline.h' \
|
||||
"$readline_inc" "$readline_lib -ledit" \
|
||||
'add_history(readline("prompt"));'
|
||||
then
|
||||
add_def FEAT_READLINE
|
||||
add_def USE_EDITLINE
|
||||
READLINE_COMPILE="$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" \
|
||||
'add_history(readline("prompt"));'
|
||||
then
|
||||
add_def FEAT_READLINE
|
||||
READLINE_COMPILE="$readline_inc"
|
||||
READLINE_LINK="$readline_lib $ncurses_lib -lreadline"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "x$READLINE_LINK" = "x" ] && [ $try_readline = "1" ]; then
|
||||
if test_code 'readline with -lncurses' \
|
||||
'stdio.h readline/readline.h readline/history.h' \
|
||||
"$readline_inc" "$readline_lib $ncurses_lib -lreadline -lncurses" \
|
||||
'add_history(readline("prompt"));'
|
||||
then
|
||||
add_def FEAT_READLINE
|
||||
READLINE_COMPILE="$readline_inc"
|
||||
READLINE_LINK="$readline_lib $ncurses_lib -lreadline -lncurses"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
MANDIR=${INSTALL_PREFIX}/man
|
||||
INFODIR=${INSTALL_PREFIX}/info
|
||||
HASH_OBJ="hash_intmd5.o"
|
||||
HASH_COMPILE=""
|
||||
HASH_LINK=""
|
||||
|
||||
if [ $try_nss = "1" ]; then
|
||||
test_cflags="`pkg-config --cflags nss`"
|
||||
test_link="`pkg-config --libs-only-L nss` -lfreebl3"
|
||||
if test_code 'NSS' 'nss.h hasht.h nsslowhash.h' \
|
||||
"$test_cflags" "$test_link" \
|
||||
'NSSLOWHASH_Begin(NSSLOWHASH_NewContext(NSSLOW_Init(), HASH_AlgSHA512));'
|
||||
then
|
||||
HASH_OBJ="hash_nss.o"
|
||||
HASH_COMPILE="$test_cflags"
|
||||
HASH_LINK="$test_link"
|
||||
add_def GENERATE_SHA1_KEY
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "x$HASH_LINK" = "x" ] && [ $try_tomcrypt = "1" ]; then
|
||||
if test_code 'tomcrypt' 'tomcrypt.h' '-I/usr/include/tomcrypt' '-ltomcrypt' \
|
||||
'hash_memory_multi(find_hash("md5"), NULL, NULL, NULL, 0, NULL, 0);'
|
||||
then
|
||||
HASH_OBJ="hash_tomcrypt.o"
|
||||
HASH_COMPILE="-I/usr/include/tomcrypt"
|
||||
HASH_LINK="-ltomcrypt"
|
||||
add_def GENERATE_SHA1_KEY
|
||||
fi
|
||||
fi
|
||||
|
||||
SYSCONFDIR=/etc
|
||||
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
|
||||
INFODIR=$SETINFODIR
|
||||
fi
|
||||
|
||||
MANDIR=${DATAROOTDIR}/man
|
||||
if [ "x$SETMANDIR" != "x" ]; then
|
||||
MANDIR=$SETMANDIR
|
||||
fi
|
||||
|
||||
sed -e "s%@EXTRA_OBJECTS@%${EXTRA_OBJECTS}%;\
|
||||
s%@CC@%${MYCC}%;\
|
||||
s%@CFLAGS@%${MYCFLAGS}%;\
|
||||
s%@CCWARNFLAGS@%${CCWARNFLAGS}%;\
|
||||
s%@LIBS@%${LIBS}%;\
|
||||
s%@EXTRA_LIBS@%${EXTRA_LIBS}%;\
|
||||
s%@SYSDEFS@%${SYSDEFS}%;\
|
||||
s%@EXTRA_DEFS@%${EXTRA_DEFS}%;\
|
||||
s%@EXTRA_CLI_LIBS@%${EXTRA_CLI_LIBS}%;\
|
||||
s%@READLINE_COMPILE@%${READLINE_COMPILE}%;\
|
||||
s%@READLINE_LINK@%${READLINE_LINK}%;\
|
||||
s%@INSTALL_PREFIX@%${INSTALL_PREFIX}%;\
|
||||
s%@MANDIR@%${MANDIR}%;\
|
||||
s%@INFODIR@%${INFODIR}%;"\
|
||||
< Makefile.in > Makefile
|
||||
DOCDIR=${DATAROOTDIR}/doc/chrony
|
||||
if [ "x$SETDOCDIR" != "x" ]; then
|
||||
DOCDIR=$SETDOCDIR
|
||||
fi
|
||||
|
||||
LOCALSTATEDIR=/var
|
||||
if [ "x$SETLOCALSTATEDIR" != "x" ]; then
|
||||
LOCALSTATEDIR=$SETLOCALSTATEDIR
|
||||
fi
|
||||
|
||||
CHRONYVARDIR=${LOCALSTATEDIR}/lib/chrony
|
||||
if [ "x$SETCHRONYVARDIR" != "x" ]; then
|
||||
CHRONYVARDIR=$SETCHRONYVARDIR
|
||||
fi
|
||||
|
||||
add_def DEFAULT_CONF_FILE "\"$SYSCONFDIR/chrony.conf\""
|
||||
add_def MAIL_PROGRAM "\"$mail_program\""
|
||||
|
||||
if [ -f version.txt ]; then
|
||||
add_def CHRONY_VERSION "\"`cat version.txt`\""
|
||||
else
|
||||
add_def CHRONY_VERSION "\"DEVELOPMENT\""
|
||||
fi
|
||||
|
||||
for f in Makefile chrony.conf.5 chrony.texi chronyc.1 chronyd.8
|
||||
do
|
||||
echo Creating $f
|
||||
sed -e "s%@EXTRA_OBJECTS@%${EXTRA_OBJECTS}%;\
|
||||
s%@CC@%${MYCC}%;\
|
||||
s%@CFLAGS@%${MYCFLAGS}%;\
|
||||
s%@CPPFLAGS@%${CPPFLAGS}%;\
|
||||
s%@LIBS@%${LIBS}%;\
|
||||
s%@LDFLAGS@%${MYLDFLAGS}%;\
|
||||
s%@EXTRA_LIBS@%${EXTRA_LIBS}%;\
|
||||
s%@EXTRA_CLI_LIBS@%${EXTRA_CLI_LIBS}%;\
|
||||
s%@READLINE_COMPILE@%${READLINE_COMPILE}%;\
|
||||
s%@READLINE_LINK@%${READLINE_LINK}%;\
|
||||
s%@HASH_OBJ@%${HASH_OBJ}%;\
|
||||
s%@HASH_LINK@%${HASH_LINK}%;\
|
||||
s%@HASH_COMPILE@%${HASH_COMPILE}%;\
|
||||
s%@SYSCONFDIR@%${SYSCONFDIR}%;\
|
||||
s%@BINDIR@%${BINDIR}%;\
|
||||
s%@SBINDIR@%${SBINDIR}%;\
|
||||
s%@DOCDIR@%${DOCDIR}%;\
|
||||
s%@MANDIR@%${MANDIR}%;\
|
||||
s%@INFODIR@%${INFODIR}%;\
|
||||
s%@LOCALSTATEDIR@%${LOCALSTATEDIR}%;\
|
||||
s%@CHRONYVARDIR@%${CHRONYVARDIR}%;"\
|
||||
< ${f}.in > $f
|
||||
done
|
||||
|
||||
# =======================================================================
|
||||
# vim:et:sw=2:ht=2:sts=2:fdm=marker:cms=#%s
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
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
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
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.
|
||||
|
||||
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
|
||||
modification follow.
|
||||
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
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
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
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
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
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
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
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.
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
<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
|
||||
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
|
||||
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
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.
|
||||
|
||||
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
|
||||
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'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
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
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
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.
|
||||
|
||||
@@ -14,7 +14,7 @@ my($copyrighttext) = <<'EOF';
|
||||
#
|
||||
# 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., 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
|
||||
EOF
|
||||
|
||||
|
||||
@@ -162,5 +162,5 @@ DNSchrony.pl is covered by the GPL
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# SEE COPYING FOR DETAILS
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
# 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
|
||||
# /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.
|
||||
#
|
||||
# Copyright 2002 Richard P. Curnow
|
||||
@@ -19,7 +18,7 @@
|
||||
#
|
||||
# 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.,
|
||||
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
#######################################################################
|
||||
@@ -41,21 +40,21 @@
|
||||
# more 'NTP servers'. You will probably find that your Internet Service
|
||||
# Provider or company have one or more NTP servers that you can specify.
|
||||
# Failing that, there are a lot of public NTP servers. There is a list
|
||||
# you can access at
|
||||
# http://www.eecis.udel.edu/~mills/ntp/servers.htm.
|
||||
# you can access at http://support.ntp.org/bin/view/Servers/WebHome or
|
||||
# you can use servers from the pool.ntp.org project.
|
||||
|
||||
! server ntp0.your-isp.com
|
||||
! server ntp1.your-isp.com
|
||||
! server ntp.public-server.org
|
||||
! server 0.pool.ntp.org iburst
|
||||
! server 1.pool.ntp.org iburst
|
||||
! server 2.pool.ntp.org iburst
|
||||
|
||||
# However, for dial-up use you probably want these instead. The word
|
||||
# 'offline' means that the server is not visible at boot time. Use
|
||||
# chronyc's 'online' command to tell chronyd that these servers have
|
||||
# become visible after you go on-line.
|
||||
|
||||
! server ntp0.your-isp.com offline
|
||||
! server ntp1.your-isp.com offline
|
||||
! server ntp.public-server.org offline
|
||||
! server 0.pool.ntp.org offline
|
||||
! server 1.pool.ntp.org offline
|
||||
! server 2.pool.ntp.org offline
|
||||
|
||||
# You may want to specify NTP 'peers' instead. If you run a network
|
||||
# with a lot of computers and want several computers running chrony to
|
||||
@@ -90,7 +89,7 @@
|
||||
# immediately so that it doesn't gain or lose any more time. You
|
||||
# generally want this, so it is uncommented.
|
||||
|
||||
driftfile /etc/chrony.drift
|
||||
driftfile /var/lib/chrony/drift
|
||||
|
||||
# If you want to use the program called chronyc to configure aspects of
|
||||
# chronyd's operation once it is running (e.g. tell it the Internet link
|
||||
@@ -123,7 +122,7 @@ commandkey 1
|
||||
# Enable these two options to use this.
|
||||
|
||||
! dumponexit
|
||||
! dumpdir /var/log/chrony
|
||||
! dumpdir /var/lib/chrony
|
||||
|
||||
# chronyd writes its process ID to a file. If you try to start a second
|
||||
# copy of chronyd, it will detect that the process named in the file is
|
||||
@@ -134,17 +133,16 @@ commandkey 1
|
||||
|
||||
#######################################################################
|
||||
### INITIAL CLOCK CORRECTION
|
||||
# This option is only useful if your NTP servers are visible at boot
|
||||
# time. This probably means you are on a LAN. If so, the following
|
||||
# option will choose the best-looking of the servers and correct the
|
||||
# system time to that. The value '10' means that if the error is less
|
||||
# This option is useful to quickly correct the clock on start if it's
|
||||
# off by a large amount. The value '10' means that if the error is less
|
||||
# than 10 seconds, it will be gradually removed by speeding up or
|
||||
# slowing down your computer's clock until it is correct. If the error
|
||||
# is above 10 seconds, an immediate time jump will be applied to correct
|
||||
# it. Some software can get upset if the system clock jumps (especially
|
||||
# backwards), so be careful!
|
||||
# it. The value '1' means the step is allowed only on the first update
|
||||
# of the clock. Some software can get upset if the system clock jumps
|
||||
# (especially backwards), so be careful!
|
||||
|
||||
! initstepslew 10 ntp0.your-company.com ntp1.your-company.com ntp2.your-company.com
|
||||
! makestep 10 1
|
||||
|
||||
#######################################################################
|
||||
### LOGGING
|
||||
@@ -157,8 +155,8 @@ commandkey 1
|
||||
! logdir /var/log/chrony
|
||||
! log measurements statistics tracking
|
||||
|
||||
If you have real time clock support enabled (see below), you might want
|
||||
this line instead:
|
||||
# If you have real time clock support enabled (see below), you might want
|
||||
# this line instead:
|
||||
|
||||
! log measurements statistics tracking rtc
|
||||
|
||||
@@ -209,6 +207,12 @@ this line instead:
|
||||
|
||||
! 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
|
||||
# Perhaps you want to know if chronyd suddenly detects any large error
|
||||
@@ -250,13 +254,6 @@ this line instead:
|
||||
# put into chronyc to allow you to modify chronyd's parameters. By
|
||||
# default all you can do is view information about chronyd's operation.
|
||||
|
||||
# Some people have reported that the need the following line to allow
|
||||
# chronyc to work even on the same machine. This should not be
|
||||
# necessary, and the problem is being investigated. You can leave this
|
||||
# line enabled, as it's benign otherwise.
|
||||
|
||||
cmdallow 127.0.0.1
|
||||
|
||||
#######################################################################
|
||||
### REAL TIME CLOCK
|
||||
# chronyd can characterise the system's real-time clock. This is the
|
||||
@@ -268,7 +265,7 @@ cmdallow 127.0.0.1
|
||||
# You need to have 'enhanced RTC support' compiled into your Linux
|
||||
# kernel. (Note, these options apply only to Linux.)
|
||||
|
||||
! rtcfile /etc/chrony.rtc
|
||||
! rtcfile /var/lib/chrony/rtc
|
||||
|
||||
# Your RTC can be set to keep Universal Coordinated Time (UTC) or local
|
||||
# time. (Local time means UTC +/- the effect of your timezone.) If you
|
||||
@@ -287,3 +284,21 @@ cmdallow 127.0.0.1
|
||||
! 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
|
||||
|
||||
46
examples/chrony.conf.example2
Normal file
46
examples/chrony.conf.example2
Normal file
@@ -0,0 +1,46 @@
|
||||
# Use public servers from the pool.ntp.org project.
|
||||
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
|
||||
server 0.pool.ntp.org iburst
|
||||
server 1.pool.ntp.org iburst
|
||||
server 2.pool.ntp.org iburst
|
||||
server 3.pool.ntp.org iburst
|
||||
|
||||
# Ignore stratum in source selection.
|
||||
stratumweight 0
|
||||
|
||||
# Record the rate at which the system clock gains/losses time.
|
||||
driftfile /var/lib/chrony/drift
|
||||
|
||||
# Enable kernel RTC synchronization.
|
||||
rtcsync
|
||||
|
||||
# In first three updates step the system clock instead of slew
|
||||
# if the adjustment is larger than 10 seconds.
|
||||
makestep 10 3
|
||||
|
||||
# Allow NTP client access from local network.
|
||||
#allow 192.168/16
|
||||
|
||||
# Listen for commands only on localhost.
|
||||
bindcmdaddress 127.0.0.1
|
||||
bindcmdaddress ::1
|
||||
|
||||
# Serve time even if not synchronized to any NTP server.
|
||||
#local stratum 10
|
||||
|
||||
keyfile /etc/chrony.keys
|
||||
|
||||
# Specify the key used as password for chronyc.
|
||||
commandkey 1
|
||||
|
||||
# Generate command key if missing.
|
||||
generatecommandkey
|
||||
|
||||
# Disable logging of client accesses.
|
||||
noclientlog
|
||||
|
||||
# Send a message to syslog if a clock adjustment is larger than 0.5 seconds.
|
||||
logchange 0.5
|
||||
|
||||
logdir /var/log/chrony
|
||||
#log measurements statistics tracking
|
||||
@@ -1,27 +1,29 @@
|
||||
#######################################################################
|
||||
# $Header: /cvs/src/chrony/examples/chrony.keys.example,v 1.1 2002/01/31 00:00:08 richard Exp $
|
||||
#
|
||||
# This is an example chrony keys file. You should copy it to /etc/chrony.keys
|
||||
# after editing it to set up the key(s) you want to use. In most situations,
|
||||
# you will require a single key (the 'commandkey') so that you can supply a
|
||||
# password to chronyc to enable you to modify chronyd's operation whilst it is
|
||||
# running.
|
||||
# after editing it to set up the key(s) you want to use. It should be readable
|
||||
# only by root or the user chronyd drops the root privileges to. In most
|
||||
# situations, you will require a single key (the 'commandkey') so that you can
|
||||
# supply a password to chronyc to enable you to modify chronyd's operation
|
||||
# whilst it is running.
|
||||
#
|
||||
# Copyright 2002 Richard P. Curnow
|
||||
#
|
||||
#######################################################################
|
||||
# A valid key line looks like this
|
||||
######################################################################
|
||||
|
||||
1 a_key
|
||||
# Examples of valid keys:
|
||||
|
||||
# It must consist of an integer, followed by whitespace, followed by a block of
|
||||
# text with no spaces in it. (You cannot put a space in a key). If you wanted
|
||||
# to use the above line as your commandkey (i.e. chronyc password), you would
|
||||
# put the following line into chrony.conf (remove the # from the start):
|
||||
#1 ALongAndRandomPassword
|
||||
#2 MD5 HEX:B028F91EA5C38D06C2E140B26C7F41EC
|
||||
#3 SHA1 HEX:1DC764E0791B11FA67EFC7ECBC4B0D73F68A070C
|
||||
|
||||
# commandkey 1
|
||||
# The keys should be random for maximum security. If you wanted to use a key
|
||||
# with ID 1 as your commandkey (i.e. chronyc password) you would put
|
||||
# "commandkey 1" into chrony.conf. If no commandkey is present in the keys
|
||||
# file and the generatecommandkey directive is specified in chrony.conf,
|
||||
# a random commandkey will be generated and added to the keys file
|
||||
# automatically on chronyd start.
|
||||
|
||||
# You might want to define more keys if you use the MD5 authentication facility
|
||||
# You might want to define more keys if you use the authentication facility
|
||||
# in the network time protocol to authenticate request/response packets between
|
||||
# trusted clients and servers.
|
||||
|
||||
|
||||
136
faq.txt
136
faq.txt
@@ -19,18 +19,12 @@
|
||||
<p>
|
||||
This is a set of questions and answers to common problems and issues.
|
||||
<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.
|
||||
|
||||
<hr>
|
||||
<p>
|
||||
The author can be reached by email
|
||||
<a href="mailto:rc@rc0.org.uk">
|
||||
</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)!
|
||||
The developers can be reached via the chrony-dev mailing list. See
|
||||
<a href="#question_1.4">question 1.4.</a> for details.
|
||||
<hr>
|
||||
|
||||
<br clear=all>
|
||||
@@ -38,39 +32,34 @@ mail reader can keep my mail sorted by topic)!
|
||||
S: Administrative issues
|
||||
|
||||
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?
|
||||
I am aware of packages for Debian, Mandrake and Redhat. I am not personally
|
||||
involved with how these are built or distributed.
|
||||
We are aware of packages for Debian, Fedora, Gentoo, Mandriva, Slackware,
|
||||
and Ubuntu. We are not involved with how these are built or distributed.
|
||||
|
||||
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?
|
||||
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
|
||||
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
|
||||
<a href="mailto:chrony-announce-subscribe@sunsite.dk">chrony-announce-subscribe@sunsite.dk</a> respectively.
|
||||
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-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
|
||||
developers' mailing list. You can subscribe by sending mail to
|
||||
<a href="mailto:chrony-dev-subscribe@sunsite.dk">chrony-dev-subscribe@sunsite.dk</a>.
|
||||
developers' mailing list. You can subscribe by sending mail with the
|
||||
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?
|
||||
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.
|
||||
|
||||
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
|
||||
Q: How does chrony compare to xntpd?
|
||||
If your computer is permenently connected, or connected for long periods (that
|
||||
@@ -79,7 +68,7 @@ support hardware reference clocks to your computer, then xntpd will work fine.
|
||||
Apart from not supporting hardware clocks, chrony will work fine too.
|
||||
|
||||
If your computer connects to the 'net for 5 minutes once a day (or something
|
||||
like that), or you turn your (Linux v2.0) computer off when you're not using
|
||||
like that), or you turn your Linux computer off when you're not using
|
||||
it, or you want to use NTP on an isolated network with no hardware clocks in
|
||||
sight, chrony will work much better for you.
|
||||
|
||||
@@ -107,56 +96,6 @@ at all, I found xntpd gave me no help with managing the local clock's
|
||||
gain/loss rate on the NTP master node (which I set from my watch). I
|
||||
added some automated support in chrony to deal with this.
|
||||
|
||||
S: Compilation issues
|
||||
Q:How do I apply source patches?
|
||||
Sometimes I release source patches rather than a full version when I need to
|
||||
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:
|
||||
|
||||
tar xzvf ../chrony-1.X.tar.gz
|
||||
cd chrony-1.X
|
||||
gunzip < ../../chrony-1.X-1.X.1.gz | patch -p1
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
Q:Can I compile chrony with an ANSI-C compiler that is not GCC v2.x?
|
||||
I have had reports that chrony can be compiled with GCC v1.42, by using the
|
||||
following trick when running make
|
||||
|
||||
make CC='gcc -D__FUNCTION__=\"function_not_available\"'
|
||||
|
||||
(this gets around the lack of a __FUNCTION__ macro in GCC v1.)
|
||||
|
||||
The same trick may be enough to allow other compilers to be used.
|
||||
|
||||
Q: I get errors like 'client.c:44: readline/readline.h: file not found'
|
||||
Read the section about 'readline' in the INSTALL file or in chrony.txt. You
|
||||
may need to disable readline support (e.g. if you haven't got readline
|
||||
installed at all, or just don't want it), or specify the location of the
|
||||
readline files (e.g. if you've installed them in a non-standard place).
|
||||
|
||||
Q: I have RedHat 7.3 and can't compile rtc_linux.c (error in spinlock.h)
|
||||
The following solution has been found for this. Enter the following 3 commands
|
||||
(as root):
|
||||
|
||||
cd /usr/include/
|
||||
mv linux linux.rh
|
||||
ln -s /usr/src/linux/include/linux ./linux
|
||||
|
||||
The problem seems to be that RedHat provide their own kernel header files in
|
||||
/usr/include/linux. Besides differing from those used by your current kernel,
|
||||
if you compiled it yourself, they also seem to have been changed in a way that
|
||||
causes a problem compiling chrony. Chrony compiles fine with standard kernel
|
||||
header files.
|
||||
|
||||
There have also been reports that just replacing the file
|
||||
/usr/src/linux/spinlock.h by the equivalent file from a vanilla kernel source
|
||||
tree is sufficient to fix the problem.
|
||||
|
||||
Note : from version 1.21 onwards, this problem no longer exists. The kernel
|
||||
header files are no longer included.
|
||||
|
||||
S: Selection of NTP servers
|
||||
Q: I have several computers on a LAN. Should I make one the master, or make them all clients of an external server?
|
||||
I think the best configuration is to make one computer the master, with the
|
||||
@@ -212,21 +151,6 @@ Do you have a 'local stratum X' directive in the chrony.conf file? If X is
|
||||
lower than the stratum of the server you're trying to use, this situation will
|
||||
arise. You should always make X quite high (e.g. 10) in this directive.
|
||||
|
||||
S: Issues with chronyd
|
||||
|
||||
Q: chronyd crashes after a syslog message "adjtimex failed for set frequency"
|
||||
The usual cause is that the kernel is running with a different value of 'HZ'
|
||||
(the timer interrupt rate) than the value that was found in the kernel header
|
||||
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
|
||||
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
|
||||
|
||||
Q: I keep getting the error '510 No command access from this host --- Reply not authenticated'.
|
||||
@@ -285,14 +209,6 @@ For the real time clock support to work, you need the following three things:
|
||||
* enhanced RTC support compiled into the kernel
|
||||
* an 'rtcfile' directive in your chrony.conf file.
|
||||
|
||||
S: Problems with isolated networks.
|
||||
|
||||
Q: When I use the 'settime' command, chronyd crashes.
|
||||
If you enter times that are too far away from the real time, chronyd will
|
||||
think the system clock runs fast or slow by an excessive amount. The required
|
||||
compensation factor will be outside the bounds for the adjtimex() system call.
|
||||
chronyd will crash when it tries to apply such an excessive adjustment.
|
||||
|
||||
S: Microsoft Windows
|
||||
|
||||
Q: Does chrony support Windows?
|
||||
@@ -303,13 +219,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.
|
||||
|
||||
Q: Are there any plans to support Windows?
|
||||
I have no personal plans to do this. I have neither the time nor the
|
||||
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
|
||||
We have no plans to do this. Anyone is welcome to pick this work up and
|
||||
contribute it back to the project.
|
||||
|
||||
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
|
||||
- NetTime (nettime.sourceforge.net)
|
||||
|
||||
@@ -345,12 +259,10 @@ useful to avoid this situation.
|
||||
|
||||
S: Development
|
||||
|
||||
Q: Can I get the source via CVS from anywhere?
|
||||
Yes. See <a href="http://chrony.sunsite.dk/cvs.php">http://chrony.sunsite.dk/cvs.php</a> for information. Currently there is
|
||||
only anonymous read-only access. I keep the master copy on my own PC, which is
|
||||
more convenient for me because I don't have to connect to the Internet to do
|
||||
CVS operations on the files. So for now, there is no read-write access for
|
||||
other developers. Please email me your patches + documentation instead.
|
||||
Q: Can I get the source via git from anywhere?
|
||||
Yes. See the Git link at <a
|
||||
href="http://chrony.tuxfamily.org/">http://chrony.tuxfamily.org</a> for
|
||||
information.
|
||||
|
||||
S: Linux-specific issues
|
||||
|
||||
@@ -359,7 +271,7 @@ The program needs to see the definitions of structures used to interact with
|
||||
the real time clock (via /dev/rtc) and with the adjtimex() system call. Sadly
|
||||
this has led to a number of compilation problems with newer kernels which have
|
||||
been increasingly hard to fix in a way that makes the code compilable on all
|
||||
Linux kernel versions (from 2.0 up anyway, I doubt 1.x still works.) Hopefully
|
||||
Linux kernel versions. Hopefully
|
||||
the situation will not deteriorate further with future kernel versions.
|
||||
|
||||
Q: I get "Could not open /dev/rtc, Device or resource busy" in my syslog file.
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
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., 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 */
|
||||
|
||||
|
||||
41
hash.h
Normal file
41
hash.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Miroslav Lichvar 2012
|
||||
*
|
||||
* 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 crypto hashing.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef GOT_HASH_H
|
||||
#define GOT_HASH_H
|
||||
|
||||
/* length of hash values produced by SHA512 */
|
||||
#define MAX_HASH_LENGTH 64
|
||||
|
||||
extern int HSH_GetHashId(const char *name);
|
||||
|
||||
extern unsigned int HSH_Hash(int id,
|
||||
const unsigned char *in1, unsigned int in1_len,
|
||||
const unsigned char *in2, unsigned int in2_len,
|
||||
unsigned char *out, unsigned int out_len);
|
||||
|
||||
#endif
|
||||
64
hash_intmd5.c
Normal file
64
hash_intmd5.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Miroslav Lichvar 2012
|
||||
*
|
||||
* 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 crypto hashing using internal MD5 implementation.
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "sysincl.h"
|
||||
#include "hash.h"
|
||||
#include "memory.h"
|
||||
|
||||
#include "md5.c"
|
||||
|
||||
static MD5_CTX ctx;
|
||||
|
||||
int
|
||||
HSH_GetHashId(const char *name)
|
||||
{
|
||||
/* only MD5 is supported */
|
||||
if (strcmp(name, "MD5"))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
HSH_Hash(int id, const unsigned char *in1, unsigned int in1_len,
|
||||
const unsigned char *in2, unsigned int in2_len,
|
||||
unsigned char *out, unsigned int out_len)
|
||||
{
|
||||
if (out_len < 16)
|
||||
return 0;
|
||||
|
||||
MD5Init(&ctx);
|
||||
MD5Update(&ctx, in1, in1_len);
|
||||
if (in2)
|
||||
MD5Update(&ctx, in2, in2_len);
|
||||
MD5Final(&ctx);
|
||||
|
||||
memcpy(out, ctx.digest, 16);
|
||||
|
||||
return 16;
|
||||
}
|
||||
89
hash_nss.c
Normal file
89
hash_nss.c
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Miroslav Lichvar 2012
|
||||
*
|
||||
* 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 crypto hashing using NSSLOWHASH API of the NSS library.
|
||||
|
||||
*/
|
||||
|
||||
#include <nss.h>
|
||||
#include <hasht.h>
|
||||
#include <nsslowhash.h>
|
||||
|
||||
/* #include "config.h" */
|
||||
#include "hash.h"
|
||||
|
||||
static NSSLOWInitContext *ictx;
|
||||
|
||||
struct hash {
|
||||
HASH_HashType type;
|
||||
const char *name;
|
||||
NSSLOWHASHContext *context;
|
||||
};
|
||||
|
||||
static struct hash hashes[] = {
|
||||
{ HASH_AlgMD5, "MD5", NULL },
|
||||
{ HASH_AlgSHA1, "SHA1", NULL },
|
||||
{ HASH_AlgSHA256, "SHA256", NULL },
|
||||
{ HASH_AlgSHA384, "SHA384", NULL },
|
||||
{ HASH_AlgSHA512, "SHA512", NULL },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
|
||||
int
|
||||
HSH_GetHashId(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; hashes[i].name; i++) {
|
||||
if (!strcmp(name, hashes[i].name))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hashes[i].name)
|
||||
return -1; /* not found */
|
||||
|
||||
if (!ictx && !(ictx = NSSLOW_Init()))
|
||||
return -1; /* couldn't init NSS */
|
||||
|
||||
if (!hashes[i].context &&
|
||||
!(hashes[i].context = NSSLOWHASH_NewContext(ictx, hashes[i].type)))
|
||||
return -1; /* couldn't init hash */
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
HSH_Hash(int id, const unsigned char *in1, unsigned int in1_len,
|
||||
const unsigned char *in2, unsigned int in2_len,
|
||||
unsigned char *out, unsigned int out_len)
|
||||
{
|
||||
unsigned int ret;
|
||||
|
||||
NSSLOWHASH_Begin(hashes[id].context);
|
||||
NSSLOWHASH_Update(hashes[id].context, in1, in1_len);
|
||||
if (in2)
|
||||
NSSLOWHASH_Update(hashes[id].context, in2, in2_len);
|
||||
NSSLOWHASH_End(hashes[id].context, out, &ret, out_len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
116
hash_tomcrypt.c
Normal file
116
hash_tomcrypt.c
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Miroslav Lichvar 2012
|
||||
*
|
||||
* 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 crypto hashing using tomcrypt library.
|
||||
|
||||
*/
|
||||
|
||||
#include <tomcrypt.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "hash.h"
|
||||
|
||||
struct hash {
|
||||
const char *name;
|
||||
const char *int_name;
|
||||
const struct ltc_hash_descriptor *desc;
|
||||
};
|
||||
|
||||
static const struct hash hashes[] = {
|
||||
{ "MD5", "md5", &md5_desc },
|
||||
#ifdef LTC_RIPEMD128
|
||||
{ "RMD128", "rmd128", &rmd128_desc },
|
||||
#endif
|
||||
#ifdef LTC_RIPEMD160
|
||||
{ "RMD160", "rmd160", &rmd160_desc },
|
||||
#endif
|
||||
#ifdef LTC_RIPEMD256
|
||||
{ "RMD256", "rmd256", &rmd256_desc },
|
||||
#endif
|
||||
#ifdef LTC_RIPEMD320
|
||||
{ "RMD320", "rmd320", &rmd320_desc },
|
||||
#endif
|
||||
#ifdef LTC_SHA1
|
||||
{ "SHA1", "sha1", &sha1_desc },
|
||||
#endif
|
||||
#ifdef LTC_SHA256
|
||||
{ "SHA256", "sha256", &sha256_desc },
|
||||
#endif
|
||||
#ifdef LTC_SHA384
|
||||
{ "SHA384", "sha384", &sha384_desc },
|
||||
#endif
|
||||
#ifdef LTC_SHA512
|
||||
{ "SHA512", "sha512", &sha512_desc },
|
||||
#endif
|
||||
#ifdef LTC_TIGER
|
||||
{ "TIGER", "tiger", &tiger_desc },
|
||||
#endif
|
||||
#ifdef LTC_WHIRLPOOL
|
||||
{ "WHIRLPOOL", "whirlpool", &whirlpool_desc },
|
||||
#endif
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
int
|
||||
HSH_GetHashId(const char *name)
|
||||
{
|
||||
int i, h;
|
||||
|
||||
for (i = 0; hashes[i].name; i++) {
|
||||
if (!strcmp(name, hashes[i].name))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hashes[i].name)
|
||||
return -1; /* not found */
|
||||
|
||||
h = find_hash(hashes[i].int_name);
|
||||
if (h >= 0)
|
||||
return h; /* already registered */
|
||||
|
||||
/* register and try again */
|
||||
register_hash(hashes[i].desc);
|
||||
|
||||
return find_hash(hashes[i].int_name);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
HSH_Hash(int id, const unsigned char *in1, unsigned int in1_len,
|
||||
const unsigned char *in2, unsigned int in2_len,
|
||||
unsigned char *out, unsigned int out_len)
|
||||
{
|
||||
unsigned long len;
|
||||
int r;
|
||||
|
||||
len = out_len;
|
||||
if (in2)
|
||||
r = hash_memory_multi(id, out, &len,
|
||||
in1, (unsigned long)in1_len, in2, (unsigned long)in2_len, NULL, 0);
|
||||
else
|
||||
r = hash_memory(id, in1, in1_len, out, &len);
|
||||
|
||||
if (r != CRYPT_OK)
|
||||
return 0;
|
||||
|
||||
return len;
|
||||
}
|
||||
74
io_linux.h
74
io_linux.h
@@ -1,74 +0,0 @@
|
||||
/* Taken from <asm-$foo/ioctl.h> in the Linux kernel sources.
|
||||
* The ioctl.h file is pretty similar from one architecture to another.
|
||||
* */
|
||||
#ifndef IO_LINUX_H
|
||||
#define IO_LINUX_H
|
||||
|
||||
/* Hmm. These constants vary a bit between systems. */
|
||||
/* (__sh__ includes both sh and sh64) */
|
||||
#if defined(__i386__) || defined(__sh__) || defined(__arm__)||defined(__x86_64__)
|
||||
#define CHRONY_IOC_NRBITS 8
|
||||
#define CHRONY_IOC_TYPEBITS 8
|
||||
#define CHRONY_IOC_SIZEBITS 14
|
||||
#define CHRONY_IOC_DIRBITS 2
|
||||
|
||||
#define CHRONY_IOC_NONE 0U
|
||||
#define CHRONY_IOC_WRITE 1U
|
||||
#define CHRONY_IOC_READ 2U
|
||||
|
||||
#elif defined(__alpha__) || defined(__sparc__) || defined(__ppc__) || defined(__ppc64__) || defined(__sparc64__)
|
||||
#define CHRONY_IOC_NRBITS 8
|
||||
#define CHRONY_IOC_TYPEBITS 8
|
||||
#define CHRONY_IOC_SIZEBITS 13
|
||||
#define CHRONY_IOC_DIRBITS 2
|
||||
|
||||
#define CHRONY_IOC_NONE 1U
|
||||
#define CHRONY_IOC_READ 2U
|
||||
#define CHRONY_IOC_WRITE 4U
|
||||
|
||||
#elif defined(__mips__) || defined(__mips32__)
|
||||
#define CHRONY_IOC_NRBITS 8
|
||||
#define CHRONY_IOC_TYPEBITS 8
|
||||
#define CHRONY_IOC_SIZEBITS 13
|
||||
#define CHRONY_IOC_DIRBITS 3
|
||||
#define CHRONY_IOC_NONE 1U
|
||||
#define CHRONY_IOC_READ 2U
|
||||
#define CHRONY_IOC_WRITE 4U
|
||||
|
||||
#else
|
||||
#error "I don't know the values of the _IOC_* constants for your architecture"
|
||||
#endif
|
||||
|
||||
#define CHRONY_IOC_NRMASK ((1 << CHRONY_IOC_NRBITS)-1)
|
||||
#define CHRONY_IOC_TYPEMASK ((1 << CHRONY_IOC_TYPEBITS)-1)
|
||||
#define CHRONY_IOC_SIZEMASK ((1 << CHRONY_IOC_SIZEBITS)-1)
|
||||
#define CHRONY_IOC_DIRMASK ((1 << CHRONY_IOC_DIRBITS)-1)
|
||||
|
||||
#define CHRONY_IOC_NRSHIFT 0
|
||||
#define CHRONY_IOC_TYPESHIFT (CHRONY_IOC_NRSHIFT+CHRONY_IOC_NRBITS)
|
||||
#define CHRONY_IOC_SIZESHIFT (CHRONY_IOC_TYPESHIFT+CHRONY_IOC_TYPEBITS)
|
||||
#define CHRONY_IOC_DIRSHIFT (CHRONY_IOC_SIZESHIFT+CHRONY_IOC_SIZEBITS)
|
||||
|
||||
#define CHRONY_IOC(dir,type,nr,size) \
|
||||
(((dir) << CHRONY_IOC_DIRSHIFT) | \
|
||||
((type) << CHRONY_IOC_TYPESHIFT) | \
|
||||
((nr) << CHRONY_IOC_NRSHIFT) | \
|
||||
((size) << CHRONY_IOC_SIZESHIFT))
|
||||
|
||||
/* used to create numbers */
|
||||
#define CHRONY_IO(type,nr) CHRONY_IOC(CHRONY_IOC_NONE,(type),(nr),0)
|
||||
#define CHRONY_IOR(type,nr,size) CHRONY_IOC(CHRONY_IOC_READ,(type),(nr),sizeof(size))
|
||||
#define CHRONY_IOW(type,nr,size) CHRONY_IOC(CHRONY_IOC_WRITE,(type),(nr),sizeof(size))
|
||||
#define CHRONY_IOWR(type,nr,size) CHRONY_IOC(CHRONY_IOC_READ|CHRONY_IOC_WRITE,(type),(nr),sizeof(size))
|
||||
|
||||
#define RTC_UIE_ON CHRONY_IO('p', 0x03) /* Update int. enable on */
|
||||
#define RTC_UIE_OFF CHRONY_IO('p', 0x04) /* ... off */
|
||||
|
||||
#define RTC_RD_TIME CHRONY_IOR('p', 0x09, struct rtc_time) /* Read RTC time */
|
||||
#define RTC_SET_TIME CHRONY_IOW('p', 0x0a, struct rtc_time) /* Set RTC time */
|
||||
|
||||
/* From mc146818.h */
|
||||
#define RTC_UIE 0x10 /* update-finished interrupt enable */
|
||||
|
||||
#endif
|
||||
|
||||
326
keys.c
326
keys.c
@@ -1,12 +1,9 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/keys.c,v 1.12 2003/09/22 21:22:30 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Miroslav Lichvar 2012-2013
|
||||
*
|
||||
* 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
|
||||
@@ -19,7 +16,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -29,18 +26,25 @@
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "keys.h"
|
||||
#include "cmdparse.h"
|
||||
#include "conf.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "local.h"
|
||||
#include "logging.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned long id;
|
||||
char *val;
|
||||
int len;
|
||||
int hash_id;
|
||||
int auth_delay;
|
||||
} Key;
|
||||
|
||||
#define MAX_KEYS 256
|
||||
@@ -49,13 +53,71 @@ static int n_keys;
|
||||
static Key keys[MAX_KEYS];
|
||||
|
||||
static int command_key_valid;
|
||||
static int command_key_pos;
|
||||
static int command_key_id;
|
||||
static int cache_valid;
|
||||
static unsigned long cache_key_id;
|
||||
static int cache_key_pos;
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
generate_key(unsigned long key_id)
|
||||
{
|
||||
#ifdef GENERATE_SHA1_KEY
|
||||
unsigned char key[20];
|
||||
const char *hashname = "SHA1";
|
||||
#else
|
||||
unsigned char key[16];
|
||||
const char *hashname = "MD5";
|
||||
#endif
|
||||
const char *key_file, *rand_dev = "/dev/urandom";
|
||||
FILE *f;
|
||||
struct stat st;
|
||||
int i;
|
||||
|
||||
key_file = CNF_GetKeysFile();
|
||||
|
||||
if (!key_file)
|
||||
return 0;
|
||||
|
||||
f = fopen(rand_dev, "r");
|
||||
if (!f || fread(key, sizeof (key), 1, f) != 1) {
|
||||
if (f)
|
||||
fclose(f);
|
||||
LOG_FATAL(LOGF_Keys, "Could not read %s", rand_dev);
|
||||
return 0;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
f = fopen(key_file, "a");
|
||||
if (!f) {
|
||||
LOG_FATAL(LOGF_Keys, "Could not open keyfile %s for writing", key_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Make sure the keyfile is not world-readable */
|
||||
if (stat(key_file, &st) || chmod(key_file, st.st_mode & 0770)) {
|
||||
fclose(f);
|
||||
LOG_FATAL(LOGF_Keys, "Could not change permissions of keyfile %s", key_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(f, "\n%lu %s HEX:", key_id, hashname);
|
||||
for (i = 0; i < sizeof (key); i++)
|
||||
fprintf(f, "%02hhX", key[i]);
|
||||
fprintf(f, "\n");
|
||||
fclose(f);
|
||||
|
||||
/* Erase the key from stack */
|
||||
memset(key, 0, sizeof (key));
|
||||
|
||||
LOG(LOGS_INFO, LOGF_Keys, "Generated key %lu", key_id);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
KEY_Initialise(void)
|
||||
{
|
||||
@@ -63,7 +125,11 @@ KEY_Initialise(void)
|
||||
command_key_valid = 0;
|
||||
cache_valid = 0;
|
||||
KEY_Reload();
|
||||
return;
|
||||
|
||||
if (CNF_GetGenerateCommandKey() && !KEY_KeyKnown(KEY_GetCommandKey())) {
|
||||
if (generate_key(KEY_GetCommandKey()))
|
||||
KEY_Reload();
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -71,8 +137,37 @@ KEY_Initialise(void)
|
||||
void
|
||||
KEY_Finalise(void)
|
||||
{
|
||||
/* Nothing to do */
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
determine_hash_delay(int key_id)
|
||||
{
|
||||
NTP_Packet pkt;
|
||||
struct timeval before, after;
|
||||
unsigned long usecs, min_usecs=0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
LCL_ReadRawTime(&before);
|
||||
KEY_GenerateAuth(key_id, (unsigned char *)&pkt, NTP_NORMAL_PACKET_SIZE,
|
||||
(unsigned char *)&pkt.auth_data, sizeof (pkt.auth_data));
|
||||
LCL_ReadRawTime(&after);
|
||||
|
||||
usecs = (after.tv_sec - before.tv_sec) * 1000000 + (after.tv_usec - before.tv_usec);
|
||||
|
||||
if (i == 0 || usecs < min_usecs) {
|
||||
min_usecs = usecs;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_Keys, "authentication delay for key %lu: %d useconds", key_id, min_usecs);
|
||||
#endif
|
||||
|
||||
/* Add on a bit extra to allow for copying, conversions etc */
|
||||
return min_usecs + (min_usecs >> 4);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -97,61 +192,84 @@ compare_keys_by_id(const void *a, const void *b)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
|
||||
#define KEYLEN 2047
|
||||
#define SKEYLEN "2047"
|
||||
|
||||
void
|
||||
KEY_Reload(void)
|
||||
{
|
||||
int i, len1;
|
||||
char *key_file;
|
||||
int i, line_number;
|
||||
FILE *in;
|
||||
unsigned long key_id;
|
||||
char line[KEYLEN+1], keyval[KEYLEN+1];
|
||||
char line[2048], *keyval, *key_file;
|
||||
const char *hashname;
|
||||
|
||||
for (i=0; i<n_keys; i++) {
|
||||
Free(keys[i].val);
|
||||
}
|
||||
|
||||
n_keys = 0;
|
||||
|
||||
key_file = CNF_GetKeysFile();
|
||||
|
||||
if (key_file) {
|
||||
in = fopen(key_file, "r");
|
||||
if (in) {
|
||||
while (fgets(line, sizeof(line), in)) {
|
||||
len1 = strlen(line) - 1;
|
||||
|
||||
/* Guard against removing last character of the line
|
||||
* if the last line of the file is missing an end-of-line */
|
||||
if (line[len1] == '\n') {
|
||||
line[len1] = '\0';
|
||||
}
|
||||
|
||||
if (sscanf(line, "%lu%" SKEYLEN "s", &key_id, keyval) == 2) {
|
||||
keys[n_keys].id = key_id;
|
||||
keys[n_keys].len = strlen(keyval);
|
||||
keys[n_keys].val = MallocArray(char, 1 + keys[n_keys].len);
|
||||
strcpy(keys[n_keys].val, keyval);
|
||||
n_keys++;
|
||||
}
|
||||
}
|
||||
fclose(in);
|
||||
|
||||
/* Sort keys into order. Note, if there's a duplicate, it is
|
||||
arbitrary which one we use later - the user should have been
|
||||
more careful! */
|
||||
qsort((void *) keys, n_keys, sizeof(Key), compare_keys_by_id);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
command_key_valid = 0;
|
||||
cache_valid = 0;
|
||||
|
||||
return;
|
||||
key_file = CNF_GetKeysFile();
|
||||
line_number = 0;
|
||||
|
||||
if (!key_file)
|
||||
return;
|
||||
|
||||
in = fopen(key_file, "r");
|
||||
if (!in) {
|
||||
LOG(LOGS_WARN, LOGF_Keys, "Could not open keyfile %s", key_file);
|
||||
return;
|
||||
}
|
||||
|
||||
while (fgets(line, sizeof (line), in)) {
|
||||
line_number++;
|
||||
|
||||
CPS_NormalizeLine(line);
|
||||
if (!*line)
|
||||
continue;
|
||||
|
||||
if (!CPS_ParseKey(line, &key_id, &hashname, &keyval)) {
|
||||
LOG(LOGS_WARN, LOGF_Keys, "Could not parse key at line %d in file %s", line_number, key_file);
|
||||
continue;
|
||||
}
|
||||
|
||||
keys[n_keys].hash_id = HSH_GetHashId(hashname);
|
||||
if (keys[n_keys].hash_id < 0) {
|
||||
LOG(LOGS_WARN, LOGF_Keys, "Unknown hash function in key %lu", key_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
keys[n_keys].len = UTI_DecodePasswordFromText(keyval);
|
||||
if (!keys[n_keys].len) {
|
||||
LOG(LOGS_WARN, LOGF_Keys, "Could not decode password in key %lu", key_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
keys[n_keys].id = key_id;
|
||||
keys[n_keys].val = MallocArray(char, keys[n_keys].len);
|
||||
memcpy(keys[n_keys].val, keyval, keys[n_keys].len);
|
||||
n_keys++;
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
|
||||
/* Sort keys into order. Note, if there's a duplicate, it is
|
||||
arbitrary which one we use later - the user should have been
|
||||
more careful! */
|
||||
qsort((void *) keys, n_keys, sizeof(Key), compare_keys_by_id);
|
||||
|
||||
/* Check for duplicates */
|
||||
for (i = 1; i < n_keys; i++) {
|
||||
if (keys[i - 1].id == keys[i].id) {
|
||||
LOG(LOGS_WARN, LOGF_Keys, "Detected duplicate key %lu", key_id);
|
||||
}
|
||||
}
|
||||
|
||||
/* Erase any passwords from stack */
|
||||
memset(line, 0, sizeof (line));
|
||||
|
||||
for (i=0; i<n_keys; i++) {
|
||||
keys[i].auth_delay = determine_hash_delay(keys[i].id);
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -174,30 +292,8 @@ lookup_key(unsigned long id)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
KEY_CommandKey(char **key, int *len)
|
||||
{
|
||||
unsigned long command_key_id;
|
||||
|
||||
if (!command_key_valid) {
|
||||
command_key_id = CNF_GetCommandKey();
|
||||
command_key_pos = lookup_key(command_key_id);
|
||||
command_key_valid = 1;
|
||||
}
|
||||
|
||||
if (command_key_pos >= 0) {
|
||||
*key = keys[command_key_pos].val;
|
||||
*len = keys[command_key_pos].len;
|
||||
} else {
|
||||
*key = "";
|
||||
*len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
KEY_GetKey(unsigned long key_id, char **key, int *len)
|
||||
static int
|
||||
get_key_pos(unsigned long key_id)
|
||||
{
|
||||
if (!cache_valid || key_id != cache_key_id) {
|
||||
cache_valid = 1;
|
||||
@@ -205,15 +301,19 @@ KEY_GetKey(unsigned long key_id, char **key, int *len)
|
||||
cache_key_id = key_id;
|
||||
}
|
||||
|
||||
if (cache_key_pos >= 0) {
|
||||
*key = keys[cache_key_pos].val;
|
||||
*len = keys[cache_key_pos].len;
|
||||
return 1;
|
||||
} else {
|
||||
*key = "";
|
||||
*len = 0;
|
||||
return 0;
|
||||
return cache_key_pos;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
unsigned long
|
||||
KEY_GetCommandKey(void)
|
||||
{
|
||||
if (!command_key_valid) {
|
||||
command_key_id = CNF_GetCommandKey();
|
||||
}
|
||||
|
||||
return command_key_id;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -241,3 +341,57 @@ KEY_KeyKnown(unsigned long key_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
KEY_GetAuthDelay(unsigned long key_id)
|
||||
{
|
||||
int key_pos;
|
||||
|
||||
key_pos = get_key_pos(key_id);
|
||||
|
||||
if (key_pos < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return keys[key_pos].auth_delay;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
KEY_GenerateAuth(unsigned long key_id, const unsigned char *data, int data_len,
|
||||
unsigned char *auth, int auth_len)
|
||||
{
|
||||
int key_pos;
|
||||
|
||||
key_pos = get_key_pos(key_id);
|
||||
|
||||
if (key_pos < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return UTI_GenerateNTPAuth(keys[key_pos].hash_id,
|
||||
(unsigned char *)keys[key_pos].val, keys[key_pos].len,
|
||||
data, data_len, auth, auth_len);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
KEY_CheckAuth(unsigned long key_id, const unsigned char *data, int data_len,
|
||||
const unsigned char *auth, int auth_len)
|
||||
{
|
||||
int key_pos;
|
||||
|
||||
key_pos = get_key_pos(key_id);
|
||||
|
||||
if (key_pos < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return UTI_CheckNTPAuth(keys[key_pos].hash_id,
|
||||
(unsigned char *)keys[key_pos].val, keys[key_pos].len,
|
||||
data, data_len, auth, auth_len);
|
||||
}
|
||||
|
||||
14
keys.h
14
keys.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/keys.h,v 1.8 2002/02/28 23:27:10 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -36,9 +32,15 @@ extern void KEY_Finalise(void);
|
||||
|
||||
extern void KEY_Reload(void);
|
||||
|
||||
extern void KEY_CommandKey(char **key, int *len);
|
||||
extern unsigned long KEY_GetCommandKey(void);
|
||||
|
||||
extern int KEY_GetKey(unsigned long key_id, char **key, int *len);
|
||||
extern int KEY_KeyKnown(unsigned long key_id);
|
||||
extern int KEY_GetAuthDelay(unsigned long key_id);
|
||||
|
||||
extern int KEY_GenerateAuth(unsigned long key_id, const unsigned char *data,
|
||||
int data_len, unsigned char *auth, int auth_len);
|
||||
extern int KEY_CheckAuth(unsigned long key_id, const unsigned char *data,
|
||||
int data_len, const unsigned char *auth, int auth_len);
|
||||
|
||||
#endif /* GOT_KEYS_H */
|
||||
|
||||
274
local.c
274
local.c
@@ -1,12 +1,9 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/local.c,v 1.21 2003/09/22 21:22:30 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Miroslav Lichvar 2011
|
||||
*
|
||||
* 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
|
||||
@@ -19,7 +16,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -31,9 +28,11 @@
|
||||
They interface with the system specific driver files in sys_*.c
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "conf.h"
|
||||
#include "local.h"
|
||||
#include "localp.h"
|
||||
#include "memory.h"
|
||||
@@ -45,6 +44,9 @@
|
||||
/* Variable to store the current frequency, in ppm */
|
||||
static double current_freq_ppm;
|
||||
|
||||
/* Temperature compensation, in ppm */
|
||||
static double temp_comp_ppm;
|
||||
|
||||
/* ================================================== */
|
||||
/* Store the system dependent drivers */
|
||||
|
||||
@@ -53,7 +55,7 @@ static lcl_SetFrequencyDriver drv_set_freq;
|
||||
static lcl_AccrueOffsetDriver drv_accrue_offset;
|
||||
static lcl_ApplyStepOffsetDriver drv_apply_step_offset;
|
||||
static lcl_OffsetCorrectionDriver drv_offset_convert;
|
||||
static lcl_ImmediateStepDriver drv_immediate_step;
|
||||
static lcl_SetLeapDriver drv_set_leap;
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
@@ -88,6 +90,8 @@ static DispersionNotifyListEntry dispersion_notify_list;
|
||||
static int precision_log;
|
||||
static double precision_quantum;
|
||||
|
||||
static double max_clock_error;
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
/* Define the number of increments of the system clock that we want
|
||||
@@ -100,17 +104,15 @@ static double precision_quantum;
|
||||
static void
|
||||
calculate_sys_precision(void)
|
||||
{
|
||||
struct timeval tv, old_tv, first_tv;
|
||||
struct timezone tz;
|
||||
struct timeval tv, old_tv;
|
||||
int dusec, best_dusec;
|
||||
int iters;
|
||||
|
||||
gettimeofday(&old_tv, &tz);
|
||||
first_tv = old_tv;
|
||||
gettimeofday(&old_tv, NULL);
|
||||
best_dusec = 1000000; /* Assume we must be better than a second */
|
||||
iters = 0;
|
||||
do {
|
||||
gettimeofday(&tv, &tz);
|
||||
gettimeofday(&tv, NULL);
|
||||
dusec = 1000000*(tv.tv_sec - old_tv.tv_sec) + (tv.tv_usec - old_tv.tv_usec);
|
||||
old_tv = tv;
|
||||
if (dusec > 0) {
|
||||
@@ -120,18 +122,15 @@ calculate_sys_precision(void)
|
||||
iters++;
|
||||
}
|
||||
} while (iters < NITERS);
|
||||
if (!(best_dusec > 0)) {
|
||||
CROAK("best_dusec should be positive");
|
||||
}
|
||||
|
||||
assert(best_dusec > 0);
|
||||
|
||||
precision_quantum = best_dusec * 1.0e-6;
|
||||
precision_log = 0;
|
||||
while (best_dusec < 500000) {
|
||||
precision_log--;
|
||||
best_dusec *= 2;
|
||||
}
|
||||
|
||||
precision_quantum = 1.0 / (double)(1<<(-precision_log));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -153,8 +152,11 @@ LCL_Initialise(void)
|
||||
|
||||
/* This ought to be set from the system driver layer */
|
||||
current_freq_ppm = 0.0;
|
||||
temp_comp_ppm = 0.0;
|
||||
|
||||
calculate_sys_precision();
|
||||
|
||||
max_clock_error = CNF_GetMaxClockError() * 1e-6;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -162,7 +164,6 @@ LCL_Initialise(void)
|
||||
void
|
||||
LCL_Finalise(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -185,6 +186,14 @@ LCL_GetSysPrecisionAsQuantum(void)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
double
|
||||
LCL_GetMaxClockError(void)
|
||||
{
|
||||
return max_clock_error;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
LCL_AddParameterChangeHandler(LCL_ParameterChangeHandler handler, void *anything)
|
||||
{
|
||||
@@ -193,7 +202,7 @@ LCL_AddParameterChangeHandler(LCL_ParameterChangeHandler handler, void *anything
|
||||
/* Check that the handler is not already registered */
|
||||
for (ptr = change_list.next; ptr != &change_list; ptr = ptr->next) {
|
||||
if (!(ptr->handler != handler || ptr->anything != anything)) {
|
||||
CROAK("a handler is already registered");
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,14 +216,11 @@ LCL_AddParameterChangeHandler(LCL_ParameterChangeHandler handler, void *anything
|
||||
new_entry->prev = change_list.prev;
|
||||
change_list.prev->next = new_entry;
|
||||
change_list.prev = new_entry;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
/* Remove a handler */
|
||||
extern
|
||||
void LCL_RemoveParameterChangeHandler(LCL_ParameterChangeHandler handler, void *anything)
|
||||
{
|
||||
|
||||
@@ -231,17 +237,13 @@ void LCL_RemoveParameterChangeHandler(LCL_ParameterChangeHandler handler, void *
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
CROAK("did not find a matching handler");
|
||||
}
|
||||
assert(ok);
|
||||
|
||||
/* Unlink entry from the list */
|
||||
ptr->next->prev = ptr->prev;
|
||||
ptr->prev->next = ptr->next;
|
||||
|
||||
free(ptr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -254,7 +256,7 @@ LCL_AddDispersionNotifyHandler(LCL_DispersionNotifyHandler handler, void *anythi
|
||||
/* Check that the handler is not already registered */
|
||||
for (ptr = dispersion_notify_list.next; ptr != &dispersion_notify_list; ptr = ptr->next) {
|
||||
if (!(ptr->handler != handler || ptr->anything != anything)) {
|
||||
CROAK("a handler is already registered");
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,8 +270,6 @@ LCL_AddDispersionNotifyHandler(LCL_DispersionNotifyHandler handler, void *anythi
|
||||
new_entry->prev = dispersion_notify_list.prev;
|
||||
dispersion_notify_list.prev->next = new_entry;
|
||||
dispersion_notify_list.prev = new_entry;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -292,17 +292,13 @@ void LCL_RemoveDispersionNotifyHandler(LCL_DispersionNotifyHandler handler, void
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
CROAK("no matching handler found");
|
||||
}
|
||||
assert(ok);
|
||||
|
||||
/* Unlink entry from the list */
|
||||
ptr->next->prev = ptr->prev;
|
||||
ptr->prev->next = ptr->next;
|
||||
|
||||
free(ptr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -312,13 +308,9 @@ void LCL_RemoveDispersionNotifyHandler(LCL_DispersionNotifyHandler handler, void
|
||||
void
|
||||
LCL_ReadRawTime(struct timeval *result)
|
||||
{
|
||||
struct timezone tz;
|
||||
|
||||
if (!(gettimeofday(result, &tz) >= 0)) {
|
||||
CROAK("Could not get time of day");
|
||||
if (gettimeofday(result, NULL) < 0) {
|
||||
LOG_FATAL(LOGF_Local, "gettimeofday() failed");
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -327,39 +319,47 @@ void
|
||||
LCL_ReadCookedTime(struct timeval *result, double *err)
|
||||
{
|
||||
struct timeval raw;
|
||||
double correction;
|
||||
|
||||
LCL_ReadRawTime(&raw);
|
||||
|
||||
/* For now, cheat and set the error to zero in all cases.
|
||||
*/
|
||||
|
||||
*err = 0.0;
|
||||
|
||||
/* Call system specific driver to get correction */
|
||||
(*drv_offset_convert)(&raw, &correction);
|
||||
UTI_AddDoubleToTimeval(&raw, correction, result);
|
||||
|
||||
return;
|
||||
LCL_CookTime(&raw, result, err);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
double
|
||||
LCL_GetOffsetCorrection(struct timeval *raw)
|
||||
void
|
||||
LCL_CookTime(struct timeval *raw, struct timeval *cooked, double *err)
|
||||
{
|
||||
double correction;
|
||||
(*drv_offset_convert)(raw, &correction);
|
||||
return correction;
|
||||
|
||||
LCL_GetOffsetCorrection(raw, &correction, err);
|
||||
UTI_AddDoubleToTimeval(raw, correction, cooked);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
/* This is just a simple passthrough of the system specific routine */
|
||||
|
||||
void
|
||||
LCL_GetOffsetCorrection(struct timeval *raw, double *correction, double *err)
|
||||
{
|
||||
/* Call system specific driver to get correction */
|
||||
(*drv_offset_convert)(raw, correction, err);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
/* Return current frequency */
|
||||
|
||||
double
|
||||
LCL_ReadAbsoluteFrequency(void)
|
||||
{
|
||||
return (*drv_read_freq)();
|
||||
double freq;
|
||||
|
||||
freq = current_freq_ppm;
|
||||
|
||||
/* Undo temperature compensation */
|
||||
if (temp_comp_ppm != 0.0) {
|
||||
freq = (freq + temp_comp_ppm) / (1.0 - 1.0e-6 * temp_comp_ppm);
|
||||
}
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -371,22 +371,25 @@ LCL_SetAbsoluteFrequency(double afreq_ppm)
|
||||
{
|
||||
ChangeListEntry *ptr;
|
||||
struct timeval raw, cooked;
|
||||
double correction;
|
||||
double dfreq;
|
||||
|
||||
/* Apply temperature compensation */
|
||||
if (temp_comp_ppm != 0.0) {
|
||||
afreq_ppm = afreq_ppm * (1.0 - 1.0e-6 * temp_comp_ppm) - temp_comp_ppm;
|
||||
}
|
||||
|
||||
/* Call the system-specific driver for setting the frequency */
|
||||
|
||||
(*drv_set_freq)(afreq_ppm);
|
||||
afreq_ppm = (*drv_set_freq)(afreq_ppm);
|
||||
|
||||
dfreq = 1.0e-6 * (afreq_ppm - current_freq_ppm) / (1.0 - 1.0e-6 * current_freq_ppm);
|
||||
dfreq = (afreq_ppm - current_freq_ppm) / (1.0e6 + current_freq_ppm);
|
||||
|
||||
LCL_ReadRawTime(&raw);
|
||||
(drv_offset_convert)(&raw, &correction);
|
||||
UTI_AddDoubleToTimeval(&raw, correction, &cooked);
|
||||
LCL_CookTime(&raw, &cooked, NULL);
|
||||
|
||||
/* Dispatch to all handlers */
|
||||
for (ptr = change_list.next; ptr != &change_list; ptr = ptr->next) {
|
||||
(ptr->handler)(&raw, &cooked, dfreq, afreq_ppm, 0.0, 0, ptr->anything);
|
||||
(ptr->handler)(&raw, &cooked, dfreq, 0.0, 0, ptr->anything);
|
||||
}
|
||||
|
||||
current_freq_ppm = afreq_ppm;
|
||||
@@ -400,25 +403,26 @@ LCL_AccumulateDeltaFrequency(double dfreq)
|
||||
{
|
||||
ChangeListEntry *ptr;
|
||||
struct timeval raw, cooked;
|
||||
double correction;
|
||||
double old_freq_ppm;
|
||||
|
||||
old_freq_ppm = current_freq_ppm;
|
||||
|
||||
/* Work out new absolute frequency. Note that absolute frequencies
|
||||
are handled in units of ppm, whereas the 'dfreq' argument is in
|
||||
terms of the gradient of the (offset) v (local time) function. */
|
||||
|
||||
current_freq_ppm = (1.0 - dfreq) * current_freq_ppm +
|
||||
(1.0e6 * dfreq);
|
||||
current_freq_ppm = (1.0 + dfreq) * current_freq_ppm + 1.0e6 * dfreq;
|
||||
|
||||
/* Call the system-specific driver for setting the frequency */
|
||||
(*drv_set_freq)(current_freq_ppm);
|
||||
current_freq_ppm = (*drv_set_freq)(current_freq_ppm);
|
||||
dfreq = (current_freq_ppm - old_freq_ppm) / (1.0e6 + old_freq_ppm);
|
||||
|
||||
LCL_ReadRawTime(&raw);
|
||||
(drv_offset_convert)(&raw, &correction);
|
||||
UTI_AddDoubleToTimeval(&raw, correction, &cooked);
|
||||
LCL_CookTime(&raw, &cooked, NULL);
|
||||
|
||||
/* Dispatch to all handlers */
|
||||
for (ptr = change_list.next; ptr != &change_list; ptr = ptr->next) {
|
||||
(ptr->handler)(&raw, &cooked, dfreq, current_freq_ppm, 0.0, 0, ptr->anything);
|
||||
(ptr->handler)(&raw, &cooked, dfreq, 0.0, 0, ptr->anything);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -426,24 +430,22 @@ LCL_AccumulateDeltaFrequency(double dfreq)
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
LCL_AccumulateOffset(double offset)
|
||||
LCL_AccumulateOffset(double offset, double corr_rate)
|
||||
{
|
||||
ChangeListEntry *ptr;
|
||||
struct timeval raw, cooked;
|
||||
double correction;
|
||||
|
||||
/* In this case, the cooked time to be passed to the notify clients
|
||||
has to be the cooked time BEFORE the change was made */
|
||||
|
||||
LCL_ReadRawTime(&raw);
|
||||
(drv_offset_convert)(&raw, &correction);
|
||||
UTI_AddDoubleToTimeval(&raw, correction, &cooked);
|
||||
LCL_CookTime(&raw, &cooked, NULL);
|
||||
|
||||
(*drv_accrue_offset)(offset);
|
||||
(*drv_accrue_offset)(offset, corr_rate);
|
||||
|
||||
/* Dispatch to all handlers */
|
||||
for (ptr = change_list.next; ptr != &change_list; ptr = ptr->next) {
|
||||
(ptr->handler)(&raw, &cooked, 0.0, current_freq_ppm, offset, 0, ptr->anything);
|
||||
(ptr->handler)(&raw, &cooked, 0.0, offset, 0, ptr->anything);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -455,20 +457,18 @@ LCL_ApplyStepOffset(double offset)
|
||||
{
|
||||
ChangeListEntry *ptr;
|
||||
struct timeval raw, cooked;
|
||||
double correction;
|
||||
|
||||
/* In this case, the cooked time to be passed to the notify clients
|
||||
has to be the cooked time BEFORE the change was made */
|
||||
|
||||
LCL_ReadRawTime(&raw);
|
||||
(drv_offset_convert)(&raw, &correction);
|
||||
UTI_AddDoubleToTimeval(&raw, correction, &cooked);
|
||||
LCL_CookTime(&raw, &cooked, NULL);
|
||||
|
||||
(*drv_apply_step_offset)(offset);
|
||||
|
||||
/* Dispatch to all handlers */
|
||||
for (ptr = change_list.next; ptr != &change_list; ptr = ptr->next) {
|
||||
(ptr->handler)(&raw, &cooked, 0.0, current_freq_ppm, offset, 1, ptr->anything);
|
||||
(ptr->handler)(&raw, &cooked, 0.0, offset, 1, ptr->anything);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -476,26 +476,39 @@ LCL_ApplyStepOffset(double offset)
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
LCL_AccumulateFrequencyAndOffset(double dfreq, double doffset)
|
||||
LCL_NotifyExternalTimeStep(struct timeval *raw, struct timeval *cooked,
|
||||
double offset, double dispersion)
|
||||
{
|
||||
ChangeListEntry *ptr;
|
||||
|
||||
/* Dispatch to all handlers */
|
||||
for (ptr = change_list.next; ptr != &change_list; ptr = ptr->next) {
|
||||
(ptr->handler)(raw, cooked, 0.0, offset, 1, ptr->anything);
|
||||
}
|
||||
|
||||
lcl_InvokeDispersionNotifyHandlers(dispersion);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
LCL_AccumulateFrequencyAndOffset(double dfreq, double doffset, double corr_rate)
|
||||
{
|
||||
ChangeListEntry *ptr;
|
||||
struct timeval raw, cooked;
|
||||
double correction;
|
||||
double old_freq_ppm;
|
||||
|
||||
LCL_ReadRawTime(&raw);
|
||||
(drv_offset_convert)(&raw, &correction);
|
||||
/* Due to modifying the offset, this has to be the cooked time prior
|
||||
to the change we are about to make */
|
||||
UTI_AddDoubleToTimeval(&raw, correction, &cooked);
|
||||
LCL_CookTime(&raw, &cooked, NULL);
|
||||
|
||||
old_freq_ppm = current_freq_ppm;
|
||||
|
||||
/* Work out new absolute frequency. Note that absolute frequencies
|
||||
are handled in units of ppm, whereas the 'dfreq' argument is in
|
||||
terms of the gradient of the (offset) v (local time) function. */
|
||||
current_freq_ppm = (1.0 - dfreq) * old_freq_ppm +
|
||||
(1.0e6 * dfreq);
|
||||
current_freq_ppm = (1.0 + dfreq) * old_freq_ppm + 1.0e6 * dfreq;
|
||||
|
||||
#ifdef TRACEON
|
||||
LOG(LOGS_INFO, LOGF_Local, "old_freq=%.3fppm new_freq=%.3fppm offset=%.6fsec",
|
||||
@@ -503,12 +516,14 @@ LCL_AccumulateFrequencyAndOffset(double dfreq, double doffset)
|
||||
#endif
|
||||
|
||||
/* Call the system-specific driver for setting the frequency */
|
||||
(*drv_set_freq)(current_freq_ppm);
|
||||
(*drv_accrue_offset)(doffset);
|
||||
current_freq_ppm = (*drv_set_freq)(current_freq_ppm);
|
||||
dfreq = (current_freq_ppm - old_freq_ppm) / (1.0e6 + old_freq_ppm);
|
||||
|
||||
(*drv_accrue_offset)(doffset, corr_rate);
|
||||
|
||||
/* Dispatch to all handlers */
|
||||
for (ptr = change_list.next; ptr != &change_list; ptr = ptr->next) {
|
||||
(ptr->handler)(&raw, &cooked, dfreq, current_freq_ppm, doffset, 0, ptr->anything);
|
||||
(ptr->handler)(&raw, &cooked, dfreq, doffset, 0, ptr->anything);
|
||||
}
|
||||
|
||||
|
||||
@@ -535,40 +550,83 @@ lcl_RegisterSystemDrivers(lcl_ReadFrequencyDriver read_freq,
|
||||
lcl_AccrueOffsetDriver accrue_offset,
|
||||
lcl_ApplyStepOffsetDriver apply_step_offset,
|
||||
lcl_OffsetCorrectionDriver offset_convert,
|
||||
lcl_ImmediateStepDriver immediate_step)
|
||||
lcl_SetLeapDriver set_leap)
|
||||
{
|
||||
drv_read_freq = read_freq;
|
||||
drv_set_freq = set_freq;
|
||||
drv_accrue_offset = accrue_offset;
|
||||
drv_apply_step_offset = apply_step_offset;
|
||||
drv_offset_convert = offset_convert;
|
||||
drv_immediate_step = immediate_step;
|
||||
drv_set_leap = set_leap;
|
||||
|
||||
current_freq_ppm = (*drv_read_freq)();
|
||||
|
||||
#ifdef TRACEON
|
||||
LOG(LOGS_INFO, LOGF_Local, "Local freq=%.3fppm", current_freq_ppm);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
/* Look at the current difference between the system time and the NTP
|
||||
time, and make a step to cancel it. */
|
||||
time, and make a step to cancel it if it's larger than the threshold. */
|
||||
|
||||
int
|
||||
LCL_MakeStep(void)
|
||||
LCL_MakeStep(double threshold)
|
||||
{
|
||||
if (drv_immediate_step) {
|
||||
(drv_immediate_step)();
|
||||
#ifdef TRACEON
|
||||
LOG(LOGS_INFO, LOGF_Local, "Made step to system time to apply remaining slew");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
struct timeval raw;
|
||||
double correction;
|
||||
|
||||
return 0;
|
||||
LCL_ReadRawTime(&raw);
|
||||
LCL_GetOffsetCorrection(&raw, &correction, NULL);
|
||||
|
||||
if (fabs(correction) <= threshold)
|
||||
return 0;
|
||||
|
||||
/* Cancel remaining slew and make the step */
|
||||
LCL_AccumulateOffset(correction, 0.0);
|
||||
LCL_ApplyStepOffset(-correction);
|
||||
|
||||
LOG(LOGS_WARN, LOGF_Local, "System clock was stepped by %.3f seconds", correction);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
LCL_SetLeap(int leap)
|
||||
{
|
||||
if (drv_set_leap) {
|
||||
(drv_set_leap)(leap);
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
double
|
||||
LCL_SetTempComp(double comp)
|
||||
{
|
||||
double uncomp_freq_ppm;
|
||||
|
||||
if (temp_comp_ppm == comp)
|
||||
return comp;
|
||||
|
||||
/* Undo previous compensation */
|
||||
current_freq_ppm = (current_freq_ppm + temp_comp_ppm) /
|
||||
(1.0 - 1.0e-6 * temp_comp_ppm);
|
||||
|
||||
uncomp_freq_ppm = current_freq_ppm;
|
||||
|
||||
/* Apply new compensation */
|
||||
current_freq_ppm = current_freq_ppm * (1.0 - 1.0e-6 * comp) - comp;
|
||||
|
||||
/* Call the system-specific driver for setting the frequency */
|
||||
current_freq_ppm = (*drv_set_freq)(current_freq_ppm);
|
||||
|
||||
temp_comp_ppm = (uncomp_freq_ppm - current_freq_ppm) /
|
||||
(1.0e-6 * uncomp_freq_ppm + 1.0);
|
||||
|
||||
return temp_comp_ppm;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
52
local.h
52
local.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/local.h,v 1.16 2002/02/28 23:27:10 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -50,11 +46,13 @@ extern void LCL_ReadRawTime(struct timeval *);
|
||||
|
||||
extern void LCL_ReadCookedTime(struct timeval *t, double *err);
|
||||
|
||||
/* Read the current offset between the system clock and true time
|
||||
(i.e. 'cooked' - 'raw') (in seconds). Only intended for use in
|
||||
status reporting, really. */
|
||||
/* Convert raw time to cooked. */
|
||||
extern void LCL_CookTime(struct timeval *raw, struct timeval *cooked, double *err);
|
||||
|
||||
extern double LCL_GetOffsetCorrection(struct timeval *raw);
|
||||
/* Read the current offset between the system clock and true time
|
||||
(i.e. 'cooked' - 'raw') (in seconds). */
|
||||
|
||||
extern void LCL_GetOffsetCorrection(struct timeval *raw, double *correction, double *err);
|
||||
|
||||
/* Type of routines that may be invoked as callbacks when there is a
|
||||
change to the frequency or offset.
|
||||
@@ -66,10 +64,6 @@ extern double LCL_GetOffsetCorrection(struct timeval *raw);
|
||||
dfreq : delta frequency relative to previous value (in terms of
|
||||
seconds gained by system clock per unit system clock time)
|
||||
|
||||
afreq : absolute frequency relative to uncompensated system (in
|
||||
terms of ppm seconds gained by system clock per unit of the
|
||||
uncalibrated system clock)
|
||||
|
||||
doffset : delta offset applied (positive => make local system fast
|
||||
by that amount, negative => make it slow by that amount)
|
||||
|
||||
@@ -81,7 +75,7 @@ extern double LCL_GetOffsetCorrection(struct timeval *raw);
|
||||
|
||||
typedef void (*LCL_ParameterChangeHandler)
|
||||
(struct timeval *raw, struct timeval *cooked,
|
||||
double dfreq, double afreq_ppm,
|
||||
double dfreq,
|
||||
double doffset, int is_step_change,
|
||||
void *anything
|
||||
);
|
||||
@@ -144,9 +138,10 @@ extern void LCL_AccumulateDeltaFrequency(double dfreq);
|
||||
/* Routine to apply an offset (in seconds) to the local clock. The
|
||||
argument should be positive to move the clock backwards (i.e. the
|
||||
local clock is currently fast of true time), or negative to move it
|
||||
forwards (i.e. it is currently slow of true time). */
|
||||
forwards (i.e. it is currently slow of true time). Provided is also
|
||||
a suggested correction rate (correction time * offset). */
|
||||
|
||||
extern void LCL_AccumulateOffset(double offset);
|
||||
extern void LCL_AccumulateOffset(double offset, double corr_rate);
|
||||
|
||||
/* Routine to apply an immediate offset by doing a sudden step if
|
||||
possible. (Intended for use after an initial estimate of offset has
|
||||
@@ -157,9 +152,14 @@ extern void LCL_AccumulateOffset(double offset);
|
||||
|
||||
extern void LCL_ApplyStepOffset(double offset);
|
||||
|
||||
/* Routine to invoke notify handlers on an unexpected time jump
|
||||
in system clock */
|
||||
extern void LCL_NotifyExternalTimeStep(struct timeval *raw, struct timeval *cooked,
|
||||
double offset, double dispersion);
|
||||
|
||||
/* Perform the combination of modifying the frequency and applying
|
||||
a slew, in one easy step */
|
||||
extern void LCL_AccumulateFrequencyAndOffset(double dfreq, double doffset);
|
||||
extern void LCL_AccumulateFrequencyAndOffset(double dfreq, double doffset, double corr_rate);
|
||||
|
||||
/* Routine to read the system precision as a log to base 2 value. */
|
||||
extern int LCL_GetSysPrecisionAsLog(void);
|
||||
@@ -167,6 +167,10 @@ extern int LCL_GetSysPrecisionAsLog(void);
|
||||
/* Routine to read the system precision in terms of the actual time step */
|
||||
extern double LCL_GetSysPrecisionAsQuantum(void);
|
||||
|
||||
/* Routine to read the maximum frequency error of the local clock. This
|
||||
is a frequency stability, not an absolute error. */
|
||||
extern double LCL_GetMaxClockError(void);
|
||||
|
||||
/* Routine to initialise the module (to be called once at program
|
||||
start-up) */
|
||||
|
||||
@@ -179,6 +183,18 @@ extern void LCL_Finalise(void);
|
||||
/* Routine to convert the outstanding system clock error to a step and
|
||||
apply it, e.g. if the system clock has ended up an hour wrong due
|
||||
to a timezone problem. */
|
||||
extern int LCL_MakeStep(void);
|
||||
extern int LCL_MakeStep(double threshold);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Routine to set a frequency correction (in ppm) that should be applied
|
||||
to local clock to compensate for temperature changes. A positive
|
||||
argument means that the clock frequency should be increased. Return the
|
||||
actual compensation (may be different from the requested compensation
|
||||
due to clamping or rounding). */
|
||||
extern double LCL_SetTempComp(double comp);
|
||||
|
||||
#endif /* GOT_LOCAL_H */
|
||||
|
||||
25
localp.h
25
localp.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/localp.h,v 1.9 2002/02/28 23:27:10 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -40,12 +36,14 @@ typedef double (*lcl_ReadFrequencyDriver)(void);
|
||||
|
||||
/* System driver to set the current local frequency, in ppm relative
|
||||
to nominal. A positive value indicates that the local clock runs
|
||||
fast when uncompensated. */
|
||||
typedef void (*lcl_SetFrequencyDriver)(double freq_ppm);
|
||||
fast when uncompensated. Return actual frequency (may be different
|
||||
from the requested frequency due to clamping or rounding). */
|
||||
typedef double (*lcl_SetFrequencyDriver)(double freq_ppm);
|
||||
|
||||
/* System driver to accrue an offset. A positive argument means slew
|
||||
the clock forwards. */
|
||||
typedef void (*lcl_AccrueOffsetDriver)(double offset);
|
||||
the clock forwards. The suggested correction rate of time to correct the
|
||||
offset is given in 'corr_rate'. */
|
||||
typedef void (*lcl_AccrueOffsetDriver)(double offset, double corr_rate);
|
||||
|
||||
/* System driver to apply a step offset. A positive argument means step
|
||||
the clock forwards. */
|
||||
@@ -54,11 +52,10 @@ typedef void (*lcl_ApplyStepOffsetDriver)(double offset);
|
||||
/* System driver to convert a raw time to an adjusted (cooked) time.
|
||||
The number of seconds returned in 'corr' have to be added to the
|
||||
raw time to get the corrected time */
|
||||
typedef void (*lcl_OffsetCorrectionDriver)(struct timeval *raw, double *corr);
|
||||
typedef void (*lcl_OffsetCorrectionDriver)(struct timeval *raw, double *corr, double *err);
|
||||
|
||||
/* System driver to stop slewing the current offset and to apply is
|
||||
as an immediate step instead */
|
||||
typedef void (*lcl_ImmediateStepDriver)(void);
|
||||
/* System driver to schedule leap second */
|
||||
typedef void (*lcl_SetLeapDriver)(int leap);
|
||||
|
||||
extern void lcl_InvokeDispersionNotifyHandlers(double dispersion);
|
||||
|
||||
@@ -68,6 +65,6 @@ lcl_RegisterSystemDrivers(lcl_ReadFrequencyDriver read_freq,
|
||||
lcl_AccrueOffsetDriver accrue_offset,
|
||||
lcl_ApplyStepOffsetDriver apply_step_offset,
|
||||
lcl_OffsetCorrectionDriver offset_convert,
|
||||
lcl_ImmediateStepDriver immediate_step_driver);
|
||||
lcl_SetLeapDriver set_leap);
|
||||
|
||||
#endif /* GOT_LOCALP_H */
|
||||
|
||||
228
logging.c
228
logging.c
@@ -1,12 +1,9 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/logging.c,v 1.15 2003/09/22 21:22:30 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Miroslav Lichvar 2011-2012
|
||||
*
|
||||
* 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
|
||||
@@ -19,7 +16,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -28,22 +25,43 @@
|
||||
Module to handle logging of diagnostic information
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "main.h"
|
||||
#include "conf.h"
|
||||
#include "logging.h"
|
||||
#include "version.h"
|
||||
#include "mkdirpp.h"
|
||||
#include "util.h"
|
||||
|
||||
/* ================================================== */
|
||||
/* Flag indicating we have initialised */
|
||||
static int initialised = 0;
|
||||
|
||||
static int is_detached = 0;
|
||||
static int system_log = 0;
|
||||
|
||||
static int parent_fd = 0;
|
||||
|
||||
static time_t last_limited = 0;
|
||||
|
||||
#ifdef WINNT
|
||||
static FILE *logfile;
|
||||
#endif
|
||||
|
||||
struct LogFile {
|
||||
const char *name;
|
||||
const char *banner;
|
||||
FILE *file;
|
||||
unsigned long writes;
|
||||
};
|
||||
|
||||
static int n_filelogs = 0;
|
||||
|
||||
/* Increase this when adding a new logfile */
|
||||
#define MAX_FILELOGS 6
|
||||
|
||||
static struct LogFile logfiles[MAX_FILELOGS];
|
||||
|
||||
/* ================================================== */
|
||||
/* Init function */
|
||||
|
||||
@@ -55,8 +73,6 @@ LOG_Initialise(void)
|
||||
#ifdef WINNT
|
||||
logfile = fopen("./chronyd.err", "a");
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -70,13 +86,14 @@ LOG_Finalise(void)
|
||||
fclose(logfile);
|
||||
}
|
||||
#else
|
||||
if (is_detached) {
|
||||
if (system_log) {
|
||||
closelog();
|
||||
}
|
||||
#endif
|
||||
|
||||
LOG_CycleLogFiles();
|
||||
|
||||
initialised = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -94,7 +111,7 @@ LOG_Line_Function(LOG_Severity severity, LOG_Facility facility, const char *form
|
||||
fprintf(logfile, "%s\n", buf);
|
||||
}
|
||||
#else
|
||||
if (is_detached) {
|
||||
if (system_log) {
|
||||
switch (severity) {
|
||||
case LOGS_INFO:
|
||||
syslog(LOG_INFO, "%s", buf);
|
||||
@@ -111,7 +128,6 @@ LOG_Line_Function(LOG_Severity severity, LOG_Facility facility, const char *form
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -130,16 +146,18 @@ LOG_Fatal_Function(LOG_Facility facility, const char *format, ...)
|
||||
fprintf(logfile, "Fatal error : %s\n", buf);
|
||||
}
|
||||
#else
|
||||
if (is_detached) {
|
||||
if (system_log) {
|
||||
syslog(LOG_CRIT, "Fatal error : %s", buf);
|
||||
} else {
|
||||
fprintf(stderr, "Fatal error : %s\n", buf);
|
||||
}
|
||||
if (parent_fd) {
|
||||
if (write(parent_fd, buf, strlen(buf) + 1) < 0)
|
||||
; /* Not much we can do here */
|
||||
}
|
||||
#endif
|
||||
|
||||
MAI_CleanupAndExit();
|
||||
|
||||
return;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -152,7 +170,7 @@ LOG_Position(const char *filename, int line_number, const char *function_name)
|
||||
time_t t;
|
||||
struct tm stm;
|
||||
char buf[64];
|
||||
if (!is_detached) {
|
||||
if (!system_log) {
|
||||
/* Don't clutter up syslog with internal debugging info */
|
||||
time(&t);
|
||||
stm = *gmtime(&t);
|
||||
@@ -160,57 +178,145 @@ LOG_Position(const char *filename, int line_number, const char *function_name)
|
||||
fprintf(stderr, "%s:%d:(%s)[%s] ", filename, line_number, function_name, buf);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
LOG_GoDaemon(void)
|
||||
LOG_OpenSystemLog(void)
|
||||
{
|
||||
#ifdef WINNT
|
||||
|
||||
|
||||
#else
|
||||
|
||||
int pid, fd;
|
||||
|
||||
/* Does this preserve existing signal handlers? */
|
||||
pid = fork();
|
||||
|
||||
if (pid < 0) {
|
||||
LOG(LOGS_ERR, LOGF_Logging, "Could not detach, fork failed : %s", strerror(errno));
|
||||
} else if (pid > 0) {
|
||||
exit(0); /* In the 'grandparent' */
|
||||
} else {
|
||||
|
||||
setsid();
|
||||
|
||||
/* Do 2nd fork, as-per recommended practice for launching daemons. */
|
||||
pid = fork();
|
||||
|
||||
if (pid < 0) {
|
||||
LOG(LOGS_ERR, LOGF_Logging, "Could not detach, fork failed : %s", strerror(errno));
|
||||
} else if (pid > 0) {
|
||||
exit(0); /* In the 'parent' */
|
||||
} else {
|
||||
/* In the child we want to leave running as the daemon */
|
||||
|
||||
/* Don't keep stdin/out/err from before. */
|
||||
for (fd=0; fd<1024; fd++) {
|
||||
close(fd);
|
||||
}
|
||||
|
||||
is_detached = 1;
|
||||
|
||||
openlog("chronyd", LOG_PID, LOG_DAEMON);
|
||||
|
||||
LOG(LOGS_INFO, LOGF_Logging, "chronyd version %s starting", PROGRAM_VERSION_STRING);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
system_log = 1;
|
||||
openlog("chronyd", LOG_PID, LOG_DAEMON);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
LOG_SetParentFd(int fd)
|
||||
{
|
||||
parent_fd = fd;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
LOG_CloseParentFd()
|
||||
{
|
||||
if (parent_fd > 0)
|
||||
close(parent_fd);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
LOG_RateLimited(void)
|
||||
{
|
||||
time_t now;
|
||||
|
||||
now = time(NULL);
|
||||
|
||||
if (last_limited + 10 > now && last_limited <= now)
|
||||
return 1;
|
||||
|
||||
last_limited = now;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
LOG_FileID
|
||||
LOG_FileOpen(const char *name, const char *banner)
|
||||
{
|
||||
assert(n_filelogs < MAX_FILELOGS);
|
||||
|
||||
logfiles[n_filelogs].name = name;
|
||||
logfiles[n_filelogs].banner = banner;
|
||||
logfiles[n_filelogs].file = NULL;
|
||||
logfiles[n_filelogs].writes = 0;
|
||||
|
||||
return n_filelogs++;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
LOG_FileWrite(LOG_FileID id, const char *format, ...)
|
||||
{
|
||||
va_list other_args;
|
||||
int banner;
|
||||
|
||||
if (id < 0 || id >= n_filelogs || !logfiles[id].name)
|
||||
return;
|
||||
|
||||
if (!logfiles[id].file) {
|
||||
char filename[512];
|
||||
|
||||
if (snprintf(filename, sizeof(filename), "%s/%s.log",
|
||||
CNF_GetLogDir(), logfiles[id].name) >= sizeof(filename) ||
|
||||
!(logfiles[id].file = fopen(filename, "a"))) {
|
||||
LOG(LOGS_WARN, LOGF_Refclock, "Couldn't open logfile %s for update", filename);
|
||||
logfiles[id].name = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Close on exec */
|
||||
UTI_FdSetCloexec(fileno(logfiles[id].file));
|
||||
}
|
||||
|
||||
banner = CNF_GetLogBanner();
|
||||
if (banner && logfiles[id].writes++ % banner == 0) {
|
||||
char bannerline[256];
|
||||
int i, bannerlen;
|
||||
|
||||
bannerlen = strlen(logfiles[id].banner);
|
||||
|
||||
for (i = 0; i < bannerlen; i++)
|
||||
bannerline[i] = '=';
|
||||
bannerline[i] = '\0';
|
||||
|
||||
fprintf(logfiles[id].file, "%s\n", bannerline);
|
||||
fprintf(logfiles[id].file, "%s\n", logfiles[id].banner);
|
||||
fprintf(logfiles[id].file, "%s\n", bannerline);
|
||||
}
|
||||
|
||||
va_start(other_args, format);
|
||||
vfprintf(logfiles[id].file, format, other_args);
|
||||
va_end(other_args);
|
||||
fprintf(logfiles[id].file, "\n");
|
||||
|
||||
fflush(logfiles[id].file);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
LOG_CreateLogFileDir(void)
|
||||
{
|
||||
const char *logdir;
|
||||
|
||||
logdir = CNF_GetLogDir();
|
||||
|
||||
if (!mkdir_and_parents(logdir)) {
|
||||
LOG(LOGS_ERR, LOGF_Logging, "Could not create directory %s", logdir);
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
LOG_CycleLogFiles(void)
|
||||
{
|
||||
LOG_FileID i;
|
||||
|
||||
for (i = 0; i < n_filelogs; i++) {
|
||||
if (logfiles[i].file)
|
||||
fclose(logfiles[i].file);
|
||||
logfiles[i].file = NULL;
|
||||
logfiles[i].writes = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
35
logging.h
35
logging.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/logging.h,v 1.15 2002/02/28 23:27:10 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -53,18 +49,23 @@ typedef enum {
|
||||
LOGF_Local,
|
||||
LOGF_Util,
|
||||
LOGF_Main,
|
||||
LOGF_ClientLog,
|
||||
LOGF_Configure,
|
||||
LOGF_CmdMon,
|
||||
LOGF_Acquire,
|
||||
LOGF_Manual,
|
||||
LOGF_Keys,
|
||||
LOGF_Logging,
|
||||
LOGF_Rtc,
|
||||
LOGF_Regress,
|
||||
LOGF_Sys,
|
||||
LOGF_SysLinux,
|
||||
LOGF_SysNetBSD,
|
||||
LOGF_SysSolaris,
|
||||
LOGF_SysSunOS,
|
||||
LOGF_SysWinnt,
|
||||
LOGF_RtcLinux
|
||||
LOGF_RtcLinux,
|
||||
LOGF_Refclock
|
||||
} LOG_Facility;
|
||||
|
||||
/* Init function */
|
||||
@@ -82,7 +83,17 @@ extern void LOG_Fatal_Function(LOG_Facility facility, const char *format, ...);
|
||||
/* Position in code reporting function */
|
||||
extern void LOG_Position(const char *filename, int line_number, const char *function_name);
|
||||
|
||||
extern void LOG_GoDaemon(void);
|
||||
/* Log messages to syslog instead of stderr */
|
||||
extern void LOG_OpenSystemLog(void);
|
||||
|
||||
/* Send fatal message also to the foreground process */
|
||||
extern void LOG_SetParentFd(int fd);
|
||||
|
||||
/* Close the pipe to the foreground process so it can exit */
|
||||
extern void LOG_CloseParentFd(void);
|
||||
|
||||
/* Return zero once per 10 seconds */
|
||||
extern int LOG_RateLimited(void);
|
||||
|
||||
/* Line logging macro. If the compiler is GNU C, we take advantage of
|
||||
being able to get the function name also. */
|
||||
@@ -94,4 +105,14 @@ extern void LOG_GoDaemon(void);
|
||||
#define LOG_FATAL LOG_Position(__FILE__, __LINE__, ""); LOG_Fatal_Function
|
||||
#endif /* defined (__GNUC__) */
|
||||
|
||||
/* File logging functions */
|
||||
|
||||
typedef int LOG_FileID;
|
||||
|
||||
extern LOG_FileID LOG_FileOpen(const char *name, const char *banner);
|
||||
extern void LOG_FileWrite(LOG_FileID id, const char *format, ...);
|
||||
|
||||
extern void LOG_CreateLogFileDir(void);
|
||||
extern void LOG_CycleLogFiles(void);
|
||||
|
||||
#endif /* GOT_LOGGING_H */
|
||||
|
||||
195
main.c
195
main.c
@@ -1,12 +1,10 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/main.c,v 1.31 2003/09/22 21:22:30 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) John G. Hasler 2009
|
||||
* Copyright (C) Miroslav Lichvar 2012
|
||||
*
|
||||
* 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
|
||||
@@ -19,7 +17,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -28,6 +26,8 @@
|
||||
The main program
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "main.h"
|
||||
@@ -46,10 +46,12 @@
|
||||
#include "keys.h"
|
||||
#include "acquire.h"
|
||||
#include "manual.h"
|
||||
#include "version.h"
|
||||
#include "rtc.h"
|
||||
#include "refclock.h"
|
||||
#include "clientlog.h"
|
||||
#include "broadcast.h"
|
||||
#include "nameserv.h"
|
||||
#include "tempcomp.h"
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
@@ -83,19 +85,21 @@ MAI_CleanupAndExit(void)
|
||||
SRC_DumpSources();
|
||||
}
|
||||
|
||||
RTC_Finalise();
|
||||
TMC_Finalise();
|
||||
MNL_Finalise();
|
||||
ACQ_Finalise();
|
||||
CAM_Finalise();
|
||||
KEY_Finalise();
|
||||
CLG_Finalise();
|
||||
NIO_Finalise();
|
||||
NSR_Finalise();
|
||||
NCR_Finalise();
|
||||
BRD_Finalise();
|
||||
SRC_Finalise();
|
||||
SST_Finalise();
|
||||
REF_Finalise();
|
||||
KEY_Finalise();
|
||||
RCL_Finalise();
|
||||
SRC_Finalise();
|
||||
RTC_Finalise();
|
||||
CAM_Finalise();
|
||||
NIO_Finalise();
|
||||
SYS_Finalise();
|
||||
SCH_Finalise();
|
||||
LCL_Finalise();
|
||||
@@ -112,8 +116,8 @@ MAI_CleanupAndExit(void)
|
||||
static void
|
||||
signal_cleanup(int x)
|
||||
{
|
||||
LOG(LOGS_WARN, LOGF_Main, "chronyd exiting on signal");
|
||||
MAI_CleanupAndExit();
|
||||
if (!initialised) exit(0);
|
||||
SCH_QuitProgram();
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -121,6 +125,8 @@ signal_cleanup(int x)
|
||||
static void
|
||||
post_acquire_hook(void *anything)
|
||||
{
|
||||
/* Close the pipe to the foreground process so it can exit */
|
||||
LOG_CloseParentFd();
|
||||
|
||||
CNF_AddSources();
|
||||
CNF_AddBroadcasts();
|
||||
@@ -134,6 +140,7 @@ post_acquire_hook(void *anything)
|
||||
CNF_SetupAccessRestrictions();
|
||||
|
||||
RTC_StartMeasurements();
|
||||
RCL_StartRefclocks();
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -202,13 +209,87 @@ write_lockfile(void)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
go_daemon(void)
|
||||
{
|
||||
#ifdef WINNT
|
||||
|
||||
|
||||
#else
|
||||
|
||||
int pid, fd, pipefd[2];
|
||||
|
||||
/* Create pipe which will the daemon use to notify the grandparent
|
||||
when it's initialised or send an error message */
|
||||
if (pipe(pipefd)) {
|
||||
LOG(LOGS_ERR, LOGF_Logging, "Could not detach, pipe failed : %s", strerror(errno));
|
||||
}
|
||||
|
||||
/* Does this preserve existing signal handlers? */
|
||||
pid = fork();
|
||||
|
||||
if (pid < 0) {
|
||||
LOG(LOGS_ERR, LOGF_Logging, "Could not detach, fork failed : %s", strerror(errno));
|
||||
} else if (pid > 0) {
|
||||
/* In the 'grandparent' */
|
||||
char message[1024];
|
||||
int r;
|
||||
|
||||
close(pipefd[1]);
|
||||
r = read(pipefd[0], message, sizeof (message));
|
||||
if (r) {
|
||||
if (r > 0) {
|
||||
/* Print the error message from the child */
|
||||
fprintf(stderr, "%.1024s\n", message);
|
||||
}
|
||||
exit(1);
|
||||
} else
|
||||
exit(0);
|
||||
} else {
|
||||
close(pipefd[0]);
|
||||
|
||||
setsid();
|
||||
|
||||
/* Do 2nd fork, as-per recommended practice for launching daemons. */
|
||||
pid = fork();
|
||||
|
||||
if (pid < 0) {
|
||||
LOG(LOGS_ERR, LOGF_Logging, "Could not detach, fork failed : %s", strerror(errno));
|
||||
} else if (pid > 0) {
|
||||
exit(0); /* In the 'parent' */
|
||||
} else {
|
||||
/* In the child we want to leave running as the daemon */
|
||||
|
||||
/* Change current directory to / */
|
||||
if (chdir("/") < 0) {
|
||||
LOG(LOGS_ERR, LOGF_Logging, "Could not chdir to / : %s", strerror(errno));
|
||||
}
|
||||
|
||||
/* Don't keep stdin/out/err from before. But don't close
|
||||
the parent pipe yet. */
|
||||
for (fd=0; fd<1024; fd++) {
|
||||
if (fd != pipefd[1])
|
||||
close(fd);
|
||||
}
|
||||
|
||||
LOG_SetParentFd(pipefd[1]);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int main
|
||||
(int argc, char **argv)
|
||||
{
|
||||
char *conf_file = NULL;
|
||||
int debug = 0;
|
||||
int do_init_rtc = 0;
|
||||
const char *conf_file = DEFAULT_CONF_FILE;
|
||||
char *user = NULL;
|
||||
int debug = 0, nofork = 0, address_family = IPADDR_UNSPEC;
|
||||
int do_init_rtc = 0, restarted = 0;
|
||||
int other_pid;
|
||||
int lock_memory = 0, sched_priority = 0;
|
||||
|
||||
LOG_Initialise();
|
||||
|
||||
@@ -218,49 +299,77 @@ int main
|
||||
if (!strcmp("-f", *argv)) {
|
||||
++argv, --argc;
|
||||
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)) {
|
||||
reload = 1;
|
||||
} else if (!strcmp("-R", *argv)) {
|
||||
restarted = 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)) {
|
||||
do_init_rtc = 1;
|
||||
} else if (!strcmp("-v", *argv) || !strcmp("--version",*argv)) {
|
||||
/* This write to the terminal is OK, it comes before we turn into a daemon */
|
||||
printf("chronyd (chrony) version %s\n", PROGRAM_VERSION_STRING);
|
||||
printf("chronyd (chrony) version %s\n", CHRONY_VERSION);
|
||||
exit(0);
|
||||
} else if (!strcmp("-n", *argv)) {
|
||||
nofork = 1;
|
||||
} else if (!strcmp("-d", *argv)) {
|
||||
debug = 1;
|
||||
nofork = 1;
|
||||
} else if (!strcmp("-4", *argv)) {
|
||||
address_family = IPADDR_INET4;
|
||||
} else if (!strcmp("-6", *argv)) {
|
||||
address_family = IPADDR_INET6;
|
||||
} else {
|
||||
LOG(LOGS_WARN, LOGF_Main, "Unrecognized command line option [%s]", *argv);
|
||||
LOG_FATAL(LOGF_Main, "Unrecognized command line option [%s]", *argv);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef SYS_WINNT
|
||||
if (getuid() != 0) {
|
||||
/* This write to the terminal is OK, it comes before we turn into a daemon */
|
||||
fprintf(stderr,"Not superuser\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/* Turn into a daemon */
|
||||
if (!nofork) {
|
||||
go_daemon();
|
||||
}
|
||||
|
||||
if (!debug) {
|
||||
LOG_GoDaemon();
|
||||
LOG_OpenSystemLog();
|
||||
}
|
||||
|
||||
LOG(LOGS_INFO, LOGF_Main, "chronyd version %s starting", CHRONY_VERSION);
|
||||
|
||||
DNS_SetAddressFamily(address_family);
|
||||
|
||||
CNF_SetRestarted(restarted);
|
||||
CNF_ReadFile(conf_file);
|
||||
|
||||
/* Check whether another chronyd may already be running. Do this after
|
||||
* forking, so that message logging goes to the right place (i.e. syslog), in
|
||||
* case this chronyd is being run from a boot script. */
|
||||
if (maybe_another_chronyd_running(&other_pid)) {
|
||||
LOG_FATAL(LOGF_Main, "Another chronyd may already be running (pid=%d), check lockfile (%s)",
|
||||
other_pid, CNF_GetPidFile());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Write our lockfile to prevent other chronyds running. This has *GOT* to
|
||||
* be done *AFTER* the daemon-creation fork() */
|
||||
write_lockfile();
|
||||
#endif
|
||||
|
||||
CNF_ReadFile(conf_file);
|
||||
|
||||
if (do_init_rtc) {
|
||||
RTC_TimePreInit();
|
||||
@@ -269,19 +378,43 @@ int main
|
||||
LCL_Initialise();
|
||||
SCH_Initialise();
|
||||
SYS_Initialise();
|
||||
NIO_Initialise(address_family);
|
||||
CAM_Initialise(address_family);
|
||||
RTC_Initialise();
|
||||
SRC_Initialise();
|
||||
RCL_Initialise();
|
||||
KEY_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) {
|
||||
user = CNF_GetUser();
|
||||
}
|
||||
if (user) {
|
||||
SYS_DropRoot(user);
|
||||
}
|
||||
|
||||
LOG_CreateLogFileDir();
|
||||
|
||||
REF_Initialise();
|
||||
SST_Initialise();
|
||||
SRC_Initialise();
|
||||
BRD_Initialise();
|
||||
NCR_Initialise();
|
||||
NSR_Initialise();
|
||||
NIO_Initialise();
|
||||
CLG_Initialise();
|
||||
KEY_Initialise();
|
||||
CAM_Initialise();
|
||||
ACQ_Initialise();
|
||||
MNL_Initialise();
|
||||
RTC_Initialise();
|
||||
TMC_Initialise();
|
||||
|
||||
/* From now on, it is safe to do finalisation on exit */
|
||||
initialised = 1;
|
||||
@@ -303,6 +436,8 @@ int main
|
||||
the scheduler. */
|
||||
SCH_MainLoop();
|
||||
|
||||
LOG(LOGS_INFO, LOGF_Main, "chronyd exiting");
|
||||
|
||||
MAI_CleanupAndExit();
|
||||
|
||||
return 0;
|
||||
|
||||
6
main.h
6
main.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/main.h,v 1.8 2002/02/28 23:27:10 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
|
||||
80
make_release
80
make_release
@@ -1,52 +1,54 @@
|
||||
#!/usr/bin/env perl
|
||||
#!/bin/sh
|
||||
|
||||
$tool = "chrony";
|
||||
LANG=C
|
||||
export LANG
|
||||
|
||||
$version = shift || die "Usage : $0 <version>\n";
|
||||
$subdir = "${tool}-${version}";
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "Usage : $0 <version>"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
unless (-d ".git") {
|
||||
die "No .git subdirectory?"
|
||||
}
|
||||
version=$1
|
||||
subdir=chrony-${version}
|
||||
mandate=$(date +'%B %Y')
|
||||
|
||||
unless (-d "RELEASES") {
|
||||
mkdir "RELEASES", 0755;
|
||||
}
|
||||
umask 022
|
||||
|
||||
system ("git-tag -s $version");
|
||||
die "git-tag failed" if ($? != 0);
|
||||
if (-d "RELEASES/$subdir") {
|
||||
system ("rm -rf RELEASES/$subdir");
|
||||
}
|
||||
if [ ! -d .git ]; then
|
||||
echo "No .git subdirectory?"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
system ("git-archive --format=tar --prefix=RELEASES/${subdir}/ $version | tar xf -");
|
||||
die "git-tar-tree failed" if ($? != 0);
|
||||
[ -d RELEASES ] || mkdir RELEASES
|
||||
|
||||
chdir "RELEASES";
|
||||
$here = qx/pwd/;
|
||||
chomp $here;
|
||||
chdir $subdir;
|
||||
git tag -s $version || exit 1
|
||||
|
||||
open (OUT, ">version.txt");
|
||||
print OUT $version."\n";
|
||||
close OUT;
|
||||
rm -rf RELEASES/$subdir
|
||||
|
||||
open (IN, "<${tool}.spec.sample");
|
||||
open (OUT, ">${tool}.spec");
|
||||
while (<IN>) {
|
||||
s/\@\@VERSION\@\@/$version/;
|
||||
print OUT;
|
||||
}
|
||||
close (IN);
|
||||
close (OUT);
|
||||
git archive --format=tar --prefix=RELEASES/${subdir}/ $version | \
|
||||
tar xf - || exit 1
|
||||
|
||||
system("makeinfo --no-headers --number-sections -o chrony.txt chrony.texi");
|
||||
unlink "make_release";
|
||||
unlink "${tool}.spec.sample";
|
||||
unlink ".gitignore";
|
||||
cd RELEASES/$subdir || exit 1
|
||||
|
||||
chdir $here;
|
||||
system ("tar cvf - $subdir | gzip -9 > ${subdir}.tar.gz");
|
||||
system ("gpg -b -a -o ${subdir}-tar-gz-asc.txt ${subdir}.tar.gz");
|
||||
echo $version > version.txt
|
||||
|
||||
sed -e "s%@@VERSION@@%${version}%" < chrony.spec.sample > chrony.spec
|
||||
|
||||
for m in chrony.1.in chronyc.1.in chrony.conf.5.in chronyd.8.in; do
|
||||
sed -e "s%@VERSION@%${version}%;s%@MAN_DATE@%${mandate}%" \
|
||||
< $m > ${m}_
|
||||
mv -f ${m}_ $m
|
||||
done
|
||||
|
||||
./configure && make chrony.txt || exit 1
|
||||
mv chrony.txt chrony.txt_
|
||||
make distclean
|
||||
mv chrony.txt_ chrony.txt
|
||||
|
||||
rm -f faqgen.pl make_release chrony.spec.sample .gitignore
|
||||
|
||||
cd ..
|
||||
tar cvf - $subdir | gzip -9 > ${subdir}.tar.gz
|
||||
gpg -b -a -o ${subdir}-tar-gz-asc.txt ${subdir}.tar.gz
|
||||
|
||||
|
||||
|
||||
35
manual.c
35
manual.c
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/manual.c,v 1.21 2003/09/22 21:22:30 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -34,7 +30,9 @@
|
||||
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "manual.h"
|
||||
#include "logging.h"
|
||||
@@ -74,7 +72,6 @@ static void
|
||||
slew_samples(struct timeval *raw,
|
||||
struct timeval *cooked,
|
||||
double dfreq,
|
||||
double afreq,
|
||||
double doffset,
|
||||
int is_step_change,
|
||||
void *not_used);
|
||||
@@ -96,8 +93,6 @@ MNL_Initialise(void)
|
||||
error = ERROR_MARGIN;
|
||||
|
||||
LCL_AddParameterChangeHandler(slew_samples, NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -105,7 +100,6 @@ MNL_Initialise(void)
|
||||
void
|
||||
MNL_Finalise(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -148,6 +142,8 @@ estimate_and_set_system(struct timeval *now, int offset_provided, double offset,
|
||||
}
|
||||
b1 = freq = 0.0;
|
||||
found_freq = 0;
|
||||
agos[0] = 0.0;
|
||||
offsets[0] = b0;
|
||||
}
|
||||
|
||||
if (offset_provided) {
|
||||
@@ -158,7 +154,7 @@ estimate_and_set_system(struct timeval *now, int offset_provided, double offset,
|
||||
|
||||
if (found_freq) {
|
||||
LOG(LOGS_INFO, LOGF_Manual,
|
||||
"Making a frequency change of %.3fppm and a slew of %.6f\n",
|
||||
"Making a frequency change of %.3f ppm and a slew of %.6f",
|
||||
1.0e6 * freq, slew_by);
|
||||
|
||||
REF_SetManualReference(now,
|
||||
@@ -188,14 +184,13 @@ int
|
||||
MNL_AcceptTimestamp(struct timeval *ts, long *offset_cs, double *dfreq_ppm, double *new_afreq_ppm)
|
||||
{
|
||||
struct timeval now;
|
||||
double local_clock_err;
|
||||
double offset;
|
||||
int i;
|
||||
|
||||
if (enabled) {
|
||||
|
||||
/* Check whether timestamp is within margin of old one */
|
||||
LCL_ReadCookedTime(&now, &local_clock_err);
|
||||
LCL_ReadCookedTime(&now, NULL);
|
||||
|
||||
UTI_DiffTimevalsToDouble(&offset, &now, ts);
|
||||
|
||||
@@ -230,20 +225,17 @@ static void
|
||||
slew_samples(struct timeval *raw,
|
||||
struct timeval *cooked,
|
||||
double dfreq,
|
||||
double afreq,
|
||||
double doffset,
|
||||
int is_step_change,
|
||||
void *not_used)
|
||||
{
|
||||
double elapsed, delta_time;
|
||||
double delta_time;
|
||||
int i;
|
||||
for (i=0; i<n_samples; i++) {
|
||||
UTI_DiffTimevalsToDouble(&elapsed, cooked, &samples[i].when);
|
||||
delta_time = elapsed * dfreq - doffset;
|
||||
UTI_AddDoubleToTimeval(&samples[i].when, delta_time, &samples[i].when);
|
||||
UTI_AdjustTimeval(&samples[i].when, cooked, &samples[i].when, &delta_time,
|
||||
dfreq, doffset);
|
||||
samples[i].offset += delta_time;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -287,7 +279,7 @@ MNL_ReportSamples(RPT_ManualSamplesReport *report, int max, int *n)
|
||||
}
|
||||
|
||||
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].orig_offset = samples[i].orig_offset;
|
||||
report[i].residual = samples[i].residual;
|
||||
@@ -303,7 +295,6 @@ MNL_DeleteSample(int index)
|
||||
{
|
||||
int i;
|
||||
struct timeval now;
|
||||
double local_clock_err;
|
||||
|
||||
if ((index < 0) || (index >= n_samples)) {
|
||||
return 0;
|
||||
@@ -319,7 +310,7 @@ MNL_DeleteSample(int index)
|
||||
|
||||
/* Now re-estimate. NULLs because we don't want the parameters back
|
||||
in this case. */
|
||||
LCL_ReadCookedTime(&now, &local_clock_err);
|
||||
LCL_ReadCookedTime(&now, NULL);
|
||||
estimate_and_set_system(&now, 0, 0.0, NULL, NULL, NULL);
|
||||
|
||||
return 1;
|
||||
|
||||
6
manual.h
6
manual.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/manual.h,v 1.12 2002/02/28 23:27:11 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
|
||||
6
md5.h
6
md5.h
@@ -32,11 +32,7 @@
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#ifdef HAS_STDINT_H
|
||||
#include <stdint.h>
|
||||
#elif defined(HAS_INTTYPES_H)
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#include "sysincl.h"
|
||||
|
||||
/* typedef a 32-bit type */
|
||||
typedef uint32_t UINT4;
|
||||
|
||||
8
memory.h
8
memory.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/memory.h,v 1.7 2002/02/28 23:27:11 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -31,8 +27,6 @@
|
||||
#ifndef GOT_MEMORY_H
|
||||
#define GOT_MEMORY_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define Malloc(x) malloc(x)
|
||||
#define MallocNew(T) ((T *) malloc(sizeof(T)))
|
||||
#define MallocArray(T, n) ((T *) malloc((n) * sizeof(T)))
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/mkdirpp.c,v 1.10 2002/11/03 22:49:17 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -30,6 +26,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "mkdirpp.h"
|
||||
@@ -86,6 +84,7 @@ mkdir_and_parents(const char *path)
|
||||
p[i] = 0;
|
||||
|
||||
if (do_dir(p) < 0) {
|
||||
free(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/mkdirpp.h,v 1.6 2002/02/28 23:27:11 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
|
||||
15
mkversion
15
mkversion
@@ -1,15 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm -f version.h
|
||||
echo "#ifndef VERSION_H" > version.h
|
||||
echo "#define VERSION_H 1" >> version.h
|
||||
|
||||
if [ -f version.txt ]; then
|
||||
ver=`cat version.txt`
|
||||
echo "#define PROGRAM_VERSION_STRING \"$ver\"" >> version.h
|
||||
else
|
||||
echo "#define PROGRAM_VERSION_STRING \"DEVELOPMENT\"" >> version.h
|
||||
fi
|
||||
|
||||
echo "#endif /* VERSION_H */" >> version.h
|
||||
|
||||
189
nameserv.c
189
nameserv.c
@@ -1,12 +1,9 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/nameserv.c,v 1.15 2003/09/22 21:22:30 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Miroslav Lichvar 2009-2011
|
||||
*
|
||||
* 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
|
||||
@@ -19,7 +16,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -29,63 +26,157 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "nameserv.h"
|
||||
#include "util.h"
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
unsigned long
|
||||
DNS_Name2IPAddress(const char *name)
|
||||
static int address_family = IPADDR_UNSPEC;
|
||||
|
||||
void
|
||||
DNS_SetAddressFamily(int family)
|
||||
{
|
||||
struct hostent *host;
|
||||
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;
|
||||
|
||||
address_family = family;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
const char *
|
||||
DNS_IPAddress2Name(unsigned long ip_addr)
|
||||
DNS_Status
|
||||
DNS_Name2IPAddress(const char *name, IPAddr *addr)
|
||||
{
|
||||
struct hostent *host;
|
||||
static char buffer[16];
|
||||
unsigned int a, b, c, d;
|
||||
unsigned long addr;
|
||||
#ifdef HAVE_IPV6
|
||||
struct addrinfo hints, *res, *ai;
|
||||
int result;
|
||||
|
||||
memset(&hints, 0, sizeof (hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
addr = htonl(ip_addr);
|
||||
if (addr == 0UL) {
|
||||
/* Catch this as a special case that will never resolve to
|
||||
anything */
|
||||
strcpy(buffer, "0.0.0.0");
|
||||
return buffer;
|
||||
} else {
|
||||
host = gethostbyaddr((const char *) &addr, sizeof(ip_addr), AF_INET);
|
||||
if (!host) {
|
||||
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;
|
||||
result = getaddrinfo(name, NULL, &hints, &res);
|
||||
|
||||
if (result) {
|
||||
#ifdef FORCE_DNSRETRY
|
||||
return DNS_TryAgain;
|
||||
#else
|
||||
return result == EAI_AGAIN ? DNS_TryAgain : DNS_Failure;
|
||||
#endif
|
||||
}
|
||||
|
||||
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 ? DNS_Success : DNS_Failure;
|
||||
#else
|
||||
struct hostent *host;
|
||||
|
||||
host = gethostbyname(name);
|
||||
|
||||
if (host == NULL) {
|
||||
if (h_errno == TRY_AGAIN)
|
||||
return DNS_TryAgain;
|
||||
} else {
|
||||
addr->family = IPADDR_INET4;
|
||||
addr->addr.in4 = ntohl(*(uint32_t *)host->h_addr_list[0]);
|
||||
return DNS_Success;
|
||||
}
|
||||
|
||||
#ifdef FORCE_DNSRETRY
|
||||
return DNS_TryAgain;
|
||||
#else
|
||||
return DNS_Failure;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
DNS_IPAddress2Name(IPAddr *ip_addr, char *name, int len)
|
||||
{
|
||||
char *result = NULL;
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
struct sockaddr_in in4;
|
||||
struct sockaddr_in6 in6;
|
||||
char hbuf[NI_MAXHOST];
|
||||
|
||||
switch (ip_addr->family) {
|
||||
case IPADDR_INET4:
|
||||
memset(&in4, 0, sizeof (in4));
|
||||
#ifdef SIN6_LEN
|
||||
in4.sin_len = sizeof (in4);
|
||||
#endif
|
||||
in4.sin_family = AF_INET;
|
||||
in4.sin_addr.s_addr = htonl(ip_addr->addr.in4);
|
||||
if (!getnameinfo((const struct sockaddr *)&in4, sizeof (in4), hbuf, sizeof (hbuf), NULL, 0, 0))
|
||||
result = hbuf;
|
||||
break;
|
||||
case IPADDR_INET6:
|
||||
memset(&in6, 0, sizeof (in6));
|
||||
#ifdef SIN6_LEN
|
||||
in6.sin6_len = sizeof (in6);
|
||||
#endif
|
||||
in6.sin6_family = AF_INET6;
|
||||
memcpy(&in6.sin6_addr.s6_addr, ip_addr->addr.in6, sizeof (in6.sin6_addr.s6_addr));
|
||||
if (!getnameinfo((const struct sockaddr *)&in6, sizeof (in6), hbuf, sizeof (hbuf), NULL, 0, 0))
|
||||
result = hbuf;
|
||||
break;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
if (host)
|
||||
result = host->h_name;
|
||||
#endif
|
||||
|
||||
if (result == NULL)
|
||||
result = UTI_IPToString(ip_addr);
|
||||
if (snprintf(name, len, "%s", result) >= len)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
DNS_Reload(void)
|
||||
{
|
||||
res_init();
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
23
nameserv.h
23
nameserv.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/nameserv.h,v 1.8 2002/02/28 23:27:11 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -32,11 +28,22 @@
|
||||
#ifndef 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);
|
||||
typedef enum {
|
||||
DNS_Success,
|
||||
DNS_TryAgain,
|
||||
DNS_Failure
|
||||
} DNS_Status;
|
||||
|
||||
const char *DNS_IPAddress2Name(unsigned long ip_addr);
|
||||
/* Resolve names only to selected address family */
|
||||
extern void DNS_SetAddressFamily(int family);
|
||||
|
||||
extern DNS_Status DNS_Name2IPAddress(const char *name, IPAddr *addr);
|
||||
|
||||
extern int DNS_IPAddress2Name(IPAddr *ip_addr, char *name, int len);
|
||||
|
||||
extern void DNS_Reload(void);
|
||||
|
||||
#endif /* GOT_NAMESERV_H */
|
||||
|
||||
|
||||
38
ntp.h
38
ntp.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/ntp.h,v 1.12 2003/09/22 21:22:30 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -31,11 +27,9 @@
|
||||
#ifndef GOT_NTP_H
|
||||
#define GOT_NTP_H
|
||||
|
||||
#ifdef HAS_STDINT_H
|
||||
#include <stdint.h>
|
||||
#elif defined(HAS_INTTYPES_H)
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "hash.h"
|
||||
|
||||
typedef struct {
|
||||
uint32_t hi;
|
||||
@@ -44,7 +38,7 @@ typedef struct {
|
||||
|
||||
typedef uint32_t NTP_int32;
|
||||
|
||||
#define AUTH_DATA_LEN 16
|
||||
#define MAX_NTP_AUTH_DATA_LEN MAX_HASH_LENGTH
|
||||
|
||||
/* Type definition for leap bits */
|
||||
typedef enum {
|
||||
@@ -76,7 +70,7 @@ typedef struct {
|
||||
NTP_int64 receive_ts;
|
||||
NTP_int64 transmit_ts;
|
||||
NTP_int32 auth_keyid;
|
||||
uint8_t auth_data[AUTH_DATA_LEN];
|
||||
uint8_t auth_data[MAX_NTP_AUTH_DATA_LEN];
|
||||
} NTP_Packet;
|
||||
|
||||
/* We have to declare a buffer type to hold a datagram read from the
|
||||
@@ -93,24 +87,6 @@ typedef union {
|
||||
uint8_t arbitrary[MAX_NTP_MESSAGE_SIZE];
|
||||
} ReceiveBuffer;
|
||||
|
||||
#define NTP_NORMAL_PACKET_SIZE (sizeof(NTP_Packet) - (sizeof(NTP_int32) + AUTH_DATA_LEN))
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
inline static double
|
||||
int32_to_double(NTP_int32 x)
|
||||
{
|
||||
return (double) ntohl(x) / 65536.0;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
inline static NTP_int32
|
||||
double_to_int32(double x)
|
||||
{
|
||||
return htonl((NTP_int32)(0.5 + 65536.0 * x));
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
#define NTP_NORMAL_PACKET_SIZE offsetof(NTP_Packet, auth_keyid)
|
||||
|
||||
#endif /* GOT_NTP_H */
|
||||
|
||||
1251
ntp_core.c
1251
ntp_core.c
File diff suppressed because it is too large
Load Diff
46
ntp_core.h
46
ntp_core.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/ntp_core.h,v 1.16 2002/02/28 23:27:12 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -38,6 +34,10 @@
|
||||
#include "ntp.h"
|
||||
#include "reports.h"
|
||||
|
||||
typedef enum {
|
||||
NTP_SERVER, NTP_PEER
|
||||
} NTP_Source_Type;
|
||||
|
||||
/* This is a private data type used for storing the instance record for
|
||||
each source that we are chiming with */
|
||||
typedef struct NCR_Instance_Record *NCR_Instance;
|
||||
@@ -46,31 +46,19 @@ typedef struct NCR_Instance_Record *NCR_Instance;
|
||||
extern void NCR_Initialise(void);
|
||||
extern void NCR_Finalise(void);
|
||||
|
||||
/* Get a new instance for a server */
|
||||
extern NCR_Instance NCR_GetServerInstance(NTP_Remote_Address *remote_addr, SourceParameters *params);
|
||||
|
||||
/* Get a new instance for a peer */
|
||||
extern NCR_Instance NCR_GetPeerInstance(NTP_Remote_Address *remote_addr, SourceParameters *params);
|
||||
/* Get a new instance for a server or peer */
|
||||
extern NCR_Instance NCR_GetInstance(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourceParameters *params);
|
||||
|
||||
/* Destroy an instance */
|
||||
extern void NCR_DestroyInstance(NCR_Instance instance);
|
||||
|
||||
/* This routine is called when a new packet arrives off the network,
|
||||
and it relates to a source we have an ongoing protocol exchange with */
|
||||
extern void NCR_ProcessNoauthKnown(NTP_Packet *message, struct timeval *now, NCR_Instance data);
|
||||
extern void NCR_ProcessKnown(NTP_Packet *message, struct timeval *now, double now_err, NCR_Instance data, int length);
|
||||
|
||||
/* This routine is called when a new packet arrives off the network,
|
||||
and we do not recognize its source */
|
||||
extern void NCR_ProcessNoauthUnknown(NTP_Packet *message, struct timeval *now, NTP_Remote_Address *remote_addr);
|
||||
|
||||
/* This routine is called when a new authenticated packet arrives off
|
||||
the network, and it relates to a source we have an ongoing protocol
|
||||
exchange with */
|
||||
extern void NCR_ProcessAuthKnown(NTP_Packet *message, struct timeval *now, NCR_Instance data);
|
||||
|
||||
/* This routine is called when a new authenticated packet arrives off
|
||||
the network, and we do not recognize its source */
|
||||
extern void NCR_ProcessAuthUnknown(NTP_Packet *message, struct timeval *now, NTP_Remote_Address *remote_addr);
|
||||
extern void NCR_ProcessUnknown(NTP_Packet *message, struct timeval *now, double now_err, NTP_Remote_Address *remote_addr, int length);
|
||||
|
||||
/* Slew receive and transmit times in instance records */
|
||||
extern void NCR_SlewTimes(NCR_Instance inst, struct timeval *when, double dfreq, double doffset);
|
||||
@@ -90,16 +78,24 @@ extern void NCR_ModifyMaxdelay(NCR_Instance inst, double new_max_delay);
|
||||
|
||||
extern void NCR_ModifyMaxdelayratio(NCR_Instance inst, double new_max_delay_ratio);
|
||||
|
||||
extern void NCR_ModifyMaxdelaydevratio(NCR_Instance inst, double new_max_delay_dev_ratio);
|
||||
|
||||
extern void NCR_ModifyMinstratum(NCR_Instance inst, int new_min_stratum);
|
||||
|
||||
extern void NCR_ModifyPolltarget(NCR_Instance inst, int new_poll_target);
|
||||
|
||||
extern void NCR_InitiateSampleBurst(NCR_Instance inst, int n_good_samples, int n_total_samples);
|
||||
|
||||
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_CheckAccessRestriction(unsigned long ip_addr);
|
||||
|
||||
extern void NCR_CycleLogFile(void);
|
||||
extern int NCR_AddAccessRestriction(IPAddr *ip_addr, int subnet_bits, int allow, int all);
|
||||
extern int NCR_CheckAccessRestriction(IPAddr *ip_addr);
|
||||
|
||||
extern void NCR_IncrementActivityCounters(NCR_Instance inst, int *online, int *offline,
|
||||
int *burst_online, int *burst_offline);
|
||||
|
||||
extern NTP_Remote_Address *NCR_GetRemoteAddress(NCR_Instance instance);
|
||||
|
||||
extern int NCR_IsSyncPeer(NCR_Instance instance);
|
||||
|
||||
#endif /* GOT_NTP_CORE_H */
|
||||
|
||||
438
ntp_io.c
438
ntp_io.c
@@ -1,12 +1,10 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/ntp_io.c,v 1.24 2003/09/22 21:22:30 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* 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
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@@ -19,7 +17,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -28,6 +26,8 @@
|
||||
This file deals with the IO aspects of reading and writing NTP packets
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "ntp_io.h"
|
||||
@@ -39,10 +39,19 @@
|
||||
#include "conf.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
union sockaddr_in46 {
|
||||
struct sockaddr_in in4;
|
||||
#ifdef HAVE_IPV6
|
||||
struct sockaddr_in6 in6;
|
||||
#endif
|
||||
struct sockaddr u;
|
||||
};
|
||||
|
||||
/* The file descriptor for the socket */
|
||||
static int sock_fd;
|
||||
/* 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 */
|
||||
static int initialised=0;
|
||||
@@ -50,6 +59,7 @@ static int initialised=0;
|
||||
/* ================================================== */
|
||||
|
||||
/* Forward prototypes */
|
||||
static int prepare_socket(int family);
|
||||
static void read_from_socket(void *anything);
|
||||
|
||||
/* ================================================== */
|
||||
@@ -81,32 +91,35 @@ do_size_checks(void)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
NIO_Initialise(void)
|
||||
static int
|
||||
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 long bind_address;
|
||||
IPAddr bind_address;
|
||||
int on_off = 1;
|
||||
|
||||
assert(!initialised);
|
||||
initialised = 1;
|
||||
|
||||
do_size_checks();
|
||||
|
||||
port_number = CNF_GetNTPPort();
|
||||
|
||||
/* Open Internet domain UDP socket for NTP message transmissions */
|
||||
|
||||
#if 0
|
||||
sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
sock_fd = socket(family, SOCK_DGRAM, IPPROTO_UDP);
|
||||
#else
|
||||
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
sock_fd = socket(family, SOCK_DGRAM, 0);
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* Close on exec */
|
||||
UTI_FdSetCloexec(sock_fd);
|
||||
|
||||
/* Make the socket capable of re-using an old address */
|
||||
if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on_off, sizeof(on_off)) < 0) {
|
||||
LOG(LOGS_ERR, LOGF_NtpIO, "Could not set reuseaddr socket options");
|
||||
@@ -119,28 +132,92 @@ NIO_Initialise(void)
|
||||
/* 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
|
||||
|
||||
#ifdef IPV6_RECVPKTINFO
|
||||
if (setsockopt(sock_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, (char *)&on_off, sizeof(on_off)) < 0) {
|
||||
LOG(LOGS_ERR, LOGF_NtpIO, "Could not request IPv6 packet info socket option");
|
||||
}
|
||||
#elif defined(IPV6_PKTINFO)
|
||||
if (setsockopt(sock_fd, IPPROTO_IPV6, IPV6_PKTINFO, (char *)&on_off, sizeof(on_off)) < 0) {
|
||||
LOG(LOGS_ERR, LOGF_NtpIO, "Could not request IPv6 packet info socket option");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Bind the port */
|
||||
my_addr.sin_family = AF_INET;
|
||||
my_addr.sin_port = htons(port_number);
|
||||
memset(&my_addr, 0, sizeof (my_addr));
|
||||
|
||||
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) {
|
||||
my_addr.sin_addr.s_addr = htonl(bind_address);
|
||||
} else {
|
||||
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
CNF_GetBindAddress(IPADDR_INET4, &bind_address);
|
||||
|
||||
if (bind_address.family == IPADDR_INET4)
|
||||
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
|
||||
LOG(LOGS_INFO, LOGF_NtpIO, "Initialising, socket fd=%d", sock_fd);
|
||||
#endif
|
||||
|
||||
if (bind(sock_fd, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0) {
|
||||
LOG_FATAL(LOGF_NtpIO, "Could not bind socket : %s", strerror(errno));
|
||||
if (bind(sock_fd, &my_addr.u, my_addr_len) < 0) {
|
||||
LOG(LOGS_ERR, LOGF_NtpIO, "Could not bind %s NTP socket : %s",
|
||||
family == AF_INET ? "IPv4" : "IPv6", strerror(errno));
|
||||
close(sock_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 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 (fcntl(sock_fd, F_SETFL, O_NONBLOCK | O_NDELAY) < 0) {
|
||||
@@ -151,8 +228,37 @@ NIO_Initialise(void)
|
||||
LOG(LOGS_ERR, LOGF_NtpIO, "Could not enable signal");
|
||||
}
|
||||
#endif
|
||||
return sock_fd;
|
||||
}
|
||||
|
||||
return;
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
NIO_Initialise(int family)
|
||||
{
|
||||
assert(!initialised);
|
||||
initialised = 1;
|
||||
|
||||
do_size_checks();
|
||||
|
||||
if (family == IPADDR_UNSPEC || family == IPADDR_INET4)
|
||||
sock_fd4 = prepare_socket(AF_INET);
|
||||
else
|
||||
sock_fd4 = -1;
|
||||
#ifdef HAVE_IPV6
|
||||
if (family == IPADDR_UNSPEC || family == IPADDR_INET6)
|
||||
sock_fd6 = prepare_socket(AF_INET6);
|
||||
else
|
||||
sock_fd6 = -1;
|
||||
#endif
|
||||
|
||||
if (sock_fd4 < 0
|
||||
#ifdef HAVE_IPV6
|
||||
&& sock_fd6 < 0
|
||||
#endif
|
||||
) {
|
||||
LOG_FATAL(LOGF_NtpIO, "Could not open any NTP socket");
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -160,13 +266,19 @@ NIO_Initialise(void)
|
||||
void
|
||||
NIO_Finalise(void)
|
||||
{
|
||||
if (sock_fd >= 0) {
|
||||
SCH_RemoveInputFileHandler(sock_fd);
|
||||
close(sock_fd);
|
||||
if (sock_fd4 >= 0) {
|
||||
SCH_RemoveInputFileHandler(sock_fd4);
|
||||
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;
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -180,24 +292,34 @@ read_from_socket(void *anything)
|
||||
/* This should only be called when there is something
|
||||
to read, otherwise it will block. */
|
||||
|
||||
int status;
|
||||
int status, sock_fd;
|
||||
ReceiveBuffer message;
|
||||
int message_length;
|
||||
struct sockaddr_in where_from;
|
||||
socklen_t from_length;
|
||||
union sockaddr_in46 where_from;
|
||||
unsigned int flags = 0;
|
||||
struct timeval now;
|
||||
struct timeval now, now_raw;
|
||||
double now_err;
|
||||
NTP_Remote_Address remote_addr;
|
||||
double local_clock_err;
|
||||
char cmsgbuf[256];
|
||||
struct msghdr msg;
|
||||
struct iovec iov;
|
||||
struct cmsghdr *cmsg;
|
||||
|
||||
assert(initialised);
|
||||
|
||||
from_length = sizeof(where_from);
|
||||
message_length = sizeof(message);
|
||||
SCH_GetLastEventTime(&now, &now_err, &now_raw);
|
||||
|
||||
LCL_ReadCookedTime(&now, &local_clock_err);
|
||||
status = recvfrom(sock_fd, (char *)&message, message_length, flags,
|
||||
(struct sockaddr *)&where_from, &from_length);
|
||||
iov.iov_base = message.arbitrary;
|
||||
iov.iov_len = sizeof(message);
|
||||
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
|
||||
likely than not, it will be connection refused, resulting from a
|
||||
@@ -207,16 +329,63 @@ read_from_socket(void *anything)
|
||||
reponse on a subsequent recvfrom). */
|
||||
|
||||
if (status > 0) {
|
||||
remote_addr.ip_addr = ntohl(where_from.sin_addr.s_addr);
|
||||
remote_addr.port = ntohs(where_from.sin_port);
|
||||
memset(&remote_addr, 0, sizeof (remote_addr));
|
||||
|
||||
if (status == NTP_NORMAL_PACKET_SIZE) {
|
||||
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);
|
||||
}
|
||||
|
||||
NSR_ProcessReceive((NTP_Packet *) &message.ntp_pkt, &now, &remote_addr);
|
||||
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;
|
||||
|
||||
} else if (status == sizeof(NTP_Packet)) {
|
||||
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
|
||||
|
||||
NSR_ProcessAuthenticatedReceive((NTP_Packet *) &message.ntp_pkt, &now, &remote_addr);
|
||||
#if defined(IPV6_PKTINFO) && defined(HAVE_IN6_PKTINFO)
|
||||
if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) {
|
||||
struct in6_pktinfo ipi;
|
||||
|
||||
memcpy(&ipi, CMSG_DATA(cmsg), sizeof(ipi));
|
||||
memcpy(&remote_addr.local_ip_addr.addr.in6, &ipi.ipi6_addr.s6_addr,
|
||||
sizeof (remote_addr.local_ip_addr.addr.in6));
|
||||
remote_addr.local_ip_addr.family = IPADDR_INET6;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SO_TIMESTAMP
|
||||
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMP) {
|
||||
struct timeval tv;
|
||||
|
||||
memcpy(&tv, CMSG_DATA(cmsg), sizeof(tv));
|
||||
|
||||
/* This should be more accurate than LCL_CookTime(&now_raw,...) */
|
||||
UTI_AddDiffToTimeval(&now, &now_raw, &tv, &now);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (status >= NTP_NORMAL_PACKET_SIZE && status <= sizeof(NTP_Packet)) {
|
||||
|
||||
NSR_ProcessReceive((NTP_Packet *) &message.ntp_pkt, &now, now_err, &remote_addr, status);
|
||||
|
||||
} else {
|
||||
|
||||
@@ -224,8 +393,120 @@ read_from_socket(void *anything)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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 defined(IPV6_PKTINFO) && defined(HAVE_IN6_PKTINFO)
|
||||
if (remote_addr->local_ip_addr.family == IPADDR_INET6) {
|
||||
struct cmsghdr *cmsg;
|
||||
struct in6_pktinfo *ipi;
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
memset(cmsg, 0, CMSG_SPACE(sizeof(struct in6_pktinfo)));
|
||||
cmsglen += CMSG_SPACE(sizeof(struct in6_pktinfo));
|
||||
|
||||
cmsg->cmsg_level = IPPROTO_IPV6;
|
||||
cmsg->cmsg_type = IPV6_PKTINFO;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
|
||||
|
||||
ipi = (struct in6_pktinfo *) CMSG_DATA(cmsg);
|
||||
memcpy(&ipi->ipi6_addr.s6_addr, &remote_addr->local_ip_addr.addr.in6,
|
||||
sizeof(ipi->ipi6_addr.s6_addr));
|
||||
}
|
||||
#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 &&
|
||||
#ifdef ENETUNREACH
|
||||
errno != ENETUNREACH &&
|
||||
#endif
|
||||
#ifdef ENETDOWN
|
||||
errno != ENETDOWN &&
|
||||
#endif
|
||||
!LOG_RateLimited()) {
|
||||
LOG(LOGS_WARN, LOGF_NtpIO, "Could not send to %s:%d : %s",
|
||||
UTI_IPToString(&remote_addr->ip_addr), remote_addr->port, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -234,44 +515,16 @@ read_from_socket(void *anything)
|
||||
void
|
||||
NIO_SendNormalPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr)
|
||||
{
|
||||
struct sockaddr_in remote;
|
||||
|
||||
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;
|
||||
send_packet((void *) packet, NTP_NORMAL_PACKET_SIZE, remote_addr);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
/* Send an authenticated packet to a given address */
|
||||
|
||||
void
|
||||
NIO_SendAuthenticatedPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr)
|
||||
NIO_SendAuthenticatedPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr, int auth_len)
|
||||
{
|
||||
struct sockaddr_in remote;
|
||||
|
||||
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;
|
||||
send_packet((void *) packet, NTP_NORMAL_PACKET_SIZE + auth_len, remote_addr);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -283,15 +536,10 @@ void
|
||||
NIO_SendEcho(NTP_Remote_Address *remote_addr)
|
||||
{
|
||||
unsigned long magic_message = 0xbe7ab1e7UL;
|
||||
struct sockaddr_in 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));
|
||||
NTP_Remote_Address addr;
|
||||
|
||||
addr = *remote_addr;
|
||||
addr.port = ECHO_PORT;
|
||||
|
||||
send_packet((void *) &magic_message, sizeof(unsigned long), &addr);
|
||||
}
|
||||
|
||||
10
ntp_io.h
10
ntp_io.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/ntp_io.h,v 1.9 2002/02/28 23:27:12 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -36,7 +32,7 @@
|
||||
#include "addressing.h"
|
||||
|
||||
/* Function to initialise the module. */
|
||||
extern void NIO_Initialise(void);
|
||||
extern void NIO_Initialise(int family);
|
||||
|
||||
/* Function to finalise the module */
|
||||
extern void NIO_Finalise(void);
|
||||
@@ -45,7 +41,7 @@ extern void NIO_Finalise(void);
|
||||
extern void NIO_SendNormalPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr);
|
||||
|
||||
/* Function to transmit an authenticated packet */
|
||||
extern void NIO_SendAuthenticatedPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr);
|
||||
extern void NIO_SendAuthenticatedPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr, int auth_len);
|
||||
|
||||
/* Function to send a datagram to a remote machine's UDP echo port. */
|
||||
extern void NIO_SendEcho(NTP_Remote_Address *remote_addr);
|
||||
|
||||
409
ntp_sources.c
409
ntp_sources.c
@@ -1,12 +1,9 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/ntp_sources.c,v 1.18 2003/09/22 21:22:30 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Miroslav Lichvar 2011-2012
|
||||
*
|
||||
* 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
|
||||
@@ -19,7 +16,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -30,6 +27,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "ntp_sources.h"
|
||||
@@ -37,14 +36,17 @@
|
||||
#include "util.h"
|
||||
#include "logging.h"
|
||||
#include "local.h"
|
||||
#include "memory.h"
|
||||
#include "nameserv.h"
|
||||
#include "sched.h"
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
/* Record type private to this file, used to store information about
|
||||
particular sources */
|
||||
typedef struct {
|
||||
NTP_Remote_Address remote_addr; /* The address of this source */
|
||||
int in_use; /* Whether this slot in the table is in use */
|
||||
NTP_Remote_Address *remote_addr; /* The address of this source, non-NULL
|
||||
means this slot in table is in use */
|
||||
NCR_Instance data; /* Data for the protocol engine for this source */
|
||||
} SourceRecord;
|
||||
|
||||
@@ -60,13 +62,25 @@ static int n_sources;
|
||||
/* The largest number of sources we want to have stored in the hash table */
|
||||
#define MAX_SOURCES 64
|
||||
|
||||
/* Source with unknown address (which may be resolved later) */
|
||||
struct UnresolvedSource {
|
||||
char *name;
|
||||
int port;
|
||||
NTP_Source_Type type;
|
||||
SourceParameters params;
|
||||
struct UnresolvedSource *next;
|
||||
};
|
||||
|
||||
static struct UnresolvedSource *unresolved_sources = NULL;
|
||||
static int resolving_interval = 0;
|
||||
static SCH_TimeoutID resolving_id;
|
||||
|
||||
/* ================================================== */
|
||||
/* Forward prototypes */
|
||||
static void
|
||||
slew_sources(struct timeval *raw,
|
||||
struct timeval *cooked,
|
||||
double dfreq,
|
||||
double afreq,
|
||||
double doffset,
|
||||
int is_step_change,
|
||||
void *anything);
|
||||
@@ -83,14 +97,12 @@ NSR_Initialise(void)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<N_RECORDS; i++) {
|
||||
records[i].in_use = 0;
|
||||
records[i].remote_addr = NULL;
|
||||
}
|
||||
n_sources = 0;
|
||||
initialised = 1;
|
||||
|
||||
LCL_AddParameterChangeHandler(slew_sources, NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -99,7 +111,6 @@ void
|
||||
NSR_Finalise(void)
|
||||
{
|
||||
initialised = 0;
|
||||
return; /* Nothing to do yet */
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -120,23 +131,42 @@ static void
|
||||
find_slot(NTP_Remote_Address *remote_addr, int *slot, int *found)
|
||||
{
|
||||
unsigned long hash;
|
||||
unsigned long ip = remote_addr->ip_addr;
|
||||
unsigned short port = remote_addr->port;
|
||||
unsigned long ip;
|
||||
unsigned short port;
|
||||
uint8_t *ip6;
|
||||
|
||||
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 */
|
||||
hash = ip ^ (ip >> 16);
|
||||
hash = (hash ^ (hash >> 8)) & 0xff;
|
||||
|
||||
while ((records[hash].in_use) &&
|
||||
(records[hash].remote_addr.ip_addr != ip)) {
|
||||
while (records[hash].remote_addr &&
|
||||
UTI_CompareIPs(&records[hash].remote_addr->ip_addr,
|
||||
&remote_addr->ip_addr, NULL)) {
|
||||
hash++;
|
||||
if (hash == 256) hash = 0;
|
||||
}
|
||||
|
||||
if (records[hash].in_use) {
|
||||
if (records[hash].remote_addr.port == port) {
|
||||
if (records[hash].remote_addr) {
|
||||
if (records[hash].remote_addr->port == port) {
|
||||
*found = 2;
|
||||
} else {
|
||||
*found = 1;
|
||||
@@ -146,23 +176,20 @@ find_slot(NTP_Remote_Address *remote_addr, int *slot, int *found)
|
||||
*found = 0;
|
||||
*slot = hash;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
/* Procedure to add a new server source (to which this machine will be
|
||||
a client) */
|
||||
/* Procedure to add a new source */
|
||||
NSR_Status
|
||||
NSR_AddServer(NTP_Remote_Address *remote_addr, SourceParameters *params)
|
||||
NSR_AddSource(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourceParameters *params)
|
||||
{
|
||||
int slot, found;
|
||||
|
||||
assert(initialised);
|
||||
|
||||
#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
|
||||
|
||||
/* Find empty bin & check that we don't have the address already */
|
||||
@@ -172,11 +199,13 @@ NSR_AddServer(NTP_Remote_Address *remote_addr, SourceParameters *params)
|
||||
} else {
|
||||
if (n_sources == MAX_SOURCES) {
|
||||
return NSR_TooManySources;
|
||||
} else if (remote_addr->ip_addr.family != IPADDR_INET4 &&
|
||||
remote_addr->ip_addr.family != IPADDR_INET6) {
|
||||
return NSR_InvalidAF;
|
||||
} else {
|
||||
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_GetInstance(remote_addr, type, params); /* Will need params passing through */
|
||||
records[slot].remote_addr = NCR_GetRemoteAddress(records[slot].data);
|
||||
return NSR_Success;
|
||||
}
|
||||
}
|
||||
@@ -184,32 +213,83 @@ NSR_AddServer(NTP_Remote_Address *remote_addr, SourceParameters *params)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
/* Procedure to add a new peer. */
|
||||
NSR_Status
|
||||
NSR_AddPeer(NTP_Remote_Address *remote_addr, SourceParameters *params)
|
||||
static void
|
||||
resolve_sources(void *arg)
|
||||
{
|
||||
int slot, found;
|
||||
NTP_Remote_Address address;
|
||||
struct UnresolvedSource *us, **i;
|
||||
DNS_Status s;
|
||||
|
||||
assert(initialised);
|
||||
memset(&address.local_ip_addr, 0, sizeof (address.local_ip_addr));
|
||||
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_NtpSources, "IP=%08lx port=%d", (unsigned long) remote_addr->ip_addr, remote_addr->port);
|
||||
#endif
|
||||
DNS_Reload();
|
||||
|
||||
/* Find empty bin & check that we don't have the address already */
|
||||
find_slot(remote_addr, &slot, &found);
|
||||
if (found) {
|
||||
return NSR_AlreadyInUse;
|
||||
} else {
|
||||
if (n_sources == MAX_SOURCES) {
|
||||
return NSR_TooManySources;
|
||||
for (i = &unresolved_sources; *i; ) {
|
||||
us = *i;
|
||||
s = DNS_Name2IPAddress(us->name, &address.ip_addr);
|
||||
if (s == DNS_TryAgain) {
|
||||
i = &(*i)->next;
|
||||
continue;
|
||||
} else if (s == DNS_Success) {
|
||||
address.port = us->port;
|
||||
NSR_AddSource(&address, us->type, &us->params);
|
||||
} else {
|
||||
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 */
|
||||
return NSR_Success;
|
||||
LOG(LOGS_WARN, LOGF_NtpSources, "Invalid host %s", us->name);
|
||||
}
|
||||
|
||||
*i = us->next;
|
||||
|
||||
Free(us->name);
|
||||
Free(us);
|
||||
}
|
||||
|
||||
if (unresolved_sources) {
|
||||
/* Try again later */
|
||||
if (resolving_interval < 9)
|
||||
resolving_interval++;
|
||||
resolving_id = SCH_AddTimeoutByDelay(7 * (1 << resolving_interval), resolve_sources, NULL);
|
||||
} else {
|
||||
resolving_interval = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
/* Procedure to add a new server or peer source, but instead of an IP address
|
||||
only a name is provided */
|
||||
void
|
||||
NSR_AddUnresolvedSource(char *name, int port, NTP_Source_Type type, SourceParameters *params)
|
||||
{
|
||||
struct UnresolvedSource *us, **i;
|
||||
|
||||
us = MallocNew(struct UnresolvedSource);
|
||||
|
||||
us->name = name;
|
||||
us->port = port;
|
||||
us->type = type;
|
||||
us->params = *params;
|
||||
us->next = NULL;
|
||||
|
||||
for (i = &unresolved_sources; *i; i = &(*i)->next)
|
||||
;
|
||||
*i = us;
|
||||
|
||||
if (!resolving_interval) {
|
||||
resolving_interval = 2;
|
||||
resolving_id = SCH_AddTimeoutByDelay(7 * (1 << resolving_interval), resolve_sources, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
NSR_ResolveSources(void)
|
||||
{
|
||||
/* Try to resolve unresolved sources now */
|
||||
if (resolving_interval) {
|
||||
SCH_RemoveTimeout(resolving_id);
|
||||
resolving_interval--;
|
||||
resolve_sources(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,26 +302,49 @@ NSR_AddPeer(NTP_Remote_Address *remote_addr, SourceParameters *params)
|
||||
NSR_Status
|
||||
NSR_RemoveSource(NTP_Remote_Address *remote_addr)
|
||||
{
|
||||
int slot, found;
|
||||
int i, slot, found;
|
||||
SourceRecord temp_records[N_RECORDS];
|
||||
|
||||
assert(initialised);
|
||||
|
||||
find_slot(remote_addr, &slot, &found);
|
||||
if (!found) {
|
||||
return NSR_NoSuchSource;
|
||||
} else {
|
||||
n_sources--;
|
||||
records[slot].in_use = 0;
|
||||
NCR_DestroyInstance(records[slot].data);
|
||||
return NSR_Success;
|
||||
}
|
||||
|
||||
n_sources--;
|
||||
records[slot].remote_addr = NULL;
|
||||
NCR_DestroyInstance(records[slot].data);
|
||||
|
||||
/* Rehash the table to make sure there are no broken probe sequences.
|
||||
This is costly, but it's not expected to happen frequently. */
|
||||
|
||||
memcpy(temp_records, records, sizeof (records));
|
||||
|
||||
for (i = 0; i < N_RECORDS; i++) {
|
||||
records[i].remote_addr = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < N_RECORDS; i++) {
|
||||
if (!temp_records[i].remote_addr)
|
||||
continue;
|
||||
|
||||
find_slot(temp_records[i].remote_addr, &slot, &found);
|
||||
assert(!found);
|
||||
|
||||
records[slot].remote_addr = temp_records[i].remote_addr;
|
||||
records[slot].data = temp_records[i].data;
|
||||
}
|
||||
|
||||
return NSR_Success;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
/* This routine is called by ntp_io when a new packet arrives off the network.*/
|
||||
/* This routine is called by ntp_io when a new packet arrives off the network,
|
||||
possibly with an authentication tail */
|
||||
void
|
||||
NSR_ProcessReceive(NTP_Packet *message, struct timeval *now, NTP_Remote_Address *remote_addr)
|
||||
NSR_ProcessReceive(NTP_Packet *message, struct timeval *now, double now_err, NTP_Remote_Address *remote_addr, int length)
|
||||
{
|
||||
int slot, found;
|
||||
|
||||
@@ -249,33 +352,15 @@ NSR_ProcessReceive(NTP_Packet *message, struct timeval *now, NTP_Remote_Address
|
||||
|
||||
#if 0
|
||||
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));
|
||||
#endif
|
||||
|
||||
find_slot(remote_addr, &slot, &found);
|
||||
if (found == 2) { /* Must match IP address AND port number */
|
||||
NCR_ProcessNoauthKnown(message, now, records[slot].data);
|
||||
NCR_ProcessKnown(message, now, now_err, records[slot].data, length);
|
||||
} else {
|
||||
NCR_ProcessNoauthUnknown(message, now, remote_addr);
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
/* This routine is called by ntp_io when a new packet with an authentication tail arrives off the network */
|
||||
void
|
||||
NSR_ProcessAuthenticatedReceive(NTP_Packet *message, struct timeval *now, NTP_Remote_Address *remote_addr)
|
||||
{
|
||||
int slot, found;
|
||||
|
||||
assert(initialised);
|
||||
|
||||
find_slot(remote_addr, &slot, &found);
|
||||
if (found == 2) {
|
||||
NCR_ProcessAuthKnown(message, now, records[slot].data);
|
||||
} else {
|
||||
NCR_ProcessAuthUnknown(message, now, remote_addr);
|
||||
NCR_ProcessUnknown(message, now, now_err, remote_addr, length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,7 +370,6 @@ static void
|
||||
slew_sources(struct timeval *raw,
|
||||
struct timeval *cooked,
|
||||
double dfreq,
|
||||
double afreq,
|
||||
double doffset,
|
||||
int is_step_change,
|
||||
void *anything)
|
||||
@@ -293,10 +377,10 @@ slew_sources(struct timeval *raw,
|
||||
int i;
|
||||
|
||||
for (i=0; i<N_RECORDS; i++) {
|
||||
if (records[i].in_use) {
|
||||
if (records[i].remote_addr) {
|
||||
#if 0
|
||||
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
|
||||
|
||||
NCR_SlewTimes(records[i].data, cooked, dfreq, doffset);
|
||||
@@ -308,43 +392,30 @@ slew_sources(struct timeval *raw,
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
NSR_TakeSourcesOnline(unsigned long mask, unsigned long address)
|
||||
NSR_TakeSourcesOnline(IPAddr *mask, IPAddr *address)
|
||||
{
|
||||
int i;
|
||||
int any;
|
||||
unsigned long ip;
|
||||
|
||||
NSR_ResolveSources();
|
||||
|
||||
any = 0;
|
||||
for (i=0; i<N_RECORDS; i++) {
|
||||
if (records[i].in_use) {
|
||||
ip = records[i].remote_addr.ip_addr;
|
||||
if ((ip & mask) == address) {
|
||||
if (records[i].remote_addr) {
|
||||
if (address->family == IPADDR_UNSPEC ||
|
||||
!UTI_CompareIPs(&records[i].remote_addr->ip_addr, address, mask)) {
|
||||
any = 1;
|
||||
NCR_TakeSourceOnline(records[i].data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return any;
|
||||
}
|
||||
if (address->family == IPADDR_UNSPEC) {
|
||||
struct UnresolvedSource *us;
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
NSR_TakeSourcesOffline(unsigned long mask, unsigned long address)
|
||||
{
|
||||
int i;
|
||||
int any;
|
||||
unsigned long ip;
|
||||
|
||||
any = 0;
|
||||
for (i=0; i<N_RECORDS; i++) {
|
||||
if (records[i].in_use) {
|
||||
ip = records[i].remote_addr.ip_addr;
|
||||
if ((ip & mask) == address) {
|
||||
any = 1;
|
||||
NCR_TakeSourceOffline(records[i].data);
|
||||
}
|
||||
for (us = unresolved_sources; us; us = us->next) {
|
||||
any = 1;
|
||||
us->params.online = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,11 +425,51 @@ NSR_TakeSourcesOffline(unsigned long mask, unsigned long address)
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
NSR_ModifyMinpoll(unsigned long address, int new_minpoll)
|
||||
NSR_TakeSourcesOffline(IPAddr *mask, IPAddr *address)
|
||||
{
|
||||
int i, any, syncpeer;
|
||||
|
||||
any = 0;
|
||||
syncpeer = -1;
|
||||
for (i=0; i<N_RECORDS; i++) {
|
||||
if (records[i].remote_addr) {
|
||||
if (address->family == IPADDR_UNSPEC ||
|
||||
!UTI_CompareIPs(&records[i].remote_addr->ip_addr, address, mask)) {
|
||||
any = 1;
|
||||
if (NCR_IsSyncPeer(records[i].data)) {
|
||||
syncpeer = i;
|
||||
continue;
|
||||
}
|
||||
NCR_TakeSourceOffline(records[i].data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Take sync peer offline as last to avoid reference switching */
|
||||
if (syncpeer >= 0) {
|
||||
NCR_TakeSourceOffline(records[syncpeer].data);
|
||||
}
|
||||
|
||||
if (address->family == IPADDR_UNSPEC) {
|
||||
struct UnresolvedSource *us;
|
||||
|
||||
for (us = unresolved_sources; us; us = us->next) {
|
||||
any = 1;
|
||||
us->params.online = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return any;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
NSR_ModifyMinpoll(IPAddr *address, int new_minpoll)
|
||||
{
|
||||
int slot, found;
|
||||
NTP_Remote_Address addr;
|
||||
addr.ip_addr = address;
|
||||
addr.ip_addr = *address;
|
||||
addr.port = 0;
|
||||
|
||||
find_slot(&addr, &slot, &found);
|
||||
@@ -373,11 +484,11 @@ NSR_ModifyMinpoll(unsigned long address, int new_minpoll)
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
NSR_ModifyMaxpoll(unsigned long address, int new_maxpoll)
|
||||
NSR_ModifyMaxpoll(IPAddr *address, int new_maxpoll)
|
||||
{
|
||||
int slot, found;
|
||||
NTP_Remote_Address addr;
|
||||
addr.ip_addr = address;
|
||||
addr.ip_addr = *address;
|
||||
addr.port = 0;
|
||||
|
||||
find_slot(&addr, &slot, &found);
|
||||
@@ -392,11 +503,11 @@ NSR_ModifyMaxpoll(unsigned long address, int new_maxpoll)
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
NSR_ModifyMaxdelay(unsigned long address, double new_max_delay)
|
||||
NSR_ModifyMaxdelay(IPAddr *address, double new_max_delay)
|
||||
{
|
||||
int slot, found;
|
||||
NTP_Remote_Address addr;
|
||||
addr.ip_addr = address;
|
||||
addr.ip_addr = *address;
|
||||
addr.port = 0;
|
||||
|
||||
find_slot(&addr, &slot, &found);
|
||||
@@ -411,11 +522,11 @@ NSR_ModifyMaxdelay(unsigned long address, double new_max_delay)
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
NSR_ModifyMaxdelayratio(unsigned long address, double new_max_delay_ratio)
|
||||
NSR_ModifyMaxdelayratio(IPAddr *address, double new_max_delay_ratio)
|
||||
{
|
||||
int slot, found;
|
||||
NTP_Remote_Address addr;
|
||||
addr.ip_addr = address;
|
||||
addr.ip_addr = *address;
|
||||
addr.port = 0;
|
||||
|
||||
find_slot(&addr, &slot, &found);
|
||||
@@ -429,19 +540,75 @@ NSR_ModifyMaxdelayratio(unsigned long address, double new_max_delay_ratio)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
NSR_ModifyMaxdelaydevratio(IPAddr *address, double new_max_delay_dev_ratio)
|
||||
{
|
||||
int slot, found;
|
||||
NTP_Remote_Address addr;
|
||||
addr.ip_addr = *address;
|
||||
addr.port = 0;
|
||||
|
||||
find_slot(&addr, &slot, &found);
|
||||
if (found == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
NCR_ModifyMaxdelaydevratio(records[slot].data, new_max_delay_dev_ratio);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
NSR_ModifyMinstratum(IPAddr *address, int new_min_stratum)
|
||||
{
|
||||
int slot, found;
|
||||
NTP_Remote_Address addr;
|
||||
addr.ip_addr = *address;
|
||||
addr.port = 0;
|
||||
|
||||
find_slot(&addr, &slot, &found);
|
||||
if (found == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
NCR_ModifyMinstratum(records[slot].data, new_min_stratum);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
NSR_ModifyPolltarget(IPAddr *address, int new_poll_target)
|
||||
{
|
||||
int slot, found;
|
||||
NTP_Remote_Address addr;
|
||||
addr.ip_addr = *address;
|
||||
addr.port = 0;
|
||||
|
||||
find_slot(&addr, &slot, &found);
|
||||
if (found == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
NCR_ModifyPolltarget(records[slot].data, new_poll_target);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int
|
||||
NSR_InitiateSampleBurst(int n_good_samples, int n_total_samples,
|
||||
unsigned long mask, unsigned long address)
|
||||
IPAddr *mask, IPAddr *address)
|
||||
{
|
||||
int i;
|
||||
int any;
|
||||
unsigned long ip;
|
||||
|
||||
any = 0;
|
||||
for (i=0; i<N_RECORDS; i++) {
|
||||
if (records[i].in_use) {
|
||||
ip = records[i].remote_addr.ip_addr;
|
||||
if ((ip & mask) == address) {
|
||||
if (records[i].remote_addr) {
|
||||
if (address->family == IPADDR_UNSPEC ||
|
||||
!UTI_CompareIPs(&records[i].remote_addr->ip_addr, address, mask)) {
|
||||
any = 1;
|
||||
NCR_InitiateSampleBurst(records[i].data, n_good_samples, n_total_samples);
|
||||
}
|
||||
@@ -479,6 +646,7 @@ void
|
||||
NSR_GetActivityReport(RPT_ActivityReport *report)
|
||||
{
|
||||
int i;
|
||||
struct UnresolvedSource *us;
|
||||
|
||||
report->online = 0;
|
||||
report->offline = 0;
|
||||
@@ -486,12 +654,17 @@ NSR_GetActivityReport(RPT_ActivityReport *report)
|
||||
report->burst_offline = 0;
|
||||
|
||||
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,
|
||||
&report->burst_online, &report->burst_offline);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
report->unresolved = 0;
|
||||
|
||||
for (us = unresolved_sources; us; us = us->next) {
|
||||
report->unresolved++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/ntp_sources.h,v 1.12 2002/02/28 23:27:12 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -45,26 +41,27 @@
|
||||
typedef enum {
|
||||
NSR_Success, /* Operation successful */
|
||||
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_TooManySources /* AddServer, AddPeer - too many sources already present */
|
||||
NSR_AlreadyInUse, /* AddSource - attempt to add a source that is already known */
|
||||
NSR_TooManySources, /* AddSource - too many sources already present */
|
||||
NSR_InvalidAF /* AddSource - attempt to add a source with invalid address family */
|
||||
} NSR_Status;
|
||||
|
||||
/* Procedure to add a new server source (to which this machine will be
|
||||
a client) */
|
||||
extern NSR_Status NSR_AddServer(NTP_Remote_Address *remote_addr, SourceParameters *params);
|
||||
/* Procedure to add a new server or peer source. */
|
||||
extern NSR_Status NSR_AddSource(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourceParameters *params);
|
||||
|
||||
/* Procedure to add a new peer source. We will use symmetric active
|
||||
mode packets when communicating with this source */
|
||||
extern NSR_Status NSR_AddPeer(NTP_Remote_Address *remote_addr, SourceParameters *params);
|
||||
/* Procedure to add a new server or peer source with currently unknown address.
|
||||
The name will be periodically resolved in exponentially increasing intervals
|
||||
until it succeeds or fails with a non-temporary error. */
|
||||
extern void NSR_AddUnresolvedSource(char *name, int port, NTP_Source_Type type, SourceParameters *params);
|
||||
|
||||
/* Procedure to try resolve unresolved sources immediately. */
|
||||
extern void NSR_ResolveSources(void);
|
||||
|
||||
/* Procedure to remove a source */
|
||||
extern NSR_Status NSR_RemoveSource(NTP_Remote_Address *remote_addr);
|
||||
|
||||
/* This routine is called by ntp_io when a new packet arrives off the network */
|
||||
extern void NSR_ProcessReceive(NTP_Packet *message, struct timeval *now, NTP_Remote_Address *remote_addr);
|
||||
|
||||
/* This routine is called by ntp_io when a new packet with an authentication tail arrives off the network */
|
||||
extern void NSR_ProcessAuthenticatedReceive(NTP_Packet *message, struct timeval *now, NTP_Remote_Address *remote_addr);
|
||||
extern void NSR_ProcessReceive(NTP_Packet *message, struct timeval *now, double now_err, NTP_Remote_Address *remote_addr, int length);
|
||||
|
||||
/* Initialisation function */
|
||||
extern void NSR_Initialise(void);
|
||||
@@ -75,22 +72,28 @@ extern void NSR_Finalise(void);
|
||||
/* This routine is used to indicate that sources whose IP addresses
|
||||
match a particular subnet should be set online again. Returns a
|
||||
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
|
||||
match a particular subnet should be set offline. Returns a flag
|
||||
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_ModifyMaxdelaydevratio(IPAddr *address, double new_max_delay_ratio);
|
||||
|
||||
extern int NSR_ModifyMinstratum(IPAddr *address, int new_min_stratum);
|
||||
|
||||
extern int NSR_ModifyPolltarget(IPAddr *address, int new_poll_target);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
56
pktlength.c
56
pktlength.c
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/pktlength.c,v 1.12 2002/02/28 23:27:12 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -30,6 +26,8 @@
|
||||
integer endianness within the structures.
|
||||
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "util.h"
|
||||
@@ -65,6 +63,8 @@ PKL_CommandLength(CMD_Request *r)
|
||||
return offsetof(CMD_Request, data.modify_maxdelay.EOR);
|
||||
case REQ_MODIFY_MAXDELAYRATIO:
|
||||
return offsetof(CMD_Request, data.modify_maxdelayratio.EOR);
|
||||
case REQ_MODIFY_MAXDELAYDEVRATIO:
|
||||
return offsetof(CMD_Request, data.modify_maxdelaydevratio.EOR);
|
||||
case REQ_MODIFY_MAXUPDATESKEW:
|
||||
return offsetof(CMD_Request, data.modify_maxupdateskew.EOR);
|
||||
case REQ_LOGON :
|
||||
@@ -124,19 +124,9 @@ PKL_CommandLength(CMD_Request *r)
|
||||
case REQ_CYCLELOGS :
|
||||
return offsetof(CMD_Request, data.cyclelogs.EOR);
|
||||
case REQ_SUBNETS_ACCESSED :
|
||||
{
|
||||
unsigned long ns;
|
||||
ns = ntohl(r->data.subnets_accessed.n_subnets);
|
||||
return (offsetof(CMD_Request, data.subnets_accessed.subnets) +
|
||||
ns * sizeof(REQ_SubnetsAccessed_Subnet));
|
||||
}
|
||||
case REQ_CLIENT_ACCESSES:
|
||||
{
|
||||
unsigned long nc;
|
||||
nc = ntohl(r->data.client_accesses.n_clients);
|
||||
return (offsetof(CMD_Request, data.client_accesses.client_ips) +
|
||||
nc * sizeof(unsigned long));
|
||||
}
|
||||
/* No longer supported */
|
||||
return 0;
|
||||
case REQ_CLIENT_ACCESSES_BY_INDEX:
|
||||
return offsetof(CMD_Request, data.client_accesses_by_index.EOR);
|
||||
case REQ_MANUAL_LIST:
|
||||
@@ -147,6 +137,14 @@ PKL_CommandLength(CMD_Request *r)
|
||||
return offsetof(CMD_Request, data.make_step.EOR);
|
||||
case REQ_ACTIVITY:
|
||||
return offsetof(CMD_Request, data.activity.EOR);
|
||||
case REQ_RESELECT:
|
||||
return offsetof(CMD_Request, data.reselect.EOR);
|
||||
case REQ_RESELECTDISTANCE:
|
||||
return offsetof(CMD_Request, data.reselect_distance.EOR);
|
||||
case REQ_MODIFY_MINSTRATUM:
|
||||
return offsetof(CMD_Request, data.modify_minstratum.EOR);
|
||||
case REQ_MODIFY_POLLTARGET:
|
||||
return offsetof(CMD_Request, data.modify_polltarget.EOR);
|
||||
default:
|
||||
/* If we fall through the switch, it most likely means we've forgotten to implement a new case */
|
||||
assert(0);
|
||||
@@ -186,29 +184,15 @@ PKL_ReplyLength(CMD_Reply *r)
|
||||
case RPY_RTC:
|
||||
return offsetof(CMD_Reply, data.rtc.EOR);
|
||||
case RPY_SUBNETS_ACCESSED :
|
||||
{
|
||||
unsigned long ns = ntohl(r->data.subnets_accessed.n_subnets);
|
||||
if (r->status == htons(STT_SUCCESS)) {
|
||||
return (offsetof(CMD_Reply, data.subnets_accessed.subnets) +
|
||||
ns * sizeof(RPY_SubnetsAccessed_Subnet));
|
||||
} else {
|
||||
return offsetof(CMD_Reply, data);
|
||||
}
|
||||
}
|
||||
case RPY_CLIENT_ACCESSES:
|
||||
{
|
||||
unsigned long nc = ntohl(r->data.client_accesses.n_clients);
|
||||
if (r->status == htons(STT_SUCCESS)) {
|
||||
return (offsetof(CMD_Reply, data.client_accesses.clients) +
|
||||
nc * sizeof(RPY_ClientAccesses_Client));
|
||||
} else {
|
||||
return offsetof(CMD_Reply, data);
|
||||
}
|
||||
}
|
||||
/* No longer supported */
|
||||
return 0;
|
||||
case RPY_CLIENT_ACCESSES_BY_INDEX:
|
||||
{
|
||||
unsigned long nc = ntohl(r->data.client_accesses_by_index.n_clients);
|
||||
if (r->status == htons(STT_SUCCESS)) {
|
||||
if (nc > MAX_CLIENT_ACCESSES)
|
||||
return 0;
|
||||
return (offsetof(CMD_Reply, data.client_accesses_by_index.clients) +
|
||||
nc * sizeof(RPY_ClientAccesses_Client));
|
||||
} else {
|
||||
@@ -218,6 +202,8 @@ PKL_ReplyLength(CMD_Reply *r)
|
||||
case RPY_MANUAL_LIST:
|
||||
{
|
||||
unsigned long ns = ntohl(r->data.manual_list.n_samples);
|
||||
if (ns > MAX_MANUAL_LIST_SAMPLES)
|
||||
return 0;
|
||||
if (r->status == htons(STT_SUCCESS)) {
|
||||
return (offsetof(CMD_Reply, data.manual_list.samples) +
|
||||
ns * sizeof(RPY_ManualListSample));
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/pktlength.h,v 1.4 2002/02/28 23:27:12 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
|
||||
898
refclock.c
Normal file
898
refclock.c
Normal file
@@ -0,0 +1,898 @@
|
||||
/*
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Miroslav Lichvar 2009-2011
|
||||
*
|
||||
* 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 "config.h"
|
||||
|
||||
#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 "regress.h"
|
||||
#include "sched.h"
|
||||
|
||||
/* list of refclock drivers */
|
||||
extern RefclockDriver RCL_SHM_driver;
|
||||
extern RefclockDriver RCL_SOCK_driver;
|
||||
extern RefclockDriver RCL_PPS_driver;
|
||||
|
||||
struct FilterSample {
|
||||
double offset;
|
||||
double dispersion;
|
||||
struct timeval sample_time;
|
||||
};
|
||||
|
||||
struct MedianFilter {
|
||||
int length;
|
||||
int index;
|
||||
int used;
|
||||
int last;
|
||||
int avg_var_n;
|
||||
double avg_var;
|
||||
struct FilterSample *samples;
|
||||
int *selected;
|
||||
double *x_data;
|
||||
double *y_data;
|
||||
double *w_data;
|
||||
};
|
||||
|
||||
struct RCL_Instance_Record {
|
||||
RefclockDriver *driver;
|
||||
void *data;
|
||||
char *driver_parameter;
|
||||
int driver_parameter_length;
|
||||
int driver_poll;
|
||||
int driver_polled;
|
||||
int poll;
|
||||
int leap_status;
|
||||
int pps_rate;
|
||||
struct MedianFilter filter;
|
||||
uint32_t ref_id;
|
||||
uint32_t lock_ref;
|
||||
double offset;
|
||||
double delay;
|
||||
double precision;
|
||||
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;
|
||||
|
||||
static LOG_FileID logfileid;
|
||||
|
||||
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 doffset, int is_step_change, void *anything);
|
||||
static void add_dispersion(double dispersion, void *anything);
|
||||
static void log_sample(RCL_Instance instance, struct timeval *sample_time, int filtered, int pulse, double raw_offset, double cooked_offset, double dispersion);
|
||||
|
||||
static void filter_init(struct MedianFilter *filter, int length);
|
||||
static void filter_fini(struct MedianFilter *filter);
|
||||
static void filter_reset(struct MedianFilter *filter);
|
||||
static double filter_get_avg_sample_dispersion(struct MedianFilter *filter);
|
||||
static void filter_add_sample(struct MedianFilter *filter, struct timeval *sample_time, double offset, double dispersion);
|
||||
static int filter_get_last_sample(struct MedianFilter *filter, struct timeval *sample_time, double *offset, double *dispersion);
|
||||
static int filter_select_samples(struct MedianFilter *filter);
|
||||
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);
|
||||
static void filter_add_dispersion(struct MedianFilter *filter, double dispersion);
|
||||
|
||||
void
|
||||
RCL_Initialise(void)
|
||||
{
|
||||
CNF_AddRefclocks();
|
||||
|
||||
if (n_sources > 0) {
|
||||
LCL_AddParameterChangeHandler(slew_samples, NULL);
|
||||
LCL_AddDispersionNotifyHandler(add_dispersion, NULL);
|
||||
}
|
||||
|
||||
logfileid = CNF_GetLogRefclocks() ? LOG_FileOpen("refclocks",
|
||||
" Date (UTC) Time Refid DP L P Raw offset Cooked offset Disp.")
|
||||
: -1;
|
||||
}
|
||||
|
||||
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);
|
||||
LCL_RemoveDispersionNotifyHandler(add_dispersion, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
RCL_AddRefclock(RefclockParameters *params)
|
||||
{
|
||||
int pps_source = 0;
|
||||
|
||||
RCL_Instance inst = &refclocks[n_sources];
|
||||
|
||||
if (n_sources == MAX_RCL_SOURCES)
|
||||
return 0;
|
||||
|
||||
if (strcmp(params->driver_name, "SHM") == 0) {
|
||||
inst->driver = &RCL_SHM_driver;
|
||||
inst->precision = 1e-6;
|
||||
} else if (strcmp(params->driver_name, "SOCK") == 0) {
|
||||
inst->driver = &RCL_SOCK_driver;
|
||||
inst->precision = 1e-9;
|
||||
pps_source = 1;
|
||||
} else if (strcmp(params->driver_name, "PPS") == 0) {
|
||||
inst->driver = &RCL_PPS_driver;
|
||||
inst->precision = 1e-9;
|
||||
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_parameter_length = 0;
|
||||
inst->driver_poll = params->driver_poll;
|
||||
inst->poll = params->poll;
|
||||
inst->driver_polled = 0;
|
||||
inst->leap_status = LEAP_Normal;
|
||||
inst->pps_rate = params->pps_rate;
|
||||
inst->lock_ref = params->lock_ref_id;
|
||||
inst->offset = params->offset;
|
||||
inst->delay = params->delay;
|
||||
if (params->precision > 0.0)
|
||||
inst->precision = params->precision;
|
||||
inst->timeout_id = -1;
|
||||
inst->source = NULL;
|
||||
|
||||
if (inst->driver_parameter) {
|
||||
int i;
|
||||
|
||||
inst->driver_parameter_length = strlen(inst->driver_parameter);
|
||||
for (i = 0; i < inst->driver_parameter_length; i++)
|
||||
if (inst->driver_parameter[i] == ':')
|
||||
inst->driver_parameter[i] = '\0';
|
||||
}
|
||||
|
||||
if (pps_source) {
|
||||
if (inst->pps_rate < 1)
|
||||
inst->pps_rate = 1;
|
||||
} else {
|
||||
inst->pps_rate = 0;
|
||||
}
|
||||
|
||||
if (params->ref_id)
|
||||
inst->ref_id = params->ref_id;
|
||||
else {
|
||||
unsigned char ref[5] = { 0, 0, 0, 0, 0 };
|
||||
|
||||
snprintf((char *)ref, 5, "%3.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->poll) {
|
||||
int max_samples;
|
||||
|
||||
if (inst->driver_poll > inst->poll)
|
||||
inst->driver_poll = inst->poll;
|
||||
|
||||
max_samples = 1 << (inst->poll - inst->driver_poll);
|
||||
if (max_samples < params->filter_length) {
|
||||
if (max_samples < 4) {
|
||||
LOG(LOGS_WARN, LOGF_Refclock, "Setting filter length for %s to %d",
|
||||
UTI_RefidToString(inst->ref_id), max_samples);
|
||||
}
|
||||
params->filter_length = max_samples;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
inst->source = SRC_CreateNewInstance(inst->ref_id, SRC_REFCLOCK, params->sel_option, NULL);
|
||||
|
||||
#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++;
|
||||
|
||||
Free(params->driver_name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
RCL_StartRefclocks(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < n_sources; i++) {
|
||||
RCL_Instance inst = &refclocks[i];
|
||||
|
||||
SRC_SetSelectable(inst->source);
|
||||
inst->timeout_id = SCH_AddTimeoutByDelay(0.0, poll_timeout, (void *)inst);
|
||||
|
||||
if (inst->lock_ref) {
|
||||
/* Replace lock refid with index to refclocks */
|
||||
for (j = 0; j < n_sources && refclocks[j].ref_id != inst->lock_ref; j++)
|
||||
;
|
||||
inst->lock_ref = (j < n_sources) ? j : -1;
|
||||
} else
|
||||
inst->lock_ref = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RCL_ReportSource(RPT_SourceReport *report, struct timeval *now)
|
||||
{
|
||||
int i;
|
||||
uint32_t 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;
|
||||
}
|
||||
|
||||
char *
|
||||
RCL_GetDriverOption(RCL_Instance instance, char *name)
|
||||
{
|
||||
char *s, *e;
|
||||
int n;
|
||||
|
||||
s = instance->driver_parameter;
|
||||
e = s + instance->driver_parameter_length;
|
||||
n = strlen(name);
|
||||
|
||||
while (1) {
|
||||
s += strlen(s) + 1;
|
||||
if (s >= e)
|
||||
break;
|
||||
if (!strncmp(name, s, n)) {
|
||||
if (s[n] == '=')
|
||||
return s + n + 1;
|
||||
if (s[n] == '\0')
|
||||
return s + n;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
RCL_AddSample(RCL_Instance instance, struct timeval *sample_time, double offset, int leap)
|
||||
{
|
||||
double correction, dispersion;
|
||||
struct timeval cooked_time;
|
||||
|
||||
LCL_GetOffsetCorrection(sample_time, &correction, &dispersion);
|
||||
UTI_AddDoubleToTimeval(sample_time, correction, &cooked_time);
|
||||
dispersion += instance->precision + filter_get_avg_sample_dispersion(&instance->filter);
|
||||
|
||||
if (!valid_sample_time(instance, sample_time))
|
||||
return 0;
|
||||
|
||||
filter_add_sample(&instance->filter, &cooked_time, offset - correction + instance->offset, dispersion);
|
||||
|
||||
switch (leap) {
|
||||
case LEAP_Normal:
|
||||
case LEAP_InsertSecond:
|
||||
case LEAP_DeleteSecond:
|
||||
instance->leap_status = leap;
|
||||
break;
|
||||
default:
|
||||
instance->leap_status = LEAP_Unsynchronised;
|
||||
break;
|
||||
}
|
||||
|
||||
log_sample(instance, &cooked_time, 0, 0, offset, offset - correction + instance->offset, dispersion);
|
||||
|
||||
/* for logging purposes */
|
||||
if (!instance->driver->poll)
|
||||
instance->driver_polled++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
RCL_AddPulse(RCL_Instance instance, struct timeval *pulse_time, double second)
|
||||
{
|
||||
double correction, dispersion, offset;
|
||||
struct timeval cooked_time;
|
||||
int rate;
|
||||
|
||||
LCL_GetOffsetCorrection(pulse_time, &correction, &dispersion);
|
||||
UTI_AddDoubleToTimeval(pulse_time, correction, &cooked_time);
|
||||
dispersion += instance->precision + filter_get_avg_sample_dispersion(&instance->filter);
|
||||
|
||||
if (!valid_sample_time(instance, pulse_time))
|
||||
return 0;
|
||||
|
||||
rate = instance->pps_rate;
|
||||
assert(rate > 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 (instance->lock_ref != -1) {
|
||||
struct timeval ref_sample_time;
|
||||
double sample_diff, ref_offset, ref_dispersion, shift;
|
||||
|
||||
if (!filter_get_last_sample(&refclocks[instance->lock_ref].filter,
|
||||
&ref_sample_time, &ref_offset, &ref_dispersion))
|
||||
return 0;
|
||||
|
||||
UTI_DiffTimevalsToDouble(&sample_diff, &cooked_time, &ref_sample_time);
|
||||
if (fabs(sample_diff) >= 2.0 / rate)
|
||||
return 0;
|
||||
|
||||
/* Align the offset to the reference sample */
|
||||
if ((ref_offset - offset) >= 0.0)
|
||||
shift = (long)((ref_offset - offset) * rate + 0.5) / (double)rate;
|
||||
else
|
||||
shift = (long)((ref_offset - offset) * rate - 0.5) / (double)rate;
|
||||
|
||||
offset += shift;
|
||||
|
||||
if (fabs(ref_offset - offset) + ref_dispersion + dispersion >= 0.2 / rate)
|
||||
return 0;
|
||||
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_Refclock, "refclock pulse second=%.9f offset=%.9f offdiff=%.9f samplediff=%.9f",
|
||||
second, offset, ref_offset - offset, sample_diff);
|
||||
#endif
|
||||
} else {
|
||||
struct timeval ref_time;
|
||||
int is_synchronised, stratum;
|
||||
double root_delay, root_dispersion, distance;
|
||||
NTP_Leap leap;
|
||||
uint32_t ref_id;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
filter_add_sample(&instance->filter, &cooked_time, offset, dispersion);
|
||||
instance->leap_status = LEAP_Normal;
|
||||
|
||||
log_sample(instance, &cooked_time, 0, 1, offset + correction - instance->offset, offset, dispersion);
|
||||
|
||||
/* for logging purposes */
|
||||
if (!instance->driver->poll)
|
||||
instance->driver_polled++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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;
|
||||
uint32_t 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 && refclocks[i].lock_ref == -1)
|
||||
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);
|
||||
inst->driver_polled = 0;
|
||||
|
||||
if (sample_ok) {
|
||||
if (inst->pps_rate && inst->lock_ref == -1)
|
||||
/* Handle special case when PPS is used with local stratum */
|
||||
stratum = pps_stratum(inst, &sample_time);
|
||||
else
|
||||
stratum = 0;
|
||||
|
||||
SRC_UpdateReachability(inst->source, 1);
|
||||
SRC_AccumulateSample(inst->source, &sample_time, offset,
|
||||
inst->delay, dispersion, inst->delay, dispersion, stratum, inst->leap_status);
|
||||
|
||||
log_sample(inst, &sample_time, 1, 0, 0.0, offset, dispersion);
|
||||
} else {
|
||||
SRC_UpdateReachability(inst->source, 0);
|
||||
}
|
||||
}
|
||||
|
||||
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 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
|
||||
add_dispersion(double dispersion, void *anything)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_sources; i++)
|
||||
filter_add_dispersion(&refclocks[i].filter, dispersion);
|
||||
}
|
||||
|
||||
static void
|
||||
log_sample(RCL_Instance instance, struct timeval *sample_time, int filtered, int pulse, double raw_offset, double cooked_offset, double dispersion)
|
||||
{
|
||||
char sync_stats[4] = {'N', '+', '-', '?'};
|
||||
|
||||
if (logfileid == -1)
|
||||
return;
|
||||
|
||||
if (!filtered) {
|
||||
LOG_FileWrite(logfileid, "%s.%06d %-5s %3d %1c %1d %13.6e %13.6e %10.3e",
|
||||
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,
|
||||
dispersion);
|
||||
} else {
|
||||
LOG_FileWrite(logfileid, "%s.%06d %-5s - %1c - - %13.6e %10.3e",
|
||||
UTI_TimeToLogForm(sample_time->tv_sec),
|
||||
(int)sample_time->tv_usec,
|
||||
UTI_RefidToString(instance->ref_id),
|
||||
sync_stats[instance->leap_status],
|
||||
cooked_offset,
|
||||
dispersion);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
filter_init(struct MedianFilter *filter, int length)
|
||||
{
|
||||
if (length < 1)
|
||||
length = 1;
|
||||
|
||||
filter->length = length;
|
||||
filter->index = -1;
|
||||
filter->used = 0;
|
||||
filter->last = -1;
|
||||
/* set first estimate to system precision */
|
||||
filter->avg_var_n = 0;
|
||||
filter->avg_var = LCL_GetSysPrecisionAsQuantum() * LCL_GetSysPrecisionAsQuantum();
|
||||
filter->samples = MallocArray(struct FilterSample, filter->length);
|
||||
filter->selected = MallocArray(int, filter->length);
|
||||
filter->x_data = MallocArray(double, filter->length);
|
||||
filter->y_data = MallocArray(double, filter->length);
|
||||
filter->w_data = MallocArray(double, filter->length);
|
||||
}
|
||||
|
||||
static void
|
||||
filter_fini(struct MedianFilter *filter)
|
||||
{
|
||||
Free(filter->samples);
|
||||
Free(filter->selected);
|
||||
Free(filter->x_data);
|
||||
Free(filter->y_data);
|
||||
Free(filter->w_data);
|
||||
}
|
||||
|
||||
static void
|
||||
filter_reset(struct MedianFilter *filter)
|
||||
{
|
||||
filter->index = -1;
|
||||
filter->used = 0;
|
||||
}
|
||||
|
||||
static double
|
||||
filter_get_avg_sample_dispersion(struct MedianFilter *filter)
|
||||
{
|
||||
return sqrt(filter->avg_var);
|
||||
}
|
||||
|
||||
static void
|
||||
filter_add_sample(struct MedianFilter *filter, struct timeval *sample_time, double offset, double dispersion)
|
||||
{
|
||||
filter->index++;
|
||||
filter->index %= filter->length;
|
||||
filter->last = filter->index;
|
||||
if (filter->used < filter->length)
|
||||
filter->used++;
|
||||
|
||||
filter->samples[filter->index].sample_time = *sample_time;
|
||||
filter->samples[filter->index].offset = offset;
|
||||
filter->samples[filter->index].dispersion = dispersion;
|
||||
}
|
||||
|
||||
static int
|
||||
filter_get_last_sample(struct MedianFilter *filter, struct timeval *sample_time, double *offset, double *dispersion)
|
||||
{
|
||||
if (filter->last < 0)
|
||||
return 0;
|
||||
|
||||
*sample_time = filter->samples[filter->last].sample_time;
|
||||
*offset = filter->samples[filter->last].offset;
|
||||
*dispersion = filter->samples[filter->last].dispersion;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct FilterSample *tmp_sorted_array;
|
||||
|
||||
static int
|
||||
sample_compare(const void *a, const void *b)
|
||||
{
|
||||
const struct FilterSample *s1, *s2;
|
||||
|
||||
s1 = &tmp_sorted_array[*(int *)a];
|
||||
s2 = &tmp_sorted_array[*(int *)b];
|
||||
|
||||
if (s1->offset < s2->offset)
|
||||
return -1;
|
||||
else if (s1->offset > s2->offset)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
filter_select_samples(struct MedianFilter *filter)
|
||||
{
|
||||
int i, j, k, o, from, to, *selected;
|
||||
double min_dispersion;
|
||||
|
||||
if (filter->used < 1)
|
||||
return 0;
|
||||
|
||||
/* for lengths below 4 require full filter,
|
||||
for 4 and above require at least 4 samples */
|
||||
if ((filter->length < 4 && filter->used != filter->length) ||
|
||||
(filter->length >= 4 && filter->used < 4))
|
||||
return 0;
|
||||
|
||||
selected = filter->selected;
|
||||
|
||||
if (filter->used > 4) {
|
||||
/* select samples with dispersion better than 1.5 * minimum */
|
||||
|
||||
for (i = 1, min_dispersion = filter->samples[0].dispersion; i < filter->used; i++) {
|
||||
if (min_dispersion > filter->samples[i].dispersion)
|
||||
min_dispersion = filter->samples[i].dispersion;
|
||||
}
|
||||
|
||||
for (i = j = 0; i < filter->used; i++) {
|
||||
if (filter->samples[i].dispersion <= 1.5 * min_dispersion)
|
||||
selected[j++] = i;
|
||||
}
|
||||
} else {
|
||||
j = 0;
|
||||
}
|
||||
|
||||
if (j < 4) {
|
||||
/* select all samples */
|
||||
|
||||
for (j = 0; j < filter->used; j++)
|
||||
selected[j] = j;
|
||||
}
|
||||
|
||||
/* and sort their indices by offset */
|
||||
tmp_sorted_array = filter->samples;
|
||||
qsort(selected, j, sizeof (int), sample_compare);
|
||||
|
||||
/* select 60 percent of the samples closest to the median */
|
||||
if (j > 2) {
|
||||
from = j / 5;
|
||||
if (from < 1)
|
||||
from = 1;
|
||||
to = j - from;
|
||||
} else {
|
||||
from = 0;
|
||||
to = j;
|
||||
}
|
||||
|
||||
/* mark unused samples and sort the rest from oldest to newest */
|
||||
|
||||
o = filter->used - filter->index - 1;
|
||||
|
||||
for (i = 0; i < from; i++)
|
||||
selected[i] = -1;
|
||||
for (; i < to; i++)
|
||||
selected[i] = (selected[i] + o) % filter->used;
|
||||
for (; i < filter->used; i++)
|
||||
selected[i] = -1;
|
||||
|
||||
for (i = from; i < to; i++) {
|
||||
j = selected[i];
|
||||
selected[i] = -1;
|
||||
while (j != -1 && selected[j] != j) {
|
||||
k = selected[j];
|
||||
selected[j] = j;
|
||||
j = k;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = j = 0, k = -1; i < filter->used; i++) {
|
||||
if (selected[i] != -1)
|
||||
selected[j++] = (selected[i] + filter->used - o) % filter->used;
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
static int
|
||||
filter_get_sample(struct MedianFilter *filter, struct timeval *sample_time, double *offset, double *dispersion)
|
||||
{
|
||||
struct FilterSample *s, *ls;
|
||||
int i, n, dof;
|
||||
double x, y, d, e, var, prev_avg_var;
|
||||
|
||||
n = filter_select_samples(filter);
|
||||
|
||||
if (n < 1)
|
||||
return 0;
|
||||
|
||||
ls = &filter->samples[filter->selected[n - 1]];
|
||||
|
||||
/* prepare data */
|
||||
for (i = 0; i < n; i++) {
|
||||
s = &filter->samples[filter->selected[i]];
|
||||
|
||||
UTI_DiffTimevalsToDouble(&filter->x_data[i], &s->sample_time, &ls->sample_time);
|
||||
filter->y_data[i] = s->offset;
|
||||
filter->w_data[i] = s->dispersion;
|
||||
}
|
||||
|
||||
/* mean offset, sample time and sample dispersion */
|
||||
for (i = 0, x = y = e = 0.0; i < n; i++) {
|
||||
x += filter->x_data[i];
|
||||
y += filter->y_data[i];
|
||||
e += filter->w_data[i];
|
||||
}
|
||||
x /= n;
|
||||
y /= n;
|
||||
e /= n;
|
||||
|
||||
e -= sqrt(filter->avg_var);
|
||||
|
||||
if (n >= 4) {
|
||||
double b0, b1, s2, sb0, sb1;
|
||||
|
||||
/* set y axis to the mean sample time */
|
||||
for (i = 0; i < n; i++)
|
||||
filter->x_data[i] -= x;
|
||||
|
||||
/* make a linear fit and use the estimated standard deviation of intercept
|
||||
as dispersion */
|
||||
RGR_WeightedRegression(filter->x_data, filter->y_data, filter->w_data, n,
|
||||
&b0, &b1, &s2, &sb0, &sb1);
|
||||
var = s2;
|
||||
d = sb0;
|
||||
dof = n - 2;
|
||||
} else if (n >= 2) {
|
||||
for (i = 0, d = 0.0; i < n; i++)
|
||||
d += (filter->y_data[i] - y) * (filter->y_data[i] - y);
|
||||
var = d / (n - 1);
|
||||
d = sqrt(var);
|
||||
dof = n - 1;
|
||||
} else {
|
||||
var = filter->avg_var;
|
||||
d = sqrt(var);
|
||||
dof = 1;
|
||||
}
|
||||
|
||||
/* avoid having zero dispersion */
|
||||
if (var < 1e-20) {
|
||||
var = 1e-20;
|
||||
d = sqrt(var);
|
||||
}
|
||||
|
||||
prev_avg_var = filter->avg_var;
|
||||
|
||||
/* update exponential moving average of the variance */
|
||||
if (filter->avg_var_n > 50) {
|
||||
filter->avg_var += dof / (dof + 50.0) * (var - filter->avg_var);
|
||||
} else {
|
||||
filter->avg_var = (filter->avg_var * filter->avg_var_n + var * dof) /
|
||||
(dof + filter->avg_var_n);
|
||||
if (filter->avg_var_n == 0)
|
||||
prev_avg_var = filter->avg_var;
|
||||
filter->avg_var_n += dof;
|
||||
}
|
||||
|
||||
/* reduce noise in sourcestats weights by using the long-term average
|
||||
instead of the estimated variance if it's not significantly lower */
|
||||
if (var * dof / RGR_GetChi2Coef(dof) < prev_avg_var)
|
||||
d = sqrt(filter->avg_var) * d / sqrt(var);
|
||||
|
||||
if (d < e)
|
||||
d = e;
|
||||
|
||||
UTI_AddDoubleToTimeval(&ls->sample_time, x, sample_time);
|
||||
*offset = y;
|
||||
*dispersion = d;
|
||||
|
||||
filter_reset(filter);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
filter_slew_samples(struct MedianFilter *filter, struct timeval *when, double dfreq, double doffset)
|
||||
{
|
||||
int i;
|
||||
double delta_time, prev_offset;
|
||||
struct timeval *sample;
|
||||
|
||||
for (i = 0; i < filter->used; i++) {
|
||||
sample = &filter->samples[i].sample_time;
|
||||
UTI_AdjustTimeval(sample, when, sample, &delta_time, dfreq, doffset);
|
||||
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);
|
||||
#else
|
||||
(void)prev_offset;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
filter_add_dispersion(struct MedianFilter *filter, double dispersion)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < filter->used; i++) {
|
||||
filter->samples[i].dispersion += dispersion;
|
||||
}
|
||||
}
|
||||
72
refclock.h
Normal file
72
refclock.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
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;
|
||||
char *driver_parameter;
|
||||
int driver_poll;
|
||||
int poll;
|
||||
int filter_length;
|
||||
int pps_rate;
|
||||
uint32_t ref_id;
|
||||
uint32_t lock_ref_id;
|
||||
double offset;
|
||||
double delay;
|
||||
double precision;
|
||||
SRC_SelectOption sel_option;
|
||||
} 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);
|
||||
|
||||
/* 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 char *RCL_GetDriverOption(RCL_Instance instance, char *name);
|
||||
extern int RCL_AddSample(RCL_Instance instance, struct timeval *sample_time, double offset, int leap);
|
||||
extern int RCL_AddPulse(RCL_Instance instance, struct timeval *pulse_time, double second);
|
||||
|
||||
#endif
|
||||
172
refclock_pps.c
Normal file
172
refclock_pps.c
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
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 "config.h"
|
||||
|
||||
#include "refclock.h"
|
||||
|
||||
#if HAVE_PPSAPI
|
||||
|
||||
#if defined(HAVE_SYS_TIMEPPS_H)
|
||||
#include <sys/timepps.h>
|
||||
#elif defined(HAVE_TIMEPPS_H)
|
||||
#include <timepps.h>
|
||||
#endif
|
||||
|
||||
#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;
|
||||
|
||||
path = RCL_GetDriverParameter(instance);
|
||||
edge_clear = RCL_GetDriverOption(instance, "clear") ? 1 : 0;
|
||||
|
||||
fd = open(path, O_RDWR);
|
||||
if (fd < 0) {
|
||||
LOG_FATAL(LOGF_Refclock, "open() failed on %s", path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
UTI_FdSetCloexec(fd);
|
||||
|
||||
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
|
||||
128
refclock_shm.c
Normal file
128
refclock_shm.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
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 "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "refclock.h"
|
||||
#include "logging.h"
|
||||
#include "util.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
|
||||
*/
|
||||
volatile int count;
|
||||
time_t clockTimeStampSec;
|
||||
int clockTimeStampUSec;
|
||||
time_t receiveTimeStampSec;
|
||||
int receiveTimeStampUSec;
|
||||
int leap;
|
||||
int precision;
|
||||
int nsamples;
|
||||
volatile int valid;
|
||||
int clockTimeStampNSec;
|
||||
int receiveTimeStampNSec;
|
||||
int dummy[8];
|
||||
};
|
||||
|
||||
static int shm_initialise(RCL_Instance instance) {
|
||||
int id, param, perm;
|
||||
char *s;
|
||||
struct shmTime *shm;
|
||||
|
||||
param = atoi(RCL_GetDriverParameter(instance));
|
||||
s = RCL_GetDriverOption(instance, "perm");
|
||||
perm = s ? strtol(s, NULL, 8) & 0777 : 0600;
|
||||
|
||||
id = shmget(SHMKEY + param, sizeof (struct shmTime), IPC_CREAT | perm);
|
||||
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 tv;
|
||||
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;
|
||||
|
||||
tv.tv_sec = t.receiveTimeStampSec;
|
||||
tv.tv_usec = t.receiveTimeStampUSec;
|
||||
|
||||
offset = t.clockTimeStampSec - t.receiveTimeStampSec;
|
||||
if (t.clockTimeStampNSec / 1000 == t.clockTimeStampUSec &&
|
||||
t.receiveTimeStampNSec / 1000 == t.receiveTimeStampUSec)
|
||||
offset += (t.clockTimeStampNSec - t.receiveTimeStampNSec) * 1e-9;
|
||||
else
|
||||
offset += (t.clockTimeStampUSec - t.receiveTimeStampUSec) * 1e-6;
|
||||
|
||||
return RCL_AddSample(instance, &tv, offset, t.leap);
|
||||
}
|
||||
|
||||
RefclockDriver RCL_SHM_driver = {
|
||||
shm_initialise,
|
||||
shm_finalise,
|
||||
shm_poll
|
||||
};
|
||||
133
refclock_sock.c
Normal file
133
refclock_sock.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
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 "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "refclock.h"
|
||||
#include "logging.h"
|
||||
#include "util.h"
|
||||
#include "sched.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;
|
||||
}
|
||||
|
||||
UTI_FdSetCloexec(sockfd);
|
||||
|
||||
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
|
||||
};
|
||||
747
reference.c
747
reference.c
File diff suppressed because it is too large
Load Diff
16
reference.h
16
reference.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/reference.h,v 1.13 2002/02/28 23:27:12 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -75,7 +71,7 @@ extern void REF_GetReferenceParams
|
||||
int *is_synchronised,
|
||||
NTP_Leap *leap,
|
||||
int *stratum,
|
||||
unsigned long *ref_id,
|
||||
uint32_t *ref_id,
|
||||
struct timeval *ref_time,
|
||||
double *root_delay,
|
||||
double *root_dispersion
|
||||
@@ -109,9 +105,12 @@ extern void REF_SetReference
|
||||
(
|
||||
int stratum,
|
||||
NTP_Leap leap,
|
||||
unsigned long ref_id,
|
||||
int combined_sources,
|
||||
uint32_t ref_id,
|
||||
IPAddr *ref_ip,
|
||||
struct timeval *ref_time,
|
||||
double offset,
|
||||
double offset_sd,
|
||||
double frequency,
|
||||
double skew,
|
||||
double root_delay,
|
||||
@@ -139,9 +138,8 @@ extern void REF_ModifyMaxupdateskew(double new_max_update_skew);
|
||||
|
||||
extern void REF_EnableLocal(int stratum);
|
||||
extern void REF_DisableLocal(void);
|
||||
extern int REF_IsLocalActive(void);
|
||||
|
||||
extern void REF_GetTrackingReport(RPT_TrackingReport *rep);
|
||||
|
||||
extern void REF_CycleLogFile(void);
|
||||
|
||||
#endif /* GOT_REFERENCE_H */
|
||||
|
||||
142
regress.c
142
regress.c
@@ -1,12 +1,9 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/regress.c,v 1.32 2003/09/22 21:22:30 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Miroslav Lichvar 2011
|
||||
*
|
||||
* 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
|
||||
@@ -19,7 +16,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -29,11 +26,9 @@
|
||||
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "regress.h"
|
||||
#include "logging.h"
|
||||
@@ -69,9 +64,7 @@ RGR_WeightedRegression
|
||||
double u, ui, aa;
|
||||
int i;
|
||||
|
||||
if (n<3) {
|
||||
CROAK("Insufficient points");
|
||||
}
|
||||
assert(n >= 3);
|
||||
|
||||
W = U = 0;
|
||||
for (i=0; i<n; i++) {
|
||||
@@ -106,8 +99,6 @@ RGR_WeightedRegression
|
||||
*sb0 = sqrt(*s2 / W + aa * aa);
|
||||
|
||||
*s2 *= (n / W); /* Giving weighted average of variances */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -135,6 +126,30 @@ RGR_GetTCoef(int dof)
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
/* Get 90% quantile of chi-square distribution */
|
||||
|
||||
double
|
||||
RGR_GetChi2Coef(int dof)
|
||||
{
|
||||
static double coefs[] = {
|
||||
2.706, 4.605, 6.251, 7.779, 9.236, 10.645, 12.017, 13.362,
|
||||
14.684, 15.987, 17.275, 18.549, 19.812, 21.064, 22.307, 23.542,
|
||||
24.769, 25.989, 27.204, 28.412, 29.615, 30.813, 32.007, 33.196,
|
||||
34.382, 35.563, 36.741, 37.916, 39.087, 40.256, 41.422, 42.585,
|
||||
43.745, 44.903, 46.059, 47.212, 48.363, 49.513, 50.660, 51.805,
|
||||
52.949, 54.090, 55.230, 56.369, 57.505, 58.641, 59.774, 60.907,
|
||||
62.038, 63.167, 64.295, 65.422, 66.548, 67.673, 68.796, 69.919,
|
||||
71.040, 72.160, 73.279, 74.397, 75.514, 76.630, 77.745, 78.860
|
||||
};
|
||||
|
||||
if (dof <= 64) {
|
||||
return coefs[dof-1];
|
||||
} else {
|
||||
return 1.2 * dof; /* Until I can be bothered to do something better */
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
/* Structure used for holding results of each regression */
|
||||
|
||||
@@ -150,23 +165,23 @@ typedef struct {
|
||||
} RegressionResult;
|
||||
|
||||
/* ================================================== */
|
||||
/* Critical value for number of runs of residuals with same sign. 10%
|
||||
critical region for now */
|
||||
/* Critical value for number of runs of residuals with same sign.
|
||||
5% critical region for now. */
|
||||
|
||||
static int critical_runs10[] =
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 3, 3,
|
||||
4, 4, 4, 4, 5, 5, 6, 6, 7, 7,
|
||||
7, 8, 8, 9, 9, 10, 10, 10, 11, 11,
|
||||
12, 12, 13, 13, 14, 14, 14, 15, 15, 16,
|
||||
16, 17, 17, 18, 18, 18, 19, 19, 20, 20,
|
||||
|
||||
/* Note that 66 onwards are bogus - I haven't worked out the
|
||||
critical values */
|
||||
21, 21, 22, 22, 23, 23, 23, 24, 24, 25,
|
||||
25, 26, 26, 27, 27, 28, 28, 28, 28, 28,
|
||||
28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
|
||||
28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
|
||||
28, 28, 28, 28, 28, 28, 28, 28, 28, 28
|
||||
static char critical_runs[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 2, 3,
|
||||
3, 3, 4, 4, 5, 5, 5, 6, 6, 7,
|
||||
7, 7, 8, 8, 9, 9, 9, 10, 10, 11,
|
||||
11, 11, 12, 12, 13, 13, 14, 14, 14, 15,
|
||||
15, 16, 16, 17, 17, 18, 18, 18, 19, 19,
|
||||
20, 20, 21, 21, 21, 22, 22, 23, 23, 24,
|
||||
24, 25, 25, 26, 26, 26, 27, 27, 28, 28,
|
||||
29, 29, 30, 30, 30, 31, 31, 32, 32, 33,
|
||||
33, 34, 34, 35, 35, 35, 36, 36, 37, 37,
|
||||
38, 38, 39, 39, 40, 40, 40, 41, 41, 42,
|
||||
42, 43, 43, 44, 44, 45, 45, 46, 46, 46,
|
||||
47, 47, 48, 48, 49, 49, 50, 50, 51, 51,
|
||||
52, 52, 52, 53, 53, 54, 54, 55, 55, 56
|
||||
};
|
||||
|
||||
/* ================================================== */
|
||||
@@ -194,7 +209,6 @@ n_runs_from_residuals(double *resid, int n)
|
||||
/* Return a boolean indicating whether we had enough points for
|
||||
regression */
|
||||
|
||||
#define RESID_SIZE 1024
|
||||
#define MIN_SAMPLES_FOR_REGRESS 3
|
||||
|
||||
int
|
||||
@@ -205,6 +219,12 @@ RGR_FindBestRegression
|
||||
less reliable) */
|
||||
|
||||
int n, /* number of data points */
|
||||
int m, /* number of extra samples in x and y arrays
|
||||
(negative index) which can be used to
|
||||
extend runs test */
|
||||
int min_samples, /* minimum number of samples to be kept after
|
||||
changing the starting index to pass the runs
|
||||
test */
|
||||
|
||||
/* And now the results */
|
||||
|
||||
@@ -228,13 +248,16 @@ RGR_FindBestRegression
|
||||
)
|
||||
{
|
||||
double P, Q, U, V, W; /* total */
|
||||
double resid[RESID_SIZE];
|
||||
double resid[MAX_POINTS * REGRESS_RUNS_RATIO];
|
||||
double ss;
|
||||
double a, b, u, ui, aa;
|
||||
|
||||
int start, nruns, npoints, npoints_left;
|
||||
int start, resid_start, nruns, npoints;
|
||||
int i;
|
||||
|
||||
assert(n <= MAX_POINTS);
|
||||
assert(n * REGRESS_RUNS_RATIO < sizeof (critical_runs) / sizeof (critical_runs[0]));
|
||||
|
||||
if (n < MIN_SAMPLES_FOR_REGRESS) {
|
||||
return 0;
|
||||
}
|
||||
@@ -258,20 +281,28 @@ RGR_FindBestRegression
|
||||
V += ui * ui / w[i];
|
||||
}
|
||||
|
||||
npoints = n - start;
|
||||
b = Q / V;
|
||||
a = (P / W) - (b * u);
|
||||
|
||||
for (i=start; i<n; i++) {
|
||||
resid[i] = y[i] - a - b*x[i];
|
||||
/* Get residuals also for the extra samples before start */
|
||||
resid_start = n - (n - start) * REGRESS_RUNS_RATIO;
|
||||
if (resid_start < -m)
|
||||
resid_start = -m;
|
||||
|
||||
for (i=resid_start; i<n; i++) {
|
||||
resid[i - resid_start] = y[i] - a - b*x[i];
|
||||
}
|
||||
|
||||
/* Count number of runs */
|
||||
nruns = n_runs_from_residuals(resid + start, npoints);
|
||||
nruns = n_runs_from_residuals(resid, n - resid_start);
|
||||
|
||||
npoints_left = n - start - 1;
|
||||
|
||||
if ((nruns > critical_runs10[npoints]) || (npoints_left < MIN_SAMPLES_FOR_REGRESS)) {
|
||||
if (nruns > critical_runs[n - resid_start] ||
|
||||
n - start <= MIN_SAMPLES_FOR_REGRESS ||
|
||||
n - start <= min_samples) {
|
||||
if (start != resid_start) {
|
||||
/* Ignore extra samples in returned nruns */
|
||||
nruns = n_runs_from_residuals(resid - resid_start + start, n - start);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
/* Try dropping one sample at a time until the runs test passes. */
|
||||
@@ -286,7 +317,7 @@ RGR_FindBestRegression
|
||||
|
||||
ss = 0.0;
|
||||
for (i=start; i<n; i++) {
|
||||
ss += resid[i]*resid[i] / w[i];
|
||||
ss += resid[i - resid_start]*resid[i - resid_start] / w[i];
|
||||
}
|
||||
|
||||
npoints = n - start;
|
||||
@@ -332,9 +363,7 @@ find_ordered_entry_with_flags(double *x, int n, int index, int *flags)
|
||||
double piv;
|
||||
int pivind;
|
||||
|
||||
if (index < 0) {
|
||||
CROAK("Negative index");
|
||||
}
|
||||
assert(index >= 0);
|
||||
|
||||
/* If this bit of the array is already sorted, simple! */
|
||||
if (flags[index]) {
|
||||
@@ -363,7 +392,7 @@ find_ordered_entry_with_flags(double *x, int n, int index, int *flags)
|
||||
l = u + 1;
|
||||
r = v;
|
||||
do {
|
||||
while (x[l] < piv) l++;
|
||||
while (x[l] < piv && l < v) l++;
|
||||
while (x[r] > piv) r--;
|
||||
if (r <= l) break;
|
||||
EXCH(x[l], x[r]);
|
||||
@@ -378,8 +407,6 @@ find_ordered_entry_with_flags(double *x, int n, int index, int *flags)
|
||||
v = r - 1;
|
||||
} else if (index > r) {
|
||||
u = l;
|
||||
} else {
|
||||
CROAK("Impossible");
|
||||
}
|
||||
}
|
||||
} while (1);
|
||||
@@ -394,7 +421,7 @@ find_ordered_entry(double *x, int n, int index)
|
||||
{
|
||||
int flags[MAX_POINTS];
|
||||
|
||||
bzero(flags, n * sizeof(int));
|
||||
memset(flags, 0, n * sizeof(int));
|
||||
return find_ordered_entry_with_flags(x, n, index, flags);
|
||||
}
|
||||
#endif
|
||||
@@ -498,6 +525,8 @@ RGR_FindBestRobustRegression
|
||||
double mx, dx, my, dy;
|
||||
int nruns = 0;
|
||||
|
||||
assert(n < MAX_POINTS);
|
||||
|
||||
if (n < 2) {
|
||||
return 0;
|
||||
} else if (n == 2) {
|
||||
@@ -558,7 +587,7 @@ RGR_FindBestRobustRegression
|
||||
Estimate standard deviation of b and expand range about b based
|
||||
on that. */
|
||||
sb = sqrt(s2 * W/V);
|
||||
if (sb > 0.0) {
|
||||
if (sb > tol) {
|
||||
incr = 3.0 * sb;
|
||||
} else {
|
||||
incr = 3.0 * tol;
|
||||
@@ -568,6 +597,11 @@ RGR_FindBestRobustRegression
|
||||
bhi = b;
|
||||
|
||||
do {
|
||||
/* Make sure incr is significant to blo and bhi */
|
||||
while (bhi + incr == bhi || blo - incr == blo) {
|
||||
incr *= 2;
|
||||
}
|
||||
|
||||
blo -= incr;
|
||||
bhi += incr;
|
||||
|
||||
@@ -575,8 +609,8 @@ RGR_FindBestRobustRegression
|
||||
eval_robust_residual(x + start, y + start, n_points, blo, &a, &rlo);
|
||||
eval_robust_residual(x + start, y + start, n_points, bhi, &a, &rhi);
|
||||
|
||||
} while (rlo * rhi > 0.0); /* fn vals have same sign, i.e. root not
|
||||
in interval. */
|
||||
} while (rlo * rhi >= 0.0); /* fn vals have same sign or one is zero,
|
||||
i.e. root not in interval (rlo, rhi). */
|
||||
|
||||
/* OK, so the root for b lies in (blo, bhi). Start bisecting */
|
||||
do {
|
||||
@@ -591,9 +625,9 @@ RGR_FindBestRobustRegression
|
||||
bhi = bmid;
|
||||
rhi = rmid;
|
||||
} else {
|
||||
CROAK("Impossible");
|
||||
assert(0);
|
||||
}
|
||||
} while ((bhi - blo) > tol);
|
||||
} while ((bhi - blo) > tol && (bmid - blo) * (bhi - bmid) > 0.0);
|
||||
|
||||
*b0 = a;
|
||||
*b1 = bmid;
|
||||
@@ -610,7 +644,7 @@ RGR_FindBestRobustRegression
|
||||
|
||||
nruns = n_runs_from_residuals(resids + start, n_points);
|
||||
|
||||
if (nruns > critical_runs10[n_points]) {
|
||||
if (nruns > critical_runs[n_points]) {
|
||||
break;
|
||||
} else {
|
||||
start++;
|
||||
|
||||
21
regress.h
21
regress.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/regress.h,v 1.13 2002/02/28 23:27:13 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -61,6 +57,15 @@ RGR_WeightedRegression
|
||||
|
||||
extern double RGR_GetTCoef(int dof);
|
||||
|
||||
/* Return the value to apply to the variance to make an upper one-sided
|
||||
test assuming a chi-square distribution. */
|
||||
|
||||
extern double RGR_GetChi2Coef(int dof);
|
||||
|
||||
/* Maximum ratio of number of points used for runs test to number of regression
|
||||
points */
|
||||
#define REGRESS_RUNS_RATIO 2
|
||||
|
||||
/* Return a status indicating whether there were enough points to
|
||||
carry out the regression */
|
||||
|
||||
@@ -72,6 +77,12 @@ RGR_FindBestRegression
|
||||
less reliable) */
|
||||
|
||||
int n, /* number of data points */
|
||||
int m, /* number of extra samples in x and y arrays
|
||||
(negative index) which can be used to
|
||||
extend runs test */
|
||||
int min_samples, /* minimum number of samples to be kept after
|
||||
changing the starting index to pass the runs
|
||||
test */
|
||||
|
||||
/* And now the results */
|
||||
|
||||
|
||||
46
reports.h
46
reports.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/reports.h,v 1.17 2002/02/28 23:27:13 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -32,50 +28,57 @@
|
||||
#define GOT_REPORTS_H
|
||||
|
||||
#include "sysincl.h"
|
||||
#include "addressing.h"
|
||||
|
||||
#define REPORT_INVALID_OFFSET 0x80000000
|
||||
|
||||
typedef struct {
|
||||
unsigned long ip_addr;
|
||||
IPAddr ip_addr;
|
||||
int stratum;
|
||||
int poll;
|
||||
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_CANDIDATE, RPT_OUTLIER} state;
|
||||
enum {RPT_NORMAL, RPT_PREFER, RPT_NOSELECT} sel_option;
|
||||
|
||||
int reachability;
|
||||
unsigned long latest_meas_ago; /* seconds */
|
||||
long orig_latest_meas; /* microseconds (us) */
|
||||
long latest_meas; /* us */
|
||||
unsigned long latest_meas_err; /* us */
|
||||
long est_offset; /* us */
|
||||
unsigned long est_offset_err; /* us */
|
||||
long resid_freq; /* ppm * 1000 */
|
||||
unsigned long resid_skew; /* ppm * 1000 */
|
||||
double orig_latest_meas; /* seconds */
|
||||
double latest_meas; /* seconds */
|
||||
double latest_meas_err; /* seconds */
|
||||
} RPT_SourceReport ;
|
||||
|
||||
typedef struct {
|
||||
unsigned long ref_id;
|
||||
uint32_t ref_id;
|
||||
IPAddr ip_addr;
|
||||
unsigned long stratum;
|
||||
unsigned long leap_status;
|
||||
struct timeval ref_time;
|
||||
struct timeval current_correction;
|
||||
double current_correction;
|
||||
double last_offset;
|
||||
double rms_offset;
|
||||
double freq_ppm;
|
||||
double resid_freq_ppm;
|
||||
double skew_ppm;
|
||||
double root_delay;
|
||||
double root_dispersion;
|
||||
double last_update_interval;
|
||||
} RPT_TrackingReport;
|
||||
|
||||
typedef struct {
|
||||
unsigned long ip_addr;
|
||||
uint32_t ref_id;
|
||||
IPAddr ip_addr;
|
||||
unsigned long n_samples;
|
||||
unsigned long n_runs;
|
||||
unsigned long span_seconds;
|
||||
double resid_freq_ppm;
|
||||
double skew_ppm;
|
||||
double sd_us;
|
||||
double sd;
|
||||
double est_offset;
|
||||
double est_offset_err;
|
||||
} RPT_SourcestatsReport;
|
||||
|
||||
typedef struct {
|
||||
unsigned long ref_time;
|
||||
struct timeval ref_time;
|
||||
unsigned short n_samples;
|
||||
unsigned short n_runs;
|
||||
unsigned long span_seconds;
|
||||
@@ -94,7 +97,7 @@ typedef struct {
|
||||
} RPT_ClientAccess_Report;
|
||||
|
||||
typedef struct {
|
||||
unsigned long ip_addr;
|
||||
IPAddr ip_addr;
|
||||
unsigned long client_hits;
|
||||
unsigned long peer_hits;
|
||||
unsigned long cmd_hits_auth;
|
||||
@@ -105,7 +108,7 @@ typedef struct {
|
||||
} RPT_ClientAccessByIndex_Report;
|
||||
|
||||
typedef struct {
|
||||
time_t when;
|
||||
struct timeval when;
|
||||
double slewed_offset;
|
||||
double orig_offset;
|
||||
double residual;
|
||||
@@ -116,6 +119,7 @@ typedef struct {
|
||||
int offline;
|
||||
int burst_online;
|
||||
int burst_offline;
|
||||
int unresolved;
|
||||
} RPT_ActivityReport;
|
||||
|
||||
#endif /* GOT_REPORTS_H */
|
||||
|
||||
30
rtc.c
30
rtc.c
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/rtc.c,v 1.14 2003/09/22 21:22:30 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -27,6 +23,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "rtc.h"
|
||||
@@ -50,7 +48,6 @@ static struct {
|
||||
int (*write_parameters)(void);
|
||||
int (*get_report)(RPT_RTC_Report *report);
|
||||
int (*trim)(void);
|
||||
void (*cycle_logfile)(void);
|
||||
} driver =
|
||||
{
|
||||
#if defined LINUX && defined FEAT_RTC
|
||||
@@ -61,8 +58,7 @@ static struct {
|
||||
RTC_Linux_StartMeasurements,
|
||||
RTC_Linux_WriteParameters,
|
||||
RTC_Linux_GetReport,
|
||||
RTC_Linux_Trim,
|
||||
RTC_Linux_CycleLogFile
|
||||
RTC_Linux_Trim
|
||||
#else
|
||||
NULL,
|
||||
NULL,
|
||||
@@ -71,7 +67,6 @@ static struct {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
#endif
|
||||
};
|
||||
@@ -89,6 +84,10 @@ RTC_Initialise(void)
|
||||
file_name = CNF_GetRtcFile();
|
||||
|
||||
if (file_name) {
|
||||
if (CNF_GetRTCSync()) {
|
||||
LOG_FATAL(LOGF_Rtc, "rtcfile directive cannot be used with rtcsync");
|
||||
}
|
||||
|
||||
if (driver.init) {
|
||||
if ((driver.init)()) {
|
||||
ok = 1;
|
||||
@@ -109,9 +108,6 @@ RTC_Initialise(void)
|
||||
} else {
|
||||
driver_initialised = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -210,13 +206,3 @@ RTC_Trim(void)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
RTC_CycleLogFile(void)
|
||||
{
|
||||
if (driver_initialised) {
|
||||
(driver.cycle_logfile)();
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
|
||||
8
rtc.h
8
rtc.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/rtc.h,v 1.9 2002/02/28 23:27:13 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -47,6 +43,4 @@ extern int RTC_WriteParameters(void);
|
||||
|
||||
extern int RTC_Trim(void);
|
||||
|
||||
extern void RTC_CycleLogFile(void);
|
||||
|
||||
#endif /* GOT_RTC_H */
|
||||
|
||||
281
rtc_linux.c
281
rtc_linux.c
@@ -1,12 +1,9 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/rtc_linux.c,v 1.32 2003/09/22 21:22:30 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Miroslav Lichvar 2012
|
||||
*
|
||||
* 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
|
||||
@@ -19,7 +16,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -30,25 +27,11 @@
|
||||
|
||||
*/
|
||||
|
||||
#if defined LINUX
|
||||
#include "config.h"
|
||||
|
||||
#ifdef sparc
|
||||
#define __KERNEL__
|
||||
#endif
|
||||
#include "sysincl.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <linux/rtc.h>
|
||||
|
||||
#include "logging.h"
|
||||
#include "sched.h"
|
||||
@@ -58,22 +41,8 @@
|
||||
#include "regress.h"
|
||||
#include "rtc.h"
|
||||
#include "rtc_linux.h"
|
||||
#include "io_linux.h"
|
||||
#include "conf.h"
|
||||
#include "memory.h"
|
||||
#include "mkdirpp.h"
|
||||
|
||||
struct rtc_time {
|
||||
int tm_sec;
|
||||
int tm_min;
|
||||
int tm_hour;
|
||||
int tm_mday;
|
||||
int tm_mon;
|
||||
int tm_year;
|
||||
int tm_wday;
|
||||
int tm_yday;
|
||||
int tm_isdst;
|
||||
};
|
||||
|
||||
/* ================================================== */
|
||||
/* Forward prototypes */
|
||||
@@ -107,6 +76,8 @@ static int measurement_period = LOWEST_MEASUREMENT_PERIOD;
|
||||
static int timeout_running = 0;
|
||||
static SCH_TimeoutID timeout_id;
|
||||
|
||||
static int skip_interrupts;
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
/* Maximum number of samples held */
|
||||
@@ -178,11 +149,7 @@ static int rtc_on_utc = 1;
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static FILE *logfile=NULL;
|
||||
static char *logfilename = NULL;
|
||||
static unsigned long logwrites=0;
|
||||
|
||||
#define RTC_LOG "rtc.log"
|
||||
static LOG_FileID logfileid;
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
@@ -196,12 +163,7 @@ discard_samples(int new_first)
|
||||
{
|
||||
int n_to_save;
|
||||
|
||||
if (!(new_first < n_samples)) {
|
||||
CROAK("new_first should be < n_samples");
|
||||
}
|
||||
if (!(new_first >= 0)) {
|
||||
CROAK("new_first should be non-negative");
|
||||
}
|
||||
assert(new_first >= 0 && new_first < n_samples);
|
||||
|
||||
n_to_save = n_samples - new_first;
|
||||
|
||||
@@ -210,7 +172,6 @@ discard_samples(int new_first)
|
||||
memmove(system_times, system_times + new_first, n_to_save * sizeof(struct timeval));
|
||||
|
||||
n_samples = n_to_save;
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -238,8 +199,6 @@ accumulate_sample(time_t rtc, struct timeval *sys)
|
||||
++n_samples_since_regression;
|
||||
}
|
||||
++n_samples;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -256,14 +215,12 @@ run_regression(int new_sample,
|
||||
{
|
||||
double rtc_rel[MAX_SAMPLES]; /* Relative times on RTC axis */
|
||||
double offsets[MAX_SAMPLES]; /* How much the RTC is fast of the system clock */
|
||||
int i, n;
|
||||
int i;
|
||||
double est_intercept, est_slope;
|
||||
int best_new_start;
|
||||
|
||||
if (n_samples > 0) {
|
||||
|
||||
n = n_samples - 1;
|
||||
|
||||
for (i=0; i<n_samples; i++) {
|
||||
rtc_rel[i] = rtc_trim[i] + (double)(rtc_sec[i] - rtc_ref);
|
||||
offsets[i] = ((double) (rtc_ref - system_times[i].tv_sec) -
|
||||
@@ -305,27 +262,17 @@ run_regression(int new_sample,
|
||||
static void
|
||||
slew_samples
|
||||
(struct timeval *raw, struct timeval *cooked,
|
||||
double dfreq, double afreq_ppm,
|
||||
double dfreq,
|
||||
double doffset, int is_step_change,
|
||||
void *anything)
|
||||
{
|
||||
int i;
|
||||
double elapsed;
|
||||
double new_freq;
|
||||
double old_freq;
|
||||
double delta_time;
|
||||
double old_seconds_fast, old_gain_rate;
|
||||
|
||||
new_freq = 1.0e-6 * afreq_ppm;
|
||||
old_freq = (new_freq - dfreq) / (1.0 - dfreq);
|
||||
|
||||
for (i=0; i<n_samples; i++) {
|
||||
UTI_DiffTimevalsToDouble(&elapsed, cooked, system_times + i);
|
||||
|
||||
delta_time = -(elapsed * dfreq) - doffset;
|
||||
|
||||
UTI_AddDoubleToTimeval(system_times + i, delta_time, system_times + i);
|
||||
|
||||
UTI_AdjustTimeval(system_times + i, cooked, system_times + i, &delta_time,
|
||||
dfreq, doffset);
|
||||
}
|
||||
|
||||
old_seconds_fast = coef_seconds_fast;
|
||||
@@ -333,14 +280,16 @@ slew_samples
|
||||
|
||||
if (coefs_valid) {
|
||||
coef_seconds_fast += doffset;
|
||||
coef_gain_rate = 1.0 - ((1.0 + new_freq) / (1.0 + old_freq)) * (1.0 - coef_gain_rate);
|
||||
coef_gain_rate = (1.0 + dfreq) * (1.0 + coef_gain_rate) - 1.0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
LOG(LOGS_INFO, LOGF_RtcLinux, "dfreq=%.8f doffset=%.6f new_freq=%.3f old_freq=%.3f old_fast=%.6f old_rate=%.3f new_fast=%.6f new_rate=%.3f",
|
||||
dfreq, doffset, 1.0e6*new_freq, 1.0e6*old_freq,
|
||||
LOG(LOGS_INFO, LOGF_RtcLinux, "dfreq=%.8f doffset=%.6f old_fast=%.6f old_rate=%.3f new_fast=%.6f new_rate=%.3f",
|
||||
dfreq, doffset,
|
||||
old_seconds_fast, 1.0e6 * old_gain_rate,
|
||||
coef_seconds_fast, 1.0e6 * coef_gain_rate);
|
||||
#else
|
||||
(void)old_seconds_fast; (void)old_gain_rate;
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -501,15 +450,21 @@ write_coefs_to_file(int valid,time_t ref_time,double offset,double rate)
|
||||
}
|
||||
|
||||
/* Gain rate is written out in ppm */
|
||||
fprintf(out, "%1d %ld %.6f %.3f\n",
|
||||
valid,ref_time, offset, 1.0e6 * rate);
|
||||
|
||||
fclose(out);
|
||||
if ((fprintf(out, "%1d %ld %.6f %.3f\n",
|
||||
valid,ref_time, offset, 1.0e6 * rate) < 0) |
|
||||
fclose(out)) {
|
||||
Free(temp_coefs_file_name);
|
||||
LOG(LOGS_WARN, LOGF_RtcLinux, "Could not write to temporary RTC file %s.tmp",
|
||||
coefs_file_name);
|
||||
return RTC_ST_BADFILE;
|
||||
}
|
||||
|
||||
/* Clone the file attributes from the existing file if there is one. */
|
||||
|
||||
if (!stat(coefs_file_name,&buf)) {
|
||||
chown(temp_coefs_file_name,buf.st_uid,buf.st_gid);
|
||||
if (chown(temp_coefs_file_name,buf.st_uid,buf.st_gid)) {
|
||||
LOG(LOGS_WARN, LOGF_RtcLinux, "Could not change ownership of temporary RTC file %s.tmp", coefs_file_name);
|
||||
}
|
||||
chmod(temp_coefs_file_name,buf.st_mode&0777);
|
||||
}
|
||||
|
||||
@@ -537,63 +492,6 @@ write_coefs_to_file(int valid,time_t ref_time,double offset,double rate)
|
||||
int
|
||||
RTC_Linux_Initialise(void)
|
||||
{
|
||||
int major, minor, patch;
|
||||
char *direc;
|
||||
|
||||
/* Check whether we can support the real time clock.
|
||||
|
||||
Linux 1.2.x - haven't checked yet
|
||||
|
||||
Linux 1.3.x - don't know, haven't got a system to look at
|
||||
|
||||
Linux 2.0.x - For x<=31, using any variant of the adjtimex() call
|
||||
sets the kernel into a mode where the RTC was updated every 11
|
||||
minutes. The only way to escape this is to use settimeofday().
|
||||
Since we need to have sole control over the RTC to be able to
|
||||
measure its drift rate, and there is no 'notify' callback to warn
|
||||
you that the kernel is going to do this, I can't see a way to
|
||||
support this.
|
||||
|
||||
Linux 2.0.x - For x>=32 the adjtimex()/RTC behaviour was
|
||||
modified, so that as long as the STA_UNSYNC flag is set the RTC
|
||||
is left alone. This is the mode we exploit here, so that the RTC
|
||||
continues to go its own sweet way, unless we make updates to it
|
||||
from this module.
|
||||
|
||||
Linux 2.1.x - don't know, haven't got a system to look at.
|
||||
|
||||
Linux 2.2.x, 2.3.x and 2.4.x are believed to be OK for all
|
||||
patch levels
|
||||
|
||||
*/
|
||||
|
||||
SYS_Linux_GetKernelVersion(&major, &minor, &patch);
|
||||
|
||||
/* Obviously this test can get more elaborate when we know about
|
||||
more system types. */
|
||||
if (major != 2) {
|
||||
return 0;
|
||||
} else {
|
||||
switch (minor) {
|
||||
case 0:
|
||||
if (patch <= 31) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
return 0;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
break; /* OK for all patch levels */
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup details depending on configuration options */
|
||||
setup_config();
|
||||
|
||||
@@ -608,6 +506,9 @@ RTC_Linux_Initialise(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Close on exec */
|
||||
UTI_FdSetCloexec(fd);
|
||||
|
||||
n_samples = 0;
|
||||
n_samples_since_regression = 0;
|
||||
n_runs = 0;
|
||||
@@ -623,23 +524,9 @@ RTC_Linux_Initialise(void)
|
||||
/* Register slew handler */
|
||||
LCL_AddParameterChangeHandler(slew_samples, NULL);
|
||||
|
||||
if (CNF_GetLogRtc()) {
|
||||
direc = CNF_GetLogDir();
|
||||
if (!mkdir_and_parents(direc)) {
|
||||
LOG(LOGS_ERR, LOGF_RtcLinux, "Could not create directory %s", direc);
|
||||
logfile = NULL;
|
||||
} else {
|
||||
logfilename = MallocArray(char, 2 + strlen(direc) + strlen(RTC_LOG));
|
||||
strcpy(logfilename, direc);
|
||||
strcat(logfilename, "/");
|
||||
strcat(logfilename, RTC_LOG);
|
||||
logfile = fopen(logfilename, "a");
|
||||
if (!logfile) {
|
||||
LOG(LOGS_WARN, LOGF_RtcLinux, "Couldn't open logfile %s for update", logfilename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logfileid = CNF_GetLogRtc() ? LOG_FileOpen("rtc",
|
||||
" Date (UTC) Time RTC fast (s) Val Est fast (s) Slope (ppm) Ns Nr Meas")
|
||||
: -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -662,11 +549,6 @@ RTC_Linux_Finalise(void)
|
||||
(void) RTC_Linux_WriteParameters();
|
||||
|
||||
}
|
||||
|
||||
if (logfile) {
|
||||
fclose(logfile);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -682,6 +564,7 @@ switch_interrupts(int onoff)
|
||||
LOG(LOGS_ERR, LOGF_RtcLinux, "Could not start measurement : %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
skip_interrupts = 1;
|
||||
} else {
|
||||
status = ioctl(fd, RTC_UIE_OFF, 0);
|
||||
if (status < 0) {
|
||||
@@ -717,6 +600,9 @@ set_rtc(time_t new_rtc_time)
|
||||
rtc_raw.tm_mday = rtc_tm.tm_mday;
|
||||
rtc_raw.tm_mon = rtc_tm.tm_mon;
|
||||
rtc_raw.tm_year = rtc_tm.tm_year;
|
||||
rtc_raw.tm_wday = rtc_tm.tm_wday;
|
||||
rtc_raw.tm_yday = rtc_tm.tm_yday;
|
||||
rtc_raw.tm_isdst = rtc_tm.tm_isdst;
|
||||
|
||||
status = ioctl(fd, RTC_SET_TIME, &rtc_raw);
|
||||
if (status < 0) {
|
||||
@@ -763,7 +649,7 @@ handle_initial_trim(void)
|
||||
sys_error_now = rtc_error_now - coef_seconds_fast;
|
||||
|
||||
LOG(LOGS_INFO, LOGF_RtcLinux, "System trim from RTC = %f", sys_error_now);
|
||||
LCL_AccumulateOffset(sys_error_now);
|
||||
LCL_AccumulateOffset(sys_error_now, 0.0);
|
||||
} else {
|
||||
LOG(LOGS_WARN, LOGF_RtcLinux, "No valid file coefficients, cannot trim system time");
|
||||
}
|
||||
@@ -773,8 +659,6 @@ handle_initial_trim(void)
|
||||
(after_init_hook)(after_init_hook_arg);
|
||||
|
||||
operating_mode = OM_NORMAL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -794,6 +678,7 @@ handle_relock_after_trim(void)
|
||||
LOG(LOGS_WARN, LOGF_RtcLinux, "Could not do regression after trim");
|
||||
}
|
||||
|
||||
coefs_valid = 0;
|
||||
n_samples = 0;
|
||||
n_samples_since_regression = 0;
|
||||
operating_mode = OM_NORMAL;
|
||||
@@ -832,28 +717,19 @@ process_reading(time_t rtc_time, struct timeval *system_time)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CROAK("Impossible");
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (logfile) {
|
||||
if (logfileid != -1) {
|
||||
rtc_fast = (double)(rtc_time - system_time->tv_sec) - 1.0e-6 * (double) system_time->tv_usec;
|
||||
|
||||
if (((logwrites++) % 32) == 0) {
|
||||
fprintf(logfile,
|
||||
"===============================================================================\n"
|
||||
" Date (UTC) Time RTC fast (s) Val Est fast (s) Slope (ppm) Ns Nr Meas\n"
|
||||
"===============================================================================\n");
|
||||
}
|
||||
|
||||
fprintf(logfile, "%s %14.6f %1d %14.6f %12.3f %2d %2d %4d\n",
|
||||
LOG_FileWrite(logfileid, "%s %14.6f %1d %14.6f %12.3f %2d %2d %4d",
|
||||
UTI_TimeToLogForm(system_time->tv_sec),
|
||||
rtc_fast,
|
||||
coefs_valid,
|
||||
coef_seconds_fast, coef_gain_rate * 1.0e6, n_samples, n_runs, measurement_period);
|
||||
|
||||
fflush(logfile);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -869,12 +745,10 @@ read_from_device(void *any)
|
||||
struct rtc_time rtc_raw;
|
||||
struct tm rtc_tm;
|
||||
time_t rtc_t;
|
||||
double read_err;
|
||||
int error = 0;
|
||||
|
||||
status = read(fd, &data, sizeof(data));
|
||||
if (operating_mode == OM_NORMAL)
|
||||
status = read(fd, &data, sizeof(data));
|
||||
|
||||
if (status < 0) {
|
||||
/* This looks like a bad error : the file descriptor was indicating it was
|
||||
* ready to read but we couldn't read anything. Give up. */
|
||||
@@ -884,20 +758,22 @@ read_from_device(void *any)
|
||||
switch_interrupts(0); /* Likely to raise error too, but just to be sure... */
|
||||
close(fd);
|
||||
fd = -1;
|
||||
if (logfile) {
|
||||
fclose(logfile);
|
||||
logfile = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ((data & RTC_UIE) == RTC_UIE) {
|
||||
if (skip_interrupts > 0) {
|
||||
/* Wait for the next interrupt, this one may be bogus */
|
||||
skip_interrupts--;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((data & RTC_UF) == RTC_UF) {
|
||||
/* Update interrupt detected */
|
||||
|
||||
/* Read RTC time, sandwiched between two polls of the system clock
|
||||
so we can bound any error. */
|
||||
|
||||
LCL_ReadCookedTime(&sys_time, &read_err);
|
||||
SCH_GetLastEventTime(&sys_time, NULL, NULL);
|
||||
|
||||
status = ioctl(fd, RTC_RD_TIME, &rtc_raw);
|
||||
if (status < 0) {
|
||||
@@ -976,7 +852,7 @@ turn_off_interrupt:
|
||||
|
||||
break;
|
||||
default:
|
||||
CROAK("Impossible");
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1042,7 +918,7 @@ RTC_Linux_TimePreInit(void)
|
||||
time_t rtc_t, estimated_correct_rtc_t;
|
||||
long interval;
|
||||
double accumulated_error = 0.0;
|
||||
struct timeval new_sys_time;
|
||||
struct timeval new_sys_time, old_sys_time;
|
||||
|
||||
coefs_file_name = CNF_GetRtcFile();
|
||||
|
||||
@@ -1077,8 +953,6 @@ RTC_Linux_TimePreInit(void)
|
||||
accumulated_error = file_ref_offset + (double)(interval) * 1.0e-6 * file_rate_ppm;
|
||||
|
||||
/* Correct time */
|
||||
LOG(LOGS_INFO, LOGF_RtcLinux, "Set system time, error in RTC = %f",
|
||||
accumulated_error);
|
||||
estimated_correct_rtc_t = rtc_t - (long)(0.5 + accumulated_error);
|
||||
} else {
|
||||
estimated_correct_rtc_t = rtc_t - (long)(0.5 + accumulated_error);
|
||||
@@ -1087,9 +961,18 @@ RTC_Linux_TimePreInit(void)
|
||||
new_sys_time.tv_sec = estimated_correct_rtc_t;
|
||||
new_sys_time.tv_usec = 0;
|
||||
|
||||
/* Tough luck if this fails */
|
||||
if (settimeofday(&new_sys_time, NULL) < 0) {
|
||||
LOG(LOGS_WARN, LOGF_RtcLinux, "Could not settimeofday");
|
||||
/* Set system time only if the step is larger than 1 second */
|
||||
if (!(gettimeofday(&old_sys_time, NULL) < 0) &&
|
||||
(old_sys_time.tv_sec - new_sys_time.tv_sec > 1 ||
|
||||
old_sys_time.tv_sec - new_sys_time.tv_sec < -1)) {
|
||||
|
||||
LOG(LOGS_INFO, LOGF_RtcLinux, "Set system time, error in RTC = %f",
|
||||
accumulated_error);
|
||||
|
||||
/* Tough luck if this fails */
|
||||
if (settimeofday(&new_sys_time, NULL) < 0) {
|
||||
LOG(LOGS_WARN, LOGF_RtcLinux, "Could not settimeofday");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG(LOGS_WARN, LOGF_RtcLinux, "Could not convert RTC reading to seconds since 1/1/1970");
|
||||
@@ -1104,7 +987,8 @@ RTC_Linux_TimePreInit(void)
|
||||
int
|
||||
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_runs = n_runs;
|
||||
if (n_samples > 1) {
|
||||
@@ -1124,7 +1008,6 @@ int
|
||||
RTC_Linux_Trim(void)
|
||||
{
|
||||
struct timeval now;
|
||||
double local_clock_err;
|
||||
|
||||
|
||||
/* Remember the slope coefficient - we won't be able to determine a
|
||||
@@ -1143,7 +1026,7 @@ RTC_Linux_Trim(void)
|
||||
want |E| <= 0.5, which implies R <= S <= R+1, i.e. R is just
|
||||
the rounded down part of S, i.e. the seconds part. */
|
||||
|
||||
LCL_ReadCookedTime(&now, &local_clock_err);
|
||||
LCL_ReadCookedTime(&now, NULL);
|
||||
|
||||
set_rtc(now.tv_sec);
|
||||
|
||||
@@ -1152,6 +1035,11 @@ RTC_Linux_Trim(void)
|
||||
n_samples = 0;
|
||||
operating_mode = OM_AFTERTRIM;
|
||||
|
||||
/* Estimate the offset in case writertc is called or chronyd
|
||||
is terminated during rapid sampling */
|
||||
coef_seconds_fast = -now.tv_usec / 1e6 + 0.5;
|
||||
coef_ref_time = now.tv_sec;
|
||||
|
||||
/* And start rapid sampling, interrupts on now */
|
||||
if (timeout_running) {
|
||||
SCH_RemoveTimeout(timeout_id);
|
||||
@@ -1163,22 +1051,3 @@ RTC_Linux_Trim(void)
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
RTC_Linux_CycleLogFile(void)
|
||||
{
|
||||
if (logfile && logfilename) {
|
||||
fclose(logfile);
|
||||
logfile = fopen(logfilename, "a");
|
||||
if (!logfile) {
|
||||
LOG(LOGS_WARN, LOGF_RtcLinux, "Could not reopen logfile %s", logfilename);
|
||||
}
|
||||
logwrites = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
#endif /* defined LINUX */
|
||||
|
||||
10
rtc_linux.h
10
rtc_linux.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/rtc_linux.h,v 1.13 2002/02/28 23:27:13 richard Exp $
|
||||
|
||||
======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -32,8 +28,6 @@
|
||||
|
||||
#include "reports.h"
|
||||
|
||||
#if defined LINUX
|
||||
|
||||
extern int RTC_Linux_Initialise(void);
|
||||
extern void RTC_Linux_Finalise(void);
|
||||
extern void RTC_Linux_TimePreInit(void);
|
||||
@@ -48,6 +42,4 @@ extern int RTC_Linux_Trim(void);
|
||||
|
||||
extern void RTC_Linux_CycleLogFile(void);
|
||||
|
||||
#endif /* defined LINUX */
|
||||
|
||||
#endif /* _GOT_RTC_LINUX_H */
|
||||
|
||||
262
sched.c
262
sched.c
@@ -1,12 +1,9 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/sched.c,v 1.17 2003/09/22 21:22:30 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Miroslav Lichvar 2011
|
||||
*
|
||||
* 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
|
||||
@@ -19,7 +16,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -29,6 +26,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysincl.h"
|
||||
|
||||
#include "sched.h"
|
||||
@@ -71,6 +70,10 @@ typedef struct {
|
||||
|
||||
static FileHandlerEntry file_handlers[FD_SET_SIZE];
|
||||
|
||||
/* Timestamp when last select() returned */
|
||||
static struct timeval last_select_ts, last_select_ts_raw;
|
||||
static double last_select_ts_err;
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
/* Variables to handler the timer queue */
|
||||
@@ -106,6 +109,9 @@ static SCH_TimeoutID next_tqe_id;
|
||||
/* Pointer to head of free list */
|
||||
static TimerQueueEntry *tqe_free_list = NULL;
|
||||
|
||||
/* Timestamp when was last timeout dispatched for each class */
|
||||
static struct timeval last_class_dispatch[SCH_NumberOfClasses];
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static int need_to_exit;
|
||||
@@ -116,7 +122,6 @@ static void
|
||||
handle_slew(struct timeval *raw,
|
||||
struct timeval *cooked,
|
||||
double dfreq,
|
||||
double afreq,
|
||||
double doffset,
|
||||
int is_step_change,
|
||||
void *anything);
|
||||
@@ -126,7 +131,6 @@ handle_slew(struct timeval *raw,
|
||||
void
|
||||
SCH_Initialise(void)
|
||||
{
|
||||
|
||||
FD_ZERO(&read_fds);
|
||||
n_read_fds = 0;
|
||||
|
||||
@@ -140,9 +144,12 @@ SCH_Initialise(void)
|
||||
|
||||
LCL_AddParameterChangeHandler(handle_slew, NULL);
|
||||
|
||||
initialised = 1;
|
||||
LCL_ReadRawTime(&last_select_ts_raw);
|
||||
last_select_ts = last_select_ts_raw;
|
||||
|
||||
return;
|
||||
srandom(last_select_ts.tv_sec << 16 ^ last_select_ts.tv_usec);
|
||||
|
||||
initialised = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -151,7 +158,6 @@ SCH_Initialise(void)
|
||||
void
|
||||
SCH_Finalise(void) {
|
||||
initialised = 0;
|
||||
return; /* Nothing to do for now */
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -161,16 +167,12 @@ SCH_AddInputFileHandler
|
||||
(int fd, SCH_FileHandler handler, SCH_ArbitraryArgument arg)
|
||||
{
|
||||
|
||||
if (!initialised) {
|
||||
CROAK("Should be initialised");
|
||||
}
|
||||
assert(initialised);
|
||||
|
||||
/* Don't want to allow the same fd to register a handler more than
|
||||
once without deleting a previous association - this suggests
|
||||
a bug somewhere else in the program. */
|
||||
if (FD_ISSET(fd, &read_fds)) {
|
||||
CROAK("File handler already registered");
|
||||
}
|
||||
assert(!FD_ISSET(fd, &read_fds));
|
||||
|
||||
++n_read_fds;
|
||||
|
||||
@@ -182,8 +184,6 @@ SCH_AddInputFileHandler
|
||||
if ((fd + 1) > one_highest_fd) {
|
||||
one_highest_fd = fd + 1;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -194,14 +194,10 @@ SCH_RemoveInputFileHandler(int fd)
|
||||
{
|
||||
int fds_left, fd_to_check;
|
||||
|
||||
if (!initialised) {
|
||||
CROAK("Should be initialised");
|
||||
}
|
||||
assert(initialised);
|
||||
|
||||
/* Check that a handler was registered for the fd in question */
|
||||
if (!FD_ISSET(fd, &read_fds)) {
|
||||
CROAK("File handler not registered");
|
||||
}
|
||||
assert(FD_ISSET(fd, &read_fds));
|
||||
|
||||
--n_read_fds;
|
||||
|
||||
@@ -218,9 +214,20 @@ SCH_RemoveInputFileHandler(int fd)
|
||||
}
|
||||
|
||||
one_highest_fd = fd_to_check;
|
||||
}
|
||||
|
||||
return;
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
SCH_GetLastEventTime(struct timeval *cooked, double *err, struct timeval *raw)
|
||||
{
|
||||
if (cooked) {
|
||||
*cooked = last_select_ts;
|
||||
if (err)
|
||||
*err = last_select_ts_err;
|
||||
}
|
||||
if (raw)
|
||||
*raw = last_select_ts_raw;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -254,7 +261,6 @@ release_tqe(TimerQueueEntry *node)
|
||||
{
|
||||
node->next = tqe_free_list;
|
||||
tqe_free_list = node;
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -265,9 +271,7 @@ SCH_AddTimeout(struct timeval *tv, SCH_TimeoutHandler handler, SCH_ArbitraryArgu
|
||||
TimerQueueEntry *new_tqe;
|
||||
TimerQueueEntry *ptr;
|
||||
|
||||
if (!initialised) {
|
||||
CROAK("Should be initialised");
|
||||
}
|
||||
assert(initialised);
|
||||
|
||||
new_tqe = allocate_tqe();
|
||||
|
||||
@@ -308,9 +312,8 @@ SCH_AddTimeoutByDelay(double delay, SCH_TimeoutHandler handler, SCH_ArbitraryArg
|
||||
{
|
||||
struct timeval now, then;
|
||||
|
||||
if (!initialised) {
|
||||
CROAK("Should be initialised");
|
||||
}
|
||||
assert(initialised);
|
||||
assert(delay >= 0.0);
|
||||
|
||||
LCL_ReadRawTime(&now);
|
||||
UTI_AddDoubleToTimeval(&now, delay, &then);
|
||||
@@ -321,23 +324,35 @@ SCH_AddTimeoutByDelay(double delay, SCH_TimeoutHandler handler, SCH_ArbitraryArg
|
||||
/* ================================================== */
|
||||
|
||||
SCH_TimeoutID
|
||||
SCH_AddTimeoutInClass(double min_delay, double separation,
|
||||
SCH_AddTimeoutInClass(double min_delay, double separation, double randomness,
|
||||
SCH_TimeoutClass class,
|
||||
SCH_TimeoutHandler handler, SCH_ArbitraryArgument arg)
|
||||
{
|
||||
TimerQueueEntry *new_tqe;
|
||||
TimerQueueEntry *ptr;
|
||||
struct timeval now;
|
||||
double diff;
|
||||
double diff, r;
|
||||
double new_min_delay;
|
||||
|
||||
if (!initialised) {
|
||||
CROAK("Should be initialised");
|
||||
assert(initialised);
|
||||
assert(min_delay >= 0.0);
|
||||
assert(class < SCH_NumberOfClasses);
|
||||
|
||||
if (randomness > 0.0) {
|
||||
r = random() % 0xffff / (0xffff - 1.0) * randomness + 1.0;
|
||||
min_delay *= r;
|
||||
separation *= r;
|
||||
}
|
||||
|
||||
LCL_ReadRawTime(&now);
|
||||
new_min_delay = min_delay;
|
||||
|
||||
/* Check the separation from the last dispatched timeout */
|
||||
UTI_DiffTimevalsToDouble(&diff, &now, &last_class_dispatch[class]);
|
||||
if (diff < separation && diff >= 0.0 && diff + new_min_delay < separation) {
|
||||
new_min_delay = separation - diff;
|
||||
}
|
||||
|
||||
/* Scan through list for entries in the same class and increase min_delay
|
||||
if necessary to keep at least the separation away */
|
||||
for (ptr = timer_queue.next; ptr != &timer_queue; ptr = ptr->next) {
|
||||
@@ -347,8 +362,7 @@ SCH_AddTimeoutInClass(double min_delay, double separation,
|
||||
if (new_min_delay - diff < separation) {
|
||||
new_min_delay = diff + separation;
|
||||
}
|
||||
}
|
||||
if (new_min_delay < diff) {
|
||||
} else {
|
||||
if (diff - new_min_delay < separation) {
|
||||
new_min_delay = diff + separation;
|
||||
}
|
||||
@@ -387,13 +401,8 @@ void
|
||||
SCH_RemoveTimeout(SCH_TimeoutID id)
|
||||
{
|
||||
TimerQueueEntry *ptr;
|
||||
int ok;
|
||||
|
||||
if (!initialised) {
|
||||
CROAK("Should be initialised");
|
||||
}
|
||||
|
||||
ok = 0;
|
||||
assert(initialised);
|
||||
|
||||
for (ptr = timer_queue.next; ptr != &timer_queue; ptr = ptr->next) {
|
||||
|
||||
@@ -410,48 +419,57 @@ SCH_RemoveTimeout(SCH_TimeoutID id)
|
||||
/* Release memory back to the operating system */
|
||||
release_tqe(ptr);
|
||||
|
||||
ok = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(ok);
|
||||
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
/* The current time (now) has to be passed in from the
|
||||
caller to avoid race conditions */
|
||||
/* Try to dispatch any timeouts that have already gone by, and
|
||||
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
|
||||
completed). */
|
||||
|
||||
static int
|
||||
static void
|
||||
dispatch_timeouts(struct timeval *now) {
|
||||
TimerQueueEntry *ptr;
|
||||
int n_done = 0;
|
||||
SCH_TimeoutHandler handler;
|
||||
SCH_ArbitraryArgument arg;
|
||||
int n_done = 0, n_entries_on_start = n_timer_queue_entries;
|
||||
|
||||
while (1) {
|
||||
LCL_ReadRawTime(now);
|
||||
|
||||
if (!(n_timer_queue_entries > 0 &&
|
||||
UTI_CompareTimevals(now, &(timer_queue.next->tv)) >= 0)) {
|
||||
break;
|
||||
}
|
||||
|
||||
while ((n_timer_queue_entries > 0) &&
|
||||
(UTI_CompareTimevals(now, &(timer_queue.next->tv)) >= 0)) {
|
||||
ptr = timer_queue.next;
|
||||
|
||||
last_class_dispatch[ptr->class] = *now;
|
||||
|
||||
handler = ptr->handler;
|
||||
arg = ptr->arg;
|
||||
|
||||
SCH_RemoveTimeout(ptr->id);
|
||||
|
||||
/* Dispatch the handler */
|
||||
(ptr->handler)(ptr->arg);
|
||||
(handler)(arg);
|
||||
|
||||
/* Increment count of timeouts handled */
|
||||
++n_done;
|
||||
|
||||
/* Unlink entry from the queue */
|
||||
ptr->prev->next = ptr->next;
|
||||
ptr->next->prev = ptr->prev;
|
||||
|
||||
/* Decrement count of entries in queue */
|
||||
--n_timer_queue_entries;
|
||||
|
||||
/* Delete entry */
|
||||
release_tqe(ptr);
|
||||
/* If more timeouts were handled than there were in the timer queue on
|
||||
start and there are now, assume some code is scheduling timeouts with
|
||||
negative delays and abort. Make the actual limit higher in case the
|
||||
machine is temporarily overloaded and dispatching the handlers takes
|
||||
more time than was delay of a scheduled timeout. */
|
||||
if (n_done > n_timer_queue_entries * 4 &&
|
||||
n_done > n_entries_on_start * 4) {
|
||||
LOG_FATAL(LOGF_Scheduler, "Possible infinite loop in scheduling");
|
||||
}
|
||||
}
|
||||
|
||||
return n_done;
|
||||
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -484,25 +502,57 @@ static void
|
||||
handle_slew(struct timeval *raw,
|
||||
struct timeval *cooked,
|
||||
double dfreq,
|
||||
double afreq,
|
||||
double doffset,
|
||||
int is_step_change,
|
||||
void *anything)
|
||||
{
|
||||
TimerQueueEntry *ptr;
|
||||
struct timeval T1;
|
||||
double delta;
|
||||
int i;
|
||||
|
||||
if (is_step_change) {
|
||||
/* We're not interested in anything else - it won't affect the
|
||||
functionality of timer event dispatching. If a step change
|
||||
occurs, just shift all the timeouts by the offset */
|
||||
/* If a step change occurs, just shift all raw time stamps by the offset */
|
||||
|
||||
for (ptr = timer_queue.next; ptr != &timer_queue; ptr = ptr->next) {
|
||||
UTI_AddDoubleToTimeval(&ptr->tv, -doffset, &T1);
|
||||
ptr->tv = T1;
|
||||
UTI_AddDoubleToTimeval(&ptr->tv, -doffset, &ptr->tv);
|
||||
}
|
||||
|
||||
for (i = 0; i < SCH_NumberOfClasses; i++) {
|
||||
UTI_AddDoubleToTimeval(&last_class_dispatch[i], -doffset, &last_class_dispatch[i]);
|
||||
}
|
||||
|
||||
UTI_AddDoubleToTimeval(&last_select_ts_raw, -doffset, &last_select_ts_raw);
|
||||
}
|
||||
|
||||
UTI_AdjustTimeval(&last_select_ts, cooked, &last_select_ts, &delta, dfreq, doffset);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
/* Try to handle unexpected backward time jump */
|
||||
|
||||
static void
|
||||
recover_backjump(struct timeval *raw, struct timeval *cooked, int timeout)
|
||||
{
|
||||
double diff, err;
|
||||
|
||||
UTI_DiffTimevalsToDouble(&diff, &last_select_ts_raw, raw);
|
||||
|
||||
if (n_timer_queue_entries > 0) {
|
||||
UTI_DiffTimevalsToDouble(&err, &(timer_queue.next->tv), &last_select_ts_raw);
|
||||
} else {
|
||||
err = 0.0;
|
||||
}
|
||||
|
||||
diff += err;
|
||||
|
||||
if (timeout) {
|
||||
err = 1.0;
|
||||
}
|
||||
|
||||
LOG(LOGS_WARN, LOGF_Scheduler, "Backward time jump detected! (correction %.1f +- %.1f seconds)", diff, err);
|
||||
|
||||
LCL_NotifyExternalTimeStep(raw, cooked, diff, err);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -510,39 +560,28 @@ handle_slew(struct timeval *raw,
|
||||
void
|
||||
SCH_MainLoop(void)
|
||||
{
|
||||
fd_set rd, wr, ex;
|
||||
int status;
|
||||
fd_set rd;
|
||||
int status, errsv;
|
||||
struct timeval tv, *ptv;
|
||||
struct timeval now;
|
||||
struct timeval now, cooked;
|
||||
double err;
|
||||
|
||||
if (!initialised) {
|
||||
CROAK("Should be initialised");
|
||||
}
|
||||
assert(initialised);
|
||||
|
||||
while (!need_to_exit) {
|
||||
|
||||
/* Copy current set of read file descriptors */
|
||||
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
|
||||
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
|
||||
completed). */
|
||||
|
||||
do {
|
||||
LCL_ReadRawTime(&now);
|
||||
} while (dispatch_timeouts(&now) > 0);
|
||||
/* Dispatch timeouts and fill now with current raw time */
|
||||
dispatch_timeouts(&now);
|
||||
|
||||
/* Check whether there is a timeout and set it up */
|
||||
if (n_timer_queue_entries > 0) {
|
||||
|
||||
UTI_DiffTimevals(&tv, &(timer_queue.next->tv), &now);
|
||||
ptv = &tv;
|
||||
assert(tv.tv_sec > 0 || tv.tv_usec > 0);
|
||||
|
||||
} else {
|
||||
ptv = NULL;
|
||||
@@ -550,30 +589,36 @@ SCH_MainLoop(void)
|
||||
|
||||
/* if there are no file descriptors being waited on and no
|
||||
timeout set, this is clearly ridiculous, so stop the run */
|
||||
assert(ptv || n_read_fds);
|
||||
|
||||
if (!ptv && (n_read_fds == 0)) {
|
||||
LOG_FATAL(LOGF_Scheduler, "No descriptors or timeout to wait for");
|
||||
status = select(one_highest_fd, &rd, NULL, NULL, ptv);
|
||||
errsv = errno;
|
||||
|
||||
LCL_ReadRawTime(&now);
|
||||
LCL_CookTime(&now, &cooked, &err);
|
||||
|
||||
/* Check if time didn't jump backwards */
|
||||
if (last_select_ts_raw.tv_sec > now.tv_sec + 1) {
|
||||
recover_backjump(&now, &cooked, status == 0);
|
||||
}
|
||||
|
||||
status = select(one_highest_fd, &rd, &wr, &ex, ptv);
|
||||
last_select_ts_raw = now;
|
||||
last_select_ts = cooked;
|
||||
last_select_ts_err = err;
|
||||
|
||||
if (status < 0) {
|
||||
CROAK("Status < 0 after select");
|
||||
if (!need_to_exit && errsv != EINTR) {
|
||||
LOG_FATAL(LOGF_Scheduler, "select() failed : %s", strerror(errsv));
|
||||
}
|
||||
} else if (status > 0) {
|
||||
/* A file descriptor is ready to read */
|
||||
|
||||
dispatch_filehandlers(status, &rd);
|
||||
|
||||
} else {
|
||||
if (status != 0) {
|
||||
CROAK("Unexpected value from select");
|
||||
}
|
||||
|
||||
/* No descriptors readable, timeout must have elapsed.
|
||||
Therefore, tv must be non-null */
|
||||
if (!ptv) {
|
||||
CROAK("No descriptors or timeout?");
|
||||
}
|
||||
assert(ptv);
|
||||
|
||||
/* There's nothing to do here, since the timeouts
|
||||
will be dispatched at the top of the next loop
|
||||
@@ -581,9 +626,6 @@ SCH_MainLoop(void)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -591,9 +633,7 @@ SCH_MainLoop(void)
|
||||
void
|
||||
SCH_QuitProgram(void)
|
||||
{
|
||||
if (!initialised) {
|
||||
CROAK("Should be initialised");
|
||||
}
|
||||
assert(initialised);
|
||||
need_to_exit = 1;
|
||||
}
|
||||
|
||||
|
||||
24
sched.h
24
sched.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/sched.h,v 1.10 2002/02/28 23:27:14 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -35,10 +31,12 @@
|
||||
|
||||
typedef unsigned long SCH_TimeoutID;
|
||||
|
||||
typedef unsigned long SCH_TimeoutClass;
|
||||
static const SCH_TimeoutClass SCH_ReservedTimeoutValue = 0;
|
||||
static const SCH_TimeoutClass SCH_NtpSamplingClass = 1;
|
||||
static const SCH_TimeoutClass SCH_NtpBroadcastClass = 2;
|
||||
typedef enum {
|
||||
SCH_ReservedTimeoutValue = 0,
|
||||
SCH_NtpSamplingClass,
|
||||
SCH_NtpBroadcastClass,
|
||||
SCH_NumberOfClasses /* needs to be last */
|
||||
} SCH_TimeoutClass;
|
||||
|
||||
typedef void* SCH_ArbitraryArgument;
|
||||
typedef void (*SCH_FileHandler)(SCH_ArbitraryArgument);
|
||||
@@ -60,6 +58,9 @@ extern void SCH_AddInputFileHandler
|
||||
);
|
||||
extern void SCH_RemoveInputFileHandler(int fd);
|
||||
|
||||
/* Get the time stamp taken after a file descriptor became ready or a timeout expired */
|
||||
extern void SCH_GetLastEventTime(struct timeval *cooked, double *err, struct timeval *raw);
|
||||
|
||||
/* This queues a timeout to elapse at a given (raw) local time */
|
||||
extern SCH_TimeoutID SCH_AddTimeout(struct timeval *tv, SCH_TimeoutHandler, SCH_ArbitraryArgument);
|
||||
|
||||
@@ -68,8 +69,9 @@ extern SCH_TimeoutID SCH_AddTimeoutByDelay(double delay, SCH_TimeoutHandler, SCH
|
||||
|
||||
/* This queues a timeout in a particular class, ensuring that the
|
||||
expiry time is at least a given separation away from any other
|
||||
timeout in the same class */
|
||||
extern SCH_TimeoutID SCH_AddTimeoutInClass(double min_delay, double separation,
|
||||
timeout in the same class, given randomness is added to the delay
|
||||
and separation */
|
||||
extern SCH_TimeoutID SCH_AddTimeoutInClass(double min_delay, double separation, double randomness,
|
||||
SCH_TimeoutClass class,
|
||||
SCH_TimeoutHandler handler, SCH_ArbitraryArgument);
|
||||
|
||||
|
||||
59
sources.h
59
sources.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/sources.h,v 1.15 2002/02/28 23:27:14 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -50,10 +46,22 @@ extern void SRC_Initialise(void);
|
||||
/* Finalisation function */
|
||||
extern void SRC_Finalise(void);
|
||||
|
||||
typedef enum {
|
||||
SRC_NTP, /* NTP client/peer */
|
||||
SRC_REFCLOCK /* Rerefence clock */
|
||||
} SRC_Type;
|
||||
|
||||
/* Options used when selecting sources */
|
||||
typedef enum {
|
||||
SRC_SelectNormal,
|
||||
SRC_SelectNoselect,
|
||||
SRC_SelectPrefer
|
||||
} SRC_SelectOption;
|
||||
|
||||
/* Function to create a new instance. This would be called by one of
|
||||
the individual source-type instance creation routines. */
|
||||
|
||||
extern SRC_Instance SRC_CreateNewInstance(unsigned long ref_id);
|
||||
extern SRC_Instance SRC_CreateNewInstance(uint32_t ref_id, SRC_Type type, SRC_SelectOption sel_option, IPAddr *addr);
|
||||
|
||||
/* Function to get rid of a source when it is being unconfigured.
|
||||
This may cause the current reference source to be reselected, if this
|
||||
@@ -108,21 +116,32 @@ extern void SRC_AccumulateSample(SRC_Instance instance, struct timeval *sample_t
|
||||
|
||||
/* This routine indicates that packets with valid headers are being
|
||||
received from the designated source */
|
||||
extern void SRC_SetReachable(SRC_Instance instance);
|
||||
extern void SRC_SetSelectable(SRC_Instance instance);
|
||||
|
||||
/* This routine indicates that we are no longer receiving packets with
|
||||
valid headers from the designated source */
|
||||
extern void SRC_UnsetReachable(SRC_Instance instance);
|
||||
extern void SRC_UnsetSelectable(SRC_Instance instance);
|
||||
|
||||
/* This routine updates the reachability register */
|
||||
extern void SRC_UpdateReachability(SRC_Instance inst, int reachable);
|
||||
|
||||
/* This routine marks the source unreachable */
|
||||
extern void SRC_ResetReachability(SRC_Instance inst);
|
||||
|
||||
/* This routine is used to select the best source from amongst those
|
||||
we currently have valid data on, and use it as the tracking base
|
||||
for the local time. If match_addr is zero it means we must start
|
||||
tracking the (newly) selected reference unconditionally, otherwise
|
||||
it is equal to the address we should track if it turns out to be
|
||||
the best reference. (This avoids updating the frequency tracking
|
||||
for every sample from other sources - only the ones from the
|
||||
selected reference make a difference) */
|
||||
extern void SRC_SelectSource(unsigned long match_addr);
|
||||
for the local time. Updates are only made to the local reference
|
||||
if a new source is selected or match_addr is equal to the selected
|
||||
reference source address. (This avoids updating the frequency
|
||||
tracking for every sample from other sources - only the ones from
|
||||
the selected reference make a difference) */
|
||||
extern void SRC_SelectSource(uint32_t match_refid);
|
||||
|
||||
/* Force reselecting the best source */
|
||||
extern void SRC_ReselectSource(void);
|
||||
|
||||
/* Set reselect distance */
|
||||
extern void SRC_SetReselectDistance(double distance);
|
||||
|
||||
/* Predict the offset of the local clock relative to a given source at
|
||||
a given local cooked time. Positive indicates local clock is FAST
|
||||
@@ -133,6 +152,10 @@ extern double SRC_PredictOffset(SRC_Instance inst, struct timeval *when);
|
||||
currently held in the register */
|
||||
extern double SRC_MinRoundTripDelay(SRC_Instance inst);
|
||||
|
||||
/* This routine determines if a new sample is good enough that it should be
|
||||
accumulated */
|
||||
extern int SRC_IsGoodSample(SRC_Instance inst, double offset, double delay, double max_delay_dev_ratio, double clock_error, struct timeval *when);
|
||||
|
||||
extern void SRC_DumpSources(void);
|
||||
|
||||
extern void SRC_ReloadSources(void);
|
||||
@@ -141,7 +164,9 @@ extern int SRC_IsSyncPeer(SRC_Instance inst);
|
||||
extern int SRC_ReadNumberOfSources(void);
|
||||
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 {
|
||||
SRC_Skew_Decrease,
|
||||
@@ -151,5 +176,7 @@ typedef enum {
|
||||
|
||||
extern SRC_Skew_Direction SRC_LastSkewChange(SRC_Instance inst);
|
||||
|
||||
extern int SRC_Samples(SRC_Instance inst);
|
||||
|
||||
#endif /* GOT_SOURCES_H */
|
||||
|
||||
|
||||
752
sourcestats.c
752
sourcestats.c
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/sourcestats.h,v 1.13 2002/02/28 23:27:14 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -42,7 +38,7 @@ extern void SST_Initialise(void);
|
||||
extern void SST_Finalise(void);
|
||||
|
||||
/* This function creates a new instance of the statistics handler */
|
||||
extern SST_Stats SST_CreateInstance(unsigned long refid);
|
||||
extern SST_Stats SST_CreateInstance(uint32_t refid, IPAddr *addr);
|
||||
|
||||
/* This function deletes an instance of the statistics handler. */
|
||||
extern void SST_DeleteInstance(SST_Stats inst);
|
||||
@@ -86,26 +82,17 @@ extern void SST_GetFrequencyRange(SST_Stats inst, double *lo, double *hi);
|
||||
extern void
|
||||
SST_GetSelectionData(SST_Stats inst, struct timeval *now,
|
||||
int *stratum,
|
||||
double *best_offset, double *best_root_delay,
|
||||
double *best_root_dispersion,
|
||||
double *variance,
|
||||
int *average_ok);
|
||||
double *offset_lo_limit,
|
||||
double *offset_hi_limit,
|
||||
double *root_distance,
|
||||
double *variance, int *select_ok);
|
||||
|
||||
/* Get data needed when setting up tracking on this source */
|
||||
extern void
|
||||
SST_GetTrackingData(SST_Stats inst, struct timeval *now,
|
||||
SST_GetTrackingData(SST_Stats inst, struct timeval *ref_time,
|
||||
double *average_offset, double *offset_sd,
|
||||
double *accrued_dispersion,
|
||||
double *frequency, double *skew);
|
||||
|
||||
/* Get parameters for using this source as the reference */
|
||||
extern void
|
||||
SST_GetReferenceData(SST_Stats inst, struct timeval *now,
|
||||
int *stratum, double *offset,
|
||||
double *root_delay, double *root_dispersion,
|
||||
double *frequency, double *skew);
|
||||
|
||||
|
||||
double *frequency, double *skew,
|
||||
double *root_delay, double *root_dispersion);
|
||||
|
||||
/* This routine is called when the local machine clock parameters are
|
||||
changed. It adjusts all existing samples that we are holding for
|
||||
@@ -125,6 +112,9 @@ SST_GetReferenceData(SST_Stats inst, struct timeval *now,
|
||||
|
||||
extern void SST_SlewSamples(SST_Stats inst, struct timeval *when, double dfreq, double doffset);
|
||||
|
||||
/* This routine is called when an indeterminate offset is introduced
|
||||
into the local time. */
|
||||
extern void SST_AddDispersion(SST_Stats inst, double dispersion);
|
||||
|
||||
/* Predict the offset of the local clock relative to a given source at
|
||||
a given local cooked time. Positive indicates local clock is FAST
|
||||
@@ -134,13 +124,18 @@ extern double SST_PredictOffset(SST_Stats inst, struct timeval *when);
|
||||
/* Find the minimum round trip delay in the register */
|
||||
extern double SST_MinRoundTripDelay(SST_Stats inst);
|
||||
|
||||
/* This routine determines if a new sample is good enough that it should be
|
||||
accumulated */
|
||||
extern int SST_IsGoodSample(SST_Stats inst, double offset, double delay,
|
||||
double max_delay_dev_ratio, double clock_error, struct timeval *when);
|
||||
|
||||
extern void SST_SaveToFile(SST_Stats inst, FILE *out);
|
||||
|
||||
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_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *report);
|
||||
extern void SST_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *report, struct timeval *now);
|
||||
|
||||
typedef enum {
|
||||
SST_Skew_Decrease,
|
||||
@@ -150,7 +145,7 @@ typedef enum {
|
||||
|
||||
extern SST_Skew_Direction SST_LastSkewChange(SST_Stats inst);
|
||||
|
||||
extern void SST_CycleLogFile(void);
|
||||
extern int SST_Samples(SST_Stats inst);
|
||||
|
||||
#endif /* GOT_SOURCESTATS_H */
|
||||
|
||||
|
||||
22
srcparams.h
22
srcparams.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/srcparams.h,v 1.10 2002/02/28 23:27:14 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -31,17 +27,33 @@
|
||||
#ifndef GOT_SRCPARAMS_H
|
||||
#define GOT_SRCPARAMS_H
|
||||
|
||||
#include "sources.h"
|
||||
|
||||
typedef struct {
|
||||
int minpoll;
|
||||
int maxpoll;
|
||||
int online;
|
||||
int auto_offline;
|
||||
int presend_minpoll;
|
||||
int iburst;
|
||||
int min_stratum;
|
||||
int poll_target;
|
||||
unsigned long authkey;
|
||||
double max_delay;
|
||||
double max_delay_ratio;
|
||||
double max_delay_dev_ratio;
|
||||
SRC_SelectOption sel_option;
|
||||
} SourceParameters;
|
||||
|
||||
#define SRC_DEFAULT_PORT 123
|
||||
#define SRC_DEFAULT_MINPOLL 6
|
||||
#define SRC_DEFAULT_MAXPOLL 10
|
||||
#define SRC_DEFAULT_PRESEND_MINPOLL 0
|
||||
#define SRC_DEFAULT_MAXDELAY 16.0
|
||||
#define SRC_DEFAULT_MAXDELAYRATIO 0.0
|
||||
#define SRC_DEFAULT_MAXDELAYDEVRATIO 10.0
|
||||
#define SRC_DEFAULT_MINSTRATUM 0
|
||||
#define SRC_DEFAULT_POLLTARGET 6
|
||||
#define INACTIVE_AUTHKEY 0UL
|
||||
|
||||
#endif /* GOT_SRCPARAMS_H */
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/strerror.c,v 1.8 2002/02/28 23:27:14 richard Exp $
|
||||
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -20,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -29,6 +24,8 @@
|
||||
Replacement strerror function for systems that don't have it
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef SUNOS
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
41
sys.c
41
sys.c
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/sys.c,v 1.11 2002/02/28 23:27:14 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -29,7 +25,10 @@
|
||||
in the various operating-system specific modules
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sys.h"
|
||||
#include "logging.h"
|
||||
|
||||
#if defined (LINUX)
|
||||
#include "sys_linux.h"
|
||||
@@ -92,13 +91,39 @@ SYS_Finalise(void)
|
||||
#if defined(__NetBSD__)
|
||||
SYS_NetBSD_Finalise();
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
/* ================================================== */
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void SYS_LockMemory(void)
|
||||
{
|
||||
#if defined(LINUX) && defined(HAVE_MLOCKALL)
|
||||
SYS_Linux_MemLockAll(1);
|
||||
#else
|
||||
LOG_FATAL(LOGF_Sys, "memory locking not supported");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
12
sys.h
12
sys.h
@@ -1,8 +1,4 @@
|
||||
/*
|
||||
$Header: /cvs/src/chrony/sys.h,v 1.7 2002/02/28 23:27:14 richard Exp $
|
||||
|
||||
=======================================================================
|
||||
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
@@ -19,7 +15,7 @@
|
||||
*
|
||||
* 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.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
|
||||
@@ -39,4 +35,10 @@ extern void SYS_Initialise(void);
|
||||
/* Called at the end of the run to do final clean-up */
|
||||
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 */
|
||||
|
||||
1002
sys_linux.c
1002
sys_linux.c
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user