|
|
1.1 root 1: /* ps2udp.c - PPM: UDP backing */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/psap2-lpp/RCS/ps2udp.c,v 7.3 90/07/09 14:45:02 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/psap2-lpp/RCS/ps2udp.c,v 7.3 90/07/09 14:45:02 mrose Exp $
9: *
10: * Contributed by The Wollongong Group, Inc.
11: *
12: *
13: * $Log: ps2udp.c,v $
14: * Revision 7.3 90/07/09 14:45:02 mrose
15: * sync
16: *
17: * Revision 7.2 90/07/01 21:05:21 mrose
18: * pepsy
19: *
20: * Revision 7.1 89/12/19 16:17:48 mrose
21: * dgram
22: *
23: * Revision 7.0 89/11/23 22:15:51 mrose
24: * Release 6.0
25: *
26: */
27:
28: /*
29: * NOTICE
30: *
31: * Acquisition, use, and distribution of this module and related
32: * materials are subject to the restrictions of a license agreement.
33: * Consult the Preface in the User's Manual for the full terms of
34: * this agreement.
35: *
36: */
37:
38:
39: /* LINTLIBRARY */
40:
41: #include <errno.h>
42: #include <stdio.h>
43: #define LPP
44: #include "PS-types.h"
45: #include "ppkt.h"
46: #include "tsap.h"
47: #include "tailor.h"
48:
49: #include "dgram.h"
50: #include "internet.h"
51:
52:
53: extern int errno;
54:
55: /* */
56:
57: #define MAXTRIES 3 /* should be tailorable... */
58: #define WAITRIES 30 /* .. */
59:
60:
61: int udpopen (pb, calling, called, pi, async)
62: register struct psapblk *pb;
63: struct NSAPaddr *calling,
64: *called;
65: struct PSAPindication *pi;
66: int async;
67: {
68: int fd;
69: struct sockaddr_in lo_socket,
70: in_socket;
71: register struct sockaddr_in *lsock = &lo_socket,
72: *isock = &in_socket;
73: register struct hostent *hp;
74:
75: bzero ((char *) isock, sizeof *isock);
76:
77: if (called -> na_port == 0)
78: return psaplose (pi, PC_ADDRESS, NULLCP,
79: "UDP port of called address not specified");
80: else
81: isock -> sin_port = called -> na_port;
82:
83: if ((hp = gethostbystring (called -> na_domain)) == NULL)
84: return psaplose (pi, PC_ADDRESS, NULLCP, "%s: unknown host",
85: called -> na_domain);
86: #ifdef notanymore
87: (void) strncpy (called -> na_domain, hp -> h_name,
88: sizeof called -> na_domain);
89: #endif
90:
91: isock -> sin_family = hp -> h_addrtype;
92: inaddr_copy (hp, isock);
93:
94: #ifndef notanymore
95: (void) strcpy (called -> na_domain, inet_ntoa (isock -> sin_addr));
96: #endif
97:
98: bzero ((char *) lsock, sizeof *lsock);
99: if (calling && calling -> na_domain[0]) {
100: if ((hp = gethostbystring (calling -> na_domain)) == NULL)
101: return psaplose (pi, PC_ADDRESS, NULLCP, "%s: unknown host",
102: calling -> na_domain);
103:
104: if ((lsock -> sin_family = hp -> h_addrtype) != isock -> sin_family)
105: return psaplose (pi, PC_ADDRESS, NULLCP,
106: "address family mismatch");
107:
108: inaddr_copy (hp, lsock);
109: }
110: else
111: lsock -> sin_family = isock -> sin_family;
112:
113: if ((fd = start_udp_client (lsock, 0, 0, 0)) == NOTOK)
114: return psaplose (pi, PC_CONGEST, "socket", "unable to start");
115:
116: if (join_udp_server (fd, isock) == NOTOK) {
117: (void) psaplose (pi, PC_REFUSED, "connection", "unable to establish");
118: (void) close_udp_socket (fd);
119: return NOTOK;
120: }
121:
122: if ((pb -> pb_stream = ps_alloc (dg_open)) == NULLPS
123: || dg_setup (pb -> pb_stream, fd, MAXDGRAM, read_udp_socket,
124: write_udp_socket) == NOTOK) {
125: (void) psaplose (pi, PC_CONGEST, NULLCP, NULLCP);
126: (void) close_udp_socket (fd);
127: return NOTOK;
128: }
129:
130: PUservice (pb, fd);
131:
132: pb -> pb_tries = pb -> pb_maxtries;
133:
134: for (;;)
135: switch (udpretry (pb, PC_REFUSED, pi)) {
136: case NOTOK:
137: return NOTOK;
138:
139: case OK:
140: if (async)
141: return OK;
142: continue;
143:
144: case DONE:
145: default:
146: return DONE;
147: }
148: }
149:
150: /* */
151:
152: /* ARGSUSED */
153:
154: char *udpsave (fd, sin, cp1, cp2, td)
155: int fd;
156: struct sockaddr_in *sin;
157: char *cp1,
158: *cp2;
159: struct TSAPdisconnect *td;
160: {
161: static char buffer[BUFSIZ];
162:
163: (void) sprintf (buffer, "%c%d %s %s", PT_UDP, fd, cp1, cp2);
164:
165: return buffer;
166: }
167:
168:
169: int udprestore (pb, buffer, pi)
170: register struct psapblk *pb;
171: char *buffer;
172: struct PSAPindication *pi;
173: {
174: int fd;
175: char domain[NSAP_DOMAINLEN + 1];
176: register struct NSAPaddr *na;
177:
178: na = &pb -> pb_initiating;
179: na -> na_stack = NA_TCP;
180: na -> na_community = ts_comm_tcp_default;
181: na -> na_tset = NA_TSET_UDP;
182:
183: if (sscanf (buffer, "%d %s %s", &fd, na -> na_domain, domain) != 3
184: || fd < 0)
185: return psaplose (pi, PC_PARAMETER, NULLCP,
186: "bad initialization vector");
187:
188: PUservice (pb, fd);
189:
190: na = pb -> pb_responding.pa_addr.sa_addr.ta_addrs;
191: na -> na_stack = NA_TCP;
192: na -> na_community = ts_comm_tcp_default;
193: na -> na_tset = NA_TSET_UDP;
194: (void) strncpy (na -> na_domain, domain, sizeof na -> na_domain);
195:
196: if ((pb -> pb_stream = ps_alloc (dg_open)) == NULLPS
197: || dg_setup (pb -> pb_stream, pb -> pb_fd, MAXDGRAM,
198: read_udp_socket, write_udp_socket) == NOTOK)
199: return psaplose (pi, PC_CONGEST, NULLCP, NULLCP);
200:
201: return OK;
202: }
203:
204: /* */
205:
206: static int udpretry (pb, reason, pi)
207: register struct psapblk *pb;
208: int reason;
209: struct PSAPindication *pi;
210: {
211: int nfds;
212: fd_set ifds;
213: PS ps;
214:
215: PLOGP (psap2_log,PS_PDUs, pb -> pb_retry,
216: reason == PC_REFUSED ? "ConnectRequest-PDU" : "ReleaseRequest-PDU",
217: 0);
218:
219: if (pe2ps (ps = pb -> pb_stream, pb -> pb_retry) == NOTOK) {
220: (void) pslose (pi, ps -> ps_errno);
221: (void) close_udp_socket (pb -> pb_fd);
222: return (pb -> pb_fd = NOTOK);
223: }
224:
225: FD_ZERO (&ifds);
226:
227: nfds = pb -> pb_fd + 1;
228: FD_SET (pb -> pb_fd, &ifds);
229: if (select_udp_socket (nfds, &ifds, NULLFD, NULLFD, WAITRIES) < 1) {
230: if (--pb -> pb_tries > 0)
231: return OK;
232:
233: if (reason == PC_REFUSED) {
234: errno = ETIMEDOUT;
235: (void) ppktlose (pb, pi, PC_REFUSED, pb -> pb_reference,
236: "connection", "unable to establish");
237: }
238: else
239: (void) ppktlose (pb, pi, reason, pb -> pb_reference, NULLCP,
240: NULLCP);
241:
242: (void) close_udp_socket (pb -> pb_fd);
243: return (pb -> pb_fd = NOTOK);
244: }
245:
246: if (pb -> pb_response)
247: pe_free (pb -> pb_response);
248: if ((pb -> pb_response = ps2pe (ps = pb -> pb_stream)) == NULLPE) {
249: (void) pslose (pi, ps -> ps_errno);
250: (void) close_udp_socket (pb -> pb_fd);
251: return (pb -> pb_fd = NOTOK);
252: }
253:
254: return DONE;
255: }
256:
257: /* */
258:
259: static int udpcheck (pb, pi)
260: register struct psapblk *pb;
261: struct PSAPindication *pi;
262: {
263: int nfds;
264: fd_set ifds;
265:
266: FD_ZERO (&ifds);
267:
268: nfds = pb -> pb_fd + 1;
269: FD_SET (pb -> pb_fd, &ifds);
270: if (select_udp_socket (nfds, &ifds, NULLFD, NULLFD, OK) < 1)
271: return psaplose (pi, PC_TIMER, NULLCP, NULLCP);
272:
273: return psaplose (pi, PC_WAITING, NULLCP, NULLCP);
274: }
275:
276: /* */
277:
278: #define udpclose close_udp_socket
279: #define udpselect select_udp_socket
280:
281:
282: static int PUservice (pb, fd)
283: register struct psapblk *pb;
284: int fd;
285: {
286: pb -> pb_fd = fd;
287:
288: pb -> pb_reliability = LOW_QUALITY;
289: pb -> pb_maxtries = MAXTRIES;
290:
291: pb -> pb_retryfnx = udpretry;
292: pb -> pb_closefnx = udpclose;
293: pb -> pb_selectfnx = udpselect;
294: pb -> pb_checkfnx = udpcheck;
295: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.