26
RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 1/26 RSX102 : INTRODUCTION AUX SYSTEMES DISTRIBUES APPEL DE PROCEDURES DISTANTES : RPC 1. Remote Procedure Call : les motivations Rappel 1 : Application locale "classique" : appel "local" de procédures/fonctions définies "localement", c'est-à-dire sur le même système que l'application. Exemple en C : ... int resultat; resultat = calculPuissance(2, 32); printf("2 à la puissance 32 = %d\n", resultat); ... Ici calculPuissance est une fonction qui est appelée localement. Son code est intégré dans l'exécutable compilé ou chargé dynamiquement au lancement (librairie dynamique), et s'exécute sur le même système que l'application appelante. Les paramètres d'entrée et les résultats sont transmis par la mémoire locale, partagée par l'application appelante et les procédures appelées. Rappel 2 : sockets TCP / UDP : Communication par envoi et réception de bloc de données (par "messages") sur une liaison UDP ou une connexion TCP, définie entre 2 sockets (tuples @IP:n°port) Objectif : Application "distribuée" en mode "client/serveur" : - Un client veut calculer 2 à la puissance 32 mais n'a pas de fonction définie ou pas de ressources (temps CPU) pour cela - Un serveur est capable de faire ce calcul (il a le code compilé et les ressources de calcul nécessaires) - Le client construit une requête sous la forme d'un tableau d'octets structuré ("élever X à la puissance Y", X=2, Y=32) envoyé en tant que "message" au serveur, via un socket TCP ou UDP - Le serveur reçoit le message sur un socket TCP ou UDP et décode la requête : la fonction demandée (calculer une puissance), et ses paramètres (2 et 32) - Il exécute le service requis et renvoie via son socket un message, sous forme de tableau d'octets structuré représentant le résultat ("OK", "4294967296"), au client De manière "abstraite", on peut dire que le client a appelé un "service de calcul" hébergé sur le serveur, via une mécanique dédiée de communication utilisant les sockets : un appel de procédure distante. Mais il faut implémenter les communications "bas niveau" (sockets), en plus du code de traitement des données. Motivations des RPC (pour Remote Procedure Call) : pouvoir appeler directement ce "service"sur le serveur distant presque aussi facilement que si ce service était local (sous forme par exemple d'un simple appel de fonction) : ... int resultat; resultat = calculPuissance_sur_serveur_distant(2, 32); printf("2 à la puissance 32 = %d\n", resultat); ... 2. Remote Procedure Call : les principes RPC est une technique client-serveur, fonctionnant selon le mode requêtes/réponses, qui permet de développer simplement des applications client-serveur portant sur tous types de services à accéder à distance (serveur de fichiers, serveur d’authentification, serveur d’accès à des données, serveur de calcul…) RPC permet de simplifier la programmation d’applications distribuées/réparties, en évitant d'avoir à se préoccuper de la localisation de la procédure, des détails de la communication bas niveau (programmation sockets), et du traitement de défaillances ou du parallélisme. a) Principes On différencie le côté appelant (client) du côté appelé (serveur) : Le côté Appelé (serveur) offre la possibilité à des éléments distants d'appeler une ou plusieurs fonctions chez lui, qu'il aura au préalable "publiées" Le côté Appelant (client) appelle localement la fonction choisie sur un "élément spécial" qui relayera la demande d'appel de fonction côté serveur Côté serveur, un autre "élément spécial" reçoit la demande, appelle la fonction choisie et renvoie le résultat côté client Ces "éléments spéciaux" sont nommés talons (ou souches) (stubs) b) L’approche client-serveur "classique" (rappels) : Mode de fonctionnement "classique" d’une application informatique "moderne" : dissymétrique (il existe des rôles différents : clients et serveurs), en univers réparti (les entités s’exécutent sur des sites physiques différents). Le mode d’interaction est de style requête/réponse (pas de style "partage de données") : un client transmet une requête (typiquement par message de transport) à un serveur qui exécute un traitement et retourne ses résultats au client (typiquement par message de transport)

1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

Embed Size (px)

Citation preview

Page 1: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 1/26

RSX102 : INTRODUCTION AUX SYSTEMES DISTRIBUES APPEL DE PROCEDURES DISTANTES : RPC

1. Remote Procedure Call : les motivations Rappel 1 : Application locale "classique" : appel "local" de procédures/fonctions définies "localement", c'est-à-dire sur

le même système que l'application. Exemple en C : ...

int resultat;

resultat = calculPuissance(2, 32);

printf("2 à la puissance 32 = %d\n", resultat);

...

Ici calculPuissance est une fonction qui est appelée localement. Son code est intégré dans l'exécutable compilé ou

chargé dynamiquement au lancement (librairie dynamique), et s'exécute sur le même système que l'application appelante. Les paramètres d'entrée et les résultats sont transmis par la mémoire locale, partagée par l'application appelante et les procédures appelées.

Rappel 2 : sockets TCP / UDP : Communication par envoi et réception de bloc de données (par "messages") sur une liaison UDP ou une connexion TCP, définie entre 2 sockets (tuples @IP:n°port)

Objectif : Application "distribuée" en mode "client/serveur" :

- Un client veut calculer 2 à la puissance 32 mais n'a pas de fonction définie ou pas de ressources (temps CPU) pour cela - Un serveur est capable de faire ce calcul (il a le code compilé et les ressources de calcul nécessaires) - Le client construit une requête sous la forme d'un tableau d'octets structuré ("élever X à la puissance Y", X=2, Y=32) envoyé en tant que "message" au serveur, via un socket TCP ou UDP - Le serveur reçoit le message sur un socket TCP ou UDP et décode la requête : la fonction demandée (calculer une puissance), et ses paramètres (2 et 32) - Il exécute le service requis et renvoie via son socket un message, sous forme de tableau d'octets structuré représentant le résultat ("OK", "4294967296"), au client

De manière "abstraite", on peut dire que le client a appelé un "service de calcul" hébergé sur le serveur, via une mécanique dédiée de communication utilisant les sockets : un appel de procédure distante. Mais il faut implémenter les communications "bas niveau" (sockets), en plus du code de traitement des données.

Motivations des RPC (pour Remote Procedure Call) : pouvoir appeler directement ce "service"sur le serveur distant presque aussi facilement que si ce service était local (sous forme par exemple d'un simple appel de fonction) : ...

int resultat;

resultat = calculPuissance_sur_serveur_distant(2, 32);

printf("2 à la puissance 32 = %d\n", resultat);

...

2. Remote Procedure Call : les principes RPC est une technique client-serveur, fonctionnant selon le mode requêtes/réponses, qui permet de développer

simplement des applications client-serveur portant sur tous types de services à accéder à distance (serveur de fichiers, serveur d’authentification, serveur d’accès à des données, serveur de calcul…)

RPC permet de simplifier la programmation d’applications distribuées/réparties, en évitant d'avoir à se préoccuper de la localisation de la procédure, des détails de la communication bas niveau (programmation sockets), et du traitement de défaillances ou du parallélisme.

a) Principes

On différencie le côté appelant (client) du côté appelé (serveur) :

Le côté Appelé (serveur) offre la possibilité à des éléments distants d'appeler une ou plusieurs fonctions chez lui, qu'il aura au préalable "publiées"

Le côté Appelant (client) appelle localement la fonction choisie sur un "élément spécial" qui relayera la demande d'appel de fonction côté serveur

Côté serveur, un autre "élément spécial" reçoit la demande, appelle la fonction choisie et renvoie le résultat côté client Ces "éléments spéciaux" sont nommés talons (ou souches) (stubs)

b) L’approche client-serveur "classique" (rappels) :

Mode de fonctionnement "classique" d’une application informatique "moderne" :

