DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T t

⟦979139874⟧ TextFile

    Length: 12105 (0x2f49)
    Types: TextFile
    Names: »tsapinitiate.c«

Derivation

└─⟦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« 

TextFile

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