📄 ntp_osi.c
字号:
/* OSI ntp stuff */#ifndef lintstatic char *rcsid = "$Header: /xtel/isode/isode/others/ntp/RCS/ntp_osi.c,v 9.0 1992/06/16 12:42:48 isode Rel $";#endif/* * $Header: /xtel/isode/isode/others/ntp/RCS/ntp_osi.c,v 9.0 1992/06/16 12:42:48 isode Rel $ * * * $Log: ntp_osi.c,v $ * Revision 9.0 1992/06/16 12:42:48 isode * Release 8.0 * */#include "ntp.h"#include "NTP-ops.h"#include "NTP-types.h"void ros_advise (), acs_advise ();extern LLog *pgm_log;extern double WayTooBig;extern unsigned long clock_watchdog;extern LLog *pgm_log;#ifdef DEBUGextern int debug;extern void dump_pkt();#endifextern int trusting, logstats;extern struct sysdata sys;extern struct list peer_list;extern struct ntp_peer *check_peer();extern unsigned int servport;extern char *ntoa();extern double drift_comp, compliance; /* logical clock variables */extern void make_new_peer(), tstamp(), clock_update (), receive (), clear (), clock_filter (), select_clock (), poll_update (), adios (), advise ();extern struct ntp_peer *find_peer ();extern int demobilize ();static double ul_fixed_to_doublep ();static double ul2_fixed_to_double ();static void tstamp_osi ();static void ros_indication ();static int acsap_retry ();static int acsap_initial ();static int bindfailed ();static PE build_bind_arg ();static int check_accept ();static int handle_reject ();static int TMagic (vecp, vec, td)int *vecp;char **vec;struct TSAPdisconnect *td;{ int sd; struct TSAPstart tss; register struct TSAPstart *ts = &tss; if (TInit (*vecp, vec, ts, td) == NOTOK) return NOTOK; sd = ts -> ts_sd; if (TConnResponse (sd, &ts -> ts_called, ts -> ts_expedited, NULLCP, 0, NULLQOS, td) == NOTOK) return NOTOK; if (TSaveState (sd, vec + 1, td) == NOTOK) return NOTOK; vec[*vecp = 2] = NULL; return OK;}void create_osilisten (addr)char *addr;{ int result_func (), query_func (); struct RoSAPindication rois; register struct RoSAPindication *roi = &rois; struct TSAPdisconnect tds; struct TSAPdisconnect *td = &tds; struct PSAPaddr *pa; if (addr == NULL) return; if ((pa = str2paddr (addr)) == NULLPA) adios (NULLCP, "Address translation failed for %s", addr); if (TNetListenAux (&pa -> pa_addr.sa_addr, TMagic, td) == NOTOK) adios (NULLCP, "Address listen failed"); if (RyDispatch (NOTOK, table_NTP_Operations, operation_NTP_update, result_func, roi) == NOTOK) adios (NULLCP, "RyDispatch failed"); if (RyDispatch (NOTOK, table_NTP_Operations, operation_NTP_query, query_func, roi) == NOTOK) adios (NULLCP, "RyDispatch failed"); TRACE (1, ("Listening on address %s", addr));}struct type_NTP_TimeStamp *sstamp ();struct type_NTP_SmallFixed *sfixed ();struct type_NTP_ClockIdentifier *srclock ();Refid *gclock ();struct timeval *osi_tvp;extern struct ntp_peer dummy_peer;extern struct list peer_list;extern struct sysdata sys;static void process_packet_osi ();static void terminate ();int transmit_osi (peer)struct ntp_peer *peer;{ struct RoSAPindication rois; register struct RoSAPindication *roi = &rois; register struct RoSAPpreject *rop = &roi -> roi_preject; struct type_NTP_Packet *packet; struct type_NTP_Leap *leap; struct intf *ap; struct timeval txtv; int result_func (); int i; ap = peer -> sock < 0 ? addrs : &addrs[peer->sock]; TRACE (2, ("Sending OSI packet to %s fd %d if %d", paddr(&ap -> addr), ap -> fd, ap - addrs)); if (ap -> addr.type != AF_OSI) { advise (LLOG_EXCEPTIONS, NULLCP, "Wrong address family in send_osi!"); return -1; } packet = (struct type_NTP_Packet *) malloc (sizeof *packet); leap = (struct type_NTP_Leap *) malloc (sizeof *leap); packet -> leap = leap; switch (sys.leap & LEAPMASK) { case NO_WARNING: leap -> parm = int_NTP_Leap_nowarning; break; case PLUS_SEC: leap -> parm = int_NTP_Leap_plussecond; break; case MINUS_SEC: leap -> parm = int_NTP_Leap_minussecond; break; case ALARM: leap -> parm = int_NTP_Leap_alarm; break; }#ifdef notdef/* really 2 */ packet -> version = peer -> vers == 1 ? 2 : peer -> vers;#endif packet -> mode = (struct type_NTP_Mode *) malloc (sizeof (struct type_NTP_Mode)); packet -> mode -> parm = peer -> hmode; packet -> stratum = sys.stratum; packet -> pollInterval = peer -> hpoll; packet -> precision = sys.precision; packet -> synchDistance = sfixed (&sys.distance); packet -> synchDispersion = sfixed (&sys.dispersion); packet -> referenceClockIdentifier = srclock (&sys.refid); packet -> referenceTimestamp = sstamp (&sys.reftime); packet -> originateTimestamp = sstamp (&peer -> org); packet -> receiveTimestamp = sstamp (&peer -> rec); (void) gettimeofday (&txtv, (struct timezone *)0); tstamp_osi (&peer->xmt, &txtv); packet -> transmitTimestamp = sstamp (&peer -> xmt); switch (RyStub (ap -> fd, table_NTP_Operations, operation_NTP_update, RyGenID (ap -> fd), NULLIP, (caddr_t) packet, result_func, NULLIFP, ROS_ASYNC, roi)) { case NOTOK: ros_advise (rop, "STUB"); if (ROS_FATAL (rop -> rop_reason)) terminate (ap, roi); break; case OK: break; case DONE: terminate (ap, roi); break; } free_NTP_Packet (packet); peer->pkt_sent++; i = peer->reach; /* save a copy */ peer->reach = (peer->reach << 1) & NTP_WINDOW_SHIFT_MASK; if ((peer->reach == 0) && ((peer->flags & PEER_FL_CONFIG) == 0) && (peer != &dummy_peer) && demobilize(&peer_list, peer)) return 0; if (i && peer->reach == 0) { advise (LLOG_NOTICE, NULLCP, "Lost reachability with %s", paddr (&peer->src)); } if (peer->reach == 0) clear(peer); if (peer->valid < 2) peer->valid++; else { clock_filter(peer, 0.0, 0.0); /* call with invalid values */ select_clock(); /* and try to reselect clock */ if (sys.peer != NULL) poll_update(sys.peer, NTP_MINPOLL); } peer->timer = 1<<(MAX(MIN((int)peer->ppoll, MIN((int)peer->hpoll, NTP_MAXPOLL)), NTP_MINPOLL)); if (peer->reach == 0) { if (peer->backoff == 0) peer->backoff = BACKOFF_COUNT; else { if (peer->backoff == 1) poll_update (peer, (int)peer->hpoll + 1); peer->backoff --; } } else if (peer->estdisp > PEER_THRESHOLD) poll_update(peer, (int)peer->hpoll - 1); else poll_update(peer, (int)peer->hpoll + 1); return 0;}struct s_fixedpt gfixed ();struct l_fixedpt gstamp ();/* ARGSUSED */int result_func (sd, ryo, rox, in, roi)int sd;struct RyOperation *ryo;struct RoSAPinvoke *rox;caddr_t in;struct RoSAPindication *roi;{ struct ntp_peer *peer; int peer_mode; struct intf *ap; struct Naddr *dst; int sock; struct type_NTP_Packet *result = (struct type_NTP_Packet *)in; for (ap = addrs; ap < &addrs[nintf]; ap++) if (ap -> fd == sd) break; if (ap >= &addrs[nintf]) return OK; dst = &ap -> addr; sock = ap - addrs; if ((peer_mode = result -> mode -> parm) == int_NTP_Mode_client) { /* * Special case: Use the dummy peer item that we keep around * just for this type of thing */ peer = &dummy_peer; make_new_peer(peer); peer->src = *dst; peer->sock = sock; peer->hmode = MODE_SYM_PAS; peer->reach = 0; clear(peer); } else peer = check_peer(dst, sock); if (peer == NULL) { peer = (struct ntp_peer *) malloc(sizeof(struct ntp_peer)); if (peer == NULL) { advise (LLOG_EXCEPTIONS, "malloc", "peer"); return OK; } make_new_peer(peer); peer->src = *dst; peer->sock = sock; /* remember which socket we heard this from */ peer->hmode = MODE_SYM_PAS; peer->reach = 0; clear(peer); /* * If we decide to consider any random NTP peer that might * come as a peer we might sync to, then set the PEER_FL_SYNC * flag in the peer structure. * * Alternatively, we could change the hmode to MODE_SERVER, * but then the peer state wouldn't be persistant. */ if (trusting) peer->flags |= PEER_FL_SYNC; enqueue(&peer_list, peer); } if (peer_mode < MODE_SYM_ACT || peer_mode > MODE_BROADCAST) { TRACE (1, ("Bogus peer_mode %d from %s", peer_mode, paddr (dst))); return OK; } if (peer->hmode < MODE_SYM_ACT || peer->hmode > MODE_BROADCAST) { advise (LLOG_EXCEPTIONS, NULLCP, "Bogus hmode %d for peer %s", peer->hmode, paddr (&peer->src)); abort(); } peer->backoff = 0; switch (actions[peer_mode - 1][peer->hmode - 1]) { case ACT_RECV: if (!(((peer->flags & PEER_FL_CONFIG) == 0) && STRMCMP((int)result->stratum, >, (int)sys.stratum))) { peer->reach |= 1; process_packet_osi(dst, result, osi_tvp, peer); break; } /* Note fall-through */ case ACT_ERROR: if (((peer->flags & PEER_FL_CONFIG) == 0) && (peer != &dummy_peer) && demobilize(&peer_list, peer)) break; break; case ACT_PKT: if (!(((peer->flags & PEER_FL_CONFIG) == 0) && STRMCMP((int)result->stratum, >, (int)sys.stratum))) { peer->reach |= 1; process_packet_osi(dst, result, osi_tvp, peer); break; } /* Note fall-through */ case ACT_XMIT: process_packet_osi(dst, result, osi_tvp, peer); poll_update(peer, (int)peer->ppoll); (void) transmit_osi(peer); break; default: abort(); } return OK;}/* 3.4.3 Packet procedure */static void process_packet_osi (dst, pkt, tvp, peer)struct Naddr *dst;struct type_NTP_Packet *pkt;struct timeval *tvp;struct ntp_peer *peer;{ double t1, t2, t3, t4, offset, delay; short duplicate, bogus; duplicate = (pkt->transmitTimestamp->integer == peer->org.int_part) && (pkt->transmitTimestamp->fraction == peer->org.fraction); bogus = ((pkt->originateTimestamp -> integer != peer->xmt.int_part) || (pkt->originateTimestamp -> fraction != peer->xmt.fraction)) || (peer->xmt.int_part == 0); peer->pkt_rcvd++; switch (pkt -> leap -> parm) { case int_NTP_Leap_minussecond: peer->leap = MINUS_SEC; break; case int_NTP_Leap_alarm: peer->leap = ALARM; break; case int_NTP_Leap_plussecond: peer->leap = PLUS_SEC; break; case int_NTP_Leap_nowarning: peer->leap = NO_WARNING; break; } peer->stratum = pkt->stratum; peer->ppoll = pkt-> pollInterval; peer->precision = pkt->precision; peer->distance = gfixed (pkt->synchDistance); peer->dispersion = gfixed (pkt->synchDispersion); peer ->refid = *gclock (pkt -> referenceClockIdentifier); peer->reftime = gstamp (pkt->referenceTimestamp); peer->org = gstamp (pkt->transmitTimestamp); tstamp_osi (&peer->rec, tvp); poll_update(peer, (int)peer->hpoll); /* * may want to do something special here for Broadcast Mode peers to * allow these through */ if (bogus || duplicate || (pkt->originateTimestamp -> integer == 0 && pkt->originateTimestamp -> fraction == 0) || (pkt->receiveTimestamp -> integer == 0 && pkt->receiveTimestamp -> fraction == 0)) { peer->pkt_dropped++; TRACE (3, ("process_packet_osi: dropped duplicate or bogus")); return; } /* * Now compute local adjusts */ t1 = ul2_fixed_to_double(pkt->originateTimestamp); t2 = ul2_fixed_to_double(pkt->receiveTimestamp); t3 = ul2_fixed_to_double(pkt->transmitTimestamp); t4 = ul_fixed_to_doublep(&peer->rec);/* END Protocol specific stuff */ /* * although the delay computation looks different than the one in the * specification, it is correct. Think about it. */ delay = (t2 - t1) - (t3 - t4); offset = ((t2 - t1) + (t3 - t4)) / 2.0; delay += 1.0/(unsigned long)(1L << -sys.precision) + (peer->flags&PEER_FL_REFCLOCK) ? NTP_REFMAXSKW : NTP_MAXSKW; if (peer->precision < 0 && -peer->precision < sizeof(long)*NBBY) delay += 1.0/(unsigned long)(1L << -peer->precision); if (delay < 0.0) { peer->pkt_dropped++; return; }#ifndef REFCLOCK delay = MAX(delay, NTP_MINDIST);#else delay = MAX(delay, (peer->flags & PEER_FL_REFCLOCK) ? NTP_REFMINDIST : NTP_MINDIST);#endif peer->valid = 0; clock_filter(peer, delay, offset); /* invoke clock filter procedure */ TRACE (1, ("host: %s : %f : %f : %f : %f : %f : %o", dst ? paddr (dst) : "refclock", delay, offset, peer->estdelay, peer->estoffset, peer->estdisp, peer->reach)); clock_update(peer); /* call clock update procedure */}struct l_fixedpt gstamp (ts)struct type_NTP_TimeStamp *ts;{ static struct l_fixedpt fp; fp.int_part = ts -> integer; fp.fraction = ts -> fraction; return fp;}struct s_fixedpt gfixed (ts)struct type_NTP_SmallFixed *ts;{ static struct s_fixedpt fp; fp.int_part = ts -> integer; fp.fraction = ts -> fraction; return fp;}Refid *gclock (ci)struct type_NTP_ClockIdentifier *ci;{ static Refid rid; char *p; struct PSAPaddr *pa; switch (ci -> offset) { case type_NTP_ClockIdentifier_referenceClock: rid.rid_type = RID_STRING; p = qb2str (ci->un.referenceClock); (void) strncpy (rid.rid_string, p, 4); free (p); break; case type_NTP_ClockIdentifier_inetaddr: p = qb2str (ci->un.inetaddr); rid.rid_inet = inet_addr (p); rid.rid_type = RID_INET; free (p); break; case type_NTP_ClockIdentifier_psapaddr: p = qb2str (ci->un.psapaddr); pa = str2paddr (p); rid.rid_psap = *pa; rid.rid_type = RID_PSAP; free (p); break; default: (void) strncpy (rid.rid_string, "????", 4); rid.rid_type = RID_STRING; } return &rid;}struct type_NTP_TimeStamp *sstamp (ts)struct l_fixedpt *ts;{ struct type_NTP_TimeStamp *nts; nts = (struct type_NTP_TimeStamp *)malloc (sizeof (*nts)); nts -> integer = ts -> int_part; nts -> fraction = ts -> fraction; return nts;}struct type_NTP_SmallFixed *sfixed (ts)struct s_fixedpt *ts;{ struct type_NTP_SmallFixed *nts; nts = (struct type_NTP_SmallFixed *)malloc (sizeof *nts); nts -> integer = ts -> int_part; nts -> fraction = ts -> fraction; return nts;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -