|
|
1.1 root 1: /* psapinitiate.c - PPM: initiator */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/psap2-lpp/RCS/psapinitiate.c,v 7.3 90/07/09 14:45:05 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/psap2-lpp/RCS/psapinitiate.c,v 7.3 90/07/09 14:45:05 mrose Exp $
9: *
10: * Contributed by The Wollongong Group, Inc.
11: *
12: *
13: * $Log: psapinitiate.c,v $
14: * Revision 7.3 90/07/09 14:45:05 mrose
15: * sync
16: *
17: * Revision 7.2 90/07/01 21:05:24 mrose
18: * pepsy
19: *
20: * Revision 7.1 89/12/01 10:51:43 mrose
21: * touch-up
22: *
23: * Revision 7.0 89/11/23 22:15:53 mrose
24: * Release 6.0
25: *
26: */
27:
28: /*
29: * NOTICE
30: *
31: * Acquisition, use, and distribution of this module and related
32: * materials are subject to the restrictions of a license agreement.
33: * Consult the Preface in the User's Manual for the full terms of
34: * this agreement.
35: *
36: */
37:
38:
39: /* LINTLIBRARY */
40:
41: #include <stdio.h>
42: #include <signal.h>
43: #define LPP
44: #include "PS-types.h"
45: #include "ppkt.h"
46: #include "tailor.h"
47:
48: /* P-(ASYN-)CONNECT.REQUEST */
49:
50: #ifndef notdef
51: /* ARGSUSED */
52: #endif
53:
54: int PAsynConnRequest (calling, called, ctxlist, defctxname, prequirements,
55: srequirements, isn, settings, ref, data, ndata, qos, pc, pi, async)
56: struct PSAPaddr *calling,
57: *called;
58: int prequirements,
59: srequirements,
60: settings,
61: ndata,
62: async;
63: long isn;
64: struct PSAPctxlist *ctxlist;
65: OID defctxname;
66: struct SSAPref *ref;
67: PE *data;
68: struct QOStype *qos;
69: struct PSAPconnect *pc;
70: struct PSAPindication *pi;
71: {
72: SBV smask;
73: int result;
74:
75: isodetailor (NULLCP, 0);
76:
77: #ifdef notdef
78: missingP (calling);
79: #endif
80: missingP (called);
81: if (ctxlist == NULL || ctxlist -> pc_nctx != NPCTX_PS)
82: return psaplose (pi, PC_PARAMETER, NULLCP,
83: "exactly %d proposed presentation contexts supported",
84: NPCTX_PS);
85: #ifdef notdef
86: if (defctxname)
87: return psaplose (pi, PC_PARAMETER, NULLCP,
88: "default context name not allowed");
89: #endif
90: if (prequirements != PR_KERNEL)
91: return psaplose (pi, PC_PARAMETER, NULLCP,
92: "presentation requirements settings not supported");
93:
94: if (srequirements != SR_DUPLEX)
95: return psaplose (pi, PC_PARAMETER, NULLCP,
96: "session requirements settings not supported");
97: if (isn != SERIAL_NONE)
98: return psaplose (pi, PC_PARAMETER, NULLCP,
99: "initial serial number not permitted");
100: if (settings != 0) /* not really an accurate test... */
101: return psaplose (pi, PC_PARAMETER, NULLCP,
102: "initial token settings not permitted");
103: missingP (ref);
104: if (ref -> sr_ulen > SREF_USER_SIZE
105: || ref -> sr_ulen <= 2
106: || ref -> sr_clen > SREF_COMM_SIZE
107: || ref -> sr_clen <= 2
108: || ref -> sr_alen > SREF_ADDT_SIZE
109: || ref -> sr_alen == 1
110: || ref -> sr_vlen > 0)
111: return psaplose (pi, PC_PARAMETER, NULLCP, "bad format for reference");
112: if (data == NULL || ndata <= 0 || data[0] == NULLPE || ndata > NPDATA_PS)
113: return psaplose (pi, PC_PARAMETER, NULLCP, "bad initial user data");
114: if (data[0] -> pe_context != PCI_ACSE)
115: return psaplose (pi, PC_PARAMETER, NULLCP,
116: "wrong context for initial user data");
117: missingP (pc);
118: missingP (pi);
119:
120: smask = sigioblock ();
121:
122: result = PConnRequestAux (calling, called, ctxlist, ref, data[0], qos,
123: pc, pi, async);
124:
125: (void) sigiomask (smask);
126:
127: return result;
128: }
129:
130: /* */
131:
132: static int PConnRequestAux (calling, called, ctxlist, ref, data, qos, pc, pi,
133: async)
134: struct PSAPaddr *calling,
135: *called;
136: struct PSAPctxlist *ctxlist;
137: struct SSAPref *ref;
138: PE data;
139: struct QOStype *qos;
140: struct PSAPconnect *pc;
141: struct PSAPindication *pi;
142: int async;
143: {
144: int result;
145: OID asn;
146: register struct psapblk *pb;
147: register struct type_PS_ConnectRequest__PDU *pdu;
148: register struct type_PS_SessionConnectionIdentifier *pref;
149:
150: if ((pb = newpblk ()) == NULL)
151: return psaplose (pi, PC_CONGEST, NULLCP, "out of memory");
152:
153: if ((pref = (struct type_PS_SessionConnectionIdentifier *)
154: malloc (sizeof *pref)) == NULL) {
155: (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory");
156: goto out1;
157: }
158: pb -> pb_reference = pref;
159: pdu = NULL;
160: if ((pref -> callingSSUserReference = str2qb (ref -> sr_udata + 2,
161: (int) ref -> sr_ulen - 2, 1))
162: == NULL
163: || (pref -> commonReference = str2qb (ref -> sr_cdata + 2,
164: (int) ref -> sr_clen - 2, 1))
165: == NULL) {
166: no_mem: ;
167: (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory");
168: goto out2;
169: }
170: if (ref -> sr_alen > 0) {
171: if ((pref -> additionalReferenceInformation
172: = str2qb (ref -> sr_adata + 2,
173: (int) ref -> sr_alen - 2, 1))
174: == NULL)
175: goto no_mem;
176: }
177: else
178: pref -> additionalReferenceInformation = NULL;
179:
180: if ((pb -> pb_ber = ode2oid (DFLT_ATN)) == NULLOID) {
181: (void) psaplose (pi, PC_ABSTRACT, NULLCP, "%s: unknown", DFLT_ATN);
182: goto out2;
183: }
184: if ((pb -> pb_ber = oid_cpy (pb -> pb_ber)) == NULLOID)
185: goto no_mem;
186:
187: asn = NULLOID;
188: {
189: register int i;
190: register struct PSAPcontext *pp,
191: *qp;
192:
193: i = ctxlist -> pc_nctx - 1;
194: for (pp = ctxlist -> pc_ctx, qp = pb -> pb_contexts;
195: i >= 0;
196: i--, pp++, qp++) {
197: switch (qp -> pc_id = pp -> pc_id) {
198: case PCI_ROSE:
199: asn = pp -> pc_asn; /* and fall */
200: case PCI_ACSE:
201: break;
202:
203: default:
204: (void) psaplose (pi, PC_PARAMETER, NULLCP,
205: "illegal value for PCI (%d)",
206: pp -> pc_id);
207: goto out2;
208: }
209:
210: if (pp -> pc_asn == NULLOID) {
211: (void) psaplose (pi, PC_PARAMETER, NULLCP,
212: "no abstract syntax name given for context %d",
213: pp -> pc_id);
214: goto out2;
215: }
216:
217: if (pp -> pc_atn && !atn_is_ok (pb, pp -> pc_atn)) {
218: (void) psaplose (pi, PC_TRANSFER, NULLCP,
219: "unknown transfer syntax given for context %d",
220: pp -> pc_id);
221: goto out2;
222: }
223:
224: qp -> pc_result = PC_ACCEPT;
225:
226: pb -> pb_ncontext++;
227: }
228: }
229: if (asn == NULLOID) {
230: (void) psaplose (pi, PC_PARAMETER, NULLCP, "PCI for SASE not present");
231: goto out2;
232: }
233:
234: if ((pdu = (struct type_PS_ConnectRequest__PDU *) malloc (sizeof *pdu))
235: == NULL)
236: goto no_mem;
237:
238: pdu -> version = int_PS_version_version__1;
239: pdu -> reference = pref;
240: if (calling && calling -> pa_selectlen > 0) {
241: if ((pdu -> calling = str2qb (calling -> pa_selector,
242: calling -> pa_selectlen, 1)) == NULL)
243: goto no_mem;
244: }
245: else
246: pdu -> calling = NULL;
247:
248: if (called -> pa_selectlen > 0) {
249: if ((pdu -> called = str2qb (called -> pa_selector,
250: called -> pa_selectlen, 1)) == NULL)
251: goto no_mem;
252: }
253: else
254: pdu -> called = NULL;
255:
256: if ((pdu -> asn = oid_cpy (asn)) == NULLOID)
257: goto no_mem;
258:
259: pdu -> user__data = data;
260:
261: pb -> pb_retry = NULLPE;
262: result = encode_PS_ConnectRequest__PDU (&pb -> pb_retry, 1, 0, NULLCP,
263: pdu);
264:
265: pdu -> reference = NULL;
266: pdu -> user__data = NULLPE;
267: free_PS_ConnectRequest__PDU (pdu);
268: pdu = NULL;
269:
270: if (result == NOTOK) {
271: (void) psaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s",
272: PY_pepy);
273: goto out1;
274: }
275:
276: if ((result = PConnRequestAux2 (pb, calling ? &calling -> pa_addr.sa_addr
277: : NULLTA,
278: &called -> pa_addr.sa_addr, qos,
279: pi, async)) == NOTOK)
280: goto out1;
281:
282: if (async && result == OK) {
283: pc -> pc_sd = pb -> pb_fd;
284: return result;
285: }
286: if ((result = PAsynRetryAux (pb, pc, pi)) == DONE && !async)
287: result = OK;
288: return result;
289:
290: out2: ;
291: if (pdu) {
292: pdu -> reference = NULL;
293: pdu -> user__data = NULLPE;
294: free_PS_ConnectRequest__PDU (pdu);
295: }
296:
297: out1: ;
298: freepblk (pb);
299:
300: return NOTOK;
301: }
302:
303: /* */
304:
305: #define QOS_RELIABLE_DFLT HIGH_QUALITY
306:
307:
308: int tcpopen (), udpopen ();
309:
310: static struct nsapent {
311: int ns_reliability;
312: int ns_tset;
313:
314: IFP ns_open;
315: } nsaps[] = {
316: HIGH_QUALITY, NA_TSET_TCP, tcpopen,
317: LOW_QUALITY, NA_TSET_UDP, udpopen,
318:
319: NULL
320: };
321:
322:
323: static int PConnRequestAux2 (pb, calling, called, qos, pi, async)
324: struct psapblk *pb;
325: struct TSAPaddr *calling,
326: *called;
327: struct QOStype *qos;
328: struct PSAPindication *pi;
329: int async;
330: {
331: int reliability,
332: result;
333: register int n = called -> ta_naddr - 1;
334: register struct NSAPaddr *na = called -> ta_addrs;
335:
336: reliability = qos ? qos -> qos_reliability : QOS_RELIABLE_DFLT;
337:
338: for (; n >= 0; na++, n--) {
339: register int l;
340: register struct NSAPaddr *la;
341: register struct nsapent *ns;
342:
343: if (na -> na_stack != NA_TCP)
344: continue;
345:
346: if (na -> na_tset == 0)
347: na -> na_tset = NA_TSET_TCP;
348:
349: for (ns = nsaps; ns -> ns_open; ns++)
350: if (ns -> ns_reliability == reliability
351: && (ns -> ns_tset & na -> na_tset))
352: break;
353: if (!ns -> ns_open)
354: continue;
355:
356: if (calling) {
357: for (l = calling -> ta_naddr - 1, la = calling -> ta_addrs;
358: l >= 0;
359: la++, l--) {
360: if (la -> na_stack != NA_TCP)
361: continue;
362: if (ns -> ns_tset & la -> na_tset)
363: break;
364: }
365: if (l < 0)
366: la = NULLNA;
367: }
368: else
369: la = NULLNA;
370:
371: if ((result = (*ns -> ns_open) (pb, la, na, pi, async)) != NOTOK)
372: break;
373: }
374:
375: {
376: register struct TSAPaddr *ta = &pb -> pb_responding.pa_addr.sa_addr;
377:
378: ta -> ta_addrs[0] = *na; /* struct copy */
379: ta -> ta_naddr = 1;
380: }
381:
382: return (pb -> pb_fd != NOTOK ? result : NOTOK);
383: }
384:
385: /* P-ASYN-RETRY.REQUEST (pseudo) */
386:
387: int PAsynRetryRequest (sd, pc, pi)
388: int sd;
389: struct PSAPconnect *pc;
390: struct PSAPindication *pi;
391: {
392: SBV smask;
393: int result;
394: register struct psapblk *pb;
395:
396: missingP (pc);
397: missingP (pi);
398:
399: smask = sigioblock ();
400:
401: if ((pb = findpblk (sd)) == NULL) {
402: (void) sigiomask (smask);
403: return psaplose (pi, PC_PARAMETER, NULLCP,
404: "invalid presentation descriptor");
405: }
406: if (pb -> pb_flags & PB_CONN) {
407: (void) sigiomask (smask);
408: return psaplose (pi, PC_OPERATION, NULLCP,
409: "presentation descriptor connected");
410: }
411:
412: switch (result = (*pb -> pb_retryfnx) (pb, pi)) {
413: case NOTOK:
414: pb -> pb_fd = NOTOK;
415: freepblk (pb);
416: break;
417:
418: case OK:
419: break;
420:
421: case DONE:
422: result = PAsynRetryAux (pb, pc, pi);
423: break;
424: }
425:
426: (void) sigiomask (smask);
427:
428: return result;
429: }
430:
431: /* */
432:
433: static int PAsynRetryAux (pb, pc, pi)
434: register struct psapblk *pb;
435: struct PSAPconnect *pc;
436: struct PSAPindication *pi;
437: {
438: int result;
439: PE pe;
440: struct type_PS_PDUs *pdu;
441:
442: pdu = NULL;
443: result = decode_PS_PDUs (pb -> pb_response, 1, NULLIP, NULLVP, &pdu);
444:
445: #ifdef DEBUG
446: if (result == OK && (psap2_log -> ll_events & LLOG_PDUS))
447: pvpdu (psap2_log, print_PS_PDUs_P, pb -> pb_response, "PDU", 1);
448: #endif
449:
450: if (pb -> pb_retry) {
451: pe_free (pb -> pb_retry);
452: pb -> pb_retry = NULLPE;
453: }
454:
455: pe_free (pb -> pb_response);
456: pb -> pb_response = NULL;
457:
458: if (result == NOTOK) {
459: (void) ppktlose (pb, pi, PC_UNRECOGNIZED, NULLRF, NULLCP,
460: "error decoding PDU: %s", PY_pepy);
461: goto out;
462: }
463:
464: bzero ((char *) pc, sizeof *pc);
465:
466: switch (pdu -> offset) {
467: case type_PS_PDUs_connectResponse:
468: {
469: register struct type_PS_ConnectResponse__PDU *cr =
470: pdu -> un.connectResponse;
471:
472: if (pb -> pb_reliability == LOW_QUALITY
473: && refcmp (pb -> pb_reference, cr -> reference)) {
474: result = ppktlose (pb, pi, PC_SESSION, cr -> reference,
475: NULLCP, "reference mismatch");
476: goto out;
477: }
478:
479: if (cr -> reason == NULL) {
480: pb -> pb_flags |= PB_CONN;
481:
482: pc -> pc_sd = pb -> pb_fd;
483: pc -> pc_result = PC_ACCEPT;
484: pc -> pc_qos.qos_reliability = pb -> pb_reliability;
485: pc -> pc_qos.qos_sversion = 2;
486: }
487: else {
488: pc -> pc_sd = NOTOK;
489: pc -> pc_result = cr -> reason -> parm;
490: }
491:
492: pdu2sel (pb -> pb_responding.pa_selector,
493: &pb -> pb_responding.pa_selectlen,
494: sizeof pb -> pb_responding.pa_selector,
495: cr -> responding);
496: pc -> pc_responding = pb -> pb_responding; /* struct copy */
497:
498: pc -> pc_defctxresult = pb -> pb_result = PC_ACCEPT;
499: {
500: register int i;
501: register struct PSAPcontext *pp,
502: *qp;
503:
504: i = pb -> pb_ncontext;
505: for (pp = pb -> pb_contexts, qp = pc -> pc_ctxlist.pc_ctx;
506: i >= 0;
507: i--, pp++, qp++) {
508: qp -> pc_id = pp -> pc_id;
509: qp -> pc_asn = qp -> pc_atn = NULLOID;
510: qp -> pc_result = PC_ACCEPT;
511: }
512: pc -> pc_ctxlist.pc_nctx = pb -> pb_ncontext;
513: }
514:
515: pc -> pc_prequirements = PR_KERNEL;
516: pc -> pc_srequirements = SR_DUPLEX;
517:
518: pc -> pc_isn = SERIAL_NONE;
519:
520: pc -> pc_connect = *pdu2ref (pb -> pb_reference); /* struct copy */
521:
522: pe = cr -> user__data, cr -> user__data = NULLPE;
523: if (pc -> pc_info[0] = pe) {
524: pe -> pe_context = PCI_ACSE;
525: pc -> pc_ninfo = 1;
526: }
527:
528: free_PS_PDUs (pdu);
529:
530: return DONE;
531: }
532:
533: case type_PS_PDUs_abort:
534: {
535: register struct PSAPabort *pa = &pi -> pi_abort;
536: register struct type_PS_Abort__PDU *ab = pdu -> un.abort;
537:
538: if (pb -> pb_reliability == LOW_QUALITY
539: && refcmp (pb -> pb_reference, ab -> reference)) {
540: result = psaplose (pi, PC_SESSION, NULLCP,
541: "reference mismatch");
542: goto out;
543: }
544:
545: if (ab -> reason) {
546: switch (ab -> reason -> parm) {
547: case int_PS_Abort__reason_reason__not__specified:
548: default:
549: result = PC_NOTSPECIFIED;
550: break;
551:
552: case int_PS_Abort__reason_unrecognized__ppdu:
553: case int_PS_Abort__reason_unexpected__ppdu:
554: case int_PS_Abort__reason_unrecognized__ppdu__parameter:
555: result = PC_UNRECOGNIZED
556: + (ab -> reason -> parm
557: - int_PS_Abort__reason_unrecognized__ppdu);
558: break;
559:
560: case int_PS_Abort__reason_invalid__ppdu__parameter:
561: result = PC_INVALID;
562: break;
563:
564: case int_PS_Abort__reason_reference__mismatch:
565: result = PC_SESSION;
566: break;
567: }
568: result = psaplose (pi, result, NULLCP, NULLCP);
569: goto out;
570: }
571: pe = ab -> user__data, ab -> user__data = NULLPE;
572:
573: pi -> pi_type = PI_ABORT;
574: bzero ((char *) pa, sizeof *pa);
575:
576: pa -> pa_peer = 1;
577: pa -> pa_reason = PC_ABORTED;
578: if (pa -> pa_info[0] = pe) {
579: pe -> pe_context = PCI_ACSE;
580: pa -> pa_ninfo = 1;
581: }
582:
583: pc -> pc_sd = NOTOK;
584: pc -> pc_result = PC_ABORTED;
585:
586: result = DONE;
587: }
588: break;
589:
590: default:
591: /* this works 'cause the "reference" is always the FIRST element */
592: result = ppktlose (pb, pi, PC_SESSION,
593: pdu -> un.connectResponse -> reference, NULLCP,
594: "unexpected PDU %d", pdu -> offset);
595: break;
596: }
597:
598: out: ;
599: if (pdu)
600: free_PS_PDUs (pdu);
601: freepblk (pb);
602:
603: return result;
604: }
605:
606: /* P-ASYN-NEXT.REQUEST (pseudo) */
607:
608: /* ARGSUSED */
609:
610: int PAsynNextRequest (sd, pc, pi)
611: int sd;
612: struct PSAPconnect *pc;
613: struct PSAPindication *pi;
614: {
615: return psaplose (pi, PC_OPERATION, NULLCP,
616: "operation not supported with lightweight presentation");
617: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.