dissymétrique (il existe des rôles différents : clients et serveurs),

en univers réparti (les entités s’exécutent sur des sites physiques différents).

Le mode d’interaction est de style requête/réponse (pas de style "partage de données") :

un client transmet une requête (typiquement par message de transport)…

…à un serveur qui exécute un traitement et retourne ses résultats au client (typiquement par message de transport)

Page 2: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26

c) L’approche client-serveur en appel de procédure distante :

Mode de réalisation d’une interaction client/serveur pour laquelle

l'opération à réaliser (la requête) est présentée sous la forme d'une procédure paramétrable…

… que le client peut faire exécuter à distance par un serveur. Avantages : Utiliser une structure familière en programmation : l’appel de procédure. S’affranchir du côté basique des communications en mode message. Disposer de mécanismes modernes de programmation :

Vision modulaire des applications réparties (en approche objets répartis ou par "composants sur étagères"). Délégation en univers réparti.

Deux niveaux de services sont envisageables :

Service basique (API d’appel de procédure distante "traditionnelle") : Côté client : on invoque une procédure distante en précisant son "adresse" (id_serveur) :

invoque (id_client, id_serveur, nom_procedure, paramètres);

Côté serveur : on code la fonction qui reçoit l'appel, réalise le traitement et répond au client : traite (id_client, id_serveur, nom_procedure, paramètres);

Service intégré approche objet : Côté client : on invoque une méthode d'un objet_serveur distant dont on a une référence

ref_objet_serveur.nom_procedure (paramètres);

Côté serveur : on déploie l’objet objet_serveur qui implémente la procédure method nom_procedure (paramètres);

On distinguera en fait :

Approches à RPC traditionnelles SUN ONC/RPC : Open Network Computing / Remote Procedure Call OSF DCE : Open Software Foundation - Distributed Computing Environment Systèmes de gestion de bases de données: procédures stockées.

Approches à RPC intégrées dans les systèmes d’objets répartis OMG CORBA : Object Management Group - Common Object Request Broker Architecture SUN Java RMI : Remote Method Invocation Microsoft - DCOM : Distributed Component Object Model

Approches à RPC intégrées dans les systèmes de composants (intergiciels à composants) SUN J2EE EJB : Java 2 (Platform) Enterprise Edition - Enterprise Java Beans OMG CCM : Object Management Group - Corba Component Model WS-SOAP : Web Services - Simple Object Access Protocol

La place de RPC dans le modèle OSI (exemple de mise en œuvre du service NFS)

4

Page 3: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 3/26

d) Notion de souches/talons/stubs

Mode de réalisation par "interception" (wrapping) : Une procédure interceptrice (wrapper) intercepte l’appel d’un client vers un serveur et en modifie le traitement Décomposition en intercepteur côté client et intercepteur côté serveur.

Souches : composants logiciels réalisant la transformation d’appel local en appel distant et réciproquement.

Client et serveur utilisent deux espaces d'adressage physique distincts, entre lesquels les données de l'appel doivent être transportées. Une adaptation au transport des paramètres utilisés dans un appel de fonction distante doit donc être réalisée (on parle d'emballage et réciproquement de désemballage)

Client et serveur peuvent aussi utiliser différentes représentations (codage) des données (par exemple big-endian versus little-endian pour les entiers) ; une conversion / un transcodage des données doit donc être réalisées

Les souches (talons, stubs) réalisent des deux côtés cette fonction de conversion/adaptation des paramètres, qui fait qu'un appel d'une fonction distante apparait de part et d'autre comme un appel de procédure locale avec passage de paramètres. Des librairies "souches" doivent pour cela être installées sur le client et sur le serveur.

La souche côté client est responsable de la conversion/adaptation-emballage (marshalling) des paramètres transmis lors d'un appel de fonction et de la conversion/adaptation inverse-désemballage (unmarshalling) des résultats transmis à partir du serveur après l'exécution de la fonction. Le stub client est donc le représentant local (pour le client/appelant) de la procédure ou de l'objet distant. On parle aussi de "proxy" (intermédiaire). Le stub client peut proposer des fonctions supplémentaires : mises en cache, balance de charge, collecte de statistiques…

La souche côté serveur est responsable de conversion/adaptation-désemballage (unmarshalling) des paramètres transmis par le client et de la conversion/adaptation-emballage (marshalling) des résultats après l'exécution de la fonction en vue de leur transmission. Elle agit donc comme le représentant de la procédure/de l'objet serveur pour les clients distants. Le stub serveur, appelé aussi skeleton, est l'intermédiaire (proxy) par lequel l'objet serveur interagit avec le monde extérieur. Il peut proposer des fonctions annexes, comme la prise en compte de la persistance des données.

Les stubs clients et serveurs doivent donc implémenter au minimum toutes les tâches essentielles de marshalling/unmarshalling et être capables de réaliser l'émission ou la réception des messages, en utilisant les fonctions bas-niveau de la librairie RPC. On trouve heureusement des outils de génération automatique des souches à partir du profil d’appel de la procédure distante.

Page 4: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 4/26

Avantages Volume de code ou de données serveur quelconque. Applicable en univers hétérogène moyennant des conversions. Partage d’accès sur le site serveur analogue au transactionnel.

Inconvénients Pas d’usage des pointeurs dans les paramètres. Échange de données complexes/de grande taille délicat et peu performant Peu efficace pour de très nombreux appels. Problème de tolérance aux pannes réseaux

e) Problèmes à traiter

Comment le client connait-il l’adresse du serveur ? Comment client et serveur s'authentifient-ils ? Comment emballer (marshalling) et déballer (unmarshalling) efficacement les paramètres d’appel et de réponse

vis-à-vis des entités hétérogènes ? (structures complexes, représentation de données, messages de grande taille…) Comment gérer simultanément plusieurs appels ? Comment traiter des pannes ? (mode de détection, procédures de reprise…) Comment générer automatiquement une souche ?

3. RPC : gestion des appels multiples. Parallélisme

a) Parallélisme côté client :

Appel de procédure distante en mode synchrone L'exécution du client est suspendue tant que la réponse du serveur n'est pas revenue ou qu'une condition

d'exception n'a pas entraîné un traitement spécifique. Avantage: le flot de contrôle est le même que dans l'appel en mode centralisé

Inconvénient: le client reste inactif.

Appel de procédure distante en mode asynchrone

Le client poursuit son exécution immédiatement après l'émission du message porteur de l'appel. La procédure distante s'exécute en parallèle avec la poursuite du client. Le client doit récupérer les résultats quand il en a besoin (primitive spéciale).

Cas particulier : Invocation asynchrone sans réponse (autre terminologie : "peut-être", "oneway", "maybe")

Invocation asynchrone utilisé pour déclencher une procédure qui ne retourne pas de résultats. Pour obtenir un dialogue il faut prévoir d’autres procédures en sens inverse.

Avantage: Utilisation d'un mode appel de procédure pour des communications en mode message. Inconvénient : Uniquement possible en l'absence de retour de résultat, pas d'informations sur la terminaison du

travail demandé. Exemple : le client incrémente un compteur sur le serveur, en appelant une procédure du genre Add(n) ou Inc()

CLIENT SERVEUR

Appel

Retour

Debut

Fin

proc(...) procedure proc()

client

bloqué

serveur

actif

CLIENT SERVEUR

Appel

Retour

Debut

Fin

proc(...)

procedure proc

serveur

actif

client

actif

proc(...)

Récupération

des résultats

Page 5: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 5/26

b) Parallélisme côté serveur :

Exécution séquentielle des appels Les requêtes d’exécution sont traitées l’une après l’autre par le serveur : exclusion mutuelle entre les traitements. Si la couche transport assure la livraison en séquence et que l’on gère une file d’attente "premier arrivé premier

servi", on a un traitement ordonné des suites d’appels. Exemple RPC SUN : traitement séquentiel des requêtes mais utilisation de UDP => requêtes non ordonnées

(mais mode synchrone : le client attend la fin du traitement). Les autres RPC ont un mode séquentiel (ex CORBA)

Exécution parallèle des appels

Dans ce mode le serveur créé un processus ou une activité (un processus léger ou “thread”) par appel (gestion possible de pool de processus ou d’activités).

Les appels sont exécutés concurremment. Si les procédures manipulent des données globales rémanentes sur le site serveur, le contrôle de concurrence

doit être géré. Exemple : Corba : Notion d’adaptateur d’objets.

4. Gestion des données applicatives

Données locales à la procédure : pas de problème. Données applicatives partagées : variables d’instance, fichiers, bases de données : problème de persistance.

Sans données partagées persistantes Situation idéale du cas où l’appel de procédure s'exécute en fonction uniquement des paramètres d’entrée et en

produisant uniquement des paramètres résultats. Exemple: calcul d’une fonction scientifique Il n’y a pas de modification de données rémanentes sur le site serveur. Pas de problème pour la tolérance aux pannes et pour le contrôle de concurrence Un exemple type : EJB session ‘Stateless’

Avec données applicatives partagées persistantes Les exécutions successives manipulent des données persistantes sur le site serveur. Une exécution modifie le contexte sur le site distant (un serveur de fichier réparti, un serveur de bases de

données). => Problème de contrôle de concurrence. => Problème des pannes en cours d'exécution.

Solution: le couplage d'une gestion transactionnelle avec une approche RPC (ou système d'objets répartis). Exemple type : EJB Session stateful, EJB Entité

5. Gestion des données protocolaires : mode avec ou sans état Autre aspect de la rémanence des données sur le serveur. La terminologie "avec ou sans état" porte sur l'existence ou non d’un descriptif pour chaque relation client serveur au

niveau du serveur. Notion d’état : un ensemble de données rémanentes au niveau du protocole pour chaque relation client serveur. Permettrait de traiter les requêtes dans l’ordre d’émission et/ou en fonction des caractéristiques de la relation client serveur (qualité de service). Il s'agit en fait d'une notion identique à celle du descriptif de connexion chez le serveur dans une communication en mode connecté.

Mode sans état Les appels successifs d’une même procédure s'exécutent sans liens entre eux. Il peut y avoir modification de données globales rémanentes sur le site serveur mais chaque opération du point de

vue du protocole s’effectue sans référence au passé (indépendamment de toutes celles qui ont précédé). Ex: NFS (Network File System) de SUN : système de fichier réparti basé sur RPC sans état. Lecture/Écriture du

nième article d’un fichier dont toutes les caractéristiques utiles (nom, droit d’accès) sont passées au moment de l’appel. Ex non basé RPC : HTTP, protocole d’exécution de méthodes distantes (GET, POST…) sans état.

Mode avec état Les appels successifs s'exécutent en fonction d’un état de la relation client serveur laissé par les appels antérieurs. Exemple d’utilisation : la gestion de l'ordre de traitement des requêtes, la gestion de caractéristiques du client. Exemple système de fichier en RPC : Lecture d’article de fichier sur le pointeur courant.

Page 6: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 6/26

6. Transmission des arguments : syntaxe de transfert et syntaxe

abstraite

Transmission par valeur : rappels Le seul mode de transmission des données dans les messages en réseau. Si le site client et le site serveur utilisent des formats de données différents : problème syntaxique => une

conversion est nécessaire. La solution : présentation des données au moyen d’une syntaxe de transfert => une représentation lexicale des

données simples et une convention d’alignement des données commune au client et au serveur. Elle décrit donc la façon dont les données sont codées dans les messages qui circulent.

Exemple dans le domaine des communications en mode message : norme de représentation lexicale des données simples : la syntaxe de transfert BER (Basic Encoding Rules).

Mais une syntaxe de transfert (plutôt du style "langage machine") est très peu pratique pour définir, manipuler et comprendre les structures de données nécessaires à l'invocation d'un service Définir une syntaxe abstraite de données pivot : analogue des langages de description de données des langages évolués, facile à générer pour un développeur d’application (exemple en mode message : ASN1 Abstract Syntax Notation 1).

A partir de la syntaxe abstraite: codage/décodage de la syntaxe de transfert (technique de compilation, notion de compilateur de protocole).

Exemple en mode message : ASN.1/BER utilisé par SNMP ou LDAP

Transmission par valeur dans l’appel de procédure distante : les IDL Insuffisance des normes de syntaxe abstraite et de de transfert en mode message asynchrone (ASN1/BER). Définition de nouveaux langages de syntaxe abstraite adaptés aux appels de procédure distante : IDL (Interface

Definition Language) En appel de procédure distante : génération automatique du code des souches à partir de la syntaxe abstraite Les souches fabriquent la syntaxe de transfert en réalisant l’alignement des paramètres dans les messages

(marshalling) Pour chaque IDL en général, il y a redéfinition d’une syntaxe de transfert.

Motivation pour une classe de langages de syntaxes abstraites : IDL

Être indépendant des langages évolués utilisant le RPC. Permettre l’invocation distante avec tout langage évolué

Définition d’un langage pivot de description de données ayant des fonctionnalités assez riches pour les langages les plus récents.

Définition d’un langage pivot qui permette de corriger les ambiguïtés et les insuffisances des langages anciens (comme le C).

Notion de correspondance entre les types retenus dans l'IDL et les types des différents langages existants ("mappings").

Permettre aux utilisateurs de définir un identifiant unique pour chaque interface afin de l'utiliser. Supporter les caractéristiques particulières des langages objets Exemple : permettre de définir des relations d'héritage entre définitions d'interfaces. Éventuellement structurer les interfaces en modules.

Un exemple en IDL Corba :

module StockObjects {

struct Quote {

string symbol;

long at_time;

double price;

long volume;};

exception Unknown{};

interface Stock {

Quote get_quote() raises(Unknown); // lit la cotation.

void set_quote(in Quote stock_quote); // écrit la cotation

};

interface StockFactory {

Stock create_stock(

in string symbol,

in string description );

};

};

Page 7: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 7/26

La génération des souches à partir de l'IDL

Quelques exemples d’IDL et de format de présentation en RPC : SUN ONC/RPC : XDR eXternal Data Representation OSF DCE : IDL DCE - Format NDR Network Data Representation OMG CORBA : IDL Corba - Format CDR Common Data Representation, Protocole IIOP SUN Java RMI : Langage Java - Protocole JRMP Java Remote Method Protocol Microsoft - DCOM : MIDL Microsoft IDL - DCOM Protocole ORPC Object RPC Format NDR WS-SOAP : Web Services Definition Language - XML

Autres modes de transmission : le passage par adresse (pointeurs)

Le passage par adresse (par pointeur) utilise une adresse mémoire centrale du site de l'appelant qui n'a aucun sens sur l'appelé (sauf cas particulier).

Indispensable de traiter ce problème. Interdiction totale des pointeurs

Dans la plupart des RPC, pas de passage des paramètres par adresse ou de structures de données contenant des pointeurs.

