diff --git a/chrony.texi.in b/chrony.texi.in index fd2f487..7192ed3 100644 --- a/chrony.texi.in +++ b/chrony.texi.in @@ -2900,6 +2900,11 @@ Target number of measurements to use for the regression algorithm which @code{minpoll} and @code{maxpoll}. A higher target makes @code{chronyd} prefer shorter polling intervals. The default is 6 and a useful range is 6 to 60. +@item version +This option sets the NTP version number used in packets sent to the server. +This can be useful when the server runs an old NTP implementation that doesn't +respond to newer versions. The default version number is 4. + @item prefer Prefer this source over sources without prefer option. diff --git a/client.c b/client.c index d0df889..7c01435 100644 --- a/client.c +++ b/client.c @@ -955,6 +955,11 @@ process_cmd_add_server_or_peer(CMD_Request *msg, char *line) break; } + if (data.params.version != NTP_VERSION) { + fprintf(stderr, "Option version not supported\n"); + break; + } + msg->data.ntp_source.port = htonl((unsigned long) data.port); UTI_IPHostToNetwork(&ip_addr, &msg->data.ntp_source.ip_addr); msg->data.ntp_source.minpoll = htonl(data.params.minpoll); @@ -1008,6 +1013,9 @@ process_cmd_add_server_or_peer(CMD_Request *msg, char *line) case CPS_BadPolltarget: fprintf(stderr, "Unreadable polltarget value\n"); break; + case CPS_BadVersion: + fprintf(stderr, "Unreadable version value\n"); + break; } return result; diff --git a/cmdparse.c b/cmdparse.c index cca94a3..5e589ef 100644 --- a/cmdparse.c +++ b/cmdparse.c @@ -34,6 +34,7 @@ #include "cmdparse.h" #include "memory.h" #include "nameserv.h" +#include "ntp.h" #include "util.h" /* ================================================== */ @@ -58,6 +59,7 @@ CPS_ParseNTPSourceAdd(char *line, CPS_NTP_Source *src) src->params.iburst = 0; src->params.min_stratum = SRC_DEFAULT_MINSTRATUM; src->params.poll_target = SRC_DEFAULT_POLLTARGET; + src->params.version = NTP_VERSION; src->params.sel_option = SRC_SelectNormal; result = CPS_Success; @@ -165,6 +167,14 @@ CPS_ParseNTPSourceAdd(char *line, CPS_NTP_Source *src) } else if (!strcasecmp(cmd, "prefer")) { src->params.sel_option = SRC_SelectPrefer; + } else if (!strcasecmp(cmd, "version")) { + if (sscanf(line, "%d%n", &src->params.version, &n) != 1) { + result = CPS_BadVersion; + done = 1; + } else { + line += n; + } + } else { result = CPS_BadOption; done = 1; diff --git a/cmdparse.h b/cmdparse.h index 6807f72..df8484a 100644 --- a/cmdparse.h +++ b/cmdparse.h @@ -43,7 +43,8 @@ typedef enum { CPS_BadMaxdelay, CPS_BadKey, CPS_BadMinstratum, - CPS_BadPolltarget + CPS_BadPolltarget, + CPS_BadVersion } CPS_Status; typedef struct { diff --git a/conf.c b/conf.c index cdd8894..26a15be 100644 --- a/conf.c +++ b/conf.c @@ -604,6 +604,9 @@ parse_source(char *line, NTP_Source_Type type) case CPS_BadPolltarget: other_parse_error("Unreadable polltarget"); break; + case CPS_BadVersion: + other_parse_error("Unreadable version"); + break; } } diff --git a/ntp_core.c b/ntp_core.c index 214ea72..cdc32df 100644 --- a/ntp_core.c +++ b/ntp_core.c @@ -105,6 +105,8 @@ struct NCR_Instance_Record { int poll_target; /* Target number of sourcestats samples */ + int version; /* Version set in packets for server/peer */ + double poll_score; /* Score of current local poll */ double max_delay; /* Maximum round-trip delay to the @@ -440,6 +442,12 @@ NCR_GetInstance(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourcePar result->auto_offline = params->auto_offline; result->poll_target = params->poll_target; + result->version = params->version; + if (result->version < NTP_MIN_COMPAT_VERSION) + result->version = NTP_MIN_COMPAT_VERSION; + else if (result->version > NTP_VERSION) + result->version = NTP_VERSION; + if (params->authkey == INACTIVE_AUTHKEY) { result->do_auth = 0; result->auth_key_id = 0; @@ -864,7 +872,7 @@ transmit_timeout(void *arg) /* Send a client packet, don't store the local tx values as the reply will be ignored */ - transmit_packet(MODE_CLIENT, inst->local_poll, NTP_VERSION, 0, 0, + transmit_packet(MODE_CLIENT, inst->local_poll, inst->version, 0, 0, &inst->remote_orig, &inst->local_rx, NULL, NULL, &inst->remote_addr, &inst->local_addr); @@ -879,7 +887,7 @@ transmit_timeout(void *arg) inst->presend_done = 0; /* Reset for next time */ sent = transmit_packet(inst->mode, inst->local_poll, - NTP_VERSION, + inst->version, inst->do_auth, inst->auth_key_id, &inst->remote_orig, &inst->local_rx, &inst->local_tx, &inst->local_ntp_tx, diff --git a/srcparams.h b/srcparams.h index d37f6c1..5fd7517 100644 --- a/srcparams.h +++ b/srcparams.h @@ -38,6 +38,7 @@ typedef struct { int iburst; int min_stratum; int poll_target; + int version; uint32_t authkey; double max_delay; double max_delay_ratio;