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 + -
显示快捷键?