Introduit une différence dans le développement de procédures locales et celles destinées à un usage distant. Passage par nom (références ou pointeurs d'objets)

En approche "objets répartis" utilisation des références d'objets. Le passage d'un argument se fait en transmettant une référence sur l'objet en univers réparti (en CORBA IOR). L'accès s'effectue au moyen des méthodes implémentées par l'objet. Par exemple accès à un attribut en lecture

ou en écriture. Avantages/ inconvénients

Mécanisme universel. Coûteux pour des accès fréquents.

7. Désignation Comment sont structurés les noms et références permettant de désigner les services distants :

Nom symbolique : utilisable au moyen d’un serveur d’annuaire. Référence : une structure de données permettant de réaliser l’invocation.

Notion de référence : selon l’implantation considérée

Désignation du protocole permettant l’accès distant (TCP) Désignation de l’hôte ou se trouve le serveur (adresse IP). Désignation du point d’accès de service transport (numéro de port) Désignation locale de l’objet ou se trouve la procédure. Désignation de la procédure.

Page 8: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 8/26

8. Problématiques de liaison Comment localiser une procédure distante ?

Au moyen d’un service de gestion de noms (serveur d’annuaire) A quel moment effectuer la liaison ?

Le plus tôt possible (à la compilation) -> moins souple, plus performant Vision très statique, le serveur ne doit pas bouger.

Le plus tard plus possible (à l'exécution) -> plus souple, moins performant Au chargement du client Au moment de la première invocation Localiser la procédure (référence), mettre en cache Relocaliser à chaque fois qu’il est nécessaire

Le serveur est-il disponible ? Solution : fabrique/ferme de serveurs

Est-ce que la version de l’interface utilisée est consistante ? Solution - gestion d’identificateurs uniques d’interface (comportant des numéros de version).

Existence de serveurs multiples Gestion d’une technique d’équilibrage de charge. Gestion de redondances

9. Tolérance aux pannes En appel local

L'appelant et l'appelé s'exécutent sur la même machine : même exécutant => mêmes performances et modes de pannes.

L'appel et le retour de procédure sont des mécanismes internes considérés comme fiables (sauf exigences spéciales)

Les erreurs chez l'appelé => des exceptions chez l'appelant.

Page 9: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 9/26

En appel distant Appelant et appelé peuvent tomber en panne indépendamment. Le message d'appel ou celui de retour peuvent être perdus (sauf si l'on emploie un protocole de transport fiable). Le temps de réponse peut-être très long en raison de surcharges diverses (réseau, site appelé).

Les différents modes de pannes : les pannes franches du serveur 1 - Attente indéfinie par le client d'une réponse qui ne viendra jamais => abandon du programme sur temps limite 2 - Utilisation d'un délai de garde par le site appelant

=> Signalement de l'absence de réponse au client qui décide de la stratégie de reprise. => Reprise arrière automatique (si possible)

soit tentative d'exécution sur un autre site

soit reprise sur le même site (si relance) => Plusieurs exécutions successives de la même procédure pour une seule demande.

Les différents modes de pannes : les pannes franches du client Le serveur est dit orphelin (“orphan”). Réalisation de travaux inutiles, utilisation de ressources qui ne sont plus accessibles pour des tâches utiles. Confusion après relance du client entre les nouvelles réponses attendues et les réponses à d'anciennes

requêtes. => Nécessité de détruire les tâches serveurs orphelines et de distinguer les requêtes utiles des vieilles requêtes.

Problème des pannes franches L’état du client ou du serveur peuvent devenir inconsistants => Analyse des modifications de l’état du client et du serveur.

Les différents modes de pannes : les pertes de messages Cas facile: pertes traitées par une couche transport fiable. Cas difficile: il existe des RPC implantés pour des raisons d'efficacité au-dessus d’une communication non fiable

(couche réseau sans connexion type UDP) => Mécanisme de traitement des pertes de message à prévoir dans la conception du RPC. Exemple :

La réponse acquitte la demande

La prochaine requête acquitte la réponse. Pour tolérer les pertes de messages on peut lancer plusieurs exécutions de la même requête

Reprise arrière complète Les exécutions successives du serveur peuvent laisser l’état du serveur indéterminé (panne en cours

d'exécution). Le client peut être dans un état incertain (panne au moment de la modification en retour des variables

persistantes du client). Solution maximale => Pour chaque tentative l’état du client et celui du serveur doivent être restaurés aux valeurs

avant le premier appel

Reprise arrière du serveur seul Hypothèse: les réexécutions du serveur sont toujours complètes ou équivalentes à une exécution complète

correcte. Par exemple retransmission d’appel sur délai de garde pour un mode d'exécution séquentiel des appels distants Il n'y a pas de perte de cohérence de l'état du serveur (pas d'exécutions partielles interrompues avec des

variables globales rémanentes laissées incohérentes).

Fonctionnement de la reprise Pas de sauvegarde de l'état client : on peut s'en passer, le client réalise seulement l'écriture des paramètres

résultats. Pas de sauvegarde de l'état du serveur : au moment d'une tentative n l'état du serveur est donc celui qui résulte

de la dernière tentative n-1.

Condition à respecter Les états "après" sont conservés si des exécutions répétées du code du serveur sur les données résultant de

l'exécution précédente produisent des résultats identiques : F est idempotente c'est-à-dire F (F (x) )=F (x). Exemples relatifs à l'idempotence :

F est idempotente si l'exécution de la procédure ne modifie pas l’état du serveur (Ex. : lecture kième

article d’un fichier)

F est idempotente si l’état du serveur est modifié seulement à la première exécution de F (Ex. : écriture du kième

article).

L’écriture en fin de fichier est une opération non idempotente.

L'incrémentation d'une variable est non idempotente.

Résumé des techniques de reprise arrière A) Reprise arrière complète : mise œuvre de techniques de type "gestion transactionnelle". B) Reprise arrière du serveur seul : uniquement valable si le serveur est une fonction idempotente sur son état. C) Tentatives de reprise hors des deux cas précédents : interdiction totale.

Page 10: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 10/26

Sémantique du RPC du point de vue des pannes serveurs :

Sémantique : "Exactement une fois" Définition théorique: Une seule exécution est effectuée et celle-ci réussit toujours. Impossible au sens strict dès lors qu’une hypothèse de panne est formulée. Comportement souhaité : le plus voisin possible de celui de l'appel de procédure en mode centralisé.

Une suite de n tentatives est effectuée

Avec sauvegarde état du client et du serveur avant chaque tentative.

Pour une procédure déterministe

Sémantique : "Au plus une fois" Cas d'une fonction quelconque (non idempotente): on ne doit pas l'exécuter deux fois. Solution très répandue : garantir qu’on n’exécute pas deux fois une même procédure. Identification des requêtes + exécution effectuée une seule fois.

Si tout va bien le résultat est retourné à l’utilisateur.

