|
|
1.1 ! root 1: /* psaptcp.c - PPM: TCP backing */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/psap2-lpp/RCS/ps2tcp.c,v 7.2 90/07/09 14:45:01 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/psap2-lpp/RCS/ps2tcp.c,v 7.2 90/07/09 14:45:01 mrose Exp $ ! 9: * ! 10: * Contributed by The Wollongong Group, Inc. ! 11: * ! 12: * ! 13: * $Log: ps2tcp.c,v $ ! 14: * Revision 7.2 90/07/09 14:45:01 mrose ! 15: * sync ! 16: * ! 17: * Revision 7.1 90/07/01 21:05:19 mrose ! 18: * pepsy ! 19: * ! 20: * Revision 7.0 89/11/23 22:15:50 mrose ! 21: * Release 6.0 ! 22: * ! 23: */ ! 24: ! 25: /* ! 26: * NOTICE ! 27: * ! 28: * Acquisition, use, and distribution of this module and related ! 29: * materials are subject to the restrictions of a license agreement. ! 30: * Consult the Preface in the User's Manual for the full terms of ! 31: * this agreement. ! 32: * ! 33: */ ! 34: ! 35: ! 36: /* LINTLIBRARY */ ! 37: ! 38: #include <stdio.h> ! 39: #define LPP ! 40: #include "PS-types.h" ! 41: #include "ppkt.h" ! 42: #include "tsap.h" ! 43: #include "tailor.h" ! 44: ! 45: #include "internet.h" ! 46: #include <errno.h> ! 47: #ifdef BSD42 ! 48: #include <sys/ioctl.h> ! 49: #endif ! 50: ! 51: /* DATA */ ! 52: ! 53: #ifdef FIONBIO ! 54: static fd_set inprogress; ! 55: static struct sockaddr_in *peers = NULL; ! 56: #endif ! 57: ! 58: extern int errno; ! 59: ! 60: /* */ ! 61: ! 62: int tcpopen (pb, calling, called, pi, async) ! 63: register struct psapblk *pb; ! 64: struct NSAPaddr *calling, ! 65: *called; ! 66: struct PSAPindication *pi; ! 67: int async; ! 68: { ! 69: int fd; ! 70: #ifdef FIONBIO ! 71: int onoff; ! 72: #endif ! 73: struct sockaddr_in lo_socket, ! 74: in_socket; ! 75: register struct sockaddr_in *lsock = &lo_socket, ! 76: *isock = &in_socket; ! 77: register struct hostent *hp; ! 78: ! 79: #ifndef FIONBIO ! 80: if (async) ! 81: return psaplose (pi, PC_PARAMETER, NULLCP, ! 82: "asynchronous not supported"); ! 83: #endif ! 84: ! 85: bzero ((char *) isock, sizeof *isock); ! 86: ! 87: if (called -> na_port == 0) ! 88: return psaplose (pi, PC_ADDRESS, NULLCP, ! 89: "TCP port of called address not specified"); ! 90: else ! 91: isock -> sin_port = called -> na_port; ! 92: ! 93: if ((hp = gethostbystring (called -> na_domain)) == NULL) ! 94: return psaplose (pi, PC_ADDRESS, NULLCP, "%s: unknown host", ! 95: called -> na_domain); ! 96: #ifdef notanymore ! 97: (void) strncpy (called -> na_domain, hp -> h_name, ! 98: sizeof called -> na_domain); ! 99: #endif ! 100: ! 101: isock -> sin_family = hp -> h_addrtype; ! 102: inaddr_copy (hp, isock); ! 103: ! 104: #ifndef notanymore ! 105: (void) strcpy (called -> na_domain, inet_ntoa (isock -> sin_addr)); ! 106: #endif ! 107: ! 108: if (calling && calling -> na_domain[0]) { ! 109: bzero ((char *) lsock, sizeof *lsock); ! 110: ! 111: if ((hp = gethostbystring (calling -> na_domain)) == NULL) ! 112: return psaplose (pi, PC_ADDRESS, NULLCP, "%s: unknown host", ! 113: calling -> na_domain); ! 114: ! 115: if ((lsock -> sin_family = hp -> h_addrtype) != isock -> sin_family) ! 116: return psaplose (pi, PC_ADDRESS, NULLCP, ! 117: "address family mismatch"); ! 118: ! 119: inaddr_copy (hp, lsock); ! 120: } ! 121: else ! 122: lsock = NULL; ! 123: ! 124: if ((fd = start_tcp_client (lsock, 0)) == NOTOK) ! 125: return psaplose (pi, PC_CONGEST, "socket", "unable to start"); ! 126: ! 127: #ifdef FIONBIO ! 128: if (async) ! 129: (void) ioctl (fd, FIONBIO, (onoff = 1, (char *) &onoff)); ! 130: #endif ! 131: PTservice (pb, fd); ! 132: ! 133: if (join_tcp_server (fd, isock) == NOTOK) { ! 134: #ifdef FIONBIO ! 135: if (async) ! 136: switch (errno) { ! 137: case EINPROGRESS: ! 138: if (peers == NULL) { ! 139: peers = (struct sockaddr_in *) ! 140: calloc ((unsigned) getdtablesize (), ! 141: sizeof *peers); ! 142: if (peers == NULL) { ! 143: (void) psaplose (pi, PC_CONGEST, NULLCP, ! 144: "out of memory"); ! 145: (void) close_tcp_socket (fd); ! 146: return (pb -> pb_fd = NOTOK); ! 147: } ! 148: ! 149: FD_ZERO (&inprogress); ! 150: } ! 151: FD_SET (fd, &inprogress); ! 152: peers[fd] = *isock;/* struct copy */ ! 153: return OK; ! 154: ! 155: case EISCONN: ! 156: goto done; ! 157: ! 158: default: ! 159: break; ! 160: } ! 161: #endif ! 162: ! 163: (void) psaplose (pi, PC_REFUSED, "connection", "unable to establish"); ! 164: (void) close_tcp_socket (fd); ! 165: return (pb -> pb_fd = NOTOK); ! 166: } ! 167: #ifdef FIONBIO ! 168: done: ; ! 169: ! 170: if (async) ! 171: (void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff)); ! 172: #endif ! 173: ! 174: if (tcpready (pb, pi) == NOTOK) { ! 175: (void) close_tcp_socket (fd); ! 176: pb -> pb_fd = NOTOK; ! 177: } ! 178: ! 179: return DONE; ! 180: } ! 181: ! 182: /* */ ! 183: ! 184: /* ARGSUSED */ ! 185: ! 186: char *tcpsave (fd, sin, cp1, cp2, td) ! 187: int fd; ! 188: struct sockaddr_in *sin; ! 189: char *cp1, ! 190: *cp2; ! 191: struct TSAPdisconnect *td; ! 192: { ! 193: static char buffer[BUFSIZ]; ! 194: ! 195: (void) sprintf (buffer, "%c%d %s %s", PT_TCP, fd, cp1, cp2); ! 196: ! 197: return buffer; ! 198: } ! 199: ! 200: ! 201: int tcprestore (pb, buffer, pi) ! 202: register struct psapblk *pb; ! 203: char *buffer; ! 204: struct PSAPindication *pi; ! 205: { ! 206: int fd; ! 207: char domain[NSAP_DOMAINLEN + 1]; ! 208: register struct NSAPaddr *na; ! 209: ! 210: na = &pb -> pb_initiating; ! 211: na -> na_stack = NA_TCP; ! 212: na -> na_community = ts_comm_tcp_default; ! 213: ! 214: if (sscanf (buffer, "%d %s %s", &fd, na -> na_domain, domain) != 3 ! 215: || fd < 0) ! 216: return psaplose (pi, PC_PARAMETER, NULLCP, ! 217: "bad initialization vector"); ! 218: ! 219: PTservice (pb, fd); ! 220: ! 221: na = pb -> pb_responding.pa_addr.sa_addr.ta_addrs; ! 222: na -> na_stack = NA_TCP; ! 223: na -> na_community = ts_comm_tcp_default; ! 224: (void) strncpy (na -> na_domain, domain, sizeof na -> na_domain); ! 225: ! 226: if ((pb -> pb_stream = ps_alloc (fdx_open)) == NULLPS ! 227: || fdx_setup (pb -> pb_stream, pb -> pb_fd) == NOTOK) ! 228: return psaplose (pi, PC_CONGEST, NULLCP, NULLCP); ! 229: ! 230: return OK; ! 231: } ! 232: ! 233: /* */ ! 234: ! 235: static int tcpretry (pb, pi) ! 236: register struct psapblk *pb; ! 237: struct PSAPindication *pi; ! 238: { ! 239: #ifdef FIONBIO ! 240: int onoff; ! 241: int fd = pb -> pb_fd; ! 242: fd_set mask; ! 243: struct sockaddr_in *isock = &peers[fd]; ! 244: ! 245: if (!FD_SET (fd, &inprogress)) ! 246: return psaplose (pi, PC_PARAMETER, NULLCP, ! 247: "connection not in progress"); ! 248: FD_ZERO (&mask); ! 249: FD_SET (fd, &mask); ! 250: ! 251: if (xselect (fd + 1, NULLFD, &mask, NULLFD, 0) < 1) ! 252: return OK; ! 253: ! 254: isock = &peers[fd]; ! 255: if (join_tcp_server (fd, isock) == NOTOK) { ! 256: switch (errno) { ! 257: case EINPROGRESS: ! 258: return OK; ! 259: ! 260: case EISCONN: ! 261: goto done; ! 262: ! 263: case EINVAL: /* UNIX bug: could be any socket errno, e.g., ! 264: ETIMEDOUT */ ! 265: errno = ECONNREFUSED; ! 266: /* and fall */ ! 267: default: ! 268: break; ! 269: } ! 270: ! 271: (void) psaplose (pi, PC_REFUSED, "connection", "unable to establish"); ! 272: FD_CLR (fd, &inprogress); ! 273: (void) close_tcp_socket (fd); ! 274: return (pb -> pb_fd = NOTOK); ! 275: } ! 276: done: ; ! 277: ! 278: (void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff)); ! 279: FD_CLR (fd, &inprogress); ! 280: ! 281: if (tcpready (pb, pi) == NOTOK) { ! 282: (void) close_tcp_socket (fd); ! 283: return (pb -> pb_fd = NOTOK); ! 284: } ! 285: ! 286: return DONE; ! 287: #else ! 288: return psaplose (pi, PC_OPERATION, NULLCP, "connection not in progress"); ! 289: #endif ! 290: } ! 291: ! 292: /* */ ! 293: ! 294: static int tcpready (pb, pi) ! 295: register struct psapblk *pb; ! 296: struct PSAPindication *pi; ! 297: { ! 298: PS ps; ! 299: ! 300: if ((pb -> pb_stream = ps_alloc (fdx_open)) == NULLPS ! 301: || fdx_setup (pb -> pb_stream, pb -> pb_fd) == NOTOK) ! 302: return psaplose (pi, PC_CONGEST, NULLCP, NULLCP); ! 303: ! 304: PLOGP (psap2_log,PS_PDUs, pb -> pb_retry, "ConnectRequest-PDU", 0); ! 305: ! 306: if (pe2ps (ps = pb -> pb_stream, pb -> pb_retry) == NOTOK) ! 307: return pslose (pi, ps -> ps_errno); ! 308: ! 309: pe_free (pb -> pb_retry); ! 310: pb -> pb_retry = NULLPE; ! 311: ! 312: if ((pb -> pb_response = ps2pe (pb -> pb_stream)) == NULLPE) ! 313: return pslose (pi, ps -> ps_errno); ! 314: ! 315: return OK; ! 316: } ! 317: ! 318: /* */ ! 319: ! 320: #define tcpclose close_tcp_socket ! 321: #define tcpselect select_tcp_socket ! 322: ! 323: ! 324: static int PTservice (pb, fd) ! 325: register struct psapblk *pb; ! 326: int fd; ! 327: { ! 328: pb -> pb_fd = fd; ! 329: ! 330: pb -> pb_reliability = HIGH_QUALITY; ! 331: ! 332: pb -> pb_retryfnx = tcpretry; ! 333: pb -> pb_closefnx = tcpclose; ! 334: pb -> pb_selectfnx = tcpselect; ! 335: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.