|
|
1.1 root 1: /* psaprespond.c - PPM: responder */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/psap2/RCS/psaprespond.c,v 7.2 90/07/01 21:05:08 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/psap2/RCS/psaprespond.c,v 7.2 90/07/01 21:05:08 mrose Exp $
9: *
10: *
11: * $Log: psaprespond.c,v $
12: * Revision 7.2 90/07/01 21:05:08 mrose
13: * pepsy
14: *
15: * Revision 7.1 89/11/24 16:22:17 mrose
16: * sync
17: *
18: * Revision 7.0 89/11/23 22:14:30 mrose
19: * Release 6.0
20: *
21: */
22:
23: /*
24: * NOTICE
25: *
26: * Acquisition, use, and distribution of this module and related
27: * materials are subject to the restrictions of a license agreement.
28: * Consult the Preface in the User's Manual for the full terms of
29: * this agreement.
30: *
31: */
32:
33:
34: /* LINTLIBRARY */
35:
36: #include <stdio.h>
37: #include "PS-types.h"
38: #include "ppkt.h"
39: #include "tailor.h"
40:
41: /* P-CONNECT.INDICATION */
42:
43: int PInit (vecp, vec, ps, pi)
44: int vecp;
45: char **vec;
46: struct PSAPstart *ps;
47: struct PSAPindication *pi;
48: {
49: int i,
50: len,
51: result,
52: result2;
53: char *base;
54: register struct psapblk *pb;
55: PE pe;
56: struct SSAPref ref;
57: struct SSAPstart sss;
58: register struct SSAPstart *ss = &sss;
59: struct SSAPindication sis;
60: register struct SSAPindication *si = &sis;
61: register struct SSAPabort *sa = &si -> si_abort;
62: struct type_PS_CP__type *cp;
63: register struct element_PS_0 *cp_normal;
64: register struct type_PS_CPR__type *cpr;
65:
66: isodetailor (NULLCP, 0);
67:
68: missingP (vec);
69: missingP (ps);
70: missingP (pi);
71:
72: if ((pb = newpblk ()) == NULL)
73: return psaplose (pi, PC_CONGEST, NULLCP, "out of memory");
74:
75: cp = NULL, cpr = NULL;
76:
77: if (SInit (vecp, vec, ss, si) == NOTOK) {
78: (void) ss2pslose (pb, pi, "SInit", sa);
79: goto out1;
80: }
81:
82: pb -> pb_fd = ss -> ss_sd;
83:
84: if ((pe = ssdu2pe (ss -> ss_data, ss -> ss_cc, NULLCP, &result))
85: == NULLPE) {
86: if (result == PS_ERR_NMEM)
87: goto congest;
88:
89: (void) ppktlose (pb, pi, PC_PROTOCOL, PPDU_CP, NULLCP, "%s",
90: ps_error (result));
91: goto out1;
92: }
93:
94: SSFREE (ss);
95:
96: pb -> pb_srequirements = ss -> ss_requirements;
97:
98: pb -> pb_ssdusize = ss -> ss_ssdusize;
99:
100: bzero ((char *) ps, sizeof *ps);
101:
102: if (decode_PS_CP__type (pe, 1, NULLIP, NULLVP, &cp) == NOTOK) {
103: (void) ppktlose (pb, pi, PC_UNRECOGNIZED, PPDU_CP, NULLCP, "%s",
104: PY_pepy);
105: goto out1;
106: }
107:
108: PLOGP (psap2_log,PS_CP__type, pe, "CP-type", 1);
109:
110: if (cp -> mode -> parm != int_PS_Mode__selector_normal__mode) {
111: (void) ppktlose (pb, pi, PC_INVALID, PPDU_CP, NULLCP,
112: "X.410-mode not supported");
113: goto out1;
114: }
115: cp_normal = cp -> normal__mode;
116:
117: ps -> ps_sd = pb -> pb_fd;
118:
119: ps -> ps_connect = ss -> ss_connect; /* struct copy */
120:
121: ps -> ps_calling.pa_addr = ss -> ss_calling;/* struct copy */
122: if (cp_normal -> calling) {
123: if ((base = qb2str (cp_normal -> calling)) == NULLCP)
124: goto congest;
125: if ((len = cp_normal -> calling -> qb_len) >
126: sizeof ps -> ps_calling.pa_selector)
127: len = sizeof ps -> ps_calling.pa_selector;
128: bcopy (base, ps -> ps_calling.pa_selector,
129: ps -> ps_calling.pa_selectlen = len);
130: free (base);
131: }
132: ps -> ps_called.pa_addr = ss -> ss_called; /* struct copy */
133: if (cp_normal -> called) {
134: if ((base = qb2str (cp_normal -> called)) == NULLCP)
135: goto congest;
136: if ((len = cp_normal -> called -> qb_len) >
137: sizeof ps -> ps_called.pa_selector)
138: len = sizeof ps -> ps_called.pa_selector;
139: bcopy (base, ps -> ps_called.pa_selector,
140: ps -> ps_called.pa_selectlen = len);
141: free (base);
142: }
143:
144: if ((pb -> pb_asn = ode2oid (DFLT_ASN)) == NULLOID) {
145: (void) ppktlose (pb, pi, PC_ABSTRACT, PPDU_CP, NULLCP, "%s: unknown",
146: DFLT_ASN);
147: goto out1;
148: }
149: if ((pb -> pb_asn = oid_cpy (pb -> pb_asn)) == NULLOID)
150: goto congest;
151: if ((pb -> pb_atn = ode2oid (DFLT_ATN)) == NULLOID) {
152: (void) ppktlose (pb, pi, PC_TRANSFER, PPDU_CP, NULLCP, "%s: unknown",
153: DFLT_ATN);
154: goto out1;
155: }
156: if ((pb -> pb_atn = oid_cpy (pb -> pb_atn)) == NULLOID)
157: goto congest;
158: if ((pb -> pb_ber = oid_cpy (pb -> pb_atn)) == NULLOID)
159: goto congest;
160:
161: {
162: register struct PSAPcontext *pp,
163: *qp;
164: register struct type_PS_Definition__list *lp;
165:
166: i = 0;
167: for (lp = cp_normal -> context__list,
168: pp = ps -> ps_ctxlist.pc_ctx,
169: qp = pb -> pb_contexts;
170: lp;
171: lp = lp -> next, pp++, qp++, i++) {
172: register struct element_PS_6 *pctx = lp -> element_PS_5;
173: register struct element_PS_7 *atn;
174:
175: pp -> pc_id = qp -> pc_id = pctx -> identifier;
176:
177: pp -> pc_result = PC_ACCEPT;
178: pp -> pc_asn = pctx -> abstract__syntax;
179: pctx -> abstract__syntax = NULLOID;
180: if ((qp -> pc_asn = oid_cpy (pp -> pc_asn)) == NULLOID)
181: goto congest;
182:
183: for (atn = pctx -> transfer__syntax__list; atn; atn = atn -> next)
184: if (atn_is_ok (pb, atn -> Transfer__syntax__name)) {
185: qp -> pc_atn = atn -> Transfer__syntax__name;
186: atn -> Transfer__syntax__name = NULLOID;
187: break;
188: }
189: if (atn == NULL)
190: pp -> pc_result = PC_TRANSFER;
191: pp -> pc_atn = NULLOID;
192:
193: qp -> pc_result = pp -> pc_result;
194: }
195:
196: ps -> ps_ctxlist.pc_nctx = pb -> pb_ncontext = i;
197: }
198:
199: if (ppdu2info (pb, pi, cp_normal -> user__data, ps -> ps_info,
200: &ps -> ps_ninfo, PPDU_CP) == NOTOK)
201: goto out1;
202:
203: ps -> ps_defctxresult = PC_ACCEPT;
204: if (cp_normal -> default__context) {
205: oid_free (pb -> pb_asn);
206: pb -> pb_asn = cp_normal -> default__context -> abstract__syntax;
207: cp_normal -> default__context -> abstract__syntax = NULLOID;
208: if ((ps -> ps_defctx = oid_cpy (pb -> pb_asn)) == NULLOID)
209: goto congest;
210:
211: oid_free (pb -> pb_atn);
212: pb -> pb_atn = cp_normal -> default__context -> transfer__syntax;
213: cp_normal -> default__context -> transfer__syntax = NULLOID;
214: if (!atn_is_ok (pb, pb -> pb_atn))
215: ps -> ps_defctxresult = PC_TRANSFER;
216:
217: pb -> pb_flags |= PB_DFLT;
218: }
219: pb -> pb_result = ps -> ps_defctxresult;
220:
221: if (cp_normal -> presentation__fu) {
222: register struct pair *pp;
223:
224: if (!(pb -> pb_srequirements & SR_TYPEDATA)) {
225: (void) bit_off (cp_normal -> presentation__fu,
226: bit_PS_Presentation__requirements_context__management);
227: (void) bit_off (cp_normal -> presentation__fu,
228: bit_PS_Presentation__requirements_restoration);
229: }
230:
231: for (pp = preq_pairs; pp -> p_mask; pp++)
232: if (bit_test (cp_normal -> presentation__fu, pp -> p_bitno) == 1)
233: pb -> pb_prequirements |= pp -> p_mask;
234: }
235: ps -> ps_prequirements = (pb -> pb_prequirements &= PR_MYREQUIRE);
236:
237: if (cp_normal -> session__fu) {
238: register struct pair *pp;
239:
240: for (pp = sreq_pairs; pp -> p_mask; pp++)
241: if (bit_test (cp_normal -> session__fu, pp -> p_bitno) == 1)
242: pb -> pb_urequirements |= pp -> p_mask;
243: }
244: else
245: pb -> pb_urequirements = pb -> pb_srequirements;
246: ps -> ps_srequirements = (pb -> pb_urequirements & pb -> pb_srequirements);
247:
248: ps -> ps_settings = ss -> ss_settings;
249: ps -> ps_isn = ss -> ss_isn;
250:
251: ps -> ps_ssdusize = ss -> ss_ssdusize;
252:
253: ps -> ps_qos = ss -> ss_qos; /* struct copy */
254:
255: pe_free (pe);
256: free_PS_CP__type (cp);
257:
258: return OK;
259:
260: congest: ;
261: result = SC_CONGESTION;
262: (void) psaplose (pi, result2 = PC_CONGEST, NULLCP, NULLCP);
263:
264: if (pe) {
265: pe_free (pe);
266: pe = NULLPE;
267: }
268:
269: if (cpr = (struct type_PS_CPR__type *) calloc (1, sizeof *cpr)) {
270: if (cp
271: && cp -> mode
272: && cp -> mode -> parm ==
273: int_PS_Mode__selector_x410__1984__mode) {
274: cpr -> offset = type_PS_CPR__type_x410__mode;
275: if (pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, PE_CONS_SET)) {
276: cpr -> un.x410__mode = pe;
277: (void) set_add (pe, num2prim (result2 != PC_CONGEST ? 0 : 3,
278: PE_CLASS_CONT, 0));
279: }
280: }
281: else {
282: register struct element_PS_2 *cpr_normal;
283:
284: cpr -> offset = type_PS_CPR__type_normal__mode;
285: if (cpr_normal = (struct element_PS_2 *)
286: calloc (1, sizeof *cpr_normal)) {
287: cpr -> un.normal__mode = cpr_normal;
288: cpr_normal -> optionals |= opt_PS_element_PS_2_reason;
289: cpr_normal -> reason = result2 - PC_PROV_BASE;
290: }
291: }
292: }
293:
294: if (encode_PS_CPR__type (&pe, 1, 0, NULLCP, cpr) != NOTOK) {
295: PLOGP (psap2_log,PS_CPR__type, pe, "CPR-type", 0);
296:
297: if (pe)
298: (void) pe2ssdu (pe, &base, &len);
299: }
300: else
301: base = NULL, len = 0;
302:
303: bzero ((char *) &ref, sizeof ref);
304: (void) SConnResponse (ss -> ss_sd, &ref, NULLSA, result, 0, 0,
305: SERIAL_NONE, base, len, si);
306: if (base)
307: free (base);
308: (void) psaplose (pi, result2, NULLCP, NULLCP);
309:
310: out1: ;
311: SSFREE (ss);
312: if (pe)
313: pe_free (pe);
314: if (cp)
315: free_PS_CP__type (cp);
316: if (cpr)
317: free_PS_CPR__type (cpr);
318:
319: freepblk (pb);
320:
321: return NOTOK;
322: }
323:
324: /* P-CONNECT.RESPONSE */
325:
326: int PConnResponse (sd, status, responding, ctxlist, defctxresult,
327: prequirements, srequirements, isn, settings, ref, data, ndata, pi)
328: int sd;
329: struct PSAPaddr *responding;
330: int status,
331: prequirements,
332: srequirements,
333: settings,
334: ndata;
335: long isn;
336: struct PSAPctxlist *ctxlist;
337: int defctxresult;
338: struct SSAPref *ref;
339: PE *data;
340: struct PSAPindication *pi;
341: {
342: int i,
343: len,
344: result,
345: result2;
346: char *base;
347: PE pe;
348: register struct psapblk *pb;
349: struct SSAPindication sis;
350: register struct SSAPindication *si = &sis;
351: register struct SSAPabort *sa = &si -> si_abort;
352: struct type_PS_CPA__type *cpa;
353: register struct element_PS_1 *cpa_normal;
354: struct type_PS_CPR__type *cpr;
355: register struct element_PS_2 *cpr_normal;
356:
357: if ((pb = findpblk (sd)) == NULL || (pb -> pb_flags & PB_CONN))
358: return psaplose (pi, PC_PARAMETER, NULLCP,
359: "invalid presentation descriptor");
360: #ifdef notdef
361: missingP (responding);
362: #endif
363: switch (status) {
364: case PC_ACCEPT:
365: case PC_REJECTED:
366: break;
367:
368: default:
369: return psaplose (pi, PC_PARAMETER, NULLCP,
370: "bad value for status parameter");
371: }
372:
373: if (ctxlist) {
374: register struct PSAPcontext *pp,
375: *qp;
376:
377: if (ctxlist -> pc_nctx != pb -> pb_ncontext)
378: return psaplose (pi, PC_PARAMETER, NULLCP,
379: "proposed/resulting presentation contexts mismatch");
380:
381: i = pb -> pb_ncontext - 1;
382: for (pp = ctxlist -> pc_ctx, qp = pb -> pb_contexts;
383: i >= 0;
384: i--, pp++, qp++) {
385: if (pp -> pc_id != qp -> pc_id)
386: return psaplose (pi, PC_PARAMETER, NULLCP,
387: "bad context id %d at offset %d (wanted %d)",
388: pp -> pc_id, pp - ctxlist -> pc_ctx, qp -> pc_id);
389: switch (pp -> pc_result) {
390: case PC_ACCEPT:
391: case PC_REJECTED:
392: if (qp -> pc_result != PC_ACCEPT)
393: return psaplose (pi, PC_PARAMETER, NULLCP,
394: "invalid result %d for context id %d",
395: pp -> pc_result, pp -> pc_id);
396: qp -> pc_result = pp -> pc_result;
397: break;
398:
399: default:
400: if (qp -> pc_result != pp -> pc_result)
401: return psaplose (pi, PC_PARAMETER, NULLCP,
402: "invalid result %d for context id %d",
403: pp -> pc_result, pp -> pc_id);
404: break;
405: }
406: }
407: }
408:
409: switch (defctxresult) {
410: case PC_ACCEPT:
411: case PC_REJECTED:
412: if (pb -> pb_result != PC_ACCEPT)
413: return psaplose (pi, PC_PARAMETER, NULLCP,
414: "invalid result %d for default context name",
415: defctxresult);
416: if ((pb -> pb_result = defctxresult) == PC_REJECTED
417: && status != PC_REJECTED)
418: return psaplose (pi, PC_PARAMETER, NULLCP,
419: "default context rejected implies connection rejected");
420: break;
421:
422: default:
423: if (pb -> pb_result != defctxresult)
424: return psaplose (pi, PC_PARAMETER, NULLCP,
425: "invalid result %d for default context name",
426: defctxresult);
427: break;
428: }
429: if (prequirements & ~pb -> pb_prequirements)
430: return psaplose (pi, PC_PARAMETER, NULLCP,
431: "presentation requirements not available");
432: if (srequirements & ~pb -> pb_urequirements)
433: return psaplose (pi, PC_PARAMETER, NULLCP,
434: "session requirements not available");
435:
436: /* let session provider catch errors in remainder of session parameters */
437:
438: toomuchP (data, ndata, NPDATA, "initial");
439: missingP (pi);
440:
441: base = NULLCP;
442: pe = NULLPE;
443: cpa = NULL, cpr = NULL;
444:
445: switch (status) {
446: case PC_ACCEPT:
447: if ((cpa = (struct type_PS_CPA__type *) calloc (1, sizeof *cpa))
448: == NULL) {
449: no_mem: ;
450: (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory");
451: goto out2;
452: }
453: if ((cpa -> mode = (struct type_PS_Mode__selector *)
454: malloc (sizeof *cpa -> mode)) == NULL)
455: goto no_mem;
456: cpa -> mode -> parm = int_PS_Mode__selector_normal__mode;
457: if ((cpa_normal = (struct element_PS_1 *)
458: calloc (1, sizeof *cpa_normal)) == NULL)
459: goto no_mem;
460: cpa -> normal__mode = cpa_normal;
461: break;
462:
463: case PC_REJECTED:
464: if ((cpr = (struct type_PS_CPR__type *) calloc (1, sizeof *cpr))
465: == NULL)
466: goto no_mem;
467: cpr -> offset = type_PS_CPR__type_normal__mode;
468: if ((cpr_normal = (struct element_PS_2 *)
469: calloc (1, sizeof *cpr_normal)) == NULL)
470: goto no_mem;
471: cpr -> un.normal__mode = cpr_normal;
472: break;
473: }
474:
475: {
476: register struct qbuf *qb = NULL;
477:
478: if (responding
479: && responding -> pa_selectlen > 0
480: && (qb = str2qb (responding -> pa_selector,
481: responding -> pa_selectlen, 1)) == NULL)
482: goto no_mem;
483:
484: if (status == PC_ACCEPT)
485: cpa_normal -> responding = qb;
486: else
487: cpr_normal -> responding = qb;
488: }
489:
490: if (pb -> pb_ncontext > 0) {
491: register struct PSAPcontext *qp;
492: register struct type_PS_Definition__result__list *cd,
493: **cp;
494:
495: if (status == PC_ACCEPT)
496: cp = &cpa_normal -> context__list;
497: else
498: cp = &cpr_normal -> context__list;
499:
500: i = pb -> pb_ncontext - 1;
501: for (qp = pb -> pb_contexts; i >= 0; i--, qp++) {
502: switch (qp -> pc_result) {
503: case PC_ACCEPT:
504: result = int_PS_result_acceptance;
505: break;
506:
507: case PC_REJECTED:
508: result = int_PS_result_user__rejection;
509: break;
510:
511: case PC_ABSTRACT:
512: result = int_PS_result_provider__rejection;
513: result2 = int_PS_provider__reason_abstract__syntax__not__supported;
514: break;
515:
516: case PC_TRANSFER:
517: result = int_PS_result_provider__rejection;
518: result2 = int_PS_provider__reason_proposed__transfer__syntaxes__not__supported;
519: break;
520:
521: case PC_CONGEST:
522: result = int_PS_result_provider__rejection;
523: result2 = int_PS_provider__reason_local__limit__on__DCS__exceeded;
524: break;
525:
526: case PC_NOTSPECIFIED:
527: default:
528: result = int_PS_result_provider__rejection;
529: result2 = int_PS_provider__reason_reason__not__specified;
530: break;
531: }
532:
533: if ((cd = (struct type_PS_Definition__result__list *)
534: calloc (1, sizeof *cd)) == NULL)
535: goto no_mem;
536: *cp = cd;
537: cp = &cd -> next;
538: if ((cd -> element_PS_12 = (struct element_PS_13 *)
539: calloc (1, sizeof (struct element_PS_13))) == NULL)
540: goto no_mem;
541: cd -> element_PS_12 -> result = result;
542: switch (qp -> pc_result) {
543: case PC_ACCEPT:
544: if ((cd -> element_PS_12 -> transfer__syntax =
545: oid_cpy (qp -> pc_atn)) == NULLOID)
546: goto no_mem;
547: break;
548:
549: case PC_REJECTED:
550: break;
551:
552: default:
553: cd -> element_PS_12 -> optionals |=
554: opt_PS_element_PS_13_provider__reason;
555: cd -> element_PS_12 -> provider__reason = result2;
556: break;
557: }
558: }
559:
560: i = pb -> pb_ncontext - 1;
561: for (qp = pb -> pb_contexts + i; i >= 0; i--, qp--)
562: if (qp -> pc_result != PC_ACCEPT) {
563: register struct PSAPcontext *qqp;
564:
565: qqp = pb -> pb_contexts + --pb -> pb_ncontext;
566: if (qp -> pc_asn)
567: oid_free (qp -> pc_asn);
568: if (qp -> pc_atn)
569: oid_free (qp -> pc_atn);
570: if (qp != qqp)
571: *qp = *qqp; /* struct copy */
572: }
573: }
574:
575: pb -> pb_srequirements &= srequirements;
576: if (pb -> pb_prequirements & PR_MANAGEMENT)
577: pb -> pb_srequirements |= SR_TYPEDATA;
578: if (status == PC_ACCEPT) {
579: if ((pb -> pb_prequirements &= prequirements) != PR_MYREQUIRE) {
580: register struct pair *pp;
581:
582: if ((cpa_normal -> presentation__fu =
583: prim2bit (pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM,
584: PE_PRIM_BITS))) == NULL)
585: goto no_mem;
586:
587: for (pp = preq_pairs; pp -> p_mask; pp++)
588: if ((pb -> pb_prequirements & pp -> p_mask)
589: && bit_on (cpa_normal -> presentation__fu, pp -> p_bitno)
590: == NOTOK)
591: goto no_mem;
592:
593: if (bit2prim (cpa_normal -> presentation__fu) == NULLPE)
594: goto no_mem;
595: }
596:
597: if ((pb -> pb_urequirements &= srequirements)
598: != pb -> pb_srequirements) {
599: register struct pair *pp;
600:
601: if ((cpa_normal -> session__fu = prim2bit (pe_alloc (PE_CLASS_UNIV,
602: PE_FORM_PRIM,
603: PE_PRIM_BITS)))
604: == NULL)
605: goto no_mem;
606:
607: for (pp = sreq_pairs; pp -> p_mask; pp++)
608: if ((pb -> pb_urequirements & pp -> p_mask)
609: && bit_on (cpa_normal -> session__fu, pp -> p_bitno)
610: == NOTOK)
611: goto no_mem;
612:
613: if (bit2prim (cpa_normal -> session__fu) == NULLPE)
614: goto no_mem;
615: }
616:
617: status = SC_ACCEPT;
618: }
619: else {
620: if (pb -> pb_flags & PB_DFLT) {
621: if ((cpr_normal -> default__context =
622: (struct type_PS_Context__result *)
623: malloc (sizeof *cpr_normal -> default__context))
624: == NULL)
625: goto no_mem;
626: switch (defctxresult) {
627: case PC_ACCEPT:
628: default:
629: result = int_PS_Result_acceptance;
630: break;
631:
632: case PC_REJECTED:
633: result = int_PS_Result_user__rejection;
634: break;
635:
636: case PC_NOTSPECIFIED:
637: result = int_PS_Result_provider__rejection;
638: break;
639: }
640: cpr_normal -> default__context -> parm = result;
641: }
642:
643: status = SC_REJECTED;
644: }
645:
646: if (data && ndata > 0) {
647: struct type_PS_User__data *info;
648:
649: if ((info = info2ppdu (pb, pi, data, ndata, status == SC_ACCEPT
650: ? PPDU_CPA : PPDU_CPR)) == NULL)
651: goto out2;
652:
653: if (status == SC_ACCEPT)
654: cpa_normal -> user__data = info;
655: else
656: cpr_normal -> user__data = info;
657: }
658:
659: if (status == SC_ACCEPT) {
660: result = encode_PS_CPA__type (&pe, 1, 0, NULLCP, cpa);
661:
662: #ifdef DEBUG
663: if (result == OK && (psap2_log -> ll_events & LLOG_PDUS))
664: pvpdu (psap2_log, print_PS_CPA__type_P, pe, "CPA-type", 0);
665: #endif
666: }
667: else {
668: result = encode_PS_CPR__type (&pe, 1, 0, NULLCP, cpr);
669:
670: #ifdef DEBUG
671: if (result == OK && (psap2_log -> ll_events & LLOG_PDUS))
672: pvpdu (psap2_log, print_PS_CPR__type_P, pe, "CPR-type", 0);
673: #endif
674: }
675:
676: if (result == NOTOK) {
677: (void) psaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s",
678: PY_pepy);
679: goto out2;
680: }
681:
682: if (pe2ssdu (pe, &base, &len) == NOTOK)
683: goto no_mem;
684:
685: if (status == SC_ACCEPT) {
686: free_PS_CPA__type (cpa);
687: cpa = NULL;
688: }
689: else {
690: free_PS_CPR__type (cpr);
691: cpr = NULL;
692: }
693:
694: pe_free (pe);
695: pe = NULL;
696:
697: if (SConnResponse (pb -> pb_fd, ref, responding ? &responding -> pa_addr
698: : NULLSA, status, pb -> pb_srequirements, settings, isn, base,
699: len, si) == NOTOK)
700: if (SC_FATAL (sa -> sa_reason)) {
701: (void) ss2pslose (pb, pi, "SConnResponse", sa);
702: goto out2;
703: }
704: else { /* assume SS-user parameter error */
705: result = ss2pslose (NULLPB, pi, "SConnResponse", sa);
706: goto out1;
707: }
708:
709: if (status == SC_ACCEPT) {
710: pb -> pb_flags |= PB_CONN;
711: #define dotoken(requires,shift,bit,type) \
712: { \
713: if (pb -> pb_srequirements & requires) \
714: switch (settings & (ST_MASK << shift)) { \
715: case ST_INIT_VALUE << shift: \
716: pb -> pb_owned |= bit; \
717: pb -> pb_avail |= bit; \
718: break; \
719: \
720: case ST_RESP_VALUE << shift: \
721: pb -> pb_avail |= bit; \
722: break; \
723: } \
724: }
725: dotokens ();
726: #undef dotoken
727: }
728: else {
729: pb -> pb_fd = NOTOK;
730: freepblk (pb);
731: }
732: result = OK;
733: goto out1;
734:
735: out2: ;
736: result = NOTOK;
737: if (cpr) {
738: free_PS_CPR__type (cpr);
739: cpr = NULL;
740: }
741:
742: if (cpr = (struct type_PS_CPR__type *) calloc (1, sizeof *cpr)) {
743: cpr -> offset = type_PS_CPR__type_normal__mode;
744: if (cpr_normal = (struct element_PS_2 *)
745: calloc (1, sizeof *cpr_normal)) {
746: cpr -> un.normal__mode = cpr_normal;
747: cpr_normal -> optionals |= opt_PS_element_PS_2_reason;
748: cpr_normal -> reason = int_PS_reason_temporary__congestion;
749: }
750: }
751:
752: if (encode_PS_CPR__type (&pe, 1, 0, NULLCP, cpr) != NOTOK) {
753: PLOGP (psap2_log,PS_CPR__type, pe, "CPR-type", 0);
754:
755: if (pe)
756: (void) pe2ssdu (pe, &base, &len);
757: }
758: else
759: base = NULL, len = 0;
760:
761: (void) SConnResponse (pb -> pb_fd, ref, NULLSA, result, 0, 0,
762: SERIAL_NONE, base, len, si);
763:
764: if (base)
765: free (base);
766: (void) pe2ssdu (pe, &base, &len);
767: (void) SConnResponse (pb -> pb_fd, ref, NULLSA, SC_CONGESTION, 0, 0,
768: SERIAL_NONE, base, len, si);
769:
770: freepblk (pb);
771:
772: out1: ;
773: if (base)
774: free (base);
775:
776: if (pe)
777: pe_free (pe);
778: if (cpa)
779: free_PS_CPA__type (cpa);
780: if (cpr)
781: free_PS_CPR__type (cpr);
782:
783: return result;
784: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.