From 8b9021bf3403ce74f1b20266053352687f685c5c Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Thu, 24 May 2018 15:17:53 +0200 Subject: [PATCH] ntp: allow online/offline state to be selected by connectability Allow SRC_MAYBE_ONLINE to be specified for new NTP sources and connectivity setting to select between SRC_ONLINE and SRC_OFFLINE according to the result of the connect() system call, i.e. check whether the client has a route to send its requests. --- ntp_core.c | 7 ++++++- ntp_io.c | 17 +++++++++++++++++ ntp_io.h | 3 +++ srcparams.h | 1 + 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/ntp_core.c b/ntp_core.c index 45956e7..c9d0969 100644 --- a/ntp_core.c +++ b/ntp_core.c @@ -603,7 +603,9 @@ NCR_GetInstance(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourcePar result->rx_timeout_id = 0; result->tx_timeout_id = 0; result->tx_suspended = 1; - result->opmode = params->connectivity == SRC_ONLINE ? MD_ONLINE : MD_OFFLINE; + result->opmode = params->connectivity == SRC_ONLINE || + (params->connectivity == SRC_MAYBE_ONLINE && + NIO_IsServerConnectable(remote_addr)) ? MD_ONLINE : MD_OFFLINE; result->local_poll = result->minpoll; result->poll_score = 0.0; zero_local_timestamp(&result->local_tx); @@ -2281,6 +2283,9 @@ NCR_SetConnectivity(NCR_Instance inst, SRC_Connectivity connectivity) s = UTI_IPToString(&inst->remote_addr.ip_addr); + if (connectivity == SRC_MAYBE_ONLINE) + connectivity = NIO_IsServerConnectable(&inst->remote_addr) ? SRC_ONLINE : SRC_OFFLINE; + switch (connectivity) { case SRC_ONLINE: switch (inst->opmode) { diff --git a/ntp_io.c b/ntp_io.c index 3a3398a..8df093e 100644 --- a/ntp_io.c +++ b/ntp_io.c @@ -574,6 +574,23 @@ NIO_IsServerSocket(int sock_fd) /* ================================================== */ +int +NIO_IsServerConnectable(NTP_Remote_Address *remote_addr) +{ + int sock_fd, r; + + sock_fd = prepare_separate_client_socket(remote_addr->ip_addr.family); + if (sock_fd == INVALID_SOCK_FD) + return 0; + + r = connect_socket(sock_fd, remote_addr); + close_socket(sock_fd); + + return r; +} + +/* ================================================== */ + static void process_message(struct msghdr *hdr, int length, int sock_fd) { diff --git a/ntp_io.h b/ntp_io.h index 1bdcf12..628f736 100644 --- a/ntp_io.h +++ b/ntp_io.h @@ -53,6 +53,9 @@ extern void NIO_CloseServerSocket(int sock_fd); /* Function to check if socket is a server socket */ extern int NIO_IsServerSocket(int sock_fd); +/* Function to check if client packets can be sent to a server */ +extern int NIO_IsServerConnectable(NTP_Remote_Address *remote_addr); + /* Function to transmit a packet */ extern int NIO_SendPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int length, int process_tx); diff --git a/srcparams.h b/srcparams.h index 48fa19c..e11edc6 100644 --- a/srcparams.h +++ b/srcparams.h @@ -32,6 +32,7 @@ typedef enum { SRC_OFFLINE, SRC_ONLINE, + SRC_MAYBE_ONLINE, } SRC_Connectivity; typedef struct {