|
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 t
Length: 12105 (0x2f49) Types: TextFile Names: »tsapinitiate.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦e83f91978⟧ »EurOpenD22/isode/osimis-2.0.tar.Z« └─⟦d846658bd⟧ └─⟦this⟧ »osimis/misode/tsap/tsapinitiate.c« └─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« └─⟦de7628f85⟧ └─⟦this⟧ »isode-6.0/tsap/tsapinitiate.c«
/* tsapinitiate.c - TPM: initiator */ #ifndef lint static char *rcsid = "$Header: /f/osi/tsap/RCS/tsapinitiate.c,v 7.0 89/11/23 22:30:44 mrose Rel $"; #endif /* * $Header: /f/osi/tsap/RCS/tsapinitiate.c,v 7.0 89/11/23 22:30:44 mrose Rel $ * * * $Log: tsapinitiate.c,v $ * Revision 7.0 89/11/23 22:30:44 mrose * Release 6.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 <signal.h> #include "tpkt.h" #include "mpkt.h" #include "isoservent.h" #include "tailor.h" static struct nsapent { int ns_type; int ns_stack; IFP ns_open; } nsaps[] = { #ifdef TCP NA_TCP, TS_TCP, tcpopen, #endif #ifdef X25 NA_X25, TS_X25, x25open, #endif #ifdef BRIDGE_X25 NA_BRG, TS_BRG, bridgeopen, #endif #ifdef TP4 NA_NSAP, TS_TP4, tp4open, #endif NOTOK, TS_NONE, NULL }; struct TSAPaddr *newtaddr (), *ta2norm (), *maketsbaddr (); /* \f T-(ASYN-)CONNECT.REQUEST */ int TAsynConnRequest (calling, called, expedited, data, cc, qos, tc, td, async) struct TSAPaddr *calling, *called; int expedited, cc, async; char *data; struct QOStype *qos; struct TSAPconnect *tc; struct TSAPdisconnect *td; { register int n; SBV smask; int result; isodetailor (NULLCP, 0); #ifdef notdef missingP (calling); #endif missingP (called); if ((n = called -> ta_naddr) <= 0) return tsaplose (td, DR_PARAMETER, NULLCP, "no NSAP addresses in called parameter"); if (n > NTADDR) return tsaplose (td, DR_PARAMETER, NULLCP, "too many NSAP addresses in called parameter"); if ((called = ta2norm (called)) == NULLTA) return tsaplose (td, DR_PARAMETER, "invalid called parameter"); toomuchP (data, cc, TS_SIZE, "initial"); #ifdef notdef missingP (qos); #endif missingP (td); smask = sigioblock (); result = TConnRequestAux (calling, called, expedited, data, cc, qos, tc, td, async); (void) sigiomask (smask); return result; } /* \f */ static int TConnRequestAux (calling, called, expedited, data, cc, qos, tc, td, async) struct TSAPaddr *calling, *called; char *data; int expedited, cc, async; struct QOStype *qos; register struct TSAPconnect *tc; register struct TSAPdisconnect *td; { int result; register struct tsapblk *tb; if ((tb = newtblk ()) == NULL) return tsaplose (td, DR_CONGEST, NULLCP, "out of memory"); if (calling == NULLTA) { static struct TSAPaddr tas; calling = &tas; bzero ((char *) calling, sizeof *calling); } #ifdef notdef if (called -> ta_selectlen > 0 && calling -> ta_selectlen == 0) { calling -> ta_port = htons ((u_short) (0x8000 | (getpid () & 0x7fff))); calling -> ta_selectlen = sizeof calling -> ta_port; } #endif if (qos) tb -> tb_qos = *qos; /* struct copy */ tb -> tb_initiating = *calling; /* struct copy */ tb -> tb_caddr = *called; /* .. */ if ((tb -> tb_cc = cc) > 0) { if ((tb -> tb_data = malloc ((unsigned) cc)) == NULLCP) { (void) tsaplose (td, DR_CONGEST, NULLCP, "out of memory"); goto out; } bcopy (data, tb -> tb_data, cc); } tb -> tb_expedited = expedited; if ((result = TConnAttempt (tb, td, async)) == NOTOK) { #ifdef MGMT if (tb -> tb_manfnx) (*tb -> tb_manfnx) (OPREQOUTBAD, tb); #endif goto out; } if (async) { tc -> tc_sd = tb -> tb_fd; switch (result) { case CONNECTING_1: case CONNECTING_2: return result; } } if ((result = (*tb -> tb_retryPfnx) (tb, async, tc, td)) == DONE && !async) result = OK; return result; out: ; freetblk (tb); return NOTOK; } /* \f */ static int TConnAttempt (tb, td, async) struct tsapblk *tb; struct TSAPdisconnect *td; int async; { register int n; int didone, l, result; register struct TSAPaddr *called, *calling; struct TSAPaddr *realcalled; register struct NSAPaddr *na, *la; struct NSAPaddr *realna; register struct TSAPdisconnect *te = td; struct TSAPdisconnect tds; called = &tb -> tb_caddr; calling = &tb -> tb_initiating; didone = 0; for (na = called -> ta_addrs, n = called -> ta_naddr - 1; n >= 0; na++, n--) { register int *ip; register char **ap; register struct nsapent *ns; realcalled = called; realna = na; for (ip = ts_communities; *ip; ip++) if (*ip == na -> na_subnet) break; if (!*ip) continue; for (ip = tsb_communities, ap = tsb_addresses; *ip; ip++, ap++) if (*ip == na -> na_subnet) { if ((realcalled = maketsbaddr (*ap, na, called)) == NULLTA) continue; realna = realcalled -> ta_addrs; break; } for (la = calling -> ta_addrs, l = calling -> ta_naddr - 1; l >= 0; la++, l--) if (la -> na_subnet == na -> na_subnet) break; if (l < 0) la = NULLNA; for (ns = nsaps; ns -> ns_open; ns++) if (ns -> ns_type == realna -> na_type && (ns -> ns_stack & ts_stacks)) break; if (!ns -> ns_open) continue; didone = 1; switch (ns -> ns_type) { case NA_NSAP: if ((result = (*ns -> ns_open) (tb, calling, la, realcalled, realna, te, async)) == NOTOK) { te = &tds; continue; } break; default: if ((result = (*ns -> ns_open) (tb, la, realna, te, async)) == NOTOK) { te = &tds; continue; } break; } break; } if (tb -> tb_fd == NOTOK) { if (!didone) return tsaplose (td, DR_PARAMETER, NULLCP, "no supported NSAP addresses in, nor known TSBridges for, called parameter"); return NOTOK; } if (la && la != calling -> ta_addrs) { struct NSAPaddr ns; ns = calling -> ta_addrs[0]; /* struct copy */ calling -> ta_addrs[0] = *la; /* .. */ *la = ns; /* .. */ la = calling -> ta_addrs; /* .. */ } tb -> tb_responding = *realcalled; /* struct copy */ tb -> tb_responding.ta_addrs[0] = *realna; /* .. */ tb -> tb_responding.ta_naddr = 1; if ((result = (*tb -> tb_connPfnx) (tb, tb -> tb_expedited, tb -> tb_data, tb -> tb_cc, td)) == NOTOK) return NOTOK; if (result == OK) result = CONNECTING_1; return result; } /* \f T-ASYN-RETRY.REQUEST (pseudo) */ int TAsynRetryRequest (sd, tc, td) int sd; struct TSAPconnect *tc; struct TSAPdisconnect *td; { SBV smask; int result; register struct tsapblk *tb; struct TSAPaddr *ta; missingP (tc); missingP (td); smask = sigioblock (); if ((tb = findtblk (sd)) == NULL) { (void) sigiomask (smask); return tsaplose (td, DR_PARAMETER, NULLCP, "invalid transport descriptor"); } if (tb -> tb_flags & TB_CONN) { (void) sigiomask (smask); return tsaplose (td, DR_OPERATION, NULLCP, "transport descriptor connected"); } ta = &tb -> tb_caddr; switch (result = (*tb -> tb_retryPfnx) (tb, 1, tc, td)) { case NOTOK: /* try next nsap in list */ if (ta -> ta_naddr <= 1) { freetblk (tb); break; } tb -> tb_caddr = *newtaddr (ta, &ta -> ta_addrs[1], ta -> ta_naddr - 1); /* struct copy */ switch (result = TConnAttempt (tb, td, 1)) { case DONE: result = OK; /* and fall... */ case CONNECTING_1: case CONNECTING_2: if (tb -> tb_fd != sd) { (void) dup2 (tb -> tb_fd, sd); (void) close (tb -> tb_fd); tb -> tb_fd = sd; } break; case NOTOK: freetblk (tb); break; } break; case DONE: if (tb -> tb_data) { free (tb -> tb_data); tb -> tb_data = NULLCP; } tb -> tb_cc = 0; tb -> tb_expedited = 0; break; case CONNECTING_1: case CONNECTING_2: default: break; } (void) sigiomask (smask); return result; } /* \f T-ASYN-NEXT.REQUEST (pseudo) */ int TAsynNextRequest (sd, tc, td) int sd; struct TSAPconnect *tc; struct TSAPdisconnect *td; { SBV smask; int result; register struct tsapblk *tb; struct TSAPaddr *ta; missingP (tc); missingP (td); smask = sigioblock (); if ((tb = findtblk (sd)) == NULL) { (void) sigiomask (smask); return tsaplose (td, DR_PARAMETER, NULLCP, "invalid transport descriptor"); } if (tb -> tb_flags & TB_CONN) { (void) sigiomask (smask); return tsaplose (td, DR_OPERATION, NULLCP, "transport descriptor connected"); } ta = &tb -> tb_caddr; /* close previous connection attempt */ if (tb -> tb_fd != NOTOK) (void) (*tb -> tb_closefnx) (tb -> tb_fd); tb -> tb_fd = NOTOK; if (ta -> ta_naddr <= 1) { freetblk (tb); (void) sigiomask (smask); return tsaplose (td, DR_PARAMETER, NULLCP, "no more NSAPs to try"); } tb -> tb_caddr = *newtaddr (ta, &ta -> ta_addrs[1], ta -> ta_naddr - 1); /* struct copy */ switch (result = TConnAttempt (tb, td, 1)) { case DONE: result = OK; /* and fall... */ case CONNECTING_1: case CONNECTING_2: if (tb -> tb_fd != sd) { (void) dup2 (tb -> tb_fd, sd); (void) close (tb -> tb_fd); tb -> tb_fd = sd; } break; case NOTOK: freetblk (tb); break; } (void) sigiomask (smask); return result; } /* \f */ static struct TSAPaddr *newtaddr (ta, na, n) register struct TSAPaddr *ta; register struct NSAPaddr *na; int n; { static struct TSAPaddr tzs; register struct TSAPaddr *tz = &tzs; register struct NSAPaddr *nz = tz -> ta_addrs; bzero ((char *) tz, sizeof *tz); if (tz -> ta_selectlen = ta -> ta_selectlen) bcopy (ta -> ta_selector, tz -> ta_selector, ta -> ta_selectlen); if (na) for (tz -> ta_naddr = n; n > 0; n--) *nz++ = *na++; /* struct copy */ return tz; } /* \f */ struct TSAPaddr *ta2norm (ta) register struct TSAPaddr *ta; { register int n, *ip; static struct TSAPaddr tzs; register struct TSAPaddr *tz = &tzs; register struct NSAPaddr *na, *ca; SLOG (addr_log, LLOG_TRACE, NULLCP, ("ta2norm %s", taddr2str (ta))); for (na = ta -> ta_addrs, n = ta -> ta_naddr - 1; n >= 0; na++, n--) if (na -> na_subnet == 0) { SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("ta2norm: empty subnet in NSAP address at offset %d", na - ta -> ta_addrs)); return NULLTA; } bzero ((char *) tz, sizeof *tz); bcopy (ta -> ta_selector, tz -> ta_selector, tz -> ta_selectlen = ta -> ta_selectlen); ca = tz -> ta_addrs; for (ip = ts_communities; *ip; ip++) for (na = ta -> ta_addrs, n = ta -> ta_naddr - 1; n >= 0; na++, n--) if (*ip == na -> na_subnet) { *ca++ = *na; /* struct copy */ tz -> ta_naddr++; } for (na = ta -> ta_addrs, n = ta -> ta_naddr - 1; n >= 0; na++, n--) { for (ip = ts_communities; *ip; ip++) if (*ip == na -> na_subnet) break; if (!*ip) { *ca++ = *na; /* struct copy */ tz -> ta_naddr++; } } SLOG (addr_log, LLOG_TRACE, NULLCP, ("ta2norm returns %s", taddr2str (tz))); return tz; } /* \f */ static struct TSAPaddr *maketsbaddr (cp, na, ta) char *cp; struct NSAPaddr *na; struct TSAPaddr *ta; { static struct TSAPaddr newta; register struct TSAPaddr *nta = &newta; struct TSAPaddr *taz; char *p; struct PSAPaddr pas; struct PSAPaddr *pa = &pas; if ((taz = str2taddr (cp)) == NULLTA) return taz; *nta = *taz; /* struct copy */ bzero ((char *)pa, sizeof *pa); pa -> pa_addr.sa_addr.ta_naddr = 1; pa -> pa_addr.sa_addr.ta_addrs[0] = *na; pa -> pa_addr.sa_addr.ta_selectlen = ta -> ta_selectlen; (void) strncpy (pa -> pa_addr.sa_addr.ta_selector, ta -> ta_selector, ta -> ta_selectlen); if ((p = _paddr2str (pa, NULLNA, -1)) == NULL) return NULLTA; if ((nta -> ta_selectlen = strlen (p)) >= TSSIZE) return NULLTA; else (void) strncpy (nta -> ta_selector, p, TSSIZE); nta -> ta_naddr = 1; return nta; }