1506 lines
88 KiB
TeX
1506 lines
88 KiB
TeX
% !TeX document-id = {d31ec456-0f13-4d95-9fc2-bd99b70397a1}
|
||
% !TeX TXS-program:compile = txs:///xelatex/[-shell-escape]
|
||
% !TEX encoding = UTF-8 Unicode
|
||
% !TEX spellcheck = el-GR
|
||
%
|
||
% Compiter Networks II report
|
||
%
|
||
% Requires compilation with pdfLaTeX or XeLaTeX
|
||
%
|
||
% authors:
|
||
% Χρήστος Χουτουρίδης ΑΕΜ 8997
|
||
% cchoutou@ece.auth.gr
|
||
|
||
%
|
||
% Options:
|
||
%
|
||
% 1) mainlang=<language>
|
||
% Default: english
|
||
% Set the default language of the document which affects hyphenations,
|
||
% localization (section, dates, etc...)
|
||
%
|
||
% example: \documentclass[mainlang=greek]{AUThReport}
|
||
%
|
||
% 2) <language>
|
||
% Add hyphenation and typesetting support for other languages
|
||
% Currently supports: english, greek, german, frenc
|
||
%
|
||
% example: \documentclass[english, greek]{AUThReport}
|
||
%
|
||
% 3) short: Requests a shorter title for the document
|
||
% Default: no short
|
||
%
|
||
% example: \documentclass[short]{AUThReport}
|
||
%
|
||
\documentclass[a4paper, 11pt, mainlang=greek, english]{AUThReport/AUThReport}
|
||
|
||
\CurrentDate{\today}
|
||
|
||
% Document setup
|
||
%---------------------------------
|
||
|
||
% \WorkGroup{Ομάδα Χ}
|
||
|
||
\AuthorName{Χρήστος Χουτουρίδης}
|
||
\AuthorMail{cchoutou@ece.auth.gr}
|
||
\AuthorAEM{8997}
|
||
|
||
%\CoAuthorName{Όνομα Επίθετο}
|
||
%\CoAuthorAEM{AEM}
|
||
%\CoAuthorMail{xxx@ece.auth.gr}
|
||
|
||
\DocTitle{Αυτοματοποιημένη Ανάπτυξη Τοπολογίας και Ανάλυση Πρωτοκόλλων στο Mininet}
|
||
%\DocSubTitle{Ανάλυση και υλοποίηση του αλγόριθμου bitonic sort για υποσύστημα γραφικών με χρήση CUDA}
|
||
|
||
\Department{Τμήμα ΗΜΜΥ. Τομέας Ηλεκτρονικής}
|
||
\ClassName{Δίκτυα Υπολογιστών ΙΙ}
|
||
%
|
||
\InstructorName{Αναστάσιος Ντελόπουλος}
|
||
\InstructorMail{antelopo@ece.auth.gr}
|
||
|
||
\CoInstructorName{Εμανουήλ Τσαρδουλιάς}
|
||
\CoInstructorMail{etsardou@ece.auth.gr}
|
||
|
||
|
||
% Local package requirements
|
||
%---------------------------------
|
||
|
||
\usepackage{enumitem}
|
||
\usepackage{tabularx}
|
||
\usepackage{array}
|
||
\usepackage{multirow}
|
||
\usepackage{float}
|
||
\usepackage{xcolor}
|
||
\usepackage{soul}
|
||
\usepackage{amsmath}
|
||
\usepackage{footnote}
|
||
\usepackage{footmisc}
|
||
|
||
\usepackage{minted}
|
||
\usepackage{xcolor} %
|
||
|
||
\setminted[python]{
|
||
fontsize=\small,
|
||
breaklines,
|
||
autogobble,
|
||
baselinestretch=1.1,
|
||
obeytabs=true
|
||
tabsize=2,
|
||
numbersep=8pt,
|
||
startinline,
|
||
gobble=0
|
||
}
|
||
|
||
\setminted[json]{
|
||
fontsize=\small,
|
||
breaklines,
|
||
autogobble,
|
||
baselinestretch=1.1,
|
||
obeytabs=true
|
||
tabsize=2,
|
||
numbersep=8pt,
|
||
startinline,
|
||
gobble=0
|
||
}
|
||
|
||
\setminted[bash]{
|
||
fontsize=\small,
|
||
breaklines,
|
||
autogobble,
|
||
baselinestretch=1.1,
|
||
obeytabs=true
|
||
tabsize=2,
|
||
numbersep=8pt,
|
||
startinline,
|
||
gobble=0
|
||
}
|
||
|
||
%\definecolor{red-highlight}{rgb}{1.0, 0.11, 0.0}
|
||
\definecolor{red-highlight}{rgb}{1.0, 0.31, 0.0}
|
||
\definecolor{green-highlight}{rgb}{0.0, 0.62, 0.42}
|
||
|
||
\newcommand{\bxrd}[1]{\colorbox{red-highlight}{#1}}
|
||
\newcommand{\bxgr}[1]{\colorbox{green-highlight}{#1}}
|
||
|
||
\newcommand{\trd}[1]{\textcolor{red-highlight}{\textbf{#1}}}
|
||
\newcommand{\tgr}[1]{\textcolor{green-highlight}{\textbf{#1}}}
|
||
|
||
% “virtual” cites
|
||
% ----------------------------------------
|
||
%\newcommand{\citeKnuthACM}{%
|
||
% Donald E. Knuth, \emph{Structured Programming with go to Statements}, ACM Computing Surveys, vol. 6, no. 4, 1974
|
||
%}
|
||
|
||
% Links
|
||
% Repository links
|
||
% ----------------------------------------
|
||
\newcommand{\repoGithub}{https://github.com/hoo2/Computer-Networks-II}
|
||
\newcommand{\repoGitea}{https://git.hoo2.net/hoo2/Computer-Networks-II}
|
||
|
||
\newcommand{\topologyJsonUrl}{\repoGithub/blob/HEAD/exercise/topology.json}
|
||
\newcommand{\buildNetworkUrl}{\repoGithub/blob/HEAD/source/build_network.py}
|
||
\newcommand{\resultsUrl}{\repoGithub/tree/HEAD/exercise/results}
|
||
|
||
\newcommand{\dslDesignUrl}{\repoGithub/blob/HEAD/Mininet_DSL_Design.md}
|
||
|
||
% Experiment 1
|
||
\newcommand{\dhcpExecutionUrl}{\repoGithub/blob/HEAD/exercise/results/exp1-dhcp/execution.txt}
|
||
\newcommand{\dhcpDecodedUrl}{\repoGithub/blob/HEAD/exercise/results/exp1-dhcp/dhcp-decoded.txt}
|
||
\newcommand{\dhcpPcapUrl}{\repoGithub/blob/HEAD/exercise/results/exp1-dhcp/dhcp.pcap}
|
||
|
||
% Experiment 2
|
||
\newcommand{\arpExecutionUrl}{\repoGithub/blob/HEAD/exercise/results/exp2-arp/execution.txt}
|
||
\newcommand{\arpDecodedUrl}{\repoGithub/blob/HEAD/exercise/results/exp2-arp/arp-decoded.txt}
|
||
\newcommand{\arpPcapUrl}{\repoGithub/blob/HEAD/exercise/results/exp2-arp/arp.pcap}
|
||
|
||
% Experiment 3
|
||
\newcommand{\routingExecutionUrl}{\repoGithub/blob/HEAD/exercise/results/exp3-routing/execution.txt}
|
||
\newcommand{\icmpAPcapUrl}{\repoGithub/blob/HEAD/exercise/results/exp3-routing/icmp-A.pcap}
|
||
\newcommand{\icmpBPcapUrl}{\repoGithub/blob/HEAD/exercise/results/exp3-routing/icmp-B.pcap}
|
||
\newcommand{\icmpADecodedUrl}{\repoGithub/blob/HEAD/exercise/results/exp3-routing/icmp-A-decoded.txt}
|
||
\newcommand{\icmpBDecodedUrl}{\repoGithub/blob/HEAD/exercise/results/exp3-routing/icmp-B-decoded.txt}
|
||
|
||
\begin{document}
|
||
|
||
\InsertTitle
|
||
|
||
%\tableofcontents
|
||
|
||
|
||
\section{Εισαγωγή}
|
||
|
||
Η παρούσα εργασία έχει ως αντικείμενο την \textbf{αυτοματοποιημένη ανάπτυξη δικτυακών τοπολογιών στο περιβάλλον Mininet},
|
||
με βάση μια δηλωτική περιγραφή σε αρχείο JSON.
|
||
Στο πλαίσιο αυτό υλοποιείται εφαρμογή σε Python, η οποία διαβάζει περιγραφές της τοπολογίας σε μια πρότυπη \textbf{Domain-Specific
|
||
Language -- DSL}, και δημιουργεί δυναμικά τους αντίστοιχους hosts, μεταγωγείς, συνδέσμους και δρομολογητές και εφαρμόζει
|
||
τις απαιτούμενες ρυθμίσεις δικτύου.
|
||
Το Mininet χρησιμοποιείται ως περιβάλλον εξομοίωσης, ώστε η τοπολογία να μπορεί να κατασκευάζεται και να εξετάζεται
|
||
με χρήση των ίδιων εργαλείων και πρωτοκόλλων που χρησιμοποιούνται σε ένα πραγματικό σύστημα Linux.
|
||
|
||
Μετά την ανάπτυξη της τοπολογίας πραγματοποιούνται τρία πειράματα χαμηλού επιπέδου για τη μελέτη των πρωτοκόλλων
|
||
\textbf{DHCP} και \textbf{ARP}, καθώς και της \textbf{δρομολόγησης μεταξύ διαφορετικών υποδικτύων}.
|
||
Μέσω καταγραφών με το \texttt{tcpdump} εξετάζεται η διαδικασία D.O.R.A. του DHCP, η αντιστοίχιση διευθύνσεων IP σε
|
||
διευθύνσεις MAC μέσω του ARP και η μεταβολή των Ethernet διευθύνσεων και του TTL κατά τη διέλευση ενός IP πακέτου
|
||
από τον δρομολογητή.
|
||
Στόχος των πειραμάτων είναι η σύνδεση της θεωρητικής λειτουργίας των πρωτοκόλλων με την πραγματική μορφή των
|
||
πακέτων που ανταλλάσσονται στα διαφορετικά επίπεδα του δικτύου.
|
||
|
||
|
||
\subsection{Παραδοτέα}
|
||
|
||
Τα παραδοτέα της εργασίας αποτελούνται από:
|
||
\begin{itemize}
|
||
\item Την παρούσα τεχνική αναφορά.
|
||
\item Το αρχείο \href{\topologyJsonUrl}{\texttt{exercise/topology.json}}, το οποίο περιγράφει δηλωτικά την τοπολογία δικτύου που χρησιμοποιείται στην εργασία.
|
||
\item Τον κατάλογο \texttt{source/}, ο οποίος περιέχει το αρχείο \href{\buildNetworkUrl}{\texttt{build\_network.py}}, καθώς και τα υπόλοιπα αρχεία
|
||
Python που υλοποιούν την εφαρμογή.
|
||
\item Τον κατάλογο \href{\resultsUrl}{\texttt{exercise/results/}}, ο οποίος περιέχει τις μετρήσεις και τα παραγόμενα αρχεία των πειραμάτων της εργασίας.
|
||
\item Τους συνδέσμους προς τα αποθετήρια στο \href{\repoGithub}{GitHub} και στον \href{\repoGitea}{προσωπικό μου server}, τα οποία περιέχουν τον πηγαίο κώδικα,
|
||
τον κώδικα παραγωγής της αναφοράς και τα αποτελέσματα των πειραμάτων.
|
||
\end{itemize}
|
||
|
||
|
||
\section{Υλοποίηση}
|
||
|
||
|
||
% ========================= DSL =========================
|
||
|
||
\subsection{Δηλωτική γλώσσα περιγραφής τοπολογίας}
|
||
|
||
Για την περιγραφή των δικτυακών τοπολογιών σχεδιάστηκε μία μικρή \textbf{δηλωτική γλώσσα ειδικού σκοπού}
|
||
(Domain-Specific Language -- DSL), η οποία χρησιμοποιεί το JSON ως μορφή αναπαράστασης.
|
||
Στόχος της γλώσσας είναι να περιγράφει την \emph{επιθυμητή κατάσταση του δικτύου} και όχι τη σειρά των εντολών
|
||
που απαιτούνται για την κατασκευή του στο Mininet.
|
||
Με αυτόν τον τρόπο η περιγραφή της τοπολογίας παραμένει ανεξάρτητη από λεπτομέρειες της υλοποίησης, όπως τα
|
||
ονόματα των εικονικών διεπαφών ή η ακριβής ακολουθία κλήσεων προς το Mininet API.
|
||
Η αναλυτική σχεδίαση και η γραμματική της γλώσσας τεκμηριώνονται επίσης στο αρχείο
|
||
\href{\dslDesignUrl}{\texttt{Mininet\_DSL\_Design.md}} του αποθετηρίου.
|
||
|
||
\subsubsection{Σχεδιαστική προσέγγιση}
|
||
|
||
Ο σχεδιασμός της γλώσσας πραγματοποιήθηκε \textbf{από πάνω προς τα κάτω}, ξεκινώντας από τις έννοιες που είναι
|
||
φυσικό να χρησιμοποιούνται για την περιγραφή ενός δικτύου, όπως οι \emph{κόμβοι}, οι \emph{διεπαφές}, οι \emph{σύνδεσμοι} και οι
|
||
\emph{υπηρεσίες}.
|
||
Παράλληλα, κάθε αφηρημένη έννοια επιλέχθηκε έχοντας υπόψη τις διαθέσιμες πρωτογενείς λειτουργίες του Mininet και
|
||
του δικτυακού υποσυστήματος του Linux.
|
||
Η προσέγγιση αυτή επιτρέπει στη γλώσσα να παραμένει υψηλού επιπέδου, χωρίς να εισάγει κατασκευές που δεν μπορούν
|
||
να μεταφραστούν με σαφή και συστηματικό τρόπο στο υποκείμενο περιβάλλον εκτέλεσης.
|
||
|
||
Οι βασικές λειτουργίες που απαιτούνται από την εργασία μπορούν να αναχθούν σε ένα σχετικά μικρό σύνολο
|
||
\emph{πρωτογενών κατασκευών} του Mininet και του Linux.
|
||
Η δημιουργία hosts και switches, η σύνδεσή τους μέσω links και η εκτέλεση εντολών μέσα στους αντίστοιχους
|
||
network namespaces επαρκούν για την κατασκευή της απαιτούμενης τοπολογίας.
|
||
Ένας δρομολογητής μπορεί αντίστοιχα να μοντελοποιηθεί ως host με περισσότερες από μία διεπαφές, κατάλληλη
|
||
Layer-3 διευθυνσιοδότηση και ενεργοποιημένη προώθηση IP.
|
||
Ο DHCP server μπορεί να θεωρηθεί ως υπηρεσία που εκτελείται σε έναν κόμβο και συνδέεται με συγκεκριμένη διεπαφή.
|
||
|
||
Πριν οριστικοποιηθούν οι οντότητες της DSL, εξετάστηκαν οι βασικές λειτουργίες που παρέχει το Mininet και το
|
||
δικτυακό υποσύστημα του Linux για την κατασκευή και παραμετροποίηση μιας τοπολογίας.
|
||
Οι κύριες λειτουργίες που χρησιμοποιήθηκαν ως βάση είναι οι \texttt{addHost()}, \texttt{addSwitch()} και
|
||
\texttt{addLink()}, καθώς και η δυνατότητα εκτέλεσης εντολών μέσα σε κάθε network namespace μέσω του
|
||
\texttt{node.cmd()}.
|
||
Στις λειτουργίες αυτές προστίθενται η παραμετροποίηση διεπαφών και δρομολόγησης μέσω εργαλείων του Linux και η
|
||
εκκίνηση διεργασιών, όπως ο \texttt{dnsmasq}, μέσα στον αντίστοιχο κόμβο.
|
||
Η ανάλυση αυτή χρησιμοποιήθηκε για να \textbf{σταθεροποιηθεί το σύνολο των αφαιρέσεων της DSL}, έτσι ώστε κάθε
|
||
υψηλού επιπέδου κατασκευή να έχει σαφή δρόμο μετάφρασης προς τις διαθέσιμες λειτουργίες του backend.
|
||
|
||
Με βάση τις παρατηρήσεις αυτές επιλέχθηκε ένα σύνολο οντοτήτων ώστε η DSL να \textbf{καλύπτει τον χώρο των
|
||
κατασκευών που απαιτούνται από την εργασία}.
|
||
Αντίστοιχα, το σύνολο των primitives του Mininet και του Linux που χρησιμοποιείται είναι επαρκές ώστε κάθε
|
||
κατασκευή της DSL να μπορεί να μεταφραστεί σε συγκεκριμένες λειτουργίες του backend.
|
||
Με αυτή την έννοια, τόσο η γλώσσα ως προς τον χώρο του προβλήματος όσο και τα χρησιμοποιούμενα primitives ως
|
||
προς τον χώρο της υλοποίησης λειτουργούν \emph{«επί»}.
|
||
Δηλαδή, δεν παραμένει απαίτηση της εργασίας χωρίς αναπαράσταση στη DSL ούτε κατασκευή της DSL χωρίς αντίστοιχη
|
||
υλοποίηση στο Mininet και στο Linux.
|
||
Οι βασικές οντότητες της γλώσσας είναι οι \emph{κόμβοι}, οι \emph{διεπαφές}, οι \emph{σύνδεσμοι}, οι
|
||
\emph{ρυθμίσεις κόμβων} και οι \emph{υπηρεσίες}.
|
||
|
||
\subsubsection{Βασική γραμματική}
|
||
|
||
Η τοπολογία περιγράφεται από τρεις κύριες κατηγορίες αντικειμένων: \texttt{nodes}, \texttt{links} και
|
||
\texttt{services}.
|
||
Η βασική δομή της γλώσσας μπορεί να συνοψιστεί ως εξής:
|
||
|
||
\begin{verbatim}
|
||
Network
|
||
|-- Nodes
|
||
| |-- name
|
||
| |-- type
|
||
| |-- interfaces
|
||
| `-- settings
|
||
|
|
||
|-- Links
|
||
| |-- name
|
||
| |-- endpoints
|
||
| | |-- node
|
||
| | `-- interface
|
||
| `-- settings
|
||
|
|
||
`-- Services
|
||
|-- type
|
||
|-- node
|
||
|-- interface
|
||
`-- settings
|
||
\end{verbatim}
|
||
|
||
Κάθε κατηγορία έχει \textbf{διαφορετική σημασιολογική ευθύνη}.
|
||
Ένας κόμβος(node) αναπαριστά έναν συμμετέχοντα του δικτύου, μία διεπαφή(interface) ένα σημείο σύνδεσης που ανήκει σε έναν κόμβο
|
||
και ένας σύνδεσμος(link) συνδέει δύο τέτοια σημεία.
|
||
Οι ρυθμίσεις(settings) κόμβου περιγράφουν ιδιότητες του ίδιου του δικτυακού namespace, ενώ οι υπηρεσίες(services) αναπαριστούν
|
||
ανεξάρτητες διεργασίες που εκτελούνται μέσα σε αυτό.
|
||
|
||
\subsubsection{Κόμβοι και διεπαφές}
|
||
|
||
Οι κόμβοι δηλώνονται με ένα μοναδικό λογικό όνομα και έναν τύπο.
|
||
Οι τύποι που υποστηρίζονται στην παρούσα υλοποίηση είναι \texttt{host}, \texttt{switch} και \texttt{router}.
|
||
Ο τύπος εκφράζει τη \emph{σημασιολογία του κόμβου} και όχι απαραίτητα το συγκεκριμένο αντικείμενο του Mininet που
|
||
θα χρησιμοποιηθεί για την υλοποίησή του.
|
||
|
||
Οι διεπαφές \textbf{ανήκουν στους κόμβους} και προσδιορίζονται από λογικά ονόματα, τα οποία δεν απαιτείται να
|
||
ταυτίζονται με τα ονόματα που θα δημιουργηθούν τελικά στο Linux.
|
||
Για παράδειγμα, μία διεπαφή με λογικό όνομα \texttt{lan} μπορεί κατά την υλοποίηση να αντιστοιχιστεί στη φυσική
|
||
διεπαφή \texttt{r0-eth0}.
|
||
Η επιλογή αυτή επιτρέπει στο αρχείο JSON να χρησιμοποιεί ονόματα που εκφράζουν τον ρόλο μιας διεπαφής και όχι
|
||
λεπτομέρειες της διαδικασίας δημιουργίας της.
|
||
|
||
Μία διεπαφή μπορεί να χρησιμοποιεί στατική διευθυνσιοδότηση, DHCP ή να μην διαθέτει καθόλου Layer-3
|
||
παραμετροποίηση.
|
||
Στην περίπτωση στατικής διευθυνσιοδότησης δηλώνεται η διεύθυνση μαζί με το prefix και, προαιρετικά, μία
|
||
προεπιλεγμένη πύλη.
|
||
Επιπλέον μπορούν να δηλωθούν ιδιότητες όπως η διεύθυνση MAC και το MTU.
|
||
|
||
Ιδιαίτερη σημασία έχει η διάκριση μεταξύ της \textbf{απουσίας} του πεδίου \texttt{interfaces} και της δήλωσης
|
||
ενός κενού αντικειμένου \texttt{interfaces}.
|
||
Όταν το πεδίο παραλείπεται, ο κόμβος θεωρείται ότι διαθέτει \emph{δυναμικό σύνολο διεπαφών} και νέες διεπαφές
|
||
μπορούν να δημιουργηθούν κατά την επίλυση των συνδέσμων.
|
||
Αντίθετα, όταν το πεδίο υπάρχει, ακόμη και αν είναι κενό, το σύνολο των διαθέσιμων διεπαφών θεωρείται
|
||
\emph{σταθερό}.
|
||
|
||
\subsubsection{Σύνδεσμοι και αυτόματη επιλογή διεπαφών}
|
||
|
||
Κάθε σύνδεσμος αποτελεί αυτοτελή οντότητα και συνδέει ακριβώς δύο endpoints.
|
||
Κάθε endpoint προσδιορίζει τον κόμβο στον οποίο ανήκει και τη λογική διεπαφή μέσω της οποίας πραγματοποιείται η
|
||
σύνδεση.
|
||
Η διεπαφή μπορεί να δηλωθεί ρητά ή να χρησιμοποιηθεί ο ειδικός επιλογέας \texttt{auto}.
|
||
|
||
Όταν χρησιμοποιείται το \texttt{auto} σε κόμβο με σταθερό σύνολο διεπαφών, επιλέγεται μία από τις δηλωμένες
|
||
διεπαφές που δεν έχει ήδη δεσμευτεί από άλλη σύνδεση.
|
||
Αν δεν υπάρχει ελεύθερη διεπαφή, η τοπολογία θεωρείται μη έγκυρη και \textbf{δεν δημιουργείται επιπλέον θύρα
|
||
σιωπηρά}.
|
||
Όταν αντίθετα το σύνολο διεπαφών έχει παραλειφθεί, το \texttt{auto} επιτρέπει τη δυναμική δημιουργία νέας λογικής
|
||
διεπαφής για τις ανάγκες του συνδέσμου.
|
||
|
||
Οι σύνδεσμοι μπορούν επίσης να περιλαμβάνουν παραμέτρους προσομοίωσης χαρακτηριστικών του φυσικού μέσου.
|
||
Η τρέχουσα γλώσσα υποστηρίζει περιορισμό εύρους ζώνης, καθυστέρηση, απώλεια πακέτων και jitter μέσω των πεδίων
|
||
\texttt{bandwidth\_mbps}, \texttt{delay\_ms}, \texttt{loss\_percent} και \texttt{jitter\_ms}.
|
||
|
||
\subsubsection{Ρυθμίσεις κόμβων και υπηρεσίες}
|
||
|
||
Οι ρυθμίσεις που αφορούν τη λειτουργία του ίδιου του κόμβου τοποθετούνται στο αντικείμενο \texttt{settings} του
|
||
αντίστοιχου node.
|
||
Για τον τύπο \texttt{router}, για παράδειγμα, υποστηρίζονται η ενεργοποίηση του IP forwarding και η
|
||
απενεργοποίηση του reverse path filtering.
|
||
Οι ιδιότητες αυτές αντιμετωπίζονται ως \emph{χαρακτηριστικά του network namespace} και όχι ως ανεξάρτητες
|
||
υπηρεσίες.
|
||
|
||
Οι υπηρεσίες μοντελοποιούνται ξεχωριστά επειδή αντιστοιχούν σε \textbf{διεργασίες που εκτελούνται πάνω σε έναν
|
||
κόμβο}.
|
||
Στην παρούσα εργασία υποστηρίζεται η υπηρεσία \texttt{dhcp-server}, η οποία συνδέεται με έναν κόμβο και μία από
|
||
τις διεπαφές του.
|
||
Οι παράμετροι της υπηρεσίας περιλαμβάνουν το εύρος διευθύνσεων που μπορούν να εκχωρηθούν και την προεπιλεγμένη
|
||
πύλη που διαφημίζεται στους DHCP clients.
|
||
|
||
Η θέση εκτέλεσης μιας υπηρεσίας και η διεπαφή στην οποία συνδέεται αποτελούν μέρος της ίδιας της ταυτότητάς της
|
||
και για τον λόγο αυτό δηλώνονται έξω από το αντικείμενο \texttt{settings}.
|
||
Με αυτόν τον διαχωρισμό, το \texttt{settings} περιγράφει αποκλειστικά τη συμπεριφορά της υπηρεσίας και όχι το
|
||
σημείο στο οποίο αυτή τοποθετείται μέσα στην τοπολογία.
|
||
|
||
\subsubsection{Αυστηρότητα της γραμματικής}
|
||
|
||
Η γραμματική σχεδιάστηκε ώστε να είναι \textbf{αυστηρή} και να μην αγνοεί άγνωστα πεδία ή μη υποστηριζόμενες
|
||
τιμές.
|
||
Ένα τυπογραφικό λάθος σε ένα όνομα ιδιότητας δεν αντιμετωπίζεται επομένως ως απουσία της ιδιότητας, αλλά ως
|
||
σφάλμα της περιγραφής.
|
||
Η επιλογή αυτή περιορίζει την πιθανότητα μία συντακτικά αποδεκτή αλλά διαφορετική από την επιθυμητή τοπολογία
|
||
να δημιουργηθεί χωρίς εμφανή προειδοποίηση.
|
||
|
||
Η γλώσσα διαχωρίζει επίσης τη \emph{δομική εγκυρότητα} μιας περιγραφής από τη \emph{σημασιολογική συνέπειά} της.
|
||
Ένα αντικείμενο μπορεί να ακολουθεί σωστά τη γραμματική αλλά να περιγράφει, για παράδειγμα, έναν σύνδεσμο προς
|
||
ανύπαρκτο κόμβο ή μία στατική πύλη εκτός του αντίστοιχου υποδικτύου.
|
||
Η διάκριση αυτή αξιοποιείται στη συνέχεια από την αρχιτεκτονική του builder, όπου η ανάλυση της γραμματικής και
|
||
ο σημασιολογικός έλεγχος πραγματοποιούνται σε \textbf{διαφορετικά στάδια}.
|
||
|
||
|
||
% ========================= Builder =========================
|
||
\subsection{Υλοποίηση του Builder}
|
||
|
||
Η υλοποίηση του builder ακολουθεί τον διαχωρισμό που εισάγει η DSL και οργανώνεται ως μία ακολουθία ανεξάρτητων
|
||
σταδίων, καθένα από τα οποία μετασχηματίζει την πληροφορία σε μία περισσότερο συγκεκριμένη αναπαράσταση.
|
||
Η δομή αυτή επιτρέπει τον σαφή διαχωρισμό ανάμεσα στην περιγραφή της τοπολογίας, στον έλεγχο της εγκυρότητάς της
|
||
και στην τελική δημιουργία και εκτέλεση του δικτύου στο Mininet.
|
||
|
||
\subsubsection{Δομή των αρχείων}
|
||
|
||
Ο πηγαίος κώδικας του builder βρίσκεται στον κατάλογο \texttt{source/}, ενώ η περιγραφή και τα αποτελέσματα της
|
||
συγκεκριμένης εργαστηριακής άσκησης διατηρούνται χωριστά στον κατάλογο \texttt{exercise/}.
|
||
Η βασική δομή του αποθετηρίου είναι η ακόλουθη:
|
||
|
||
\begin{verbatim}
|
||
.
|
||
|-- source/
|
||
| |-- build_network.py
|
||
| |-- topology_loader.py
|
||
| |-- topology_parser.py
|
||
| |-- topology_validator.py
|
||
| |-- topology_plan.py
|
||
| `-- topology_renderer.py
|
||
|
|
||
|-- exercise/
|
||
| |-- topology.json
|
||
| |-- topology.generated.py
|
||
| `-- results/
|
||
|
|
||
|-- Mininet_DSL_Design.md
|
||
`-- README.md
|
||
\end{verbatim}
|
||
|
||
\begin{itemize}
|
||
\item Το \texttt{topology\_loader.py} είναι υπεύθυνο αποκλειστικά για τη φόρτωση του αρχείου JSON από το σύστημα
|
||
αρχείων και την παραγωγή της αντίστοιχης ακατέργαστης Python δομής.
|
||
|
||
\item Το \texttt{topology\_parser.py} περιέχει τη γραμματική, τα \texttt{Enum} και τα \texttt{dataclass} αντικείμενα
|
||
που αποτελούν το τυποποιημένο σημασιολογικό μοντέλο της DSL.
|
||
|
||
\item Το \texttt{topology\_validator.py} ελέγχει τη σημασιολογική συνέπεια της τοπολογίας, χωρίς να πραγματοποιεί
|
||
οποιαδήποτε μεταβολή στο δίκτυο.
|
||
|
||
\item Το \texttt{topology\_plan.py} επιλύει τις αφηρημένες επιλογές της DSL και παράγει ένα πλήρως συγκεκριμένο
|
||
\texttt{ExecutionPlan}.
|
||
|
||
\item Το \texttt{topology\_renderer.py} μετατρέπει το σχέδιο αυτό σε εκτελέσιμο Python κώδικα για το Mininet, οποίος
|
||
εξάγεται σε ξεχωριστό αρχείο και αποτελεί ένα ιδιότυπο \emph{python-listing} του renderer.
|
||
|
||
\item Τέλος, το \texttt{build\_network.py} αποτελεί τον \textbf{coordinator} και το μοναδικό user-facing entry point,
|
||
συνδέοντας τα επιμέρους στάδια και αναλαμβάνοντας την τελική εκτέλεση του παραγόμενου προγράμματος.
|
||
\end{itemize}
|
||
|
||
|
||
\subsubsection{Χρήση}
|
||
|
||
Η κανονική χρήση του builder απαιτεί μόνο το αρχείο JSON που περιγράφει την επιθυμητή τοπολογία.
|
||
Για την τοπολογία της παρούσας εργασίας η πλήρης κατασκευή και εκτέλεση πραγματοποιείται με την εντολή:
|
||
|
||
\begin{minted}{bash}
|
||
sudo python3 source/build_network.py exercise/topology.json
|
||
\end{minted}
|
||
|
||
Η εκτέλεση αυτή μεταγλωττίζει πρώτα την τοπολογία, δημιουργεί το αρχείο
|
||
\texttt{exercise/topology.generated.py} και στη συνέχεια εκτελεί \textbf{το ίδιο ακριβώς παραγόμενο αρχείο}.
|
||
Μετά την κατασκευή και παραμετροποίηση του δικτύου ανοίγει το Mininet CLI, από το οποίο εκτελούνται τα πειράματα.
|
||
|
||
Κατά την ανάπτυξη είναι επίσης δυνατό να παραχθεί μόνο το ενδιάμεσο Python πρόγραμμα, χωρίς να δημιουργηθεί
|
||
κανένα network namespace ή άλλη κατάσταση στο σύστημα.
|
||
Για παράδειγμα:
|
||
|
||
\begin{minted}{bash}
|
||
python3 source/build_network.py exercise/topology.json --emit [Optional file name]
|
||
\end{minted}
|
||
|
||
Η μορφή αυτή δεν απαιτεί δικαιώματα root και είναι χρήσιμη για την επιθεώρηση του αποτελέσματος της
|
||
μεταγλώττισης ή για τον εντοπισμό σφαλμάτων πριν από την πραγματική εκτέλεση.
|
||
Το \texttt{--emit} μπορεί επιπλέον να δεχθεί συγκεκριμένο path για το παραγόμενο αρχείο.
|
||
|
||
Πριν από την εκτέλεση μπορεί επίσης να πραγματοποιηθεί έλεγχος του περιβάλλοντος με:
|
||
|
||
\begin{minted}{bash}
|
||
python3 source/build_network.py --env-check
|
||
\end{minted}
|
||
|
||
Ο έλεγχος επιβεβαιώνει την παρουσία του Mininet, του Open vSwitch και των εργαλείων Linux που απαιτούνται από
|
||
τον builder και τα πειράματα, όπως τα \texttt{ip}, \texttt{tc}, \texttt{sysctl}, \texttt{dnsmasq},
|
||
\texttt{dhclient}, \texttt{tcpdump} και \texttt{ping}.
|
||
Ο ίδιος έλεγχος πραγματοποιείται αυτόματα πριν από την πραγματική εκτέλεση μιας παραγόμενης τοπολογίας.
|
||
|
||
\subsubsection{Διαχωρισμός περιγραφής τοπολογίας και runtime κατάστασης}
|
||
|
||
Βασική σχεδιαστική επιλογή είναι ο \textbf{διαχωρισμός της δηλωμένης τοπολογίας από την κατάσταση που δημιουργείται
|
||
κατά την εκτέλεσή της}.
|
||
Το αρχείο JSON περιγράφει την επιθυμητή διαμόρφωση και τις πηγές από τις οποίες θα προκύψει η παραμετροποίηση,
|
||
χωρίς να επιχειρεί να αποθηκεύσει την παροδική κατάσταση ενός εκτελούμενου δικτύου.
|
||
|
||
Για παράδειγμα, η δήλωση:
|
||
|
||
\begin{minted}{json}
|
||
"net0": {
|
||
"addressing": "dhcp"
|
||
}
|
||
\end{minted}
|
||
|
||
δεν καθορίζει ποια διεύθυνση IP θα έχει τελικά ο host.
|
||
Δηλώνει ότι η διεύθυνση πρέπει να αποκτηθεί δυναμικά από μία υπηρεσία DHCP κατά την εκτέλεση της τοπολογίας.
|
||
Αντίστοιχα, ένας στατικός σύνδεσμος στο JSON οδηγεί στη δημιουργία πραγματικών virtual Ethernet interfaces,
|
||
χωρίς τα τελικά ονόματα αυτών των interfaces να χρειάζεται να εμφανίζονται στην αρχική περιγραφή.
|
||
|
||
Η ίδια διάκριση ισχύει για τις DHCP leases, τον ARP neighbor table, τους μετρητές πακέτων και τα αρχεία
|
||
\texttt{pcap}, τα οποία αποτελούν \emph{runtime state} και δεν ανήκουν στη δηλωτική γλώσσα.
|
||
Για τον ίδιο λόγο ο builder δεν εκκινεί αυτόματα το \texttt{dhclient} στους hosts που έχουν δηλωθεί ως DHCP
|
||
clients, καθώς η απόκτηση της διεύθυνσης αποτελεί μέρος της πειραματικής διαδικασίας της εργασίας.
|
||
|
||
Η αρχή αυτή αποτυπώνεται συνοπτικά ως:
|
||
|
||
\begin{verbatim}
|
||
Declarative topology Runtime state
|
||
|
||
static address -------> configured IP address
|
||
static gateway -------> routing-table entry
|
||
DHCP addressing -------> dynamically acquired lease
|
||
link declaration -------> veth / Mininet interfaces
|
||
service declaration -------> running process
|
||
ARP entries
|
||
packet captures
|
||
counters
|
||
\end{verbatim}
|
||
|
||
\subsubsection{Compiler-like αρχιτεκτονική}
|
||
|
||
Η εσωτερική αρχιτεκτονική του builder σχεδιάστηκε με λογική παρόμοια με αυτή ενός \textbf{μεταγλωττιστή}.
|
||
Αντί η εφαρμογή να διαβάζει ένα JSON και να καλεί άμεσα συναρτήσεις του Mininet, η περιγραφή περνά από
|
||
διαδοχικά στάδια, καθένα από τα οποία έχει σαφώς περιορισμένη ευθύνη.
|
||
|
||
Η συνολική ροή είναι:
|
||
|
||
\begin{verbatim}
|
||
topology.json
|
||
↓
|
||
[load]
|
||
↓
|
||
raw JSON dictionary
|
||
↓
|
||
[parse]
|
||
↓
|
||
typed Topology model
|
||
↓
|
||
[validate]
|
||
↓
|
||
validated Topology
|
||
↓
|
||
[plan]
|
||
↓
|
||
ExecutionPlan
|
||
↓
|
||
[render]
|
||
↓
|
||
topology.generated.py
|
||
↓
|
||
[execute]
|
||
↓
|
||
Mininet CLI
|
||
↓
|
||
[cleanup]
|
||
\end{verbatim}
|
||
|
||
Ο διαχωρισμός αυτός επιτρέπει σε κάθε στάδιο να εξετάζεται ανεξάρτητα και μεταφέρει σταδιακά την περιγραφή από
|
||
μία υψηλού επιπέδου δήλωση πρόθεσης σε μία πλήρως συγκεκριμένη ακολουθία ενεργειών Mininet και Linux.
|
||
Παράλληλα, κάθε κατηγορία σφάλματος ανήκει στο στάδιο που διαθέτει την απαραίτητη πληροφορία για να την εντοπίσει.
|
||
|
||
\paragraph{Φόρτωση -- \texttt{topology\_loader.py}.}
|
||
|
||
Το πρώτο στάδιο αφορά αποκλειστικά την πρόσβαση στο αρχείο και την ανάλυση της σύνταξης JSON.
|
||
Η δημόσια συνάρτηση \texttt{load\_topology()} διαβάζει το αρχείο και επιστρέφει ένα
|
||
\texttt{Dict[str, Any]}, χωρίς να γνωρίζει οτιδήποτε για τη σημασιολογία της DSL.
|
||
|
||
\begin{verbatim}
|
||
raw = load_topology("exercise/topology.json")
|
||
|
||
JSON file
|
||
|
|
||
`--> Dict[str, Any]
|
||
\end{verbatim}
|
||
|
||
Σφάλματα όπως ανύπαρκτο αρχείο, μη έγκυρο JSON ή root αντικείμενο διαφορετικό από JSON object αναφέρονται ως
|
||
\texttt{TopologyLoadError}.
|
||
Στο σημείο αυτό δεν εξετάζεται ακόμη αν ένα \texttt{type} είναι έγκυρο ή αν ένας σύνδεσμος αναφέρεται σε
|
||
υπαρκτό κόμβο.
|
||
|
||
\paragraph{Parsing -- \texttt{topology\_parser.py}.}
|
||
|
||
Το δεύτερο στάδιο μετατρέπει την ακατέργαστη δομή JSON στο \textbf{τυποποιημένο σημασιολογικό μοντέλο} της DSL.
|
||
Η δημόσια συνάρτηση \texttt{parse\_topology()} κατασκευάζει αντικείμενα όπως \texttt{Topology}, \texttt{Node},
|
||
\texttt{Interface}, \texttt{Link} και \texttt{Service}, χρησιμοποιώντας \texttt{Enum} για τα κλειστά σύνολα τιμών.
|
||
|
||
Για παράδειγμα, ένα τμήμα JSON όπως:
|
||
|
||
\begin{minted}{json}
|
||
{
|
||
"node": "s1",
|
||
"interface": "auto"
|
||
}
|
||
\end{minted}
|
||
|
||
δεν παραμένει ένα γενικό dictionary, αλλά μετατρέπεται εννοιολογικά σε:
|
||
|
||
\begin{minted}{python}
|
||
LinkEndpoint(
|
||
node="s1",
|
||
interface=LinkInterfaceSelector.AUTO
|
||
)
|
||
\end{minted}
|
||
|
||
Το στάδιο αυτό εφαρμόζει επίσης την \emph{αυστηρή γραμματική} της γλώσσας.
|
||
Άγνωστα πεδία ή μη υποστηριζόμενες τιμές προκαλούν \texttt{TopologyParseError}, αντί να αγνοούνται σιωπηρά.
|
||
|
||
\paragraph{Validation -- \texttt{topology\_validator.py}.}
|
||
|
||
Μετά το parsing η δομή είναι γραμματικά έγκυρη, αυτό όμως δεν συνεπάγεται ότι περιγράφει και συνεπές δίκτυο.
|
||
Η δημόσια συνάρτηση \texttt{validate()} πραγματοποιεί τους ελέγχους που απαιτούν γνώση περισσότερων από ενός
|
||
αντικειμένων της τοπολογίας.
|
||
|
||
Για παράδειγμα, το ακόλουθο JSON μπορεί να αναλυθεί συντακτικά, αλλά δεν περιγράφει έγκυρη στατική διεπαφή:
|
||
|
||
\begin{minted}{json}
|
||
"net0": {
|
||
"addressing": "static"
|
||
}
|
||
\end{minted}
|
||
|
||
Το validation θα απορρίψει τη συγκεκριμένη περιγραφή επειδή απουσιάζει η στατική διεύθυνση.
|
||
Αντίστοιχα ελέγχονται αναφορές σε ανύπαρκτους κόμβους, επαναχρησιμοποίηση interfaces, διευθύνσεις και gateways,
|
||
διαθεσιμότητα ports για \texttt{auto}, καθώς και η συνέπεια των ρυθμίσεων της υπηρεσίας DHCP.
|
||
|
||
Σε αντίθεση με ένα απλό fail-fast μοντέλο, ο validator συλλέγει τα προβλήματα σε αντικείμενα
|
||
\texttt{ValidationIssue} και τα επιστρέφει συγκεντρωτικά μέσω ενός \texttt{TopologyValidationError}.
|
||
Με αυτόν τον τρόπο ο χρήστης μπορεί να διορθώσει περισσότερα από ένα προβλήματα σε έναν κύκλο εκτέλεσης.
|
||
|
||
\paragraph{Planning -- \texttt{topology\_plan.py}.}
|
||
|
||
Το planning είναι το σημείο στο οποίο η έγκυρη πλέον περιγραφή μετατρέπεται σε μία
|
||
\textbf{πλήρως επιλυμένη ενδιάμεση αναπαράσταση}.
|
||
Η δημόσια συνάρτηση \texttt{plan()} παράγει ένα \texttt{ExecutionPlan}, στο οποίο δεν παραμένουν αφηρημένοι
|
||
selectors όπως \texttt{auto} ή άλλες αποφάσεις που πρέπει να ληφθούν από τον backend.
|
||
|
||
Για παράδειγμα, έστω ένας switch(node) με δύο ρητά δηλωμένες λογικές διεπαφές:
|
||
|
||
\begin{minted}{json}
|
||
{
|
||
"name": "s1",
|
||
"type": "switch",
|
||
"interfaces": {
|
||
"client": {},
|
||
"uplink": {}
|
||
}
|
||
}
|
||
\end{minted}
|
||
|
||
και δύο σύνδεσμοι, από τους οποίους ο πρώτος χρησιμοποιεί \texttt{auto}, ενώ ο δεύτερος ζητά ρητά τη διεπαφή
|
||
\texttt{uplink}:
|
||
|
||
\begin{minted}{json}
|
||
{
|
||
"endpoints": [
|
||
{"node": "h1", "interface": "net0"},
|
||
{"node": "s1", "interface": "auto"}
|
||
]
|
||
},
|
||
{
|
||
"endpoints": [
|
||
{"node": "r0", "interface": "lan"},
|
||
{"node": "s1", "interface": "uplink"}
|
||
]
|
||
}
|
||
\end{minted}
|
||
|
||
Πριν από την επίλυση των \texttt{auto}, ο planner εντοπίζει όλες τις ρητές αναφορές σε interfaces και δεσμεύει
|
||
τη \texttt{uplink}.
|
||
Το διαθέσιμο σύνολο διεπαφών του \texttt{s1} για αυτόματη επιλογή περιέχει επομένως μόνο τη \texttt{client}.
|
||
|
||
\begin{minted}{python}
|
||
reserved["s1"] = {"uplink"}
|
||
free_interfaces["s1"] = ["client"]
|
||
\end{minted}
|
||
|
||
Κατά το planning, το \texttt{auto} του πρώτου συνδέσμου επιλύεται συνεπώς στη λογική διεπαφή \texttt{client}.
|
||
Στο συγκεκριμένο παράδειγμα οι λογικές διεπαφές αντιστοιχίζονται στη συνέχεια και στα συγκεκριμένα ονόματα
|
||
διεπαφών που θα χρησιμοποιήσει το Mininet:
|
||
|
||
\begin{verbatim}
|
||
h1:net0 -> h1-eth0
|
||
s1:client -> s1-eth0
|
||
|
||
r0:lan -> r0-eth0
|
||
s1:uplink -> s1-eth1
|
||
\end{verbatim}
|
||
|
||
Με αυτόν τον τρόπο μία προηγούμενη αυτόματη επιλογή δεν μπορεί να καταλάβει interface που έχει ζητηθεί ρητά από
|
||
μεταγενέστερο link.
|
||
Το \texttt{auto} λειτουργεί επομένως ως \emph{επιλογέας διαθέσιμης λογικής διεπαφής} και όχι ως όνομα
|
||
διεπαφής.
|
||
|
||
Η συμπεριφορά είναι διαφορετική όταν το πεδίο \texttt{interfaces} έχει παραλειφθεί πλήρως από έναν κόμβο.
|
||
Σε αυτή την περίπτωση ο planner δημιουργεί συνθετικά λογικά ονόματα, όπως \texttt{auto0} και \texttt{auto1},
|
||
τα οποία αντιστοιχίζονται στη συνέχεια σε φυσικά ονόματα όπως \texttt{s1-eth0} και \texttt{s1-eth1}.
|
||
|
||
Στο ίδιο στάδιο αποφασίζονται και backend-specific λεπτομέρειες που δεν πρέπει να εμφανίζονται στη DSL.
|
||
Έτσι, η σημασιολογία ενός απλού Layer-2 switch μετατρέπεται από τον planner στην επιλογή
|
||
\texttt{switch\_fail\_mode = "standalone"} για το Open vSwitch.
|
||
|
||
Ένα απλοποιημένο τμήμα του \texttt{ExecutionPlan} για το προηγούμενο παράδειγμα μπορεί επομένως να θεωρηθεί ότι
|
||
έχει τη μορφή:
|
||
|
||
\begin{minted}{python}
|
||
PlannedLinkEndpoint(
|
||
node="s1",
|
||
logical_interface="client",
|
||
interface_name="s1-eth0"
|
||
)
|
||
|
||
PlannedLinkEndpoint(
|
||
node="s1",
|
||
logical_interface="uplink",
|
||
interface_name="s1-eth1"
|
||
)
|
||
|
||
PlannedNode(
|
||
name="s1",
|
||
type=NodeType.SWITCH,
|
||
switch_fail_mode="standalone"
|
||
)
|
||
\end{minted}
|
||
|
||
Ο planner δεν δημιουργεί interfaces και δεν τα εισάγει στο Mininet.
|
||
Η ευθύνη του τελειώνει όταν όλες οι αποφάσεις που απαιτούνται για την εκτέλεση έχουν αποτυπωθεί στο
|
||
\texttt{ExecutionPlan}.
|
||
|
||
\paragraph{Rendering -- \texttt{topology\_renderer.py}.}
|
||
|
||
Το renderer δέχεται το πλήρως επιλυμένο \texttt{ExecutionPlan} και το μετατρέπει σε ένα ολοκληρωμένο Python
|
||
πρόγραμμα μέσω της δημόσιας συνάρτησης \texttt{render\_python()}.
|
||
Σε αυτό το στάδιο \textbf{δεν πραγματοποιείται νέα σημασιολογική απόφαση}: ο renderer αποτυπώνει σε κώδικα τις
|
||
επιλογές που έχουν ήδη γίνει από τον planner.
|
||
|
||
Για το προηγούμενο παράδειγμα μπορούν να παραχθούν εντολές της μορφής:
|
||
|
||
\begin{minted}{python}
|
||
nodes['h1'] = net.addHost('h1', ip=None)
|
||
nodes['r0'] = net.addHost('r0', ip=None)
|
||
nodes['s1'] = net.addSwitch('s1', failMode='standalone')
|
||
|
||
net.addLink(
|
||
nodes['h1'],
|
||
nodes['s1'],
|
||
intfName1='h1-eth0',
|
||
intfName2='s1-eth0',
|
||
)
|
||
|
||
net.addLink(
|
||
nodes['r0'],
|
||
nodes['s1'],
|
||
intfName1='r0-eth0',
|
||
intfName2='s1-eth1',
|
||
)
|
||
\end{minted}
|
||
|
||
Παρατηρείται ότι στο παραγόμενο πρόγραμμα δεν υπάρχει πλέον ο selector \texttt{auto}.
|
||
Η επιλογή \texttt{s1:client} έχει ήδη πραγματοποιηθεί από τον planner και ο renderer γνωρίζει μόνο το πλήρως
|
||
επιλυμένο ζεύγος \texttt{s1:client} και \texttt{s1-eth0}.
|
||
|
||
Η χρήση του \texttt{ip=None} εμποδίζει το Mininet να εκχωρήσει τις δικές του προεπιλεγμένες διευθύνσεις στους
|
||
hosts, ώστε η διευθυνσιοδότηση να παραμένει αποκλειστικά υπό τον έλεγχο της DSL.
|
||
Ανάλογα με το σχέδιο, ο renderer παράγει επίσης εντολές για IP addresses, routes, sysctls, \texttt{TCLink} και
|
||
εκκίνηση του \texttt{dnsmasq}.
|
||
|
||
Το παραγόμενο πρόγραμμα περιλαμβάνει ακόμη το πλήρες lifecycle του δικτύου:
|
||
|
||
\begin{minted}{python}
|
||
net.build()
|
||
net.start()
|
||
|
||
# interface configuration
|
||
# routes
|
||
# sysctls
|
||
# services
|
||
|
||
CLI(net)
|
||
|
||
# finally:
|
||
# stop started services
|
||
# net.stop()
|
||
\end{minted}
|
||
|
||
\paragraph{Το παραγόμενο Python ως ενδιάμεση ``assembly''.}
|
||
|
||
Το αρχείο \texttt{topology.generated.py} έχει σκόπιμα κεντρικό ρόλο στην αρχιτεκτονική και δεν αποτελεί απλώς
|
||
ένα προσωρινό implementation detail.
|
||
Μπορεί να θεωρηθεί ως η \emph{``assembly'' της DSL}: είναι χαμηλότερου επιπέδου από το JSON, πλήρως συγκεκριμένο,
|
||
άμεσα εκτελέσιμο και ταυτόχρονα αρκετά αναγνώσιμο ώστε να μπορεί να επιθεωρηθεί από τον χρήστη.
|
||
|
||
Η αντιστοίχιση μπορεί να συνοψιστεί ως:
|
||
|
||
\begin{verbatim}
|
||
topology.json: declarative source
|
||
Topology: typed semantic representation
|
||
ExecutionPlan: resolved intermediate representation
|
||
topology.generated.py: executable "assembly"
|
||
Mininet / Linux: runtime
|
||
\end{verbatim}
|
||
|
||
Ο coordinator αποθηκεύει πάντοτε το παραγόμενο Python πριν από την εκτέλεση και στη συνέχεια εκτελεί ακριβώς
|
||
αυτό το αρχείο.
|
||
Δεν υπάρχει δεύτερος, ανεξάρτητος executor που να μεταφράζει απευθείας το \texttt{ExecutionPlan} σε Mininet
|
||
operations, αποφεύγοντας έτσι τον κίνδυνο διαφορετικής συμπεριφοράς μεταξύ του inspectable artifact και του
|
||
πραγματικού runtime.
|
||
|
||
\paragraph{Εκτέλεση και συντονισμός -- \texttt{build\_network.py}.}
|
||
|
||
Το \texttt{build\_network.py} συνθέτει τα προηγούμενα στάδια μέσω της συνάρτησης
|
||
\texttt{compile\_topology()}:
|
||
|
||
\begin{minted}{python}
|
||
topology = parse_topology(load_topology(path))
|
||
validate(topology)
|
||
execution_plan = plan(topology)
|
||
source = render_python(execution_plan)
|
||
\end{minted}
|
||
|
||
Το παραγόμενο source γράφεται στο \texttt{topology.generated.py} και, στην κανονική λειτουργία, εκτελείται ως
|
||
ξεχωριστό Python process με τα ίδια δικαιώματα με τον coordinator.
|
||
Η πραγματική εκτέλεση απαιτεί root privileges, ενώ η φόρτωση, το parsing, το validation, το planning και το
|
||
rendering μπορούν να πραγματοποιηθούν χωρίς αυτά.
|
||
|
||
Το generated πρόγραμμα δημιουργεί τους κόμβους και τα links, εφαρμόζει τη δικτυακή παραμετροποίηση, εκκινεί τις
|
||
προβλεπόμενες υπηρεσίες και παραδίδει τον έλεγχο στον χρήστη μέσω του Mininet CLI.
|
||
Η έξοδος από το CLI οδηγεί σε δομημένο cleanup μέσω \texttt{finally}, όπου τερματίζονται οι service processes που
|
||
ξεκίνησε το ίδιο το πρόγραμμα και στη συνέχεια καλείται το \texttt{net.stop()}.
|
||
|
||
\subsubsection{Έλεγχος των επιμέρους σταδίων}
|
||
|
||
Η ανεξαρτησία των σταδίων αξιοποιείται και κατά την ανάπτυξη και τον εντοπισμό σφαλμάτων.
|
||
Κάθε βασικό module του pipeline διαθέτει ένα μικρό \textbf{self-test του δημόσιου interface του}, το οποίο μπορεί
|
||
να εκτελεστεί χωρίς να δημιουργηθεί πραγματικό Mininet δίκτυο.
|
||
|
||
Για παράδειγμα:
|
||
|
||
\begin{minted}{bash}
|
||
python3 source/topology_loader.py
|
||
python3 source/topology_parser.py
|
||
python3 source/topology_validator.py
|
||
python3 source/topology_plan.py
|
||
python3 source/topology_renderer.py
|
||
\end{minted}
|
||
|
||
Μία επιτυχής εκτέλεση καταλήγει σε μήνυμα της μορφής:
|
||
|
||
\begin{verbatim}
|
||
topology_parser: self-test passed
|
||
\end{verbatim}
|
||
|
||
Τα tests δεν περιορίζονται στην απλή εισαγωγή των modules, αλλά ελέγχουν την κύρια συμπεριφορά του αντίστοιχου
|
||
δημόσιου API.
|
||
Ο parser, για παράδειγμα, ελέγχει τόσο σωστή μετατροπή σε typed objects όσο και απόρριψη άγνωστων πεδίων, ενώ ο
|
||
validator εξετάζει τόσο έγκυρες όσο και πολλαπλά λανθασμένες τοπολογίες.
|
||
|
||
Αντίστοιχα, ο planner ελέγχει την επίλυση του \texttt{auto}, την παραγωγή των physical interface names, την
|
||
επιλογή \texttt{standalone} για τους switches και την παραγωγή των απαιτούμενων sysctls.
|
||
Ο renderer ελέγχει ότι το παραγόμενο source είναι συντακτικά έγκυρο Python και ότι περιλαμβάνει τις αναμενόμενες
|
||
κλήσεις Mininet, τις υπηρεσίες και το cleanup.
|
||
|
||
Ο διαχωρισμός αυτός αποδείχθηκε ιδιαίτερα χρήσιμος κατά την ανάπτυξη, καθώς ένα σφάλμα μπορεί να απομονωθεί στο
|
||
στάδιο στο οποίο εμφανίζεται, χωρίς να απαιτείται κάθε φορά εκκίνηση του Mininet με δικαιώματα root.
|
||
Το \texttt{--emit} συμπληρώνει αυτή τη διαδικασία, επιτρέποντας την επιθεώρηση της τελικής
|
||
\emph{``assembly''} πριν από οποιαδήποτε μεταβολή της πραγματικής δικτυακής κατάστασης του συστήματος.
|
||
|
||
|
||
|
||
% ========================= Πείραμα 1 =========================
|
||
|
||
\section{Πείραμα 1 -- DHCP και διαδικασία D.O.R.A.}
|
||
|
||
\subsection{Σκοπός και πειραματική διαδικασία}
|
||
|
||
Σκοπός του πρώτου πειράματος είναι η παρατήρηση της διαδικασίας μέσω της οποίας ένας host χωρίς στατική
|
||
διευθυνσιοδότηση αποκτά τις απαραίτητες ρυθμίσεις δικτύου από έναν DHCP server.
|
||
Ειδικότερα, εξετάζεται η ακολουθία \textbf{Discover--Offer--Request--ACK (D.O.R.A.)} και τα αντίστοιχα πεδία των
|
||
Ethernet, IP και UDP headers.
|
||
|
||
Η τοπολογία εκκινήθηκε από τον κατάλογο \texttt{exercise/} με την εντολή:
|
||
|
||
\begin{minted}{bash}
|
||
sudo python3 ../source/build_network.py topology.json
|
||
\end{minted}
|
||
|
||
Πριν από την καταγραφή αφαιρέθηκε το αποθηκευμένο lease του \texttt{dhclient}, ώστε ο \texttt{h1} να ξεκινήσει
|
||
τη διαδικασία χωρίς να επιχειρήσει να επαναχρησιμοποιήσει διεύθυνση από προηγούμενη εκτέλεση.
|
||
Αφαιρέθηκε επίσης τυχόν προηγούμενο αρχείο καταγραφής και στη συνέχεια ξεκίνησε το \texttt{tcpdump} στη διεπαφή
|
||
\texttt{h1-eth0}.
|
||
|
||
Οι εντολές που εκτελέστηκαν στο Mininet CLI ήταν:
|
||
|
||
\begin{minted}{bash}
|
||
minted> h1 rm -f /var/lib/dhcp/dhclient.leases
|
||
minted> h1 rm -f /tmp/dhcp.pcap
|
||
minted> h1 tcpdump -i h1-eth0 -n -w /tmp/dhcp.pcap &
|
||
minted> h1 ps aux | grep tcpdump
|
||
minted> h1 dhclient h1-eth0
|
||
minted> h1 pkill -INT tcpdump
|
||
minted> h1 tcpdump -n -e -vv -r /tmp/dhcp.pcap
|
||
\end{minted}
|
||
|
||
Η επιλογή \texttt{-e} κατά την ανάγνωση της καταγραφής επιτρέπει την εμφάνιση των Ethernet headers και επομένως
|
||
των MAC διευθύνσεων που απαιτούνται για την ανάλυση.
|
||
Η καταγραφή ολοκληρώθηκε χωρίς απώλειες από το \texttt{tcpdump}, με 12 πακέτα να έχουν καταγραφεί συνολικά.
|
||
|
||
Η πλήρης συνεδρία της εκτέλεσης βρίσκεται στο \href{\dhcpExecutionUrl}{\texttt{execution.txt}}.
|
||
Το αρχικό αρχείο καταγραφής διατίθεται στο \href{\dhcpPcapUrl}{\texttt{dhcp.pcap}}, ενώ η αναλυτικά
|
||
αποκωδικοποιημένη μορφή του βρίσκεται στο \href{\dhcpDecodedUrl}{\texttt{dhcp-decoded.txt}}.
|
||
|
||
\subsection{Αποτελέσματα καταγραφής -- Ζητούμενο 1.1}
|
||
|
||
Η καταγραφή περιλαμβάνει την αναμενόμενη ακολουθία
|
||
\textbf{Discover $\rightarrow$ Offer $\rightarrow$ Request $\rightarrow$ ACK}, η οποία ολοκληρώθηκε επιτυχώς.
|
||
Στην πραγματική εκτέλεση καταγράφηκαν δύο DHCP Discover με το ίδιο transaction ID πριν από το πρώτο Offer.
|
||
|
||
Η χρονική ακολουθία των σχετικών DHCP μηνυμάτων ήταν:
|
||
|
||
\begin{verbatim}
|
||
10:58:29.655251 DHCP Discover
|
||
10:58:32.214530 DHCP Discover
|
||
10:58:32.670897 DHCP Offer
|
||
10:58:32.671193 DHCP Request
|
||
10:58:32.673025 DHCP ACK
|
||
10:58:32.678132 DHCP Offer
|
||
\end{verbatim}
|
||
|
||
Μεταξύ του πρώτου Discover και του πρώτου Offer παρατηρήθηκαν τρία ARP probes από τον DHCP server για τη
|
||
διεύθυνση \texttt{192.168.1.131} και στη συνέχεια ένα ICMP Echo Request προς την ίδια διεύθυνση.
|
||
Ο έλεγχος αυτός εισήγαγε καθυστέρηση στην πρώτη απάντηση του server, με αποτέλεσμα ο \texttt{dhclient} να
|
||
επαναμεταδώσει το Discover περίπου τρία δευτερόλεπτα μετά το πρώτο.
|
||
|
||
Και τα δύο Discover χρησιμοποιούν το ίδιο transaction ID, \texttt{0x0ecb5a2e}, επομένως αποτελούν μέρος της
|
||
ίδιας προσπάθειας απόκτησης διεύθυνσης και όχι δύο ανεξάρτητες διαδικασίες DHCP.
|
||
Παρά την επαναμετάδοση, η διαδικασία ολοκληρώθηκε κανονικά με Offer, Request και ACK και ο \texttt{h1} έλαβε τη
|
||
διεύθυνση \texttt{192.168.1.131}.
|
||
Μετά το ACK καταγράφηκε ακόμη ένα Offer, χωρίς αυτό να επηρεάζει την ήδη ολοκληρωμένη παραχώρηση της διεύθυνσης.
|
||
|
||
Η βασική τετράδα D.O.R.A. δίνει τα ακόλουθα στοιχεία:
|
||
|
||
\begin{table}[H]
|
||
\centering
|
||
\small
|
||
\begin{tabularx}{\textwidth}{
|
||
>{\raggedright\arraybackslash}p{1.3cm}
|
||
>{\raggedright\arraybackslash}p{5.2cm}
|
||
>{\raggedright\arraybackslash}p{2.0cm}
|
||
>{\raggedright\arraybackslash}X
|
||
}
|
||
\textbf{Μήνυμα} &
|
||
\textbf{IP} &
|
||
\textbf{UDP port} &
|
||
\textbf{MAC} \\ \hline
|
||
|
||
% \textbf{Μήνυμα} &
|
||
% \textbf{από $\rightarrow$ προς} &
|
||
% \textbf{UDP port από $\rightarrow$ προς} &
|
||
% \textbf{MAC από $\rightarrow$ προς} \\ \hline
|
||
|
||
Discover &
|
||
\texttt{0.0.0.0 $\rightarrow$ 255.255.255.255} &
|
||
\texttt{68 $\rightarrow$ 67} &
|
||
\texttt{12:07:f8:bf:6e:ff $\rightarrow$ ff:ff:ff:ff:ff:ff} \\
|
||
|
||
Offer &
|
||
\texttt{192.168.1.1 $\rightarrow$ 192.168.1.131} &
|
||
\texttt{67 $\rightarrow$ 68} &
|
||
\texttt{82:3b:16:e9:bb:17 $\rightarrow$ 12:07:f8:bf:6e:ff} \\
|
||
|
||
Request &
|
||
\texttt{0.0.0.0 $\rightarrow$ 255.255.255.255} &
|
||
\texttt{68 $\rightarrow$ 67} &
|
||
\texttt{12:07:f8:bf:6e:ff $\rightarrow$ ff:ff:ff:ff:ff:ff} \\
|
||
|
||
ACK &
|
||
\texttt{192.168.1.1 $\rightarrow$ 192.168.1.131} &
|
||
\texttt{67 $\rightarrow$ 68} &
|
||
\texttt{82:3b:16:e9:bb:17 $\rightarrow$ 12:07:f8:bf:6e:ff} \\
|
||
\end{tabularx}
|
||
\caption{Διευθύνσεις και UDP θύρες των μηνυμάτων της διαδικασίας D.O.R.A.}
|
||
\end{table}
|
||
|
||
\subsection{Ανάλυση της διαδικασίας D.O.R.A.}
|
||
|
||
Στο \textbf{Discover} ο \texttt{h1} δεν διαθέτει ακόμη διεύθυνση IPv4 και αναζητά διαθέσιμο DHCP server στο
|
||
τοπικό δίκτυο.
|
||
Για τον λόγο αυτό χρησιμοποιεί ως source IP την \texttt{0.0.0.0} και μεταδίδει το μήνυμα προς την περιορισμένη
|
||
broadcast διεύθυνση \texttt{255.255.255.255}, με Ethernet destination \texttt{ff:ff:ff:ff:ff:ff}.
|
||
|
||
Στο \textbf{Offer} ο DHCP server του \texttt{r0}, με διεύθυνση \texttt{192.168.1.1}, προσφέρει στον client τη
|
||
διεύθυνση \texttt{192.168.1.131}.
|
||
Στο ίδιο μήνυμα περιλαμβάνονται επίσης η μάσκα \texttt{255.255.255.0}, η broadcast διεύθυνση
|
||
\texttt{192.168.1.255} και η προεπιλεγμένη πύλη \texttt{192.168.1.1}.
|
||
|
||
Ο \texttt{h1} απαντά με \textbf{Request}, στο οποίο δηλώνει τόσο τον server που επέλεξε όσο και τη διεύθυνση που
|
||
ζητά να του εκχωρηθεί.
|
||
Τα αντίστοιχα options που καταγράφηκαν είναι:
|
||
|
||
\begin{minted}{text}
|
||
Server-ID Option: 192.168.1.1
|
||
Requested-IP Option: 192.168.1.131
|
||
\end{minted}
|
||
|
||
Τέλος, με το \textbf{ACK} ο server επιβεβαιώνει την παραχώρηση της \texttt{192.168.1.131} και αποστέλλει τις
|
||
τελικές παραμέτρους του lease.
|
||
Στην καταγραφή το lease time είναι \texttt{43200} δευτερόλεπτα και η προεπιλεγμένη πύλη που παρέχεται στον
|
||
client είναι η \texttt{192.168.1.1}.
|
||
|
||
\subsection{Broadcast μετάδοση του DHCP Request -- Ζητούμενο 1.2}
|
||
|
||
Το DHCP Request της αρχικής διαδικασίας απόκτησης διεύθυνσης μεταδόθηκε ως \textbf{broadcast} τόσο στο επίπεδο
|
||
Ethernet όσο και στο επίπεδο IP.
|
||
Στην καταγραφή παρατηρούνται συγκεκριμένα:
|
||
|
||
\begin{minted}{text}
|
||
Ethernet destination: ff:ff:ff:ff:ff:ff
|
||
IP destination: 255.255.255.255
|
||
UDP ports: 68 -> 67
|
||
\end{minted}
|
||
|
||
Κατά τη στιγμή αποστολής του Request η παραχώρηση της διεύθυνσης δεν έχει ακόμη ολοκληρωθεί και ο client
|
||
συνεχίζει να χρησιμοποιεί την \texttt{0.0.0.0} ως source IP.
|
||
Η broadcast μετάδοση επιτρέπει επιπλέον σε όλους τους DHCP servers του τοπικού δικτύου να παρατηρήσουν ποια
|
||
προσφορά επέλεξε ο client.
|
||
|
||
Ο επιλεγμένος server αναγνωρίζεται από το \texttt{Server-ID} του Request, ενώ τυχόν άλλοι servers μπορούν να
|
||
διαπιστώσουν ότι οι δικές τους προσφορές δεν επιλέχθηκαν.
|
||
Το ACK του \texttt{192.168.1.1} ολοκληρώνει τελικά τη διαδικασία και επιβεβαιώνει ότι η
|
||
\texttt{192.168.1.131} μπορεί πλέον να χρησιμοποιηθεί από τον \texttt{h1}.
|
||
|
||
|
||
|
||
% ========================= Πείραμα 2 =========================
|
||
|
||
\section{Πείραμα 2 -- Πρωτόκολλο ARP}
|
||
|
||
\subsection{Σκοπός και πειραματική διαδικασία}
|
||
|
||
Σκοπός του δεύτερου πειράματος είναι η παρατήρηση της διαδικασίας αντιστοίχισης μιας γνωστής διεύθυνσης IPv4
|
||
στην αντίστοιχη διεύθυνση MAC μέσω του πρωτοκόλλου \textbf{ARP}.
|
||
Ειδικότερα, εξετάζεται η αρχική επίλυση της διεύθυνσης του \texttt{h2} από τον \texttt{h1} και η διαφορετική
|
||
μορφή μετάδοσης του ARP Request και του ARP Reply.
|
||
|
||
Η τοπολογία εκκινήθηκε εκ νέου και οι δύο hosts του Subnet A απέκτησαν διευθύνσεις μέσω DHCP.
|
||
Οι διευθύνσεις που εκχωρήθηκαν κατά τη συγκεκριμένη εκτέλεση ήταν:
|
||
\begin{itemize}
|
||
\item \texttt{\textbf{192.168.1.131/24}} για τον \texttt{\textbf{h1}} και
|
||
\item \texttt{\textbf{192.168.1.164/24}} για τον \texttt{\textbf{h2}}.
|
||
\end{itemize}
|
||
|
||
Οι αρχικές εντολές της εκτέλεσης ήταν:
|
||
|
||
\begin{minted}{bash}
|
||
sudo python3 ../source/build_network.py topology.json
|
||
|
||
minted> h1 ip -4 -br addr
|
||
minted> h2 ip -4 -br addr
|
||
minted> h1 dhclient h1-eth0
|
||
minted> h2 dhclient h2-eth0
|
||
minted> h1 ip -4 -br addr
|
||
minted> h2 ip -4 -br addr
|
||
\end{minted}
|
||
|
||
Πριν από το ping διαγράφηκε ο neighbor table του \texttt{h1}, ώστε να μην υπάρχει ήδη γνωστή αντιστοίχιση
|
||
μεταξύ της IP και της MAC διεύθυνσης του \texttt{h2}.
|
||
Η κενή κατάσταση του πίνακα επιβεβαιώθηκε με την εντολή \texttt{ip neigh show}.
|
||
|
||
\begin{minted}{bash}
|
||
minted> h1 ip neigh flush all
|
||
minted> h1 ip neigh show
|
||
minted> h1 rm -f /tmp/arp.pcap
|
||
minted> h1 tcpdump -i h1-eth0 -n arp -w /tmp/arp.pcap &
|
||
minted> h1 ping -c 1 192.168.1.164
|
||
minted> h1 ip neigh show
|
||
minted> h1 pkill -INT tcpdump
|
||
minted> h1 tcpdump -n -e -vv -r /tmp/arp.pcap
|
||
\end{minted}
|
||
|
||
Το φίλτρο \texttt{arp} του \texttt{tcpdump} περιορίζει την καταγραφή στα ARP frames, ενώ η επιλογή \texttt{-e}
|
||
κατά την ανάγνωση εμφανίζει τα Ethernet headers και επομένως τις MAC διευθύνσεις πηγής και προορισμού.
|
||
Η καταγραφή ολοκληρώθηκε χωρίς απώλειες, με τέσσερα ARP frames να έχουν καταγραφεί συνολικά.
|
||
|
||
Η πλήρης συνεδρία της εκτέλεσης βρίσκεται στο \href{\arpExecutionUrl}{\texttt{execution.txt}}.
|
||
Το αρχικό αρχείο καταγραφής διατίθεται στο \href{\arpPcapUrl}{\texttt{arp.pcap}}, ενώ η αποκωδικοποιημένη μορφή του βρίσκεται στο
|
||
\href{\arpDecodedUrl}{\texttt{arp-decoded.txt}}.
|
||
|
||
\subsection{Αποτελέσματα καταγραφής}
|
||
|
||
Μετά την εκκαθάριση του neighbor table, το πρώτο ping από τον \texttt{h1} προς τον \texttt{h2} απαίτησε την
|
||
επίλυση της MAC διεύθυνσης που αντιστοιχεί στην \texttt{192.168.1.164}.
|
||
Το πρώτο ζεύγος πακέτων της καταγραφής ήταν:
|
||
|
||
\begin{minted}{text}
|
||
4a:6f:2a:18:f4:80 > ff:ff:ff:ff:ff:ff
|
||
Request who-has 192.168.1.164 tell 192.168.1.131
|
||
|
||
82:c0:6d:ae:3f:56 > 4a:6f:2a:18:f4:80
|
||
Reply 192.168.1.164 is-at 82:c0:6d:ae:3f:56
|
||
\end{minted}
|
||
|
||
Από την καταγραφή προκύπτει επομένως ότι στη συγκεκριμένη εκτέλεση οι δύο hosts είχαν τα ακόλουθα στοιχεία:
|
||
|
||
\begin{table}[H]
|
||
\centering
|
||
\begin{tabular}{lll}
|
||
\textbf{Host} & \textbf{IPv4} & \textbf{MAC} \\ \hline
|
||
\texttt{h1} & \texttt{192.168.1.131} & \texttt{4a:6f:2a:18:f4:80} \\
|
||
\texttt{h2} & \texttt{192.168.1.164} & \texttt{82:c0:6d:ae:3f:56} \\
|
||
\end{tabular}
|
||
\caption{Διευθύνσεις των hosts που συμμετέχουν στο πείραμα ARP.}
|
||
\end{table}
|
||
|
||
Το ping ολοκληρώθηκε επιτυχώς και, μετά την ανταλλαγή ARP, ο neighbor table του \texttt{h1} περιείχε (λογικά) την
|
||
αντιστοίχιση:
|
||
|
||
\begin{minted}{text}
|
||
192.168.1.164 dev h1-eth0 lladdr 82:c0:6d:ae:3f:56 REACHABLE
|
||
\end{minted}
|
||
|
||
Το αποτέλεσμα αυτό επιβεβαιώνει ότι ο \texttt{h1} έμαθε τη MAC διεύθυνση του \texttt{h2} μέσω της προηγούμενης
|
||
ανταλλαγής ARP και μπορεί πλέον να δημιουργεί απευθείας Ethernet frames προς αυτόν.
|
||
|
||
\subsection{Ανάλυση του ARP Request και Reply -- Ζητούμενο 2.1}
|
||
|
||
Κατά την αποστολή του αρχικού ARP Request ο \texttt{h1} γνωρίζει τη διεύθυνση IP του προορισμού, αλλά
|
||
\textbf{δεν γνωρίζει ακόμη τη MAC διεύθυνσή του}.
|
||
Δεν μπορεί επομένως να δημιουργήσει ένα unicast Ethernet frame προς τον \texttt{h2}.
|
||
|
||
Για τον λόγο αυτό το ARP Request μεταδίδεται προς την Ethernet broadcast διεύθυνση:
|
||
|
||
\begin{minted}{text}
|
||
Source MAC: 4a:6f:2a:18:f4:80
|
||
Destination MAC: ff:ff:ff:ff:ff:ff
|
||
|
||
Who has 192.168.1.164?
|
||
Tell 192.168.1.131
|
||
\end{minted}
|
||
|
||
Όλοι οι κόμβοι του ίδιου Layer-2 broadcast domain μπορούν να λάβουν το Request, αλλά μόνο ο host στον οποίο
|
||
ανήκει η \texttt{192.168.1.164} πρέπει να απαντήσει.
|
||
Στην συγκεκριμένη περίπτωση ο host αυτός είναι ο \texttt{h2}.
|
||
|
||
Το ARP Reply, αντίθετα, μεταδίδεται ως \textbf{unicast}:
|
||
|
||
\begin{minted}{text}
|
||
Source MAC: 82:c0:6d:ae:3f:56
|
||
Destination MAC: 4a:6f:2a:18:f4:80
|
||
|
||
192.168.1.164 is-at 82:c0:6d:ae:3f:56
|
||
\end{minted}
|
||
|
||
Ο \texttt{h2} μπορεί να στείλει την απάντηση απευθείας στον \texttt{h1}, επειδή το ARP Request περιλαμβάνει τα
|
||
στοιχεία του αποστολέα και επομένως παρέχει στον \texttt{h2} τη MAC διεύθυνση στην οποία πρέπει να απαντήσει.
|
||
Δεν υπάρχει συνεπώς ανάγκη το Reply να μεταδοθεί σε όλους τους κόμβους του broadcast domain.
|
||
|
||
\textbf{Η MAC προορισμού του αρχικού ARP Request είναι επομένως \texttt{ff:ff:ff:ff:ff:ff},
|
||
ενώ το ARP Reply επιστρέφει ως unicast στη MAC \texttt{4a:6f:2a:18:f4:80} του \texttt{h1}.}
|
||
|
||
\subsection{Πρόσθετη παρατήρηση}
|
||
|
||
Στην καταγραφή εμφανίστηκε περίπου πέντε δευτερόλεπτα αργότερα και ένα δεύτερο ζεύγος ARP Request/Reply προς
|
||
την αντίθετη κατεύθυνση:
|
||
|
||
\begin{minted}{text}
|
||
82:c0:6d:ae:3f:56 > 4a:6f:2a:18:f4:80
|
||
Request who-has 192.168.1.131 tell 192.168.1.164
|
||
|
||
4a:6f:2a:18:f4:80 > 82:c0:6d:ae:3f:56
|
||
Reply 192.168.1.131 is-at 4a:6f:2a:18:f4:80
|
||
\end{minted}
|
||
|
||
Σε αντίθεση με το αρχικό Request, το δεύτερο Request έχει ήδη ως Ethernet destination τη MAC του
|
||
\texttt{h1} και επομένως είναι unicast.
|
||
Η ανταλλαγή αυτή σχετίζεται με τη διαχείριση και επιβεβαίωση της κατάστασης του neighbor cache από το Linux και
|
||
δεν αποτελεί την αρχική επίλυση που προκαλεί το ping.
|
||
|
||
Για το ζητούμενο του πειράματος εξετάζεται συνεπώς το \textbf{πρώτο ζεύγος Request/Reply}, στο οποίο φαίνεται
|
||
καθαρά η μετάβαση από broadcast αναζήτηση σε unicast απάντηση.
|
||
Παρόλα αυτά το γεγονός ότι υπήρχε δεύτερο ζεύγος μας προβλημάτισε ιδιαίτερα μέχρι να ανακαλύψουμε τον λόγο ύπαρξής του!
|
||
|
||
|
||
% ========================= Πείραμα 3 =========================
|
||
|
||
\section{Πείραμα 3 -- Δρομολόγηση L3 και αλλαγή MAC}
|
||
|
||
\subsection{Σκοπός και πειραματική διαδικασία}
|
||
|
||
Σκοπός του τρίτου πειράματος είναι η παρατήρηση της προώθησης ενός IP πακέτου μεταξύ δύο διαφορετικών
|
||
υποδικτύων μέσω του δρομολογητή \texttt{r0}.
|
||
Ειδικότερα, εξετάζεται ο τρόπος με τον οποίο ο \texttt{h1} αποφασίζει ότι ο \texttt{h3} βρίσκεται σε διαφορετικό
|
||
υποδίκτυο, καθώς και οι μεταβολές των MAC διευθύνσεων και του TTL κατά τη διέλευση από τον router.
|
||
|
||
Το πείραμα εκτελέστηκε στην ήδη ενεργή τοπολογία, στην οποία ο \texttt{h1} είχε αποκτήσει μέσω DHCP τη διεύθυνση
|
||
\texttt{192.168.1.131/24}, ενώ ο \texttt{h3} χρησιμοποιούσε τη στατική διεύθυνση
|
||
\texttt{192.168.2.10/24}.
|
||
Πριν από την καταγραφή εκκαθαρίστηκαν οι neighbor tables των δύο hosts και του router, ώστε να απομακρυνθεί
|
||
προϋπάρχουσα κατάσταση ARP.
|
||
|
||
Οι πρώτες εντολές της εκτέλεσης ήταν:
|
||
|
||
\begin{minted}{bash}
|
||
mininet> h1 ip neigh flush all
|
||
mininet> h3 ip neigh flush all
|
||
mininet> r0 ip neigh flush all
|
||
|
||
mininet> h1 ip -4 -br addr
|
||
mininet> h1 ip route
|
||
|
||
mininet> r0 ip -4 -br addr
|
||
mininet> r0 ip route
|
||
|
||
mininet> h3 ip -4 -br addr
|
||
mininet> h3 ip route
|
||
\end{minted}
|
||
|
||
Η κατάσταση διευθυνσιοδότησης και δρομολόγησης που επιβεβαιώθηκε ήταν:
|
||
|
||
\begin{minted}{text}
|
||
h1:
|
||
192.168.1.131/24
|
||
default via 192.168.1.1 dev h1-eth0
|
||
|
||
r0:
|
||
r0-eth0: 192.168.1.1/24
|
||
r0-eth1: 192.168.2.1/24
|
||
|
||
h3:
|
||
192.168.2.10/24
|
||
default via 192.168.2.1 dev h3-eth0
|
||
\end{minted}
|
||
|
||
Στη συνέχεια ξεκίνησαν \textbf{δύο ταυτόχρονες καταγραφές ICMP}, μία στο Subnet A μέσω του \texttt{h1} και μία
|
||
στο Subnet B μέσω του \texttt{h3}.
|
||
Έτσι, το ίδιο ICMP Echo Request μπορούσε να παρατηρηθεί πριν και μετά την προώθησή του από τον \texttt{r0}.
|
||
|
||
\begin{minted}{bash}
|
||
mininet> h1 rm -f /tmp/icmp-A.pcap
|
||
mininet> h3 rm -f /tmp/icmp-B.pcap
|
||
|
||
mininet> h1 tcpdump -i h1-eth0 -n icmp -w /tmp/icmp-A.pcap &
|
||
mininet> h3 tcpdump -i h3-eth0 -n icmp -w /tmp/icmp-B.pcap &
|
||
|
||
mininet> h1 ps aux | grep tcpdump
|
||
mininet> h3 ps aux | grep tcpdump
|
||
|
||
mininet> h1 ping -c 1 192.168.2.10
|
||
|
||
mininet> h1 pkill -INT tcpdump
|
||
mininet> h3 pkill -INT tcpdump
|
||
\end{minted}
|
||
|
||
Το ping ολοκληρώθηκε επιτυχώς:
|
||
|
||
\begin{minted}{text}
|
||
64 bytes from 192.168.2.10: icmp_seq=1 ttl=63 time=1.66 ms
|
||
|
||
1 packets transmitted, 1 received, 0% packet loss
|
||
\end{minted}
|
||
|
||
Μετά την καταγραφή εμφανίστηκαν οι MAC διευθύνσεις των τεσσάρων interfaces που συμμετέχουν στη διαδρομή και
|
||
διαβάστηκαν τα δύο αρχεία \texttt{pcap} με εμφάνιση των Ethernet headers:
|
||
|
||
\begin{minted}{bash}
|
||
mininet> h1 ip link show h1-eth0
|
||
mininet> h3 ip link show h3-eth0
|
||
mininet> r0 ip link show r0-eth0
|
||
mininet> r0 ip link show r0-eth1
|
||
|
||
mininet> h1 tcpdump -n -e -vv -r /tmp/icmp-A.pcap
|
||
mininet> h3 tcpdump -n -e -vv -r /tmp/icmp-B.pcap
|
||
\end{minted}
|
||
|
||
Η πλήρης συνεδρία της εκτέλεσης βρίσκεται στο \href{\routingExecutionUrl}{\texttt{execution.txt}}.
|
||
Οι αρχικές καταγραφές διατίθενται στα \href{\icmpAPcapUrl}{\texttt{icmp-A.pcap}} και
|
||
\href{\icmpBPcapUrl}{\texttt{icmp-B.pcap}}, ενώ οι αποκωδικοποιημένες μορφές τους βρίσκονται στα
|
||
\href{\icmpADecodedUrl}{\texttt{icmp-A-decoded.txt}} και \href{\icmpBDecodedUrl}{\texttt{icmp-B-decoded.txt}}.
|
||
|
||
\subsection{Απόφαση δρομολόγησης μέσω bitwise AND -- Ζητούμενο 3.1}
|
||
|
||
Ο \texttt{h1} πρέπει αρχικά να αποφασίσει αν η διεύθυνση προορισμού \texttt{192.168.2.10} ανήκει στο ίδιο
|
||
υποδίκτυο με τη δική του διεύθυνση \texttt{192.168.1.131/24}.
|
||
Για τον σκοπό αυτό εφαρμόζεται bitwise AND μεταξύ κάθε διεύθυνσης και της μάσκας
|
||
\texttt{255.255.255.0}.
|
||
|
||
Για τη διεύθυνση του \texttt{h1} προκύπτει:
|
||
|
||
\[
|
||
192.168.1.131
|
||
\mathbin{\&}
|
||
255.255.255.0
|
||
=
|
||
192.168.1.0
|
||
\]
|
||
|
||
ενώ για τη διεύθυνση προορισμού:
|
||
|
||
\[
|
||
192.168.2.10
|
||
\mathbin{\&}
|
||
255.255.255.0
|
||
=
|
||
192.168.2.0
|
||
\]
|
||
|
||
Η διαφορά φαίνεται ήδη στο τρίτο octet:
|
||
|
||
\begin{minted}{text}
|
||
h1:
|
||
00000001
|
||
AND 11111111
|
||
= 00000001
|
||
|
||
h3:
|
||
00000010
|
||
AND 11111111
|
||
= 00000010
|
||
\end{minted}
|
||
|
||
Εφόσον \texttt{192.168.1.0} και \texttt{192.168.2.0} είναι διαφορετικές network addresses, ο \texttt{h1}
|
||
συμπεραίνει ότι ο προορισμός \textbf{δεν βρίσκεται στο τοπικό του subnet}.
|
||
Συμβουλεύεται επομένως τον πίνακα δρομολόγησης και χρησιμοποιεί την προεπιλεγμένη διαδρομή:
|
||
|
||
\begin{minted}{text}
|
||
default via 192.168.1.1 dev h1-eth0
|
||
\end{minted}
|
||
|
||
Το IP packet εξακολουθεί να έχει ως τελικό προορισμό την \texttt{192.168.2.10}, αλλά το Ethernet frame που
|
||
δημιουργεί ο \texttt{h1} αποστέλλεται στη MAC διεύθυνση του gateway \texttt{r0-eth0}.
|
||
|
||
\subsection{Σύγκριση του ICMP Echo Request στα δύο υποδίκτυα -- Ζητούμενο 3.2}
|
||
|
||
Οι MAC διευθύνσεις των interfaces που συμμετέχουν στη διαδρομή καταγράφηκαν πριν από την ανάλυση των πακέτων.
|
||
Οι τιμές που προέκυψαν κατά τη συγκεκριμένη εκτέλεση ήταν:
|
||
|
||
\begin{table}[H]
|
||
\centering
|
||
\begin{tabular}{lll}
|
||
\textbf{Interface} & \textbf{IPv4} & \textbf{MAC} \\ \hline
|
||
\texttt{h1-eth0} & \texttt{192.168.1.131} & \texttt{4a:6f:2a:18:f4:80} \\
|
||
\texttt{h3-eth0} & \texttt{192.168.2.10} & \texttt{2e:ef:81:65:2c:c9} \\
|
||
\texttt{r0-eth0} & \texttt{192.168.1.1} & \texttt{ea:2e:7b:6d:78:82} \\
|
||
\texttt{r0-eth1} & \texttt{192.168.2.1} & \texttt{7e:41:8e:cb:65:05} \\
|
||
|
||
\end{tabular}
|
||
\caption{Διευθύνσεις των interfaces που συμμετέχουν στη δρομολόγηση.}
|
||
\end{table}
|
||
|
||
Στο Subnet A το ICMP Echo Request καταγράφηκε στη διεπαφή \texttt{h1-eth0} ως:
|
||
|
||
\begin{minted}{text}
|
||
4a:6f:2a:18:f4:80 > ea:2e:7b:6d:78:82
|
||
ttl 64
|
||
192.168.1.131 > 192.168.2.10
|
||
ICMP echo request, id 4650, seq 1
|
||
\end{minted}
|
||
|
||
Η source MAC είναι επομένως η MAC του \texttt{h1-eth0}, ενώ η destination MAC είναι εκείνη του
|
||
\texttt{r0-eth0}.
|
||
Το Ethernet frame στο Subnet A παραδίδεται δηλαδή από τον \texttt{h1} στην τοπική διεπαφή του gateway.
|
||
|
||
Μετά την προώθηση του IP packet από τον \texttt{r0}, το ίδιο Echo Request καταγράφηκε στη διεπαφή
|
||
\texttt{h3-eth0} του Subnet B ως:
|
||
|
||
\begin{minted}{text}
|
||
7e:41:8e:cb:65:05 > 2e:ef:81:65:2c:c9
|
||
ttl 63
|
||
192.168.1.131 > 192.168.2.10
|
||
ICMP echo request, id 4650, seq 1
|
||
\end{minted}
|
||
|
||
Στο δεύτερο subnet η source MAC είναι πλέον η MAC του \texttt{r0-eth1}, ενώ η destination MAC είναι η MAC του
|
||
\texttt{h3-eth0}.
|
||
Ο router έχει επομένως δημιουργήσει νέο Ethernet frame για το επόμενο Layer-2 τμήμα της διαδρομής.
|
||
|
||
Οι δύο καταγραφές επιτρέπουν την άμεση σύγκριση των πεδίων του ίδιου ICMP Echo Request:
|
||
|
||
\begin{table}[H]
|
||
\centering
|
||
\small
|
||
\begin{tabularx}{\textwidth}{
|
||
>{\raggedright\arraybackslash}p{3.0cm}
|
||
>{\raggedright\arraybackslash}X
|
||
>{\raggedright\arraybackslash}X
|
||
}
|
||
\textbf{Πεδίο} & \textbf{Subnet A} & \textbf{Subnet B} \\ \hline
|
||
Source IP & \texttt{192.168.1.131} & \texttt{192.168.1.131} \\
|
||
Destination IP & \texttt{192.168.2.10} & \texttt{192.168.2.10} \\
|
||
|
||
Source MAC & \texttt{4a:6f:2a:18:f4:80} (\texttt{h1-eth0}) & \texttt{7e:41:8e:cb:65:05} (\texttt{r0-eth1}) \\
|
||
Destination MAC & \texttt{ea:2e:7b:6d:78:82} (\texttt{r0-eth0}) & \texttt{2e:ef:81:65:2c:c9} (\texttt{h3-eth0}) \\
|
||
|
||
TTL & \texttt{64} & \texttt{63} \\
|
||
\end{tabularx}
|
||
\caption{Σύγκριση του ICMP Echo Request στα δύο υποδίκτυα.}
|
||
\end{table}
|
||
|
||
Η διαδρομή του Ethernet frame μπορεί επομένως να αποδοθεί συνοπτικά ως:
|
||
|
||
\begin{minted}{text}
|
||
Subnet A ---- → | r0 | ← ---- Subnet Β
|
||
h1-eth0 → [r0-eth0 → routing → r0-eth1] → h3-eth0
|
||
\end{minted}
|
||
|
||
Οι IP διευθύνσεις, το ICMP identifier \texttt{4650} και το sequence number \texttt{1} επιβεβαιώνουν ότι οι δύο
|
||
καταγραφές αφορούν το \textbf{ίδιο ICMP Echo Request}.
|
||
Οι IP διευθύνσεις παραμένουν ίδιες, ενώ οι MAC διευθύνσεις αντικαθίστανται από εκείνες των interfaces που
|
||
συμμετέχουν στο εκάστοτε Layer-2 segment.
|
||
|
||
Παράλληλα, το TTL μειώνεται από \texttt{64} σε \texttt{63}.
|
||
Η μεταβολή αυτή αποτελεί άμεση ένδειξη ότι το IP packet προωθήθηκε από έναν router, καθώς το TTL μειώνεται κατά
|
||
μία μονάδα σε κάθε Layer-3 hop.
|
||
|
||
\subsection{Μεταβολή των MAC διευθύνσεων και διατήρηση των IP}
|
||
|
||
Η διαφορετική συμπεριφορά των IP και MAC διευθύνσεων οφείλεται στο διαφορετικό πεδίο ισχύος των δύο επιπέδων.
|
||
Οι IP διευθύνσεις χαρακτηρίζουν τους \textbf{τελικούς endpoints της επικοινωνίας}, ενώ οι MAC διευθύνσεις
|
||
χρησιμοποιούνται για την παράδοση ενός Ethernet frame μέσα σε ένα συγκεκριμένο Layer-2 δίκτυο.
|
||
|
||
Στο Subnet A ο \texttt{h1} δημιουργεί ένα IP packet με source \texttt{192.168.1.131} και destination
|
||
\texttt{192.168.2.10}.
|
||
Επειδή ο προορισμός βρίσκεται σε διαφορετικό subnet, το packet τοποθετείται σε Ethernet frame με destination
|
||
τη MAC του \texttt{r0-eth0}, δηλαδή τη MAC της διεπαφής του gateway που βρίσκεται στο ίδιο subnet με τον
|
||
\texttt{h1}.
|
||
|
||
Ο \texttt{r0} παραλαμβάνει το Ethernet frame από το \texttt{r0-eth0}, αφαιρεί το Layer-2 header και εξετάζει
|
||
το IP packet.
|
||
Με βάση τον πίνακα δρομολόγησής του επιλέγει ως εξερχόμενη διεπαφή το \texttt{r0-eth1}, μειώνει το TTL κατά μία
|
||
μονάδα και δημιουργεί \textbf{νέο Ethernet frame} για το Subnet B.
|
||
Στο νέο frame source MAC είναι η MAC του \texttt{r0-eth1} και destination MAC η MAC του \texttt{h3-eth0}.
|
||
|
||
Η διαδικασία αποτυπώνεται στις πραγματικές τιμές της καταγραφής ως:
|
||
|
||
\begin{minted}{text}
|
||
Subnet A:
|
||
4a:6f:2a:18:f4:80 -> ea:2e:7b:6d:78:82
|
||
h1-eth0 r0-eth0
|
||
IP: 192.168.1.131 -> 192.168.2.10
|
||
TTL: 64
|
||
|
||
|
||
Subnet B:
|
||
7e:41:8e:cb:65:05 -> 2e:ef:81:65:2c:c9
|
||
r0-eth1 h3-eth0
|
||
IP: 192.168.1.131 -> 192.168.2.10
|
||
TTL: 63
|
||
\end{minted}
|
||
|
||
Επομένως, οι MAC διευθύνσεις έχουν \emph{hop-by-hop} σημασία και αλλάζουν όταν το IP packet προωθείται από τον
|
||
δρομολογητή σε διαφορετικό Layer-2 δίκτυο.
|
||
Αντίθετα, οι IP διευθύνσεις έχουν \emph{end-to-end} σημασία και παραμένουν ίδιες από τον αρχικό αποστολέα μέχρι
|
||
τον τελικό προορισμό, καθώς στην τοπολογία δεν πραγματοποιείται μετάφραση διευθύνσεων NAT.
|
||
|
||
Η ίδια συμπεριφορά παρατηρείται και στην αντίστροφη κατεύθυνση.
|
||
Στο Subnet B το ICMP Echo Reply καταγράφηκε ως:
|
||
|
||
\begin{minted}{text}
|
||
2e:ef:81:65:2c:c9 > 7e:41:8e:cb:65:05
|
||
ttl 64
|
||
192.168.2.10 > 192.168.1.131
|
||
ICMP echo reply, id 4650, seq 1
|
||
\end{minted}
|
||
|
||
Μετά την προώθησή του από τον \texttt{r0}, το ίδιο Reply εμφανίζεται στο Subnet A ως:
|
||
|
||
\begin{minted}{text}
|
||
ea:2e:7b:6d:78:82 > 4a:6f:2a:18:f4:80
|
||
ttl 63
|
||
192.168.2.10 > 192.168.1.131
|
||
ICMP echo reply, id 4650, seq 1
|
||
\end{minted}
|
||
|
||
Η αντίστροφη πορεία επιβεβαιώνει το ίδιο αποτέλεσμα: οι IP διευθύνσεις παραμένουν σταθερές, οι MAC διευθύνσεις
|
||
προσαρμόζονται στο εκάστοτε Layer-2 segment και το TTL μειώνεται κατά μία μονάδα κατά τη διέλευση από τον
|
||
\texttt{r0}.
|
||
|
||
|
||
\section{Συμπεράσματα}
|
||
|
||
Στην παρούσα εργασία υλοποιήθηκε ένας γενικός builder δικτυακών τοπολογιών για το Mininet, βασισμένος σε μία
|
||
δηλωτική γλώσσα περιγραφής σε JSON.
|
||
Η σχεδίαση της DSL βασίστηκε στον διαχωρισμό της επιθυμητής τοπολογίας από τις λεπτομέρειες της εκτέλεσης και
|
||
στην αντιστοίχιση των αφαιρέσεων της γλώσσας σε συγκεκριμένες δυνατότητες του Mininet και του Linux.
|
||
|
||
Η υλοποίηση οργανώθηκε με \textbf{compiler-like αρχιτεκτονική}, στην οποία η αρχική περιγραφή περνά διαδοχικά
|
||
από τα στάδια φόρτωσης, parsing, validation, planning και rendering.
|
||
Ο διαχωρισμός αυτός επέτρεψε κάθε στάδιο να έχει σαφή ευθύνη, ενώ το \texttt{ExecutionPlan} λειτουργεί ως
|
||
πλήρως επιλυμένη ενδιάμεση αναπαράσταση πριν από την παραγωγή του τελικού κώδικα.
|
||
Το παραγόμενο \texttt{topology.generated.py} αποτελεί την εκτελέσιμη ``assembly'' της DSL και ταυτόχρονα ένα
|
||
ανθρώπινα αναγνώσιμο artifact, το οποίο μπορεί να επιθεωρηθεί ανεξάρτητα πριν από την πραγματική εκτέλεση.
|
||
|
||
Η τοπολογία της εργασίας δημιουργήθηκε αποκλειστικά από το αντίστοιχο \texttt{topology.json}, χωρίς να απαιτείται
|
||
ειδική λογική στον builder για το συγκεκριμένο δίκτυο.
|
||
Η ίδια περιγραφή χρησιμοποιήθηκε για την αυτόματη δημιουργία των hosts, switches και links, την παραμετροποίηση
|
||
του router και την εκκίνηση της υπηρεσίας DHCP.
|
||
|
||
Τα τρία πειράματα επέτρεψαν την παρατήρηση της λειτουργίας του δικτύου σε διαφορετικά επίπεδα.
|
||
Στο πρώτο πείραμα καταγράφηκε η διαδικασία D.O.R.A. του DHCP και επιβεβαιώθηκε η απόκτηση δυναμικής διεύθυνσης
|
||
από τον \texttt{h1}, καθώς και η broadcast φύση του αρχικού DHCP Request.
|
||
Στο δεύτερο πείραμα παρατηρήθηκε η επίλυση μιας IPv4 διεύθυνσης σε MAC μέσω ARP, με broadcast Request και
|
||
unicast Reply.
|
||
Τέλος, στο τρίτο πείραμα καταγράφηκε το ίδιο ICMP Echo Request στις δύο πλευρές του router και επιβεβαιώθηκε
|
||
πειραματικά ότι οι IP διευθύνσεις παραμένουν σταθερές end-to-end, ενώ οι MAC διευθύνσεις μεταβάλλονται
|
||
hop-by-hop και το TTL μειώνεται κατά μία μονάδα κατά τη δρομολόγηση.
|
||
|
||
Ιδιαίτερη σημασία είχε το γεγονός ότι οι πραγματικές καταγραφές δεν περιορίστηκαν πάντα στην ελάχιστη
|
||
θεωρητική ακολουθία μηνυμάτων.
|
||
Στο DHCP, για παράδειγμα, παρατηρήθηκε επαναμετάδοση του Discover πριν από την ολοκλήρωση της διαδικασίας, ενώ
|
||
στο ARP εμφανίστηκε επιπλέον ανταλλαγή σχετική με τη διαχείριση του neighbor cache.
|
||
Οι παρατηρήσεις αυτές δείχνουν τη διαφορά ανάμεσα στην αφαιρετική περιγραφή ενός πρωτοκόλλου και στη συμπεριφορά
|
||
ενός πραγματικού δικτυακού stack.
|
||
|
||
Συνολικά, η εργασία συνέδεσε δύο διαφορετικά επίπεδα αφαίρεσης: από τη μία τη δηλωτική περιγραφή και αυτόματη
|
||
κατασκευή της υποδομής και από την άλλη την παρατήρηση των πραγματικών πακέτων που παράγονται κατά τη λειτουργία
|
||
της.
|
||
Ο διαχωρισμός αυτός καθιστά τον builder επαναχρησιμοποιήσιμο για διαφορετικές τοπολογίες, ενώ παράλληλα
|
||
διατηρεί τη δυνατότητα λεπτομερούς ελέγχου της συμπεριφοράς του δικτύου μέσω των συνηθισμένων εργαλείων Linux.
|
||
Η ίδια αρχιτεκτονική μπορεί να επεκταθεί με νέα είδη services, περισσότερες παραμέτρους συνδέσμων ή διαφορετικά
|
||
backend-specific settings, χωρίς να απαιτείται αλλαγή της βασικής ροής του builder.
|
||
|
||
|
||
\end{document}
|