|
|
1.1 ! root 1: .lf 1 ipcpaper ! 2: .ND ! 3: .TL ! 4: Interprocess Communication ! 5: .br ! 6: in the Ninth Edition Unix System ! 7: .AU ! 8: D. L. Presotto ! 9: D. M. Ritchie ! 10: .AI ! 11: AT&T Bell Laboratories ! 12: Murray Hill, New Jersey 07974 ! 13: .AB ! 14: When processes wish to communicate, they must first establish communication, ! 15: and then decide what to say. ! 16: The stream mechanisms introduced in the Eighth Edition Unix system\*(<,\*([.1\*(.]\*(>, ! 17: .FS ! 18: Unix is a trademark of AT&T. ! 19: .FE ! 20: which have now become part of AT&T's Unix System V\*(<,\*([.2\*(.]\*(>, ! 21: provide a flexible way for processes ! 22: to speak with devices and with ! 23: each other: ! 24: an existing stream connection is named by a file descriptor, ! 25: and the usual read, write, and I/O control requests apply. ! 26: Processing modules may be inserted dynamically ! 27: into a stream connection, so ! 28: network protocols, terminal processing, and device drivers separate ! 29: cleanly. ! 30: .PP ! 31: Simple extensions provide new ways of establishing communication. ! 32: In our system, the traditional Unix IPC mechanism, the pipe, is ! 33: a cross-connected stream. ! 34: .PP ! 35: A new request associates a stream with a named file. ! 36: When the file is opened, ! 37: operations on the file are operations on the ! 38: stream. ! 39: .PP ! 40: Open files may be passed from ! 41: one process to another over a stream. ! 42: .PP ! 43: These low-level mechanisms allow ! 44: construction of flexible and general ! 45: routines for connecting local and remote processes. ! 46: .AE ! 47: .LP ! 48: .SH ! 49: Introduction ! 50: .PP ! 51: The Ninth Edition version of Unix\(rg operating system ! 52: is used in the Information Sciences ! 53: Research Division of AT&T Bell Laboratories, and at a few sites elsewhere. ! 54: It is named, by our custom, ! 55: after its manual. ! 56: .PP ! 57: The work reported here provides convenient ways ! 58: for programs to establish communication with unrelated ! 59: processes, on the same or different machines. ! 60: The communication we are interested in is conducted by ! 61: ordinary read and write calls, occasionally supplemented ! 62: by I/O control requests, so that it resembles\(emand, where possible, ! 63: is indistinguishable from\(emI/O to files. ! 64: Moreover, we wish to commence communication in ways that resemble ! 65: the opening of ordinary files, or at least takes advantage of ! 66: the properties of the file system name space. ! 67: .PP ! 68: In particular, we study how to ! 69: .IP 1) ! 70: provide objects nameable as files that invoke useful services, ! 71: such as connecting to other machines over various media, ! 72: .IP 2) ! 73: make it easy to write the programs that provide the services. ! 74: .PP ! 75: .SH ! 76: Recapitulation ! 77: .PP ! 78: The Eighth Edition system introduced a new way of communicating with ! 79: terminal and network devices\*(<,\*([.1\*(.]\*(>, ! 80: and a generalization of the internal interface to the file system\*(<.\*([.3,\|4\*(.]\*(>. ! 81: Because the new mechanisms build on these ideas, we ! 82: review the nomenclature and mechanisms ! 83: of our I/O and file systems. ! 84: .SH ! 85: .I "Streams ! 86: .PP ! 87: A ! 88: .I "stream ! 89: is a full-duplex connection between a process and a device ! 90: or another process. ! 91: It consists of several linearly connected processing modules, ! 92: and is analogous to a Shell pipeline, except that ! 93: data flows in both directions. ! 94: The modules in a stream communicate ! 95: by passing messages to their neighbors. ! 96: A module provides only one entry point to each neighbor, namely ! 97: a routine that accepts messages. ! 98: .PP ! 99: At the end of the stream closest to the process ! 100: is a set of routines that provide the interface to the rest of the system. ! 101: A user's ! 102: .I "write ! 103: and ! 104: I/O control requests are turned into messages sent along the stream, ! 105: and ! 106: .I "read ! 107: requests take data from the stream and pass it to the user. ! 108: At the other end of the stream is either a ! 109: device driver module, or another process. ! 110: Data arriving from the stream at a driver module ! 111: is transmitted to the device, and ! 112: data and state transitions detected by the device are ! 113: composed into messages and sent into the stream towards the user process. ! 114: Pipes, which are streams connecting processes, ! 115: are bidirectional; ! 116: a writer at either end generates stream messages that are picked up by the reader ! 117: at the other. ! 118: .PP ! 119: Intermediate modules process messages in various ways. ! 120: They come in pairs, for handling messages ! 121: in each of the two directions, and each pair is symmetrical; ! 122: their read and write interfaces are identical. ! 123: .PP ! 124: The end modules in a device stream become connected automatically when ! 125: the process opens the device; ! 126: streams between processes are created by a ! 127: .I pipe ! 128: call. ! 129: Intermediate modules are attached dynamically by request of the user's program. ! 130: They are addressed like a stack with its top close to the process, ! 131: so installing one is called `pushing' a new module. ! 132: .PP ! 133: For example, ! 134: Figure 1 shows a stream device that has just ! 135: been opened. ! 136: The top-level routines, drawn as a pair of half-open rectangles ! 137: on the left, are invoked by users' ! 138: .I read ! 139: and ! 140: .I write ! 141: calls. ! 142: The ! 143: writer ! 144: routine sends messages to the device driver shown on the right. ! 145: Data arriving from the device becomes ! 146: messages sent to the top-level ! 147: reader ! 148: routine, which returns the data to the user process ! 149: when it executes ! 150: .I read . ! 151: .so pfig1 ! 152: .PP ! 153: Figure 2 shows a stream with intermediate modules. ! 154: This arrangement might be used when a terminal is connected to the computer ! 155: through a network. ! 156: The leftmost intermediate module carries out processing ! 157: (such as character-erase and line-kill) needed for terminals, while ! 158: the rightmost intermediate module does the ! 159: flow- and error-control ! 160: protocol needed to interface to the network. ! 161: .so pfig2 ! 162: .PP ! 163: Finally, Figure 3 ! 164: shows the connections for a pipe. ! 165: .so pfig3 ! 166: .SH ! 167: .I "File Systems ! 168: .PP ! 169: Weinberger\*([.3\*(.] ! 170: generalized the file system ! 171: by identifying a small set of primitive operations on files ! 172: (read, write, look up name, truncate, get status, etc.: a total of 11) ! 173: and modifying the ! 174: .I mount ! 175: request so that it specifies a file system type and, where appropriate, ! 176: a stream. ! 177: When file operations are requested, the calls to the underlying ! 178: primitives are routed through a switch table indexed by the ! 179: type. ! 180: Where the standard file system type performs operations directly ! 181: on a disk, ! 182: a second type generates remote procedure calls ! 183: across the associated stream. ! 184: At the other end of the stream, which usually goes over ! 185: a network to another machine, is a server process ! 186: that answers the calls to read and write data and perform the other operations. ! 187: This scheme thus provides a remote file system. ! 188: In general structure, this arrangement is analogous ! 189: to that used by AT&T's RFS ! 190: and Sun Microsystems' NFS. ! 191: .PP ! 192: Pike's `face server'\*([.5\*(.] ! 193: appears to be an ordinary remote file system, ! 194: but his server simulates a hierarchy containing images classified by ! 195: machine, person name, and resolution. ! 196: The apparent structure of the hierarchy as viewed by ! 197: a client differs considerably from ! 198: its actual layout on the server's machine. ! 199: .PP ! 200: Killian\*([.4\*(.] ! 201: added a file system type that ! 202: appears to be a directory containing the names (process ID numbers) ! 203: of currently running processes. ! 204: Once a process file is opened, its memory may be read or written, ! 205: and control operations can start it or stop it. ! 206: This simplifies the construction of sophisticated debuggers, ! 207: for example Cargill's process-inspector ! 208: .I pi \*(<.\*([.6\*(.]\*(>. ! 209: .SH ! 210: Establishing Communication ! 211: .PP ! 212: Traditional Unix systems provide few ways for a process ! 213: to establish communication with another. ! 214: The oldest one, the pipe, has proved astonishingly valuable ! 215: despite its limitations, and indeed remains central in the design ! 216: we shall describe. ! 217: Its cardinal limitation is, of course, that it is anonymous, ! 218: and cannot be used to create a channel between unrelated processes. ! 219: .PP ! 220: More recently, ! 221: AT&T's System V has offered a variety of communication mechanisms including ! 222: semaphores, messages, and shared memory. ! 223: They are all useful in certain circumstances, but programs that ! 224: use them are all special-purpose; they know that they are communicating ! 225: over a certain kind of channel, and must use special calls and techniques. ! 226: System V also provides named pipes (FIFOs). ! 227: They reside in the file system, and ordinary I/O operations ! 228: apply to them. ! 229: They can provide a convenient place for processes to meet. ! 230: However, because the messages of all writers are intermingled, ! 231: writers must observe a carefully designed, application-specific protocol ! 232: when using them. ! 233: Moreover, FIFOs supply only one-way communication; ! 234: to receive a reply from a process reached through ! 235: a FIFO, a return channel must be constructed somehow. ! 236: .PP ! 237: Berkeley's 4.2 BSD system introduced ! 238: .I sockets ! 239: (communication connection points) ! 240: that exist in domains (naming spaces). ! 241: The design is powerful enough to provide most of the needed facilities, ! 242: but is uncomfortable in various ways. ! 243: For example, unless extensive libraries are used, creating a new ! 244: domain implies additions to the kernel. ! 245: Consider the problem of adding a `phone' domain, in which the addresses ! 246: are telephone numbers. ! 247: Should complicated negotiations with various kinds of ! 248: automatic dialers be added to the kernel? ! 249: If not, how can the required code be invoked in user mode ! 250: when a program calls ! 251: 4.2 BSD's ! 252: .I connect ! 253: primitive? ! 254: .PP ! 255: Another problem with the socket interface is that it exposes ! 256: peculiarities of the domain; ! 257: various domains support very different kinds of name ! 258: (for example, 32-bit Internet address versus character string), and it is difficult ! 259: to deal with the names in a general way. ! 260: Similarly, the details of option processing and other aspects of ! 261: each domain's protocols complicate an interface that attempts generality. ! 262: .SH ! 263: New System Mechanisms ! 264: .PP ! 265: Two small additions to the operating system allowed us to build ! 266: a variety of communication mechanisms, which will be ! 267: described below. ! 268: .SH ! 269: .I "Generalized Mounting ! 270: .PP ! 271: Traditionally, the ! 272: .I mount ! 273: request attaches a disk containing ! 274: a new piece of the file system tree at a leaf of the existing structure. ! 275: In the Ninth Edition, it takes the form ! 276: .DS ! 277: .ft CW ! 278: mount(type, fd, name, flag); ! 279: .ft ! 280: .DE ! 281: in which ! 282: .I type ! 283: identifies the kind of file system, ! 284: .I fd ! 285: is a file descriptor, ! 286: .I name ! 287: is a string identifying a file, and ! 288: .I flag ! 289: may specify a few options. ! 290: Like its original version, this call attaches a new file system structure ! 291: atop the file ! 292: .I name ! 293: in the existing file hierarchy. ! 294: The operating system gains access to the contents of newly-attached file tree ! 295: by communicating over the descriptor ! 296: .I fd, ! 297: according to a protocol appropriate for the new file system ! 298: .I type. ! 299: For example, ordinary disk volumes have type ! 300: .I ordinary, ! 301: and the file descriptor is the special file for ! 302: the disk, while ! 303: remote file systems use type ! 304: .I remote, ! 305: and the descriptor ! 306: refers to a stream connection to a server that understands ! 307: the appropriate RPC messages. ! 308: Some types are handled entirely internally; ! 309: for example, the `proc' type ignores the file descriptor. ! 310: .PP ! 311: We added a new, very simple, file system type. ! 312: Its ! 313: .I mount ! 314: request merely attaches the file descriptor (which must be a stream) to ! 315: the file. ! 316: Subsequently, when processes open and do I/O on that file, ! 317: their requests refer to the stream mounted on the file. ! 318: Often, the stream is one end of a pipe created by a server ! 319: process, but it can equally well be a connection to a device, ! 320: or a network connection to a process on another machine. ! 321: The effect is similar to a System V FIFO that has already been opened ! 322: by a server, but more general: communication is full-duplex, ! 323: the server can be on another machine, and (because the connection is a stream), ! 324: intermediate processing modules may be installed. ! 325: .SH ! 326: .I "Passing Files ! 327: .PP ! 328: By itself, a mounted stream shares an important difficulty ! 329: of the FIFO; ! 330: several processes attempting to use it simultaneously must ! 331: somehow cooperate. ! 332: Another addition facilitates this cooperation: ! 333: an open file may be passed ! 334: from one process to another across a pipe connection. ! 335: The primitives may be written ! 336: .DS ! 337: .ft CW ! 338: sendfile(wpipefd, fd); ! 339: .ft ! 340: .DE ! 341: in the sender process, and ! 342: .DS ! 343: .ft CW ! 344: (fd1, info) = recvfile(rpipefd); ! 345: .ft ! 346: .DE ! 347: in the receiver. ! 348: By using ! 349: .I sendfile, ! 350: the sender transmits a copy of its file descriptor ! 351: .I fd ! 352: over the pipe to the receiver; ! 353: when the receiver accepts it by ! 354: .I recvfile, ! 355: it gains a new open file denoted by ! 356: .I fd1. ! 357: (Other information, such as the user- and group-id of the sender, ! 358: is also passed.) ! 359: The facility may be used only locally, over a pipe; ! 360: we do not attempt to extend it to remote systems. ! 361: .PP ! 362: A similar facility is available in the 4.3 BSD system\*(<,\*([.7\*(.]\*(>, ! 363: but is little-used, possibly because in earlier versions ! 364: the related socket facilities were buggy. ! 365: It will appear in future versions of Unix System V. ! 366: .SH ! 367: Simple Examples ! 368: .PP ! 369: A graded set of examples will illustrate how these mechanisms ! 370: can solve problems that vex other systems. ! 371: .SH ! 372: .I "Talking to Users ! 373: .PP ! 374: When a user logs in to traditional Unix systems, an entry is made in the ! 375: .I /etc/utmp ! 376: file, recording the login name and the terminal or network channel ! 377: being used. ! 378: Although this file is often used merely to show who is where, ! 379: it is also used to establish communication with the user. ! 380: For example, the ! 381: .I write ! 382: command and the mail-notification service look up ! 383: a user's name, and send a message ! 384: to the corresponding terminal. ! 385: This simple scheme does not work well with windowing terminals, ! 386: because the messages disturb the protocol between ! 387: the host and the terminal, and because there is no obvious way ! 388: to relate the terminal's special file to a particular window. ! 389: Even without windows, there are security problems and other difficulties ! 390: that follow from letting users write on each other's terminals. ! 391: .PP ! 392: We use stream-mounting to interpose a program ! 393: between a terminal special file and the terminal itself. ! 394: The program, called ! 395: .I vismon , ! 396: mounts one end of a pipe on the user's terminal. ! 397: Normally it occupies an inconspicuous window, displaying system ! 398: activity and announcing arriving mail. ! 399: When some other process opens and writes on the special file ! 400: for the terminal, the mounted stream receives the data; ! 401: .I vismon ! 402: creates a new window, and copies this data to it. ! 403: The new window has a shell, so that if the message was ! 404: from a ! 405: .I write ! 406: command, the recipient can write back. ! 407: .PP ! 408: Communication between the terminal and the windowing ! 409: multiplexor on the host is not disturbed; ! 410: it continues to flow to the terminal itself, not to ! 411: .I vismon, ! 412: because the ! 413: .I mount ! 414: operation affects only the interpretation of file names, ! 415: not existing file descriptors. ! 416: .SH ! 417: .I "Network Calling: Simple Form ! 418: .PP ! 419: Making a network connection is a complicated activity. ! 420: There is often name translation of various kinds, ! 421: and sometimes negotiations with various entities. ! 422: With the Datakit\(rg VCS network\*(<,\*([.8\*(.]\*(>, ! 423: for example, a call is placed ! 424: by negotiating with a node controller. ! 425: When dialing over the switched telephone system, one must talk ! 426: to any of several kinds of automatic dialers. ! 427: Setting up a connection on an Internet ! 428: under any of the extant protocols requires translation of ! 429: a symbolic name to a net address, and then special communication ! 430: with the remote host. ! 431: These setup protocols should certainly not be in kernel code, so ! 432: most systems package them in user-callable libraries. ! 433: .PP ! 434: With our primitives, it is straightforward to encapsulate a ! 435: network-connection algorithm to a single executable program. ! 436: A application desiring to make an outward connection calls a simple routine ! 437: that creates a pipe, forks, and in the child process executes the ! 438: network dialer program. ! 439: The dialer passes back either an error code, or a file descriptor ! 440: referring to an open connection to the other machine. ! 441: The pseudo-code for this library routine, ! 442: neglecting error-checking and closing down the pipe, is: ! 443: .DS ! 444: .ft CW ! 445: netcall(address) ! 446: { int p[2]; ! 447: .sp .25 ! 448: pipe(p); ! 449: if (fork()!=0) ! 450: execute("/etc/netcaller", address, p[0]); ! 451: status = wait(); ! 452: if (bad(status)) ! 453: return(errcode); ! 454: passedinfo = recvfile(p[1]); ! 455: return(passedinfo.fd); ! 456: } ! 457: .ft ! 458: .DE ! 459: The ! 460: .ft CW ! 461: /etc/netcaller ! 462: .ft ! 463: program can be arbitrarily complicated, but does not occupy the ! 464: same address space as its caller. ! 465: In this way, if something in the network interface changes, ! 466: only one program needs to be fixed and reinstalled. ! 467: Its job is to create the connection, and pass its descriptor ! 468: for the open connection; it then terminates, and is no ! 469: longer involved in the connection. ! 470: Along the way, it may negotiate permissions and provide the caller's ! 471: identity reliably, because it can be a privileged (set-uid) program. ! 472: Thus, the segregation of the program that does the actual call setup ! 473: from its client is important. ! 474: When connections are made by library routines, ! 475: the operating system must know enough about ! 476: the call setup protocols to authenticate the caller to the target system. ! 477: In the method described above, this task need not be done in kernel code. ! 478: Even shared libraries, which do reduce the bulk of ! 479: code included with each program that makes network connections, ! 480: run in the protection domain of the person who ! 481: executes them. ! 482: .SH ! 483: .I "Process Connections ! 484: .PP ! 485: Suppose you are writing a multi-player game, ! 486: in which several people interact with each other. ! 487: One design uses a pair of programs: ! 488: a controller process that runs throughout the game and ! 489: coordinates ! 490: the play, and a player program, with one instance for each player, ! 491: that communicates with the controller. ! 492: .PP ! 493: When the controller starts, ! 494: it creates a conventionally-located file, stream-mounts ! 495: one end of a pipe on this file, ! 496: and waits for connection messages to arrive from players. ! 497: When the player program is run, it opens ! 498: the communication file, and creates its own pipe. ! 499: It starts communication by sending one end of this pipe to the ! 500: game controller over the communication file. ! 501: .PP ! 502: As each passed pipe appears on the controller's connection stream, ! 503: it accepts the connection with ! 504: .I recvfile. ! 505: Thereafter, each player transmits moves and receives replies ! 506: over its end of the pipe; ! 507: the controller reads players' moves and transmits replies ! 508: over the end it received. ! 509: It maintains the global state of the game, and uses the ! 510: .I select (2) ! 511: mechanism ! 512: to multiplex connection requests and the communication with the ! 513: player programs. ! 514: .SH ! 515: The Connection Server ! 516: .PP ! 517: The final example illustrates a general ! 518: connection server. ! 519: It combines ideas used by the initial network-calling ! 520: scheme and the game design, described above, ! 521: to create a flexible switchboard ! 522: through which programs can connect to remote or local services. ! 523: .PP ! 524: Two things are necessary for handling server-client relationships: ! 525: first, some program must establish itself as a server, ! 526: and wait for requests for the service; ! 527: and second, programs must make requests. ! 528: We will first describe the external appearance of the scheme (the ! 529: library entry points), then the addressing and naming, and then the implementation. ! 530: .PP ! 531: A program that desires to make a connection calls the routine ! 532: .I ipcopen, ! 533: passing a string ! 534: of characters that specifies the address and the desired service at ! 535: that address. ! 536: .DS ! 537: .ft CW ! 538: fd = ipcopen(service); ! 539: .ft ! 540: .DE ! 541: The ! 542: .I ipcopen ! 543: routine returns a file descriptor connected to the requested server. ! 544: If it fails, a string describing the error is available. ! 545: .PP ! 546: In order to announce a service, ! 547: .I ipccreat ! 548: is used; ! 549: its argument is a string that names the service. ! 550: The return value is a file descriptor ! 551: .I fd ! 552: that is a channel on which connection requests will be sent. ! 553: .DS ! 554: .ft CW ! 555: fd = ipccreat(service); ! 556: .ft ! 557: .DE ! 558: To wait for requests, the server uses the ! 559: .I ipclisten ! 560: routine. Its argument is the same ! 561: .I fd ! 562: returned by ! 563: .I ipccreat: ! 564: .DS ! 565: .ft CW ! 566: ip = ipclisten(fd); ! 567: .ft ! 568: .DE ! 569: .I Ipclisten ! 570: returns when some program calls ! 571: .I ipcopen ! 572: with an argument corresponding to the service, in a way discussed below. ! 573: The return value ! 574: is a structure containing ! 575: information about the caller, such as the user name, and, ! 576: where relevant, the name of the machine from which the call was placed. ! 577: This new connection may be rejected: ! 578: .DS ! 579: .ft CW ! 580: ipcreject(ip, errcode); ! 581: .ft ! 582: .DE ! 583: or it may be accepted: ! 584: .DS ! 585: .ft CW ! 586: fd = ipcaccept(ip, cfd); ! 587: .ft ! 588: .DE ! 589: If the server itself is capable of handling all communication with ! 590: its client, it passes a null file descriptor as ! 591: .I cfd, ! 592: and uses the return value of ! 593: .I ipcaccept ! 594: as a file descriptor to communicate with its client. ! 595: Depending on the locations of the server and the client, ! 596: this may be either a pipe, or a stream connection to a remote machine. ! 597: .PP ! 598: Sometimes, the purpose of a server is not to communicate directly, ! 599: but to set up another connection on behalf of its client. ! 600: A network dialing server, for example, receives the desired address ! 601: in the ! 602: .I ip ! 603: structure returned by ! 604: .I ipclisten, ! 605: and connects to this address with network-specific primitives. ! 606: If the connection succeeds, the server sends the descriptor ! 607: for the connection to the client using the ! 608: .I cfd ! 609: argument of ! 610: .I ipcaccept. ! 611: .PP ! 612: The various file descriptors in these calls all work properly ! 613: with the ! 614: .I select ! 615: system call, so a single program may issue several ! 616: .I ipccreat ! 617: calls, and wait a connection to appear before committing ! 618: itself to using ! 619: .I ipclisten ! 620: on any one of them. ! 621: .SH ! 622: .I Addresses ! 623: .PP ! 624: The arguments supplied to ! 625: .I ipcopen ! 626: and ! 627: .I ipccreat ! 628: are strings with several components ! 629: separated by exclamation mark `!' characters. ! 630: The first part is interpreted as a file name. ! 631: If it is absolute, it is used as is; otherwise, it is interpreted as ! 632: a file in the directory ! 633: .I /cs, ! 634: which we use, conventionally, to collect rendezvous points. ! 635: For example, a game controller like that discussed ! 636: in a previous section might announce itself with ! 637: .DS ! 638: .ft CW ! 639: ipccreat("mazewar"); ! 640: .ft ! 641: .DE ! 642: The player program could then connect to the controller with ! 643: .DS ! 644: .ft CW ! 645: ipcopen("mazewar"); ! 646: .ft ! 647: .DE ! 648: In this simple case, the IPC routines merely accomplish a convenient ! 649: packaging of the scheme discussed above. ! 650: .PP ! 651: When a multi-component argument is given to ! 652: .I ipcopen, ! 653: the server selected by the first component receives the remaining ! 654: components ! 655: as part of the ! 656: .I ip ! 657: structure returned by its ! 658: .I ipclisten, ! 659: and interprets them according to its own conventions. ! 660: For example, there is a dialing server for each kind of network. ! 661: If the first component of an ! 662: .I ipcopen ! 663: specifies a network server, ! 664: the remaining components conventionally supply an address ! 665: within that network, and possibly a service obtainable at that address. ! 666: We have three kinds of networks: ! 667: .I tcp ! 668: (TCP/IP connection), ! 669: .I dk ! 670: (Datakit connection), and ! 671: .I phone ! 672: (dial-up telephone). ! 673: Each network server adopts the convention that a missing service name ! 674: means a connection to an end-point that allows one to log in by hand. ! 675: Therefore, calling ! 676: .I ipcopen ! 677: with the strings ! 678: .DS ! 679: .ft CW ! 680: tcp!research.att.com ! 681: dk!nj/astro/research ! 682: phone!201-582-5940 ! 683: .ft ! 684: .DE ! 685: gets connections over which one will receive a `login:' greeting, ! 686: each over a different kind of network. ! 687: The servers are responsible for the details of name translation, ! 688: performing the appropriate connection protocol, and so forth. ! 689: Some examples of named services at particular locations are ! 690: .DS ! 691: .ft CW ! 692: tcp!dutoit.att.com!whoami ! 693: dk!research!smtp ! 694: .ft ! 695: .DE ! 696: The first is a debugging service that echoes facts about the ! 697: connection and the user ID of the person who requests it. ! 698: The second illustrates how remote mail is sent: ! 699: by connecting to the ! 700: .I smtp ! 701: server (mail receiver) on the appropriate machine. ! 702: .SH ! 703: .I "IPC Implementation ! 704: .PP ! 705: For a simple service, the ! 706: .I ipccreat ! 707: routine works just like the ! 708: game-manager program described above; it first creates a file in the ! 709: .I /cs ! 710: directory corresponding to the name of the service, then makes ! 711: a pipe and stream-mounts one end of the pipe on this file. ! 712: For complex services, which have a `!' in their names, the ! 713: simple service named to the left of the `!' must be created first; ! 714: when ! 715: .I ipccreat ! 716: is handed the name of such a service, it uses ! 717: a version of ! 718: .I ipcopen ! 719: referring to the simple, underlying server, and passes it the remainder ! 720: of the name. ! 721: In either case, ! 722: .I ipccreat ! 723: returns its own end of its pipe, ready to receive requests. ! 724: .PP ! 725: The ! 726: .I ipcopen ! 727: routine uses a technique that resembles that used by the ! 728: simple network calling routine described above, but differs ! 729: in detail. ! 730: It opens the file in ! 731: .I /cs ! 732: corresponding to the desired service, makes a pipe, and hands ! 733: one end of the pipe to the server. It then sends the actual contents ! 734: of the request (the full address) to its end of the pipe, ! 735: and waits for an acceptance or rejection message to appear on ! 736: this pipe. ! 737: .PP ! 738: The server ! 739: .I ipclisten ! 740: call waits for a stream (passed by someone's ! 741: .I ipcopen ) ! 742: to appear on the file descriptor mounted on its ! 743: .I /cs ! 744: communication file; as each appears, ! 745: it reads the request block from the passed stream, ! 746: and returns it to the server. ! 747: .PP ! 748: After analyzing the request, the server calls either ! 749: .I ipcaccept ! 750: or ! 751: .I ipcreject; ! 752: each sends an appropriate message back to the client over the passed ! 753: stream. ! 754: .I Ipcaccept ! 755: has two cases: ! 756: when its ! 757: .I cfd ! 758: argument is empty, the same pipe sent to ! 759: the server by the client is used for communication; when ! 760: .I cfd ! 761: is non-empty, ! 762: that file descriptor is sent back to the client. ! 763: .I Ipcopen ! 764: returns the appropriate descriptor. ! 765: .PP ! 766: .SH ! 767: .I "Network Managers" ! 768: .PP ! 769: The IPC routines discussed above handle both clients and servers ! 770: that are local to a single system, and are also sufficient to accomplish ! 771: outgoing network connections. ! 772: One missing piece is how to write the programs ! 773: that accept connections from a network, and arrange to invoke ! 774: the appropriate local services. ! 775: We call such programs ! 776: .I managers. ! 777: .PP ! 778: The networking part of a manager is specific to its ! 779: network, and usually must conduct dialogues both with the ! 780: operating system and with its remote client. ! 781: For example, the manager for TCP/IP must arrange ! 782: to receive IP packets sent to certain port numbers, ! 783: and analyze the packets to determine what service is being ! 784: requested; ! 785: then it must select a port number for ! 786: the conversation, communicate it to the peer, and arrange to collect ! 787: packets on this port number. ! 788: Finally, the manager must supply the selected local service. ! 789: Each network manager could have ! 790: .I "ad hoc" ! 791: code for this part of the job; ! 792: instead, they depend on a more general program called the ! 793: .I "service manager. ! 794: .SH ! 795: .I "The Service Manager ! 796: .PP ! 797: By using ! 798: .I ipccreat, ! 799: a process establishes itself as a server and prepares to receive requests. ! 800: While it is serving, it must remain in existence. ! 801: For some servers, like the multi-player game controller that ! 802: continues to run as users enter and leave the game, ! 803: the longevity of the server is appropriate. ! 804: However, many, or even most, useful services do not necessarily ! 805: need individual long-lived servers, because the service merely involves ! 806: execution of a particular program. ! 807: For example, services like ! 808: .I rlogin, ! 809: .I telnet, ! 810: .I smtp ! 811: and ! 812: .I ftp, ! 813: as well as simpler ones that merely provide the ! 814: date, or send a file to a line printer, can all ! 815: be accomplished merely by running the appropriate program ! 816: with input and output connected to the right place. ! 817: Even when the characteristics of such services differ ! 818: in detail, there are general patterns. ! 819: Some, for example, require no authentication, some require checking ! 820: of authentication according to an automatic scheme, and others ! 821: always insist on a password. ! 822: .PP ! 823: The observation that many services share a common structure ! 824: suggested a common solution: the Service Manager. ! 825: It is started when the operating system is booted, and is ! 826: driven by a specification file; ! 827: each entry in the file ! 828: contains the name of the service, and a list of actions ! 829: to be performed when that service is requested. ! 830: The service manager issues ! 831: .I ipccreat ! 832: for the name given in each entry; when another process uses ! 833: .I ipcopen ! 834: to request the service, the service manager carries out each ! 835: encoded action. ! 836: .PP ! 837: The most important action specifies a command to be executed; ! 838: for example, the line ! 839: .DS ! 840: .ft CW ! 841: date cmd(date) ! 842: .ft ! 843: .DE ! 844: means that connecting to the service ! 845: .I date ! 846: would run the `date' command. ! 847: Other actions may specify the user ID under which the program ! 848: is run: ! 849: .DS ! 850: .ft CW ! 851: uucp user(uucp)+cmd(/usr/lib/uucp/uucico) ! 852: .ft ! 853: .DE ! 854: This service specifies a passwordless connection to the ! 855: .I uucp ! 856: file-transfer program; ! 857: a locally-conventional TCP/IP port ! 858: number is used for such connections, and a corresponding convention ! 859: is used on our Datakit network. ! 860: There are other built-in actions: ! 861: .DS ! 862: .ft CW ! 863: login ttyld+password ! 864: .ft ! 865: .DE ! 866: means that the ! 867: .I login ! 868: service needs to install the line discipline module for terminal ! 869: processing, and also to execute the ! 870: .I login ! 871: command; ! 872: .DS ! 873: .ft CW ! 874: oklogin auth+ttyld+login ! 875: .ft ! 876: .DE ! 877: is similar, but allows passwordless login. ! 878: Authorization is checked by the ! 879: .I auth ! 880: specification, which determines whether the call came from a ! 881: trusted host on a trusted network, so that the passed user ID ! 882: can be believed. ! 883: .SH ! 884: Uses ! 885: .PP ! 886: The techniques described in this paper permit a general approach ! 887: to network and local connections in which most of the work ! 888: is done in a few user-mode programs. ! 889: As an example of the benefits of the scheme, we have unified ! 890: various commands that do remote login over two kinds of networks ! 891: (TCP/IP and Datakit). ! 892: A single command, ! 893: .I con, ! 894: tries various networks and uses the first over which a connection ! 895: can be made. ! 896: The traditional names (like ! 897: .I rlogin ) ! 898: are retained as links, but the only effect of using them is to ! 899: influence the order in which networks are tried. ! 900: The stream implementation makes the transport layers of the networks ! 901: sufficiently similar ! 902: that the same code can be used once the connection is established; ! 903: the techniques described here make even the connection interface uniform. ! 904: .PP ! 905: These same techniques extend well to inter-network connectivity. ! 906: For example, all our machines have a ! 907: Datakit interface, but only a few have Ethernet connections. ! 908: Nevertheless, from a Datakit-only machine, ! 909: it is easy to connect to another machine that ! 910: has only Ethernet, even one that does not run the ! 911: Ninth Edition system. ! 912: There are two schemes. ! 913: In the first, ! 914: the local operating system contains the TCP/IP protocol ! 915: code, and below the TCP/IP level, the `device' interface is ! 916: actually a Datakit connection to another local machine on both networks. ! 917: Because Datakit channels and the network layer expected by ! 918: TCP/IP have stream interfaces, they are easily connected; ! 919: on the gateway machine, ! 920: the IP packets are routed appropriately. ! 921: This approach transparently handles other services, like UDP, ! 922: that use the IP protocol. ! 923: .PP ! 924: The other scheme uses the methods described in this paper. ! 925: On the Datakit-only machine, ! 926: the TCP network dialout program does not ! 927: use TCP/IP at all, and indeed TCP/IP code need not be configured into ! 928: the operating system; ! 929: instead, it creates a Datakit transport-level connection ! 930: to a protocol-conversion server on a gateway machine. ! 931: A complementary server on the gateway accepts TCP/IP ! 932: connections on behalf of the Datakit-only machine, and forwards them. ! 933: The difference between the two schemes is invisible to ! 934: users of connection-oriented protocols, although it does not support ! 935: connectionless protocols like UDP. ! 936: .SH ! 937: Conclusion ! 938: .PP ! 939: Unix has always had a rich file system structure, ! 940: both in its naming scheme (hierarchical directories) ! 941: and in the properties of open files (disk files, devices, pipes). ! 942: The Eighth Edition exploited the file system even more insistently ! 943: than its predecessors ! 944: or contemporaries of the same genus. ! 945: Remote file systems, process files, and the face server ! 946: all create objects with names that can ! 947: be handed as usefully to an existing tool ! 948: as to a new one designed to take advantage of the object's special ! 949: properties. ! 950: Similarly, the stream I/O system ! 951: provides a framework for making file descriptors ! 952: act in the standard way most programs already expect, ! 953: while providing a richer underlying behavior, ! 954: for handling network protocols, or processing appropriate ! 955: for terminals. ! 956: .PP ! 957: The developments described here follow the same path; ! 958: they encourage use of the file name space ! 959: to establish communication between processes. ! 960: In the best of cases, ! 961: merely opening a named file is enough. ! 962: More complicated situations require more involved negotiations, ! 963: but the file system still supplies the point of contact. ! 964: Moreover, the necessary negotiations ! 965: may be encapsulated in a common form that hides the differences between ! 966: local and any of a variety of remote connections. ! 967: .SH ! 968: References ! 969: .PP ! 970: .]< ! 971: .ds [F 1 ! 972: .]- ! 973: .ds [A D. M. Ritchie ! 974: .ds [K bltj ! 975: .ds [T A Stream Input-Output System ! 976: .ds [J AT&T Bell Laboratories Technical Journal ! 977: .ds [D October 1984 ! 978: .ds [V 63 ! 979: .ds [N 8 ! 980: .nr [T 0 ! 981: .nr [A 0 ! 982: .nr [O 0 ! 983: .][ 1 journal-article ! 984: .ds [F 2 ! 985: .]- ! 986: .ds [A AT&T ! 987: .ds [T UNIX System V Release 3 STREAMS Programmer's Guide ! 988: .ds [K systemv streams ! 989: .ds [D 1986 ! 990: .ds [V 307-227 ! 991: .nr [T 0 ! 992: .nr [A 0 ! 993: .nr [O 0 ! 994: .][ 0 other ! 995: .ds [F 3 ! 996: .]- ! 997: .ds [A P. J. Weinberger ! 998: .ds [K remote ! 999: .ds [T The Version 8 Network File System ! 1000: .ds [J USENIX Summer Conference Proceedings ! 1001: .ds [D June 1984 ! 1002: .ds [C Salt Lake City, UT ! 1003: .nr [T 0 ! 1004: .nr [A 0 ! 1005: .nr [O 0 ! 1006: .][ 1 journal-article ! 1007: .ds [F 4 ! 1008: .]- ! 1009: .ds [A T. J. Killian ! 1010: .ds [T Processes as Files ! 1011: .ds [J USENIX Summer Conference Proceedings ! 1012: .ds [D June 1984 ! 1013: .ds [C Salt Lake City, UT ! 1014: .nr [T 0 ! 1015: .nr [A 0 ! 1016: .nr [O 0 ! 1017: .][ 1 journal-article ! 1018: .ds [F 5 ! 1019: .]- ! 1020: .ds [A R. Pike ! 1021: .as [A " and D. L. Presotto ! 1022: .ds [T Face the Nation ! 1023: .ds [J USENIX Summer Conference Proceedings ! 1024: .ds [D June 1985 ! 1025: .ds [C Portland, OR ! 1026: .nr [T 0 ! 1027: .nr [A 0 ! 1028: .nr [O 0 ! 1029: .][ 1 journal-article ! 1030: .ds [F 6 ! 1031: .]- ! 1032: .ds [A T. A. Cargill ! 1033: .ds [T The Blit Debugger ! 1034: .ds [J Journal of Systems and Software ! 1035: .ds [V 3 ! 1036: .ds [N 4 ! 1037: .ds [D December 1983 ! 1038: .ds [P 277-284 ! 1039: .nr [P 1 ! 1040: .ds [K pi ! 1041: .nr [T 0 ! 1042: .nr [A 0 ! 1043: .nr [O 0 ! 1044: .][ 1 journal-article ! 1045: .ds [F 7 ! 1046: .]- ! 1047: .ds [A Computer Systems Research Group, U.C. Berkeley ! 1048: .ds [T Unix Programmer's Reference Manual: 4.3 Berkeley Software Distribution ! 1049: .ds [K fourthree bsd ! 1050: .ds [D April, 1986 ! 1051: .ds [C Berkeley, California ! 1052: .nr [T 0 ! 1053: .nr [A 0 ! 1054: .nr [O 0 ! 1055: .][ 0 other ! 1056: .ds [F 8 ! 1057: .]- ! 1058: .ds [A A. G. Fraser ! 1059: .ds [T Datakit\-A Modular Network for Synchronous and Asynchronous Traffic ! 1060: .ds [J Proc. Int. Conf. on Commun. ! 1061: .ds [D June 1980 ! 1062: .ds [C Boston, MA ! 1063: .nr [T 0 ! 1064: .nr [A 0 ! 1065: .nr [O 0 ! 1066: .][ 1 journal-article ! 1067: .nr [W \w'1' ! 1068: .]> ! 1069: .nr [W \w'1'
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.