📄 ntp_osi.c
字号:
struct type_NTP_ClockIdentifier *srclock (rid)Refid *rid;{ struct type_NTP_ClockIdentifier *ci; char *p; ci = (struct type_NTP_ClockIdentifier *) malloc (sizeof *ci); switch (rid -> rid_type) { default: case RID_STRING: ci -> offset = type_NTP_ClockIdentifier_referenceClock; if (rid -> rid_type == RID_STRING) ci -> un.referenceClock = str2qb (rid->rid_string, 4, 1); else ci -> un.referenceClock = str2qb ("??", 2, 1); break; case RID_INET: { struct in_addr in; ci -> offset = type_NTP_ClockIdentifier_inetaddr; in.s_addr = rid -> rid_inet; p = inet_ntoa (in); ci -> un.inetaddr = str2qb (p, strlen (p), 1); break; } case RID_PSAP: ci -> offset = type_NTP_ClockIdentifier_psapaddr; p = _paddr2str (&rid->rid_psap, NULLNA, -1); ci -> un.psapaddr = str2qb (p, strlen(p), 1); break; } return ci;}int recv_osi (ap, tvp)struct intf *ap;struct timeval *tvp;{ caddr_t out; struct RoSAPindication rois; register struct RoSAPindication *roi = &rois; register struct RoSAPpreject *rop = &roi -> roi_preject; TRACE (2, ("Received OSI packet from %s", paddr (&ap->addr))); osi_tvp = tvp; switch (RyWait (ap -> fd, NULLIP, &out, OK, roi)) { case NOTOK: if (rop -> rop_reason == ROS_TIMER) break; case OK: case DONE: ros_indication (ap -> fd, ap, roi); break; default: advise (LLOG_EXCEPTIONS, NULLCP, "Unknown return from RyWait"); } return 0;}static void ros_indication (fd, ap, roi)int fd;struct intf *ap;register struct RoSAPindication *roi;{ int result; switch (roi -> roi_type) { case ROI_INVOKE: case ROI_RESULT: case ROI_ERROR: advise (LLOG_EXCEPTIONS, NULLCP, "unexpected indication type=%d", roi -> roi_type); terminate (ap, roi); break; case ROI_UREJECT: { register struct RoSAPureject *rou = &roi -> roi_ureject; if (rou -> rou_noid) advise (LLOG_EXCEPTIONS, NULLCP, "RO-REJECT-U.INDICATION/%d: %s", fd, RoErrString (rou -> rou_reason)); else advise (LLOG_EXCEPTIONS, NULLCP, "RO-REJECT-U.INDICATION/%d: %s (id=%d)", fd, RoErrString (rou -> rou_reason), rou -> rou_id); } break; case ROI_PREJECT: { register struct RoSAPpreject *rop = &roi -> roi_preject; ros_advise (rop, "RO-REJECT-P.INDICATION"); if (ROS_FATAL (rop -> rop_reason)) { terminate (ap, roi); } } break; case ROI_FINISH: { register struct AcSAPfinish *acf = &roi -> roi_finish; struct AcSAPindication acis; register struct AcSAPabort *aca = &acis.aci_abort; advise (LLOG_EXCEPTIONS, NULLCP, "A-RELEASE.INDICATION/%d: %d", fd, acf -> acf_reason); result = AcRelResponse (fd, ACS_ACCEPT, ACR_NORMAL, NULLPEP, 0, &acis); ACFFREE (acf); if (result == NOTOK) acs_advise (aca, "A-RELEASE.RESPONSE"); terminate (ap, roi); break; } /* NOTREACHED */ default: advise (LLOG_EXCEPTIONS, NULLCP, "unknown indication type=%d", roi -> roi_type); }}static void terminate (ap, roi)struct intf *ap;struct RoSAPindication *roi;{ struct AcSAPindication acsis; extern struct list peer_list; struct ntp_peer *peer; int fd = ap -> fd; (void) AcUAbortRequest (fd, NULLPEP, 0, &acsis); (void) RyLose (fd, roi); if (fd >= 0) { FD_CLR (fd, &globmask); FD_CLR (fd, &globwmask); if (fd == selfds + 1) selfds --; ap -> fd = -1; } if ((peer = find_peer (ap - addrs)) != NULL) { peer-> flags &= ~PEER_FL_CONNSTATE; peer -> reach = 0; clear (peer); } ap -> flags = 0; advise (LLOG_NOTICE, NULLCP, "Connection on %d if %d TERMINATED", ap -> fd, fd);}void iso_init (vecp, vec, fd)int vecp;char **vec;int fd;{ struct intf *ap; int acount; ap = getintf (&acount); ap->name = "OSI"; ap->addr.type = AF_OSI; ap->fd = fd; ap -> flags = INTF_ACCEPTING; if (vecp > 0) ap -> vec[0] = strdup (vec[0]); if (vecp > 1) ap -> vec[1] = strdup (vec[1]); if (vecp > 2) ap -> vec[2] = strdup (vec[2]); if (vecp > 3) ap -> vec[3] = strdup (vec[3]); ap -> vecp = vecp; ap -> vec[vecp] = NULLCP; ap -> inum = acount; FD_SET (fd, &globmask); if (fd >= selfds) selfds = fd + 1; TRACE (1, ("Incoming Connection pending on %d", fd));}iso_accept (ap)struct intf *ap;{ int result, i, sd; struct AcSAPstart acss; register struct AcSAPstart *acs = &acss; struct AcSAPindication acis; register struct AcSAPindication *aci = &acis; register struct AcSAPabort *aca = &aci -> aci_abort; register struct PSAPstart *ps = &acs -> acs_start; struct PSAPaddr *pa; struct RoSAPindication rois; register struct RoSAPindication *roi = &rois; register struct RoSAPpreject *rop = &roi -> roi_preject; struct Naddr *adr; struct ntp_peer *peer; struct type_NTP_BindArgument *bindarg; struct type_NTP_BindResult *bindresult; PE *pep, pe; int version, mode; if (AcInit (ap -> vecp, ap -> vec, acs, aci) == NOTOK) { acs_advise (aca, "Initialisation fails"); return NOTOK; } for (i = 0; i < ap -> vecp; i++) { free (ap -> vec[i]); ap -> vec[i] = NULLCP; } ap -> vecp = 0; TRACE (1,("A-ASSOCIATE.INDICATION: <%d, %s, %s, %s, %d>", acs -> acs_sd, oid2ode (acs -> acs_context), sprintaei (&acs -> acs_callingtitle), sprintaei (&acs -> acs_calledtitle), acs -> acs_ninfo)); sd = acs -> acs_sd; if (acs -> acs_ninfo > 0) { PLOG (pgm_log, print_NTP_BindArgument, acs -> acs_info[0], "NTP.BindArgument", 1); if (decode_NTP_BindArgument (acs -> acs_info[0], 1, NULLIP, NULLVP, &bindarg) == NOTOK) { advise (LLOG_EXCEPTIONS, NULLCP, "bind decode failed [%s]", PY_pepy); free_NTP_BindArgument(bindarg); return bindfailed (ap, acs, int_NTP_reason_badarg, NULLCP); } if (bindarg -> psap == NULL) pa = &acs -> acs_start.ps_calling; else { char *p; p = qb2str(bindarg -> psap); if ((pa = str2paddr (p)) == NULLPA) pa = &acs -> acs_start.ps_calling; free (p); } if (bit_test (bindarg -> version, bit_NTP_version_version__2)) version = 2; else if (bit_test (bindarg -> version, bit_NTP_version_version__1)) version = 1; else { free_NTP_BindArgument(bindarg); return bindfailed (ap, acs, int_NTP_reason_version, "No acceptable version"); } if (bindarg -> authentication) { advise (LLOG_NOTICE, "Connection specifies authentication"); free_NTP_BindArgument(bindarg); return bindfailed (ap, acs, int_NTP_reason_validation, "Authentication not supported"); } switch (bindarg -> mode -> parm) { case int_NTP_BindMode_normal: mode = PEERMODE_NORMAL; break; case int_NTP_BindMode_query: mode = PEERMODE_QUERY; break; default: free_NTP_BindArgument(bindarg); return bindfailed (ap, acs, int_NTP_reason_badarg, "Unknown mode"); } free_NTP_BindArgument(bindarg); bindresult = (struct type_NTP_BindResult *) calloc (1, sizeof *bindresult); bindresult -> version = version; bindresult -> mode = (struct type_NTP_BindMode *) calloc (1, sizeof *bindresult -> mode); bindresult -> mode -> parm = mode == PEERMODE_QUERY ? int_NTP_BindMode_query : int_NTP_BindMode_normal; if (encode_NTP_BindResult (&pe, 1, 0, NULLCP, bindresult) == NOTOK) { advise (LLOG_EXCEPTIONS, NULLCP, "encode failed [%s]", PY_pepy); return bindfailed (ap, acs, int_NTP_reason_congested, "Can't build result"); } PLOG (pgm_log, print_NTP_BindResult, pe, "NTP.BindResult", 0); pe -> pe_context = 3; free_NTP_BindResult (bindresult); pep = &pe; } else { pa = &acs -> acs_start.ps_calling; mode = int_NTP_BindMode_normal; version = 1; pep = NULLPEP; } ap->addr.psap_ad = *pa; ap->addr.type = AF_OSI; ap ->flags = INTF_VALID; ap->fd = sd; adr = &ap->addr; pa = &adr->psap_ad; result = AcAssocResponse (sd, ACS_ACCEPT, ACS_USER_NULL, NULLOID, NULLAEI, NULLPA, NULLPC, ps -> ps_defctxresult, ps -> ps_prequirements, ps -> ps_srequirements, SERIAL_NONE, ps -> ps_settings, &ps -> ps_connect, pep, pep == NULLPEP ? 0 : 1, aci); if (pep) pe_free (*pep); ACSFREE (acs); if (result == NOTOK) { acs_advise (aca, "Association response failed"); terminate (ap, roi); return NOTOK; } if (RoSetService (sd, RoPService, roi) == NOTOK) { ros_advise (rop, "set RO/PS fails"); terminate (ap, roi); return NOTOK; } ap -> flags |= INTF_VALID; FD_SET (sd, &globmask); if (sd >= selfds) selfds = sd + 1; result = 0; for (peer = peer_list.head; peer; peer = peer->next) { if (peer->src.type != AF_OSI) continue; if (psapaddr_cmp (pa, &peer->src.psap_ad)) { result = 1; peer -> flags |= PEER_FL_CONNECTED; peer -> sock = ap -> inum; peer -> vers = version; peer -> mode = mode; } } if (result == 0 && mode == int_NTP_BindMode_normal) { 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 = ap->addr; peer -> flags |= PEER_FL_CONNECTED; peer->sock = ap -> inum; peer->hmode = MODE_SYM_PAS; peer->vers = version; peer->mode = mode; peer->reach = 0; clear(peer); if (trusting) peer -> flags |= PEER_FL_SYNC; enqueue(&peer_list, peer); } peer = find_peer (ap -> inum); TRACE (2, ("Association accepted from %s sd %d if %d", paddr (adr), sd, ap -> inum)); if (peer && peer -> flags & PEER_FL_CONFIG) (void) transmit_osi (peer); return OK;}static int bindfailed (ap, acs, type, msg)struct intf *ap;struct AcSAPstart *acs;int type;char *msg;{ PE pe; register struct PSAPstart *ps = &acs -> acs_start; struct type_NTP_BindError *binderr; struct RoSAPindication rois; struct RoSAPindication *roi = &rois; struct AcSAPindication acis; register struct AcSAPindication *aci = &acis; binderr = (struct type_NTP_BindError *) calloc (1, sizeof *binderr); binderr -> reason = type; if (msg != NULLCP) binderr -> supplementary = str2qb (msg, strlen (msg), 1); if (encode_NTP_BindError (&pe, 1, 0, NULLCP, binderr) == NOTOK) { advise (LLOG_EXCEPTIONS, NULLCP, "ecode binderror failed [%s]", PY_pepy); ACSFREE (acs); terminate (ap, roi); return NOTOK; } PLOG (pgm_log, print_NTP_BindError, pe, "NTP.BindError", 0); pe -> pe_context = 3; free_NTP_BindError (binderr); (void) AcAssocResponse (ap -> fd, ACS_REJECT, ACS_USER_NULL, NULLOID, NULLAEI, NULLPA, NULLPC, ps -> ps_defctxresult, ps -> ps_prequirements, ps -> ps_srequirements, SERIAL_NONE, ps -> ps_settings, &ps -> ps_connect, &pe, 1, aci); pe_free (pe); ACSFREE (acs); terminate (ap, roi); return NOTOK;}char *mycontext = "ntp";char *mypci = "ntp pci";int make_osi_conn (peer, addr)struct ntp_peer *peer;char *addr;{ int result = NOTOK; struct intf *ap; struct RoSAPindication rois; register struct RoSAPindication *roi = &rois; switch (peer->flags & PEER_FL_CONNSTATE) { case PEER_FL_CONNECTED: return OK; case 0: switch (acsap_initial (peer, addr, roi)) { case NOTOK: return NOTOK; case CONNECTING_1: ap = &addrs[peer->sock]; peer -> flags |= PEER_FL_CONINP1; FD_SET (ap -> fd, &globwmask); return NOTOK; case CONNECTING_2: ap = &addrs[peer->sock]; peer -> flags |= PEER_FL_CONINP2; FD_SET (ap -> fd, &globmask); return NOTOK; case DONE: ap = &addrs[peer->sock]; peer -> flags &= ~ PEER_FL_CONNSTATE; peer -> flags |= PEER_FL_CONNECTED; FD_CLR (ap -> fd, &globwmask); FD_SET (ap -> fd, &globmask); ap -> flags = INTF_VALID; return OK; } return NOTOK; case PEER_FL_CONINP1: ap = &addrs[peer->sock]; switch (result = acsap_retry (peer, roi)) { case CONNECTING_1: peer -> flags &= ~ PEER_FL_CONNSTATE; peer -> flags |= PEER_FL_CONINP1; FD_CLR (ap -> fd, &globmask); FD_SET (ap -> fd, &globwmask); return NOTOK; case CONNECTING_2: peer -> flags &= ~ PEER_FL_CONNSTATE; peer -> flags |= PEER_FL_CONINP2; FD_CLR (ap -> fd, &globwmask); FD_SET (ap -> fd, &globmask); return NOTOK; case NOTOK: terminate (ap, roi); return NOTOK; case DONE: peer -> flags &= ~ PEER_FL_CONNSTATE; peer -> flags |= PEER_FL_CONNECTED; FD_CLR (ap -> fd, &globwmask); FD_SET (ap -> fd, &globmask); ap -> flags = INTF_VALID; return OK; } break; case PEER_FL_CONINP2: ap = &addrs[peer->sock]; switch( result = acsap_retry (peer, roi)) { case CONNECTING_1: peer -> flags &= ~ PEER_FL_CONNSTATE; peer -> flags |= PEER_FL_CONINP1; FD_CLR (ap -> fd, &globmask); FD_SET (ap -> fd, &globwmask); return OK; case CONNECTING_2: peer -> flags &= ~ PEER_FL_CONNSTATE; peer -> flags |= PEER_FL_CONINP2; FD_CLR (ap -> fd, &globwmask); FD_SET (ap -> fd, &globmask); return OK; case DONE: peer -> flags &= ~ PEER_FL_CONNSTATE; peer -> flags |= PEER_FL_CONNECTED; FD_CLR (ap -> fd, &globwmask); FD_SET (ap -> fd, &globmask); ap -> flags = INTF_VALID; return OK; case NOTOK: terminate (ap, roi); return NOTOK; } } return result == DONE ? OK : NOTOK;}/* ARGSUSED */static int acsap_initial (peer, addr, roi)struct ntp_peer *peer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -