📄 tsapunitdata.c
字号:
register struct tsapblk *tb;int result;SBV smask; /* signal save mask */#ifdef HULADEBUG printf ("\n in TUnitDataUnbind \n");#endif/* * Find the correct transport block and set the signal mask. */ tsap_udPsig (tb, sd);/* * Close the transport socket and free its resources. */#ifdef HULADEBUG printf ("\n freeing the tsap block \n");#endif freetublk (tb); return OK; }/* *//* **************************************************************** * * * TuSave * * * * This routine sets up a control block path and socket for * * datagram that has arrived on the server listen socket. It * * saves the datagram in the control block to return it on the * * first read. This is required since we want to bind and * * write a server response on a new socket without tying up * * the common listen socket. * * * * returns: socket descriptor * * * **************************************************************** */int TuSave (sd, vecp, vec, td)int sd;register int vecp;register char **vec;register struct TSAPdisconnect *td;{ register struct tsapblk *tb; char domain[NASIZE]; register struct NSAPaddr *na; int fd; int result; SBV smask; /* signal save mask */ if (vecp < 3) return tusaplose (td, DR_PARAMETER, NULLCP, TuErrString(UDERR_BAD_INIT_VECTOR)); missing_udP (vec); missing_udP (td); /* * Check if we need to create a new socket or just * reuse an already bound socket. */ if (sd < 0) { /* * Allocate a new tsap block and create a new socket. */ if ( (tb = newtublk () ) == NULL) return tusaplose (td, DR_CONGEST, NULLCP, TuErrString(UDERR_NO_MEMORY) ); /* * Now parse the vector for the args. * vec[0] = ptr to buffer containing: * network type * socket fd * remote host name (sock addr) * vec[1] = TPDU */ vec += vecp - 2; switch (*vec[0]) { case NT_TCP: case NT_UDP:#ifdef UDP if (sscanf((vec[0]+1), "%d %s %s", &fd, na->na_domain, domain) != 3) return tusaplose (td, DR_PARAMETER, NULLCP, TuErrString(UDERR_BAD_INIT_VECTOR)); /* * Create the temp socket. We don't need addresses since * the remote address will be specifeied when the service binds. */ if ((result = (*tb -> tb_UnitDataStart) (tb, NULL, NULL, TUNITDATA_START), td) != OK)#endif default: (void) tusaplose (td, DR_ADDRESS, NULLCP, "unknown network type: 0x%x (%c)", *vec[0], *vec[0]); freetblk (tb); return NOTOK; } } else { /* * Find the correct tsap block and set the signal mask. */ tsap_udPsig (tb, sd); } /* * Now save the TPDU in the control block for the first read. */ tb -> tb_holding_tpdu = 1; bcopy ( vec[1], &tb -> tb_hold_tpdu, strlen (vec[1]) ); bzero (vec[0], strlen (vec[0])); bzero (vec[1], strlen (vec[1])); *vec = NULL; return (tb -> tb_fd);}/* */ /* **************************************************************** * * * TUnitDataRequest * * * * This routine implements the T-UNITDATA.REQUEST primitive * * for writing data to a datagram transport 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 TUnitDataRequest (calling, called, qos, uv, td)struct TSAPaddr *calling, *called;struct QOStype *qos;register struct udvec *uv;struct TSAPdisconnect *td;{int sd;#ifdef HULADEBUG printf ("\n in TUnitDataRequest \n");#endif/* * Create the socket on the fly. */ sd = TUnitDataBind (calling, called, qos, td); if (sd == NOTOK) return NOTOK;/* * Now do the datagram send. */ if ( TUnitDataWrite (sd, uv, td) == NOTOK) return NOTOK;/* * Unbind the socket. */ TUnitDataUnbind (sd, td); return OK;} /* *//* **************************************************************** * * * TUnitDataWrite * * * * This routine implements the tsap 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 TUnitDataWrite (sd, uv, td)int sd;register struct udvec *uv;register struct TSAPdisconnect td;{int n, cc, hlen;SBV smask; /* signal save mask */int result; /* write result */register struct udvec *vv; /* udvec */register struct tsapblk *tb; /* transport blk ptr*/char *data, *buffer, *hptr; /* data buffer ptr */#ifdef HULADEBUG printf ("\n in TUnitDataWrite \n"); printf ("\n writing on socket %d \n", sd);#endif/* * Check for missing parameters. */ missing_udP (uv); missing_udP (uv -> uv_base); /* * Check user data. */ cc = 0; for (vv = uv; vv -> uv_base; vv++) {#ifdef HULADEBUG printf ("\n scanning the udvec - len = %d ", vv->uv_len);#endif cc += vv -> uv_len; } if (n <= 0) return tusaplose ( td, DR_PARAMETER, NULLCP, TuErrString(UDERR_ILLEGAL_UD_SIZE) ); /* * Block any signals while we do the write. */ smask = sigioblock ();/* * Find the correct transport block and set the signal mask. */ tsap_udPsig (tb, sd);/* * Add the ISO T-UNITDATA header. For prototype purposes we * do this as a subroutine call. Ideally, it should be * implemented as a bona-fide transport service. */ hlen = 0; hlen = T_UnitDataWrite (tb, uv, &hptr, td); /* * Now check if we have to allocate a contiguous buffer * for the buffer since datagrams must be a complete msg. * If the len in the first udvec is not the total len, it * means that the data spans multiple buffers. *//* * NOTE: FOR ISO HEADER, WE WILL ALWAYS SPAN BUFFERS */ if ( (cc != uv -> uv_len) || (hlen > 0) ) {#ifdef HULADEBUG printf ("\n data spans multiple buffers - alloc buf %d \n", cc);#endif /* * Allocate the buffer. */ buffer = (char *) calloc (1, cc + hlen); if (buffer == NULL) return tusaplose ( td, DR_CONGEST, NULLCP, TuErrString(UDERR_NO_MEMORY) ); /* * Save the buffer ptr. */ data = buffer; /* * Copy the header first. */ if (hlen > 0) { bcopy (hptr, buffer, hlen); buffer += hlen; } /* * Now copy all the non-contiguous buffers into the * contiguous buffer we just allocated. */ for (vv = uv; vv -> uv_base; vv++) { bcopy (vv -> uv_base, buffer, vv -> uv_len); buffer += vv -> uv_len; } } /* end if non-contiguous user data */ else { data = uv -> uv_base;#ifdef HULADEBUG printf ("\n data is contiguous - %d bytes \n", cc);#endif }/* * Do the unit data write over the real transport service. * The service entry point is in the transport block service * area. It returns the number of bytes written. */#ifdef HULADEBUG printf ("\n Tunitdata ... \n"); for (n=0; n < min(cc,256); n++) printf (" %x", *(data+n) );#endif if (*tb -> tb_UnitDataWrite) result = (*tb -> tb_UnitDataWrite) (sd, data, cc, td); else result = 0; if (data == uv -> uv_base) free ((char *) data);/* * Restore the mask. */ (void) sigiomask (smask);/* * And return the result from the write. To succeed, it * must have written the entire length cc since datagrams * cannot be partially sent. */ if (result == cc) return OK; else return NOTOK;}/* */ /* **************************************************************** * * * TUnitDataRead * * * * This routine reads datagram messages from the transport * * unit data service. It blocks until data is read or secs * * expires. If secs is 0, it blocks indefinitely. * * * * returns: # of bytes read * * * **************************************************************** */int TUnitDataRead (sd, tud, secs, td)int sd;register struct TSAPunitdata *tud;int secs;struct TSAPdisconnect *td;{ int cc, hlen; SBV smask; /* signal save mask */ register struct tsapblk *tb; register struct qbuf *qb; struct sockaddr_in socket; register struct hostent *hp; register struct NSAPaddr *na;#ifdef HULADEBUG int j; printf ("\n in TUnitDataRead \n");#endif/* * Check for missing parameters. */ missing_udP (tud);/* * Block any incomming signals while we do the read. */ smask = sigioblock ();/* * Find the current transport block and set the signal mask. */ tsap_udPsig (tb, sd);/* * Check if we are holding a tpdu that hasn't been read yet. * This would happen with dynamic service invocation on the * tsap unitdata daemon side of things where it calls the * the save function on unitdata indications and then spawns * the service. */ if (tb -> tb_holding_tpdu) { /* * Copy the held one into the real one. */ bcopy ( &tb -> tb_hold_tpdu, tud, sizeof(tb -> tb_hold_tpdu) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -