1 /*
2 chronyd/chronyc - Programs for keeping computer clocks accurate.
3
4 **********************************************************************
5 * Copyright (C) Richard P. Curnow 1997-2003
6 * Copyright (C) Timo Teras 2009
7 * Copyright (C) Miroslav Lichvar 2009, 2013-2016, 2018-2021
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 *
22 **********************************************************************
23
24 =======================================================================
25
26 This file deals with the IO aspects of reading and writing NTP packets
27 */
28
29 #include "config.h"
30
31 #include "sysincl.h"
32
33 #include "memory.h"
34 #include "ntp_io.h"
35 #include "ntp_core.h"
36 #include "ntp_sources.h"
37 #include "ptp.h"
38 #include "sched.h"
39 #include "socket.h"
40 #include "local.h"
41 #include "logging.h"
42 #include "conf.h"
43 #include "privops.h"
44 #include "util.h"
45
46 #ifdef HAVE_LINUX_TIMESTAMPING
47 #include "ntp_io_linux.h"
48 #endif
49
50 #define INVALID_SOCK_FD -1
51
52 /* The server/peer and client sockets for IPv4 and IPv6 */
53 static int server_sock_fd4;
54 static int server_sock_fd6;
55 static int client_sock_fd4;
56 static int client_sock_fd6;
57
58 /* Reference counters for server sockets to keep them open only when needed */
59 static int server_sock_ref4;
60 static int server_sock_ref6;
61
62 /* Flag indicating we create a new connected client socket for each
63 server instead of sharing client_sock_fd4 and client_sock_fd6 */
64 static int separate_client_sockets;
65
66 /* Flag indicating the server sockets are not created dynamically when needed,
67 either to have a socket for client requests when separate client sockets
68 are disabled and client port is equal to server port, or the server port is
69 disabled */
70 static int permanent_server_sockets;
71
72 /* Flag indicating the server IPv4 socket is bound to an address */
73 static int bound_server_sock_fd4;
74
75 /* PTP event port, or 0 if disabled */
76 static int ptp_port;
77
78 /* Shared server/client sockets for NTP-over-PTP */
79 static int ptp_sock_fd4;
80 static int ptp_sock_fd6;
81
82 /* Buffer for transmitted NTP-over-PTP messages */
83 static PTP_NtpMessage *ptp_message;
84
85 /* Flag indicating that we have been initialised */
86 static int initialised=0;
87
88 /* ================================================== */
89
90 /* Forward prototypes */
91 static void read_from_socket(int sock_fd, int event, void *anything);
92
93 /* ================================================== */
94
95 static int
open_socket(int family,int local_port,int client_only,IPSockAddr * remote_addr)96 open_socket(int family, int local_port, int client_only, IPSockAddr *remote_addr)
97 {
98 int sock_fd, sock_flags, dscp, events = SCH_FILE_INPUT;
99 IPSockAddr local_addr;
100 char *iface;
101
102 if (!SCK_IsIpFamilyEnabled(family))
103 return INVALID_SOCK_FD;
104
105 if (!client_only) {
106 CNF_GetBindAddress(family, &local_addr.ip_addr);
107 iface = CNF_GetBindNtpInterface();
108 } else {
109 CNF_GetBindAcquisitionAddress(family, &local_addr.ip_addr);
110 iface = CNF_GetBindAcquisitionInterface();
111 }
112
113 local_addr.port = local_port;
114
115 sock_flags = SCK_FLAG_RX_DEST_ADDR | SCK_FLAG_PRIV_BIND;
116 if (!client_only)
117 sock_flags |= SCK_FLAG_BROADCAST;
118
119 sock_fd = SCK_OpenUdpSocket(remote_addr, &local_addr, iface, sock_flags);
120 if (sock_fd < 0) {
121 if (!client_only)
122 LOG(LOGS_ERR, "Could not open NTP socket on %s", UTI_IPSockAddrToString(&local_addr));
123 return INVALID_SOCK_FD;
124 }
125
126 dscp = CNF_GetNtpDscp();
127 if (dscp > 0 && dscp < 64) {
128 #ifdef IP_TOS
129 if (!SCK_SetIntOption(sock_fd, IPPROTO_IP, IP_TOS, dscp << 2))
130 ;
131 #endif
132 }
133
134 if (!client_only && family == IPADDR_INET4 && local_addr.port > 0)
135 bound_server_sock_fd4 = local_addr.ip_addr.addr.in4 != INADDR_ANY;
136
137 /* Enable kernel/HW timestamping of packets */
138 #ifdef HAVE_LINUX_TIMESTAMPING
139 if (!NIO_Linux_SetTimestampSocketOptions(sock_fd, client_only, &events))
140 #endif
141 if (!SCK_EnableKernelRxTimestamping(sock_fd))
142 ;
143
144 /* Register handler for read and possibly exception events on the socket */
145 SCH_AddFileHandler(sock_fd, events, read_from_socket, NULL);
146
147 return sock_fd;
148 }
149
150 /* ================================================== */
151
152 static int
open_separate_client_socket(IPSockAddr * remote_addr)153 open_separate_client_socket(IPSockAddr *remote_addr)
154 {
155 return open_socket(remote_addr->ip_addr.family, 0, 1, remote_addr);
156 }
157
158 /* ================================================== */
159
160 static void
close_socket(int sock_fd)161 close_socket(int sock_fd)
162 {
163 if (sock_fd == INVALID_SOCK_FD)
164 return;
165
166 #ifdef HAVE_LINUX_TIMESTAMPING
167 NIO_Linux_NotifySocketClosing(sock_fd);
168 #endif
169 SCH_RemoveFileHandler(sock_fd);
170 SCK_CloseSocket(sock_fd);
171 }
172
173 /* ================================================== */
174
175 void
NIO_Initialise(void)176 NIO_Initialise(void)
177 {
178 int server_port, client_port;
179
180 assert(!initialised);
181 initialised = 1;
182
183 #ifdef PRIVOPS_BINDSOCKET
184 SCK_SetPrivBind(PRV_BindSocket);
185 #endif
186
187 #ifdef HAVE_LINUX_TIMESTAMPING
188 NIO_Linux_Initialise();
189 #else
190 if (1) {
191 CNF_HwTsInterface *conf_iface;
192 if (CNF_GetHwTsInterface(0, &conf_iface))
193 LOG_FATAL("HW timestamping not supported");
194 }
195 #endif
196
197 server_port = CNF_GetNTPPort();
198 client_port = CNF_GetAcquisitionPort();
199
200 /* Use separate connected sockets if client port is negative */
201 separate_client_sockets = client_port < 0;
202 if (client_port < 0)
203 client_port = 0;
204
205 permanent_server_sockets = !server_port || (!separate_client_sockets &&
206 client_port == server_port);
207
208 server_sock_fd4 = INVALID_SOCK_FD;
209 server_sock_fd6 = INVALID_SOCK_FD;
210 client_sock_fd4 = INVALID_SOCK_FD;
211 client_sock_fd6 = INVALID_SOCK_FD;
212 server_sock_ref4 = 0;
213 server_sock_ref6 = 0;
214
215 if (permanent_server_sockets && server_port) {
216 server_sock_fd4 = open_socket(IPADDR_INET4, server_port, 0, NULL);
217 server_sock_fd6 = open_socket(IPADDR_INET6, server_port, 0, NULL);
218 }
219
220 if (!separate_client_sockets) {
221 if (client_port != server_port || !server_port) {
222 client_sock_fd4 = open_socket(IPADDR_INET4, client_port, 1, NULL);
223 client_sock_fd6 = open_socket(IPADDR_INET6, client_port, 1, NULL);
224 } else {
225 client_sock_fd4 = server_sock_fd4;
226 client_sock_fd6 = server_sock_fd6;
227 }
228 }
229
230 if ((server_port && permanent_server_sockets &&
231 server_sock_fd4 == INVALID_SOCK_FD && server_sock_fd6 == INVALID_SOCK_FD) ||
232 (!separate_client_sockets &&
233 client_sock_fd4 == INVALID_SOCK_FD && client_sock_fd6 == INVALID_SOCK_FD)) {
234 LOG_FATAL("Could not open NTP sockets");
235 }
236
237 ptp_port = CNF_GetPtpPort();
238 ptp_sock_fd4 = INVALID_SOCK_FD;
239 ptp_sock_fd6 = INVALID_SOCK_FD;
240 ptp_message = NULL;
241
242 if (ptp_port > 0) {
243 ptp_sock_fd4 = open_socket(IPADDR_INET4, ptp_port, 0, NULL);
244 ptp_sock_fd6 = open_socket(IPADDR_INET6, ptp_port, 0, NULL);
245 ptp_message = MallocNew(PTP_NtpMessage);
246 }
247 }
248
249 /* ================================================== */
250
251 void
NIO_Finalise(void)252 NIO_Finalise(void)
253 {
254 if (server_sock_fd4 != client_sock_fd4)
255 close_socket(client_sock_fd4);
256 close_socket(server_sock_fd4);
257 server_sock_fd4 = client_sock_fd4 = INVALID_SOCK_FD;
258
259 if (server_sock_fd6 != client_sock_fd6)
260 close_socket(client_sock_fd6);
261 close_socket(server_sock_fd6);
262 server_sock_fd6 = client_sock_fd6 = INVALID_SOCK_FD;
263
264 close_socket(ptp_sock_fd4);
265 close_socket(ptp_sock_fd6);
266 ptp_sock_fd4 = ptp_sock_fd6 = INVALID_SOCK_FD;
267 Free(ptp_message);
268
269 #ifdef HAVE_LINUX_TIMESTAMPING
270 NIO_Linux_Finalise();
271 #endif
272
273 initialised = 0;
274 }
275
276 /* ================================================== */
277
278 int
NIO_OpenClientSocket(NTP_Remote_Address * remote_addr)279 NIO_OpenClientSocket(NTP_Remote_Address *remote_addr)
280 {
281 switch (remote_addr->ip_addr.family) {
282 case IPADDR_INET4:
283 if (ptp_port > 0 && remote_addr->port == ptp_port)
284 return ptp_sock_fd4;
285 if (separate_client_sockets)
286 return open_separate_client_socket(remote_addr);
287 return client_sock_fd4;
288 case IPADDR_INET6:
289 if (ptp_port > 0 && remote_addr->port == ptp_port)
290 return ptp_sock_fd6;
291 if (separate_client_sockets)
292 return open_separate_client_socket(remote_addr);
293 return client_sock_fd6;
294 default:
295 return INVALID_SOCK_FD;
296 }
297 }
298
299 /* ================================================== */
300
301 int
NIO_OpenServerSocket(NTP_Remote_Address * remote_addr)302 NIO_OpenServerSocket(NTP_Remote_Address *remote_addr)
303 {
304 switch (remote_addr->ip_addr.family) {
305 case IPADDR_INET4:
306 if (ptp_port > 0 && remote_addr->port == ptp_port)
307 return ptp_sock_fd4;
308 if (permanent_server_sockets)
309 return server_sock_fd4;
310 if (server_sock_fd4 == INVALID_SOCK_FD)
311 server_sock_fd4 = open_socket(IPADDR_INET4, CNF_GetNTPPort(), 0, NULL);
312 if (server_sock_fd4 != INVALID_SOCK_FD)
313 server_sock_ref4++;
314 return server_sock_fd4;
315 case IPADDR_INET6:
316 if (ptp_port > 0 && remote_addr->port == ptp_port)
317 return ptp_sock_fd6;
318 if (permanent_server_sockets)
319 return server_sock_fd6;
320 if (server_sock_fd6 == INVALID_SOCK_FD)
321 server_sock_fd6 = open_socket(IPADDR_INET6, CNF_GetNTPPort(), 0, NULL);
322 if (server_sock_fd6 != INVALID_SOCK_FD)
323 server_sock_ref6++;
324 return server_sock_fd6;
325 default:
326 return INVALID_SOCK_FD;
327 }
328 }
329
330 /* ================================================== */
331
332 static int
is_ptp_socket(int sock_fd)333 is_ptp_socket(int sock_fd)
334 {
335 return ptp_port > 0 && sock_fd != INVALID_SOCK_FD &&
336 (sock_fd == ptp_sock_fd4 || sock_fd == ptp_sock_fd6);
337 }
338
339 /* ================================================== */
340
341 void
NIO_CloseClientSocket(int sock_fd)342 NIO_CloseClientSocket(int sock_fd)
343 {
344 if (is_ptp_socket(sock_fd))
345 return;
346
347 if (separate_client_sockets)
348 close_socket(sock_fd);
349 }
350
351 /* ================================================== */
352
353 void
NIO_CloseServerSocket(int sock_fd)354 NIO_CloseServerSocket(int sock_fd)
355 {
356 if (permanent_server_sockets || sock_fd == INVALID_SOCK_FD || is_ptp_socket(sock_fd))
357 return;
358
359 if (sock_fd == server_sock_fd4) {
360 if (--server_sock_ref4 <= 0) {
361 close_socket(server_sock_fd4);
362 server_sock_fd4 = INVALID_SOCK_FD;
363 }
364 } else if (sock_fd == server_sock_fd6) {
365 if (--server_sock_ref6 <= 0) {
366 close_socket(server_sock_fd6);
367 server_sock_fd6 = INVALID_SOCK_FD;
368 }
369 } else {
370 assert(0);
371 }
372 }
373
374 /* ================================================== */
375
376 int
NIO_IsServerSocket(int sock_fd)377 NIO_IsServerSocket(int sock_fd)
378 {
379 return sock_fd != INVALID_SOCK_FD &&
380 (sock_fd == server_sock_fd4 || sock_fd == server_sock_fd6 || is_ptp_socket(sock_fd));
381 }
382
383 /* ================================================== */
384
385 int
NIO_IsServerSocketOpen(void)386 NIO_IsServerSocketOpen(void)
387 {
388 return server_sock_fd4 != INVALID_SOCK_FD || server_sock_fd6 != INVALID_SOCK_FD ||
389 ptp_sock_fd4 != INVALID_SOCK_FD || ptp_sock_fd6 != INVALID_SOCK_FD;
390 }
391
392 /* ================================================== */
393
394 int
NIO_IsServerConnectable(NTP_Remote_Address * remote_addr)395 NIO_IsServerConnectable(NTP_Remote_Address *remote_addr)
396 {
397 int sock_fd;
398
399 sock_fd = open_separate_client_socket(remote_addr);
400 if (sock_fd == INVALID_SOCK_FD)
401 return 0;
402
403 close_socket(sock_fd);
404
405 return 1;
406 }
407
408 /* ================================================== */
409
410 static void
process_message(SCK_Message * message,int sock_fd,int event)411 process_message(SCK_Message *message, int sock_fd, int event)
412 {
413 NTP_Local_Address local_addr;
414 NTP_Local_Timestamp local_ts;
415 struct timespec sched_ts;
416
417 SCH_GetLastEventTime(&local_ts.ts, &local_ts.err, NULL);
418 local_ts.source = NTP_TS_DAEMON;
419 sched_ts = local_ts.ts;
420
421 if (message->addr_type != SCK_ADDR_IP) {
422 DEBUG_LOG("Unexpected address type");
423 return;
424 }
425
426 local_addr.ip_addr = message->local_addr.ip;
427 local_addr.if_index = message->if_index;;
428 local_addr.sock_fd = sock_fd;
429
430 #ifdef HAVE_LINUX_TIMESTAMPING
431 if (NIO_Linux_ProcessMessage(message, &local_addr, &local_ts, event))
432 return;
433 #else
434 if (!UTI_IsZeroTimespec(&message->timestamp.kernel)) {
435 LCL_CookTime(&message->timestamp.kernel, &local_ts.ts, &local_ts.err);
436 local_ts.source = NTP_TS_KERNEL;
437 }
438 #endif
439
440 if (local_ts.source != NTP_TS_DAEMON)
441 DEBUG_LOG("Updated RX timestamp delay=%.9f tss=%u",
442 UTI_DiffTimespecsToDouble(&sched_ts, &local_ts.ts), local_ts.source);
443
444 if (!NIO_UnwrapMessage(message, sock_fd))
445 return;
446
447 /* Just ignore the packet if it's not of a recognized length */
448 if (message->length < NTP_HEADER_LENGTH || message->length > sizeof (NTP_Packet)) {
449 DEBUG_LOG("Unexpected length");
450 return;
451 }
452
453 NSR_ProcessRx(&message->remote_addr.ip, &local_addr, &local_ts, message->data, message->length);
454 }
455
456 /* ================================================== */
457
458 static void
read_from_socket(int sock_fd,int event,void * anything)459 read_from_socket(int sock_fd, int event, void *anything)
460 {
461 SCK_Message *messages;
462 int i, received, flags = 0;
463
464 #ifdef HAVE_LINUX_TIMESTAMPING
465 if (NIO_Linux_ProcessEvent(sock_fd, event))
466 return;
467 #endif
468
469 if (event == SCH_FILE_EXCEPTION) {
470 #ifdef HAVE_LINUX_TIMESTAMPING
471 flags |= SCK_FLAG_MSG_ERRQUEUE;
472 #else
473 assert(0);
474 #endif
475 }
476
477 messages = SCK_ReceiveMessages(sock_fd, flags, &received);
478 if (!messages)
479 return;
480
481 for (i = 0; i < received; i++)
482 process_message(&messages[i], sock_fd, event);
483 }
484
485 /* ================================================== */
486
487 int
NIO_UnwrapMessage(SCK_Message * message,int sock_fd)488 NIO_UnwrapMessage(SCK_Message *message, int sock_fd)
489 {
490 PTP_NtpMessage *msg;
491
492 if (!is_ptp_socket(sock_fd))
493 return 1;
494
495 if (message->length <= PTP_NTP_PREFIX_LENGTH) {
496 DEBUG_LOG("Unexpected length");
497 return 0;
498 }
499
500 msg = message->data;
501
502 if (msg->header.type != PTP_TYPE_DELAY_REQ || msg->header.version != PTP_VERSION ||
503 ntohs(msg->header.length) != message->length ||
504 msg->header.domain != PTP_DOMAIN_NTP ||
505 ntohs(msg->header.flags) != PTP_FLAG_UNICAST ||
506 ntohs(msg->tlv_header.type) != PTP_TLV_NTP ||
507 ntohs(msg->tlv_header.length) != message->length - PTP_NTP_PREFIX_LENGTH) {
508 DEBUG_LOG("Unexpected PTP message");
509 return 0;
510 }
511
512 message->data = (char *)message->data + PTP_NTP_PREFIX_LENGTH;
513 message->length -= PTP_NTP_PREFIX_LENGTH;
514
515 DEBUG_LOG("Unwrapped PTP->NTP len=%d", message->length);
516
517 return 1;
518 }
519
520 /* ================================================== */
521
522 static int
wrap_message(SCK_Message * message,int sock_fd)523 wrap_message(SCK_Message *message, int sock_fd)
524 {
525 assert(PTP_NTP_PREFIX_LENGTH == 48);
526
527 if (!is_ptp_socket(sock_fd))
528 return 1;
529
530 if (!ptp_message)
531 return 0;
532
533 if (message->length < NTP_HEADER_LENGTH ||
534 message->length + PTP_NTP_PREFIX_LENGTH > sizeof (*ptp_message)) {
535 DEBUG_LOG("Unexpected length");
536 return 0;
537 }
538
539 memset(ptp_message, 0, PTP_NTP_PREFIX_LENGTH);
540 ptp_message->header.type = PTP_TYPE_DELAY_REQ;
541 ptp_message->header.version = PTP_VERSION;
542 ptp_message->header.length = htons(PTP_NTP_PREFIX_LENGTH + message->length);
543 ptp_message->header.domain = PTP_DOMAIN_NTP;
544 ptp_message->header.flags = htons(PTP_FLAG_UNICAST);
545 ptp_message->tlv_header.type = htons(PTP_TLV_NTP);
546 ptp_message->tlv_header.length = htons(message->length);
547 memcpy((char *)ptp_message + PTP_NTP_PREFIX_LENGTH, message->data, message->length);
548
549 message->data = ptp_message;
550 message->length += PTP_NTP_PREFIX_LENGTH;
551
552 DEBUG_LOG("Wrapped NTP->PTP len=%d", message->length - PTP_NTP_PREFIX_LENGTH);
553
554 return 1;
555 }
556
557 /* ================================================== */
558 /* Send a packet to remote address from local address */
559
560 int
NIO_SendPacket(NTP_Packet * packet,NTP_Remote_Address * remote_addr,NTP_Local_Address * local_addr,int length,int process_tx)561 NIO_SendPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr,
562 NTP_Local_Address *local_addr, int length, int process_tx)
563 {
564 SCK_Message message;
565
566 assert(initialised);
567
568 if (local_addr->sock_fd == INVALID_SOCK_FD) {
569 DEBUG_LOG("No socket to send to %s", UTI_IPSockAddrToString(remote_addr));
570 return 0;
571 }
572
573 SCK_InitMessage(&message, SCK_ADDR_IP);
574
575 message.data = packet;
576 message.length = length;
577
578 if (!wrap_message(&message, local_addr->sock_fd))
579 return 0;
580
581 /* Specify remote address if the socket is not connected */
582 if (NIO_IsServerSocket(local_addr->sock_fd) || !separate_client_sockets) {
583 message.remote_addr.ip.ip_addr = remote_addr->ip_addr;
584 message.remote_addr.ip.port = remote_addr->port;
585 }
586
587 message.local_addr.ip = local_addr->ip_addr;
588
589 /* Don't require responses to non-link-local addresses to use the same
590 interface */
591 message.if_index = SCK_IsLinkLocalIPAddress(&message.remote_addr.ip.ip_addr) ?
592 local_addr->if_index : INVALID_IF_INDEX;
593
594 #if !defined(HAVE_IN_PKTINFO) && defined(IP_SENDSRCADDR)
595 /* On FreeBSD a local IPv4 address cannot be specified on bound socket */
596 if (message.local_addr.ip.family == IPADDR_INET4 &&
597 (bound_server_sock_fd4 || !NIO_IsServerSocket(local_addr->sock_fd)))
598 message.local_addr.ip.family = IPADDR_UNSPEC;
599 #endif
600
601 #ifdef HAVE_LINUX_TIMESTAMPING
602 if (process_tx)
603 NIO_Linux_RequestTxTimestamp(&message, local_addr->sock_fd);
604 #endif
605
606 if (!SCK_SendMessage(local_addr->sock_fd, &message, 0))
607 return 0;
608
609 return 1;
610 }
611