La requête ne sera plus exécutée (modulo le délai de garde de l'historique).

Si un problème est détecté Il est signalé à l’utilisateur pour qu' ’il puisse éventuellement statuer. Aucune tentative de reprise n’est effectuée. Elle est laissée entièrement à la charge du client.

Sémantique : "Au moins une fois" On se place dans le cas où chaque exécution du serveur est réalisée sans sauvegarde de l'état du serveur. L'exécution est lancée plusieurs fois si nécessaire (dans une certaine limite) pour obtenir une réponse correcte. => La procédure doit être idempotente. Variante: La "dernière de toutes"

Sémantique du RPC du point de vue des pannes client

Problème des serveurs en cas de panne du client Abandonner le plus vite possible l’exécution en cours. En laissant un état cohérent sur le site serveur.

Extermination Une approche de journalisation : la souche client note en mémoire stable tous les appels en cours. Lorsqu'un site client est relancé, il doit examiner l'historique des appels en cours non terminés et demande la

destruction de tous les serveurs orphelins encore actifs. Réincarnation

Une technique de numéros de séquence, en fait un numéro d'époque correspondant aux périodes d'activité successives du client.

Il doit être enregistré en mémoire stable et doit marquer toutes les requêtes. Lorsqu'un client est relancé il change d'époque et diffuse sa nouvelle époque à ses serveurs qui détruisent les

appels anciens. Expiration

Une technique de délais de garde : L'exécution d'un serveur est toujours associée à une surveillance périodique du client : le serveur arme des délais de garde.

Si le quantum s'achève, le serveur demande à son client s'il est encore opérationnel :

si le client répond : armement d'un nouveau délai et poursuite.

si le client est en panne : abandon cohérent d'exécution. Remarque : Cette technique permet à la fois la surveillance du client par le serveur et celle du serveur par le

client.

10. RPC : Conclusion

Les avantages de l’appel de procédure distante : Une structure de contrôle bien connue, l’appel de procédure (mode de communication support naturel de l’approche

client-serveur).

De plus haut niveau que les communications en mode message.

Qui s’intègre à l’univers réparti des concepts modernes de génie logiciel: approche objets, approches composants : Modularité, encapsulation, réutilisation par délégation.

Mais une application en appel distant est une application répartie qui risque de présenter à un moment ou à un autre pratiquement toutes les difficultés systèmes/réseaux :

de conception. de désignation et de liaison. de présentation des données échangées. de synchronisation.

de contrôle de concurrence. de tolérance aux pannes et de sécurité. de performances. de sécurité.

Page 11: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 11/26

Table des matières

1. Remote Procedure Call : les motivations ....................................................................................... 1

2. Remote Procedure Call : les principes ............................................................................................ 1

a) Principes ...................................................................................................................................................................... 1

b) L’approche client-serveur "classique" (rappels) : ....................................................................................................... 1

c) L’approche client-serveur en appel de procédure distante : ..................................................................................... 2

d) Notion de souches/talons/stubs ................................................................................................................................. 3

e) Problèmes à traiter ..................................................................................................................................................... 4

3. RPC : gestion des appels multiples. Parallélisme.................................................................. 4

a) Parallélisme côté client : ............................................................................................................................................. 4

b) Parallélisme côté serveur : .......................................................................................................................................... 5

4. Gestion des données applicatives ........................................................................................................ 5

5. Gestion des données protocolaires : mode avec ou sans état .......................................... 5

6. Transmission des arguments : syntaxe de transfert et syntaxe abstraite ............. 6

7. Désignation .......................................................................................................................................................... 7

8. Problématiques de liaison......................................................................................................................... 8

9. Tolérance aux pannes .................................................................................................................................... 8

10. RPC : Conclusion ............................................................................................................................................ 10

Page 12: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 12/26

TP RSX102 : ONC RPC

Rappel : Fonctionnement général d'un appel de fonction

Communication via sockets TCP ou UDP pour faire transiter les demandes d'appels de fonction et le résultat des appels Toutes les données transitant via les sockets sont codées via XDR (eXternal data Representation - RFC 4056)

RPCGEN

RPC Generator : Utilitaire permettant de générer automatiquement le code des talons et des fonctions XDR associées aux données utilisées par les fonctions, à partir des spécifications rédigés dans un IDL Principe d'utilisation :

On décrit dans un fichier "filtre" (d'extension .x) les structures de données propres aux fonctions et les fonctions appelables à distance. Syntaxe RPL

RPCGEN génère ensuite un ensemble de fichiers utilisables pour le codage des programmes client et serveur Exemple

On code (en C) un ensemble de fonctions de traitement de formes géométriques appelables à distance par des clients :

struct rectangle creer_rectangle(int x1, y1, x2, y2);

int surface_rectangle(struct rectangle rect);

booleen inclus(struct rectangle r, struct point p);

Avec les structures et types suivants (on supposera que pour un rectangle, le point p1 est le coin inférieur gauche et p2 le supérieur droit) :

struct point {

int x, y;

};

struct rectangle {

struct point p1, p2;

};

typedef int booleen;

Code des 3 fonctions :

struct rectangle creer_rectangle(int x1, int x2,int y1, int y2) {

struct rectangle rect;

rect.p1.x = x1; rect.p1.y = y1;

rect.p2.x = x2; rect.p2.y = y2;

return rect;

}

int surface_rectangle(struct rectangle rect) {

return abs((rect.p2.x - rect.p1.x) * (rect.p2.y - rect.p1.y));

}

booleen inclus(struct rectangle rect, struct point p){

return ( (p.x >= rect.p1.x) && (p.x <= rect.p2.x) && (p.y >= rect.p1.y) && (p.y <= rect.p2.y));

}

Règles d'écriture du fichier .x

Fichier décrivant les fonctions et données

Pour les données : décrit les structures presque comme en C

Pour les fonctions : règle fondamentale : une fonction ne prend qu'UN seul paramètre On doit donc définir une structure de données dédiée à la fonction si on veut passer plusieurs valeurs en paramètre. En fait un RPC nouvelle génération existe qui lève cette limitation.

La syntaxe utilisée est le RPC Language (RPL), qui est un IDL proche du C conçu spécifiquement pour le RPC

"historique" (ONC RPC).

Page 13: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 13/26

Définition d'un « programme » RPC :

Programme = ensemble de fonctions/services

Chaque programme possède un nom avec un numéro associé

Un programme peut exister en plusieurs versions : chaque version est identifiée par un nom et un numéro associé.

Chaque version définit une liste de fonctions,

Chaque fonction est identifiée par un numéro unique

On aura donc les éléments de syntaxe suivants :

program program-ident {version-list} = value

version version-ident {procedure-list} = value

type-ident procedure-ident (type-ident) = value

RPCL définit également des constantes entières typées, par exp. : const const-ident = integer

mais aussi des types (avec typedef), des structures (avec struct), des énumérations (avec enum) et des unions (avec

union).

Exemple d'un programme PING_PROG existant en 2 versions :

program PING_PROG {

version PING_VERS_ORIG {

void

PINGPROC_NULL(void) = 0;

} = 1;

version PING_VERS_PINGBACK {

void

PINGPROC_NULL(void) = 0;

int

PINGPROC_PINGBACK(void) = 1;

} = 2;

} = 200000;

const PING_VERS = 2; /* latest version */

Exemple : fichier geometrie.x (récupérable avec wget http://z32.ipst-info.net/tprsx/rpc/geometrie.x ; se

placer au préalable dans un répertoire /home/i1/rpc à créer)

struct point {

int x;

int y;

};

struct rectangle {

struct point p1;

struct point p2;

};

struct coordonnees {

int x1;

int x2;

int y1;

int y2;

};

struct param_inclus {

struct rectange rect;

struct point p;

};

typedef int booleen;

program GEOM_PROG {

version GEOM_VERSION_1 {

rectangle CREER_RECTANGLE(coordonnees) = 1;

int SURFACE_RECTANGLE(rectangle) = 2;

booleen INCLUS(param_inclus) = 3;

} = 1;

} = 0x20000001;

Nom du programme : GEOM_PROG d'identifiant 20000001 (en hexa) Nom de version : GEOM_VERSION_1 de numéro 1 Les 3 fonctions sont numérotées 1, 2 et 3

Les structures coordonnees et param_inclus ont été créées pour les fonctions nécessitant plus de 2 paramètres.

Remarque : par convention, on écrit les noms de fonctions, programmes et versions en MAJUSCULES.

Notes sur les numéros de programmes RPC : 4 plages de valeurs, en hexa :

0000 0000 à 1FFF FFFF : gérés par Sun

2000 0000 à 3FFF FFFF : programmes utilisateurs

4000 0000 à 5FFF FFFF : transient

6000 0000 à FFFF FFFF : réservé, non utilisé

Page 14: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 14/26

Génération des fichiers

$ rpcgen geometrie.x

Faire un man rpcgen. Fichiers générés par défaut à partir du .x :

geometrie.h : Définition de toutes les structures et des signatures des opérations

geometrie_xdr.c : Fonctions/routines de codage XDR des structures de données

geometrie_clnt.c et geometrie_svc.c : Talons côtés client et serveur

Avec option -a , rpcgen génère aussi des fichiers geometrie_client.c et geometrie_server.c , qui sont des

squelettes pour l'écriture des fonctions du programme, plus un fichier MakeFile (voir plus loin) Exemple : fichier geometrie.h

#include <rpc/rpc.h>

struct point {

int x;

int y;

};

typedef struct point point;

struct rectangle {

struct point p1;

struct point p2;

};

typedef struct rectangle rectangle;

struct coordonnees {

int x1;

int x2;

int y1;

int y2;

};

typedef struct coordonnees coordonnees;

struct param_inclus {

struct rectangle rect;

struct point p;

};

typedef struct param_inclus param_inclus;

typedef int booleen;

#define GEOM_PROG 0x20000001

#define GEOM_VERSION_1 1

#define CREER_RECTANGLE 1

extern rectangle * creer_rectangle_1(coordonnees *, CLIENT *);

extern rectangle * creer_rectangle_1_svc(coordonnees *, struct svc_req *);

#define SURFACE_RECTANGLE 2

extern int * surface_rectangle_1(rectangle *, CLIENT *);

extern int * surface_rectangle_1_svc(rectangle *, struct svc_req *);

#define INCLUS 3

extern booleen * inclus_1(param_inclus *, CLIENT *);

extern booleen * inclus_1_svc(param_inclus *, struct svc_req *);

extern int geom_prog_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t);

