|
|
1.1 root 1: /* tsaprovider.c - implement the transport service */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/tsap/RCS/tsaprovider.c,v 7.3 90/03/23 17:31:50 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/tsap/RCS/tsaprovider.c,v 7.3 90/03/23 17:31:50 mrose Exp $
9: *
10: *
11: * $Log: tsaprovider.c,v $
12: * Revision 7.3 90/03/23 17:31:50 mrose
13: * 8
14: *
15: * Revision 7.2 90/01/11 18:38:09 mrose
16: * real-sync
17: *
18: * Revision 7.1 89/12/07 01:07:53 mrose
19: * queued writes
20: *
21: * Revision 7.0 89/11/23 22:30:56 mrose
22: * Release 6.0
23: *
24: */
25:
26: /*
27: * NOTICE
28: *
29: * Acquisition, use, and distribution of this module and related
30: * materials are subject to the restrictions of a license agreement.
31: * Consult the Preface in the User's Manual for the full terms of
32: * this agreement.
33: *
34: */
35:
36:
37: /* LINTLIBRARY */
38:
39: #include <stdio.h>
40: #include <signal.h>
41: #include "tpkt.h"
42: #include "mpkt.h"
43: #include "isoservent.h"
44: #include "tailor.h"
45:
46:
47: #define selmask(fd,m,n) \
48: { \
49: FD_SET (fd, &(m)); \
50: if ((fd) >= (n)) \
51: (n) = (fd) + 1; \
52: }
53:
54: /* DATA */
55:
56: static int once_only = 0;
57: static struct tsapblk tsapque;
58: static struct tsapblk *THead = &tsapque;
59:
60:
61: #ifndef SIGPOLL
62: static int TPid = NOTOK;
63: #endif
64:
65: /* T-DATA.REQUEST */
66:
67: int TDataRequest (sd, data, cc, td)
68: int sd;
69: char *data;
70: int cc;
71: struct TSAPdisconnect *td;
72: {
73: SBV smask,
74: imask;
75: SFP istat;
76: int result;
77: struct udvec uvs[2];
78: register struct udvec *uv = uvs;
79: register struct tsapblk *tb;
80:
81: missingP (data);
82: if (cc <= 0)
83: return tsaplose (td, DR_PARAMETER, NULLCP,
84: "illegal value for TSDU length (%d)", cc);
85: missingP (td);
86:
87: smask = sigioblock ();
88:
89: tsapPsig (tb, sd);
90:
91: if ((istat = signal (SIGINT, SIG_DFL)) != SIG_DFL) {
92: (void) signal (SIGINT, istat);
93: imask = siginblock ();
94: }
95:
96: uv -> uv_base = data, uv -> uv_len = cc, uv++;
97: uv -> uv_base = NULL;
98:
99: result = (*tb -> tb_writePfnx) (tb, uvs, 0, td);
100:
101: if (istat != SIG_DFL)
102: (void) siginmask (imask);
103:
104: (void) sigiomask (smask);
105:
106: return result;
107: }
108:
109: /* T-EXPEDITED-DATA.REQUEST */
110:
111: int TExpdRequest (sd, data, cc, td)
112: int sd;
113: char *data;
114: int cc;
115: struct TSAPdisconnect *td;
116: {
117: SBV smask,
118: imask;
119: SFP istat;
120: int result;
121: struct udvec uvs[2];
122: register struct udvec *uv = uvs;
123: register struct tsapblk *tb;
124:
125: missingP (data);
126: toomuchP (data, cc, TX_SIZE, "expedited");
127: if (cc <= 0)
128: return tsaplose (td, DR_PARAMETER, NULLCP,
129: "illegal value for XSDU length (%d)", cc);
130: missingP (td);
131:
132: smask = sigioblock ();
133:
134: tsapPsig (tb, sd);
135:
136: if ((istat = signal (SIGINT, SIG_DFL)) != SIG_DFL) {
137: (void) signal (SIGINT, istat);
138: imask = siginblock ();
139: }
140:
141: uv -> uv_base = data, uv -> uv_len = cc, uv++;
142: uv -> uv_base = NULL;
143:
144: if (tb -> tb_flags & TB_EXPD)
145: result = (*tb -> tb_writePfnx) (tb, uvs, 1, td);
146: else
147: result = tsaplose (td, DR_OPERATION, NULLCP,
148: "expedited service unavailable");
149:
150: if (istat != SIG_DFL)
151: (void) siginmask (imask);
152:
153: (void) sigiomask (smask);
154:
155: return result;
156: }
157:
158: /* T-WRITE.REQUEST (pseudo; write user data vectors) */
159:
160: int TWriteRequest (sd, uv, td)
161: int sd;
162: struct udvec *uv;
163: struct TSAPdisconnect *td;
164: {
165: register int n;
166: SBV smask,
167: imask;
168: SFP istat;
169: int result;
170: register struct tsapblk *tb;
171: register struct udvec *vv;
172:
173: missingP (uv);
174: n = 0;
175: for (vv = uv; vv -> uv_base; vv++)
176: n += vv -> uv_len;
177: if (n == 0)
178: return tsaplose (td, DR_PARAMETER, NULLCP, "zero-length TSDU");
179: missingP (td);
180:
181: smask = sigioblock ();
182:
183: tsapPsig (tb, sd);
184:
185: if ((istat = signal (SIGINT, SIG_DFL)) != SIG_DFL) {
186: (void) signal (SIGINT, istat);
187: imask = siginblock ();
188: }
189:
190: result = (*tb -> tb_writePfnx) (tb, uv, 0, td);
191:
192: if (istat != SIG_DFL)
193: (void) siginmask (imask);
194:
195: (void) sigiomask (smask);
196:
197: return result;
198: }
199:
200: /* T-READ.REQUEST (pseudo; synchronous read) */
201:
202: int TReadRequest (sd, tx, secs, td)
203: int sd;
204: register struct TSAPdata *tx;
205: int secs;
206: register struct TSAPdisconnect *td;
207: {
208: SBV smask,
209: imask;
210: SFP istat;
211: int nfds,
212: oob,
213: result;
214: fd_set ifds,
215: efds,
216: mask;
217: register struct tsapblk *tb;
218:
219: missingP (tx);
220: missingP (td);
221:
222: smask = sigioblock ();
223:
224: tsapPsig (tb, sd);
225:
226: if ((istat = signal (SIGINT, SIG_DFL)) != SIG_DFL) {
227: (void) signal (SIGINT, istat);
228: imask = siginblock ();
229: }
230:
231: nfds = 0;
232: FD_ZERO (&mask);
233: selmask (tb -> tb_fd, mask, nfds);
234:
235: for (;;) {
236: ifds = efds = mask; /* struct copy */
237:
238: if (tb -> tb_checkfnx == NULLIFP || (*tb -> tb_checkfnx) (tb) != OK)
239: switch ((*tb -> tb_selectfnx) (nfds, &ifds, NULLFD, &efds, secs)) {
240: case NOTOK: /* let read function find error... */
241: ifds = mask;
242: break;
243:
244: case OK:
245: result = tsaplose (td, DR_TIMER, NULLCP, NULLCP);
246: goto out;
247:
248: default:
249: break;
250: }
251: else
252: FD_ZERO (&efds);
253:
254: if ((oob = FD_ISSET (tb -> tb_fd, &efds))
255: || FD_ISSET (tb -> tb_fd, &ifds))
256: result = (*tb -> tb_readPfnx) (tb, tx, td, secs != NOTOK, oob);
257: else
258: result = DONE;
259: if (result != DONE)
260: break;
261: if (secs != NOTOK) {
262: result = tsaplose (td, DR_TIMER, NULLCP, NULLCP);
263: break;
264: }
265: }
266: out: ;
267:
268: if (istat != SIG_DFL)
269: (void) siginmask (imask);
270:
271: (void) sigiomask (smask);
272:
273: return result;
274: }
275:
276: /* T-DISCONNECT.REQUEST */
277:
278: int TDiscRequest (sd, data, cc, td)
279: int sd;
280: char *data;
281: int cc;
282: register struct TSAPdisconnect *td;
283: {
284: SBV smask;
285: int result;
286: register struct tsapblk *tb;
287:
288: toomuchP (data, cc, TD_SIZE, "disconnect");
289:
290: smask = sigioblock ();
291:
292: if ((tb = findtblk (sd)) == NULL) {
293: (void) sigiomask (smask);
294: return tsaplose (td, DR_PARAMETER, NULLCP,
295: "invalid transport descriptor");
296: }
297:
298: result = (*tb -> tb_discPfnx) (tb, data, cc, td);
299:
300: (void) sigiomask (smask);
301:
302: return result;
303: }
304:
305: /* set asynchronous event indications */
306:
307: int TSetIndications (sd, data, disc, td)
308: int sd;
309: IFP data,
310: disc;
311: struct TSAPdisconnect *td;
312: {
313: SBV smask;
314: int result;
315: register struct tsapblk *tb;
316:
317: if (data || disc) {
318: missingP (data);
319: missingP (disc);
320: }
321:
322: smask = sigioblock ();
323:
324: tsapPsig (tb, sd);
325:
326: if (tb -> tb_DataIndication = data)
327: tb -> tb_flags |= TB_ASYN;
328: else
329: tb -> tb_flags &= ~TB_ASYN;
330: tb -> tb_DiscIndication = disc;
331:
332: result = TWakeUp (tb, td);
333:
334: (void) sigiomask (smask);
335:
336: return result;
337: }
338:
339: /* map transport descriptors for select() */
340:
341: int TSelectMask (sd, mask, nfds, td)
342: int sd;
343: fd_set *mask;
344: int *nfds;
345: register struct TSAPdisconnect *td;
346: {
347: SBV smask;
348: register struct tsapblk *tb;
349:
350: missingP (mask);
351: missingP (nfds);
352:
353: smask = sigioblock ();
354:
355: if ((tb = findtblk (sd)) == NULL) {
356: (void) sigiomask (smask);
357: return tsaplose (td, DR_PARAMETER, NULLCP,
358: "invalid transport descriptor");
359: }
360:
361: if (tb -> tb_checkfnx && (*tb -> tb_checkfnx) (tb) == OK) {
362: (void) sigiomask (smask);
363: return tsaplose (td, DR_WAITING, NULLCP, NULLCP);
364: }
365:
366: selmask (tb -> tb_fd, *mask, *nfds);
367:
368: (void) sigiomask (smask);
369:
370: return OK;
371: }
372:
373: /* NSAP interface: N-DATA.INDICATION */
374:
375: /* ARGSUSED */
376:
377: static SFD DATAser (sig, code, sc)
378: int sig;
379: long code;
380: struct sigcontext *sc;
381: {
382: int n,
383: nfds,
384: oob,
385: sd;
386: fd_set ifds,
387: efds,
388: imask,
389: emask;
390: #ifndef BSDSIGS
391: SBV smask;
392: #endif
393: IFP disc;
394: register struct tsapblk *tb,
395: *tb2;
396: struct TSAPdata txs;
397: register struct TSAPdata *tx = &txs;
398: struct TSAPdisconnect tds;
399: register struct TSAPdisconnect *td = &tds;
400:
401: #ifndef BSDSIGS
402: (void) signal (SIGEMT, DATAser);
403:
404: smask = sigioblock ();
405: #endif
406:
407: for (;;) {
408: n = 0;
409: FD_ZERO (&ifds);
410: FD_ZERO (&efds);
411: for (tb = THead -> tb_forw; tb != THead; tb = tb -> tb_forw)
412: if (tb -> tb_fd != NOTOK && (tb -> tb_flags & TB_ASYN)) {
413: nfds = 0;
414: FD_ZERO (&imask);
415: selmask (tb -> tb_fd, imask, nfds);
416: emask = imask; /* struct copy */
417: if ((*tb -> tb_selectfnx) (nfds, &imask, NULLFD, &emask, 0)
418: > OK) {
419: if (FD_ISSET (tb -> tb_fd, &imask))
420: FD_SET (tb -> tb_fd, &ifds);
421: if (FD_ISSET (tb -> tb_fd, &emask))
422: FD_SET (tb -> tb_fd, &efds);
423: n++;
424: }
425: }
426:
427: if (n == 0)
428: break;
429:
430: for (tb = THead -> tb_forw; tb != THead; tb = tb2) {
431: tb2 = tb -> tb_forw;
432:
433: sd = tb -> tb_fd;
434: if ((oob = FD_ISSET (sd, &efds)) || FD_ISSET (sd, &ifds)) {
435: disc = tb -> tb_DiscIndication;
436: switch ((*tb -> tb_readPfnx) (tb, tx, td, 1, oob)) {
437: case NOTOK:
438: (*disc) (sd, td);
439: break;
440:
441: case OK:
442: (*tb -> tb_DataIndication) (sd, tx);
443: break;
444:
445: case DONE: /* partially assembled TSDU */
446: break;
447: }
448: }
449: }
450: }
451:
452: #ifndef SIGPOLL
453: (void) kill (TPid, SIGEMT);
454: #endif
455:
456: #ifndef BSDSIGS
457: (void) sigiomask (smask);
458: #endif
459: }
460:
461: /* */
462:
463: #ifndef SIGPOLL
464: static int TWakeUp (tb, td)
465: register struct tsapblk *tb;
466: struct TSAPdisconnect *td;
467: {
468: int i,
469: nfds;
470: fd_set mask;
471: char buf1[10],
472: buf2[10],
473: buf3[10];
474: register struct isoservent *is;
475: static int inited = 0;
476:
477: if (TPid > OK) {
478: (void) kill (TPid, SIGTERM);
479: TPid = NOTOK;
480: }
481:
482: nfds = 0;
483: FD_ZERO (&mask);
484: for (tb = THead -> tb_forw; tb != THead; tb = tb -> tb_forw)
485: if (tb -> tb_fd != NOTOK && (tb -> tb_flags & TB_ASYN))
486: selmask (tb -> tb_fd, mask, nfds);
487:
488: if (nfds == 0)
489: return OK;
490:
491: if (nfds > sizeof (int) * 8)
492: return tsaplose (td, DR_CONGEST, NULLCP, "you lose");
493: if (!inited) {
494: #ifndef BSDSIGS
495: int smask = sigsetmask (sigblock (0) & ~sigmask (SIGEMT));
496: #endif
497:
498: (void) signal (SIGEMT, DATAser);
499: #ifndef BSDSIGS
500: (void) sigiomask (smask);
501: #endif
502: inited++;
503: }
504:
505: if ((is = getisoserventbyname ("isore", "tsap")) == NULL)
506: return tsaplose (td, DR_CONGEST, NULLCP,
507: "ISO service tsap/isore not found");
508:
509: (void) sprintf (buf1, "%d", nfds);
510: *is -> is_tail++ = buf1;
511: (void) sprintf (buf2, "0x%x", mask.fds_bits[0]);
512: *is -> is_tail++ = buf2;
513: (void) sprintf (buf3, "%d", getpid ());
514: *is -> is_tail++ = buf3;
515: *is -> is_tail = NULL;
516:
517: for (i = 0; i < 5; i++)
518: switch (TPid = vfork ()) {
519: case NOTOK:
520: continue;
521:
522: case OK:
523: (void) signal (SIGEMT, SIG_DFL);
524: (void) execv (*is -> is_vec, is -> is_vec);
525: _exit (1);
526:
527: default:
528: return OK;
529: }
530:
531: return tsaplose (td, DR_CONGEST, "isore", "unable to fork");
532: }
533: #else
534: #ifdef BSDSIGS
535: #include <fcntl.h>
536: #include <sys/ioctl.h>
537: #else
538: #include <sys/stropts.h>
539: #endif
540:
541:
542: static int TWakeUp (tb, td)
543: register struct tsapblk *tb;
544: struct TSAPdisconnect *td;
545: {
546: int result;
547: #ifndef notdef
548: int pgrp;
549: #endif
550: static int inited = 0;
551:
552: if (tb -> tb_flags & TB_ASYN) {
553: if (!inited) {
554: (void) signal (SIGPOLL, DATAser);
555:
556: inited++;
557: }
558:
559: #ifdef BSDSIGS
560: #ifdef notdef
561: if (fcntl (tb -> tb_fd, F_SETOWN, getpid ()) == NOTOK)
562: return tsaplose (td, DR_CONGEST, "failed", "fcntl F_SETOWN");
563: #else
564: pgrp = -getpid ();
565: if (ioctl (tb -> tb_fd, SIOCSPGRP, (char *) &pgrp) == NOTOK)
566: return tsaplose (td, DR_CONGEST, "failed", "ioctl SIOCSPGRP %d",
567: pgrp);
568: #endif
569: if ((result = fcntl (tb -> tb_fd, F_GETFL, 0x00)) == NOTOK)
570: return tsaplose (td, DR_CONGEST, "failed", "fcntl F_GETFL");
571: result |= FASYNC;
572: if (fcntl (tb -> tb_fd, F_SETFL, result) == NOTOK)
573: return tsaplose (td, DR_CONGEST, "failed", "fcntl F_SETFL 0x%x",
574: result);
575: #else
576: #ifdef notdef
577: if (ioctl (tb -> tb_fd, I_GETSIG, &result) == NOTOK)
578: result = 0;
579: result |= S_INPUT;
580: if (ioctl (tb -> tb_fd, I_SETSIG, result) == NOTOK)
581: return tsaplose (td, DR_CONGEST, "failed", "ioctl I_SETSIG 0x%x",
582: result);
583: #else
584: return tsaplose (td, DR_CONGEST, NULLCP,
585: "asynchronous operations not yet supported under SVR3");
586: #endif
587: #endif
588: }
589: else {
590: #ifdef BSDSIGS
591: if ((result = fcntl (tb -> tb_fd, F_GETFL, 0x00)) == NOTOK)
592: return tsaplose (td, DR_CONGEST, "failed", "fcntl F_GETFL");
593: result &= ~FASYNC;
594: if (fcntl (tb -> tb_fd, F_SETFL, result) == NOTOK)
595: return tsaplose (td, DR_CONGEST, "failed", "fcntl F_SETFL 0x%x",
596: result);
597: #else
598: if (ioctl (tb -> tb_fd, I_GETSIG, &result) == NOTOK)
599: return tsaplose (td, DR_CONGEST, "failed", "ioctl I_GETSIG");
600: result &= ~S_INPUT;
601: if (ioctl (tb -> tb_fd, I_SETSIG, result) == NOTOK)
602: return tsaplose (td, DR_CONGEST, "failed", "ioctl I_SETSIG 0x%x",
603: result);
604: #endif
605: }
606:
607: return OK;
608: }
609: #endif
610:
611: /* INTERNAL */
612:
613: struct tsapblk *newtblk () {
614: register struct tsapblk *tb;
615:
616: tb = (struct tsapblk *) calloc (1, sizeof *tb);
617: if (tb == NULL)
618: return NULL;
619:
620: tb -> tb_fd = NOTOK;
621:
622: tb -> tb_qbuf.qb_forw = tb -> tb_qbuf.qb_back = &tb -> tb_qbuf;
623: tb -> tb_qwrites.qb_forw = tb -> tb_qwrites.qb_back = &tb -> tb_qwrites;
624:
625: if (once_only == 0) {
626: THead -> tb_forw = THead -> tb_back = THead;
627: once_only++;
628: }
629:
630: insque (tb, THead -> tb_back);
631:
632: return tb;
633: }
634:
635:
636: freetblk (tb)
637: register struct tsapblk *tb;
638: {
639: SBV smask;
640: #ifndef SIGPOLL
641: struct TSAPdisconnect tds;
642: #endif
643:
644: if (tb == NULL)
645: return;
646:
647: smask = sigioblock ();
648:
649: if (tb -> tb_fd != NOTOK) {
650: (void) (*tb -> tb_closefnx) (tb -> tb_fd);
651: #ifdef MGMT
652: if (tb -> tb_manfnx)
653: (*tb -> tb_manfnx) (DISCREQ, tb);
654: #endif
655: }
656:
657: if (tb -> tb_retry)
658: freetpkt (tb -> tb_retry);
659:
660: if (tb -> tb_calling)
661: free ((char *) tb -> tb_calling);
662: if (tb -> tb_called)
663: free ((char *) tb -> tb_called);
664: if (tb -> tb_data)
665: free (tb -> tb_data);
666:
667: #ifndef SIGPOLL
668: if ((tb -> tb_flags & TB_ASYN) && TPid > OK) {
669: (void) kill (TPid, SIGTERM);
670: TPid = NOTOK;
671: }
672: #endif
673:
674: QBFREE (&tb -> tb_qbuf);
675:
676: if (tb -> tb_queuePfnx)
677: (*tb -> tb_queuePfnx) (tb, 0, (struct TSAPdisconnect *) 0);
678: QBFREE (&tb -> tb_qwrites);
679:
680: remque (tb);
681:
682: free ((char *) tb);
683:
684: #ifndef SIGPOLL
685: for (tb = THead -> tb_forw; tb != THead; tb = tb -> tb_forw)
686: if (tb -> tb_fd != NOTOK && (tb -> tb_flags & TB_ASYN)) {
687: (void) TWakeUp (tb, &tds);
688: break;
689: }
690: #endif
691:
692: (void) sigiomask (smask);
693: }
694:
695: /* */
696:
697: struct tsapblk *findtblk (sd)
698: register int sd;
699: {
700: register struct tsapblk *tb;
701:
702: if (once_only == 0)
703: return NULL;
704:
705: for (tb = THead -> tb_forw; tb != THead; tb = tb -> tb_forw)
706: if (tb -> tb_fd == sd)
707: return tb;
708:
709: return NULL;
710: }
711:
712: /* */
713:
714: int copyTSAPaddrX (in, out)
715: struct tsapADDR *in;
716: struct TSAPaddr *out;
717: {
718: bzero ((char *) out, sizeof *out);
719:
720: bcopy (in -> ta_selector, out -> ta_selector,
721: out -> ta_selectlen = in -> ta_selectlen);
722:
723: if (in -> ta_present) {
724: out -> ta_addrs[0] = in -> ta_addr; /* struct copy */
725: out -> ta_naddr = 1;
726: }
727: }
728:
729:
730: int copyTSAPaddrY (in, out)
731: struct TSAPaddr *in;
732: struct tsapADDR *out;
733: {
734: bzero ((char *) out, sizeof *out);
735:
736: bcopy (in -> ta_selector, out -> ta_selector,
737: out -> ta_selectlen = in -> ta_selectlen);
738:
739: if (out -> ta_present = (in -> ta_naddr >= 1) ? 1 : 0)
740: out -> ta_addr = in -> ta_addrs[0]; /* struct copy */
741: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.