|
|
1.1 root 1: /* rt2ps.c - RTPM: AcSAP/PSAP interface */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/rtsap/RCS/rt2ps.c,v 7.3 90/07/27 08:47:36 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/rtsap/RCS/rt2ps.c,v 7.3 90/07/27 08:47:36 mrose Exp $
9: *
10: *
11: * $Log: rt2ps.c,v $
12: * Revision 7.3 90/07/27 08:47:36 mrose
13: * update
14: *
15: * Revision 7.2 90/07/01 21:06:46 mrose
16: * pepsy
17: *
18: * Revision 6.2 89/06/23 11:28:32 mrose
19: * touch-up
20: *
21: * Revision 6.1 89/05/31 15:02:22 mrose
22: * sek
23: *
24: * Revision 6.0 89/03/18 23:43:06 mrose
25: * Release 5.0
26: *
27: */
28:
29: /*
30: * NOTICE
31: *
32: * Acquisition, use, and distribution of this module and related
33: * materials are subject to the restrictions of a license agreement.
34: * Consult the Preface in the User's Manual for the full terms of
35: * this agreement.
36: *
37: */
38:
39:
40: /* LINTLIBRARY */
41:
42: #include <stdio.h>
43: #include "RTS-types.h"
44: #include "rtpkt.h"
45: #include "tailor.h"
46:
47: /* DATA */
48:
49: int psDATAser (), psTOKENser (), psSYNCser (), psACTIVITYser (),
50: psREPORTser (), psFINISHser (), psABORTser ();
51:
52:
53: long time ();
54:
55: /* */
56:
57: int rt2pspturn (acb, priority, rti)
58: register struct assocblk *acb;
59: int priority;
60: register struct RtSAPindication *rti;
61: {
62: int result;
63: PE pe;
64: struct PSAPindication pis;
65: struct PSAPindication *pi = &pis;
66: struct PSAPabort *pa = &pi -> pi_abort;
67:
68: if (!(acb -> acb_flags & ACB_TWA))
69: return rtsaplose (rti, RTS_OPERATION, NULLCP,
70: "mode of association is monologue");
71: if (acb -> acb_flags & ACB_TURN)
72: return rtsaplose (rti, RTS_OPERATION, NULLCP, "turn owned by you");
73:
74: /* begin RTTP APDU */
75: if ((pe = int2prim (priority)) == NULLPE)
76: return rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP);
77: pe -> pe_context = acb -> acb_rtsid;
78: /* end RTTP APDU */
79:
80: PLOGP (rtsap_log,RTS_RTSE__apdus, pe, "RTTPapdu", 0);
81:
82: result = PPTokenRequest (acb -> acb_fd, ST_DAT_TOKEN, &pe, 1, pi);
83:
84: pe_free (pe);
85:
86: if (result == NOTOK) {
87: (void) ps2rtslose (acb, rti, "PPTokenRequest", pa);
88: freeacblk (acb);
89: }
90:
91: return result;
92: }
93:
94: /* */
95:
96: int rt2psgturn (acb, rti)
97: register struct assocblk *acb;
98: register struct RtSAPindication *rti;
99: {
100: struct PSAPindication pis;
101: struct PSAPindication *pi = &pis;
102: struct PSAPabort *pa = &pi -> pi_abort;
103:
104: if (!(acb -> acb_flags & ACB_TWA))
105: return rtsaplose (rti, RTS_OPERATION, NULLCP,
106: "mode of association is monologue");
107: if (!(acb -> acb_flags & ACB_TURN))
108: return rtsaplose (rti, RTS_OPERATION, NULLCP, "turn not owned by you");
109: if (acb -> acb_flags & ACB_ACT)
110: return rtsaplose (rti, RTS_OPERATION, NULLCP, "transfer in progress");
111:
112: if (PGControlRequest (acb -> acb_fd, pi) == NOTOK) {
113: (void) ps2rtslose (acb, rti, "PGControlRequest", pa);
114: freeacblk (acb);
115: return NOTOK;
116: }
117:
118: acb -> acb_flags &= ~(ACB_TURN | ACB_PLEASE);
119:
120: return OK;
121: }
122:
123: /* */
124:
125: int rt2pstrans (acb, data, secs, rti)
126: register struct assocblk *acb;
127: register PE data;
128: int secs;
129: register struct RtSAPindication *rti;
130: {
131: register int cc,
132: size;
133: int result,
134: len;
135: long clock,
136: limit;
137: register char *dp;
138: char *base;
139: PE pe;
140: struct SSAPactid ids;
141: register struct SSAPactid *id = &ids;
142: struct PSAPindication pis;
143: struct PSAPindication *pi = &pis;
144: struct PSAPabort *pa = &pi -> pi_abort;
145: struct RtSAPabort *rta = &rti -> rti_abort;
146:
147: if (!(acb -> acb_flags & ACB_TURN))
148: return rtsaplose (rti, RTS_OPERATION, NULLCP, "turn not owned by you");
149: if (acb -> acb_flags & ACB_ACT)
150: return rtsaplose (rti, RTS_OPERATION, NULLCP, "transfer in progress");
151:
152: if ((pe = int2prim (acb -> acb_actno)) == NULLPE)
153: return rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP);
154: result = pe2ssdu (pe, &base, &len);
155: pe_free (pe);
156: if (result == NOTOK)
157: return rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP);
158: bcopy (base, id -> sd_data, (int) (id -> sd_len = len));
159: free (base);
160: base = NULL;
161:
162: if (pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_OCTS)) {
163: pe -> pe_inline = 1;
164: pe -> pe_context = acb -> acb_rtsid;
165: }
166: else {
167: (void) rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP);
168: goto out;
169: }
170: if (PActStartRequest (acb -> acb_fd, id, NULLPEP, 0, pi) == NOTOK) {
171: (void) ps2rtslose (acb, rti, "PActStartRequest", pa);
172: goto out;
173: }
174:
175: acb -> acb_flags |= ACB_ACT;
176:
177: if (data && pe2ssdu (data, &base, &len) == NOTOK) {
178: (void) rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP);
179: goto out;
180: }
181:
182: result = OK;
183: if (acb -> acb_ckpoint == 0) {
184: if (data == NULLPE) {
185: if ((*acb -> acb_downtrans) (acb -> acb_fd, &base, &len, 0, 0L,
186: 0L, rti) == NOTOK) {
187: bad_trans: ;
188: if (PActDiscRequest (acb -> acb_fd, SP_LOCAL, pi) == NOTOK) {
189: (void) ps2rtslose (acb, rti, "PActDiscRequest", pa);
190: goto out;
191: }
192: goto done;
193: }
194: if (len == 0) {
195: base = NULL;
196: goto done;
197: }
198: }
199:
200: pe -> pe_prim = (PElementData) base, pe -> pe_len = (PElementLen) len;
201:
202: if (PDataRequest (acb -> acb_fd, &pe, 1, pi) == NOTOK) {
203: (void) ps2rtslose (acb, rti, "PDataRequest", pa);
204: goto out;
205: }
206: }
207: else {
208: size = acb -> acb_ckpoint << 10; /* units of 1024 octets */
209: if (acb -> acb_ssdusize >= 0x0100) /* at least 256 octets */
210: size = min (size, acb -> acb_ssdusize);
211: acb -> acb_ssn = acb -> acb_ack = 0L;
212: if (secs != NOTOK) {
213: (void) time (&limit);
214: limit += secs;
215: }
216:
217: if (data == NULLPE) {
218: if ((*acb -> acb_downtrans) (acb -> acb_fd, &base, &len, size,
219: acb -> acb_ssn, acb -> acb_ack,
220: rti) == NOTOK)
221: goto bad_trans;
222: if (len == 0) {
223: base = NULL;
224: goto done;
225: }
226: }
227:
228: dp = base, cc = min (len, size);
229: pe -> pe_prim = (PElementData) dp, pe -> pe_len = (PElementLen) cc;
230: if (PDataRequest (acb -> acb_fd, &pe, 1, pi) == NOTOK) {
231: (void) ps2rtslose (acb, rti, "PDataRequest", pa);
232: goto out;
233: }
234:
235: for (dp += cc, len -= cc;
236: data == NULLPE || len > 0;
237: dp += cc, len -= cc) {
238: if (data == NULLPE && len == 0) {
239: if ((*acb -> acb_downtrans) (acb -> acb_fd, &base, &len, size,
240: acb -> acb_ssn, acb -> acb_ack,
241: rti) == NOTOK)
242: goto bad_trans;
243: if (len == 0) {
244: base = NULL;
245: break;
246: }
247: dp = base;
248: }
249:
250: if (secs != NOTOK) {
251: (void) time (&clock);
252: if (limit < clock) {
253: result = NOTOK;
254: break;
255: }
256: }
257:
258: if (PMinSyncRequest (acb -> acb_fd, SYNC_CONFIRM,
259: &acb -> acb_ssn, NULLPEP, 0, pi) == NOTOK) {
260: (void) ps2rtslose (acb, rti, "PMinSyncRequest", pa);
261: goto out;
262: }
263:
264: if (acb -> acb_ssn - acb -> acb_ack > acb -> acb_window) {
265: do {
266: if (RtWaitRequestAux (acb, NOTOK, 1, rti) == NOTOK) {
267: if (RTS_FATAL (rta -> rta_reason))
268: acb = NULLACB;
269: goto out;
270: }
271: }
272: while (acb -> acb_ssn - acb -> acb_ack > acb -> acb_window);
273:
274: #ifdef notdef
275: /* avoid silly window syndrome */
276: while (acb -> acb_ssn != acb -> acb_ack)
277: if (RtWaitRequestAux (acb, OK, 1, rti) == NOTOK)
278: if (rta -> rta_reason != RTS_TIMER) {
279: if (RTS_FATAL (rta -> rta_reason))
280: acb = NULLACB;
281: goto out;
282: }
283: else
284: break;
285: #endif
286: }
287:
288: cc = min (len, size);
289: pe -> pe_prim = (PElementData) dp, pe -> pe_len = cc;
290: if (PDataRequest (acb -> acb_fd, &pe, 1, pi) == NOTOK) {
291: (void) ps2rtslose (acb, rti, "PDataRequest", pa);
292: goto out;
293: }
294: }
295: }
296: if (data)
297: free (base);
298: base = NULL;
299:
300: done: ;
301: switch (result) {
302: case OK:
303: if (PActEndRequest (acb -> acb_fd, &acb -> acb_ssn, NULLPEP, 0,
304: pi) == NOTOK) {
305: (void) ps2rtslose (acb, rti, "PActEndRequest", pa);
306: goto out;
307: }
308: break;
309:
310: default:
311: acb -> acb_flags |= ACB_TIMER;
312: if (PActDiscRequest (acb -> acb_fd, SP_LOCAL, pi) == NOTOK) {
313: (void) ps2rtslose (acb, rti, "PActDiscRequest", pa);
314: goto out;
315: }
316: break;
317: }
318:
319: while (acb -> acb_flags & ACB_ACT)
320: if (RtWaitRequestAux (acb, NOTOK, 1, rti) == NOTOK) {
321: if (RTS_FATAL (rta -> rta_reason))
322: acb = NULLACB;
323: goto out;
324: }
325:
326: acb -> acb_flags &= ~ACB_TIMER;
327: acb -> acb_actno++;
328:
329: if (pe)
330: pe_free (pe);
331:
332: return result;
333:
334: out: ;
335: if (data && base)
336: free (base);
337: if (pe)
338: pe_free (pe);
339: if (acb)
340: freeacblk (acb);
341:
342: return NOTOK;
343: }
344:
345: /* */
346:
347: int rt2pswait (acb, secs, trans, rti)
348: register struct assocblk *acb;
349: int secs,
350: trans;
351: register struct RtSAPindication *rti;
352: {
353: int result;
354: struct PSAPdata pxs;
355: register struct PSAPdata *px = &pxs;
356: struct PSAPindication pis;
357: register struct PSAPindication *pi = &pis;
358:
359: for (;;) {
360: switch (result = PReadRequest (acb -> acb_fd, px, secs, pi)) {
361: case NOTOK:
362: return doPSabort (acb, &pi -> pi_abort, rti);
363:
364: case OK:
365: if (doPSdata (acb, px, rti) == NOTOK)
366: return NOTOK;
367: continue;
368:
369: case DONE:
370: switch (pi -> pi_type) {
371: case PI_TOKEN:
372: if ((result = doPStoken (acb, &pi -> pi_token, trans,
373: rti)) != OK)
374: return result;
375: continue;
376:
377: case PI_SYNC:
378: if ((result = doPSsync (acb, &pi -> pi_sync, rti)) != OK
379: || trans)
380: return result;
381: continue;
382:
383: case PI_ACTIVITY:
384: if ((result = doPSactivity (acb, &pi -> pi_activity, rti)) != OK
385: || trans)
386: return (result != DONE ? result : OK);
387: continue;
388:
389: case PI_REPORT:
390: if (doPSreport (acb, &pi -> pi_report, rti) == NOTOK)
391: return NOTOK;
392: continue;
393:
394: case PI_FINISH:
395: return doPSfinish (acb, &pi -> pi_finish, rti);
396:
397: default:
398: (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP,
399: "unknown indication (0x%x) from presentation",
400: pi -> pi_type);
401: break;
402: }
403: break;
404:
405: default:
406: (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP,
407: "unexpected return from PReadRequest=%d", result);
408: break;
409: }
410: break;
411: }
412:
413: freeacblk (acb);
414: return NOTOK;
415: }
416:
417: /* define vectors for INDICATION events */
418:
419: #define e(i) (indication ? (i) : NULLIFP)
420:
421:
422: int rt2psasync (acb, indication, rti)
423: register struct assocblk *acb;
424: IFP indication;
425: struct RtSAPindication *rti;
426: {
427: struct PSAPindication pis;
428: struct PSAPindication *pi = &pis;
429: struct PSAPabort *pa = &pi -> pi_abort;
430:
431: if (PSetIndications (acb -> acb_fd, e (psDATAser), e (psTOKENser),
432: e (psSYNCser), e (psACTIVITYser), e (psREPORTser),
433: e (psFINISHser), e (psABORTser), pi) == NOTOK)
434: switch (pa -> pa_reason) {
435: case PC_WAITING:
436: return rtsaplose (rti, RTS_WAITING, NULLCP, NULLCP);
437:
438: default:
439: (void) ps2rtslose (acb, rti, "PSetIndications", pa);
440: freeacblk (acb);
441: return NOTOK;
442: }
443:
444: if (acb -> acb_rtsindication = indication)
445: acb -> acb_flags |= ACB_ASYN;
446: else
447: acb -> acb_flags &= ~ACB_ASYN;
448:
449: return OK;
450: }
451:
452: #undef e
453:
454: /* map association descriptors for select() */
455:
456: int rt2psmask (acb, mask, nfds, rti)
457: register struct assocblk *acb;
458: fd_set *mask;
459: int *nfds;
460: struct RtSAPindication *rti;
461: {
462: struct PSAPindication pis;
463: struct PSAPindication *pi = &pis;
464: struct PSAPabort *pa = &pi -> pi_abort;
465:
466: if (PSelectMask (acb -> acb_fd, mask, nfds, pi) == NOTOK)
467: switch (pa -> pa_reason) {
468: case PC_WAITING:
469: return rtsaplose (rti, RTS_WAITING, NULLCP, NULLCP);
470:
471: default:
472: (void) ps2rtslose (acb, rti, "PSelectMask", pa);
473: freeacblk (acb);
474: return NOTOK;
475: }
476:
477: return OK;
478: }
479:
480: /* protocol-level abort */
481:
482: int rt2pslose (acb, result)
483: register struct assocblk *acb;
484: int result;
485: {
486: PE pe;
487: struct AcSAPindication acis;
488:
489: /* begin RTAB APDU */
490: if ((pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, 22))
491: && set_add (pe, num2prim (result, PE_CLASS_CONT, RTAB_REASON))
492: != NOTOK) {
493: pe -> pe_context = acb -> acb_rtsid;
494:
495: PLOGP (rtsap_log,RTS_RTSE__apdus, pe, "RTABapdu", 0);
496:
497: (void) AcUAbortRequest (acb -> acb_fd, &pe, 1, &acis);
498: pe_free (pe);
499: }
500: /* end RTAB APDU */
501: }
502:
503: /* AcSAP interface */
504:
505: int acs2rtslose (acb, rti, event, aca)
506: register struct assocblk *acb;
507: register struct RtSAPindication *rti;
508: char *event;
509: register struct AcSAPabort *aca;
510: {
511: int reason;
512: char *cp,
513: buffer[BUFSIZ];
514:
515: if (event)
516: SLOG (rtsap_log, LLOG_EXCEPTIONS, NULLCP,
517: (aca -> aca_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event,
518: AcErrString (aca -> aca_reason), aca -> aca_cc, aca -> aca_cc,
519: aca -> aca_data));
520:
521: cp = "";
522: switch (aca -> aca_reason) {
523: case ACS_ADDRESS:
524: reason = RTS_ADDRESS;
525: break;
526:
527: case ACS_REFUSED:
528: reason = RTS_REFUSED;
529: break;
530:
531: case ACS_CONGEST:
532: reason = RTS_CONGEST;
533: break;
534:
535: case ACS_PARAMETER:
536: reason = RTS_PARAMETER;
537: break;
538:
539: case ACS_OPERATION:
540: reason = RTS_OPERATION;
541: break;
542:
543: default:
544: (void) sprintf (cp = buffer, " (%s at association control)",
545: AcErrString (aca -> aca_reason));
546: case ACS_PRESENTATION:
547: reason = RTS_ACS;
548: break;
549: }
550:
551: if (acb) {
552: if (aca -> aca_cc > 0)
553: return rtpktlose (acb, rti, reason, NULLCP, "%*.*s%s",
554: aca -> aca_cc, aca -> aca_cc, aca -> aca_data, cp);
555: else
556: return rtpktlose (acb, rti, reason, NULLCP, "%s", cp);
557: }
558: else
559: if (aca -> aca_cc > 0)
560: return rtsaplose (rti, reason, NULLCP, "%*.*s%s",
561: aca -> aca_cc, aca -> aca_cc, aca -> aca_data, cp);
562: else
563: return rtsaplose (rti, reason, NULLCP, "%s", cp);
564: }
565:
566: /* */
567:
568: int acs2rtsabort (acb, aca, rti)
569: register struct assocblk *acb;
570: register struct AcSAPabort *aca;
571: struct RtSAPindication *rti;
572: {
573: int result;
574: PE pe;
575: struct type_RTS_RTSE__apdus *rtpdu = NULL;
576: struct type_RTS_RTABapdu *prtab;
577:
578: if (aca -> aca_source != ACA_USER) {
579: (void) acs2rtslose (acb, rti, NULLCP, aca);
580: goto out;
581: }
582:
583: if (aca -> aca_ninfo == 0) {
584: (void) rtsaplose (rti, RTS_ABORTED, NULLCP, NULLCP);
585: goto out;
586: }
587:
588: pe = aca -> aca_info[0];
589: /* acsap_abort = ABORT_PERM, acsap_data = NULLPE; */
590: result = decode_RTS_RTSE__apdus (pe, 1, NULLIP, NULLVP, &rtpdu);
591:
592: #ifdef DEBUG
593: if (result != NOTOK && (rtsap_log -> ll_events & LLOG_PDUS))
594: pvpdu (rtsap_log, print_RTS_RTSE__apdus_P, pe, "RTABapdu", 1);
595: #endif
596: if (result != NOTOK) {
597: if (rtpdu -> offset != type_RTS_RTSE__apdus_rtab__apdu) {
598: (void) rtsaplose (rti, RTS_PROTOCOL, "Unexpected PDU");
599: ACAFREE (aca);
600: goto out;
601: }
602: prtab = rtpdu -> un.rtab__apdu;
603:
604: if (prtab->userdataAB != NULLPE)
605: (void) pe_extract (pe, prtab->userdataAB);
606: else
607: pe = NULLPE;
608: }
609: ACAFREE (aca);
610:
611: if (result == NOTOK) {
612: (void) rtsaplose (rti, RTS_PROTOCOL, "%s", PY_pepy);
613: goto out;
614: }
615: if (prtab->abortReason) {
616: result = prtab -> abortReason -> parm;
617: } else {
618: result = ABORT_PERM;
619: }
620: switch (result) {
621: case ABORT_LSP:
622: case ABORT_TMP:
623: result = RTS_REMOTE;
624: break;
625:
626: default:
627: result = RTS_PROTOCOL;
628: break;
629:
630: case ABORT_USER:
631: result = RTS_ABORTED;
632: break;
633: }
634: if (result == RTS_ABORTED) {
635: register struct RtSAPabort *rta = &rti -> rti_abort;
636:
637: rti -> rti_type = RTI_ABORT;
638: bzero ((char *) rta, sizeof *rta);
639:
640: rta -> rta_peer = 1;
641: rta -> rta_reason = RTS_ABORTED;
642: rta -> rta_udata = prtab->userdataAB;
643: prtab->userdataAB = NULLPE;
644: }
645: else {
646: (void) rtsaplose (rti, result, NULLCP, NULLCP);
647: }
648:
649: out: ;
650: if (rtpdu)
651: free_RTS_RTSE__apdus (rtpdu);
652: if (acb) {
653: if (!(acb -> acb_flags & ACB_STICKY))
654: acb -> acb_fd = NOTOK;
655: freeacblk (acb);
656: }
657:
658: return NOTOK;
659: }
660:
661: /* PSAP interface */
662:
663: static int doPSdata (acb, px, rti)
664: register struct assocblk *acb;
665: register struct PSAPdata *px;
666: struct RtSAPindication *rti;
667: {
668: unsigned int i;
669: register char *dp;
670: register PE pe;
671: struct PSAPindication pis;
672: register struct PSAPindication *pi = &pis;
673: register struct PSAPabort *pa = &pi -> pi_abort;
674:
675: pe = NULLPE;
676: if (!(acb -> acb_flags & ACB_ACT)
677: || (acb -> acb_flags & ACB_TURN)
678: || px -> px_type != SX_NORMAL) {
679: (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP,
680: "unexpected data indication (0x%x)", px -> px_type);
681: PXFREE (px);
682: goto out;
683: }
684:
685: pe = px -> px_info[0], px -> px_info[0] = NULLPE;
686: PXFREE (px);
687:
688: if (acb -> acb_uptrans) {
689: int result;
690: register struct qbuf *qb;
691:
692: if ((qb = prim2qb (pe)) == NULL)
693: goto congested;
694: result = (*acb -> acb_uptrans) (acb -> acb_fd, SI_DATA, (caddr_t) qb,
695: rti);
696: qb_free (qb);
697: if (result == NOTOK)
698: goto congested;
699: goto done;
700: }
701:
702: if (pe -> pe_form == PE_FORM_CONS && pe_pullup (pe) == NOTOK)
703: goto congested;
704:
705: if (acb -> acb_len > 0) {
706: i = acb -> acb_len + pe -> pe_len;
707: if (acb -> acb_realbase) {
708: if ((dp = malloc (i)) == NULL) {
709: congested: ;
710: if (PUReportRequest (acb -> acb_fd, SP_LOCAL, NULLPEP, 0, pi)
711: == NOTOK) {
712: (void) ps2rtslose (acb, rti, "PUReportRequest", pa);
713: goto out;
714: }
715: FREEACB (acb);
716: return OK;
717: }
718: bcopy (acb -> acb_base, dp, acb -> acb_len);
719: free (acb -> acb_realbase), acb -> acb_realbase = NULL;
720: }
721: else
722: if ((dp = realloc (acb -> acb_base, i)) == NULL)
723: goto congested;
724: bcopy ((char *) pe -> pe_prim, dp + acb -> acb_len, pe -> pe_len);
725: acb -> acb_base = dp;
726: acb -> acb_len = i;
727: }
728: else {
729: acb -> acb_base = (char *) pe -> pe_prim;
730: acb -> acb_len = pe -> pe_len;
731: pe -> pe_prim = NULLPED, pe -> pe_len = 0;
732: acb -> acb_realbase = pe -> pe_realbase, pe -> pe_realbase = NULLCP;
733: }
734: done: ;
735: pe_free (pe);
736: return OK;
737:
738: out: ;
739: if (pe)
740: pe_free (pe);
741:
742: freeacblk (acb);
743: return NOTOK;
744: }
745:
746: /* */
747:
748: static int doPStoken (acb, pt, trans, rti)
749: register struct assocblk *acb;
750: register struct PSAPtoken *pt;
751: int trans;
752: struct RtSAPindication *rti;
753: {
754: register PE pe;
755: struct PSAPindication pis;
756: register struct PSAPindication *pi = &pis;
757: register struct PSAPabort *pa = &pi -> pi_abort;
758: struct type_RTS_RTSE__apdus *rtpdu;
759: struct type_RTS_RTTPapdu *prttp;
760:
761: if (acb -> acb_flags & ACB_TWA)
762: switch (pt -> pt_type) {
763: case ST_CONTROL:
764: if (acb -> acb_flags & ACB_ACT)
765: break;
766:
767: PTFREE (pt);
768:
769: acb -> acb_owned = pt -> pt_owned;
770: acb -> acb_flags |= ACB_TURN;
771:
772: rti -> rti_type = RTI_TURN;
773: {
774: register struct RtSAPturn *rtu = &rti -> rti_turn;
775:
776: rtu -> rtu_please = 0;
777: }
778: return DONE;
779:
780: case ST_PLEASE:
781: pe = pt -> pt_info[0];
782: if (decode_RTS_RTSE__apdus (pe, 1, NULLIP, NULLVP, &rtpdu) == NOTOK) {
783: (void) pylose ();
784: goto out;
785: }
786:
787: PLOGP (rtsap_log,RTS_RTSE__apdus, pe, "RTTPapdu", 1);
788: if (rtpdu -> offset != type_RTS_RTSE__apdus_rttp__apdu) {
789: (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP,
790: "unexpected PDU");
791: free_RTS_RTSE__apdus (rtpdu);
792: goto out;
793: }
794: prttp = rtpdu -> un.rttp__apdu;
795: PTFREE (pt);
796:
797: if (trans) {
798: if (acb -> acb_downtrans) {
799: if ((*acb -> acb_downtrans) (acb -> acb_fd, NULLVP,
800: /* surely this should be rtsap_priority NULLIP, acsap_priority,*/
801: NULLIP, prttp -> parm,
802: 0L, 0L, rti) == NOTOK
803: && PActIntrRequest (acb -> acb_fd, SP_LOCAL,
804: pi) == NOTOK) {
805: (void) ps2rtslose (acb, rti, "PActIntrRequest",pa);
806: free_RTS_RTSE__apdus (rtpdu);
807: goto out;
808: }
809: }
810: else {
811: acb -> acb_flags |= ACB_PLEASE;
812: acb -> acb_priority = prttp -> parm;
813: }
814: free_RTS_RTSE__apdus (rtpdu);
815: return OK;
816: }
817:
818: rti -> rti_type = RTI_TURN;
819: {
820: register struct RtSAPturn *rtu = &rti -> rti_turn;
821:
822: rtu -> rtu_please = 1;
823: rtu -> rtu_priority = prttp -> parm;
824: }
825: free_RTS_RTSE__apdus (rtpdu);
826: return DONE;
827:
828: default:
829: break;
830: }
831: (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP,
832: "unexpected token indication (0x%x)", pt -> pt_type);
833:
834: out: ;
835: PTFREE (pt);
836: freeacblk (acb);
837:
838: return NOTOK;
839: }
840:
841: /* */
842:
843: static int doPSsync (acb, pn, rti)
844: register struct assocblk *acb;
845: register struct PSAPsync *pn;
846: struct RtSAPindication *rti;
847: {
848: struct PSAPindication pis;
849: register struct PSAPindication *pi = &pis;
850: register struct PSAPabort *pa = &pi -> pi_abort;
851:
852: PNFREE (pn);
853:
854: if (acb -> acb_flags & ACB_ACT)
855: switch (pn -> pn_type) {
856: case SN_MINORIND: /* always confirm it */
857: if (acb -> acb_flags & ACB_TURN)
858: break;
859: if (acb -> acb_uptrans) {
860: if ((*acb -> acb_uptrans) (acb -> acb_fd, SI_SYNC,
861: (caddr_t) pn, rti) == NOTOK) {
862: if (PUReportRequest (acb -> acb_fd, SP_LOCAL,
863: NULLPEP, 0, pi) == NOTOK) {
864: (void) ps2rtslose (acb, rti, "PUReportRequest",pa);
865: goto out;
866: }
867: return OK;
868: }
869: }
870: if (PMinSyncResponse (acb -> acb_fd, pn -> pn_ssn,
871: NULLPEP, 0, pi) == NOTOK) {
872: (void) ps2rtslose (acb, rti, "PMinSyncResponse", pa);
873: goto out;
874: }
875: return OK;
876:
877: case SN_MINORCNF:
878: if (!(acb -> acb_flags & ACB_TURN))
879: break;
880: acb -> acb_ack = pn -> pn_ssn;
881: return OK;
882:
883: default:
884: break;
885: }
886: (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP,
887: "unexpected sync indication (0x%x)", pn -> pn_type);
888:
889: out: ;
890: freeacblk (acb);
891:
892: return NOTOK;
893: }
894:
895: /* */
896:
897: static int doPSactivity (acb, pv, rti)
898: register struct assocblk *acb;
899: register struct PSAPactivity *pv;
900: struct RtSAPindication *rti;
901: {
902: int result;
903: register PE pe;
904: struct PSAPindication pis;
905: register struct PSAPindication *pi = &pis;
906: register struct PSAPabort *pa = &pi -> pi_abort;
907:
908: PVFREE (pv);
909:
910: switch (pv -> pv_type) {
911: case SV_START:
912: if (acb -> acb_flags & (ACB_ACT | ACB_TURN))
913: break;
914: if (acb -> acb_uptrans) {
915: if ((*acb -> acb_uptrans) (acb -> acb_fd, SI_ACTIVITY,
916: (caddr_t) pv, rti) == NOTOK) {
917: if (PUReportRequest (acb -> acb_fd, SP_LOCAL,
918: NULLPEP, 0, pi) == NOTOK) {
919: (void) ps2rtslose (acb, rti, "PUReportRequest", pa);
920: goto out;
921: }
922: return OK;
923: }
924: }
925: acb -> acb_flags |= ACB_ACT;
926: return OK;
927:
928: case SV_RESUME: /* XXX: will support this later */
929: if (acb -> acb_flags & (ACB_ACT | ACB_TURN))
930: break;
931: if (PUReportRequest (acb -> acb_fd, SP_PROCEDURAL, NULLPEP, 0,
932: pi) == NOTOK) {
933: (void) ps2rtslose (acb, rti, "PUReportRequest", pa);
934: goto out;
935: }
936: acb -> acb_flags |= ACB_ACT;
937: return OK;
938:
939: case SV_INTRIND:
940: case SV_DISCIND:
941: if (!(acb -> acb_flags & ACB_ACT)
942: || (acb -> acb_flags & ACB_TURN))
943: break;
944: if (acb -> acb_uptrans)
945: (void) (*acb -> acb_uptrans) (acb -> acb_fd, SI_ACTIVITY,
946: (caddr_t) pv, rti);
947: if ((pv -> pv_type == SV_INTRIND
948: ? PActIntrResponse (acb -> acb_fd, pi)
949: : PActDiscResponse (acb -> acb_fd, pi)) == NOTOK) {
950: (void) ps2rtslose (acb, rti, pv -> pv_type == SV_INTRIND
951: ? "PActIntrResponse" : "PActDiscResponse", pa);
952: goto out;
953: }
954: FREEACB (acb);
955: acb -> acb_flags &= ~ACB_ACT;
956: return OK;
957:
958: case SV_INTRCNF:
959: case SV_DISCCNF:
960: if (!(acb -> acb_flags & ACB_ACT)
961: || !(acb -> acb_flags & ACB_TURN))
962: break;
963: acb -> acb_flags &= ~ACB_ACT;
964: (void) rtsaplose (rti, acb -> acb_flags & ACB_TIMER ? RTS_TIMER
965: : RTS_TRANSFER, NULLCP, NULLCP);
966: return OK;
967:
968: case SV_ENDIND:
969: if (!(acb -> acb_flags & ACB_ACT)
970: || (acb -> acb_flags & ACB_TURN))
971: break;
972: if (acb -> acb_uptrans) {
973: if ((*acb -> acb_uptrans) (acb -> acb_fd, SI_ACTIVITY,
974: (caddr_t) pv, rti) == NOTOK) {
975: if (PUReportRequest (acb -> acb_fd, SP_LOCAL, NULLPEP, 0,
976: pi) == NOTOK) {
977: (void) ps2rtslose (acb, rti, "PUReportRequest", pa);
978: goto out;
979: }
980:
981: return OK;
982: }
983:
984: pe = NULLPE;
985: goto end_it;
986: }
987:
988: if (acb -> acb_base) {
989: if (pe = ssdu2pe (acb -> acb_base, acb -> acb_len,
990: acb -> acb_realbase ? acb -> acb_realbase
991: : acb -> acb_base,
992: &result))
993: acb -> acb_realbase = acb -> acb_base = NULL;
994: }
995: else
996: pe = NULLPE, result = PS_ERR_EOF;
997: FREEACB (acb);
998: if (pe == NULLPE) {
999: if (result != PS_ERR_NMEM) {
1000: (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, "%s",
1001: ps_error (result));
1002: goto out;
1003: }
1004: if (PUReportRequest (acb -> acb_fd, SP_LOCAL, NULLPEP, 0, pi)
1005: == NOTOK) {
1006: (void) ps2rtslose (acb, rti, "PUReportRequest", pa);
1007: goto out;
1008: }
1009: return OK;
1010: }
1011: end_it: ;
1012: if (PActEndResponse (acb -> acb_fd, NULLPEP, 0, pi) == NOTOK) {
1013: (void) ps2rtslose (acb, rti, "PActEndResponse", pa);
1014: if (pe)
1015: pe_free (pe);
1016: goto out;
1017: }
1018: acb -> acb_flags &= ~ACB_ACT;
1019:
1020: rti -> rti_type = RTI_TRANSFER;
1021: {
1022: register struct RtSAPtransfer *rtt = &rti -> rti_transfer;
1023:
1024: rtt -> rtt_data = pe;
1025: }
1026: return DONE;
1027:
1028: case SV_ENDCNF:
1029: if (!(acb -> acb_flags & ACB_ACT)
1030: || !(acb -> acb_flags & ACB_TURN))
1031: break;
1032: acb -> acb_flags &= ~ACB_ACT;
1033: return OK;
1034:
1035: default:
1036: break;
1037: }
1038: (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP,
1039: "unexpected activity indication (0x%x)", pv -> pv_type);
1040:
1041: out: ;
1042: freeacblk (acb);
1043: return NOTOK;
1044: }
1045:
1046: /* */
1047:
1048: static int doPSreport (acb, pp, rti)
1049: register struct assocblk *acb;
1050: register struct PSAPreport *pp;
1051: struct RtSAPindication *rti;
1052: {
1053: struct PSAPindication pis;
1054: register struct PSAPindication *pi = &pis;
1055: register struct PSAPabort *pa = &pi -> pi_abort;
1056:
1057: PPFREE (pp);
1058:
1059: if (!pp -> pp_peer) {
1060: if (!(acb -> acb_flags & ACB_ACT))
1061: goto out2;
1062: if (!(acb -> acb_flags & ACB_TURN))
1063: return OK;
1064:
1065: /* XXX: should try lots of things here, based on how many checkpoints have
1066: been acknowledged, but, for now we'll treate everything as severe... */
1067:
1068: (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP,
1069: "unrecoverable provider-initiated exception report");
1070: }
1071:
1072: if ((acb -> acb_flags & ACB_ACT)
1073: || !(acb -> acb_flags & ACB_TURN)) {
1074: out2: ;
1075: (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP,
1076: "unexpected exception report indication (0x%x)",
1077: pp -> pp_peer);
1078: goto out1;
1079: }
1080:
1081: /* XXX: should try lots of things here, based on pp_reason,
1082: but, for now we'll treat everything as SP_NOREASON... */
1083:
1084: if (acb -> acb_uptrans)
1085: (void) (*acb -> acb_uptrans) (acb -> acb_fd, SI_REPORT,
1086: (caddr_t) pp, rti);
1087: if (PActDiscRequest (acb -> acb_fd, SP_NOREASON, pi) != NOTOK)
1088: return OK;
1089: (void) ps2rtslose (acb, rti, "PActDiscRequest", pa);
1090:
1091: out1: ;
1092: freeacblk (acb);
1093: return NOTOK;
1094: }
1095:
1096: /* */
1097:
1098: static int doPSfinish (acb, pf, rti)
1099: register struct assocblk *acb;
1100: struct PSAPfinish *pf;
1101: struct RtSAPindication *rti;
1102: {
1103: struct AcSAPindication acis;
1104: register struct AcSAPabort *aca = &acis.aci_abort;
1105:
1106: if (((acb -> acb_flags & ACB_INIT) && (acb -> acb_flags & ACB_TWA))
1107: || (acb -> acb_flags & ACB_TURN)) {
1108: (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP,
1109: "association management botched");
1110: PFFREE (pf);
1111: goto out;
1112: }
1113:
1114: if (acb -> acb_flags & ACB_ACT) {
1115: (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP,
1116: "unexpected release indication");
1117: PFFREE (pf);
1118: goto out;
1119: }
1120:
1121: rti -> rti_type = RTI_FINISH;
1122: {
1123: register struct AcSAPfinish *acf = &rti -> rti_finish;
1124:
1125: if (AcFINISHser (acb -> acb_fd, pf, &acis) == NOTOK)
1126: return acs2rtslose (acb, rti, "AcFINISHser", aca);
1127:
1128: *acf = acis.aci_finish; /* struct copy */
1129: }
1130:
1131: return DONE;
1132:
1133: out: ;
1134: freeacblk (acb);
1135: return NOTOK;
1136: }
1137:
1138: /* */
1139:
1140: static int doPSabort (acb, pa, rti)
1141: register struct assocblk *acb;
1142: register struct PSAPabort *pa;
1143: struct RtSAPindication *rti;
1144: {
1145: struct AcSAPindication acis;
1146: register struct AcSAPabort *aca = &acis.aci_abort;
1147:
1148: if (!pa -> pa_peer && pa -> pa_reason == PC_TIMER)
1149: return rtsaplose (rti, RTS_TIMER, NULLCP, NULLCP);
1150:
1151: if (AcABORTser (acb -> acb_fd, pa, &acis) == NOTOK) {
1152: (void) acs2rtslose (acb, rti, "AcABORTser", aca);
1153: if (!(acb -> acb_flags & ACB_STICKY))
1154: acb -> acb_fd = NOTOK;
1155: freeacblk (acb);
1156:
1157: return NOTOK;
1158: }
1159:
1160: return acs2rtsabort (acb, aca, rti);
1161: }
1162:
1163: /* */
1164:
1165: static int psDATAser (sd, px)
1166: int sd;
1167: register struct PSAPdata *px;
1168: {
1169: IFP handler;
1170: register struct assocblk *acb;
1171: struct RtSAPindication rtis;
1172: register struct RtSAPindication *rti = &rtis;
1173:
1174: if ((acb = findacblk (sd)) == NULL)
1175: return;
1176: handler = acb -> acb_rtsindication;
1177:
1178: if (doPSdata (acb, px, rti) != OK)
1179: (*handler) (sd, rti);
1180: }
1181:
1182: /* */
1183:
1184: static int psTOKENser (sd, pt)
1185: int sd;
1186: register struct PSAPtoken *pt;
1187: {
1188: IFP handler;
1189: register struct assocblk *acb;
1190: struct RtSAPindication rtis;
1191: register struct RtSAPindication *rti = &rtis;
1192:
1193: if ((acb = findacblk (sd)) == NULL)
1194: return;
1195: handler = acb -> acb_rtsindication;
1196:
1197: if (doPStoken (acb, pt, 0, rti) != OK)
1198: (*handler) (sd, rti);
1199: }
1200:
1201: /* */
1202:
1203: static int psSYNCser (sd, pn)
1204: int sd;
1205: register struct PSAPsync *pn;
1206: {
1207: IFP handler;
1208: register struct assocblk *acb;
1209: struct RtSAPindication rtis;
1210: register struct RtSAPindication *rti = &rtis;
1211:
1212: if ((acb = findacblk (sd)) == NULL)
1213: return;
1214: handler = acb -> acb_rtsindication;
1215:
1216: if (doPSsync (acb, pn, rti) != OK)
1217: (*handler) (sd, rti);
1218: }
1219:
1220: /* */
1221:
1222: static int psACTIVITYser (sd, pv)
1223: int sd;
1224: register struct PSAPactivity *pv;
1225: {
1226: IFP handler;
1227: register struct assocblk *acb;
1228: struct RtSAPindication rtis;
1229: register struct RtSAPindication *rti = &rtis;
1230:
1231: if ((acb = findacblk (sd)) == NULL)
1232: return;
1233: handler = acb -> acb_rtsindication;
1234:
1235: if (doPSactivity (acb, pv, rti) != OK)
1236: (*handler) (sd, rti);
1237: }
1238:
1239: /* */
1240:
1241: static int psREPORTser (sd, pp)
1242: int sd;
1243: register struct PSAPreport *pp;
1244: {
1245: IFP handler;
1246: register struct assocblk *acb;
1247: struct RtSAPindication rtis;
1248: register struct RtSAPindication *rti = &rtis;
1249:
1250: if ((acb = findacblk (sd)) == NULL)
1251: return;
1252: handler = acb -> acb_rtsindication;
1253:
1254: if (doPSreport (acb, pp, rti) != OK)
1255: (*handler) (sd, rti);
1256: }
1257:
1258: /* */
1259:
1260: static int psFINISHser (sd, pf)
1261: int sd;
1262: struct PSAPfinish *pf;
1263: {
1264: IFP handler;
1265: register struct assocblk *acb;
1266: struct RtSAPindication rtis;
1267: register struct RtSAPindication *rti = &rtis;
1268:
1269: if ((acb = findacblk (sd)) == NULL)
1270: return;
1271: handler = acb -> acb_rtsindication;
1272:
1273: (void) doPSfinish (acb, pf, rti);
1274:
1275: (*handler) (sd, rti);
1276: }
1277:
1278: /* */
1279:
1280: static int psABORTser (sd, pa)
1281: int sd;
1282: register struct PSAPabort *pa;
1283: {
1284: IFP handler;
1285: register struct assocblk *acb;
1286: struct RtSAPindication rtis;
1287: register struct RtSAPindication *rti = &rtis;
1288:
1289: if ((acb = findacblk (sd)) == NULL)
1290: return;
1291: handler = acb -> acb_rtsindication;
1292:
1293: (void) doPSabort (acb, pa, rti);
1294:
1295: (*handler) (sd, rti);
1296: }
1297:
1298: /* */
1299:
1300: int ps2rtslose (acb, rti, event, pa)
1301: register struct assocblk *acb;
1302: register struct RtSAPindication *rti;
1303: char *event;
1304: register struct PSAPabort *pa;
1305: {
1306: int reason;
1307: char *cp,
1308: buffer[BUFSIZ];
1309:
1310: if (event)
1311: SLOG (rtsap_log, LLOG_EXCEPTIONS, NULLCP,
1312: (pa -> pa_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event,
1313: PErrString (pa -> pa_reason), pa -> pa_cc, pa -> pa_cc,
1314: pa -> pa_data));
1315:
1316: cp = "";
1317: switch (pa -> pa_reason) {
1318: case PC_ADDRESS:
1319: reason = RTS_ADDRESS;
1320: break;
1321:
1322: case PC_REFUSED:
1323: reason = RTS_REFUSED;
1324: break;
1325:
1326: case PC_CONGEST:
1327: reason = RTS_CONGEST;
1328: break;
1329:
1330: default:
1331: (void) sprintf (cp = buffer, " (%s at presentation)",
1332: PErrString (pa -> pa_reason));
1333: case PC_SESSION:
1334: reason = RTS_PRESENTATION;
1335: break;
1336: }
1337:
1338: if (pa -> pa_cc > 0)
1339: return rtpktlose (acb, rti, reason, NULLCP, "%*.*s%s",
1340: pa -> pa_cc, pa -> pa_cc, pa -> pa_data, cp);
1341: else
1342: return rtpktlose (acb, rti, reason, NULLCP, "%s", *cp ? cp + 1 : cp);
1343: }
1344:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.