|
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 p
Length: 20352 (0x4f80) Types: TextFile Names: »psaprespond.c«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« └─⟦d3ac74d73⟧ └─⟦this⟧ »isode-5.0/psap2/psaprespond.c«
/* psaprespond.c - PPM: responder */ #ifndef lint static char *rcsid = "$Header: /f/osi/psap2/RCS/psaprespond.c,v 6.0 89/03/18 23:40:04 mrose Rel $"; #endif /* * $Header: /f/osi/psap2/RCS/psaprespond.c,v 6.0 89/03/18 23:40:04 mrose Rel $ * * * $Log: psaprespond.c,v $ * Revision 6.0 89/03/18 23:40:04 mrose * Release 5.0 * */ /* * 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 "PS-types.h" #include "ppkt.h" #include "tailor.h" /* \f P-CONNECT.INDICATION */ int PInit (vecp, vec, ps, pi) int vecp; char **vec; struct PSAPstart *ps; struct PSAPindication *pi; { int i, len, result, result2; char *base; register struct psapblk *pb; PE pe; struct SSAPref ref; struct SSAPstart sss; register struct SSAPstart *ss = &sss; struct SSAPindication sis; register struct SSAPindication *si = &sis; register struct SSAPabort *sa = &si -> si_abort; struct type_PS_CP__type *cp; register struct element_PS_0 *cp_normal; register struct type_PS_CPR__type *cpr; isodetailor (NULLCP, 0); missingP (vec); missingP (ps); missingP (pi); if ((pb = newpblk ()) == NULL) return psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); cp = NULL, cpr = NULL; if (SInit (vecp, vec, ss, si) == NOTOK) { (void) ss2pslose (pb, pi, "SInit", sa); goto out1; } pb -> pb_fd = ss -> ss_sd; if ((pe = ssdu2pe (ss -> ss_data, ss -> ss_cc, NULLCP, &result)) == NULLPE) { if (result == PS_ERR_NMEM) goto congest; (void) ppktlose (pb, pi, PC_PROTOCOL, PPDU_CP, NULLCP, "%s", ps_error (result)); goto out1; } SSFREE (ss); pb -> pb_srequirements = ss -> ss_requirements; pb -> pb_ssdusize = ss -> ss_ssdusize; bzero ((char *) ps, sizeof *ps); if (decode_PS_CP__type (pe, 1, NULLIP, NULLVP, &cp) == NOTOK) { (void) ppktlose (pb, pi, PC_UNRECOGNIZED, PPDU_CP, "%s", PY_pepy); goto out1; } PLOG (psap2_log, print_PS_CP__type, pe, "CP-type", 1); if (cp -> mode -> parm != int_PS_Mode__selector_normal__mode) { (void) ppktlose (pb, pi, PC_INVALID, PPDU_CP, NULLCP, "X.410-mode not supported"); goto out1; } cp_normal = cp -> normal__mode; ps -> ps_sd = pb -> pb_fd; ps -> ps_connect = ss -> ss_connect; /* struct copy */ ps -> ps_calling.pa_addr = ss -> ss_calling;/* struct copy */ if (cp_normal -> calling) { if ((base = qb2str (cp_normal -> calling)) == NULLCP) goto congest; if ((len = cp_normal -> calling -> qb_len) > sizeof ps -> ps_calling.pa_selector) len = sizeof ps -> ps_calling.pa_selector; bcopy (base, ps -> ps_calling.pa_selector, ps -> ps_calling.pa_selectlen = len); free (base); } ps -> ps_called.pa_addr = ss -> ss_called; /* struct copy */ if (cp_normal -> called) { if ((base = qb2str (cp_normal -> called)) == NULLCP) goto congest; if ((len = cp_normal -> called -> qb_len) > sizeof ps -> ps_called.pa_selector) len = sizeof ps -> ps_called.pa_selector; bcopy (base, ps -> ps_called.pa_selector, ps -> ps_called.pa_selectlen = len); free (base); } if ((pb -> pb_asn = ode2oid (DFLT_ASN)) == NULLOID) { (void) ppktlose (pb, pi, PC_ABSTRACT, PPDU_CP, NULLCP, "%s: unknown", DFLT_ASN); goto out1; } if ((pb -> pb_asn = oid_cpy (pb -> pb_asn)) == NULLOID) goto congest; if ((pb -> pb_atn = ode2oid (DFLT_ATN)) == NULLOID) { (void) ppktlose (pb, pi, PC_TRANSFER, PPDU_CP, NULLCP, "%s: unknown", DFLT_ATN); goto out1; } if ((pb -> pb_atn = oid_cpy (pb -> pb_atn)) == NULLOID) goto congest; if ((pb -> pb_ber = oid_cpy (pb -> pb_atn)) == NULLOID) goto congest; { register struct PSAPcontext *pp, *qp; register struct type_PS_Definition__list *lp; i = 0; for (lp = cp_normal -> context__list, pp = ps -> ps_ctxlist.pc_ctx, qp = pb -> pb_contexts; lp; lp = lp -> next, pp++, qp++, i++) { register struct element_PS_6 *pctx = lp -> element_PS_5; register struct element_PS_7 *atn; pp -> pc_id = qp -> pc_id = pctx -> identifier; pp -> pc_result = PC_ACCEPT; pp -> pc_asn = pctx -> abstract__syntax; pctx -> abstract__syntax = NULLOID; if ((qp -> pc_asn = oid_cpy (pp -> pc_asn)) == NULLOID) goto congest; for (atn = pctx -> transfer__syntax__list; atn; atn = atn -> next) if (atn_is_ok (pb, atn -> Transfer__syntax__name)) { qp -> pc_atn = atn -> Transfer__syntax__name; atn -> Transfer__syntax__name = NULLOID; break; } if (atn == NULL) pp -> pc_result = PC_TRANSFER; pp -> pc_atn = NULLOID; qp -> pc_result = pp -> pc_result; } ps -> ps_ctxlist.pc_nctx = pb -> pb_ncontext = i; } if (ppdu2info (pb, pi, cp_normal -> user__data, ps -> ps_info, &ps -> ps_ninfo, PPDU_CP) == NOTOK) goto out1; ps -> ps_defctxresult = PC_ACCEPT; if (cp_normal -> default__context) { oid_free (pb -> pb_asn); pb -> pb_asn = cp_normal -> default__context -> abstract__syntax; cp_normal -> default__context -> abstract__syntax = NULLOID; if ((ps -> ps_defctx = oid_cpy (pb -> pb_asn)) == NULLOID) goto congest; oid_free (pb -> pb_atn); pb -> pb_atn = cp_normal -> default__context -> transfer__syntax; cp_normal -> default__context -> transfer__syntax = NULLOID; if (!atn_is_ok (pb, pb -> pb_atn)) ps -> ps_defctxresult = PC_TRANSFER; pb -> pb_flags |= PB_DFLT; } pb -> pb_result = ps -> ps_defctxresult; if (cp_normal -> presentation__fu) { register struct pair *pp; if (!(pb -> pb_srequirements & SR_TYPEDATA)) { (void) bit_off (cp_normal -> presentation__fu, bit_PS_Presentation__requirements_context__management); (void) bit_off (cp_normal -> presentation__fu, bit_PS_Presentation__requirements_restoration); } for (pp = preq_pairs; pp -> p_mask; pp++) if (bit_test (cp_normal -> presentation__fu, pp -> p_bitno) == 1) pb -> pb_prequirements |= pp -> p_mask; } ps -> ps_prequirements = (pb -> pb_prequirements &= PR_MYREQUIRE); if (cp_normal -> session__fu) { register struct pair *pp; for (pp = sreq_pairs; pp -> p_mask; pp++) if (bit_test (cp_normal -> session__fu, pp -> p_bitno) == 1) pb -> pb_urequirements |= pp -> p_mask; } else pb -> pb_urequirements = pb -> pb_srequirements; ps -> ps_srequirements = (pb -> pb_urequirements & pb -> pb_srequirements); ps -> ps_settings = ss -> ss_settings; ps -> ps_isn = ss -> ss_isn; ps -> ps_ssdusize = ss -> ss_ssdusize; ps -> ps_qos = ss -> ss_qos; /* struct copy */ pe_free (pe); free_PS_CP__type (cp); return OK; congest: ; result = SC_CONGESTION; (void) psaplose (pi, result2 = PC_CONGEST, NULLCP, NULLCP); if (pe) { pe_free (pe); pe = NULLPE; } if (cpr = (struct type_PS_CPR__type *) calloc (1, sizeof *cpr)) { if (cp && cp -> mode && cp -> mode -> parm == int_PS_Mode__selector_x410__1984__mode) { cpr -> offset = type_PS_CPR__type_x410__mode; if (pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, PE_CONS_SET)) { cpr -> un.x410__mode = pe; (void) set_add (pe, num2prim (result2 != PC_CONGEST ? 0 : 3, PE_CLASS_CONT, 0)); } } else { register struct element_PS_2 *cpr_normal; cpr -> offset = type_PS_CPR__type_normal__mode; if (cpr_normal = (struct element_PS_2 *) calloc (1, sizeof *cpr_normal)) { cpr -> un.normal__mode = cpr_normal; cpr_normal -> optionals |= opt_PS_element_PS_2_reason; cpr_normal -> reason = result2 - PC_PROV_BASE; } } } if (encode_PS_CPR__type (&pe, 1, 0, NULLCP, cpr) != NOTOK) { PLOG (psap2_log, print_PS_CPR__type, pe, "CPR-type", 0); if (pe) (void) pe2ssdu (pe, &base, &len); } else base = NULL, len = 0; bzero ((char *) &ref, sizeof ref); (void) SConnResponse (ss -> ss_sd, &ref, NULLSA, result, 0, 0, SERIAL_NONE, base, len, si); if (base) free (base); (void) psaplose (pi, result2, NULLCP, NULLCP); out1: ; SSFREE (ss); if (pe) pe_free (pe); if (cp) free_PS_CP__type (cp); if (cpr) free_PS_CPR__type (cpr); freepblk (pb); return NOTOK; } /* \f P-CONNECT.RESPONSE */ int PConnResponse (sd, status, responding, ctxlist, defctxresult, prequirements, srequirements, isn, settings, ref, data, ndata, pi) int sd; struct PSAPaddr *responding; int status, prequirements, srequirements, settings, ndata; long isn; struct PSAPctxlist *ctxlist; int defctxresult; struct SSAPref *ref; PE *data; struct PSAPindication *pi; { int i, len, result, result2; char *base; PE pe; register struct psapblk *pb; struct SSAPindication sis; register struct SSAPindication *si = &sis; register struct SSAPabort *sa = &si -> si_abort; struct type_PS_CPA__type *cpa; register struct element_PS_1 *cpa_normal; struct type_PS_CPR__type *cpr; register struct element_PS_2 *cpr_normal; if ((pb = findpblk (sd)) == NULL || (pb -> pb_flags & PB_CONN)) return psaplose (pi, PC_PARAMETER, NULLCP, "invalid presentation descriptor"); #ifdef notdef missingP (responding); #endif switch (status) { case PC_ACCEPT: case PC_REJECTED: break; default: return psaplose (pi, PC_PARAMETER, NULLCP, "bad value for status parameter"); } if (ctxlist) { register struct PSAPcontext *pp, *qp; if (ctxlist -> pc_nctx != pb -> pb_ncontext) return psaplose (pi, PC_PARAMETER, NULLCP, "proposed/resulting presentation contexts mismatch"); i = pb -> pb_ncontext - 1; for (pp = ctxlist -> pc_ctx, qp = pb -> pb_contexts; i >= 0; i--, pp++, qp++) { if (pp -> pc_id != qp -> pc_id) return psaplose (pi, PC_PARAMETER, NULLCP, "bad context id %d at offset %d (wanted %d)", pp -> pc_id, pp - ctxlist -> pc_ctx, qp -> pc_id); switch (pp -> pc_result) { case PC_ACCEPT: case PC_REJECTED: if (qp -> pc_result != PC_ACCEPT) return psaplose (pi, PC_PARAMETER, NULLCP, "invalid result %d for context id %d", pp -> pc_result, pp -> pc_id); qp -> pc_result = pp -> pc_result; break; default: if (qp -> pc_result != pp -> pc_result) return psaplose (pi, PC_PARAMETER, NULLCP, "invalid result %d for context id %d", pp -> pc_result, pp -> pc_id); break; } } } switch (defctxresult) { case PC_ACCEPT: case PC_REJECTED: if (pb -> pb_result != PC_ACCEPT) return psaplose (pi, PC_PARAMETER, NULLCP, "invalid result %d for default context name", defctxresult); if ((pb -> pb_result = defctxresult) == PC_REJECTED && status != PC_REJECTED) return psaplose (pi, PC_PARAMETER, NULLCP, "default context rejected implies connection rejected"); break; default: if (pb -> pb_result != defctxresult) return psaplose (pi, PC_PARAMETER, NULLCP, "invalid result %d for default context name", defctxresult); break; } if (prequirements & ~pb -> pb_prequirements) return psaplose (pi, PC_PARAMETER, NULLCP, "presentation requirements not available"); if (srequirements & ~pb -> pb_urequirements) return psaplose (pi, PC_PARAMETER, NULLCP, "session requirements not available"); /* let session provider catch errors in remainder of session parameters */ toomuchP (data, ndata, NPDATA, "initial"); missingP (pi); base = NULLCP; pe = NULLPE; cpa = NULL, cpr = NULL; switch (status) { case PC_ACCEPT: if ((cpa = (struct type_PS_CPA__type *) calloc (1, sizeof *cpa)) == NULL) { no_mem: ; (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); goto out2; } if ((cpa -> mode = (struct type_PS_Mode__selector *) malloc (sizeof *cpa -> mode)) == NULL) goto no_mem; cpa -> mode -> parm = int_PS_Mode__selector_normal__mode; if ((cpa_normal = (struct element_PS_1 *) calloc (1, sizeof *cpa_normal)) == NULL) goto no_mem; cpa -> normal__mode = cpa_normal; break; case PC_REJECTED: if ((cpr = (struct type_PS_CPR__type *) calloc (1, sizeof *cpr)) == NULL) goto no_mem; cpr -> offset = type_PS_CPR__type_normal__mode; if ((cpr_normal = (struct element_PS_2 *) calloc (1, sizeof *cpr_normal)) == NULL) goto no_mem; cpr -> un.normal__mode = cpr_normal; break; } { register struct qbuf *qb = NULL; if (responding && responding -> pa_selectlen > 0 && (qb = str2qb (responding -> pa_selector, responding -> pa_selectlen, 1)) == NULL) goto no_mem; if (status == PC_ACCEPT) cpa_normal -> responding = qb; else cpr_normal -> responding = qb; } if (pb -> pb_ncontext > 0) { register struct PSAPcontext *qp; register struct type_PS_Definition__result__list *cd, **cp; if (status == PC_ACCEPT) cp = &cpa_normal -> context__list; else cp = &cpr_normal -> context__list; i = pb -> pb_ncontext - 1; for (qp = pb -> pb_contexts; i >= 0; i--, qp++) { switch (qp -> pc_result) { case PC_ACCEPT: result = int_PS_result_acceptance; break; case PC_REJECTED: result = int_PS_result_user__rejection; break; case PC_ABSTRACT: result = int_PS_result_provider__rejection; result2 = int_PS_provider__reason_abstract__syntax__not__supported; break; case PC_TRANSFER: result = int_PS_result_provider__rejection; result2 = int_PS_provider__reason_proposed__transfer__syntaxes__not__supported; break; case PC_CONGEST: result = int_PS_result_provider__rejection; result2 = int_PS_provider__reason_local__limit__on__DCS__exceeded; break; case PC_NOTSPECIFIED: default: result = int_PS_result_provider__rejection; result2 = int_PS_provider__reason_reason__not__specified; break; } if ((cd = (struct type_PS_Definition__result__list *) calloc (1, sizeof *cd)) == NULL) goto no_mem; *cp = cd; cp = &cd -> next; if ((cd -> element_PS_12 = (struct element_PS_13 *) calloc (1, sizeof (struct element_PS_13))) == NULL) goto no_mem; cd -> element_PS_12 -> result = result; switch (qp -> pc_result) { case PC_ACCEPT: if ((cd -> element_PS_12 -> transfer__syntax = oid_cpy (qp -> pc_atn)) == NULLOID) goto no_mem; break; case PC_REJECTED: break; default: cd -> element_PS_12 -> optionals |= opt_PS_element_PS_13_provider__reason; cd -> element_PS_12 -> provider__reason = result2; break; } } i = pb -> pb_ncontext - 1; for (qp = pb -> pb_contexts + i; i >= 0; i--, qp--) if (qp -> pc_result != PC_ACCEPT) { register struct PSAPcontext *qqp; qqp = pb -> pb_contexts + --pb -> pb_ncontext; if (qp -> pc_asn) oid_free (qp -> pc_asn); if (qp -> pc_atn) oid_free (qp -> pc_atn); if (qp != qqp) *qp = *qqp; /* struct copy */ } } pb -> pb_srequirements &= srequirements; if (pb -> pb_prequirements & PR_MANAGEMENT) pb -> pb_srequirements |= SR_TYPEDATA; if (status == PC_ACCEPT) { if ((pb -> pb_prequirements &= prequirements) != PR_MYREQUIRE) { register struct pair *pp; if ((cpa_normal -> presentation__fu = prim2bit (pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_BITS))) == NULL) goto no_mem; for (pp = preq_pairs; pp -> p_mask; pp++) if ((pb -> pb_prequirements & pp -> p_mask) && bit_on (cpa_normal -> presentation__fu, pp -> p_bitno) == NOTOK) goto no_mem; if (bit2prim (cpa_normal -> presentation__fu) == NULLPE) goto no_mem; } if ((pb -> pb_urequirements &= srequirements) != pb -> pb_srequirements) { register struct pair *pp; if ((cpa_normal -> session__fu = prim2bit (pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_BITS))) == NULL) goto no_mem; for (pp = sreq_pairs; pp -> p_mask; pp++) if ((pb -> pb_urequirements & pp -> p_mask) && bit_on (cpa_normal -> session__fu, pp -> p_bitno) == NOTOK) goto no_mem; if (bit2prim (cpa_normal -> session__fu) == NULLPE) goto no_mem; } status = SC_ACCEPT; } else { if (pb -> pb_flags & PB_DFLT) { if ((cpr_normal -> default__context = (struct type_PS_Context__result *) malloc (sizeof *cpr_normal -> default__context)) == NULL) goto no_mem; switch (defctxresult) { case PC_ACCEPT: default: result = int_PS_Result_acceptance; break; case PC_REJECTED: result = int_PS_Result_user__rejection; break; case PC_NOTSPECIFIED: result = int_PS_Result_provider__rejection; break; } cpr_normal -> default__context -> parm = result; } status = SC_REJECTED; } if (data && ndata > 0) { struct type_PS_User__data *info; if ((info = info2ppdu (pb, pi, data, ndata, status == SC_ACCEPT ? PPDU_CPA : PPDU_CPR)) == NULL) goto out2; if (status == SC_ACCEPT) cpa_normal -> user__data = info; else cpr_normal -> user__data = info; } if (status == SC_ACCEPT) { result = encode_PS_CPA__type (&pe, 1, 0, NULLCP, cpa); #ifdef DEBUG if (result == OK && (psap2_log -> ll_events & LLOG_PDUS)) vpdu (psap2_log, print_PS_CPA__type, pe, "CPA-type", 0); #endif } else { result = encode_PS_CPR__type (&pe, 1, 0, NULLCP, cpr); #ifdef DEBUG if (result == OK && (psap2_log -> ll_events & LLOG_PDUS)) vpdu (psap2_log, print_PS_CPR__type, pe, "CPR-type", 0); #endif } if (result == NOTOK) { (void) psaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s", PY_pepy); goto out2; } if (pe2ssdu (pe, &base, &len) == NOTOK) goto no_mem; if (status == SC_ACCEPT) { free_PS_CPA__type (cpa); cpa = NULL; } else { free_PS_CPR__type (cpr); cpr = NULL; } pe_free (pe); pe = NULL; if (SConnResponse (pb -> pb_fd, ref, responding ? &responding -> pa_addr : NULLSA, status, pb -> pb_srequirements, settings, isn, base, len, si) == NOTOK) if (SC_FATAL (sa -> sa_reason)) { (void) ss2pslose (pb, pi, "SConnResponse", sa); goto out2; } else { /* assume SS-user parameter error */ result = ss2pslose (NULLPB, pi, "SConnResponse", sa); goto out1; } if (status == SC_ACCEPT) { pb -> pb_flags |= PB_CONN; #define dotoken(requires,shift,bit,type) \ { \ if (pb -> pb_srequirements & requires) \ switch (settings & (ST_MASK << shift)) { \ case ST_INIT_VALUE << shift: \ pb -> pb_owned |= bit; \ pb -> pb_avail |= bit; \ break; \ \ case ST_RESP_VALUE << shift: \ pb -> pb_avail |= bit; \ break; \ } \ } dotokens (); #undef dotoken } else { pb -> pb_fd = NOTOK; freepblk (pb); } result = OK; goto out1; out2: ; result = NOTOK; if (cpr) { free_PS_CPR__type (cpr); cpr = NULL; } if (cpr = (struct type_PS_CPR__type *) calloc (1, sizeof *cpr)) { cpr -> offset = type_PS_CPR__type_normal__mode; if (cpr_normal = (struct element_PS_2 *) calloc (1, sizeof *cpr_normal)) { cpr -> un.normal__mode = cpr_normal; cpr_normal -> optionals |= opt_PS_element_PS_2_reason; cpr_normal -> reason = int_PS_reason_temporary__congestion; } } if (encode_PS_CPR__type (&pe, 1, 0, NULLCP, cpr) != NOTOK) { PLOG (psap2_log, print_PS_CPR__type, pe, "CPR-type", 0); if (pe) (void) pe2ssdu (pe, &base, &len); } else base = NULL, len = 0; (void) SConnResponse (pb -> pb_fd, ref, NULLSA, result, 0, 0, SERIAL_NONE, base, len, si); if (base) free (base); (void) pe2ssdu (pe, &base, &len); (void) SConnResponse (pb -> pb_fd, ref, NULLSA, SC_CONGESTION, 0, 0, SERIAL_NONE, base, len, si); freepblk (pb); out1: ; if (base) free (base); if (pe) pe_free (pe); if (cpa) free_PS_CPA__type (cpa); if (cpr) free_PS_CPR__type (cpr); return result; }