Aller au contenu principal

III - Programme de contrôle du réseau

Chaque HOST met en œuvre un module appelé programme de contrôle du réseau (NCP) qui contrôle toutes les communications de réseau impliquant ce HOST. Le réseau des NCP forme un système de communication distribué qui met en œuvre des chemins de communication entre processus individuels. Les problèmes du protocole NCP portent sur: (i) la définition de ces chemins de communication, et (ii) un mécanisme de coordination du système NCP distribué pour maintenir ces chemins de communication. Ces points sont examinés ci-dessous.

Les sockets​

La communication entre deux processus se fait au moyen d'une connexion simplex entre deux sockets: un socket d'émission rattaché à un processus et un socket de réception rattaché à un autre processus. Les sockets ont les caractéristiques suivantes:

Identificateur de socket - Un identificateur de socket est utilisé dans tout le réseau pour identifier un socket de manière unique. Il se compose de 48 bits, ayant les éléments suivants:

  1. Numéro d'utilisateur (24 bits) - Un socket rattaché à un processus est identifié comme appartenant à ce processus par un numéro d'utilisateur composé de 8 bits de code de HOST "de rattachement" plus 16 bits de code d'utilisateur attribués par le HOST de rattachement. Ce numéro d'utilisateur est le même pour tous les sockets rattachés à l'un quelconque de ses processus dans n'importe quel HOST.

  2. Instance tag (8 bits) - Plusieurs processus appartenant à un même utilisateur peuvent exister simultanément dans un même HOST. L'instance tag identifie le processus précis auquel un socket appartient. Par convention, le premier processus d'un utilisateur sur un HOST à utiliser le réseau reçoit l'instance tag = 0.

  3. Numéro de HOST (8 bits) - C'est le code du HOST sur lequel existe le processus rattaché.

  4. Code de socket (8 bits) - Ce code prévoit 128 sockets d'émission et 128 sockets de réception dans chaque processus. Le bit de poids faible détermine s'il s'agit d'un socket "d'émission" (= 1) ou "de réception" (= 0).

États des sockets - Chaque socket a un état associé. Le NCP peut mettre en œuvre des états plus transitoires d'un socket, mais les trois suivants ont une importance conceptuelle.

  1. Inactif - il n'existe actuellement aucun processus ayant indiqué au NCP qu'il souhaite écouter ce socket. Aucun autre processus ne peut communiquer avec succès avec un socket inactif.

  2. Ouvert - un processus a accepté d'écouter les événements concernant ce socket, mais celui-ci n'est pas encore connecté.

  3. Connecté - Ce socket est actuellement connecté à un autre socket.

File d'événements du socket - Une file d'événements à révéler au processus propriétaire est tenue pour chaque socket ouvert ou connecté. Elle se compose d'une liste, classée chronologiquement, de certains événements engendrés par l'action d'un ou de plusieurs processus étrangers tentant de connecter ou de déconnecter ce socket. Une entrée de la file d'événements se compose du type d'événement et de l'identificateur du socket étranger concerné. Les types d'événements suivants sont définis:

  1. "request" - un socket étranger demande une connexion. (non mis en file si le socket local est déjà connecté)

  2. "accept" - un socket étranger accepte la connexion demandée.

  3. "reject" - un socket étranger refuse la connexion demandée.

  4. "close" - un socket étranger déconnecte une connexion existante.

Un événement "request" est retiré de la file lorsqu'il est accepté ou refusé. Les autres événements sont retirés de la file au fur et à mesure qu'ils sont révélés au processus propriétaire.

Certains événements sont destinés à être transparents pour le processus propriétaire du socket, et ils ne créent pas d'entrées dans la file d'événements.

Bien qu'une file d'événements soit conceptuellement illimitée, il semble nécessaire d'imposer une limite pratique à sa longueur. Lorsque la file d'événements d'un socket est pleine, tout événement entrant qui l'accroîtrait devrait être écarté et le NCP émetteur prévenu (au moyen de la commande ERR décrite ci-dessous).

