|
|
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