/* the xdr functions */

extern bool_t xdr_point (XDR *, point*);

extern bool_t xdr_rectangle (XDR *, rectangle*);

extern bool_t xdr_coordonnees (XDR *, coordonnees*);

extern bool_t xdr_param_inclus (XDR *, param_inclus*);

extern bool_t xdr_booleen (XDR *, booleen*);

}

Contenu du "fichier .h"

Pour chaque structure définie :

Définition de la structure équivalente en C

Définition d'un type du même nom correspondant à la structure

Signature de la méthode XDR correspondant à ce type

Page 15: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 15/26

Exemple, dans le .x struct point {

int x;

int y;

};

devient dans le .h struct point {

int x;

int y;

};

typedef struct point point;

bool_t xdr_point(XDR*, point*);

Définitions de constantes :

Numéros de programme et de versions en associant chaque numéro au nom précisé dans .x #define GEOM_PROG 0x20000001

#define GEOM_VERSION_1 1

Et pour chaque fonction, il y a définition d'une constante associant son nom à son numéro.Exemple : Dans .x : rectangle CREER_RECTANGLE(coordonnees) = 1;

Dans .h : #define CREER_RECTANGLE 1

Toutes ces constantes serviront à identifier le programme et les fonctions lors des appels à distance Ensuite, pour chaque fonction du .x, de version numérotée n, qui prend un type_param en paramètre et retourne un type_retour, on aura dans le .h, signature de 2 méthodes correspondantes :

type_retour *fonction_n(type_param *, CLIENT *)

type_retour *fonction_n_svc(type_param *, struct svc_req *)

Dans les 2 cas :

Le nom de la fonction est suffixée par la version (et svc pour la seconde)

Un niveau de pointeur en paramètre et en retour est ajouté par rapport au .x

La première est implémentée par le talon client. C'est cette fonction que la partie client appelle localement pour demander l'appel de la fonction associée côté serveur

Le paramètre CLIENT* contient les caractéristiques de la communication avec la partie serveur

La 2ème

est à implémenter côté serveur ; appelée par les clients

Le paramètre svc_req* contient les caractéristiques de la requête d'appel de service et l'identification du client

Exemple : geometrie.x :

int SURFACE_RECTANGLE(rectangle) = 2;

geometrie.h :

int surface_rectangle_1(rectangle *, CLIENT *);

int surface_rectangle_1_svc(rectangle *, svc_req *);

Contenu du fichier "_xdr.c" Contient les méthodes de codage XDR pour chaque type de données décrit dans le .x . Exemple :

Dans geometrie.x struct point {

int x;

int y;

};

Dans geometrie_xdr.c bool_t xdr_point(XDR* xdrs, point* objp) {

if (!xdr_int(xdrs, &objp->x)) {

return (FALSE);

}

if (!xdr_int(xdrs, &objp->y)) {

return (FALSE);

}

return (TRUE);

}

Le stub client "_clnt.c" contient la définition des fonctions clientes fonction_n Exemple :

rectangle * creer_rectangle_1(coordonnees *argp, CLIENT *clnt)

{

static rectangle clnt_res;

memset((char *)&clnt_res, 0, sizeof(clnt_res));

if (clnt_call (clnt, CREER_RECTANGLE,

(xdrproc_t) xdr_coordonnees, (caddr_t) argp,

(xdrproc_t) xdr_rectangle, (caddr_t) &clnt_res,

TIMEOUT) != RPC_SUCCESS) {

return (NULL);

}

return (&clnt_res);

}

Page 16: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 16/26

Le stub serveur "_svc.c", pour chaque version du programme, crée les sockets, enregistre les services dans le registre RPC, et transfère les appels clients aux différentes procédures fonction_n vers les procédures serveurs associées

fonction_n_svc (ces procédures seront implémentées dans le code serveur) static void

geom_prog_1(struct svc_req *rqstp, register SVCXPRT *transp)

{

union {

coordonnees creer_rectangle_1_arg;

rectangle surface_rectangle_1_arg;

param_inclus inclus_1_arg;

} argument;

char *result;

xdrproc_t _xdr_argument, _xdr_result;

char *(*local)(char *, struct svc_req *);

switch (rqstp->rq_proc) {

case NULLPROC:

(void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL);

return;

case CREER_RECTANGLE:

_xdr_argument = (xdrproc_t) xdr_coordonnees;

_xdr_result = (xdrproc_t) xdr_rectangle;

local = (char *(*)(char *, struct svc_req *)) creer_rectangle_1_svc;

break;

case SURFACE_RECTANGLE:

_xdr_argument = (xdrproc_t) xdr_rectangle;

_xdr_result = (xdrproc_t) xdr_int;

local = (char *(*)(char *, struct svc_req *)) surface_rectangle_1_svc;

break;

case INCLUS:

_xdr_argument = (xdrproc_t) xdr_param_inclus;

_xdr_result = (xdrproc_t) xdr_booleen;

local = (char *(*)(char *, struct svc_req *)) inclus_1_svc;

break;

default:

svcerr_noproc (transp);

return;

}

memset ((char *)&argument, 0, sizeof (argument));

if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {

svcerr_decode (transp);

return;

}

result = (*local)((char *)&argument, rqstp);

if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) {

svcerr_systemerr (transp);

}

if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {

fprintf (stderr, "%s", "unable to free arguments");

exit (1);

}

return;

}

int

main (int argc, char **argv)

{

register SVCXPRT *transp;

pmap_unset (GEOM_PROG, GEOM_VERSION_1);

transp = svcudp_create(RPC_ANYSOCK);

if (transp == NULL) {

fprintf (stderr, "%s", "cannot create udp service.");

exit(1);

}

if (!svc_register(transp, GEOM_PROG, GEOM_VERSION_1, geom_prog_1, IPPROTO_UDP)) {

fprintf (stderr, "%s", "unable to register (GEOM_PROG, GEOM_VERSION_1, udp).");

exit(1);

}

transp = svctcp_create(RPC_ANYSOCK, 0, 0);

if (transp == NULL) {

fprintf (stderr, "%s", "cannot create tcp service.");

exit(1);

}

if (!svc_register(transp, GEOM_PROG, GEOM_VERSION_1, geom_prog_1, IPPROTO_TCP)) {

fprintf (stderr, "%s", "unable to register (GEOM_PROG, GEOM_VERSION_1, tcp).");

exit(1);

}

svc_run ();

fprintf (stderr, "%s", "svc_run returned");

exit (1);

}