Communications de contrôle du NCP​

Le réseau des NCP coordonne ses activités au moyen de commandes de contrôle transmises entre ses composants individuels. Ces commandes concernent généralement la création et la manipulation des connexions de socket contrôlées par le NCP qui reçoit la commande. Une commande de contrôle est adressée à un NCP particulier en étant envoyée à son HOST sous forme de message sur le numéro de lien 1 (désigné comme lien de contrôle), qui est réservé à cet effet. Le réseau IMP ne distingue pas ces messages des messages de données ordinaires mettant en œuvre la communication par une connexion de socket.

Les commandes de contrôle du NCP suivantes sont définies:

  1. Demande de connexion

    RFC <local socket> <foreign socket> [<link no.>]

    Un NCP adresse cette commande à un NCP étranger pour tenter d'établir une connexion entre un socket local et un socket étranger. Si le socket étranger est ouvert, le NCP étranger place un événement "request" dans la file d'événements du socket afin de le révéler au processus qui le possède. Si le processus étranger accepte, le NCP étranger renvoie un accusé de réception positif sous la forme d'un autre RFC. Il refuse la connexion en émettant la commande CLS (voir ci-dessous). Un RFC est automatiquement refusé sans consulter le processus propriétaire si le socket étranger n'est pas ouvert (inactif ou connecté). Plusieurs RFC vers le même socket sont placés dans sa file d'événements dans l'ordre de réception. Tout RFC mis en file est automatiquement refusé par le NCP dès que le processus propriétaire décide d'accepter une connexion. Le NCP qui contrôle le socket "de réception" de la paire susceptible d'être connectée désigne un numéro de lien sur lequel les messages doivent circuler.

  2. Fermeture d'une connexion

    CLS <local socket> <foreign socket>

    Un NCP émet cette commande de réseau pour déconnecter une connexion existante ou pour accuser négativement réception d'un RFC. Il existe un risque de compétition si un NCP ferme un socket d'émission local, car la commande CLS peut atteindre le NCP étranger avant le dernier message de cette connexion de socket. Cette compétition est évitée en respectant deux règles: (i) une commande CLS pour un socket d'émission local n'est pas transmise tant que le RFNM du dernier message vers le socket étranger n'est pas revenu, et (ii) le NCP étranger traite tous les messages entrants dans l'ordre de réception.

  3. Blocage de la sortie sur une connexion

    BLK <foreign send socket>

    Un processus peut lire des données par un socket de réception plus lentement que les messages n'arrivent, et les tampons du NCP peuvent donc tendre à s'engorger. Le NCP émet cette commande vers un NCP étranger pour bloquer toute transmission ultérieure sur la paire de sockets jusqu'à ce que le processus récepteur rattrape son retard.

  4. Reprise de la sortie sur une connexion bloquée

    RSM <foreign send socket>

    Un NCP émet cette commande pour débloquer une connexion précédemment bloquée.

  5. Interruption du processus rattaché à une connexion

    INT <foreign socket>

    La réception de ce message amène le NCP étranger à interrompre immédiatement le processus étranger rattaché à <foreign socket> s'il est connecté à un socket local. Les données déjà en transit dans le réseau des NCP sur la connexion interrompue seront transmises au socket de destination. Le sens de "interruption" est que le processus interrompra immédiatement son exécution en cours et exécutera une procédure standard. Cette procédure n'est pas définie à ce niveau du protocole.

  6. Signalement d'une commande erronée à un NCP étranger

    ERR <code> <command length> <command in error>

    Cette commande sert à signaler des commandes ou des messages de réseau parasites, ou des conditions de surcharge qui empêchent le traitement de la commande. <code> spécifie le type d'erreur. Si <code> désigne une commande de réseau erronée, <command in error> est cette commande (sans l'en-tête IMP) et <command length> est un entier indiquant sa longueur en bits. Si <code> désigne un message erroné, <command in error> ne contient que le numéro de lien sur lequel le message erroné a été transmis. (Ceci diffère légèrement de la spécification du NWG/RFC 40.)

  7. Commande de test du réseau

    ECO <48 bit code> <echo switch>

    Un NCP peut tester la qualité des communications entre lui et un NCP étranger en lui adressant une commande ECO avec un <48 bit code> arbitraire (de même longueur qu'un identificateur de socket) et <echo switch> 'on'. Un NCP recevant une telle commande ECO devrait immédiatement envoyer au NCP d'origine un ECO d'accusé de réception portant le même <48 bit code> et <echo switch> 'off'. Un NCP n'accuse pas réception d'un ECO avec <echo switch> 'off'. Nous estimons que cette commande sera d'une aide considérable lors du rodage initial de l'ensemble du réseau.

  8. Commande sans opération

    NOP

    Un NCP écarte cette commande à sa réception.

Interface utilisateur du NCP​

Le NCP de chaque HOST possède une interface par laquelle un processus local peut exploiter le réseau, sous le contrôle du NCP. La spécification exacte de cette interface n'est pas un problème de protocole de réseau, car chaque installation aura sa propre interface adaptée à ses exigences particulières. Les exigences de protocole pour l'interface utilisateur d'un NCP sont qu'elle fournisse toutes les fonctions de réseau prévues et aucun privilège illégal. Parmi les exemples de tels privilèges illégaux figurent la possibilité de se faire passer pour un autre processus, d'écouter des communications qui ne lui sont pas destinées, ou d'amener le NCP à émettre des commandes ou des messages de réseau parasites.

Nous esquissons ici une interface fondée sur la proposition de Carr, Crocker et Cerf, qui suffit à utiliser pleinement le réseau. Bien que cet ensemble particulier d'appels soit principalement destiné à illustrer, il indique les types de fonctions nécessaires.

Les appels suivants au NCP sont disponibles:

  1. LISTEN <my 8 bit socket code>

    L'utilisateur ouvre ce socket, ce qui crée pour lui une file d'événements vide. Cet appel LISTEN peut se bloquer en attendant le premier événement "request", ou bien revenir immédiatement.

  2. INIT <my socket code> <foreign socket>

    L'utilisateur tente de connecter <my socket> à <foreign socket>. Le NCP local envoie un RFC au NCP étranger pour demander la création de la connexion. L'accusé de réception renvoyé est soit un RFC (demande acceptée), soit un CLS (demande refusée). Au choix de l'appelant, l'appel INIT se bloque sur l'événement "accept" ou "reject" attendu, ou bien il peut revenir immédiatement sans attendre. Dans ce cas, l'utilisateur doit appeler STATUS (voir ci-dessous) ultérieurement pour déterminer l'action du NCP étranger. Lorsqu'un appel INIT bloqué revient, l'événement "accept" ou "reject" est retiré de la file d'événements.

  3. STATUS <my socket code>

    Cet appel rapporte l'événement non signalé le plus ancien de la file de <my socket>. L'appel STATUS supprime l'événement de la file si ce type d'événement est supprimable par révélation.

  4. ACCEPT <my socket code>

    L'utilisateur accepte la connexion avec le socket étranger dont l'événement "request" est le plus ancien dans la file d'événements de <my socket>. Un RFC d'accusé de réception est envoyé au socket étranger accepté, et l'événement "request" est supprimé de la file d'événements. Si un autre événement "request" existe dans la file, le NCP refuse automatiquement la connexion en émettant une commande CLS et en supprimant l'événement.

  5. REJECT <my socket code>

    L'utilisateur refuse la connexion avec le socket étranger dont l'événement "request" est le plus ancien dans la file d'événements de <my socket>. Le NCP émet une commande CLS et supprime l'événement "request" de la file.

  6. CLOSE <my socket code>

    L'utilisateur demande au NCP de déconnecter toute connexion active vers ce socket et de désactiver le socket. Le NCP émet une commande CLS vers le socket étranger si une connexion a existé. L'état du socket étranger devient également fermé dès que l'événement "close" est révélé au processus étranger.

  7. INTERRUPT <my socket code>

    L'utilisateur demande au NCP d'émettre une commande INT vers le socket étranger connecté à <my socket>.

  8. TRANSMIT <my socket code> <pointer> <nbits>

    L'utilisateur souhaite lire (<my socket> est un socket de réception) ou écrire (<my socket> est un socket d'émission) <nbits> de données depuis ou vers une zone désignée par <pointer>. Un appel d'écriture revient immédiatement après que le NCP a mis les données en file pour envoyer un message sur la connexion. L'appel d'écriture ne se bloque que si la connexion est bloquée ou si le NCP local est trop chargé pour traiter la demande immédiatement. Les données à transmettre sur une connexion sont formatées en un ou plusieurs messages IMP d'une longueur maximale de 8095 bits et transmises au HOST étranger sur le numéro de lien spécifié dans le RFC envoyé par le NCP qui contrôle la connexion de réception. Un événement "close" dans la file d'événements de <my socket> est révélé par l'action de TRANSMIT. Un appel d'écriture révèle l'événement "close" immédiatement. Un appel de lecture le révèle lorsque toutes les données ont été lues.

L'histoire d'une connexion vue par l'utilisateur​

Un exemple illustratif​

Supposons que le processus 'a' sur le HOST A souhaite établir une connexion avec le processus 'b' sur le HOST B. Avant que la communication puisse avoir lieu, deux conditions doivent être remplies:

  1. le processus 'a' doit pouvoir désigner à son NCP un socket de l'espace de sockets de 'b' auquel il veut se connecter.

  2. le processus 'b' doit déjà être en train d'écouter (LISTEN) ce socket.

1. Établissement de la connexion​

  1. le processus 'b' exécute LISTEN sur le socket 'Bb9'.

  2. le processus 'a' exécute INIT de 'Bb9' vers son 'Aa12'. Le NCP de A engendre un RFC spécifiant le numéro de lien = 47, qu'il choisit dans son ensemble de liens disponibles. C'est le lien sur lequel il recevra les messages si la connexion est acceptée (ACCEPT) par le processus 'b'.

  3. le processus 'b' est informé de la demande INIT de A. Il peut refuser (REJECT) la connexion (le NCP B renvoie un CLS) ou l'accepter (ACCEPT) (le NCP B renvoie un RFC).

  4. Si le processus 'b' exécute ACCEPT, le RFC de confirmation établit la connexion, et les messages peuvent désormais circuler.

          HOST  A               |          HOST B
