tsbridge.c

来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 824 行 · 第 1/2 页

C
824
字号
/* tsbridge.c: transport bridge - jpo version ! */#ifndef lintstatic char *rcsid = "$Header: /xtel/isode/isode/others/tsbridge/RCS/tsbridge.c,v 9.0 1992/06/16 12:48:17 isode Rel $";#endif/* * $Header: /xtel/isode/isode/others/tsbridge/RCS/tsbridge.c,v 9.0 1992/06/16 12:48:17 isode Rel $ * * Contributed by Julian Onions, Nottingham University in the UK * * * $Log: tsbridge.c,v $ * Revision 9.0  1992/06/16  12:48:17  isode * Release 8.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. * */#include <signal.h>#include <stdio.h>#include <varargs.h>#include "manifest.h"#include "sys.file.h"#include "tsap.h"#include "logger.h"#include "psap.h"#include "tailor.h"/*  */static int debug = 0;static int nbits = FD_SETSIZE;static LLog _pgm_log = {	"tsbridge.log",	NULLCP,	NULLCP,	LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, LLOG_FATAL,	-1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK};LLog	*pgm_log = &_pgm_log;static char	*myname = "tsbridge";typedef struct ContTbl {	struct TSAPaddr	src;	struct TSAPaddr dest;	unsigned int flags;#define CONN_STRICT	01#define CONN_TRANS	02#define CONN_NOMUNGE	04#define CONN_FORCEMUNGE	010} ContTbl;ContTbl con_tbl[FD_SETSIZE];int con_tbl_cnt = 0;static struct TSAPaddr *maketa ();static struct TSAPaddr *getnewta ();static ContTbl *find_connection ();static void read_file ();static void adios (), advise ();static void ts_adios (), ts_advise ();static void ts_close (), ts_discon ();static void tsbridge (), do_the_biz (), copy_tsdu (), arginit (), envinit ();/*  *//* ARGSUSED */main (argc, argv, envp)int	argc;char	**argv,        **envp;{	struct TSAPdisconnect   tds;	register struct TSAPdisconnect  *td = &tds;	struct TSAPaddr tas, *ta = &tas;	int	vecp;	char	*vec[4];	arginit (argv);	envinit ();	for (vecp = 0; vecp < con_tbl_cnt; vecp++) {	    advise (LLOG_TRACE, NULLCP, "Listening on %s",		     taddr2str (&con_tbl[vecp].src));	    if (TNetListen (&con_tbl[vecp].src, td) == NOTOK) {		advise (LLOG_FATAL, NULLCP, "Listen failed on \"%s\"",			taddr2str (&con_tbl[vecp].src));		ts_adios (td, "listen failed");	    }	}	for (;;) {		if (TNetAcceptAux (&vecp, vec, NULLIP, ta, 0, NULLFD, NULLFD,				   NULLFD, NOTOK, td) == NOTOK)			ts_adios (td, "accept failed");		if (vecp <= 0)			continue;		advise (LLOG_TRACE, NULLCP, "accepted new connection");		switch (TNetFork (vecp, vec, td)) {		    case OK:		        ll_hdinit (pgm_log, myname);			tsbridge (vecp, vec, ta);			exit (1);			/* NOTREACHED */		    case NOTOK:			ts_advise (td, LLOG_EXCEPTIONS, "TNetFork failed");			break;		    default:			break;		}	}}/*  */static	void tsbridge (vecp, vec, ta)int	vecp;char	**vec;struct TSAPaddr *ta;{	struct TSAPstart tss;	register struct TSAPstart *ts = &tss;	struct TSAPdisconnect   tds;	register struct TSAPdisconnect  *td = &tds;	struct TSAPaddr *tota;	struct TSAPaddr *fromta;	struct TSAPconnect tcs;	struct TSAPconnect *tc = &tcs;	int	sd;	ContTbl *ctp;	if (TInit (vecp, vec, ts, td) == NOTOK)		ts_adios (td, "T-CONNECT.INDICATION failed");			sd = ts -> ts_sd;	advise (LLOG_NOTICE, NULLCP,		"T-CONNECT.INDICATION: <%d, %s, %s, %d, %d>",		ts -> ts_sd, taddr2str (&ts -> ts_calling),		taddr2str (&ts -> ts_called),		ts -> ts_expedited, ts -> ts_tsdusize);	ctp = find_connection (ta);	if (ctp == NULL) {	    ts_close (sd, "Unknown listener address");	    exit (1);	}	advise (LLOG_TRACE, NULLCP, "Accepted from address %s",		taddr2str (&ctp -> src));	tota = getnewta (&ts -> ts_called, sd, ctp);	fromta = maketa (&ts -> ts_calling, tota -> ta_addrs[0].na_stack, ctp);	if ((ctp -> flags & CONN_TRANS) == 0) {	    ts -> ts_expedited = 0;	    if (ts -> ts_cc > 0) {		advise (LLOG_EXCEPTIONS, NULLCP,			"%d octets initial user-data",			ts -> ts_cc);		ts_close (sd, "initial user-data not allowed");		exit (1);	    }	}		advise (LLOG_NOTICE, NULLCP,		"T-CONNECT.REQUEST: <%s, %s, %d, 0x%x/%d>",		taddr2str (fromta), taddr2str (tota), ts -> ts_expedited,		ts -> ts_data, ts -> ts_cc);	if (TConnRequest (fromta, tota, ts -> ts_expedited,			  ts -> ts_data, ts -> ts_cc, &ts -> ts_qos,			  tc, td) == NOTOK) {	        (void) TDiscRequest (sd, td -> td_data, td -> td_cc, td);		ts_adios(td, "T-CONNECT.REQUEST");	}	if (TConnResponse (sd, NULLTA,			   tc -> tc_expedited, tc -> tc_data, tc -> tc_cc,			   &tc -> tc_qos, td) == NOTOK) {		ts_close (sd, "connection establishment failed");		ts_close (tc -> tc_sd, "connection establishment failed");		ts_adios (td, "T-CONNECT.RESPONSE");	}		do_the_biz (sd, tc -> tc_sd);}/*  */static void	do_the_biz (sd1, sd2)int	sd1, sd2;{	int nfds = 0;	fd_set rmask, imask;	struct TSAPdisconnect   tds;	register struct TSAPdisconnect  *td = &tds;	FD_ZERO (&rmask);		if (TSelectMask (sd1, &rmask, &nfds, td) == NOTOK	        || TSelectMask (sd2, &rmask, &nfds, td) == NOTOK)	    ts_adios (td, "TSelectMask failed");	for (;;) {		imask = rmask;		if (xselect (nfds, &imask, NULLFD, NULLFD, NOTOK) == NOTOK)			adios ("select", "failed");		if (FD_ISSET (sd1, &imask))			copy_tsdu (sd1, sd2);		if (FD_ISSET (sd2, &imask))			copy_tsdu (sd2, sd1);	}}/*  */static	void copy_tsdu (s1, s2)int	s1, s2;{	struct TSAPdisconnect   tds;	register struct TSAPdisconnect  *td = &tds;	struct TSAPdata txs;	register struct TSAPdata *tx = &txs;	int	result;	char	*p;	SLOG (pgm_log, LLOG_DEBUG, NULLCP, ("copy_tsdu (%d -> %d)", s1, s2));	if (TReadRequest (s1, tx, OK, td) == NOTOK) {		switch (td -> td_reason) {		    case DR_TIMER:		    case DR_WAITING:		    case DR_OPERATION:		    case DR_PARAMETER:			ts_advise (td, LLOG_TRACE, "TReadRequest");			return;		    case DR_NORMAL:			ts_discon (td, s2);			break;		    default:			ts_adios (td, "TReadRequest");		}	}	if (tx -> tx_expedited) {		SLOG (pgm_log, LLOG_DEBUG, NULLCP, ("TExpdRequest"));		p = qb2str (&tx -> tx_qbuf);		result = TExpdRequest (s2, p, tx -> tx_cc, td);		free (p);	}	else {		struct qbuf *qb;		int	uiocnt = 0;		struct udvec uvec[100];		int total;		total = uiocnt = 0;		for (qb = tx-> tx_qbuf.qb_forw; qb != &tx -> tx_qbuf;		     qb = qb -> qb_forw) {			uvec[uiocnt].uv_base = qb -> qb_data;			uvec[uiocnt++].uv_len = qb -> qb_len;			total += qb -> qb_len;			if (uiocnt > 100)				adios (NULLCP, "Internal buffer overflow");		}		uvec[uiocnt].uv_base = NULLCP;		uvec[uiocnt].uv_len = 0;		if (tx -> tx_cc != total)			advise (LLOG_EXCEPTIONS, NULLCP,				"Mismatch in data %d != %d",				tx -> tx_cc, total);		SLOG (pgm_log, LLOG_DEBUG, NULLCP, ("TWriteRequest"));		result = TWriteRequest (s2, uvec, td);	}	TXFREE (tx);	if (result == NOTOK) {		if (td -> td_reason == DR_NORMAL)			ts_discon (td, s1);		ts_adios (td, tx -> tx_expedited ? "T-EXPEDITED-DATA.REQUEST"						 : "T-DATA.REQUEST");	}}/*  */static void ts_discon (td, sd)struct TSAPdisconnect *td;int	sd;{	ts_close (sd, "Normal Disconnect");	ts_advise (td, LLOG_NOTICE, "T-DISCONNECT.INDICATION");	exit (0);}/*  */static void ts_close (sd, event)int	sd;char	*event;{	struct TSAPdisconnect tds;	register struct TSAPdisconnect *td = &tds;	if ((int)strlen (event) >= TD_SIZE)	    event = NULLCP;	if (TDiscRequest (sd, event, event ? strlen (event) + 1: 0, td)	        == NOTOK)	    ts_advise (td, LLOG_EXCEPTIONS, "T-DISCONNECT.REQUEST");}/*  */static void  ts_adios (td, event)register struct TSAPdisconnect *td;char	*event;{	ts_advise (td, LLOG_EXCEPTIONS, event);	exit (1);}/*  */static void  ts_advise (td, code, event)register struct TSAPdisconnect *td;int     code;char   *event;{    char    buffer[BUFSIZ];    if (td -> td_cc > 0)	(void) sprintf (buffer, "[%s] %*.*s",		TErrString (td -> td_reason),		td -> td_cc, td -> td_cc, td -> td_data);    else	(void) sprintf (buffer, "[%s]", TErrString (td -> td_reason));    advise (code, NULLCP, "%s: %s", event, buffer);}/*  */static int isnew = 1;static struct TSAPaddr *getnewta (ta, sd, ctp)struct TSAPaddr *ta;int	sd;ContTbl *ctp;{	static struct TSAPaddr newta;	struct TSAPaddr *nta = &newta;	char	buffer[TSSIZE + 1];	int	n, m;	isnew = 1;	if (ctp -> flags & CONN_TRANS) {	/* make transparent address */		*nta = ctp -> dest;	/* struct copy */		if (nta -> ta_selectlen == 0) {		    nta -> ta_selectlen = ta -> ta_selectlen;		    bcopy (ta -> ta_selector, nta -> ta_selector,			   ta -> ta_selectlen);		}		return nta;	}	/* do the real TS bridge stuff */	if ((m = ta -> ta_selectlen) == 0) {		ts_close (sd, "no transport selector");		adios (NULLCP, "no transport selector");	}	/* does this look like an encoded TSEL? */	n = ta -> ta_selector[0];/*	advise (LLOG_TRACE, NULLCP, "n=%d,m=%d s[0] = %d, s[1] = %d",		n, m, ta -> ta_selector[0], ta -> ta_selector[1]);*/	if (m > 4 &&	    ta -> ta_selector[0] == ta -> ta_selector[1] &&	    n > 2 && n <= m - 2) { /* encoded! */		bzero ((char *)nta, sizeof *nta);		nta -> ta_selectlen = m - n - 2;		if (nta -> ta_selectlen > 0)			bcopy (&ta -> ta_selector[n+2], nta -> ta_selector,			       nta -> ta_selectlen);		if (norm2na (&ta -> ta_selector[2], n, nta -> ta_addrs) != OK) {			ts_close (sd, "undecodable address");			adios (NULLCP, "Can't decode address");		}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?