Page 17: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 17/26

Implémentation des fonctions côté serveur

Côté serveur, dans un fichier à part ou dans le squelette côté serveur si on l'a généré (dans le fichier

geometrie_server.c), pour chacune des fonctions du programme, on implémente le code en prenant la signature du .h

Exemple

Dans le .h

extern rectangle * creer_rectangle_1_svc(coordonnees *, struct svc_req *);

extern int * surface_rectangle_1_svc(rectangle *, struct svc_req *);

Implémentation de ces fonctions dans fichier geometrie_server.c

#include "geometrie.h"

rectangle * creer_rectangle_1_svc(coordonnees *argp, struct svc_req *rqstp)

{

static rectangle result;

result.p1.x = argp -> x1; result.p1.y = argp -> y1;

result.p2.x = argp -> x2; result.p2.y = argp -> y2;

return &result;

}

int * surface_rectangle_1_svc(rectangle *argp, struct svc_req *rqstp)

{

static int result;

result = (argp -> p2.x - argp -> p1.x) * (argp -> p2.y - argp -> p1.y);

return &result;

}

booleen * inclus_1_svc(param_inclus *argp, struct svc_req *rqstp)

{

static booleen result;

result = (argp -> p.x >= argp -> rect.p1.x) && (argp -> p.x <= argp -> rect.p2.x) && (argp ->

p.y >= argp -> rect.p1.y) && (argp -> p.y <= argp -> rect.p2.y);

return &result;

}

Remarques :

On n'a pas d'utilité ici à manipuler le paramètre svc_req

Les variables result sont déclarées en static :

o On doit retourner un pointeur sur une donnée qui existera toujours après l'appel de la fonction o Cette donnée sera retournée par copie au client

Implémentation des fonctions côté client

Pour l'appel d'un service fonction de version n sur la partie serveur, appeler simplement la fonction fonction_n côté client. Cette fonction est appelée sur le talon client qui relaie la requête côté serveur sur lequel on appellera fonction_n_svc

Avant de pouvoir appeler une fonction sur une machine distance, on doit identifier le programme RPC tournant sur cette machine, avec la procédure : * CLIENT *clnt_create(

char *machine // nom de la machine serveur

long numero_programme // id. du programme RPC

long numero_version // id. de la version du programme

char *protocole); //« udp » ou « tcp »

Pour identificateurs programme et version, on peut utiliser les noms associés se trouvant dans le .h

Cette procédure retourne un identificateur de communication côté client, nommé CLIENT, à utiliser pour appel des fonctions, ou retourne NULL en cas d'échec Implémentation de ces fonctions dans fichier geometrie_client.c

#include "geometrie.h"

void geom_prog_1(char *host)

{

CLIENT *clnt;

rectangle *result_1;

coordonnees creer_rectangle_1_arg;

int *result_2;

rectangle surface_rectangle_1_arg;

booleen *result_3;

param_inclus inclus_1_arg;

clnt = clnt_create (host, GEOM_PROG, GEOM_VERSION_1, "udp");

Page 18: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 18/26

if (clnt == NULL) {

clnt_pcreateerror (host);

exit (1);

}

creer_rectangle_1_arg.x1=12; creer_rectangle_1_arg.x2=24;

creer_rectangle_1_arg.y1=10; creer_rectangle_1_arg.y2=15;

result_1 = creer_rectangle_1(&creer_rectangle_1_arg, clnt);

if (result_1 == (rectangle *) NULL) {

clnt_perror (clnt, "call failed");

}

surface_rectangle_1_arg = *result_1;

result_2 = surface_rectangle_1(&surface_rectangle_1_arg, clnt);

if (result_2 == (int *) NULL) {

clnt_perror (clnt, "call failed");

}

printf(" Rectangle de surface %d\n", *result_2);

inclus_1_arg.p.x=16;inclus_1_arg.p.y=13;inclus_1_arg.rect=*result_1;

result_3 = inclus_1(&inclus_1_arg, clnt);

if (result_3 == (booleen *) NULL) {

clnt_perror (clnt, "call failed");

}

if (*result_3) {

printf(" p inclus dans rect\n");

}

else printf(" p en dehors de rect\n");

}

int main (int argc, char *argv[])

{

char *host;

if (argc < 2) {

printf ("usage: %s server_host\n", argv[0]);

exit (1);

}

host = argv[1];

geom_prog_1 (host);

exit (0);

}

Remarques :

Aucune différence avec appel d'une fonction locale

Transparence totale de la localisation distante du code de la fonction

Gestion des erreurs possibles lors des appels RPC : o Les fonctions retournent NULL en cas d'erreur

o clnt_perror(CLIENT*,char *msg) affiche l'erreur (précédée de msg)

Compilation parties client et serveur

Pour les 2 parties (client et serveur), on a besoin des fonctions de codage XDR :

$ gcc -c geometrie_xdr.c

Côté client, on produit un exécutable nommé client avec :

$ gcc -c geometrie_clnt.c

$ gcc -c geometrie_client.c

$ gcc -o geometrie_client geometrie_clnt.o geometrie_client.o geometrie_xdr.o

Ce qui revient à faire:

gcc -o geometrie_client geometrie_clnt.c geometrie_client.c geometrie_xdr.c

Côté serveur, on produit un exécutable nommé server avec :

$ gcc -c geometrie_svc.c

$ gcc -c geometrie_server.c

$ gcc -o geometrie_server geometrie_svc.o geometrie_server.o geometrie_xdr.o

Ce qui revient à faire:

gcc -o geometrie_server geometrie_svc.c geometrie_server.c geometrie_xdr.c

Rq : on peut réaliser toutes les compilations et l'édition de lien à la fois pour le client et le serveur avec :

make -f Makefile.geometrie

Page 19: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 19/26

Exécution parties client et serveur

Côté serveur Lancement du serveur : ./geometrie_server (faire une capture sur localhost filtre RPC pour voir les primitives

SET/UNSET de portmap)

Le talon côté serveur (geometrie_svc.c, à regarder) contient un main qui enregistre automatiquement le programme

comme service RPC (création d'un socket RPC)

Avec l'outil système rpcinfo (faire info rpcinfo), on peut connaître la liste des services RPC accessibles sur une

machine (locale ou distante) (le faire avant et après lancement du serveur) :

$ /usr/sbin/rpcinfo -p localhost ou XXX (faire une capture)

program no_version protocole no_port

100000 2 tcp 111 portmapper

100000 2 udp 111 portmapper

100024 1 udp 32768 status

100024 1 tcp 32770 status

391002 2 tcp 32771 sgi_fam

536870913 1 udp 32916

536870913 1 tcp 38950

Notre programme est bien lancé en version 1 Numéro programme : (536870913)10 = (20000001)16 Il est accessible via UDP (port 32916) ou TCP (port 38950)

Il n'a pas de nom de service déclaré/connu (on peut le nommer en éditant le fichier /etc/rpc)

Portmapper : démon système qui est interrogé pour récupérer la référence sur un service RPC et qui enregistre les services activés par les serveurs

rpcinfo -u (ou -t) localhost 536870913 (faire une capture)

program 536870913 version 1 ready and waiting

Côté client Lancement du client : ./geometrie_client host

On doit obtenir une sortie du type : rectangle de surface 60 p inclus dans rect

La capture wireshark avec filtre RPC et option RPC "dissect unknown programs" est évidemment instructive et conseillée… Utiliser 2 machines distinctes pour le client et le serveur, pour plus de clarté.

Page 20: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 20/26

Annexe 1 : TP sur RPC et la syntaxe XDR (RFC 4506 ; mise à jour non technique du RFC 1832) À faire :

1) Motivations 2) Principes 3) Syntaxe XDR (consulter rapidement le RFC4056)

