123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715 |
- #include "libbb.h"
- #include <math.h>
- #include <netinet/ip.h> /* For IPTOS_LOWDELAY definition */
- #include <sys/resource.h> /* setpriority */
- #include <sys/timex.h>
- #ifndef IPTOS_LOWDELAY
- # define IPTOS_LOWDELAY 0x10
- #endif
- #define MAX_VERBOSE 3
- #define INITIAL_SAMPLES 4
- #define BAD_DELAY_GROWTH 4
- #define RETRY_INTERVAL 32
- #define NOREPLY_INTERVAL 512
- #define RESPONSE_INTERVAL 16
- #define HOSTNAME_INTERVAL 4
- #define DNS_ERRORS_CAP 0x3f
- #define STEP_THRESHOLD 1
- #define SLEW_THRESHOLD 0.125
- #define WATCH_THRESHOLD 128
- #define BIGOFF STEP_THRESHOLD
- #define BIGOFF_INTERVAL (1 << 7)
- #define FREQ_TOLERANCE 0.000015
- #define BURSTPOLL 0
- #define MINPOLL 5
- #define BIGPOLL 9
- #define MAXPOLL 12
- #define MINDISP 0.01
- #define MAXDISP 16
- #define MAXSTRAT 16
- #define MAXDIST 1
- #define MIN_SELECTED 1
- #define MIN_CLUSTERED 3
- #define MAXDRIFT 0.000500
- #define POLLADJ_LIMIT 40
- #define POLLADJ_GATE 4
- #define TIMECONST_HACK_GATE 2
- #define ALLAN 512
- #define PLL 65536
- #define FLL (MAXPOLL + 1)
- #define AVG 4
- enum {
- NTP_VERSION = 4,
- NTP_MAXSTRATUM = 15,
- NTP_DIGESTSIZE = 16,
- NTP_MSGSIZE_NOAUTH = 48,
- NTP_MSGSIZE = (NTP_MSGSIZE_NOAUTH + 4 + NTP_DIGESTSIZE),
-
- MODE_MASK = (7 << 0),
- VERSION_MASK = (7 << 3),
- VERSION_SHIFT = 3,
- LI_MASK = (3 << 6),
-
- LI_NOWARNING = (0 << 6),
- LI_PLUSSEC = (1 << 6),
- LI_MINUSSEC = (2 << 6),
- LI_ALARM = (3 << 6),
-
- MODE_RES0 = 0,
- MODE_SYM_ACT = 1,
- MODE_SYM_PAS = 2,
- MODE_CLIENT = 3,
- MODE_SERVER = 4,
- MODE_BROADCAST = 5,
- MODE_RES1 = 6,
- MODE_RES2 = 7,
- };
- #define OFFSET_1900_1970 2208988800UL
- #define NUM_DATAPOINTS 8
- typedef struct {
- uint32_t int_partl;
- uint32_t fractionl;
- } l_fixedpt_t;
- typedef struct {
- uint16_t int_parts;
- uint16_t fractions;
- } s_fixedpt_t;
- typedef struct {
- uint8_t m_status;
- uint8_t m_stratum;
- uint8_t m_ppoll;
- int8_t m_precision_exp;
- s_fixedpt_t m_rootdelay;
- s_fixedpt_t m_rootdisp;
- uint32_t m_refid;
- l_fixedpt_t m_reftime;
- l_fixedpt_t m_orgtime;
- l_fixedpt_t m_rectime;
- l_fixedpt_t m_xmttime;
- uint32_t m_keyid;
- uint8_t m_digest[NTP_DIGESTSIZE];
- } msg_t;
- typedef struct {
- double d_offset;
- double d_recv_time;
- double d_dispersion;
- } datapoint_t;
- typedef struct {
- len_and_sockaddr *p_lsa;
- char *p_dotted;
- int p_fd;
- int datapoint_idx;
- uint32_t lastpkt_refid;
- uint8_t lastpkt_status;
- uint8_t lastpkt_stratum;
- uint8_t reachable_bits;
- uint8_t dns_errors;
-
- double next_action_time;
- double p_xmttime;
- double p_raw_delay;
-
-
- double lastpkt_recv_time;
- double lastpkt_delay;
- double lastpkt_rootdelay;
- double lastpkt_rootdisp;
-
- double filter_offset;
- double filter_dispersion;
- double filter_jitter;
- datapoint_t filter_datapoint[NUM_DATAPOINTS];
-
- msg_t p_xmt_msg;
- char p_hostname[1];
- } peer_t;
- #define USING_KERNEL_PLL_LOOP 1
- #define USING_INITIAL_FREQ_ESTIMATION 0
- enum {
- OPT_n = (1 << 0),
- OPT_q = (1 << 1),
- OPT_N = (1 << 2),
- OPT_x = (1 << 3),
-
-
- OPT_w = (1 << 4),
- OPT_p = (1 << 5),
- OPT_S = (1 << 6),
- OPT_l = (1 << 7) * ENABLE_FEATURE_NTPD_SERVER,
- OPT_I = (1 << 8) * ENABLE_FEATURE_NTPD_SERVER,
-
- OPT_qq = (1 << 31),
- };
- struct globals {
- double cur_time;
-
- double rootdelay;
-
- double reftime;
-
- double rootdisp;
- double last_script_run;
- char *script_name;
- llist_t *ntp_peers;
- #if ENABLE_FEATURE_NTPD_SERVER
- int listen_fd;
- char *if_name;
- # define G_listen_fd (G.listen_fd)
- #else
- # define G_listen_fd (-1)
- #endif
- unsigned verbose;
- unsigned peer_cnt;
-
- uint32_t refid;
- uint8_t ntp_status;
-
- #define G_precision_exp -9
-
- #define G_precision_sec 0.002
- uint8_t stratum;
- #define STATE_NSET 0
- #define STATE_SYNC 4
- uint8_t discipline_state;
- uint8_t poll_exp;
- int polladj_count;
- long kernel_freq_drift;
- peer_t *last_update_peer;
- double last_update_offset;
- double last_update_recv_time;
- double discipline_jitter;
-
- unsigned offset_to_jitter_ratio;
-
-
- #if !USING_KERNEL_PLL_LOOP
- double discipline_freq_drift;
-
- double discipline_wander;
- #endif
- };
- #define G (*ptr_to_globals)
- #define VERB1 if (MAX_VERBOSE && G.verbose)
- #define VERB2 if (MAX_VERBOSE >= 2 && G.verbose >= 2)
- #define VERB3 if (MAX_VERBOSE >= 3 && G.verbose >= 3)
- #define VERB4 if (MAX_VERBOSE >= 4 && G.verbose >= 4)
- #define VERB5 if (MAX_VERBOSE >= 5 && G.verbose >= 5)
- #define VERB6 if (MAX_VERBOSE >= 6 && G.verbose >= 6)
- static double LOG2D(int a)
- {
- if (a < 0)
- return 1.0 / (1UL << -a);
- return 1UL << a;
- }
- static ALWAYS_INLINE double SQUARE(double x)
- {
- return x * x;
- }
- static ALWAYS_INLINE double MAXD(double a, double b)
- {
- if (a > b)
- return a;
- return b;
- }
- static ALWAYS_INLINE double MIND(double a, double b)
- {
- if (a < b)
- return a;
- return b;
- }
- static NOINLINE double my_SQRT(double X)
- {
- union {
- float f;
- int32_t i;
- } v;
- double invsqrt;
- double Xhalf = X * 0.5;
-
- v.f = X;
-
- v.i = 0x5f375a86 - (v.i >> 1);
- invsqrt = v.f;
-
- invsqrt = invsqrt * (1.5 - Xhalf * invsqrt * invsqrt);
-
-
- return X * invsqrt;
- }
- static ALWAYS_INLINE double SQRT(double X)
- {
-
- if (sizeof(float) != 4)
- return sqrt(X);
-
- return my_SQRT(X);
- }
- static double
- gettime1900d(void)
- {
- struct timeval tv;
- gettimeofday(&tv, NULL);
- G.cur_time = tv.tv_sec + (1.0e-6 * tv.tv_usec) + OFFSET_1900_1970;
- return G.cur_time;
- }
- static void
- d_to_tv(double d, struct timeval *tv)
- {
- tv->tv_sec = (long)d;
- tv->tv_usec = (d - tv->tv_sec) * 1000000;
- }
- static double
- lfp_to_d(l_fixedpt_t lfp)
- {
- double ret;
- lfp.int_partl = ntohl(lfp.int_partl);
- lfp.fractionl = ntohl(lfp.fractionl);
- ret = (double)lfp.int_partl + ((double)lfp.fractionl / UINT_MAX);
- return ret;
- }
- static double
- sfp_to_d(s_fixedpt_t sfp)
- {
- double ret;
- sfp.int_parts = ntohs(sfp.int_parts);
- sfp.fractions = ntohs(sfp.fractions);
- ret = (double)sfp.int_parts + ((double)sfp.fractions / USHRT_MAX);
- return ret;
- }
- #if ENABLE_FEATURE_NTPD_SERVER
- static l_fixedpt_t
- d_to_lfp(double d)
- {
- l_fixedpt_t lfp;
- lfp.int_partl = (uint32_t)d;
- lfp.fractionl = (uint32_t)((d - lfp.int_partl) * UINT_MAX);
- lfp.int_partl = htonl(lfp.int_partl);
- lfp.fractionl = htonl(lfp.fractionl);
- return lfp;
- }
- static s_fixedpt_t
- d_to_sfp(double d)
- {
- s_fixedpt_t sfp;
- sfp.int_parts = (uint16_t)d;
- sfp.fractions = (uint16_t)((d - sfp.int_parts) * USHRT_MAX);
- sfp.int_parts = htons(sfp.int_parts);
- sfp.fractions = htons(sfp.fractions);
- return sfp;
- }
- #endif
- static double
- dispersion(const datapoint_t *dp)
- {
- return dp->d_dispersion + FREQ_TOLERANCE * (G.cur_time - dp->d_recv_time);
- }
- static double
- root_distance(peer_t *p)
- {
-
- return MAXD(MINDISP, p->lastpkt_rootdelay + p->lastpkt_delay) / 2
- + p->lastpkt_rootdisp
- + p->filter_dispersion
- + FREQ_TOLERANCE * (G.cur_time - p->lastpkt_recv_time)
- + p->filter_jitter;
- }
- static void
- set_next(peer_t *p, unsigned t)
- {
- p->next_action_time = G.cur_time + t;
- }
- static void
- filter_datapoints(peer_t *p)
- {
- int i, idx;
- double sum, wavg;
- datapoint_t *fdp;
- #if 0
- int got_newest;
- double minoff, maxoff, w;
- double x = x;
- double oldest_off = oldest_off;
- double oldest_age = oldest_age;
- double newest_off = newest_off;
- double newest_age = newest_age;
- fdp = p->filter_datapoint;
- minoff = maxoff = fdp[0].d_offset;
- for (i = 1; i < NUM_DATAPOINTS; i++) {
- if (minoff > fdp[i].d_offset)
- minoff = fdp[i].d_offset;
- if (maxoff < fdp[i].d_offset)
- maxoff = fdp[i].d_offset;
- }
- idx = p->datapoint_idx;
-
- wavg = 0;
- w = 0.5;
-
- got_newest = 0;
- sum = 0;
- for (i = 0; i < NUM_DATAPOINTS; i++) {
- VERB5 {
- bb_error_msg("datapoint[%d]: off:%f disp:%f(%f) age:%f%s",
- i,
- fdp[idx].d_offset,
- fdp[idx].d_dispersion, dispersion(&fdp[idx]),
- G.cur_time - fdp[idx].d_recv_time,
- (minoff == fdp[idx].d_offset || maxoff == fdp[idx].d_offset)
- ? " (outlier by offset)" : ""
- );
- }
- sum += dispersion(&fdp[idx]) / (2 << i);
- if (minoff == fdp[idx].d_offset) {
- minoff -= 1;
- } else
- if (maxoff == fdp[idx].d_offset) {
- maxoff += 1;
- } else {
- oldest_off = fdp[idx].d_offset;
- oldest_age = G.cur_time - fdp[idx].d_recv_time;
- if (!got_newest) {
- got_newest = 1;
- newest_off = oldest_off;
- newest_age = oldest_age;
- }
- x = oldest_off * w;
- wavg += x;
- w /= 2;
- }
- idx = (idx - 1) & (NUM_DATAPOINTS - 1);
- }
- p->filter_dispersion = sum;
- wavg += x;
-
- x = oldest_age - newest_age;
- if (x != 0) {
- x = newest_age / x;
- if (x < 1) {
- x = (newest_off - oldest_off) * x;
- wavg += x;
- }
- }
- p->filter_offset = wavg;
- #else
- fdp = p->filter_datapoint;
- idx = p->datapoint_idx;
-
- p->filter_offset = fdp[idx].d_offset;
-
- wavg = 0;
- sum = 0;
- for (i = 0; i < NUM_DATAPOINTS; i++) {
- sum += dispersion(&fdp[idx]) / (2 << i);
- wavg += fdp[idx].d_offset;
- idx = (idx - 1) & (NUM_DATAPOINTS - 1);
- }
- wavg /= NUM_DATAPOINTS;
- p->filter_dispersion = sum;
- #endif
-
- sum = 0;
- for (i = 0; i < NUM_DATAPOINTS; i++) {
- sum += SQUARE(wavg - fdp[i].d_offset);
- }
- sum = SQRT(sum / NUM_DATAPOINTS);
- p->filter_jitter = sum > G_precision_sec ? sum : G_precision_sec;
- VERB4 bb_error_msg("filter offset:%+f disp:%f jitter:%f",
- p->filter_offset,
- p->filter_dispersion,
- p->filter_jitter);
- }
- static void
- reset_peer_stats(peer_t *p, double offset)
- {
- int i;
- bool small_ofs = fabs(offset) < STEP_THRESHOLD;
-
- for (i = 0; i < NUM_DATAPOINTS; i++) {
- if (small_ofs) {
- p->filter_datapoint[i].d_recv_time += offset;
- if (p->filter_datapoint[i].d_offset != 0) {
- p->filter_datapoint[i].d_offset -= offset;
-
-
-
-
- }
- } else {
- p->filter_datapoint[i].d_recv_time = G.cur_time;
- p->filter_datapoint[i].d_offset = 0;
-
- }
- }
- if (small_ofs) {
- p->lastpkt_recv_time += offset;
- } else {
-
- p->lastpkt_recv_time = G.cur_time;
- }
- filter_datapoints(p);
- VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time);
- }
- static len_and_sockaddr*
- resolve_peer_hostname(peer_t *p)
- {
- len_and_sockaddr *lsa = host2sockaddr(p->p_hostname, 123);
- if (lsa) {
- free(p->p_lsa);
- free(p->p_dotted);
- p->p_lsa = lsa;
- p->p_dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa);
- VERB1 if (strcmp(p->p_hostname, p->p_dotted) != 0)
- bb_error_msg("'%s' is %s", p->p_hostname, p->p_dotted);
- p->dns_errors = 0;
- return lsa;
- }
- p->dns_errors = ((p->dns_errors << 1) | 1) & DNS_ERRORS_CAP;
- return lsa;
- }
- static void
- add_peers(const char *s)
- {
- llist_t *item;
- peer_t *p;
- p = xzalloc(sizeof(*p) + strlen(s));
- strcpy(p->p_hostname, s);
- p->p_fd = -1;
- p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3);
- p->next_action_time = G.cur_time;
- reset_peer_stats(p, STEP_THRESHOLD);
-
- if (resolve_peer_hostname(p)) {
- for (item = G.ntp_peers; item != NULL; item = item->link) {
- peer_t *pp = (peer_t *) item->data;
- if (pp->p_dotted && strcmp(p->p_dotted, pp->p_dotted) == 0) {
- bb_error_msg("duplicate peer %s (%s)", s, p->p_dotted);
- free(p->p_lsa);
- free(p->p_dotted);
- free(p);
- return;
- }
- }
- }
- llist_add_to(&G.ntp_peers, p);
- G.peer_cnt++;
- }
- static int
- do_sendto(int fd,
- const struct sockaddr *from, const struct sockaddr *to, socklen_t addrlen,
- msg_t *msg, ssize_t len)
- {
- ssize_t ret;
- errno = 0;
- if (!from) {
- ret = sendto(fd, msg, len, MSG_DONTWAIT, to, addrlen);
- } else {
- ret = send_to_from(fd, msg, len, MSG_DONTWAIT, to, from, addrlen);
- }
- if (ret != len) {
- bb_perror_msg("send failed");
- return -1;
- }
- return 0;
- }
- static void
- send_query_to_peer(peer_t *p)
- {
- if (!p->p_lsa)
- return;
-
- #define PROBE_LOCAL_ADDR
- if (p->p_fd == -1) {
- int fd, family;
- len_and_sockaddr *local_lsa;
- family = p->p_lsa->u.sa.sa_family;
- p->p_fd = fd = xsocket_type(&local_lsa, family, SOCK_DGRAM);
-
- PROBE_LOCAL_ADDR
- xbind(fd, &local_lsa->u.sa, local_lsa->len);
- PROBE_LOCAL_ADDR
- #if ENABLE_FEATURE_IPV6
- if (family == AF_INET)
- #endif
- setsockopt_int(fd, IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY);
- free(local_lsa);
- }
-
- VERB1 bb_error_msg("sending query to %s", p->p_dotted);
-
- p->p_xmt_msg.m_xmttime.int_partl = rand();
- p->p_xmt_msg.m_xmttime.fractionl = rand();
- p->p_xmttime = gettime1900d();
-
- p->reachable_bits <<= 1;
- if (do_sendto(p->p_fd, NULL, &p->p_lsa->u.sa, p->p_lsa->len,
- &p->p_xmt_msg, NTP_MSGSIZE_NOAUTH) == -1
- ) {
- close(p->p_fd);
- p->p_fd = -1;
-
- set_next(p, RETRY_INTERVAL);
- return;
- }
- set_next(p, RESPONSE_INTERVAL);
- }
- static void run_script(const char *action, double offset)
- {
- char *argv[3];
- char *env1, *env2, *env3, *env4;
- G.last_script_run = G.cur_time;
- if (!G.script_name)
- return;
- argv[0] = (char*) G.script_name;
- argv[1] = (char*) action;
- argv[2] = NULL;
- VERB1 bb_error_msg("executing '%s %s'", G.script_name, action);
- env1 = xasprintf("%s=%u", "stratum", G.stratum);
- putenv(env1);
- env2 = xasprintf("%s=%ld", "freq_drift_ppm", G.kernel_freq_drift);
- putenv(env2);
- env3 = xasprintf("%s=%u", "poll_interval", 1 << G.poll_exp);
- putenv(env3);
- env4 = xasprintf("%s=%f", "offset", offset);
- putenv(env4);
-
-
-
- spawn(argv);
- unsetenv("stratum");
- unsetenv("freq_drift_ppm");
- unsetenv("poll_interval");
- unsetenv("offset");
- free(env1);
- free(env2);
- free(env3);
- free(env4);
- }
- static NOINLINE void
- step_time(double offset)
- {
- llist_t *item;
- double dtime;
- struct timeval tvc, tvn;
- char buf[sizeof("yyyy-mm-dd hh:mm:ss") + 4];
- time_t tval;
- gettimeofday(&tvc, NULL);
- dtime = tvc.tv_sec + (1.0e-6 * tvc.tv_usec) + offset;
- d_to_tv(dtime, &tvn);
- if (settimeofday(&tvn, NULL) == -1)
- bb_perror_msg_and_die("settimeofday");
- VERB2 {
- tval = tvc.tv_sec;
- strftime_YYYYMMDDHHMMSS(buf, sizeof(buf), &tval);
- bb_error_msg("current time is %s.%06u", buf, (unsigned)tvc.tv_usec);
- }
- tval = tvn.tv_sec;
- strftime_YYYYMMDDHHMMSS(buf, sizeof(buf), &tval);
- bb_error_msg("setting time to %s.%06u (offset %+fs)", buf, (unsigned)tvn.tv_usec, offset);
-
-
- G.cur_time += offset;
- G.last_update_recv_time += offset;
- G.last_script_run += offset;
-
- for (item = G.ntp_peers; item != NULL; item = item->link) {
- peer_t *pp = (peer_t *) item->data;
- reset_peer_stats(pp, offset);
-
-
- pp->next_action_time += offset;
- if (pp->p_fd >= 0) {
-
- close(pp->p_fd);
- pp->p_fd = -1;
- set_next(pp, RETRY_INTERVAL);
- }
- }
- }
- static void clamp_pollexp_and_set_MAXSTRAT(void)
- {
- if (G.poll_exp < MINPOLL)
- G.poll_exp = MINPOLL;
- if (G.poll_exp > BIGPOLL)
- G.poll_exp = BIGPOLL;
- G.polladj_count = 0;
- G.stratum = MAXSTRAT;
- }
- typedef struct {
- peer_t *p;
- int type;
- double edge;
- double opt_rd;
- } point_t;
- static int
- compare_point_edge(const void *aa, const void *bb)
- {
- const point_t *a = aa;
- const point_t *b = bb;
- if (a->edge < b->edge) {
- return -1;
- }
- return (a->edge > b->edge);
- }
- typedef struct {
- peer_t *p;
- double metric;
- } survivor_t;
- static int
- compare_survivor_metric(const void *aa, const void *bb)
- {
- const survivor_t *a = aa;
- const survivor_t *b = bb;
- if (a->metric < b->metric) {
- return -1;
- }
- return (a->metric > b->metric);
- }
- static int
- fit(peer_t *p, double rd)
- {
- if ((p->reachable_bits & (p->reachable_bits-1)) == 0) {
-
- VERB4 bb_error_msg("peer %s unfit for selection: unreachable", p->p_dotted);
- return 0;
- }
- #if 0
- if ((p->lastpkt_status & LI_ALARM) == LI_ALARM
- || p->lastpkt_stratum >= MAXSTRAT
- ) {
- VERB4 bb_error_msg("peer %s unfit for selection: bad status/stratum", p->p_dotted);
- return 0;
- }
- #endif
-
- if (rd > MAXDIST + FREQ_TOLERANCE * (1 << G.poll_exp)) {
- VERB4 bb_error_msg("peer %s unfit for selection: root distance too high", p->p_dotted);
- return 0;
- }
- return 1;
- }
- static peer_t*
- select_and_cluster(void)
- {
- peer_t *p;
- llist_t *item;
- int i, j;
- int size = 3 * G.peer_cnt;
-
- point_t point[size];
- unsigned num_points, num_candidates;
- double low, high;
- unsigned num_falsetickers;
-
- survivor_t survivor[size];
- unsigned num_survivors;
-
- num_points = 0;
- item = G.ntp_peers;
- while (item != NULL) {
- double rd, offset;
- p = (peer_t *) item->data;
- rd = root_distance(p);
- offset = p->filter_offset;
- if (!fit(p, rd)) {
- item = item->link;
- continue;
- }
- VERB5 bb_error_msg("interval: [%f %f %f] %s",
- offset - rd,
- offset,
- offset + rd,
- p->p_dotted
- );
- point[num_points].p = p;
- point[num_points].type = -1;
- point[num_points].edge = offset - rd;
- point[num_points].opt_rd = rd;
- num_points++;
- point[num_points].p = p;
- point[num_points].type = 0;
- point[num_points].edge = offset;
- point[num_points].opt_rd = rd;
- num_points++;
- point[num_points].p = p;
- point[num_points].type = 1;
- point[num_points].edge = offset + rd;
- point[num_points].opt_rd = rd;
- num_points++;
- item = item->link;
- }
- num_candidates = num_points / 3;
- if (num_candidates == 0) {
- VERB3 bb_error_msg("no valid datapoints%s", ", no peer selected");
- return NULL;
- }
- qsort(point, num_points, sizeof(point[0]), compare_point_edge);
-
- num_falsetickers = 0;
- while (1) {
- int c;
- unsigned num_midpoints = 0;
- low = 1 << 9;
- high = - (1 << 9);
- c = 0;
- for (i = 0; i < num_points; i++) {
-
- c -= point[i].type;
- if (c >= num_candidates - num_falsetickers) {
-
- low = point[i].edge;
- break;
- }
- if (point[i].type == 0)
- num_midpoints++;
- }
- c = 0;
- for (i = num_points-1; i >= 0; i--) {
- c += point[i].type;
- if (c >= num_candidates - num_falsetickers) {
- high = point[i].edge;
- break;
- }
- if (point[i].type == 0)
- num_midpoints++;
- }
-
- if (num_midpoints <= num_falsetickers && low < high)
- break;
- num_falsetickers++;
- if (num_falsetickers * 2 >= num_candidates) {
- VERB3 bb_error_msg("falsetickers:%d, candidates:%d%s",
- num_falsetickers, num_candidates,
- ", no peer selected");
- return NULL;
- }
- }
- VERB4 bb_error_msg("selected interval: [%f, %f]; candidates:%d falsetickers:%d",
- low, high, num_candidates, num_falsetickers);
-
-
- num_survivors = 0;
- for (i = 0; i < num_points; i++) {
- if (point[i].edge < low || point[i].edge > high)
- continue;
- p = point[i].p;
- survivor[num_survivors].p = p;
-
- survivor[num_survivors].metric = MAXDIST * p->lastpkt_stratum + point[i].opt_rd;
- VERB5 bb_error_msg("survivor[%d] metric:%f peer:%s",
- num_survivors, survivor[num_survivors].metric, p->p_dotted);
- num_survivors++;
- }
-
- if (num_survivors < MIN_SELECTED) {
- VERB3 bb_error_msg("survivors:%d%s",
- num_survivors,
- ", no peer selected");
- return NULL;
- }
- qsort(survivor, num_survivors, sizeof(survivor[0]), compare_survivor_metric);
-
- while (1) {
- unsigned max_idx = max_idx;
- double max_selection_jitter = max_selection_jitter;
- double min_jitter = min_jitter;
- if (num_survivors <= MIN_CLUSTERED) {
- VERB4 bb_error_msg("num_survivors %d <= %d, not discarding more",
- num_survivors, MIN_CLUSTERED);
- break;
- }
-
- for (i = 0; i < num_survivors; i++) {
- double selection_jitter_sq;
- p = survivor[i].p;
- if (i == 0 || p->filter_jitter < min_jitter)
- min_jitter = p->filter_jitter;
- selection_jitter_sq = 0;
- for (j = 0; j < num_survivors; j++) {
- peer_t *q = survivor[j].p;
- selection_jitter_sq += SQUARE(p->filter_offset - q->filter_offset);
- }
- if (i == 0 || selection_jitter_sq > max_selection_jitter) {
- max_selection_jitter = selection_jitter_sq;
- max_idx = i;
- }
- VERB6 bb_error_msg("survivor %d selection_jitter^2:%f",
- i, selection_jitter_sq);
- }
- max_selection_jitter = SQRT(max_selection_jitter / num_survivors);
- VERB5 bb_error_msg("max_selection_jitter (at %d):%f min_jitter:%f",
- max_idx, max_selection_jitter, min_jitter);
-
- if (max_selection_jitter < min_jitter) {
- VERB4 bb_error_msg("max_selection_jitter:%f < min_jitter:%f, num_survivors:%d, not discarding more",
- max_selection_jitter, min_jitter, num_survivors);
- break;
- }
-
- VERB6 bb_error_msg("dropping survivor %d", max_idx);
- num_survivors--;
- while (max_idx < num_survivors) {
- survivor[max_idx] = survivor[max_idx + 1];
- max_idx++;
- }
- }
- if (0) {
-
- double x, y, z, w;
- y = z = w = 0;
- for (i = 0; i < num_survivors; i++) {
- p = survivor[i].p;
- x = root_distance(p);
- y += 1 / x;
- z += p->filter_offset / x;
- w += SQUARE(p->filter_offset - survivor[0].p->filter_offset) / x;
- }
-
-
- }
-
- p = survivor[0].p;
- if (G.last_update_peer
- && G.last_update_peer->lastpkt_stratum <= p->lastpkt_stratum
- ) {
-
- for (i = 1; i < num_survivors; i++) {
- if (G.last_update_peer == survivor[i].p) {
- VERB5 bb_error_msg("keeping old synced peer");
- p = G.last_update_peer;
- goto keep_old;
- }
- }
- }
- G.last_update_peer = p;
- keep_old:
- VERB4 bb_error_msg("selected peer %s filter_offset:%+f age:%f",
- p->p_dotted,
- p->filter_offset,
- G.cur_time - p->lastpkt_recv_time
- );
- return p;
- }
- static void
- set_new_values(int disc_state, double offset, double recv_time)
- {
-
- VERB4 bb_error_msg("disc_state=%d last update offset=%f recv_time=%f",
- disc_state, offset, recv_time);
- G.discipline_state = disc_state;
- G.last_update_offset = offset;
- G.last_update_recv_time = recv_time;
- }
- static NOINLINE int
- update_local_clock(peer_t *p)
- {
- int rc;
- struct timex tmx;
-
- double offset = p->filter_offset;
- double recv_time = p->lastpkt_recv_time;
- double abs_offset;
- #if !USING_KERNEL_PLL_LOOP
- double freq_drift;
- #endif
- #if !USING_KERNEL_PLL_LOOP || USING_INITIAL_FREQ_ESTIMATION
- double since_last_update;
- #endif
- double etemp, dtemp;
- abs_offset = fabs(offset);
- #if 0
-
-
- if (abs_offset > PANIC_THRESHOLD) {
- bb_error_msg_and_die("offset %f far too big, exiting", offset);
- }
- #endif
-
- if (recv_time <= G.last_update_recv_time) {
- VERB3 bb_error_msg("update from %s: same or older datapoint, not using it",
- p->p_dotted);
- return 0;
- }
-
- #if !USING_KERNEL_PLL_LOOP || USING_INITIAL_FREQ_ESTIMATION
- since_last_update = recv_time - G.reftime;
- #endif
- #if !USING_KERNEL_PLL_LOOP
- freq_drift = 0;
- #endif
- #if USING_INITIAL_FREQ_ESTIMATION
- if (G.discipline_state == STATE_FREQ) {
-
- if (since_last_update < WATCH_THRESHOLD) {
- VERB4 bb_error_msg("measuring drift, datapoint ignored, %f sec remains",
- WATCH_THRESHOLD - since_last_update);
- return 0;
- }
- # if !USING_KERNEL_PLL_LOOP
- freq_drift = (offset - G.last_update_offset) / since_last_update;
- # endif
- }
- #endif
-
- if (abs_offset > STEP_THRESHOLD) {
- #if 0
- double remains;
- switch (G.discipline_state) {
- case STATE_SYNC:
-
- VERB3 bb_error_msg("update from %s: offset:%+f, spike%s",
- p->p_dotted, offset,
- "");
- G.discipline_state = STATE_SPIK;
- return -1;
- case STATE_SPIK:
-
- remains = WATCH_THRESHOLD - since_last_update;
- if (remains > 0) {
- VERB3 bb_error_msg("update from %s: offset:%+f, spike%s",
- p->p_dotted, offset,
- ", datapoint ignored");
- return -1;
- }
-
- }
- #endif
-
- VERB4 bb_error_msg("stepping time by %+f; poll_exp=MINPOLL", offset);
- step_time(offset);
- if (option_mask32 & OPT_q) {
-
- exit(0);
- }
- clamp_pollexp_and_set_MAXSTRAT();
- run_script("step", offset);
- recv_time += offset;
- #if USING_INITIAL_FREQ_ESTIMATION
- if (G.discipline_state == STATE_NSET) {
- set_new_values(STATE_FREQ, 0, recv_time);
- return 1;
- }
- #endif
- abs_offset = offset = 0;
- set_new_values(STATE_SYNC, offset, recv_time);
- } else {
-
- G.offset_to_jitter_ratio = abs_offset / G.discipline_jitter;
-
- etemp = SQUARE(G.discipline_jitter);
- dtemp = SQUARE(offset - G.last_update_offset);
- G.discipline_jitter = SQRT(etemp + (dtemp - etemp) / AVG);
- if (G.discipline_jitter < G_precision_sec)
- G.discipline_jitter = G_precision_sec;
- switch (G.discipline_state) {
- case STATE_NSET:
- if (option_mask32 & OPT_q) {
-
- exit(0);
- }
- #if USING_INITIAL_FREQ_ESTIMATION
-
- set_new_values(STATE_FREQ, offset, recv_time);
- #else
- set_new_values(STATE_SYNC, offset, recv_time);
- #endif
- VERB4 bb_error_msg("transitioning to FREQ, datapoint ignored");
- return 0;
- #if 0
- case STATE_FSET:
-
- set_new_values(STATE_SYNC, offset, recv_time);
-
- break;
- #endif
- #if USING_INITIAL_FREQ_ESTIMATION
- case STATE_FREQ:
-
- set_new_values(STATE_SYNC, offset, recv_time);
- break;
- #endif
- default:
- #if !USING_KERNEL_PLL_LOOP
-
- if ((1 << G.poll_exp) > ALLAN / 2) {
- etemp = FLL - G.poll_exp;
- if (etemp < AVG)
- etemp = AVG;
- freq_drift += (offset - G.last_update_offset) / (MAXD(since_last_update, ALLAN) * etemp);
- }
-
- etemp = MIND(since_last_update, (1 << G.poll_exp));
- dtemp = (4 * PLL) << G.poll_exp;
- freq_drift += offset * etemp / SQUARE(dtemp);
- #endif
- set_new_values(STATE_SYNC, offset, recv_time);
- break;
- }
- if (G.stratum != p->lastpkt_stratum + 1) {
- G.stratum = p->lastpkt_stratum + 1;
- run_script("stratum", offset);
- }
- }
- G.reftime = G.cur_time;
- G.ntp_status = p->lastpkt_status;
- G.refid = p->lastpkt_refid;
- G.rootdelay = p->lastpkt_rootdelay + p->lastpkt_delay;
- dtemp = p->filter_jitter;
- dtemp += MAXD(p->filter_dispersion + FREQ_TOLERANCE * (G.cur_time - p->lastpkt_recv_time) + abs_offset, MINDISP);
- G.rootdisp = p->lastpkt_rootdisp + dtemp;
- VERB4 bb_error_msg("updating leap/refid/reftime/rootdisp from peer %s", p->p_dotted);
-
- #if !USING_KERNEL_PLL_LOOP
-
- dtemp = G.discipline_freq_drift + freq_drift;
- G.discipline_freq_drift = MAXD(MIND(MAXDRIFT, dtemp), -MAXDRIFT);
- etemp = SQUARE(G.discipline_wander);
- dtemp = SQUARE(dtemp);
- G.discipline_wander = SQRT(etemp + (dtemp - etemp) / AVG);
- VERB4 bb_error_msg("discipline freq_drift=%.9f(int:%ld corr:%e) wander=%f",
- G.discipline_freq_drift,
- (long)(G.discipline_freq_drift * 65536e6),
- freq_drift,
- G.discipline_wander);
- #endif
- VERB4 {
- memset(&tmx, 0, sizeof(tmx));
- if (adjtimex(&tmx) < 0)
- bb_perror_msg_and_die("adjtimex");
- bb_error_msg("p adjtimex freq:%ld offset:%+ld status:0x%x tc:%ld",
- tmx.freq, tmx.offset, tmx.status, tmx.constant);
- }
- memset(&tmx, 0, sizeof(tmx));
- #if 0
- tmx.modes = ADJ_FREQUENCY | ADJ_OFFSET;
-
- tmx.freq = G.discipline_freq_drift * 65536e6;
- #endif
- tmx.modes = ADJ_OFFSET | ADJ_STATUS | ADJ_TIMECONST;
- tmx.constant = (int)G.poll_exp - 4;
-
- if (G.offset_to_jitter_ratio >= TIMECONST_HACK_GATE)
- tmx.constant--;
- tmx.offset = (long)(offset * 1000000);
- if (SLEW_THRESHOLD < STEP_THRESHOLD) {
- if (tmx.offset > (long)(SLEW_THRESHOLD * 1000000)) {
- tmx.offset = (long)(SLEW_THRESHOLD * 1000000);
- tmx.constant--;
- }
- if (tmx.offset < -(long)(SLEW_THRESHOLD * 1000000)) {
- tmx.offset = -(long)(SLEW_THRESHOLD * 1000000);
- tmx.constant--;
- }
- }
- if (tmx.constant < 0)
- tmx.constant = 0;
- tmx.status = STA_PLL;
- if (G.ntp_status & LI_PLUSSEC)
- tmx.status |= STA_INS;
- if (G.ntp_status & LI_MINUSSEC)
- tmx.status |= STA_DEL;
-
-
- rc = adjtimex(&tmx);
- if (rc < 0)
- bb_perror_msg_and_die("adjtimex");
-
- VERB4 bb_error_msg("adjtimex:%d freq:%ld offset:%+ld status:0x%x",
- rc, tmx.freq, tmx.offset, tmx.status);
- G.kernel_freq_drift = tmx.freq / 65536;
- VERB2 bb_error_msg("update from:%s offset:%+f delay:%f jitter:%f clock drift:%+.3fppm tc:%d",
- p->p_dotted,
- offset,
- p->lastpkt_delay,
- G.discipline_jitter,
- (double)tmx.freq / 65536,
- (int)tmx.constant
- );
- return 1;
- }
- static unsigned
- poll_interval(int upper_bound)
- {
- unsigned interval, r, mask;
- interval = 1 << G.poll_exp;
- if (interval > upper_bound)
- interval = upper_bound;
- mask = ((interval-1) >> 4) | 1;
- r = rand();
- interval += r & mask;
- VERB4 bb_error_msg("chose poll interval:%u (poll_exp:%d)", interval, G.poll_exp);
- return interval;
- }
- static void
- adjust_poll(int count)
- {
- G.polladj_count += count;
- if (G.polladj_count > POLLADJ_LIMIT) {
- G.polladj_count = 0;
- if (G.poll_exp < MAXPOLL) {
- G.poll_exp++;
- VERB4 bb_error_msg("polladj: discipline_jitter:%f ++poll_exp=%d",
- G.discipline_jitter, G.poll_exp);
- }
- } else if (G.polladj_count < -POLLADJ_LIMIT || (count < 0 && G.poll_exp > BIGPOLL)) {
- G.polladj_count = 0;
- if (G.poll_exp > MINPOLL) {
- llist_t *item;
- G.poll_exp--;
-
- for (item = G.ntp_peers; item != NULL; item = item->link) {
- peer_t *pp = (peer_t *) item->data;
- if (pp->p_fd < 0)
- pp->next_action_time -= (1 << G.poll_exp);
- }
- VERB4 bb_error_msg("polladj: discipline_jitter:%f --poll_exp=%d",
- G.discipline_jitter, G.poll_exp);
- }
- } else {
- VERB4 bb_error_msg("polladj: count:%d", G.polladj_count);
- }
- }
- static NOINLINE void
- recv_and_process_peer_pkt(peer_t *p)
- {
- int rc;
- ssize_t size;
- msg_t msg;
- double T1, T2, T3, T4;
- double offset;
- double prev_delay, delay;
- unsigned interval;
- datapoint_t *datapoint;
- peer_t *q;
- offset = 0;
-
- recv_again:
- size = recv(p->p_fd, &msg, sizeof(msg), MSG_DONTWAIT);
- if (size < 0) {
- if (errno == EINTR)
-
- goto recv_again;
- if (errno == EAGAIN)
-
- return;
-
- bb_perror_msg_and_die("recv(%s) error", p->p_dotted);
- }
- if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE) {
- bb_error_msg("malformed packet received from %s", p->p_dotted);
- return;
- }
- if (msg.m_orgtime.int_partl != p->p_xmt_msg.m_xmttime.int_partl
- || msg.m_orgtime.fractionl != p->p_xmt_msg.m_xmttime.fractionl
- ) {
-
- return;
- }
-
- close(p->p_fd);
- p->p_fd = -1;
- if ((msg.m_status & LI_ALARM) == LI_ALARM
- || msg.m_stratum == 0
- || msg.m_stratum > NTP_MAXSTRATUM
- ) {
- bb_error_msg("reply from %s: peer is unsynced", p->p_dotted);
-
- if (G.poll_exp < BIGPOLL)
- goto increase_interval;
- goto pick_normal_interval;
- }
-
- T1 = p->p_xmttime;
- T2 = lfp_to_d(msg.m_rectime);
- T3 = lfp_to_d(msg.m_xmttime);
- T4 = G.cur_time;
-
- delay = (T4 - T1) - (T3 - T2);
- if (delay < G_precision_sec)
- delay = G_precision_sec;
-
- prev_delay = p->p_raw_delay;
- p->p_raw_delay = delay;
- if (p->reachable_bits && delay > prev_delay * BAD_DELAY_GROWTH) {
- bb_error_msg("reply from %s: delay %f is too high, ignoring", p->p_dotted, delay);
- goto pick_normal_interval;
- }
- p->lastpkt_delay = delay;
- p->lastpkt_recv_time = T4;
- VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time);
- p->lastpkt_status = msg.m_status;
- p->lastpkt_stratum = msg.m_stratum;
- p->lastpkt_rootdelay = sfp_to_d(msg.m_rootdelay);
- p->lastpkt_rootdisp = sfp_to_d(msg.m_rootdisp);
- p->lastpkt_refid = msg.m_refid;
- p->datapoint_idx = p->reachable_bits ? (p->datapoint_idx + 1) % NUM_DATAPOINTS : 0;
- datapoint = &p->filter_datapoint[p->datapoint_idx];
- datapoint->d_recv_time = T4;
- datapoint->d_offset = offset = ((T2 - T1) + (T3 - T4)) / 2;
- datapoint->d_dispersion = LOG2D(msg.m_precision_exp) + G_precision_sec;
- if (!p->reachable_bits) {
-
- int i;
- for (i = 0; i < NUM_DATAPOINTS; i++) {
- p->filter_datapoint[i].d_offset = offset;
- }
- }
- p->reachable_bits |= 1;
- if ((MAX_VERBOSE && G.verbose) || (option_mask32 & OPT_w)) {
- bb_error_msg("reply from %s: offset:%+f delay:%f status:0x%02x strat:%d refid:0x%08x rootdelay:%f reach:0x%02x",
- p->p_dotted,
- offset,
- p->lastpkt_delay,
- p->lastpkt_status,
- p->lastpkt_stratum,
- p->lastpkt_refid,
- p->lastpkt_rootdelay,
- p->reachable_bits
-
- );
- }
-
- filter_datapoints(p);
- q = select_and_cluster();
- rc = 0;
- if (q) {
- if (!(option_mask32 & OPT_w)) {
- rc = update_local_clock(q);
- #if 0
-
- if (fabs(q->filter_offset) >= POLLDOWN_OFFSET) {
- VERB4 bb_error_msg("offset:%+f > POLLDOWN_OFFSET", q->filter_offset);
- adjust_poll(-POLLADJ_LIMIT * 3);
- rc = 0;
- }
- #endif
- }
- } else {
-
- if (G.poll_exp < BIGPOLL)
- goto increase_interval;
- }
- if (rc != 0) {
-
- if (rc > 0 && G.offset_to_jitter_ratio <= POLLADJ_GATE) {
-
- increase_interval:
- adjust_poll(MINPOLL);
- } else {
- VERB3 if (rc > 0)
- bb_error_msg("want smaller interval: offset/jitter = %u",
- G.offset_to_jitter_ratio);
- adjust_poll(-G.poll_exp * 2);
- }
- }
-
- pick_normal_interval:
- interval = poll_interval(INT_MAX);
- if (fabs(offset) >= BIGOFF && interval > BIGOFF_INTERVAL) {
-
- interval = BIGOFF_INTERVAL;
- }
- set_next(p, interval);
- }
- #if ENABLE_FEATURE_NTPD_SERVER
- static NOINLINE void
- recv_and_process_client_pkt(void )
- {
- ssize_t size;
-
- len_and_sockaddr *to;
- struct sockaddr *from;
- msg_t msg;
- uint8_t query_status;
- l_fixedpt_t query_xmttime;
- to = get_sock_lsa(G_listen_fd);
- from = xzalloc(to->len);
- size = recv_from_to(G_listen_fd, &msg, sizeof(msg), MSG_DONTWAIT, from, &to->u.sa, to->len);
- if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE) {
- char *addr;
- if (size < 0) {
- if (errno == EAGAIN)
- goto bail;
- bb_perror_msg_and_die("recv");
- }
- addr = xmalloc_sockaddr2dotted_noport(from);
- bb_error_msg("malformed packet received from %s: size %u", addr, (int)size);
- free(addr);
- goto bail;
- }
-
- if ((msg.m_status & MODE_MASK) != MODE_CLIENT
- && (msg.m_status & MODE_MASK) != MODE_SYM_ACT
- ) {
- goto bail;
- }
- query_status = msg.m_status;
- query_xmttime = msg.m_xmttime;
-
- memset(&msg, 0, sizeof(msg));
- msg.m_status = G.stratum < MAXSTRAT ? (G.ntp_status & LI_MASK) : LI_ALARM;
- msg.m_status |= (query_status & VERSION_MASK);
- msg.m_status |= ((query_status & MODE_MASK) == MODE_CLIENT) ?
- MODE_SERVER : MODE_SYM_PAS;
- msg.m_stratum = G.stratum;
- msg.m_ppoll = G.poll_exp;
- msg.m_precision_exp = G_precision_exp;
-
- msg.m_rectime = d_to_lfp(G.cur_time);
- msg.m_xmttime = d_to_lfp(gettime1900d());
- if (G.peer_cnt == 0) {
-
- G.reftime = G.cur_time;
- }
- msg.m_reftime = d_to_lfp(G.reftime);
- msg.m_orgtime = query_xmttime;
- msg.m_rootdelay = d_to_sfp(G.rootdelay);
- msg.m_rootdisp = d_to_sfp(G.rootdisp);
-
- msg.m_refid = G.refid;
-
- do_sendto(G_listen_fd,
- &to->u.sa, from, to->len,
- &msg, size);
- bail:
- free(to);
- free(from);
- }
- #endif
- static NOINLINE void ntp_init(char **argv)
- {
- unsigned opts;
- llist_t *peers;
- srand(getpid());
- if (getuid())
- bb_error_msg_and_die(bb_msg_you_must_be_root);
-
- G.discipline_jitter = G_precision_sec;
- G.stratum = MAXSTRAT;
- if (BURSTPOLL != 0)
- G.poll_exp = BURSTPOLL;
- G.last_script_run = G.reftime = G.last_update_recv_time = gettime1900d();
-
- peers = NULL;
- opts = getopt32(argv, "^"
- "nqNx"
- "wp:*S:"IF_FEATURE_NTPD_SERVER("l")
- IF_FEATURE_NTPD_SERVER("I:")
- "d"
- "46aAbgL"
- "\0"
- "dd:wn"
- IF_FEATURE_NTPD_SERVER(":Il")
- , &peers, &G.script_name,
- #if ENABLE_FEATURE_NTPD_SERVER
- &G.if_name,
- #endif
- &G.verbose);
- #if ENABLE_FEATURE_NTPD_SERVER
- G_listen_fd = -1;
- if (opts & OPT_l) {
- G_listen_fd = create_and_bind_dgram_or_die(NULL, 123);
- if (G.if_name) {
- if (setsockopt_bindtodevice(G_listen_fd, G.if_name))
- xfunc_die();
- }
- socket_want_pktinfo(G_listen_fd);
- setsockopt_int(G_listen_fd, IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY);
- }
- #endif
-
- if (opts & OPT_N)
- setpriority(PRIO_PROCESS, 0, -15);
- if (!(opts & OPT_n)) {
- bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO, argv);
- logmode = LOGMODE_NONE;
- }
- if (peers) {
- while (peers)
- add_peers(llist_pop(&peers));
- }
- #if ENABLE_FEATURE_NTPD_CONF
- else {
- parser_t *parser;
- char *token[3];
- parser = config_open("/etc/ntp.conf");
- while (config_read(parser, token, 3, 1, "# \t", PARSE_NORMAL)) {
- if (strcmp(token[0], "server") == 0 && token[1]) {
- add_peers(token[1]);
- continue;
- }
- bb_error_msg("skipping %s:%u: unimplemented command '%s'",
- "/etc/ntp.conf", parser->lineno, token[0]
- );
- }
- config_close(parser);
- }
- #endif
- if (G.peer_cnt == 0) {
- if (!(opts & OPT_l))
- bb_show_usage();
-
- G.stratum = 1;
- }
-
- if (opts & OPT_q) {
- option_mask32 |= OPT_qq;
- alarm(10);
- }
- bb_signals(0
- | (1 << SIGTERM)
- | (1 << SIGINT)
- | (1 << SIGALRM)
- , record_signo
- );
- bb_signals(0
- | (1 << SIGPIPE)
- | (1 << SIGCHLD)
- , SIG_IGN
- );
- }
- int ntpd_main(int argc UNUSED_PARAM, char **argv) MAIN_EXTERNALLY_VISIBLE;
- int ntpd_main(int argc UNUSED_PARAM, char **argv)
- {
- #undef G
- struct globals G;
- struct pollfd *pfd;
- peer_t **idx2peer;
- unsigned cnt;
- memset(&G, 0, sizeof(G));
- SET_PTR_TO_GLOBALS(&G);
- ntp_init(argv);
-
- cnt = G.peer_cnt + ENABLE_FEATURE_NTPD_SERVER;
- idx2peer = xzalloc(sizeof(idx2peer[0]) * cnt);
- pfd = xzalloc(sizeof(pfd[0]) * cnt);
-
- cnt = G.peer_cnt * (INITIAL_SAMPLES + 1);
- write_pidfile(CONFIG_PID_FILE_PATH "/ntpd.pid");
- while (!bb_got_signal) {
- llist_t *item;
- unsigned i, j;
- int nfds, timeout;
- double nextaction;
-
- nextaction = G.last_script_run + (11*60);
- if (nextaction < G.cur_time + 1)
- nextaction = G.cur_time + 1;
- i = 0;
- #if ENABLE_FEATURE_NTPD_SERVER
- if (G_listen_fd != -1) {
- pfd[0].fd = G_listen_fd;
- pfd[0].events = POLLIN;
- i++;
- }
- #endif
-
- for (item = G.ntp_peers; item != NULL; item = item->link) {
- peer_t *p = (peer_t *) item->data;
- if (p->next_action_time <= G.cur_time) {
- if (p->p_fd == -1) {
-
- if (--cnt == 0) {
- VERB4 bb_error_msg("disabling burst mode");
- G.polladj_count = 0;
- G.poll_exp = MINPOLL;
- }
- send_query_to_peer(p);
- } else {
-
- close(p->p_fd);
- p->p_fd = -1;
-
- if (G.poll_exp < BIGPOLL)
- adjust_poll(MINPOLL);
- timeout = poll_interval(NOREPLY_INTERVAL);
- bb_error_msg("timed out waiting for %s, reach 0x%02x, next query in %us",
- p->p_dotted, p->reachable_bits, timeout);
-
- if (p->reachable_bits == 0)
- resolve_peer_hostname(p);
- set_next(p, timeout);
- }
- }
- if (p->next_action_time < nextaction)
- nextaction = p->next_action_time;
- if (p->p_fd >= 0) {
-
- pfd[i].fd = p->p_fd;
- pfd[i].events = POLLIN;
- idx2peer[i] = p;
- i++;
- }
- }
- timeout = nextaction - G.cur_time;
- if (timeout < 0)
- timeout = 0;
- timeout++;
-
- VERB2 {
- if (i > (ENABLE_FEATURE_NTPD_SERVER && G_listen_fd != -1)) {
-
- nfds = poll(pfd, i, 1000);
- if (nfds != 0)
- goto did_poll;
- if (--timeout <= 0)
- goto did_poll;
- }
- bb_error_msg("poll:%us sockets:%u interval:%us", timeout, i, 1 << G.poll_exp);
- }
- nfds = poll(pfd, i, timeout * 1000);
- did_poll:
- gettime1900d();
- if (nfds <= 0) {
- double ct;
- int dns_error;
- if (bb_got_signal)
- break;
- if (G.cur_time - G.last_script_run > 11*60) {
-
- run_script("periodic", G.last_update_offset);
- gettime1900d();
- }
-
- dns_error = 0;
- ct = G.cur_time;
- for (item = G.ntp_peers; item != NULL; item = item->link) {
- peer_t *p = (peer_t *) item->data;
- if (p->next_action_time <= ct && !p->p_lsa) {
-
- dns_error |= (!resolve_peer_hostname(p));
- }
- }
- if (!dns_error)
- goto check_unsync;
-
- gettime1900d();
- for (item = G.ntp_peers; item != NULL; item = item->link) {
- peer_t *p = (peer_t *) item->data;
- if (p->next_action_time <= ct && !p->p_lsa) {
- set_next(p, HOSTNAME_INTERVAL * p->dns_errors);
- }
- }
- goto check_unsync;
- }
-
- j = 0;
- #if ENABLE_FEATURE_NTPD_SERVER
- if (G.listen_fd != -1) {
- if (pfd[0].revents ) {
- nfds--;
- recv_and_process_client_pkt();
- gettime1900d();
- }
- j = 1;
- }
- #endif
- for (; nfds != 0 && j < i; j++) {
- if (pfd[j].revents ) {
-
- if (option_mask32 & OPT_qq) {
- option_mask32 &= ~OPT_qq;
- alarm(50);
- }
- nfds--;
- recv_and_process_peer_pkt(idx2peer[j]);
- gettime1900d();
- }
- }
- check_unsync:
- if (G.ntp_peers && G.stratum != MAXSTRAT) {
- for (item = G.ntp_peers; item != NULL; item = item->link) {
- peer_t *p = (peer_t *) item->data;
- if (p->reachable_bits)
- goto have_reachable_peer;
- }
-
- clamp_pollexp_and_set_MAXSTRAT();
- run_script("unsync", 0.0);
- have_reachable_peer: ;
- }
- }
- remove_pidfile(CONFIG_PID_FILE_PATH "/ntpd.pid");
- kill_myself_with_sig(bb_got_signal);
- }
- #if 0
- static double
- direct_freq(double fp_offset)
- {
- #ifdef KERNEL_PLL
-
- if (pll_control && kern_enable) {
- memset(&ntv, 0, sizeof(ntv));
- ntp_adjtime(&ntv);
- #ifdef STA_NANO
- clock_offset = ntv.offset / 1e9;
- #else
- clock_offset = ntv.offset / 1e6;
- #endif
- drift_comp = FREQTOD(ntv.freq);
- }
- #endif
- set_freq((fp_offset - clock_offset) / (current_time - clock_epoch) + drift_comp);
- wander_resid = 0;
- return drift_comp;
- }
- static void
- set_freq(double freq)
- {
- char tbuf[80];
- drift_comp = freq;
- #ifdef KERNEL_PLL
-
- if (pll_control && kern_enable) {
- memset(&ntv, 0, sizeof(ntv));
- ntv.modes = MOD_FREQUENCY;
- ntv.freq = DTOFREQ(drift_comp);
- ntp_adjtime(&ntv);
- snprintf(tbuf, sizeof(tbuf), "kernel %.3f PPM", drift_comp * 1e6);
- report_event(EVNT_FSET, NULL, tbuf);
- } else {
- snprintf(tbuf, sizeof(tbuf), "ntpd %.3f PPM", drift_comp * 1e6);
- report_event(EVNT_FSET, NULL, tbuf);
- }
- #else
- snprintf(tbuf, sizeof(tbuf), "ntpd %.3f PPM", drift_comp * 1e6);
- report_event(EVNT_FSET, NULL, tbuf);
- #endif
- }
- ...
- ...
- ...
- #ifdef KERNEL_PLL
-
- if (pll_control && kern_enable) {
- #define MOD_BITS (MOD_OFFSET | MOD_MAXERROR | MOD_ESTERROR | MOD_STATUS | MOD_TIMECONST)
-
- memset(&ntv, 0, sizeof(ntv));
- if (ext_enable) {
- ntv.modes = MOD_STATUS;
- } else {
- #ifdef STA_NANO
- ntv.modes = MOD_BITS | MOD_NANO;
- #else
- ntv.modes = MOD_BITS;
- #endif
- if (clock_offset < 0)
- dtemp = -.5;
- else
- dtemp = .5;
- #ifdef STA_NANO
- ntv.offset = (int32)(clock_offset * 1e9 + dtemp);
- ntv.constant = sys_poll;
- #else
- ntv.offset = (int32)(clock_offset * 1e6 + dtemp);
- ntv.constant = sys_poll - 4;
- #endif
- ntv.esterror = (u_int32)(clock_jitter * 1e6);
- ntv.maxerror = (u_int32)((sys_rootdelay / 2 + sys_rootdisp) * 1e6);
- ntv.status = STA_PLL;
-
- if (pps_enable) {
- if (!(pll_status & STA_PPSTIME))
- report_event(EVNT_KERN,
- NULL, "PPS enabled");
- ntv.status |= STA_PPSTIME | STA_PPSFREQ;
- } else {
- if (pll_status & STA_PPSTIME)
- report_event(EVNT_KERN,
- NULL, "PPS disabled");
- ntv.status &= ~(STA_PPSTIME | STA_PPSFREQ);
- }
- if (sys_leap == LEAP_ADDSECOND)
- ntv.status |= STA_INS;
- else if (sys_leap == LEAP_DELSECOND)
- ntv.status |= STA_DEL;
- }
-
- if (ntp_adjtime(&ntv) == TIME_ERROR) {
- if (!(ntv.status & STA_PPSSIGNAL))
- report_event(EVNT_KERN, NULL,
- "PPS no signal");
- }
- pll_status = ntv.status;
- #ifdef STA_NANO
- clock_offset = ntv.offset / 1e9;
- #else
- clock_offset = ntv.offset / 1e6;
- #endif
- clock_frequency = FREQTOD(ntv.freq);
-
- if (ntv.status & STA_PPSTIME) {
- #ifdef STA_NANO
- clock_jitter = ntv.jitter / 1e9;
- #else
- clock_jitter = ntv.jitter / 1e6;
- #endif
- }
- #if defined(STA_NANO) && NTP_API == 4
-
- if (loop_tai != sys_tai) {
- loop_tai = sys_tai;
- ntv.modes = MOD_TAI;
- ntv.constant = sys_tai;
- ntp_adjtime(&ntv);
- }
- #endif
- }
- #endif
- #endif
|