Annotation of researchv10dc/vol2/ipc/ipc.ms, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.