II. Questions et préférences
Dans cette section, nous essayons de présenter chacune des diverses questions soulevées dans les récents NWG/RFC et dans des conversations privées et, pour chaque question, nous proposons une réponse ou une politique. Dans bien des cas, de bonnes idées sont rejetées parce qu'à notre avis elles devraient être intégrées à un autre niveau.
A. Double remplissage
Comme l'explique le rapport BBN #1822, le côté Imp de l'interface Host-Imp concatène un 1 suivi de zéro ou plusieurs 0 pour compléter un message jusqu'à une limite de mot de l'Imp tout en préservant la longueur du message. En outre, le côté Host de l'interface Imp-Host prolonge un message avec des 0 pour le compléter jusqu'à une limite de mot du Host.
Le mécanisme de BBN fonctionne bien si le Host émetteur veut envoyer un nombre entier de mots, ou si le matériel du Host émetteur est capable d'envoyer des mots partiels. Cependant, si le Host émetteur veut envoyer un message de longueur irrégulière et que son matériel n'est capable d'envoyer que des messages multiples d'un mot, une convention supplémentaire est nécessaire.
L'une des solutions les plus simples consiste à modifier le côté Imp de l'interface Host-Imp pour qu'il n'ajoute que des 0. Cela signifierait que le logiciel du Host devrait fournir le 1 final. BBN a rejeté ce changement en raison d'une réticence forte, et compréhensible, envers les modifications matérielles. Il a aussi été suggéré qu'un correctif de cinq instructions dans le programme de l'Imp supprimerait le 1 fourni par l'interface, mais cela a également été rejeté, pour le nouveau motif qu'il semblait plus sûr de ne compter que sur le matériel du Host pour signaler la fin du message, et de ne pas dépendre du tout du logiciel du Host.
Deux autres solutions sont également possibles. L'une est le « double remplissage », par lequel le Host émetteur fournit 10* et le réseau fournit aussi 10*. À la réception, le Host récepteur retire alors les 10* 10* finaux. L'autre solution consiste à utiliser le marquage. Le marquage est une chaîne de la forme 0*1 insérée entre l'en-tête et le texte d'un message. Le but initial du marquage était de prolonger l'en-tête afin que le Host émetteur puisse commencer son texte sur une limite de mot. Il est aussi possible d'utiliser le marquage pour allonger un message afin qu'il se termine sur une limite de mot.
Remarquons que le double remplissage pourrait remplacer complètement le marquage en accolant le début du texte à l'en-tête. Pour les machines à 32 bit, c'est commode alors que le marquage ne l'est pas, tandis que pour d'autres longueurs, en particulier les machines à 36 bit, le marquage est bien plus commode que le double remplissage.
Nous n'avons pas de préférence marquée, en partie parce que nous pouvons envoyer des fragments de mot. Shoshani et al., dans le NWG/RFC #44, affirment que l'ajustement du marquage ne leur pose aucun problème, et ils disposent d'une machine à 32 bit. Comme l'idée du marquage est acceptée depuis un certain temps, nous suggérons de ne pas utiliser le double remplissage et d'utiliser le marquage pour ajuster la longueur d'un message. Nous notons que si BBN supprime un jour le 1 du remplissage matériel, seule une modification minime du logiciel du Host sera nécessaire du côté émission.
Un dispositif bien plus élégant (et plus coûteux) a été suggéré par W. Sutherland. Il a proposé que les interfaces Host/Imp soient assez intelligentes pour retirer le remplissage ou le marquage, et qu'elles puissent même analyser le message à la réception.
B. Reconnexion
Une très nombreuse population de spécialistes du réseau nous a malmenés pour avoir inclus la reconnexion dynamique dans le protocole. Nous avons pensé qu'il pourrait être intéressant de raconter comment elle en est venue à y être incluse.
Après avoir étudié quelque temps les connexions et leurs usages, nous nous sommes demandé comment le mécanisme des connexions se comparait aux formes existantes de communication entre processus au sein d'un Host. Deux aspects présentent un intérêt : quels formalismes ont été présentés dans la littérature, et quels mécanismes sont en usage. Les formalismes sont intéressants parce qu'ils conduisent à des mises en œuvre uniformes et à une conception économe. Les mécanismes existants sont intéressants parce qu'ils montrent quels problèmes doivent être résolus et indiquent parfois ce que pourrait être un formalisme approprié. En particulier, nous avons remarqué que les mécanismes qui relient une console au logger lors d'un appel entrant, les mécanismes de création d'un job et les mécanismes qui font passer une console d'un processus à l'autre au sein d'un job tendent à être très idiosyncrasiques et distincts de toutes les autres structures et de tous les autres mécanismes d'un système d'exploitation.
En ce qui concerne la littérature, il semble n'y avoir qu'une seule idée, avec plusieurs variantes, à savoir que les processus doivent partager une partie de leurs espaces d'adressage et se réveiller mutuellement de manière coopérative. Les sémaphores et les canaux d'événements sont des extensions pratiques des signaux de réveil, mais l'intention est fondamentalement la même. (Les canaux d'événements pourraient probablement fonctionner comme des connexions, mais cela ne semble pas relever de l'usage auquel ils sont destinés. Dans les petits systèmes, l'efficacité et la capacité des canaux d'événements varient en sens inverse.)
En ce qui concerne les mises en œuvre existantes, nous notons que plusieurs systèmes permettent à un processus d'apparaître comme un fichier aux yeux d'un autre processus. Certains systèmes, par exemple le SDS-940 du SRI, imposent une relation maître/esclave entre deux processus ainsi connectés, mais d'autres systèmes prévoient une relation d'égal à égal, par exemple le système PDP-6 du groupe AI au MAC. Le système PDP-6 offre aussi une fonction par laquelle un processus supérieur peut « entourer » un processus inférieur d'une correspondance entre des noms de périphériques et de fichiers et d'autres noms de périphériques et de fichiers. Les consoles ont presque la même sémantique que les fichiers, de sorte qu'il est tout à fait raisonnable qu'un processus inférieur croie communiquer avec la console alors qu'il communique en fait avec un autre processus.
La similitude entre les connexions de réseau et les connexions séquentielles existantes entre processus conforte notre conviction que les connexions de réseau sont probablement la bonne structure pour utiliser le réseau. De plus, cette structure est assez nette et compatible avec suffisamment de machines pour passer pour un formalisme ou une théorie, du moins au même titre que les autres formes de communication entre processus présentées dans la littérature.
Tout nouveau formalisme doit, selon nous, satisfaire au moins aux deux tests suivants :
-
Quels problèmes en suspens résout-il ?
-
Est-il fermé pour toutes les opérations ?
Dans le cas des connexions de réseau, les candidats pour le premier test sont ceux indiqués ci-dessus, c'est-à-dire toutes les opérations consistant à relier une console à un job ou à un processus. Présentent aussi un intérêt la modélisation des périphériques séquentiels tels que les lecteurs de bande, les imprimantes et les lecteurs de cartes, ainsi que la modélisation de leurs systèmes de mise en tampon (spooling, symbiont).
La seconde question évoque la fermeture. En appliquant le formalisme des connexions aux procédures d'appel entrant et de login, nous avons ressenti le besoin d'inclure une forme de commutation ou de reconnexion, et une forme extrêmement modérée en est présentée dans un article de la SJCC, qui est aussi le NWG/RFC #33. Cette forme modérée ne permet que la substitution d'AEN, et encore uniquement au moment de l'établissement de la connexion. Cependant, l'expérience commune montre que si une opération a une définition naturelle sur un domaine étendu, il devient tôt ou tard nécessaire, ou du moins souhaitable, d'étendre sa définition. Nous avons donc envisagé les extensions suivantes :
-
Commutation vers n'importe quel autre socket, éventuellement situé sur un autre Host.
-
Commutation même après le début du flux de données.
Il existe même un précédent qui laisse penser que ces extensions pourraient être utiles. Dans une certaine conception d'un système d'exploitation, nous voyons toutes les lignes téléphoniques disponibles comme appartenant à un processus vivant appelé le logger. Le logger répond aux appels, filtre les utilisateurs et crée des jobs et des processus. L'une des caractéristiques de la plupart des équipements de réponse téléphonique est que de nombreuses lignes peuvent desservir le même numéro de téléphone grâce à un bloc de numéros consécutifs et à un système de réponse rotatif. Dans notre recherche de modèles fidèles des systèmes pratiques, nous voulions pouvoir offrir un service équivalent aux utilisateurs du réseau, c'est-à-dire qu'ils puissent appeler un numéro unique annoncé et être connectés au logger. Ainsi, une présomption en faveur de la commutation est établie.
Nous voyons ensuite qu'après avoir interrogé un utilisateur potentiel, le logger doit connecter cet utilisateur à un job nouvellement créé. Le flux de données entre l'utilisateur et le logger a déjà commencé, si bien que le contrôle de flux doit être articulé avec la commutation si l'on veut ne pas perdre ni altérer les données en transit.
En ce qui concerne la commutation entre Hosts, nous imaginons facilement un service utilitaire réparti dans tout le réseau qui ferait passer des connexions d'un socket à un autre à l'insu de l'utilisateur. Cela ressemble aussi aux systèmes téléphoniques les plus perfectionnés, aux services courants des opératrices des compagnies de téléphone et aux systèmes privés répartis.
Ces considérations nous ont conduits à étudier la possibilité de trouver un type de reconnexion qui servirait de base à tous les modèles connus. L'algorithme n'est pas venu facilement, sans doute faute d'expérience de la théorie des automates finis, mais nous avons finalement produit l'algorithme présenté dans le NWG/RFC #36. Peu après, Bill Crowther a produit un algorithme équivalent qui aborde différemment les situations de concurrence.
Les spécialistes du réseau semblent avoir l'une de deux réactions. Soit c'était élégant et (peut-être ipso facto) utile, soit c'était complexe et (là encore peut-être ipso facto) inutile. Le second groupe était de loin le plus visible pour nous, et nous avons été placés sur la défensive, contraints d'admettre que la reconnexion dynamique était seulement
-
élégante
-
utile pour le login et le passage de console
En réponse à des critiques persistantes, nous avons apporté le changement suivant au protocole. Au lieu d'appeler le socket <O,H,O> pour se connecter, les sockets de la forme <U,H,O> et <U,H,1> sont respectivement les sockets d'entrée et de sortie d'une copie du logger ou, si un job a été démarré avec l'identifiant d'utilisateur U, ces sockets sont les sockets de console. Le protocole de login consiste donc à initier une connexion vers <U,H,O> et <U,H,1>. Si l'utilisateur U n'est pas en service, une copie du logger répondra et interrogera l'appelant. Si l'identifiant d'utilisateur U est en service, l'appel sera refusé. Cette modification a été suggérée récemment par Barry Wessler. (D'autres avaient aussi suggéré ce changement bien plus tôt, mais nous l'avions alors rejeté.)
Le logger peut exiger que l'appelant appartienne au même réseau virtuel, c'est-à-dire que l'appelant ait l'identifiant d'utilisateur U sur un autre Host, ou il peut exiger que l'utilisateur fournisse un mot de passe associé à l'identifiant d'utilisateur U, ou il peut exiger les deux. Certains systèmes pourront même choisir de permettre à quiconque de se connecter sous n'importe quel identifiant d'utilisateur.
Après le login, les AEN 0 et 1 restent les AEN de console. Chaque système dispose vraisemblablement de mécanismes pour faire passer la console, et ceux-ci seraient étendus pour connaître les AEN 0 et 1 des utilisateurs du réseau. Faire passer la console revient donc à reconnecter des sockets à des ports, et cela se passe au sein du Host, sans le réseau.
Lors de conversations avec Meyer et Skinner après réception du NWG/RFC #46, ceux-ci ont suggéré un schéma de login différent à la fois de celui de Meyer et du nôtre décrit dans la section ci-dessus. Leur nouveau schéma nous a semblé un peu meilleur et nous attendons avec intérêt leur prochaine note.
Il est généralement admis que le login doit être de « troisième niveau », c'est-à-dire situé au-dessus du niveau du NCP. Nous commençons à être indifférents quant aux schémas de login particuliers ; tous semblent acceptables et aucun ne nous impressionne beaucoup. Nous suggérons d'en essayer plusieurs. Modifier la procédure locale de login représente certes une certaine charge, mais nous pensons que traiter des procédures de login diverses n'impose aucune difficulté supplémentaire. En effet, les séquences de texte et les conventions d'interruption sont si hétérogènes que la charge additionnelle consistant à suivre, par exemple, notre schéma sur notre système et celui de Meyer sur Multics est minime.
Nous sommes d'accord pour que la reconnexion ne soit pas exigée dans le protocole initial, et nous la proposerons plus tard comme outil facultatif et expérimental. Par ailleurs, nous tenons à prédire officiellement que des fonctions générales de reconnexion deviendront utiles et fourniront un cadre unificateur aux structures de système d'exploitation actuellement ad hoc.
C. Découplage des connexions et des liens
Bill Crowther (BBN) et Steve Wolfe (UCLA) ont suggéré indépendamment que les liens ne soient pas attribués à des connexions particulières. Ils proposent plutôt d'inclure le socket de destination dans le texte du message, puis d'envoyer les messages sur n'importe quel lien non bloqué.
Nous avons abordé brièvement cette question dans le NWG/RFC #37, et nous estimons qu'il existe encore des arguments en faveur de chacune des deux solutions. Compte tenu de l'accent mis actuellement sur la simplicité, la rapidité et de faibles besoins en mémoire centrale, il semble plus efficace de laisser les liens et les connexions couplés. Nous recommandons donc cette solution.
D. Signalement des erreurs
Comme l'ont mentionné J. Heafner et E. Harslem de la RAND, il est important de traiter les erreurs susceptibles de se produire. Une bonne philosophie consiste à se prémunir contre toute entrée qui détruirait la cohérence de la base de données du NCP.
La formulation précise de la commande d'erreur donnée par Heafner et Harslem dans le NWG/RFC #40 et par Meyer dans le NWG/RFC #46 semble raisonnable et nous recommandons son adoption. Quelques commentaires s'imposent toutefois.
Il convient de distinguer les erreurs de ressources des autres types d'erreurs. Les erreurs de ressources ne sont que la détection de conditions de surcharge. Les conditions de surcharge sont bien définies et valides, bien que peut-être indésirables. Les autres types d'erreurs traduisent un logiciel ou un matériel défaillant. Nous estimons que les erreurs de ressources ne doivent pas être traitées par des mécanismes d'erreur, mais par des mécanismes propres au problème. Ainsi, la commande <CLS> peut être émise lorsqu'il n'y a plus de place pour conserver des <RFC> en attente. Le protocole de contrôle de flux est conçu uniquement pour gérer la surcharge des tampons.
En ce qui concerne les véritables erreurs, nous ne sommes pas certains de la valeur de la commande <ERR> pour son destinataire. Son NCP est vraisemblablement défaillant, et le bombarder de commandes d'erreur risque seulement d'aggraver le problème. Nous recommandons donc que la génération d'erreurs soit facultative, que toutes les erreurs soient consignées localement dans un fichier chronologique et que les commandes <ERR> reçues soient de même consignées dans un fichier chronologique. Aucune action corrective n'est spécifiée pour l'instant.
Dans le peu de temps où le réseau a fonctionné à l'UCLA, nous nous sommes convaincus que le réseau lui-même générera très peu d'erreurs. Nous avons observé l'équipe de BBN déboguer et tester le programme de l'IMP, et il nous a semblé que la plupart des erreurs affectaient la synchronisation et le débit plutôt que la validité. La plupart des erreurs proviendront donc probablement de Hosts défaillants et/ou de NCP bogués.
E. Test et compte rendu d'état
Une aide précieuse au débogage consiste à pouvoir obtenir des informations sur ce qu'un NCP étranger pense qu'il se passe. Une façon commode de le faire est de permettre aux NCP d'envoyer leur état quand ils le souhaitent, mais de toujours les obliger à le faire lorsqu'ils reçoivent une demande.
Comme nous considérons cette fonction avant tout comme un outil de débogage, nous suggérons d'utiliser un lien distinct, par exemple 255. L'intention est que le traitement des demandes d'état et la génération des messages d'état utilisent le moins possible la machinerie normale. Nous suggérons donc que le lien 255 serve à envoyer les commandes « demande d'état » et « l'état est ». La forme suit la suggestion de la page 2 du NWG/RFC #40.
La commande <ECO> de Meyer se met en œuvre facilement et remplit la fonction plus élémentaire consistant à tester si un NCP étranger est vivant. Nous suggérons que la longueur de la commande <ECO> soit variable, car 48 bits ne semblent avoir aucune signification particulière dans ce contexte. En outre, l'intérêt d'un commutateur binaire de (vraisemblablement) 8 bits n'est pas clair ; nous recommandons donc une paire de commandes :
<ECO> <length> <text>
et
<ERP> <length> <text>
où
<length> fait 8 bits.
À la réception d'une commande <ECO>, le NCP renverrait l'écho au moyen de la commande <ERP>.
F. Extension et expérimentation
Comme Meyer le fait justement remarquer dans le NWG/RFC #46, le protocole de réseau est une affaire de couches. Trois niveaux apparaissent jusqu'ici.
-
Protocole du réseau IMP
-
Protocole du programme de contrôle du réseau
-
Protocole de niveau utilisateur spécial ou de niveau sous-système
Ce dernier niveau doit rester propre à chaque Host (voire à chaque utilisateur). Le premier niveau est bien spécifié par BBN, et nous nous concentrons ici sur le niveau 2. Nous souhaitons que le niveau 2 reste aussi neutre et simple que possible, et nous convenons en particulier que le protocole de login doit se situer autant que possible au niveau 3.
Malgré la simplicité et la prévoyance, il se présentera des occasions où le protocole de niveau 2 devra changer ou faire l'objet d'expériences. Afin de permettre l'expérimentation et le changement, nous recommandons que seuls les numéros de lien 2 à 31 soient attribués aux connexions ordinaires, les autres numéros de lien, de 32 à 255, étant utilisés à titre expérimental. Nous avons déjà suggéré que le lien 255 serve aux demandes et réponses d'état, ce qui concorde avec notre vision du caractère expérimental de cette fonction.
Nous recommandons aussi que les préfixes de commande de contrôle à partir de 255 en descendant soient utilisés pour l'expérimentation.
Ces deux conventions suffisent, selon nous, à permettre une expérimentation commode de nouveaux protocoles entre n'importe quel sous-ensemble des sites. Nous ne sommes donc pas favorables à l'inclusion de la suggestion d'Ancona, dans le NWG/RFC #42, d'un code de type de données du message placé dans les huit premiers bits du texte d'un message.
G. Multiplexage de ports sur des sockets
Wolfe dans le NWG/RFC #38 et Shoshani et al. dans le NWG/RFC #44 suggèrent qu'il devrait être possible de rattacher plus d'un port à un socket. Bien que tous nos diagrammes et nos appels système prototypes aient montré une correspondance biunivoque entre sockets et ports, c'est strictement une question de mise en œuvre locale. Nous notons que les sockets forment un espace de noms à l'échelle du réseau dont le seul but est de servir d'interface entre les structures idiosyncrasiques propres à chaque système d'exploitation. Nos références aux ports ne se veulent qu'indicatives et doivent être ignorées si aucune structure interne ne leur correspond. La plupart des systèmes possèdent toutefois de telles structures ; nous continuerons donc à les utiliser à titre d'illustration.
H. Écho, interruptions et conversion de code
1. Interruptions
Nous avions l'impression que tous les systèmes d'exploitation surveillaient l'arrivée d'un caractère réservé depuis le clavier pour l'interpréter comme un signal d'interruption. Tom Skinner et Ed Meyer du MIT nous apprennent que les TTY modèle 37 et l'IBM 2741 génèrent un « espace long » de 200 à 500 millisecondes, détecté par le matériel du canal d'E/S et transmis au système d'exploitation sous forme d'interruption. L'« espace long » n'est pas un caractère : il n'a pas de code ASCII et ne peut pas être généré par un programme.
Il y a bien plus d'un an, nous avions examiné le problème de la simulation des interruptions de console et rejeté une commande de type <INT> parce qu'elle ne modélisait correctement aucun système que nous connaissions. Nous revenons aujourd'hui sur notre position et recommandons la mise en œuvre d'un appel système INTERRUPT et d'une commande de contrôle <INT>, comme le suggère Meyer dans le NWG/RFC #46.
Deux restrictions de la fonction d'interruption doivent être observées. Premièrement, cette fonction ne doit pas être utilisée pour communiquer avec des systèmes qui surveillent des caractères d'interruption. Deuxièmement, les connexions qui ne s'apparentent pas à une console ne devraient probablement pas avoir d'interruptions. Nous recommandons que les systèmes suivent leurs propres conventions et, si un <INT> arrive pour une connexion sur laquelle il ne devrait pas arriver, que le <INT> soit écarté et éventuellement renvoyé comme erreur.
2. Écho et conversion de code
Nous pensons que chaque site doit poursuivre sa politique actuelle en matière d'écho et que la conversion de code doit être effectuée par le processus utilisateur. La normalisation dans ce domaine doit attendre de nouveaux développements.
La suggestion d'Ancona d'un transducteur frontal piloté par table semble être la bonne solution, mais nous pensons que de telles techniques relèvent d'une discussion plus large portant sur des langages de plus haut niveau pour le réseau.
I. Dispositifs de diffusion
Heafner et Harslem suggèrent, dans le NWG/RFC #39, un dispositif de diffusion, c'est-à-dire <TER> et <BDC>. Nous ne comprenons pas pleinement l'intérêt de ce dispositif et y sommes donc défavorables. Nous soupçonnons que nous en comprendrions mieux l'intérêt si nous avions davantage d'expérience d'OS/360. Il est probablement vrai, en général, que les sites exploitant OS/360 ou des systèmes semblables trouveront nos suggestions sur le protocole de réseau moins pertinentes que les sites exploitant des systèmes à temps partagé. Nous apprécierions tout exposé convaincant sur la relation entre OS/360 et les concepts et hypothèses qui sous-tendent le protocole de réseau.
J. Numéros d'instance
Meyer, dans le NWG/RFC #46, suggère d'étendre le socket pour y inclure un code d'instance qui identifie le processus rattaché au socket. Nous avons soigneusement organisé les choses pour que les processus soient indiscernables. Nous l'avons fait en pensant que, tant sur le plan formel que sur le plan pratique, la question de savoir si un calcul est effectué par un ou plusieurs processus ne concerne que le Host. Nous pensons donc que tous les processus d'un job doivent coopérer pour attribuer les AEN. Si un système d'exploitation dispose de fonctions permettant de faire passer une console d'un processus à l'autre au sein d'un job, ces fonctions s'articulent parfaitement avec le protocole de réseau actuel, même avec le protocole de reconnexion ; mais les numéros d'instance font obstacle à une telle procédure.
Nous suggérons que cette question soit discutée à fond, car elle touche à la philosophie fondamentale des sockets et des connexions. Pour l'instant, nous recommandons des numéros de socket de 40 bits sans codes d'instance.
K. Les AEN
Personne, nous compris, n'est particulièrement satisfait de notre nom AEN pour les 8 bits de poids faible du socket. Nous avons rejeté socket_number et ne sommes pas plus satisfaits du socket_code de Meyer. Le mot socket ne devrait pas faire partie du nom du champ, et nous sollicitons des suggestions.