📄 tsapunitdata.c
字号:
/* **************************************************************** * * * HULA project * * * * program: tsapunitdata.c * * author: kurt dobbins * * date: 12/88 * * * * This program implements the connectionless tsap unitdata * * interface. It is designed to provide generic datagram * * transport service over multiple connectionless transports. * * * * entry points: * * * * TUnitDataListen (ta, qos, td) * * TuSave (sd, vecp, vex, td) * * TUnitDataBind (sd, calling, called, qos, td) * * TUnitDataUnbind (sd) * * TUnitDataRequest (calling, called, qos, data) * * TUnitDataWrite (sd, uv) * * TUnitDataRead (sd, tud, secs) * * TSelectUnitDataMask (sd, mask, nfds) * * UNITDATAser (sig, code, sc) * * TUnitDataWakeUp (tb, td) * * * **************************************************************** * * * * * NOTICE * * * * Acquisition, use, and distribution of this module and * * related materials are subject to the restrictions of a * * license agreement. * * * * This software is for prototype purposes only. * * * **************************************************************** */#include <stdio.h>#include <signal.h>#include "tpkt.h"#include "tsap.h"#include "tusap.h"#include "isoservent.h"#include "tailor.h"#include "internet.h"#include "uderrors.h"struct TSAPaddr *newtuaddr ();#define selmask(fd,m,n) \{ \ FD_SET (fd, &(m)); \ if ((fd) >= (n)) \ (n) = (fd) + 1; \}#ifdef HULA/* STATIC DATA */#ifdef WITHOUTCONS/* * Only allocate these if built * WITHOUT the connection-oriented service. */static int once_only = 0;static struct tsapblk tsapque;static struct tsapblk *THead = &tsapque;#endif#ifndef SIGPOLLstatic int TPid = NOTOK;#endif/* *//* **************************************************************** * * * TUnitDataListen * * * * This routine creates the "listen" socket for transport * * addresses that support datagrams. * * * * returns: socket descriptor * * * **************************************************************** */int TUnitDataListen (listen, qos, td)struct TSAPaddr *listen;struct QOStype *qos;struct TSAPdisconnect *td;{int result;register int n = listen -> ta_naddr - 1;register struct NSAPaddr *na = listen -> ta_addrs;register struct NSAPaddr *la;register struct tsapblk *tb;#ifdef HULADEBUG printf ("\n in TUnitDataListen \n");#endif /* * Check for missing parms. */ missing_udP (listen); missing_udP (td); /* * Allocate a new tsap block for this listen. */ if ((tb = newtublk ()) == NULL) return tusaplose (td, DR_CONGEST, NULLCP, TuErrString(UDERR_NO_MEMORY) ); /* * Find the type of transport service to use. * The idea is that if the listen address has * multiple network addresses, we will setup * a listen on each one. */ for (; n >= 0; na++, n--) { switch (na -> na_type) { /* * For now, we only support UDP (which is the default service * if no addresses are supplied. */ case NA_TCP: udpinit (tb); /* * Now finish setting up the control block. */ tb -> tb_srcref = htons ((u_short) (getpid () & 0xffff)); tb -> tb_dstref = htons ((u_short) 0); /* * Set the network address to be only the one we care about. */#if FALSE tb -> tb_initiating = *newtuaddr (calling, la); tb -> tb_responding = *newtuaddr (called, na); #endif if (qos) tb -> tb_qos = *qos; /* struct copy */ /* * Allocate the local socket to listen on. */ if ( (result = (*tb -> tb_UnitDataStart) (tb, na, NULL, TUNITDATA_START, td) ) != OK) { continue; } break; default: return tusaplose ( td, DR_PARAMETER, NULLCP, TuErrString(UDERR_NSAP_NOT_SUPPORTED) ); } break; } /* end of for number of net addresses */ if (tb -> tb_fd == NOTOK) { freetublk (tb); return NOTOK; } return (tb -> tb_fd);}/* *//* **************************************************************** * * * TUnitDataBind * * * * This routine sets up datagram service for the transport. * * It allocates and initializes a tsap control block for the * * calling/called address pair and calls the transport to * * initialize unitdata service. This routine drives the * * underlying transport service to create a socket and bind * * the remote address. * * * * If the remote address is specified, it is considered a * * permanent binding; otherwise, the bind to a remote address * * can be done anytime which essentially allows dynamic * * binding (and rebinding) to remote addresses. * * * * This routine must be called prior to using the TUnitData * * interface for subsequent TUniteWrite requests. If this * * isn't called, then TUnitDataRequest must be called for each * * unit data request. * * * * * * Note: BIND has write sematics only. * * * * * * returns: socket descriptor * * updated ti struct if any error (NOTOK) returned * * * **************************************************************** */int TUnitDataBind (sd, calling, called, qos, td)int sd;struct TSAPaddr *calling, *called;struct QOStype *qos;struct TSAPdisconnect *td;{int result;register int n; register struct NSAPaddr *na;register int l;register struct NSAPaddr *la;register struct tsapblk *tb;int option;SBV smask; /* signal save mask */#ifdef HULADEBUG printf ("\n in TUnitDataBind \n");#endif isodetailor ("tsap"); /* * Check for missing parms. */ missing_udP (td); /* * Check if we need to create a new socket or just * reuse (essentially "rebind") the current socket * for the specified address pair. */ if (sd < 0) { /* * Allocate a new tsap block for this calling/called address pair. */#ifdef HULADEBUG printf ("\n allocating new tsap block \n");#endif if ( (tb = newtublk () ) == NULL) return tusaplose (td, DR_CONGEST, NULLCP, TuErrString(UDERR_NO_MEMORY) ); option = TUNITDATA_START; } else { /* * Find the correct tsap block and set the signal mask. */ #ifdef HULADEBUG printf ("\n re-binding on current tsap block \n");#endif /* * There had better be a remote addr to bind to. */ if (called == NULLTA) return tusaplose (td, DR_PARAMETER, NULLCP, TuErrString(UDERR_NO_REMOTE_ADDR) ); tsap_udPsig (tb, sd); option = TUNITDATA_BIND; } if (calling == NULLTA) { static struct TSAPaddr tas_calling; /* * Zero-fill the calling address. */ calling = &tas_calling; bzero ((char *) calling, sizeof *calling); } if (called == NULLTA) { static struct TSAPaddr tas_called; /* * Zero-fill the called address. */ called = &tas_called; bzero ((char *) called, sizeof *called); } 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; } /* * Set the network address from the called address if it is specified * otherwise default the address to the calling (so we can init the * transport that it supports). */ if (n = (called -> ta_naddr - 1) < 0) { /* * No called network address. * Default it to be the local if it exists. */ if (n = (calling -> ta_naddr - 1) < 0) { freetublk (tb); return tusaplose ( td, DR_PARAMETER, NULLCP, TuErrString(UDERR_NO_NSAP_ADDRS) ); } else { /* * Set the default addr type so we can continue. */ called -> ta_addrs[0].na_type = calling -> ta_addrs[0].na_type; } } /* * Now find the type of transport service to use. * The idea is that if the called service address has * multiple network addresses, we will use the address * that matches our local (calling) address type. * If the called service address has no network address, * then we will default to the local network address. */ for (na = called -> ta_addrs; n >= 0; na++, n--) { for (l = calling -> ta_naddr - 1, la = calling -> ta_addrs; l >= 0; la++, l--) if (la -> na_type == na -> na_type) break; if (l < 0) la = NULLNA; switch (na -> na_type) { /* * For now, we only support UDP (which is the default service * if no addresses are supplied. */ case NA_TCP: udpinit (tb); /* * Now finish setting up the control block. */ tb -> tb_srcref = htons ((u_short) (getpid () & 0xffff)); tb -> tb_dstref = htons ((u_short) 0); /* * Set the network address to be only the one we care about. */ tb -> tb_initiating = *newtuaddr (calling, la); tb -> tb_responding = *newtuaddr (called, na); if (qos) tb -> tb_qos = *qos; /* struct copy */ /* * Allocate the socket and BIND it to the address pair. */ if ((result = (*tb -> tb_UnitDataStart) (tb, la, na, option), td) != OK) { continue; } break; default: return tusaplose ( td, DR_ADDRESS, NULLCP, TuErrString(UDERR_NSAP_NOT_SUPPORTED) ); } break; } /* end of for number of net addresses */ if (tb -> tb_fd == NOTOK) { freetublk (tb); return NOTOK; } return (tb -> tb_fd);}/* *//* **************************************************************** * * * TUnitDataUnbind * * * * This routine releases datagram service for the transport. * * Itfrees the tsap block for the socket and then closes the * * soeckt. * * * * returns: OK, NOTOK * * * **************************************************************** */int TUnitDataUnbind (sd, td)int sd;struct TSAPdisconnect *td;{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -