|
|
1.1 root 1: /* ts2tcp.c - TPM: TCP interface */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/tsap/RCS/ts2tcp.c,v 7.5 90/07/09 14:51:21 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/tsap/RCS/ts2tcp.c,v 7.5 90/07/09 14:51:21 mrose Exp $
9: *
10: *
11: * $Log: ts2tcp.c,v $
12: * Revision 7.5 90/07/09 14:51:21 mrose
13: * sync
14: *
15: * Revision 7.4 90/03/23 17:31:28 mrose
16: * 8
17: *
18: * Revision 7.3 90/02/19 13:07:26 mrose
19: * update
20: *
21: * Revision 7.2 89/12/08 09:41:39 mrose
22: * touch-up
23: *
24: * Revision 7.1 89/12/07 01:07:36 mrose
25: * queued writes
26: *
27: * Revision 7.0 89/11/23 22:30:40 mrose
28: * Release 6.0
29: *
30: */
31:
32: /*
33: * NOTICE
34: *
35: * Acquisition, use, and distribution of this module and related
36: * materials are subject to the restrictions of a license agreement.
37: * Consult the Preface in the User's Manual for the full terms of
38: * this agreement.
39: *
40: */
41:
42:
43: /* LINTLIBRARY */
44:
45: #include <stdio.h>
46: #include "tpkt.h"
47: #include "tailor.h"
48:
49: #ifdef TCP
50: #include "internet.h"
51: #include <errno.h>
52: #ifdef BSD42
53: #include <sys/ioctl.h>
54: #endif
55:
56: #define MAX1006 2048 /* could be as high as TPKT_MAXLEN */
57:
58: /* DATA */
59:
60: #ifdef FIONBIO
61: #define NODELAY
62: #endif
63:
64: #ifdef NODELAY
65: static fd_set inprogress;
66: static struct sockaddr_in *peers = NULL;
67: #endif
68:
69:
70: extern int errno;
71:
72: /* N-CONNECT.REQUEST */
73:
74: int tcpopen (tb, local, remote, td, async)
75: register struct tsapblk *tb;
76: struct NSAPaddr *local,
77: *remote;
78: struct TSAPdisconnect *td;
79: int async;
80: {
81: int fd;
82: #ifdef FIONBIO
83: int onoff;
84: #endif
85: struct sockaddr_in lo_socket,
86: in_socket;
87: register struct sockaddr_in *lsock = &lo_socket,
88: *isock = &in_socket;
89: register struct hostent *hp;
90: register struct servent *sp;
91:
92: #ifndef NODELAY
93: if (async)
94: return tsaplose (td, DR_PARAMETER, NULLCP,
95: "asynchronous not supported");
96: #endif
97:
98: bzero ((char *) isock, sizeof *isock);
99:
100: if (remote -> na_port == 0) {
101: if ((sp = getservbyname ("tsap", "tcp")) == NULL)
102: sp = getservbyname ("iso-tsap", "tcp");
103: isock -> sin_port = sp ? sp -> s_port : htons ((u_short) 102);
104: }
105: else
106: isock -> sin_port = remote -> na_port;
107:
108: if ((hp = gethostbystring (remote -> na_domain)) == NULL)
109: return tsaplose (td, DR_ADDRESS, NULLCP, "%s: unknown host",
110: remote -> na_domain);
111: #ifdef notanymore
112: (void) strncpy (remote -> na_domain, hp -> h_name,
113: sizeof remote -> na_domain);
114: #endif
115:
116: isock -> sin_family = hp -> h_addrtype;
117: inaddr_copy (hp, isock);
118:
119: #ifndef notanymore
120: (void) strcpy (remote -> na_domain, inet_ntoa (isock -> sin_addr));
121: #endif
122:
123: if (local && local -> na_domain[0]) {
124: bzero ((char *) lsock, sizeof *lsock);
125:
126: if ((hp = gethostbystring (local -> na_domain)) == NULL)
127: return tsaplose (td, DR_ADDRESS, NULLCP, "%s: unknown host",
128: local -> na_domain);
129:
130: if ((lsock -> sin_family = hp -> h_addrtype) != isock -> sin_family)
131: return tsaplose (td, DR_ADDRESS, NULLCP,
132: "address family mismatch");
133:
134: inaddr_copy (hp, lsock);
135: }
136: else
137: lsock = NULL;
138:
139: if ((fd = start_tcp_client (lsock, 0)) == NOTOK)
140: return tsaplose (td, DR_CONGEST, "socket", "unable to start");
141:
142: #ifdef FIONBIO
143: if (async)
144: (void) ioctl (fd, FIONBIO, (onoff = 1, (char *) &onoff));
145: #endif
146: tb -> tb_fd = fd;
147: (void) TTService (tb);
148:
149: if (join_tcp_server (fd, isock) == NOTOK) {
150: #ifdef NODELAY
151: if (async)
152: switch (errno) {
153: case EINPROGRESS:
154: if (peers == NULL) {
155: peers = (struct sockaddr_in *)
156: calloc ((unsigned) getdtablesize (),
157: sizeof *peers);
158: if (peers == NULL) {
159: (void) tsaplose (td, DR_CONGEST, NULLCP,
160: "out of memory");
161: (void) close_tcp_socket (fd);
162: return (tb -> tb_fd = NOTOK);
163: }
164:
165: FD_ZERO (&inprogress);
166: }
167: FD_SET (fd, &inprogress);
168: peers[fd] = *isock;/* struct copy */
169: return OK;
170:
171: case EISCONN:
172: goto done;
173:
174: default:
175: break;
176: }
177: #endif
178:
179: (void) tsaplose (td, DR_REFUSED, "connection", "unable to establish");
180: (void) close_tcp_socket (fd);
181: return (tb -> tb_fd = NOTOK);
182: }
183: #ifdef NODELAY
184: done: ;
185: #endif
186:
187: #ifdef FIONBIO
188: if (async)
189: (void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff));
190: #endif
191:
192: return DONE;
193: }
194:
195: /* */
196:
197: #ifndef NODELAY
198: /* ARGSUSED */
199: #endif
200:
201: static int tcpretry (tb, td)
202: struct tsapblk *tb;
203: struct TSAPdisconnect *td;
204: {
205: #ifdef NODELAY
206: #ifdef FIONBIO
207: int onoff;
208: #endif
209: int fd = tb -> tb_fd;
210: fd_set mask;
211: struct sockaddr_in *isock = &peers[fd];
212:
213: FD_ZERO (&mask);
214: FD_SET (fd, &mask);
215: if (xselect (fd + 1, NULLFD, &mask, NULLFD, 0) < 1)
216: return OK;
217:
218: if (!FD_ISSET (fd, &inprogress))
219: return DONE;
220:
221: isock = &peers[fd];
222: if (join_tcp_server (fd, isock) == NOTOK) {
223: switch (errno) {
224: case EINPROGRESS:
225: return OK;
226:
227: case EISCONN:
228: goto done;
229:
230: case EINVAL: /* UNIX bug: could be any socket errno, e.g.,
231: ETIMEDOUT */
232: errno = ECONNREFUSED;
233: /* and fall */
234: default:
235: break;
236: }
237:
238: (void) tsaplose (td, DR_REFUSED, "connection", "unable to establish");
239: FD_CLR (fd, &inprogress);
240: (void) close_tcp_socket (fd);
241: return (tb -> tb_fd = NOTOK);
242: }
243: done: ;
244:
245: #ifdef FIONBIO
246: (void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff));
247: #endif
248:
249: FD_CLR (fd, &inprogress);
250:
251: return DONE;
252: #else
253: return tsaplose (td, DR_OPERATION, NULLCP, "connection not in progress");
254: #endif
255: }
256:
257: /* init for read from network */
258:
259: #ifndef BRIDGE_X25
260: static
261: #endif
262: int tcpinit (fd, t)
263: int fd;
264: register struct tsapkt *t;
265: {
266: register int cc,
267: i;
268: register char *bp;
269:
270: for (bp = (char *) &t -> t_pkthdr, i = TPKT_HDRLEN (t);
271: i > 0;
272: bp += cc, i -= cc)
273: switch (cc = read_tcp_socket (fd, bp, i)) {
274: case NOTOK:
275: case OK:
276: return DR_NETWORK;
277:
278: default:
279: break;
280: }
281:
282: if (t -> t_vrsn != TPKT_VRSN)
283: return DR_PROTOCOL;
284:
285: if ((t -> t_length = ntohs (t -> t_length)) < TPKT_HDRLEN (t))
286: return DR_LENGTH;
287:
288: return OK;
289: }
290:
291: /* */
292:
293: /* ARGSUSED */
294:
295: char *tcpsave (fd, sin, cp1, cp2, td)
296: int fd;
297: struct sockaddr_in *sin;
298: char *cp1,
299: *cp2;
300: struct TSAPdisconnect *td;
301: {
302: static char buffer[BUFSIZ];
303:
304: (void) sprintf (buffer, "%c%d %s %s", NT_TCP, fd, cp1, cp2);
305:
306: return buffer;
307: }
308:
309: /* */
310:
311: int tcprestore (tb, buffer, td)
312: register struct tsapblk *tb;
313: char *buffer;
314: struct TSAPdisconnect *td;
315: {
316: int fd;
317: char domain[NSAP_DOMAINLEN + 1];
318: register struct NSAPaddr *na;
319: register struct tsapADDR *ta;
320:
321: ta = &tb -> tb_initiating;
322: ta -> ta_present = 1;
323: na = &ta -> ta_addr;
324: na -> na_stack = NA_TCP;
325: na -> na_community = ts_comm_tcp_default;
326:
327: if (sscanf (buffer, "%d %s %s", &fd, na -> na_domain, domain) != 3
328: || fd < 0)
329: return tsaplose (td, DR_PARAMETER, NULLCP,
330: "bad initialization vector \"%s\"", buffer);
331:
332: tb -> tb_fd = fd;
333: (void) TTService (tb);
334:
335: ta = &tb -> tb_responding;
336: ta -> ta_present = 1;
337: na = &ta -> ta_addr;
338: na -> na_stack = NA_TCP;
339: na -> na_community = ts_comm_tcp_default;
340: (void) strncpy (na -> na_domain, domain, sizeof na -> na_domain);
341:
342: return OK;
343: }
344:
345: /* */
346:
347: int TTService (tb)
348: register struct tsapblk *tb;
349: {
350: struct tsapkt *t;
351:
352: tb -> tb_flags |= TB_TCP;
353:
354: tb -> tb_tsdusize = MAX1006
355: - (tb -> tb_tpduslop = sizeof t -> t_pkthdr + DT_MAGIC);
356:
357: tb -> tb_retryfnx = tcpretry;
358:
359: tb -> tb_initfnx = tcpinit;
360: tb -> tb_readfnx = read_tcp_socket;
361: tb -> tb_writefnx = tp0write;
362: tb -> tb_closefnx = close_tcp_socket;
363: tb -> tb_selectfnx = select_tcp_socket;
364:
365: tp0init (tb);
366: }
367: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.