INITIATOR | ACCEPTOR
PROCESS 'a' | PROCESS 'b'
|
|
| a. LISTEN 'socket code 9'
|
|
b. INIT 'socket code 12' 'Bb9' |
RFC 'AA12' 'Bb9' 'link 47' ==========>
|
| c. ACCEPT 'socket code 9'
| RFC 'Bb9' 'Aa12'
|
| d. TRANSMIT 'send buffer' 'len'
| 'socket 9'
<============== IMP message 'link 47' 'send buffer'
|
e. TRANSMIT 'rec buffer' 'length'
'socket 12' ============>
|
| f. CLOSE 'socket code 9'
|
last RFNM ===>
<============== CLS 'Bb9' 'Aa12'
closes socket 'Aa12' |
|

Figure 2 : Établissement et communication sur une connexion de socket

2. Envoi de messages sur une connexion​

  1. Le processus 'b' émet un appel TRANSMIT pour envoyer des données sur la connexion. Le NCP B les formate en un message IMP et l'envoie au NCP A avec le numéro de lien = 47 tel que spécifié par le RFC de A.

  2. Le NCP A reçoit le message brut du NCP B avec le numéro de lien = 47. Le NCP A utilise ce numéro de lien pour décider qui est le destinataire prévu, et range le message dans un tampon destiné au processus destinataire.

  3. Le processus 'a' peut émettre un appel de lecture (TRANSMIT) pour le code de socket 12 à tout moment. L'appel de lecture se bloque s'il n'y a pas de données en attente pour le socket. L'appel de lecture prélève le nombre de bits spécifié transmis sur le code de socket 12, éventuellement à cheval sur une limite de message IMP. Les limites des messages IMP sont invisibles pour l'appel de lecture.

  4. Si le processus 'b' envoie des données sur la connexion plus vite que le processus 'a' ne les prélève, le NCP A peut émettre une commande BLK vers le NCP B lorsque les tampons de A commencent à se remplir. Plus tard, lorsque le processus 'a' a rattrapé son retard, le NCP A peut inviter B à reprendre la transmission au moyen d'une commande RSM.

