Ver código fonte

Changements dans les méthodes de sandboxing

Alexandre Janniaux 6 anos atrás
pai
commit
42cc7e938a

+ 112 - 7
chapters/sandbox_pattern_libvlccore.tex

@@ -1,9 +1,114 @@
-Armé des différentes abstractions mises en place pour la communication
-inter-processus des données de contrôle et des données applicatives, on va
-pouvoir commencer à intégrer réellement les morceaux de l'application dans la
-sandbox. On va donc devoir définir comment l'application sera découpée et
-cloisonnée et quels seront les points d'entrées pour la sandbox.
+\section{Utilisation d'objets proxy}
+
+Nous allons alors utiliser les différentes abstractions mises en place
+précédemment pour la communication inter-processus, que ce soit pour le
+transfert de données de contrôle pour les RPC ou des données applicatives avec
+les blocs mémoires. C'est ici qu'intervient le découpage de l'application en
+différents morceaux ainsi que les méthodes synchrones qu'on va utiliser pour
+pouvoir les relier sans altérer le fonctionnement actuel. On va donc également
+devoir définir quels seront les points d'entrées pour la sandbox, c'est-à-dire
+la manière dont la sandbox va pouvoir s'injecter dans le code existant.
+
+Le pattern utilisé ici sera principalement d'avoir un objet proxy pour tous les
+objets qui seront utilisé entre processus.
 
 Dans cette partie, nous allons majoritairement prendre en considération le cas
-du découpage du décodeur, entraînant la refactorisation d'autres dépendences de
-cet objet.
+du découpage du décodeur, ainsi que des objets étant directement lié à son
+fonctionnement.
+
+% TODO: graphe d'interaction du décodeur
+
+\section{Intégration des objets proxys dans l'architecture}
+
+Le décodeur est dans notre cas créé via l'appel à \inltype{input_DecoderNew}. On
+va donc stocker une nouvelle table de fonctions dans la libvlc, dont l'une
+\inltype{pf_create_stage} indiquera comment créer un étage donné. On peut alors
+surcharger \inltype{input_DecoderNew} poour appeler \inltype{pf_create_stage} et
+initialiser cette dernière à des valeurs différentes selon si on démarre en
+sandbox ou non. Cela justifie notamment les pointeurs \inltype{create_vlc} et
+\inltype{delete_vlc} dans la configuration de lancement de la sandbox.
+
+\begin{code}{c}{Création du décodeur}
+decoder_t *input_DecoderNew( input_thread_t *p_input,
+                             es_format_t *fmt, input_clock_t *p_clock,
+                             sout_instance_t *p_sout  )
+{
+    return vlc_CreateStage( VLC_OBJECT(p_input), STAGE_DECODER,
+                            p_input, fmt, p_clock, p_sout );
+}
+\end{code}
+
+Le décodeur fonctionne dans son propre thread et subit des interactions
+principalement depuis l'objet \inltype{input} via l'API de fonctions commençant
+par \inltype{input_Decoder}. On va donc rajouter une table virtuelle dans
+l'objet représentant le décodeur pour pouvoir changer de stratégie lors de sa
+création.
+
+Ce pattern va être présent pour tous les objets qui sont fonctionnellement liés
+au décodeur. En particulier, on a par exemple l'input et le décodeur proxy dans
+un processus, puis l'input proxy et le décodeur dans un autre, donnant lieu à la
+situation suivante.
+
+% TODO schéma croisé
+
+Les paragraphes précédents décrivent la création d'un décodeur depuis le
+processus de l'input, mais on voit au grpahe précédent qu'il faut également
+pouvoir faire un proxy de l'input dans le processus du décodeur, c'est-à-dire
+pouvoir «transmettre» l'input d'un processus à l'autre. Nous allons donc
+reprendre le concept de jeton d'accès et permettre l'envoi d'objet proxy à
+travers une IPC.\@ Il faut alors détailler ces objets proxies du point de vue de
+l'envoi de message.
+
+\begin{code}{c}{Structure privée d'un objet proxy}
+struct vlc_rpc_proxy_t
+{
+    vlc_process_interconn_t *interconn;
+    uint32_t id;
+    uint32_t stage_id;
+    void    *p_this;
+    vlc_rpc_proxy_cb call;
+};
+\end{code}
+
+Chaque objet proxy dispose de cette structure. \inltype{interconn} indique la
+méthode de communication pour rejoindre l'autre étage dans un autre processus.
+\inltype{stage_id} indique au broker quel processus contacter pour l'envoi.
+Enfin, tous les objets proxies disposent d'un identifiant unique au processus,
+permettant d'envoyer ou recevoir des RPC.\@ En cas de réception, \inltype{call}
+sera appelé.
+
+\begin{code}{c}{Fonction de rappel pour les proxies}
+typedef void (*vlc_rpc_proxy_cb)(vlc_rpc_proxy_t *p_proxy,
+                                 uint32_t i_query,
+                                 vlc_process_msg_t *p_msg);
+\end{code}
+
+Comme ces objets seront «transmis», il faut alors seulement définir des méthodes
+pour créer un \inltype{vlc_rpc_proxy_t} depuis un objet existant, et créer un
+objet proxy à partir d'un \inltype{vlc_rpc_proxy_t}.
+
+\section{Avantages et limites}
+
+Commençons par des désavantages liées à cette méthode par rapport à la
+précédente. D'abord, bien qu'apportant l'isolation demandée au chapitre
+précédent, elle demande bien plus de travail d'intégration. En plus de cela, on
+voit avec la relation entre l'input et le décodeur que la méthode est beaucoup
+soumise aux défauts ou aux difficultés d'architecture du projet et qu'il devient
+nécessaire d'effectuer des réécritures de certaines parties.
+
+Un exemple non présenté ici est celui de la réécriture de
+l'\inltype{input_clock} en \inltype{vlc_clock}, pour des raisons différentes
+mais apportant plus de flexibilité pour ce modèle.
+
+De plus, beaucoup d'abstraction doit être apportée sous la forme de tables
+virtuelles dans les différents objets de VLC.\@ Bien que pouvant apporter de la
+flexibilité, cela demande beaucoup de transfor,ation sur la manière de
+programmer dans l'application en général.
+
+Enfin, comme expliqué dans le chapitre sur la boucle événementielle, toutes les
+opérations, et en particulier les RPC dans des RPC ne sont pas possibles et
+limmitent particulièrement la conception de ce modèle.
+
+Néanmoins, ces défauts peuvent être considérés comme des incitations à améliorer
+la conception générale de l'application en donnant une ligne directrice très
+claire.

+ 5 - 4
chapters/sandbox_pattern_modules.tex

@@ -1,6 +1,6 @@
 \section{Motivation}
 
-Une autre méthode de cloisonnement qui n'a pas beaucoup été explorée est de
+Une première méthode de cloisonnement qui n'a pas beaucoup été explorée est de
 cloisonner l'application par module et non par objet de libvlccore.
 
 Cette méthode permet d'arriver plus rapidement à une situation où l'ensemble
@@ -28,7 +28,8 @@ vers le cœur de la sandbox pour transformer les requêtes de module vers des
 modules proxies. Le nom du module ou de la classe de module peut correspondre à
 une politique et permet ainsi de décider très finement et automatiquement quel
 module doit être redirigé vers un autre processus, nouveau ou déjà existant.
+C'est à ce moment que les étages définis précédemment vont intervenir pour
+permettre d'écrire le code de façon naturelle.
 
-Il n'y a plus de notion de \inltype{vlc_rpc_handler_t} étant donné que l'on
-manipule directement les modules à travers leur API et que les liens se font au
-niveau du core.
+Néanmoins, cette technique n'a pas été implémenté à cause des défauts
+d'isolation qu'elle possédait.

+ 3 - 3
main.tex

@@ -95,12 +95,12 @@ Renforcement de la sécurité d'un lecteur vidéo multiplate-forme par séparati
 \chapter{Gestion des blocs mémoires}
 \input{chapters/sandbox_memory_blocks}
 
+\chapter{Technique de sandboxing naïve, isolation par module}
+\input{chapters/sandbox_pattern_modules}
+
 \chapter{Gestion des objets de libvlccore, design pattern}
 \input{chapters/sandbox_pattern_libvlccore}
 
-\chapter{Technique de sandboxing alternative, isolation par module}
-\input{chapters/sandbox_pattern_modules}
-
 \part{Implémentation de la sandbox sous Linux}
 \chapter{Passage de descripteur de fichiers entre processus}
 \input{chapters/linux_file_descriptor}