|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T r
Length: 27922 (0x6d12) Types: TextFile Names: »rt2ss.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z« └─⟦e5a54fb17⟧ └─⟦this⟧ »pp-5.0/Chans/x40088/rt2ss.c«
/* rt2ss.c - RTPM: SSAP interface */ # ifndef lint static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Chans/x40088/RCS/rt2ss.c,v 5.0 90/09/20 15:58:14 pp Exp Locker: pp $"; # endif /* * $Header: /cs/research/pp/hubris/pp-beta/Chans/x40088/RCS/rt2ss.c,v 5.0 90/09/20 15:58:14 pp Exp Locker: pp $ * * $Log: rt2ss.c,v $ * Revision 5.0 90/09/20 15:58:14 pp * rcsforce : 5.0 public release * */ /* * NOTICE * * Acquisition, use, and distribution of this module and related * materials are subject to the restrictions of a license agreement. * Consult the Preface in the User's Manual for the full terms of * this agreement. * */ /* LINTLIBRARY */ #include <stdio.h> #include <isode/rtpkt.h> #include <isode/tailor.h> #if ISODE < 65 /* \f DATA */ #define doSSabort ss2rtsabort int ssDATAser (), ssTOKENser (), ssSYNCser (), ssACTIVITYser (), ssREPORTser (), ssFINISHser (), ssABORTser (); long time (); /* \f */ int rt2sspturn (acb, priority, rti) register struct assocblk *acb; int priority; register struct RtSAPindication *rti; { int result, len; char *base; PE pe; struct SSAPindication sis; struct SSAPindication *si = &sis; struct SSAPabort *sa = &si -> si_abort; if (!(acb -> acb_flags & ACB_TWA)) return rtsaplose (rti, RTS_OPERATION, NULLCP, "mode of association is monologue"); if (acb -> acb_flags & ACB_TURN) return rtsaplose (rti, RTS_OPERATION, NULLCP, "turn owned by you"); /* begin Priority PSDU (pseudo) */ if ((pe = int2prim (priority)) == NULLPE) return rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP); /* end Priority PSDU */ PLOG (rtsap_log, print_OACS_Priority, pe, "Priority", 0); result = pe2ssdu (pe, &base, &len); pe_free (pe); if (result == NOTOK) return rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP); result = SPTokenRequest (acb -> acb_fd, ST_DAT_TOKEN, base, len, si); free (base); if (result == NOTOK) { (void) ss2rtslose (acb, rti, "SPTokenRequest", sa); freeacblk (acb); } return result; } /* \f */ int rt2ssgturn (acb, rti) register struct assocblk *acb; register struct RtSAPindication *rti; { struct SSAPindication sis; struct SSAPindication *si = &sis; struct SSAPabort *sa = &si -> si_abort; if (!(acb -> acb_flags & ACB_TWA)) return rtsaplose (rti, RTS_OPERATION, NULLCP, "mode of association is monologue"); if (!(acb -> acb_flags & ACB_TURN)) return rtsaplose (rti, RTS_OPERATION, NULLCP, "turn not owned by you"); if (acb -> acb_flags & ACB_ACT) return rtsaplose (rti, RTS_OPERATION, NULLCP, "transfer in progress"); if (SGControlRequest (acb -> acb_fd, si) == NOTOK) { (void) ss2rtslose (acb, rti, "SGControlRequest", sa); freeacblk (acb); return NOTOK; } acb -> acb_flags &= ~(ACB_TURN | ACB_PLEASE); return OK; } /* \f */ int rt2sstrans (acb, data, secs, rti) register struct assocblk *acb; register PE data; int secs; register struct RtSAPindication *rti; { register int cc, size; int result, len; long clock, limit; register char *dp; char *base; PE pe; struct SSAPactid ids; register struct SSAPactid *id = &ids; struct SSAPindication sis; struct SSAPindication *si = &sis; struct SSAPabort *sa = &si -> si_abort; struct RtSAPabort *rta = &rti -> rti_abort; if (!(acb -> acb_flags & ACB_TURN)) return rtsaplose (rti, RTS_OPERATION, NULLCP, "turn not owned by you"); if (acb -> acb_flags & ACB_ACT) return rtsaplose (rti, RTS_OPERATION, NULLCP, "transfer in progress"); if ((pe = int2prim (acb -> acb_actno)) == NULLPE) return rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP); result = pe2ssdu (pe, &base, &len); pe_free (pe); if (result == NOTOK) return rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP); bcopy (base, id -> sd_data, (int) (id -> sd_len = len)); free (base); base = NULL; if (SActStartRequest (acb -> acb_fd, id, NULLCP, 0, si) == NOTOK) { (void) ss2rtslose (acb, rti, "SActStartRequest", sa); goto out; } acb -> acb_flags |= ACB_ACT; if (data && pe2ssdu (data, &base, &len) == NOTOK) { (void) rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP); goto out; } result = OK; if (acb -> acb_ckpoint == 0) { if (data == NULLPE) { if ((*acb -> acb_downtrans) (acb -> acb_fd, &base, &len, 0, 0L, 0L, rti) == NOTOK) { bad_trans: ; if (SActDiscRequest (acb -> acb_fd, SP_LOCAL, si) == NOTOK) { (void) ss2rtslose (acb, rti, "SActDiscRequest", sa); goto out; } goto done; } if (len == 0) { base = NULL; goto done; } } if (SDataRequest (acb -> acb_fd, base, len, si) == NOTOK) { (void) ss2rtslose (acb, rti, "SDataRequest", sa); goto out; } } else { size = acb -> acb_ckpoint << 10; /* units of 1024 octets */ #ifdef notdef if (acb -> acb_ssdusize >= 0x0100) /* at least 256 octets */ size = min (size, acb -> acb_ssdusize); #endif acb -> acb_ssn = acb -> acb_ack = 0L; if (secs != NOTOK) { (void) time (&limit); limit += secs; } if (data == NULLPE) { if ((*acb -> acb_downtrans) (acb -> acb_fd, &base, &len, size, acb -> acb_ssn, acb -> acb_ack, rti) == NOTOK) goto bad_trans; if (len == 0) { base = NULL; goto done; } } dp = base, cc = min (len, size); if (SDataRequest (acb -> acb_fd, dp, cc, si) == NOTOK) { (void) ss2rtslose (acb, rti, "SDataRequest", sa); goto out; } for (dp += cc, len -= cc; data == NULLPE || len > 0; dp += cc, len -= cc) { if (data == NULLPE && len == 0) { if ((*acb -> acb_downtrans) (acb -> acb_fd, &base, &len, size, acb -> acb_ssn, acb -> acb_ack, rti) == NOTOK) goto bad_trans; if (len == 0) { base = NULL; break; } dp = base; } if (secs != NOTOK) { (void) time (&clock); if (limit < clock) { result = NOTOK; break; } } if (SMinSyncRequest (acb -> acb_fd, SYNC_CONFIRM, &acb -> acb_ssn, NULLCP, 0, si) == NOTOK) { (void) ss2rtslose (acb, rti, "SMinSyncRequest", sa); goto out; } if (acb -> acb_ssn - acb -> acb_ack > acb -> acb_window) { do { if (RtWaitRequestAux (acb, NOTOK, 1, rti) == NOTOK) { if (RTS_FATAL (rta -> rta_reason)) acb = NULLACB; goto out; } } while (acb -> acb_ssn - acb -> acb_ack > acb -> acb_window); #ifdef notdef /* avoid silly window syndrome */ while (acb -> acb_ssn != acb -> acb_ack) if (RtWaitRequestAux (acb, OK, 1, rti) == NOTOK) if (rta -> rta_reason != RTS_TIMER) { if (RTS_FATAL (rta -> rta_reason)) acb = NULLACB; goto out; } else break; #endif } cc = min (len, size); if (SDataRequest (acb -> acb_fd, dp, cc, si) == NOTOK) { (void) ss2rtslose (acb, rti, "SDataRequest", sa); goto out; } } } if (data) free (base); base = NULL; done: ; switch (result) { case OK: if (SActEndRequest (acb -> acb_fd, &acb -> acb_ssn, NULLCP, 0, si) == NOTOK) { (void) ss2rtslose (acb, rti, "SActEndRequest", sa); goto out; } break; default: acb -> acb_flags |= ACB_TIMER; if (SActDiscRequest (acb -> acb_fd, SP_LOCAL, si) == NOTOK) { (void) ss2rtslose (acb, rti, "SActDiscRequest", sa); goto out; } break; } while (acb -> acb_flags & ACB_ACT) if (RtWaitRequestAux (acb, NOTOK, 1, rti) == NOTOK) { if (RTS_FATAL (rta -> rta_reason)) acb = NULLACB; goto out; } acb -> acb_flags &= ~ACB_TIMER; acb -> acb_actno++; return result; out: ; if (data && base) free (base); if (acb) freeacblk (acb); return NOTOK; } /* \f */ int rt2sswait (acb, secs, trans, rti) register struct assocblk *acb; int secs, trans; register struct RtSAPindication *rti; { int result; struct SSAPdata sxs; register struct SSAPdata *sx = &sxs; struct SSAPindication sis; register struct SSAPindication *si = &sis; for (;;) { switch (result = SReadRequest (acb -> acb_fd, sx, secs, si)) { case NOTOK: return doSSabort (acb, &si -> si_abort, rti); case OK: if (doSSdata (acb, sx, rti) == NOTOK) return NOTOK; continue; case DONE: switch (si -> si_type) { case SI_TOKEN: if ((result = doSStoken (acb, &si -> si_token, trans, rti)) != OK) return result; continue; case SI_SYNC: if ((result = doSSsync (acb, &si -> si_sync, rti)) != OK || trans) return result; continue; case SI_ACTIVITY: if ((result = doSSactivity (acb, &si -> si_activity, rti)) != OK || trans) return (result != DONE ? result : OK); continue; case SI_REPORT: if (doSSreport (acb, &si -> si_report, rti) == NOTOK) return NOTOK; continue; case SI_FINISH: return doSSfinish (acb, &si -> si_finish, rti); default: (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, "unknown indication (0x%x) from session", si -> si_type); break; } break; default: (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, "unexpected return from SReadRequest=%d", result); break; } break; } freeacblk (acb); return NOTOK; } /* \f define vectors for INDICATION events */ #define e(i) (indication ? (i) : NULLIFP) int rt2ssasync (acb, indication, rti) register struct assocblk *acb; IFP indication; struct RtSAPindication *rti; { struct SSAPindication sis; struct SSAPindication *si = &sis; struct SSAPabort *sa = &si -> si_abort; if (SSetIndications (acb -> acb_fd, e (ssDATAser), e (ssTOKENser), e (ssSYNCser), e (ssACTIVITYser), e (ssREPORTser), e (ssFINISHser), e (ssABORTser), si) == NOTOK) switch (sa -> sa_reason) { case SC_WAITING: return rtsaplose (rti, RTS_WAITING, NULLCP, NULLCP); default: (void) ss2rtslose (acb, rti, "SSetIndications", sa); freeacblk (acb); return NOTOK; } if (acb -> acb_rtsindication = indication) acb -> acb_flags |= ACB_ASYN; else acb -> acb_flags &= ~ACB_ASYN; return OK; } #undef e /* \f map association descriptors for select() */ int rt2ssmask (acb, mask, nfds, rti) register struct assocblk *acb; fd_set *mask; int *nfds; struct RtSAPindication *rti; { struct SSAPindication sis; struct SSAPindication *si = &sis; struct SSAPabort *sa = &si -> si_abort; if (SSelectMask (acb -> acb_fd, mask, nfds, si) == NOTOK) switch (sa -> sa_reason) { case SC_WAITING: return rtsaplose (rti, RTS_WAITING, NULLCP, NULLCP); default: (void) ss2rtslose (acb, rti, "SSelectMask", sa); freeacblk (acb); return NOTOK; } return OK; } /* \f protocol-level abort */ int rt2sslose (acb, result) register struct assocblk *acb; int result; { int len; char *base; PE pe; struct SSAPindication sis; base = NULL, len = 0; /* begin AbortInformation PSDU (pseudo) */ if (pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, PE_CONS_SET)) { if (set_add (pe, num2prim (result, PE_CLASS_CONT, 0)) != NOTOK) (void) pe2ssdu (pe, &base, &len); PLOG (rtsap_log, print_OACS_AbortInformation, pe, "AbortInformation", 0); pe_free (pe); } /* end AbortInformation PSDU */ (void) SUAbortRequest (acb -> acb_fd, base, len, &sis); if (!(acb -> acb_flags & ACB_STICKY)) acb -> acb_fd = NOTOK; if (base) free (base); } /* \f SSAP interface */ static int doSSdata (acb, sx, rti) register struct assocblk *acb; register struct SSAPdata *sx; struct RtSAPindication *rti; { register struct qbuf *qb; struct SSAPindication sis; register struct SSAPindication *si = &sis; register struct SSAPabort *sa = &si -> si_abort; if (!(acb -> acb_flags & ACB_ACT) || (acb -> acb_flags & ACB_TURN) || sx -> sx_type != SX_NORMAL) { (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, "unexpected data indication (0x%x)", sx -> sx_type); goto out; } if (acb -> acb_uptrans) { if ((*acb -> acb_uptrans) (acb -> acb_fd, SI_DATA, (caddr_t) &sx -> sx_qbuf, rti) == NOTOK) goto congested; goto done; } if (acb -> acb_len > 0) { unsigned int i; register char *cp, *dp; i = acb -> acb_len + sx -> sx_cc; if (acb -> acb_realbase) { if ((dp = malloc (i)) == NULL) { congested: ; if (SUReportRequest (acb -> acb_fd, SP_LOCAL, NULLCP, 0, si) == NOTOK) { (void) ss2rtslose (acb, rti, "SUReportRequest", sa); goto out; } FREEACB (acb); goto done; } bcopy (acb -> acb_base, dp, acb -> acb_len); free (acb -> acb_realbase), acb -> acb_realbase = NULL; } else if ((dp = realloc (acb -> acb_base, i)) == NULL) goto congested; cp = dp + acb -> acb_len; for (qb = sx -> sx_qbuf.qb_forw; qb != &sx -> sx_qbuf; qb = qb -> qb_forw) if (qb -> qb_len) { bcopy (qb -> qb_data, cp, qb -> qb_len); cp += qb -> qb_len; } acb -> acb_base = dp; acb -> acb_len = i; } else { if ((qb = sx -> sx_qbuf.qb_forw) != &sx -> sx_qbuf && qb -> qb_forw == &sx -> sx_qbuf) { remque (qb); acb -> acb_realbase = (char *) qb; acb -> acb_base = qb -> qb_data; } else acb -> acb_base = qb2str (&sx -> sx_qbuf); acb -> acb_len = sx -> sx_cc; } done: ; SXFREE (sx); return OK; out: ; SXFREE (sx); freeacblk (acb); return NOTOK; } /* \f */ static int doSStoken (acb, st, trans, rti) register struct assocblk *acb; register struct SSAPtoken *st; int trans; struct RtSAPindication *rti; { int result; register PE pe; struct SSAPindication sis; register struct SSAPindication *si = &sis; register struct SSAPabort *sa = &si -> si_abort; if (acb -> acb_flags & ACB_TWA) switch (st -> st_type) { case ST_CONTROL: STFREE (st); if (acb -> acb_flags & ACB_ACT) break; acb -> acb_owned = st -> st_owned; acb -> acb_flags |= ACB_TURN; rti -> rti_type = RTI_TURN; { register struct RtSAPturn *rtu = &rti -> rti_turn; rtu -> rtu_please = 0; } return DONE; case ST_PLEASE: pe = ssdu2pe (st -> st_data, st -> st_cc, NULLCP, &result); STFREE (st); if (pe == NULLPE) { (void) rtpktlose (acb, rti, result != PS_ERR_NMEM ? RTS_PROTOCOL : RTS_CONGEST, NULLCP, ps_error (result)); goto out; } result = parse_OACS_Priority (pe, 1, NULLIP, NULLVP, NULLCP); #ifdef DEBUG if (result != NOTOK && (rtsap_log -> ll_events & LLOG_PDUS)) vpdu (rtsap_log, print_OACS_Priority, pe, "Priority", 1); #endif pe_free (pe); if (result == NOTOK) { (void) pylose (); goto out; } if (trans) { if (acb -> acb_downtrans) { if ((*acb -> acb_downtrans) (acb -> acb_fd, NULLVP, NULLIP, acsap_priority, 0L, 0L, rti) == NOTOK && SActIntrRequest (acb -> acb_fd, SP_LOCAL, si) == NOTOK) { (void) ss2rtslose (acb, rti, "SActIntrRequest",sa); goto out; } } else { acb -> acb_flags |= ACB_PLEASE; acb -> acb_priority = acsap_priority; } return OK; } rti -> rti_type = RTI_TURN; { register struct RtSAPturn *rtu = &rti -> rti_turn; rtu -> rtu_please = 1; rtu -> rtu_priority = acsap_priority; } return DONE; default: break; } (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, "unexpected token indication (0x%x)", st -> st_type); out: ; STFREE (st); freeacblk (acb); return NOTOK; } /* \f */ static int doSSsync (acb, sn, rti) register struct assocblk *acb; register struct SSAPsync *sn; struct RtSAPindication *rti; { struct SSAPindication sis; register struct SSAPindication *si = &sis; register struct SSAPabort *sa = &si -> si_abort; SNFREE (sn); if (acb -> acb_flags & ACB_ACT) switch (sn -> sn_type) { case SN_MINORIND: /* always confirm it */ if (acb -> acb_flags & ACB_TURN) break; if (acb -> acb_uptrans) { if ((*acb -> acb_uptrans) (acb -> acb_fd, SI_SYNC, (caddr_t) sn, rti) == NOTOK) { if (SUReportRequest (acb -> acb_fd, SP_LOCAL, NULLCP, 0, si) == NOTOK) { (void) ss2rtslose (acb, rti, "SUReportRequest",sa); goto out; } return OK; } } if (SMinSyncResponse (acb -> acb_fd, sn -> sn_ssn, NULLCP, 0, si) == NOTOK) { (void) ss2rtslose (acb, rti, "SMinSyncResponse", sa); goto out; } return OK; case SN_MINORCNF: if (!(acb -> acb_flags & ACB_TURN)) break; acb -> acb_ack = sn -> sn_ssn; return OK; default: break; } (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, "unexpected sync indication (0x%x)", sn -> sn_type); out: ; freeacblk (acb); return NOTOK; } /* \f */ static int doSSactivity (acb, sv, rti) register struct assocblk *acb; register struct SSAPactivity *sv; struct RtSAPindication *rti; { int result; register PE pe; struct SSAPindication sis; register struct SSAPindication *si = &sis; register struct SSAPabort *sa = &si -> si_abort; SVFREE (sv); switch (sv -> sv_type) { case SV_START: if (acb -> acb_flags & (ACB_ACT | ACB_TURN)) break; if (acb -> acb_uptrans) { if ((*acb -> acb_uptrans) (acb -> acb_fd, SI_ACTIVITY, (caddr_t) sv, rti) == NOTOK) { if (SUReportRequest (acb -> acb_fd, SP_LOCAL, NULLCP, 0, si) == NOTOK) { (void) ss2rtslose (acb, rti, "SUReportRequest", sa); goto out; } return OK; } } acb -> acb_flags |= ACB_ACT; return OK; case SV_RESUME: /* XXX: will support this later */ if (acb -> acb_flags & (ACB_ACT | ACB_TURN)) break; if (SUReportRequest (acb -> acb_fd, SP_PROCEDURAL, NULLCP, 0, si) == NOTOK) { (void) ss2rtslose (acb, rti, "SUReportRequest", sa); goto out; } acb -> acb_flags |= ACB_ACT; return OK; case SV_INTRIND: case SV_DISCIND: if (!(acb -> acb_flags & ACB_ACT) || (acb -> acb_flags & ACB_TURN)) break; if (acb -> acb_uptrans) (void) (*acb -> acb_uptrans) (acb -> acb_fd, SI_ACTIVITY, (caddr_t) sv, rti); if ((sv -> sv_type == SV_INTRIND ? SActIntrResponse (acb -> acb_fd, si) : SActDiscResponse (acb -> acb_fd, si)) == NOTOK) { (void) ss2rtslose (acb, rti, sv -> sv_type == SV_INTRIND ? "SActIntrResponse" : "SActDiscResponse", sa); goto out; } FREEACB (acb); acb -> acb_flags &= ~ACB_ACT; return OK; case SV_INTRCNF: case SV_DISCCNF: if (!(acb -> acb_flags & ACB_ACT) || !(acb -> acb_flags & ACB_TURN)) break; acb -> acb_flags &= ~ACB_ACT; (void) rtsaplose (rti, acb -> acb_flags & ACB_TIMER ? RTS_TIMER : RTS_TRANSFER, NULLCP, NULLCP); return OK; case SV_ENDIND: if (!(acb -> acb_flags & ACB_ACT) || (acb -> acb_flags & ACB_TURN)) break; if (acb -> acb_uptrans) { if ((*acb -> acb_uptrans) (acb -> acb_fd, SI_ACTIVITY, (caddr_t) sv, rti) == NOTOK) { if (SUReportRequest (acb -> acb_fd, SP_LOCAL, NULLCP, 0, si) == NOTOK) { (void) ss2rtslose (acb, rti, "SUReportRequest", sa); goto out; } return OK; } pe = NULLPE; goto end_it; } if (acb -> acb_base) { if (pe = ssdu2pe (acb -> acb_base, acb -> acb_len, acb -> acb_realbase ? acb -> acb_realbase : acb -> acb_base, &result)) acb -> acb_realbase = acb -> acb_base = NULL; } else pe = NULLPE, result = PS_ERR_EOF; FREEACB (acb); if (pe == NULLPE) { if (result != PS_ERR_NMEM) { (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, "%s", ps_error (result)); goto out; } if (SUReportRequest (acb -> acb_fd, SP_LOCAL, NULLCP, 0, si) == NOTOK) { (void) ss2rtslose (acb, rti, "SUReportRequest", sa); goto out; } return OK; } end_it: ; if (SActEndResponse (acb -> acb_fd, NULLCP, 0, si) == NOTOK) { (void) ss2rtslose (acb, rti, "SActEndResponse", sa); if (pe) pe_free (pe); goto out; } acb -> acb_flags &= ~ACB_ACT; rti -> rti_type = RTI_TRANSFER; { register struct RtSAPtransfer *rtt = &rti -> rti_transfer; rtt -> rtt_data = pe; } return DONE; case SV_ENDCNF: if (!(acb -> acb_flags & ACB_ACT) || !(acb -> acb_flags & ACB_TURN)) break; acb -> acb_flags &= ~ACB_ACT; return OK; default: break; } (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, "unexpected activity indication (0x%x)", sv -> sv_type); out: ; freeacblk (acb); return NOTOK; } /* \f */ static int doSSreport (acb, sp, rti) register struct assocblk *acb; register struct SSAPreport *sp; struct RtSAPindication *rti; { struct SSAPindication sis; register struct SSAPindication *si = &sis; register struct SSAPabort *sa = &si -> si_abort; SPFREE (sp); if (!sp -> sp_peer) { if (!(acb -> acb_flags & ACB_ACT)) goto out2; /* XXX: should try lots of things here, based on how many checkpoints have been acknowledged, but, for now we'll treate everything as severe... */ (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, "unrecoverable provider-initiated exception report"); goto out1; } if (!(acb -> acb_flags & ACB_ACT) || !(acb -> acb_flags & ACB_TURN)) { out2: ; (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, "unexpected exception report indication (0x%x)", sp -> sp_peer); goto out1; } /* XXX: should try lots of things here, based on pp_reason, but, for now we'll treat everything as SP_NOREASON... */ if (acb -> acb_uptrans) (void) (*acb -> acb_uptrans) (acb -> acb_fd, SI_REPORT, (caddr_t) sp, rti); if (SActDiscRequest (acb -> acb_fd, SP_NOREASON, si) != NOTOK) return OK; (void) ss2rtslose (acb, rti, "SActDiscRequest", sa); out1: ; freeacblk (acb); return NOTOK; } /* \f */ /* ARGSUSED */ static int doSSfinish (acb, sf, rti) register struct assocblk *acb; struct SSAPfinish *sf; struct RtSAPindication *rti; { SFFREE (sf); if (((acb -> acb_flags & ACB_INIT) && (acb -> acb_flags & ACB_TWA)) || (acb -> acb_flags & ACB_TURN)) { (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, "association management botched"); goto out; } if (acb -> acb_flags & ACB_ACT) { (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, "unexpected release indication"); goto out; } acb -> acb_flags |= ACB_FINN; rti -> rti_type = RTI_CLOSE; { register struct RtSAPclose *rtc = &rti -> rti_close; bzero ((char *) rtc, sizeof *rtc); } return DONE; out: ; freeacblk (acb); return NOTOK; } /* \f */ int ss2rtsabort (acb, sa, rti) register struct assocblk *acb; register struct SSAPabort *sa; struct RtSAPindication *rti; { int result; register PE pe; if (!sa -> sa_peer) { if (sa -> sa_reason == SC_TIMER) return rtsaplose (rti, RTS_TIMER, NULLCP, NULLCP); (void) ss2rtslose (acb, rti, NULLCP, sa); goto out; } if (sa -> sa_cc == 0) { (void) rtsaplose (rti, RTS_ABORTED, NULLCP, NULLCP); goto out; } if ((pe = ssdu2pe (sa -> sa_info, sa -> sa_cc, NULLCP, &result)) == NULLPE) { (void) rtsaplose (rti, RTS_PROTOCOL, NULLCP, NULLCP); goto out; } acsap_abort = -1; result = parse_OACS_AbortInformation (pe, 1, NULLIP, NULLVP, NULLCP); #ifdef DEBUG if (result != NOTOK && (rtsap_log -> ll_events & LLOG_PDUS)) vpdu (rtsap_log, print_OACS_AbortInformation, pe, "AbortInformation", 1); #endif pe_free (pe); if (result == NOTOK) { (void) rtsaplose (rti, RTS_PROTOCOL, "%s", PY_pepy); goto out; } switch (acsap_abort) { case ABORT_LSP: case ABORT_TMP: result = RTS_REMOTE; break; default: result = RTS_PROTOCOL; break; } (void) rtsaplose (rti, result, NULLCP, NULLCP); out: ; SAFREE (sa); if (!(acb -> acb_flags & ACB_STICKY)) acb -> acb_fd = NOTOK; freeacblk (acb); return NOTOK; } /* \f */ static int ssDATAser (sd, sx) int sd; register struct SSAPdata *sx; { IFP handler; register struct assocblk *acb; struct RtSAPindication rtis; register struct RtSAPindication *rti = &rtis; if ((acb = findacblk (sd)) == NULL) return; handler = acb -> acb_rtsindication; if (doSSdata (acb, sx, rti) != OK) (*handler) (sd, rti); } /* \f */ static int ssTOKENser (sd, st) int sd; register struct SSAPtoken *st; { IFP handler; register struct assocblk *acb; struct RtSAPindication rtis; register struct RtSAPindication *rti = &rtis; if ((acb = findacblk (sd)) == NULL) return; handler = acb -> acb_rtsindication; if (doSStoken (acb, st, 0, rti) != OK) (*handler) (sd, rti); } /* \f */ static int ssSYNCser (sd, sn) int sd; register struct SSAPsync *sn; { IFP handler; register struct assocblk *acb; struct RtSAPindication rtis; register struct RtSAPindication *rti = &rtis; if ((acb = findacblk (sd)) == NULL) return; handler = acb -> acb_rtsindication; if (doSSsync (acb, sn, rti) != OK) (*handler) (sd, rti); } /* \f */ static int ssACTIVITYser (sd, sv) int sd; register struct SSAPactivity *sv; { IFP handler; register struct assocblk *acb; struct RtSAPindication rtis; register struct RtSAPindication *rti = &rtis; if ((acb = findacblk (sd)) == NULL) return; handler = acb -> acb_rtsindication; if (doSSactivity (acb, sv, rti) != OK) (*handler) (sd, rti); } /* \f */ static int ssREPORTser (sd, sp) int sd; register struct SSAPreport *sp; { IFP handler; register struct assocblk *acb; struct RtSAPindication rtis; register struct RtSAPindication *rti = &rtis; if ((acb = findacblk (sd)) == NULL) return; handler = acb -> acb_rtsindication; if (doSSreport (acb, sp, rti) != OK) (*handler) (sd, rti); } /* \f */ static int ssFINISHser (sd, sf) int sd; struct SSAPfinish *sf; { IFP handler; register struct assocblk *acb; struct RtSAPindication rtis; register struct RtSAPindication *rti = &rtis; if ((acb = findacblk (sd)) == NULL) return; handler = acb -> acb_rtsindication; (void) doSSfinish (acb, sf, rti); (*handler) (sd, rti); } /* \f */ static int ssABORTser (sd, sa) int sd; register struct SSAPabort *sa; { IFP handler; register struct assocblk *acb; struct RtSAPindication rtis; register struct RtSAPindication *rti = &rtis; if ((acb = findacblk (sd)) == NULL) return; handler = acb -> acb_rtsindication; (void) doSSabort (acb, sa, rti); (*handler) (sd, rti); } /* \f */ int ss2rtslose (acb, rti, event, sa) register struct assocblk *acb; register struct RtSAPindication *rti; char *event; register struct SSAPabort *sa; { int reason; char *cp, buffer[BUFSIZ]; if (event) SLOG (rtsap_log, LLOG_EXCEPTIONS, NULLCP, (sa -> sa_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event, SErrString (sa -> sa_reason), sa -> sa_cc, sa -> sa_cc, sa -> sa_data)); cp = ""; switch (sa -> sa_reason) { case SC_SSAPID: case SC_SSUSER: case SC_ADDRESS: reason = RTS_ADDRESS; break; case SC_REFUSED: reason = RTS_REFUSED; break; case SC_CONGEST: reason = RTS_CONGEST; break; default: (void) sprintf (cp = buffer, " (%s at session)", SErrString (sa -> sa_reason)); case SC_TRANSPORT: case SC_ABORT: reason = RTS_SESSION; break; } if (sa -> sa_cc > 0) return rtpktlose (acb, rti, reason, NULLCP, "%*.*s%s", sa -> sa_cc, sa -> sa_cc, sa -> sa_data, cp); else return rtpktlose (acb, rti, reason, NULLCP, "%s", *cp ? cp + 1 : cp); } #endif