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);
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) {
/* ================================================== */
+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)
{
/* 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);
typedef enum {
SRC_OFFLINE,
SRC_ONLINE,
+ SRC_MAYBE_ONLINE,
} SRC_Connectivity;
typedef struct {