⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssapunitdata.c

📁 ftam等标准协议服务器和客户端的源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* **************************************************************** *                                                              * *  HULA project						* *                                             			* *  program:  	ssapunitdata.c                                  * *  author:   	kurt dobbins                                    * *  date:     	3/89                                            * *                                                              * *  This program implements the connectionless ssap unitdata    * *  interface.  It implements the ISO 9548 "Connectionless-Mode * *  Session Protocol".						* *                                  				* *  entry points:                   				* *                                  				* *	SUnitDataBind (sd, calling, called, qos)                * *	SUnitDataUnbind (sd)                    		* *	SuSave (sd, vecp, vec, si)				* *	SUnitDataRequest (calling, called, qos, data, cc, si)   * * 	SUnitDataWrite (sd, data, cc, si)                       * * 	SUnitDataWriteV (sd, uv)                                * *      SUnitDataRead (sd, sud, secs)	                        * *      x SSelectUnitDataMask (sd, mask, nfds)                  * *	x TUNITDATAser (sig, code, sc)                          * *	x SUnitDataWakeUp (tb, td)                              * *								* *	x = not implemented					* *								* **************************************************************** *								* *								* *			     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.		* *								* **************************************************************** *//* LINTLIBRARY */#include <stdio.h>#include <signal.h>#include "spkt.h"#include "ssap.h"#include "susap.h"#include "tusap.h"#include "uderrors.h"#include "tailor.h"#ifdef HULA/*    DATA */#define SSAP_NOT_ASYNC 	0#define SSAP_ASYNC 	1int	TUNITDATAser ();/*    **************************************************************** *								* *  SUnitDataBind	                                        * *  								* *  This routine binds the local address to a socket.           * *  Optionally it allows a remote address to be bound as an     * *  address pair.  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.  But   * *  no matter what, the local address must always be specified. * *								* *  It allocates and initializes a ssap control block for the   * *  socket and calls the tsap to initialize unitdata service.	* * 								* *  This routine must be called prior to using the SUnitData    * *  interface for subsequent SUniteWrite requests.  If this     * *  isn't called, then SUnitDataRequest must be called for each * *  unit data request.						* *								* *  Note:  BIND has write sematics only.                        * *								* *								* *  returns:	transport descriptor				* *              updated si struct if any error (NOTOK) returned * *								* **************************************************************** */int	SUnitDataBind (sd, local, remote, qos, si)int    			sd;struct SSAPaddr 	*local;struct SSAPaddr 	*remote;struct QOStype  	*qos;struct SSAPindication 	*si;{    int     fd;    SBV     smask;    int     result;    register struct ssapblk *sb;    struct  TSAPdisconnect  td;#ifdef HULADEBUG	printf ("\n     in SUnitDataBind \n");#endif    isodetailor ("ssap");/* *  Check for missing parameters. */    missing_udP (si);    if (!local && !remote)	return susaplose (si,			  SC_PARAMETER,		  	  NULLCP,			  SuErrString (UDERR_MISSING_PARAMETER));			  		/* *  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 ssap block for this calling/called address pair. 	 */#ifdef HULADEBUG	printf ("\n     allocating new ssap block \n");#endif    	if ( (sb = newsublk () ) == NULL)	    return susaplose (si,			      SC_CONGEST,			      NULLCP,			      SuErrString (UDERR_NO_MEMORY));	}    else	{	/*  	 *  Find the correct session block and set the signal mask. 	 */     	if ((sb = findsublk (sd)) == NULL)	    {	    /*             *  Check for special case where a server has set up a 	     *  listen socket and is now binding the address so the 	     *  socket exists but no ssap block has been set up.	     */	    if (local)	        {#ifdef HULADEBUG	        printf ("\n     allocating new ssap block for listen socket\n");#endif    	        if ( (sb = newsublk () ) == NULL)	            return susaplose (si, 				      SC_CONGEST, 				      NULLCP, 				      SuErrString(UDERR_NO_MEMORY));	        }	    else	        {	        (void) sigsetmask (smask); 	  	return susaplose (si,				  SC_PARAMETER,				  NULLCP,				  SuErrString(UDERR_INVALID_SESSION_DESC)); 		}	    }#ifdef HULADEBUG	printf ("\n     re-binding on current ssap block \n");#endif	}    /*     *  Set up the addresses if not specified.     */       if (local == NULLSA)        {	static struct SSAPaddr salocal;	local = &salocal;	bzero ((char *) local, sizeof *local);	}    if (remote == NULLSA)        {	static struct SSAPaddr saremote;	remote = &saremote;	bzero ((char *) remote, sizeof *remote);	}    if (local -> sa_selectlen == 0)         {	local -> sa_port = htons((u_short)(0x8000 | (getpid() & 0x7fff)));	local -> sa_selectlen = sizeof local -> sa_port;	}    	/* *  Now bind (or re-bind) the address pair and get back a socket descriptor. */    fd = TUnitDataBind (sd, &local -> sa_addr, &remote -> sa_addr, qos, &td);    if (fd == NOTOK)	{	freesublk (sb);	return ts2suslose (si, "TUnitDataBind", &td);	}/* *  Now finish setting up the control block. */    sb -> sb_fd = fd;    sb -> sb_version = SB_VRSN1_CLNS;	/* version 1 connectionless */    sb -> sb_flags = SB_CLNS;		/* connectionless service */#if FALSE    sb -> sb_tsdu_us = 0;#endif    sb -> sb_initiating = *local;	/* strcut copy */        sb -> sb_responding = *remote;	/* struct copy */#if FALSE    if (qos)	sb -> sb_qos = *qos;	#endif    return fd;}  /*  *//* **************************************************************** *								* *  SUnitDataUnbind	                                        * *  								* *  This routine releases datagram service for the session      * *  provider.  It frees the ssap block for the socket and then  * *  closes the socket. 						* *								* *  returns:	OK, NOTOK					* *								* **************************************************************** */int     SUnitDataUnbind (sd, si)int	sd;struct  SSAPindication *si;{register struct ssapblk *sb;int	 result;SBV      smask;			 	/* signal save mask */struct  TSAPdisconnect  td;#ifdef HULADEBUG	printf ("\n     in SUnitDataUnbind \n");#endif/*  *  Find the correct session block and set the signal mask. */     ssap_udPsig (sb, sd);/* *  Close the transport socket and free its resources. */    if ( (result = TUnitDataUnbind (sb -> sb_fd, &td)) != OK )	return NOTOK;    /* *  Now free the ssapblk. */#ifdef HULADEBUG	printf ("\n     freeing the ssap block \n");#endif	    freesublk (sb);    return OK; }/*  *//*    **************************************************************** *								* *  SuSave		                                        * *  								* *  This routine sets up a control block path and socket for    * *  datagram that has arrived on the server listen socket.      * *								* *  returns:	socket descriptor from TuSave			* *								* **************************************************************** */int	SuSave (sd, vecp, vec, si)int	 	 sd;register int     vecp;register char  **vec;register struct  SSAPindication *si;{    register struct ssapblk *sb;    struct   TSAPdisconnect tds;    struct   TSAPdisconnect *td = &tds;    int	     result;	         SBV      smask;			 	/* signal save mask */    missing_udP (vec);    missing_udP (si);    /*     *  Check if we need to create a new socket or just     *  reuse an already bound socket.     */    if (sd < 0)        {		/* 	 *  Allocate a new ssap block for this calling/called address pair. 	 */    	if ( (sb = newsublk () ) == NULL)	    return susaplose (si,			      SC_CONGEST,			      NULLCP,			      SuErrString (UDERR_NO_MEMORY));	}    else	{	/*  	 *  Find the correct session block and set the signal mask. 	 */     	if ((sb = findsublk (sd)) == NULL)	    {	    (void) sigsetmask (smask); 	     return susaplose (si,			       SC_PARAMETER,			       NULLCP,			       SuErrString(UDERR_INVALID_SESSION_DESC)); 	    }	}    /*       *  Now pass thru the request to TSAP.     */    if ( (result = TuSave (sd, vecp, vec, td) ) == NOTOK)	return ts2suslose ( si, "TuSave", td);    return result;}/*  */ /*    **************************************************************** *								* *  SUnitDataRequest                                            * *  								* *  This routine implements the S-UNITDATA.REQUEST primitive    * *  for writing data thru a datagram session service.  This     * *  routine is used for unitdata service to remote addresses    * *  that havn't been binded.  This routine blocks until the     * *  data is written.						* *  								* **************************************************************** */int     SUnitDataRequest (calling, called, data, cc, qos, si)struct SSAPaddr *calling,		*called;register char	*data;int		cc;struct QOStype  *qos;struct  SSAPindication *si;{int	sd;#ifdef HULADEBUG	printf ("\n     in SUnitDataRequest \n");#endif/* *  Create the socket on the fly.  We do the bind here because *  tsap data writes expect iovecs instead of char data ptr. */    sd = SUnitDataBind (NOTOK, calling, called, qos, si);    if (sd == NOTOK)	return NOTOK;/*   *  Now do the S_UNITDATA send. */    if (SUnitDataWrite (sd, data, cc, si) == NOTOK)	return NOTOK;/* *  Unbind the socket. */    SUnitDataUnbind (sd, si);    return OK;}/*  *//* **************************************************************** *                                                              * *  SUnitDataWrite 						*  *      							* *  This routine implements the ssap unit write interface for   * *  writing user data over transport datagram service where     * *  the datagram service has already been established and the   * *  remote address has been binded on the socket.               * *								* *  This routine blocks until completion.			* *								* **************************************************************** */int     SUnitDataWrite (sd, data, cc, si)int 	 	sd;register char	*data;int		cc;struct  SSAPindication *si;{int 	 n, len, j;SBV      smask;			 	/* signal save mask */int      result; 		 	/* write result     */register struct ssapblk *sb;	 	/* ssap ctl blk ptr */register struct ssapkt *s;struct TSAPdisconnect   tds;register struct TSAPdisconnect *td = &tds;struct udvec vvs[3];register struct udvec  *vv, *xv;#ifdef HULADEBUG	printf ("\n     in SUnitDataWrite \n");	printf ("\n     writing on socket %d \n", sd);#endif    /*     * 	Check for missing parameters.     */    missing_udP (data);    missing_udP (si);    /*     *  Check user data.     */    if ( (cc <= 0) || (cc > UD_MAX_DATA) )	return susaplose (si,			  SC_PARAMETER,			  NULLCP,		  	  SuErrString(UDERR_ILLEGAL_UD_SIZE));    /*      *  Block any signals while we do the write.     */    smask = sigioblock ();    /*      *  Find the correct session block and set the signal mask.     */     ssap_udPsig (sb, sd);        /*     *  Init our working udvec struct.     */    vv = vvs;    vvs[0].uv_base = vvs[1].uv_base = vvs[2].uv_base = NULL;    /*     *  Allocate a new UNITDATA spkt for this datagram message.     */#ifdef HULADEBUG	printf ("\n     allocating new SPKT \n");#endif    if ((s = newspkt (SPDU_UD)) == NULL)        return susaplose (si,			  SC_CONGEST,			  NULLCP,			  SuErrString(UDERR_NO_MEMORY));    /*     *  Set the parameter field values in the spkt for encoding.     */    s -> s_mask |= (SMASK_SPDU_UD | SMASK_UD_VERSION);    s -> s_ud_version = sb -> sb_version;    if (sb -> sb_initiating.sa_selectlen > 0)        {	s -> s_mask |= SMASK_UD_CALLING;	bcopy (sb -> sb_initiating.sa_selector, s -> s_ud_calling,	        s -> s_ud_callinglen = sb -> sb_initiating.sa_selectlen);	}    if (sb -> sb_responding.sa_selectlen > 0) 	{	s -> s_mask |= SMASK_UD_CALLED;	bcopy (sb -> sb_responding.sa_selector, s -> s_ud_called,		s -> s_ud_calledlen = sb -> sb_responding.sa_selectlen);    	}#ifdef HULADEBUG		spkt2text (stdout, s, NULL);#endif    /*     *  Format the session protocol data unit.     *  The encode routine will put the SPDU header in the base     *  portion of the work udvec[0] passed to it.     */#ifdef HULADEBUG		printf ("\n     formatting the unitdata SPDU \n");#endif     if (spkt2tsdu (s, &vv -> uv_base, &vv -> uv_len) == NOTOK)        {	susaplose (si, 		   SC_PROTOCOL,		   NULLCP,		   SuErrString (UDERR_ENCODE_UDSPDU_FAILED));	freespkt (s);	return NOTOK;	}#ifdef HULADEBUG	for (j = 0; j < vv->uv_len; j++)	    printf ( " %x ", *(vv->uv_base + j) );#endif		    /*     *  Now copy the user data to the work udvec.  The SPDU UD header     *  was encoded and put as the 1st base element so put the user     *  data as the second element.     */    xv = ++vv;    xv -> uv_base = data;    xv -> uv_len = cc;    freespkt (s);    s = NULL;   /*    *  Do the unit data write over the TSAP unitdata service.    */#ifdef HULADEBUG	printf ("\n     calling the TSAP unitdata write \n");#endif    if ( (result = TUnitDataWrite (sb -> sb_fd, vvs, td)) == NOTOK)        ts2suslose (si, "TUnitDataWrite", td);    /*       *  Free the encoded header.     */	    free (vvs[0].uv_base);    /*    *  Restore the mask.    */    (void) sigiomask (smask);    if (result == NOTOK)    	return NOTOK;    else        return OK;}/*  */#define	NSPUV	12	/* really should be MSG_MAXIOVLEN - 4 *//* **************************************************************** *                                                              * *  SUnitDataWriteV 						*  *      							* *  This routine implements the ssap unit write interface for   * *  writing user vextors over transport datagram service where  * *  the datagram service has already been established and the   *

⌨️ 快捷键说明

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