\documentclass{beamer}
%\documentclass[handout]{beamer}
%\usepackage{pgfpages}
%\pgfpagesuselayout{2 on 1}[a4paper,border shrink=5mm]
\usetheme{Afnic}
\usepackage[french]{babel}
\usepackage[utf8x]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{bortzmeyer-utils}

\title{Le réseau vu du langage de programmation : quelle API pour le réseau ?}
\author{Stéphane Bortzmeyer\\AFNIC\\\texttt{bortzmeyer@nic.fr}}
\date{MiXiT, 19 avril 2018}

\setlength{\parskip}{15pt plus 10pt minus 10pt} 

\begin{document}

% 50 minutes

\maketitle
\begin{frame}
    \titlepage
\end{frame}

\begin{frame}
    \frametitle{Terminologie}
    \begin{overlayarea}{\textwidth}{.6\textheight}
      \begin{itemize}
      \item<2->API = \foreign{Application Programming Interface}
      \item<3->Bibliothèque : \emph{une} mise en œuvre particulière
        d'une API
      \item<4->L'API, c'est ce que la·e programmeur·e doit lire pour
        utiliser une bibliothèque
      \item<5->Protocole : ce qui est circule sur le réseau. Planqué dans le code de la
        bibliothèque et documenté par exemple dans un RFC.  
      \end{itemize}
      \end{overlayarea}  
\end{frame}

\begin{frame}
  \frametitle{La situation aujourd'hui}
    \begin{overlayarea}{\textwidth}{.6\textheight}
      \begin{itemize}
      \item<2->Toutes (?) les applications utilisent le réseau,
      \item<3->Et dépendent donc d'une API réseau,
      \item<4->Il n'y a pas d'API parfaite, toutes ont de sérieuses limites.  
      \end{itemize}
      \end{overlayarea}
\end{frame}

% Plusieurs exemples, par complexité croissante

% Serveur DoH
\begin{frame}[fragile]
  \frametitle{Avec un framework qui cache presque tout}
  Python + Quart (compatible avec Flask) :
  \begin{info}
@app.route('/', methods=['HEAD', 'GET', 'POST'])
async def index():
   if request.method == 'POST':
      ct = request.headers.get('content-type')
      if ct != "application/dns-udpwireformat":
          abort(415)
      data = await request.get_data()
      r = bytes(data)
   else:
      abort(405)
   return (response,
           {'Content-Type': 'application/dns-udpwireformat',
            'Cache-Control': 'no-cache'}) 
  \end{info}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Exemple simple}
  Une application Java veut récupérer un fichier :
  \begin{info}
String url = args[0];
InputStream is = new URL(url).openStream();
try {
    BufferedReader rd = new BufferedReader(new InputStreamReader(is));
    StringBuilder sb = new StringBuilder();
    int cp;
    while ((cp = rd.read()) != -1) {
        sb.append((char) cp);
    }
    text = sb.toString();
} finally {
    is.close();
}
System.out.println(text);
  \end{info}
\end{frame}

\begin{frame}[fragile]
  \frametitle{On dépend bien sûr du langage}
  Et de sa bibliothèque standard (ici, Go) :
  % gostar
  \begin{info}
import (
    "http"
)

url string = "http://data.keolis-rennes.com/xml/"

completeurl := url + "?version=1.0&key=" + http.URLEscape(key) +
    "&cmd=getstation&param[request]=number&param[value]=" +
    http.URLEscape(query)
response, _, error := http.Get(completeurl)
body := make([]byte, maxsize)
n, _ := response.Body.Read(body)    
   \end{info}
\end{frame}

% check-soa pour un exemple Go non-HTTP ?

% exemple Haskell ? src/Haskell/Network/whois.hs

\begin{frame}[fragile]
  \frametitle{C avec libcurl}
  Si pas de bibliothèque standard, plus de code portable (libcurl vs. neon)
  \begin{info}
char            data[MAX_FILE_SIZE];
char           *data_ptr = data;
size_t
write_data(void *inputbuffer, size_t size, size_t sizescale, void *userp)
{
        size_t          nbytes = size * sizescale;
        strncpy(data_ptr, inputbuffer, nbytes);
        data_ptr += nbytes;
        written += nbytes;
        return nbytes;
}
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_URL, url);
result = curl_easy_perform(curl);
/* Do something with data */
  \end{info}
\end{frame}

% Bitcoin Core https://github.com/bitcoin/bitcoin.git En src/net.cpp
% et netbase.cpp Utilise l'API socket.
\begin{frame}[fragile]
  \frametitle{API socket}
  Bitcoin Core, écrit en C++ :
  \begin{info}
bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocket, int nTimeout, 
    bool manual_connection)
{
    struct sockaddr_storage sockaddr;
    socklen_t len = sizeof(sockaddr);
    if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
    {
        fd_set fdset;
        FD_ZERO(&fdset);
        FD_SET(hSocket, &fdset);
        int nRet = select(hSocket + 1, nullptr, &fdset, nullptr, &timeout);    
  \end{info}
\end{frame}

\begin{frame}
  \frametitle{Problèmes et limites des API}
    \begin{overlayarea}{\textwidth}{.6\textheight}
      \begin{itemize} % L'informatique, ce sont toujours des abstractions
      \item<2->Trop haut niveau\only<2>{ : empêche d'utiliser
        certaines fonctions du réseau, « fuites » des problèmes réseau}
      \item<3->Trop bas niveau\only<3>{ : trop compliqué pour l·e·a
        programmeur·e, trop dangereux pour la sécurité - exemple
        d'OpenSSL} % Mon exposé à Devoxx
      \item<4->Si on veut juste récupérer une ressource en HTTP(S),
        c'est bon % Pur client. Et encore, si on ne veut pas utiliser
                  % les trucs de HTTP/2
       \item<5->Mais d'autres applications sont plus ambitieuses ! 
      \end{itemize}
      \end{overlayarea}
\end{frame}

% https://github.com/tootsuite/mastodon/issues/3762
\begin{frame}
  \frametitle{La bibiothèque n'essaie qu'une seule adresse}
  Mastodon est écrit en Ruby :
  \includegraphics[scale=0.26]{mastodon-ipv6.png}
\end{frame}

\begin{frame}
  \frametitle{Ce qu'attend l'application}
    \begin{overlayarea}{\textwidth}{.6\textheight}
      \begin{itemize}
      \item<2->L'application attend du réseau des
        \emph{services}\only<2>{. Exemple : délivrer les données
          intactes et dans l'ordre…}
        \item<3->Chaque application est différente\only<3>{. Elles
          n'ont pas toutes besoin des mêmes services.}
        \item<4->Les API de trop haut niveau limitent en général
          sévèrement les services\only<4>{ (options réseau, barre de progression…)}
        \item<5->Les API de trop bas niveau obligent à se taper des
          détails non-pertinents.\only<5>{ (Faire de l'UpnP ou du PCP, utiliser
          STUN ou TURN, se déconnecter/reconnecter…)}
        \item<6->Sans API standard, pas de portabilité des applications. 
      \end{itemize}
      \end{overlayarea}
\end{frame}

\begin{frame}
  \frametitle{Fonctions possibles}  
    \begin{overlayarea}{\textwidth}{.6\textheight}
      \begin{itemize}
      \item<2->Délivrance des données fiable\only<2>{ (transfert de fichiers)}
        ou « au mieux »\only<2>{ (vidéo en direct)} % On ne peut
                                % pas avoir le beurre et l'argent du
                                % beurre (vitesse et fiabilité)
      \item<3->Structuration en messages, ou en flot continu d'octets
      \item<4->Confidentialité
      \item<5->Gestion explicite ou implicite des adresses IP
        multiples\only<5>{ (\foreign{multipath})}
      \item<6->Gestion de la congestion  
      \item<7->Privilégier la latence ou le débit ?
      \item<8->Décroissance : « Je ne suis pas pressé, je laisse la
        place aux autres »
      \item<9->Un ensemble cohérent de \emph{fonctions} est un \emph{service}
      \end{itemize}
      \end{overlayarea}
\end{frame}

\begin{frame}
  \frametitle{L'API socket}
    \begin{overlayarea}{\textwidth}{.6\textheight}
      \begin{itemize}
      \item<2->« Responsable du succès de l'Internet » ?
       \item<3->À première vue, permet de spécifier un service
         (\computer{SOCK\_STREAM})
       \item<4->Mais en fait non (si on veut juste un flot de données, cela pourrait être
    fait avec TCP ou SCTP, mais seul TCP sera sélectionné)
     \item<5->Pas assez abstraite
      \end{itemize}
      \end{overlayarea}
\end{frame}

\begin{frame}
  \frametitle{Les réalités du réseau}
    \begin{overlayarea}{\textwidth}{.6\textheight}
      \begin{itemize}
      \item<2->Le réseau n'est pas un fichier
      \item<3->Le réseau plante (souvent ?) % Dans les langages sans
                                % exceptions, plein de ``if err''...
      \item<4->Plusieurs fonctions différentes sont possibles sur le
        réseau (par exemple avec ou sans confidentialité)
      \end{itemize}
      \end{overlayarea}
\end{frame}

\begin{frame}
  \frametitle{En dessous de l'API : les protocoles}
    \begin{overlayarea}{\textwidth}{.6\textheight}
      \begin{itemize}
      \item<2->Un protocole est la réalisation d'un ou plusieurs service(s)
      \item<3->Plusieurs protocoles peuvent réaliser un service donné  
      \item<4->TCP :
        \begin{itemize}
        \item Délivrance d'octets\only<4>{ (pas de
          structuration)}
        \item Fiable et dans l'ordre
        \item Contrôle de congestion  
        \item Aucune sécurité  
        \end{itemize}
      \item<5->UDP :
        \begin{itemize}
        \item Délivrance de messages
        \item Aucune garantie : peuvent se perdre, se doubler…
        \item Aucun contrôle de congestion  
        \item \emph{Très dangereux} : ne vous croyez pas capable de
          réimplémenter TCP % En même temps, certains semblent
                            % sérieux, comme Valve https://github.com/ValveSoftware/GameNetworkingSockets
        \end{itemize}
      \item<6->UDP-Lite (UDP mais avec corruption possible), DCCP (UDP
        mais avec contrôle de congestion)
      \end{itemize}
      \end{overlayarea}
\end{frame}

\begin{frame}
  \frametitle{Les protocoles, suite}
  \begin{overlayarea}{\textwidth}{.6\textheight}
    \begin{itemize}
    \item<2->SCTP :
      \begin{itemize}
      \item Délivrance de messages
       \item Fiable et dans l'ordre
       \item Contrôle de congestion
       \item Plein d'options en plus de TCP\only<2>{, notamment de gestion des multi-adresses}  
      \end{itemize}
       \item<3->QUIC (le nouveau TCP au dessus d'UDP, made in
         Google)
       \item<4->TLS :
         \begin{itemize}
         \item Oui, vu de l'application, c'est un protocole de
           transport
        \item Délivrance d'octets
        \item Fiable et dans l'ordre
        \item Contrôle de congestion\only<4>{ (grâce à TCP en dessous)}  
        \item Confidentialité et authentification
        \item Pas d'API standard  
         \end{itemize}
         \end{itemize}
      \end{overlayarea}
\end{frame}


\begin{frame}
  \frametitle{Les protocoles, fin}
  \begin{overlayarea}{\textwidth}{.6\textheight}
    \begin{itemize}
       \item<2-> LEDBAT : protocole humble et poli, cède toujours sa place
         à TCP
       \item<3-> HTTP :
         \begin{itemize}
         \item Oui, vu de l'application, c'est un protocole de
           transport
         \item Souvent utilisé quand on n'a pas le choix
         \end{itemize}
         \end{itemize}
      \end{overlayarea}
\end{frame}

\begin{frame}
  \frametitle{Du service au protocole}
    \begin{overlayarea}{\textwidth}{.6\textheight}
      \begin{itemize}
        \item<2->Une fois défini le service, plusieurs protocoles
          peuvent convenir
        \item<3->C'est au programmeur de choisir, il n'y a pas d'API
          qui permette cela
        \item<4>Exemple, si une application veut que ses octets soient
    distribués dans l'ordre, et sans pertes, plusieurs protocoles
    peuvent convenir (TCP, SCTP, TLS, HTTP)          
       \end{itemize}
      \end{overlayarea}
\end{frame}

\begin{frame}
  \frametitle{Le groupe de travail TAPS}
    \begin{overlayarea}{\textwidth}{.6\textheight}
      \begin{itemize}
      \item<2->Groupe de travail IETF chargé de définir rigoureusement
        les services de la couche 4\only<2>{ (couche Transport)}
      \item<3->Lisez son RFC 8303, ça vaut la peine  %  RFC 8095, 8303 et 8304
      \item<4->Des travaux en cours : définir un jeu minimum de services % draft-ietf-taps-minset  	
          et les services de sécurité % draft-ietf-taps-transport-security 
      \end{itemize}
      \end{overlayarea}
\end{frame}

\begin{frame}
  \frametitle{Vers une nouvelle API ?}
    \begin{overlayarea}{\textwidth}{.6\textheight}
      \begin{itemize}
      \item<2-> Faire une API indépendante du langage ?
      \item<3-> Non. (Exceptions vs. codes de retour, asynchronisme
        vs. parallélisme…)
      \item<4-> Plusieurs projets en cours, par exemple
        \computer{draft-trammel-taps-interface} (ex-PostSockets) ou
        NEAT \computer{draft-fairhurst-taps-neat}
      \end{itemize}
      \end{overlayarea}
\end{frame}

\end{document}
