• # Implémentation dans Linux ?

    Posté par  . Évalué à 7.

    Plan 9 is much more Unix in its approach: you open /net/tcp/clone to reserve a connection, and read the connection ID from it. Then you open /net/tcp/n/ctl and write “connect 127.0.0.1!80” to it, where “n” is that connection ID. Now you can open /net/tcp/n/data and that file is a full-duplex stream. No magic syscalls, and you can trivially implement it in a shell script.

    J'avais connaissance de ça, mais je me suis toujours demandé… pourquoi personne n'avait tenté de faire un module noyau (ou espace utilisateur ?) qui fait la même chose dans Linux ? Au moins pour tenter.

    Ça existe ?

    • [^] # Re: Implémentation dans Linux ?

      Posté par  (site web personnel) . Évalué à 5.

      Pourquoi noyau ?

      Il y a déjà bash qui le propose: https://www.linuxjournal.com/content/more-using-bashs-built-devtcp-file-tcpip

      (c'est désactivé sur Debian, dans mon souvenir).

      Sinon, le Hurd est aussi à fond Unix:

      https://www.gnu.org/software/hurd/users-guide/using_gnuhurd.html#Networking

      • [^] # Re: Implémentation dans Linux ?

        Posté par  . Évalué à 3.

        Pour Hurd, mettons, mais c'est pas réaliste de booter sur un Hurd aujourd'hui…

        Ce que bash propose, c'est… pas top. Déjà, c'est que dans Bash. Si j'ai envie de le faire en Python ou en C, je vais pas lancer un bash. Ensuite, il faut choisir soi-même un numéro de descripteur de fichier, bon courage pour éviter les conflits.
        Enfin, la syntaxe à base de 3<> et de cat <&3 est particulièrement pas simple. Peut-être parce que justement, tout devrait être stocké dans une variable, dès l'ouverture du flux bidirectionnel ?

        • [^] # Re: Implémentation dans Linux ?

          Posté par  (site web personnel) . Évalué à 6.

          Pour Hurd, mettons, mais c'est pas réaliste de booter sur un
          Hurd aujourd'hui…

          Mais nan, c'est aussi réaliste que de booter un hurd hier ou avant hier.

          Ce que bash propose, c'est… pas top

          C'est clairement pourri, oui.

          Ceci dit, ce que propose "plan 9", ça me parait mauvais.

          Par exemple, faire un open sur le fichier pour obtenir un identifiant implique de ne pas pouvoir donner d'option pour ton socket (mais c'est pas forcément l'idée).

          Du coup, ça va remplacer un API propre avec des variables, etc par un protocole texte pour ouvrir une connexion en sérialisant l'adresse dans une chaine. Et ça implique aussi de manipuler les chaines en C, un truc qu'on sait être casse gueule depuis des années.

          Et ne parlons pas du format. Je suis sur que si je dit "tiens, je propose d'écrire l'adresse en XML", tout le monde va hurler, mais avec un format ad-hoc spécifique, ça serait ok ?

          D'ailleurs, cet article vieux de 10 ans parle un peu de ces questions (surtout dans les commentaires).

          • [^] # Re: Implémentation dans Linux ?

            Posté par  . Évalué à 3. Dernière modification le 13 novembre 2022 à 01:45.

            Surtout que c'est complètement bancal ce que vous dites là. Déjà L'IP aurait dû être dans le path. Un "open" d'un et un seul fichier provoque la connection (il renvoie le socket). Le open pouvant déjà accepter pas mal d'options sous forme de flag, quelques une de plus…

            L'API socket non conforme à UNIX c'est essentiellement un historique. Fondamentalement j'ai jamais compris pourquoi on a jamais cherché à corrigee le tir en faisant évoluer le "open" pour créer les sockets.

            Mort aux cons !

            • [^] # Re: Implémentation dans Linux ?

              Posté par  . Évalué à 3.

              L'API socket non conforme à UNIX

              C'est POSIX. Je sais pas ce que tu entend par unix ? Ça n'est pas représenté par un fichier virtuel ? Comme tout descripteur de fichier la connexion est représentée par un fichier dans /proc.

              Tu ne peux pas fusionner open et socket en gardant la compatibilité, il y a trop d'options. Donc casser la compatibilité, ajouter de la complexité à l'utilisation et à l'implémentation,… Pour la beauté de geste n'a pas du intéresser grand monde.

              https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

              • [^] # Re: Implémentation dans Linux ?

                Posté par  . Évalué à 2.

                L’API Berkeley est une pièce rapportée du monde des télécom’ vers celui d’UNIX.

                The Art of UNIX Programming (Eric S. Raymond) en fait succinctement l’histoire (disponible en ligne si je ne m’abuse).

                Côté client c’est très facilement envisageable d’implémenter une interface dans le plus pur style UNIX. Sans casser la compatibilité ascendante.

                Côté serveur je reconnais que c’est un peu plus tricky car y’a une séquence bind, listen, accept à mettre en œuvre.

                Mort aux cons !

            • [^] # Re: Implémentation dans Linux ?

              Posté par  (site web personnel) . Évalué à 5.

              Je pense que ça n'aurait pas été un super design.

              Si tu fais ça, tu te retrouves avec un appel système fourre tout comme ioctl, et ça devient impossible de faire évoluer ça proprement.

              Ensuite, peut être que "faire une chose et la faire bien", ça s'applique pas pour open, mais juste quand on est pas d'accord avec le design des APIs.

              • [^] # Re: Implémentation dans Linux ?

                Posté par  . Évalué à 1.

                Si tu fais ça, tu te retrouves avec un appel système fourre tout

                C’est déjà le cas, on oublie trop souvent qu’un fichier c’est juste une abstraction pour identifier un flux de bit dans un espace de nom. De ce qui se passe en pratique quand on ouvre un fichier, écrit ou lit dedans, ça peut varier du tout au tout selon qu’on adresse un stockage, un périphérique, un tube nommé, etc. C’est le cœur du modèle UNIX de faire du fichier le “fourre tout” ultime.

                Mort aux cons !

                • [^] # Re: Implémentation dans Linux ?

                  Posté par  (site web personnel) . Évalué à 3.

                  Peut être qu'il faudrait faire évoluer le modèle vers un "tout est URL" ?

                  Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.

                • [^] # Re: Implémentation dans Linux ?

                  Posté par  (site web personnel) . Évalué à 3.

                  Oui, mais je pense que c'est pas forcément un design qu'on doit continuer à pousser à son paroxysme et qu'il faut le faire évoluer.

                  J'ai commencé à apprendre Rust il y a pas longtemps.

                  Quelque chose qui a fait clic dans mon crane, c'est la gestion des erreurs.

                  Tu veux renvoyer quelque chose de potentiellement nul, tu utilises Option, qui est une union entre None et Some(T). Une fonction peut échouer va renvoyer un Result, une union de Ok() et de Err().

                  Le langage et la lib standard sont explicites dans les concepts et utilise le typage pour ça, et pour la vérification.

                  Le C (ou du moins, le C tel qu'utilisé par Unix), c'est le contraire. Tu veux échouer, tu renvoies un nombre négatif, sauf si l'API dit que tu dois renvoyer 0, cad null. Il y a pas vraiment de typage fort, parce que justement, on veut garder ce pseudo polymorphisme de "tout est un FD" (polymorphisme datant d'avant le C++). C'est plus souple, oui. Mais c'est aussi à mon sens plus casse gueule.

                  Les systèmes plus modernes (BeOS, Windows) ont tentés d'avoir des APIs plus haut niveau, par exemple basé sur les objets C++ (au moins pour BeOS).

                  Du coup, est ce qu'avoir plus de typage, c'est aller dans la direction de l'esprit Unix, ou pas ?

                  Parce qu'on parle à l'origine de Plan 9, mais il ne faut pas oublier que si les idées de Plan 9 étaient si bien, on les aurait retrouvé dans Go vu qui a écrit le langage.

                  • [^] # Re: Implémentation dans Linux ?

                    Posté par  . Évalué à 4.

                    Quelque chose qui a fait clic dans mon crane, c'est la gestion des erreurs.

                    C'est une sacrée épiphanie, hein ? Je l'ai eu aussi mais pas avec rust et quand tu vois que le compilateur, avec la propagation de contraint et l'inlining, est capable de produire un code optimisé (supprimer le type englobant). C'est vraiment une superbe manière de gérer les erreurs et pleins d'autres choses aussi.

                    https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

        • [^] # Re: Implémentation dans Linux ?

          Posté par  (Mastodon) . Évalué à 3.

          1 - l'exemple donné me fait un retour en « Error 400 (Bad Request)!!1 » sur google.com (copié-collé exact de l'exemple).
          Et un « Bad Request. Your browser sent a request that this server could not understand. » sur mon apache local.
          Donc ça marche plus mal que ça apparemment… :)

          2 - les file descriptors, tu les choisis dynamiquement hein !

          Ensuite, il faut choisir soi-même un numéro de descripteur de fichier, bon courage pour éviter les conflits.

          url="www.google.com"
          fd=$(comm -13 <(ls /proc/$$/fd | sort) <(seq 255 | sort) | sort -g | head -1)
          eval 'exec '${fd}'<>/dev/tcp/'${url}'/80; echo -e "GET / HTTP/1.1\r\nhost: http://'${url}'\r\nConnection: close\r\n\r\n" >&'${fd}'; cat <&'${fd}
          

          Bon, ça les rends pas par contre hein les file descriptors :

          ls /proc/$$/fd -l | cut -d\  -f10-
          
          0 -> /dev/pts/21
          1 -> /dev/pts/21
          2 -> /dev/pts/21
          255 -> /dev/pts/21
          4 -> socket:[1870185]
          5 -> socket:[1870235]
          6 -> socket:[1867560]
          7 -> socket:[1871095]
          8 -> socket:[1864698]
          9 -> socket:[1869500]
          
          • Yth, en bash on peut toujours faire plus GRUIIIIICK !!!!

          PS: On avait déjà le serveur web en bash https://github.com/avleen/bashttpd avec un obscur fork capable de gérer les requêtes POST d'un webhook gitlab ici https://gitlab.com/Arn0/bashttpd2
          Maintenant on a le brouteur bash ..?

          • [^] # Re: Implémentation dans Linux ?

            Posté par  . Évalué à 2.

            l'exemple donné me fait un retour en « Error 400 (Bad Request)!!1 » sur google.com

            J'avais la même chose, mais des fois, on a la flemme de l'écrire… C'était pas hyper pertinent non plus.

            fd=$(comm -13 <(ls /proc/$$/fd | sort) <(seq 255 | sort) | sort -g | head -1)
            

            OK. J'ai appris un truc (surtout comm).

            Par contre, ça en fait des forks:
            - 2 sous-shell pour les arguments de comm
            - 7 processus lancés pour avoir le fd
            - 2 builtin (eval + exec) et 2 processus pour le duo requête-réponse. Mais ça change pas trop d'avant.

            On va s'abstenir de lancer des perf stat là-dessus je crois :) En attendant io_uring_spawn en tout cas.

            • [^] # Re: Implémentation dans Linux ?

              Posté par  (Mastodon) . Évalué à 4. Dernière modification le 15 novembre 2022 à 09:56.

              Oui, j'ai un peu fait exprès d'en rajouter pour chopper le prochain fd dans l'ordre des nombres, plutôt que la sortie de sort qui convient à comm et qui va te donner les fds suivants : 10, 100, 101 … 109, 11, 110, 111, …, 199, 20, 200, etc.

              Voire, sachant que seq et ls te les mettent déjà dans l'ordre numérique, on peut virer tous les sort, mais comm se plaint que les sources ne sont pas ordonnées, il faut donc mettre un --nocheck-order à comm.
              On aurait le même résultat avec significativement moins de processus, mais en étant moins à l'abri d'un comportement non standard. Avec les sort on est algorithmiquement sûr de notre résultat (enfin, sauf grosse bourde de ma part ^ ^ ).

              À noter que le fd n°3 n'est jamais retourné : il est squatté par la ligne qui récupère le premier fd disponible, et rendu à la fin, donc on passe toujours au 4. Je ne suis pas très sûr de quelle étape génère ce fd n°3.

              En tout cas ça fait des bashismes bien moches, miam :)

              • Yth.

              PS : comm c'est vraiment pratique, Jadis j'avais fait des coding game, en bash, et ça m'arrivait souvent d'avoir des perfs équivalentes que ce que d'autres faisaient avec des vrais langages et des algos chiadés, grâce à ce genre d'outils.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.