|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T t
Length: 9189 (0x23e5)
Types: TextFile
Names: »ts2tcp.c«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape
└─⟦eba4602b1⟧ »./isode-5.0.tar.Z«
└─⟦d3ac74d73⟧
└─⟦this⟧ »isode-5.0/tsap/ts2tcp.c«
/* ts2tcp.c - TPM: TCP interface */
#ifndef lint
static char *rcsid = "$Header: /f/osi/tsap/RCS/ts2tcp.c,v 6.0 89/03/18 23:45:22 mrose Rel $";
#endif
/*
* $Header: /f/osi/tsap/RCS/ts2tcp.c,v 6.0 89/03/18 23:45:22 mrose Rel $
*
*
* $Log: ts2tcp.c,v $
* Revision 6.0 89/03/18 23:45:22 mrose
* Release 5.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.
*
*/
/* LINTLIBRARY */
#include <stdio.h>
#include "tpkt.h"
#include "tailor.h"
#ifdef TCP
#include "internet.h"
#include <errno.h>
#ifdef BSD42
#include <sys/ioctl.h>
#include <sys/time.h>
#endif
#ifdef WRITEV
#include <sys/uio.h>
#endif
/* \f
DATA */
#ifdef FIONBIO
#define NODELAY
#endif
#ifdef NODELAY
static fd_set inprogress;
static struct sockaddr_in *peers = NULL;
#endif
extern int errno;
/* \f
N-CONNECT.REQUEST */
int tcpopen (tb, local, remote, td, async)
register struct tsapblk *tb;
struct NSAPaddr *local,
*remote;
struct TSAPdisconnect *td;
int async;
{
int fd;
#ifdef FIONBIO
int onoff;
#endif
struct sockaddr_in lo_socket,
in_socket;
register struct sockaddr_in *lsock = &lo_socket,
*isock = &in_socket;
register struct hostent *hp;
register struct servent *sp;
#ifndef NODELAY
if (async)
return tsaplose (td, DR_PARAMETER, NULLCP,
"asynchronous not supported");
#endif
bzero ((char *) isock, sizeof *isock);
if (remote -> na_port == 0) {
if ((sp = getservbyname ("tsap", "tcp")) == NULL)
return tsaplose (td, DR_ADDRESS, NULLCP,
"tcp/tsap: unknown service");
isock -> sin_port = sp -> s_port;
}
else
isock -> sin_port = remote -> na_port;
if ((hp = gethostbystring (remote -> na_domain)) == NULL)
return tsaplose (td, DR_ADDRESS, NULLCP, "%s: unknown host",
remote -> na_domain);
(void) strncpy (remote -> na_domain, hp -> h_name,
sizeof remote -> na_domain);
isock -> sin_family = hp -> h_addrtype;
inaddr_copy (hp, isock);
if (local && local -> na_domain[0]) {
bzero ((char *) lsock, sizeof *lsock);
if ((hp = gethostbystring (local -> na_domain)) == NULL)
return tsaplose (td, DR_ADDRESS, NULLCP, "%s: unknown host",
local -> na_domain);
if ((lsock -> sin_family = hp -> h_addrtype) != isock -> sin_family)
return tsaplose (td, DR_ADDRESS, NULLCP,
"address family mismatch");
inaddr_copy (hp, lsock);
}
else
lsock = NULL;
if ((fd = start_tcp_client (lsock, 0)) == NOTOK)
return tsaplose (td, DR_CONGEST, "socket", "unable to start");
#ifdef FIONBIO
if (async)
(void) ioctl (fd, FIONBIO, (onoff = 1, (char *) &onoff));
#endif
tb -> tb_fd = fd;
(void) TTService (tb);
if (join_tcp_server (fd, isock) == NOTOK) {
#ifdef NODELAY
if (async)
switch (errno) {
case EINPROGRESS:
if (peers == NULL) {
peers = (struct sockaddr_in *)
calloc ((unsigned) getdtablesize (),
sizeof *peers);
if (peers == NULL) {
(void) tsaplose (td, DR_CONGEST, NULLCP,
"out of memory");
(void) close_tcp_socket (fd);
return (tb -> tb_fd = NOTOK);
}
FD_ZERO (&inprogress);
}
FD_SET (fd, &inprogress);
peers[fd] = *isock;/* struct copy */
return OK;
case EISCONN:
goto done;
default:
break;
}
#endif
(void) tsaplose (td, DR_REFUSED, "connection", "unable to establish");
(void) close_tcp_socket (fd);
return (tb -> tb_fd = NOTOK);
}
#ifdef NODELAY
done: ;
#endif
#ifdef FIONBIO
if (async)
(void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff));
#endif
return DONE;
}
/* \f
*/
#ifndef NODELAY
/* ARGSUSED */
#endif
static int tcpretry (tb, td)
struct tsapblk *tb;
struct TSAPdisconnect *td;
{
#ifdef NODELAY
#ifdef FIONBIO
int onoff;
#endif
int fd = tb -> tb_fd;
fd_set mask;
struct sockaddr_in *isock = &peers[fd];
FD_ZERO (&mask);
FD_SET (fd, &mask);
if (xselect (fd + 1, NULLFD, &mask, NULLFD, 0) < 1)
return OK;
if (!FD_ISSET (fd, &inprogress))
return DONE;
isock = &peers[fd];
if (join_tcp_server (fd, isock) == NOTOK) {
switch (errno) {
case EINPROGRESS:
return OK;
case EISCONN:
goto done;
case EINVAL: /* UNIX bug: could be any socket errno, e.g.,
ETIMEDOUT */
errno = ECONNREFUSED;
/* and fall */
default:
break;
}
(void) tsaplose (td, DR_REFUSED, "connection", "unable to establish");
FD_CLR (fd, &inprogress);
(void) close_tcp_socket (fd);
return (tb -> tb_fd = NOTOK);
}
done: ;
#ifdef FIONBIO
(void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff));
#endif
FD_CLR (fd, &inprogress);
return DONE;
#else
return tsaplose (td, DR_OPERATION, NULLCP, "connection not in progress");
#endif
}
/* \f
init for read from network */
#ifndef BRIDGE_X25
static
#endif
int tcpinit (fd, t)
int fd;
register struct tsapkt *t;
{
register int cc,
i;
register char *bp;
for (bp = (char *) &t -> t_pkthdr, i = TPKT_HDRLEN (t);
i > 0;
bp += cc, i -= cc)
switch (cc = read_tcp_socket (fd, bp, i)) {
case NOTOK:
case OK:
return DR_NETWORK;
default:
break;
}
if (t -> t_vrsn != TPKT_VRSN)
return DR_PROTOCOL;
if ((t -> t_length = ntohs (t -> t_length)) < TPKT_HDRLEN (t))
return DR_LENGTH;
return OK;
}
/* \f
write to network */
#ifndef BRIDGE_X25
static
#endif
int tcpwrite (fd, t, cp, n)
int fd;
register struct tsapkt *t;
char *cp;
int n;
{
register int cc;
register struct udvec *uv;
#ifdef WRITEV
struct iovec iovs[NTPUV + 4];
register struct iovec *iov;
#else
register char *p,
*q;
#endif
#ifdef WRITEV
iov = iovs;
cc = 0;
iov -> iov_base = (char *) &t -> t_pkthdr;
cc += (iov -> iov_len = TPKT_HDRLEN (t));
iov++;
iov -> iov_base = cp;
cc += (iov -> iov_len = n);
iov++;
if (t -> t_vdata) {
iov -> iov_base = t -> t_vdata;
cc += (iov -> iov_len = t -> t_vlen);
iov++;
}
for (uv = t -> t_udvec; uv -> uv_base; uv++) {
iov -> iov_base = uv -> uv_base;
cc += (iov -> iov_len = uv -> uv_len);
iov++;
}
if (writev (fd, iovs, iov - iovs) != cc)
cc = NOTOK;
#else
cc = TPKT_HDRLEN (t) + n;
if (t -> t_vdata)
cc += t -> t_vlen;
for (uv = t -> t_udvec; uv -> uv_base; uv++)
cc += uv -> uv_len;
if (p = malloc ((unsigned) cc)) {
bcopy ((char *) &t -> t_pkthdr, q = p, TPKT_HDRLEN (t));
q += TPKT_HDRLEN (t);
bcopy (cp, q, n);
q += n;
if (t -> t_vdata) {
bcopy (t -> t_vdata, q, t -> t_vlen);
q += t -> t_vlen;
}
for (uv = t -> t_udvec; uv -> uv_base; uv++) {
bcopy (uv -> uv_base, q, uv -> uv_len);
q += uv -> uv_len;
}
if (write_tcp_socket (fd, p, cc) != cc)
cc = NOTOK;
free (p);
goto out;
}
SLOG (tsap_log, LLOG_EXCEPTIONS, NULLCP,
("unable to malloc %d octets for pseudo-writev, continuing...",
cc));
cc = TPKT_HDRLEN (t);
if (write_tcp_socket (fd, (char *) &t -> t_pkthdr, cc) != cc) {
err: ;
cc = NOTOK;
goto out;
}
if (write_tcp_socket (fd, cp, n) != n)
goto err;
cc += n;
if (t -> t_vdata
&& write_tcp_socket (fd, t -> t_vdata, t -> t_vlen) != t -> t_vlen)
goto err;
cc += t -> t_vlen;
for (uv = t -> t_udvec; uv -> uv_base; uv++) {
if (write_tcp_socket (fd, uv -> uv_base, uv -> uv_len) != uv -> uv_len)
goto err;
cc += uv -> uv_len;
}
out: ;
#endif
return cc;
}
/* \f
*/
/* ARGSUSED */
char *tcpsave (fd, sin, cp1, cp2, td)
int fd;
struct sockaddr_in *sin;
char *cp1,
*cp2;
struct TSAPdisconnect *td;
{
static char buffer[BUFSIZ];
(void) sprintf (buffer, "%c%d %s %s", NT_TCP, fd, cp1, cp2);
return buffer;
}
/* \f
*/
int tcprestore (tb, buffer, td)
register struct tsapblk *tb;
char *buffer;
struct TSAPdisconnect *td;
{
int fd;
char domain[NSAP_DOMAINLEN + 1];
register struct NSAPaddr *na;
register struct TSAPaddr *ta;
ta = &tb -> tb_initiating;
ta -> ta_naddr = 1;
na = ta -> ta_addrs;
na -> na_type = NA_TCP;
if (sscanf (buffer, "%d %s %s", &fd, na -> na_domain, domain) != 3
|| fd < 0)
return tsaplose (td, DR_PARAMETER, NULLCP,
"bad initialization vector \"%s\"", buffer);
tb -> tb_fd = fd;
(void) TTService (tb);
ta = &tb -> tb_responding;
ta -> ta_naddr = 1;
na = ta -> ta_addrs;
na -> na_type = NA_TCP;
(void) strncpy (na -> na_domain, domain, sizeof na -> na_domain);
return OK;
}
/* \f
*/
int TTService (tb)
register struct tsapblk *tb;
{
struct tsapkt *t;
tb -> tb_flags |= TB_TCP;
tb -> tb_tsdusize = TPKT_MAXLEN
- (tb -> tb_tpduslop = sizeof t -> t_pkthdr + DT_MAGIC);
tb -> tb_retryfnx = tcpretry;
tb -> tb_initfnx = tcpinit;
tb -> tb_readfnx = read_tcp_socket;
tb -> tb_writefnx = tcpwrite;
tb -> tb_closefnx = close_tcp_socket;
tb -> tb_selectfnx = select_tcp_socket;
tp0init (tb);
}
#endif