4) Exemples : décoder les données qui sont retournées par les 3 procédures précédentes : struct, int, bool

5) Modifier le code du filtre, du client et du serveur (créer une version 2 du programme, avec un transport via TCP, pour changer) pour que :

a. les coordonnées du rectangle et du point soient des arguments du client b. la surface du rectangle dans la version 2 soit un "float" (et permette donc de manipuler des rectangles de

grandes dimensions) c. le test d'appartenance du point au rectangle retourne dans la version 2 non plus un booléen mais un "string"

du genre "le point P appartient au rectangle" d. le client appelle les 2 versions du programme (pour comparer)

Rq : le contrat et les codes client et serveur sont accessibles sur http://z32.ipst-info.net/tprsx/rpc2/)

6) capturer, analyser et décoder le résultat : enregistrement auprès du portmap au lancement du serveur (./geometrie_server),vérification par rpcinfo, puis exécution du client :

# rpcinfo -p

program vers proto port service

100000 4 tcp 111 portmapper

..

100000 2 udp 111 portmapper

100024 1 udp 48529 status

100024 1 tcp 41058 status

536870913 1 udp 797

536870913 2 udp 797

536870913 1 tcp 800

536870913 2 tcp 800

# rpcinfo -u localhost 536870913

program 536870913 version 1 ready and waiting

program 536870913 version 2 ready and waiting

# ./geometrie_client localhost 0 0 32768 65536 1 1

Execution du programme en version 1 :

Rectangle de surface -2147483648 donne une erreur (entier 32 bits) p inclus dans le rectangle

Execution du programme en version 2 :

Rectangle de surface 2.14748E+09 donne un float approximatif mais correct Le point est inclus dans le rectangle

Page 21: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 21/26

La valeur ci-dessus est un float simple précision codé en XDR et qui vaut : 2.14748E+09

Page 22: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 22/26

On capture maintenant : [root@pc4-03 v2]# ./geometrie_client localhost 0 0 24 32 18 10

Execution du programme en version 1 :

Rectangle de surface 768

p inclus dans le rectangle

Execution du programme en version 2 :

Rectangle de surface 768

Le point est inclus dans le rectangle

On doit décoder le codage XDR de la valeur retournée pour la surface (768)

Page 23: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 23/26

Page 24: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 24/26

Annexe 2 : NFS (cf. les RFC1813 pour BFSv3 et RFC7530 pour NFSv4) À faire :

1) Présentation : système de fichier réparti/virtuel, notion de montage 2) Identifier les procédures et "opérations" appelables (dans le RFC) 3) sur XXX, se trouve un serveur NFS configuré exportant un répertoire. Vérifier par rpcinfo que des RPC sont

accessibles sur ce serveur. 4) Sur votre poste, réaliser, capturer et analyser les commandes :

rpcinfo -p XXX

rpcinfo -s XXX

rpcinfo -u XXX nfs

mount.nfs –o vers=3 -o intr XXX:/nfs /mnt/nfs/

ou (pour tester la version 4 de NFS qui réalise des appel combiné (COMPOUND) : mount -t nfs4 -o intr XXX:/nfs /mnt/nfs/

5) Se placer sur le répertoire monté /mnt/nfs ; capturer et analyser qq manips : ls, cd, cat, mkdir etc… rpcinfo -s XXX program version(s) netid(s) service owner

100000 2,3,4 local,udp,tcp,udp6,tcp6 portmapper superuser

100024 1 tcp6,udp6,tcp,udp status 29

100011 2,1 tcp,udp rquotad superuser

100005 3,2,1 tcp6,udp6,tcp,udp mountd superuser

100003 4,3,2 udp6,tcp6,udp,tcp nfs superuser

100227 3,2 udp6,tcp6,udp,tcp nfs_acl superuser

100021 4,3,1 tcp6,udp6,tcp,udp nlockmgr superuser

Page 25: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 25/26

Annexe 3 : une application RPC de type "oneway"

In one-way messaging the client thread sends a request containing a message to the server. The client thread does not wait for a reply from the server and is free to continue processing when the request has been accepted by the transport layer. The request is not always sent immediately to the server by the transport layer, but waits in a queue until the transport layer sends it. The server executes the request received by processing the message contained in the request. This method saves processing time.

In previous versions of the Sun RPC library, most requests were sent by two-way messaging. In two-way messaging, the client thread waits until it gets an answer from the server before continuing processing. If the client thread does not receive a reply from the server within a certain period of time, a time-out occurs. This client thread cannot send a second request until the first request is executed or until a time-out occurs. This messaging method is illustrated in the following figure.

Suit un exemple qui ne tournera pas sur la configuration des postes de TP, qui ne disposent pas des librairies RPC intégrant cette fonctionnalité. Cet exemple est fourni à titre d'illustration.

Page 26: 1. Remote Procedure Call : les motivationsz32.ipst-info.net/tprsx/rsx102/RSX102-L3 - Chapitre 03 - RPC - 2017... · RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 2/26 c) L’approche client-serveur

RSX102 : RPC - 2017 - B.Raiff IPST-CNAM 26/26

This example illustrates how to use a one-way procedure on a simple counter service. In this counter service the ADD() function is the only function available. Each remote call sends an integer and this integer is added to a global counter managed by the server. For this service, you must declare the oneway attribute in the RPC language definition.

1. Write the service description in the counter.x file. /* counter.x: Remote counter protocol */

program COUNTERPROG {

version COUNTERVERS {

oneway ADD(int) = 1;

} = 1;

} = 0x30000001;

The service has a program number, (COUNTERPROG) 0x300000001, and a version number, (COUNTERVERS) 1.

2. Call rpcgen on the counter.x file. rpcgen -M -N -C counter.x

This generates client and server stubs, counter.h, counter_clnt.c and counter_svc.c

3. As shown in the server.c file, write the service handler for the server side and the counterprog_1_freeresult() function used to free memory areas allocated to the handler. The RPC library calls this function when the server sends a reply to the client. #include <stdio.h>

#include "counter.h"

int counter = 0;

bool_t add_1_svc(int number, struct svc_req *rqstp)

{

bool_t retval = TRUE;

counter = counter + number;

return retval;

}

int counterprog_1_freeresult(SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result)

{

(void) xdr_free(xdr_result, result); /* Insert additional freeing code here, if needed */

return TRUE;

}

Build the server by compiling and linking the service handler to the counter_svc.c stub.

4. Write the client application, client.c #include <stdio.h>

#include "counter.h"

main(int argc, char *argv[])

{

CLIENT *clnt;

enum clnt_stat result;

char *server;

int number;

if(argc !=3) {

fprintf(stderr, "usage: %s server_name number\n", argv[0];

exit(1);

}

server = argv[1];

number = atoi(argv[2]);

clnt = clnt_create(server, COUNTERPROG, COUNTERVERS, "tcp");

if (clnt == (CLIENT *)NULL) {

clnt_pcreateerror(server);

exit(1);

}

result = add_1(number, clnt);

if (result !=RPC_SUCCESS) { clnt_perror(clnt, "call failed"); }

clnt_destroy(clnt);

exit(0);

}

The add_1() client function is the counter_clnt.c stub generated for the remote function. To build the client, compile and link the client main and the counter_clnt.c.

5. Launch the server that you built. % ./server

6. Invoke the service in another shell. % ./client servername 23