Einleitung
(Die hier vorgetragenen Ansichten sind sowohl meine persönlichen als auch solche, die nach meiner Überzeugung einen Konsens der Network Working Group am Project MAC darstellen. Die Fürwörter „ich“ und „wir“ dienen dazu, zwischen beiden zu unterscheiden.)
Am 21. und 23. April führten Thomas P. Skinner und ich Telefongespräche mit Steve Crocker in UCLA über das Netzwerkprotokoll und insbesondere über unseren Vorschlag in NWG/RFC 46. Die folgenden Punkte wurden erörtert. (Ich hoffe, Steve verzeiht mir, wenn ich ihn ungenau wiedergebe.)
-
Steve erklärte, dass seiner Ansicht nach die Notwendigkeit einer dynamischen Wiederverbindung von den Netzteilnehmern später erkannt werden wird. Wegen fehlenden Konsenses werde sie jedoch nicht in die ursprüngliche Implementierung aufgenommen. (Wir am Project MAC befürworten diese Haltung, sie zunächst nicht aufzunehmen.)
-
Steve unterstützte die Implementierung des in NWG/RFC 46 beschriebenen Netzwerkbefehls INT.
Dieser Befehl erlaubt es einem Prozess, der sich bereit erklärt hat, Unterbrechungen über eine Socket-Verbindung anzunehmen, von dem Prozess am anderen Ende zuverlässig unterbrochen zu werden. Die Unterbrechung veranlasst einen Prozess, seine laufende Ausführung abzubrechen und eine Prozedur auszuführen, die er als INT-Handler festgelegt hat. (Der NCP legt den INT-Handler nicht fest. Das ist Aufgabe höherer Protokolle.)
Der Befehl INT ist speziell dafür gedacht, von einem Protokoll der dritten Ebene zur Benutzersteuerung und -kommunikation (UCC) verwendet zu werden, um ein „quit“-Signal zu implementieren. In einem solchen Protokoll vereinbaren der Anforderer und der erzeugte Prozess, dass ein INT, das sich auf eine bestimmte Socket-Verbindung bezieht und über die NCP-Steuerstrecke an den erzeugten Prozess übertragen wird, das standardmäßige „quit“-Signal ist. Der erzeugte Prozess stellt einen INT-Handler bereit, der diese „quit“-Funktion implementiert. (Dies schließt eine andere Auslegung von INT durch andere Protokolle der dritten Ebene nicht aus.)
Obwohl viele Systeme das „quit“ als Steuerzeichen im Teletype-Eingabestrom implementieren, setzen Systeme wie CTSS, Multics und andere es als eine Pause von 200 ms auf der Leitung um. Wir am MAC halten das erste Verfahren für eine unerwünschte Implementierung innerhalb des Netzwerks (das zweite ist unmöglich). Ich habe mehrere Gründe dafür vorgetragen (und ich glaube, Steve stimmte zu).
(a) Die Strecke, über die das quit-Zeichen übertragen werden soll, kann blockiert sein.
(b) Während die Unterbrechung am wirksamsten innerhalb des NCP implementiert wird, ist es unerwünscht, dass der NCP den übertragenen Daten eine bestimmte Struktur aufzwingt. (Siehe die Erörterung weiter unten.) Dies wäre erforderlich, wenn der NCP einen Datenstrom nach einem Steuerzeichen durchsuchen sollte.
(c) Das Durchsuchen des Eingabestroms verringert die Effizienz des NCP in einem Teilsystem erheblich, in dem die Geschwindigkeit für einen wirksamen Betrieb entscheidend ist.
Steve wies darauf hin, dass die Implementierung von INT als „quit“ nicht unbedingt ausschließen sollte, dass ein HOST ein Steuerzeichen im Eingabestrom ebenfalls als „quit“ auffasst.
- Steve lehnt es sowohl ab, das Instanz-Tag in die Socket-Kennung aufzunehmen, als auch, im Identifikator ein Nullfeld für eine spätere Definition zu reservieren. Er nannte mehrere Gründe:
(a) Mehrere Prozesse eines einzelnen Benutzers sollten für einen fremden Prozess ununterscheidbar sein. (Dem stimme ich in bestimmten Fällen zu, wenn Prozesse zu gemeinsamem Handeln koordiniert sind. Doch wie steht es um den Fall, dass zwei Prozesse desselben Benutzers das Netzwerk unabhängig voneinander nutzen wollen?)
(b) Ein Prozess, der sich mit einem der Prozesse eines fremden Benutzers verbinden möchte, kennt das Instanz-Tag des betreffenden Prozesses nicht und kann es auch nicht ohne Weiteres in Erfahrung bringen.
(c) Sollte sich ein Instanz-Tag später als wünschenswert erweisen, ließe es sich mit einiger Mühe hinzufügen. (Ich behaupte, dass etwas so Grundlegendes wie die Länge einer Socket-Kennung sich als sehr änderungsresistent erweisen wird.)
Tom erklärte, man könne vielleicht die drei niedrigsten Bits des Benutzercodes für eine spätere Auslegung als Instanz-Tag reservieren. Er hält ein getrenntes Feld nicht für besonders wichtig.
Steves Argumente scheinen etwas für sich zu haben. Vielleicht ist Toms Vorschlag der richtige Weg. In dieser Frage bin ich derzeit unentschieden.
- Wir alle (Steve und das MAC) scheinen darin übereinzustimmen, dass auf der NCP-Ebene den übertragenen Daten keine besondere Struktur aufgezwungen werden sollte. Für einen NCP sind alle zu übertragenden Daten Bitfolgen beliebiger Länge. Ein erfreuliches Ergebnis ist, dass die schwierige Frage der Zeichensätze auf dieser Protokollebene nicht entschieden werden muss. Eine Zeichensatzfestlegung auf der NCP-Ebene würde die Einigung auf das Protokoll verzögern und diesen Zeichensatz änderungsresistenter machen. (Wenn es einen Standardzeichensatz geben soll, ziehen wir ASCII vor. Schließlich ist er der bevorzugte Standard unserer fördernden Organisation.)
Wir stimmen mit Steve auch darin überein, dass es auf der NCP-Protokollebene kein optionales Echo von Nachrichten geben sollte. (Dies ist auch die Position der SDC-Leute in RFC 44.)
-
Shoshani, Long und Landsberg erklären ebenfalls (RFC 33), dass sie es vorziehen, Nachrichten so auszurichten, dass sie an einer Wortgrenze enden, statt doppelt aufzufüllen. Steve stimmt mit uns darin überein, dass ihm doppeltes Auffüllen nicht gefällt.
-
In unserem Vorschlag (RFC 46) schlagen wir vor, RFCs nur für offene Sockets in eine Warteschlange zu stellen und RFCs an inaktive oder verbundene Sockets mit dem Befehl CLS automatisch abzulehnen. Steve schlägt vor, RFCs an diese Sockets kurz in eine Warteschlange zu stellen. Bleibt der Socket nach dem Eintreffen des RFC für ein bestimmtes Intervall in einem unannehmbaren Zustand, wird er abgelehnt. Dieses Verfahren ermöglicht die Implementierung bestimmter Arten von Netzwerkbefehls-Wechselwirkungen mit kritischen Wettläufen. Ein solches Verfahren begrenzter Warteschlangenbildung erscheint mir nicht unvernünftig.
-
Steve, Tom und ich erörterten Strategien für ein Protokoll zur Benutzersteuerung und -kommunikation (UCC). Steve sagte, unsere UCC-Strategie (RFC 46) gefalle ihm nicht, weil sie das Aufrechterhalten zweier Vollduplex-Verbindungen zum Anfordererprozess und das Umschalten zwischen ihnen erfordere.
Steve legte einen Alternativvorschlag vor: Ein Prozess, der auf einem fremden HOST einen Benutzerprozess erzeugen möchte, richtet RFCs an die Sockets 0 und 1 des Benutzers, dessen Prozess er erzeugen möchte. Sind diese Sockets inaktiv, leitet der NCP diese Anforderungen automatisch an den Logger-Prozess des fremden HOST weiter. Der Logger nimmt die Verbindung an und vollzieht das Anmelderitual. Ist es erfolgreich, erzeugt der Logger einen Benutzerprozess und gibt die übernommenen Sockets frei, damit der erzeugte Prozess sie zur Kommunikation mit dem Anfordererprozess nutzen kann. (Ich bemerke, dass dies auf Netzwerkebene keine Wiederverbindung nutzt, da der Logger Sockets verwendet, die dem letztendlichen Benutzer gehören. Es beinhaltet jedoch eine interne Wiederverbindung.)
Tom und ich wandten dagegen ein, dass dies das UCC-Protokoll auf die NCP-Ebene bringt. (Der NCP muss alle RFCs an die inaktiven Sockets 0 und 1 an einen Logger-Prozess leiten.) Ich machte den raschen Vorschlag, unsere beiden Vorschläge könnten kombiniert werden, sodass der Anforderer ein „Signalisierungs“-RFC an einen „Signal“-Socket des UCC-Prozesses richtet. Die UCC lehnt das RFC ab, merkt sich aber, wer anruft. Sie versucht dann, zwei Sockets des zu erzeugenden Prozesses mit den Sockets des Anforderers zu verbinden, und führt das Anmelderitual über diese durch. Steve gefiel dies und regte an, ich solle es aufschreiben.
Nach dem Gespräch fielen mir mehrere Nachteile dieser UCC-Strategie ein:
(a) Sind die Steuer-Sockets eines erzeugten Prozesses auf 0 und 1 beschränkt, kann es vorkommen, dass ein rechtmäßiger Benutzer nicht mit einer fremden UCC kommunizieren kann, weil die UCC diese Sockets bereits zur Kommunikation mit einem Betrüger verwendet. Der Logger wird dies entdecken und den Betrüger abschalten, doch ist dies ein ärgerlicher Sicherheitsverstoß. Ein bösartiger Prozess könnte gleichzeitig mehrere Anforderungen ausgeben, um die Sockets zu belegen und einem rechtmäßigen Benutzer den Zugang zu verwehren. Eine bessere Lösung ist es, jedes beliebige Socket-Paar des potenziellen Benutzerprozesses als Steuerweg zuzulassen. Damit kann die UCC gleichzeitige Abfragen konkurrierender Anforderer durchführen.
(b) Ein Nachteil sowohl von Crockers UCC als auch der kombinierten UCC ist, dass der anzumeldende Benutzer dadurch angegeben wird, dass ein Socket eines bestimmten Benutzers übergeben wird. Der Logger muss nun zusätzlich prüfen, ob der Benutzer, den er anmeldet, tatsächlich zu dem Socket-Paar gehört, über das er spricht. Dies erscheint als die Umkehrung des bevorzugten Verfahrens: einen Benutzer zu identifizieren und dann den Benutzercode für seine Socket-Kennungen zu bestimmen.
(c) Der Benutzer kennt möglicherweise den Socket-Benutzercode des Benutzers nicht, den er am fremden HOST anmelden möchte. (Schließlich gibt es keinen grundsätzlichen Grund, warum der Anforderer- und der erzeugte Prozess denselben Benutzercode haben sollten, solange der Anforderer den fremden Logger zufriedenstellt.)
(d) Bei der kombinierten Strategie kann der Anforderer nicht angeben, welchen Socket-Benutzercode er wünscht. Die einzige Annahme, die die UCC treffen kann, ist die, dass der Anfordererprozess einen Prozess anmelden möchte, der denselben Socket-Benutzercode hat wie er selbst. (Das mag nicht sehr wichtig erscheinen, doch schwebt mir ein Verfahren vor, bei dem ein lokaler Prozess existiert, der es an den lokalen HOST angeschlossenen Konsolen ermöglicht, sich an einem fremden HOST anzumelden, ohne lokal angemeldet zu sein.)
(e) Die Idee, einem Prozess zu erlauben, sich im Netzwerk durch Verwendung seines Socket-Benutzercodes als ein anderer Prozess auszugeben (selbst mit den besten Absichten), führt zu einem potenziell gefährlichen Sicherheitsverstoß. Ich meine, es sollte ein grundlegendes Protokollgesetz sein, dass kein einziger Prozess Verbindungen über einen Socket anfordern oder annehmen oder Daten darüber senden oder empfangen darf, dessen Benutzercode nicht der eigene ist. Dies gilt nicht für einen NCP-Prozess, der für solche Übertragungen verantwortlich ist, und hindert auch einen privilegierten Prozess nicht daran, Verbindungen zwischen einem fremden Prozess und einem anderen lokalen Prozess zu schließen oder abzulehnen.
Ich halte den UCC-Vorschlag, den wir in RFC 46 vorgelegt haben, nach wie vor für ein gutes und gangbares Verfahren. Er erfordert keine Socket-Wiederverbindung (weder ausdrücklich im gesamten Netzwerk noch implizit innerhalb eines NCP), und keiner der oben erhobenen Einwände trifft auf ihn zu. Der einzige besondere Nachteil, den ich sehe, ist, dass er den Anfordererprozess zwingt, zwei Vollduplex-Verbindungen aufrechtzuerhalten und zwischen ihnen umzuschalten. Ich sehe darin kein ernsthaftes Hindernis. Ich würde besonders zu diesem Punkt die Kommentare der Netzteilnehmer begrüßen.
Glücklicherweise ist die UCC ein Protokoll der dritten Ebene. Der NCP der zweiten Ebene kann festgelegt werden, bevor wir eine endgültige Einigung über eine UCC erzielen, sofern der NCP die Implementierung einer gangbaren UCC zulässt.
Steve äußerte die Ansicht, dass es keine anfängliche Standard-UCC geben müsse und dass es mehrere UCCs geben könne. Wir am MAC widersprechen. Wenn wir alle miteinander sprechen sollen und nicht nur zwischen begrenzten Teilmengen von HOSTs im Netzwerk, muss es eine anfängliche Standard-UCC geben, die jedermann implementiert. (Steve hat natürlich recht, dass daneben auch andere experimentelle UCCs implementiert werden können.)
Es ist theoretisch möglich, dass jeder HOST mehrere Softwaresätze bereitstellt, damit ein Anfordererprozess mit den Loggern von HOSTs kommunizieren kann, die unterschiedliche UCCs implementieren. Ich glaube nicht, dass es in der Praxis so laufen wird. Jeder HOST wird das ihm am meisten zusagende UCC-Protokoll implementieren und einen einzigen Softwaresatz bereitstellen, sodass ein Anfordererprozess nur mit solchen HOSTs kommunizieren kann, die ähnliche UCCs implementieren.
Ich glaube nicht, dass am Project MAC viel Begeisterung dafür besteht, eine nicht standardisierte UCC nur deshalb zu implementieren, damit wir untereinander sprechen können. Wir wollen eine einzige, an allen Installationen unterstützte UCC implementieren, sodass wir uns mit diesem Protokoll an allen HOSTs anmelden können und Benutzer an allen fremden HOSTs sich bei uns anmelden können.
Hinweis: Dieser RFC wurde von Altair Petrofsky 7/97 zur Aufnahme in die Online-RFC-Archive in maschinenlesbare Form gebracht.