3. Le processus 'b' ferme la connexion​

  1. Le processus 'b' décide de fermer la connexion et émet l'appel CLOSE vers le NCP B. Pour éviter les problèmes de compétition, B attend le RFNM du message précédent sur cette connexion, puis envoie la commande CLS au NCP A. Lorsque le RFNM du message de commande CLS revient, le NCP B purge le socket 'Bb9' de ses tables, ce qui réalise la fermeture de son côté et désactive 'Bb9'.

  2. En raison du traitement séquentiel au sein du NCP A, il est garanti que le dernier message vers le socket 'Aa12' a été dirigé vers un processus avant que le CLS du NCP B n'arrive. À la réception du CLS venant de B, le NCP A marque le socket 'Aa12' comme "close pending" et place un événement "close" dans la file d'événements de 'Aa12'.

  3. Le processus 'a' peut encore émettre des appels de lecture pour le socket 'Aa12' tant que des données en tampon sont en attente. Lorsque 'a' émet un appel de lecture après que le tampon a été vidé, l'événement "close" est révélé pour informer 'a' de la fermeture, et le socket 'Aa12' est purgé des tables du NCP A.

4. Le processus 'a' ferme la connexion​

  1. Revenons à l'étape 2 et supposons que le processus 'a' veuille fermer la connexion de son côté. Il n'y a pas de problème de compétition, car nous supposons qu'une fois que 'a' a émis un appel CLOSE, il ne souhaite plus lire de messages sur ce socket.

  2. Supposons que le processus 'a' émette un appel CLOSE sur le socket 'Aa12'. Le NCP A envoie immédiatement une commande CLS au NCP B et marque le socket 'Aa12' comme "close pending". Toute donnée mise en tampon pour lecture sur 'Aa12' est écartée. Pour permettre aux messages restants déjà en transit depuis le processus 'b' de filtrer à travers le réseau IMP jusqu'au NCP A et d'être écartés sans commentaires d'erreur, le NCP A conserve 'Aa12' dans ses tables pendant un laps de temps approprié après avoir reçu le RFNM de la commande CLS. Pendant ce laps de temps, le NCP A écarte tous les messages reçus sur la connexion en cours de fermeture. Après avoir laissé un délai raisonnable à ces messages morts pour arriver, le NCP A purge 'Aa12' de ses tables, ce qui ferme effectivement la connexion et désactive 'Aa12'. Les messages ultérieurs vers le socket 'Aa12' amènent le NCP A à envoyer un ERR "erroneous command" au NCP d'origine.

  3. Lorsque le NCP B reçoit la commande CLS, le socket 'Bb9' est marqué comme "close pending", et l'événement CLS est placé dans la file d'événements de 'Bb9'. La prochaine fois que le processus 'b' souhaite écrire sur ce socket, l'événement CLS est révélé pour l'informer de la fermeture, et le socket 'Bb9' est retiré des tables du NCP B.