Bon, je reviens après avoir utilisé quelques temps SFML dans mon coin. Jusque là, personne n’a proposé de patch pour l’ipv6, donc je me lance.
En première approche, je précise ici certaines choses. Puis en tenant compte de vos remarques, j’irai faire mon pull request en le commentant sur le forum anglais (Si j’ai bien compris, il est plus actif et fait foi).
À ce jour, 1 seul report sur ce sujet, classé rejected :
https://github.com/SFML/SFML/issues/307État des lieuxActuellement, SFML (v. 2.3 rev.746bb9c et antérieures) ne supporte pas l’IPv6. C’est à dire que le type
sf::IpAddress ainsi que ses interdépendances sont implémentés autour de l’IPv4 uniquement.
Liste des composants touchés :- SFML/Network/IpAddress.hpp
- SFML/Network/Socket.hpp
- SFML/Network/TcpSocket.hpp
- SFML/Network/SocketImpl.hpp
static sockaddr_in createAddress(Uint32 address, unsigned short port); - SFML/Network/Unix/SocketImpl.hpp
sockaddr_in SocketImpl::createAddress(Uint32 address, unsigned short port) - SFML/Network/Win32/SocketImpl.hpp
sockaddr_in SocketImpl::createAddress(Uint32 address, unsigned short port)
Différentes approches possibles- un héritage multiple
sf::IpAddress ―> sf::IpAddressV4
sf::IpAddress ―> sf::IpAddressV6 - une composition
sf::IpAddress ◄►― sf::IpAddressV4
sf::IpAddress ◄►― sf::IpAddressV6 - un type dynamique et ça reste une composition (attention au RAII)
- une union
Un type complexe en union qui peut stocker l’un au l’autre. Pas sur que le gain d’espace mémoire (quasi insignifiant) soit intéressant par rapport aux erreurs que ça pourrait occasionner.
Tip : On ne sait pas de quelle structure de stockage on a besoin tant que l’adresse n’est pas saisie et parsée. Donc 2 temps.
Pour comparer les différentes approches possible, j’ai référencé d’autres implémentations dans des libs à forte notoriété :
- Boost
boost::asio::ip::address
composition 2in1, v4 & v6 existent aussi comme classes indépendantes, et sont associées dans un type agglomérat sous forme d’une composition. - Lib Standard
std::ip::address
(celle du C++17 rejeté dans le TR2 Christopher Kohlhoff mais qui viendra plus tard) pareil que boost, c’est une composition 2in1. - WxWidget
wxIPaddress ―> wxSockAddress
2in1 via une union mais ensuite 2 classes filles typée v6 ou v4 qui héritent de wxIPaddress et que l’utilisateur à l’obligation d’utiliser. Dans leurs propres exemples, c’est sale. - Qt (v5)
QHostAddress
2in1 comme boost, un peu plus à leur sauce, mais presque pareil.
Comme première mouture, j’opte pour une approche par composition avec des variables membres comme dans
boost::asio (ou le futur std::ip).
Use case. Comment utilisera-t-on les nouveaux types ?
Un seul composant
IpAddress servira de classe publique pour l’utilisateur. Mais il existera quand même des classes spécifiques v4 et v6 (surement priv). Cette classe globale IpAddress agrégera les types adresse_v4 et adresse_v6.
Lorsqu’il utilisera IpAddress, l’utilisateur devra s’intéresser au type d’adresse dans ses procédures.
Fix au passageDans la version actuelle, tester si une adresse est localhost est à la charge de l’utilisateur.
De la forme
my_address == sf::address::LocalHostÉtait-ce la bonne approche ? C’est léger et compréhensible. Mais ne respecte pas la norme maintenue par l’IANA. En IPv4, les adresses qui loopback sont de la forme 127.0.0.1/8, c’est à dire la plage d’adresses de 127.0.0.1 à 127.255.255.255 (le /8 voulant dire 8 bits significatifs). Donc si on fixe ce défaut par rapport à la norme, plus moyen de déléguer ce test à l’utilisateur, il faut une méthode isLoopback().
Tandis qu’en IPv6, seule l’adresse ::1 est loopback.
Nommage de cette méthode,
localhost vs loopback ?
« localhost » est en général une adresse de l’interface « loopback ». Ils peuvent être et sont souvent interchangeables. Cependant, si on ne check que les adresses et non pas la réalité du réseau, il vaut mieux l’appeler localhost, c’est moins glorifiant, mais techniquement plus juste.
ExtensionIl existe aussi les adresses du domaine Unix, le type AF_UNIX (contrairement aux types ip AF_INET et AF_INET6). Il y a aussi AF_IPX et AF_AX25, mais ce sont des niches (Novell et radio émission).
Est-ce qu’on se limite aux types ip ? D’autres libs gèrent au moins le type UNIX en plus.
PS : les libs citées sont sous leur licence respective