|
|
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;
}