Stockage des adresses IPv6 dans MySQL

Comme cela a été demandé dans “les fonctions inet_aton et inet_ntoa nécessaires à ipv6 “, il n’y a actuellement aucune fonction MySQL pour stocker les adresses IPv6. Quel serait le type / la fonction de données recommandé pour le stockage / l’insertion? (Je n’ai pas l’intention de les stocker sous forme de chaîne). Je ne veux pas non plus séparer l’adresse IPv6 en 2 INT.

Que diriez-vous:

BINARY(16) 

Cela devrait être assez efficace.

Actuellement, il n’y a pas de fonction pour convertir les adresses IPv6 textuelles de / en binary sur le serveur MySQL, comme indiqué dans ce rapport de bogue. Vous devez soit le faire dans votre application ou éventuellement créer un UDF (User-Defined Function) sur le serveur MySQL pour ce faire.

METTRE À JOUR:

MySQL 5.6.3 prend en charge les adresses IPv6, voir ci-dessous: ” INET6_ATON (expr) “.

Le type de données est VARBINARY(16) au lieu de BINARY(16) comme je l’ai suggéré précédemment. La seule raison à cela est que les fonctions MySQL fonctionnent à la fois pour les adresses IPv6 et IPv4. BINARY(16) convient pour stocker uniquement les adresses IPv6 et enregistre un octet. VARBINARY(16) doit être utilisé pour gérer les adresses IPv6 et IPv4.

Une implémentation pour les anciennes versions de MySQL et MariaDB, voir ci-dessous: ” EXTENDING MYSQL 5 WITH IPV6 FUNCTIONS “.

Personne n’a posté de réponse complète (et de nombreux exemples utilisent Windows ::1 ce qui peut être très trompeur pour les environnements live (ou de production)), où (du moins je peux le trouver), voici:

  1. Le format à stocker avec.
  2. Exemple de requête INSERT utilisant une adresse IP IPv6 raisonnablement complexe.
  3. Exemple de requête SELECT qui vous permet de renvoyer l’adresse IP IPv6 au client.
  4. Dépannage pour vous assurer de ne manquer aucun code hérité.

J’ai changé tous les noms de colonnes en ipv6 pour ipv6 qu’ils supportaient correctement IPv6 (et cela vous permet de conserver l’ancienne colonne ip intacte). Il est possible de stocker la colonne ip dans la colonne ipv6 , puis de simplement faire couler la colonne ip une fois que vous êtes certain que la conversion a fonctionné; Quand j’aurai le temps, j’appendai cela à cet article.

Type de données IPv6

Comme cela a été mentionné, VARBINARY 16 est la manière souhaitable de continuer jusqu’à ce que AMD nous bénisse avec des processeurs à 128 bits et que les bases de données soient mises à jour pour prendre en charge les entiers à 128 bits (est-ce que je l’ai dit correctement?). IPv6 est 128 bits, pas 64 bits.

 CREATE TABLE `example` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `ipv6` VARBINARY(16) NOT NULL, PRIMARY KEY (`id`) ) COLLATE='utf8mb4_unicode_520_ci' ENGINE=InnoDB; 

IPv6 INSERT Query

Nous devons évidemment stocker une adresse IP IPv6 avant de pouvoir la sélectionner. voici le code PHP / SQL :

 $ipv6 = mysqli_real_escape_ssortingng($db,'FE80:0000:0000:0000:0202:B3FF:FE1E:8329'); $query1 = "INSERT INTO example (ipv6) VALUES (INET6_ATON('$ipv6'));"; 

Requête IPv6 SELECT

Le code PHP / SQL :

 $ipv6 = mysqli_real_escape_ssortingng($db,'FE80:0000:0000:0000:0202:B3FF:FE1E:8329'); $query2 = "SELECT INET6_NTOA(ipv6) AS ipv6 FROM example WHERE ipv6=INET6_ATON('$ipv6');"; 

Cela retournera fe80::202:b3ff:fe1e:8329 ; non, pas l’IPv6 complet (qui est FE80:0000:0000:0000:0202:B3FF:FE1E:8329 ), c’est une version condensée / abrégée. Il y a du code pour en faire la version intégrale formelle, mais cela permet de gagner du temps et d’économiser du temps, car cette Q / R est celle qui continue à arriver.

Important: le fait que certaines adresses IPv6 semblent s’intégrer à bigint n’implique pas deux minutes plus tard qu’une personne possédant une adresse IPv6 plus importante ne s’arrête pas et cause des ravages.

Avec un peu de chance, cela sauvera quelques personnes de la folie d’ouvrir deux autres tabs. Lorsque j’aurai le temps, j’appendai le code PHP supplémentaire qui étendra l’IPv6 condensé au format formel complet.


Dépannage

Si, pour une raison quelconque, le stockage et / ou la récupération d’adresses IPv6 ne fonctionnent pas, prenez-vous une copie de Advanced Find and Replace (fonctionne plus rapidement dans Wine que le grep natif de Linux); utilisez-le principalement pour trouver, ne pas remplacer. Assurez-vous que votre code est cohérent partout dans votre logiciel.

  • Toutes les variables $ip doivent être converties en $ipv6 pour que vous sachiez que ce bit est couvert.
  • N’oubliez pas de supprimer la fin des quatre prochaines étapes:
  • Recherchez toutes les instances de PHP inet_pton( fonctions et supprimez-les).
  • Recherchez toutes les instances de PHP inet_ntop( fonctions et supprimez-les).
  • Recherchez toutes les instances de SQL INET_ATON( fonctions et supprimez-les).
  • Recherchez toutes les instances de SQL INET_NTOA( fonctions et supprimez-les).
  • Recherchez toutes les instances de $ipv6 et assurez-vous que toutes les instances IP-IN-TO-SQL utilisent INET6_ATON('$ipv6') et toutes les instances où IP-FROM-SQL utilise INET6_NTOA(ipv6) AS ipv6 .
  • Recherchez toutes les instances de $row1['ip'] et remplacez-les par $row1['ipv6'] .
  • Assurez-vous que toutes les instances de $ipv6 = utilisent le code suivant (avec la référence de votre object de firebase database modifiée): $ipv6 = (isset($_SERVER['REMOTE_ADDR']) && strlen($_SERVER['REMOTE_ADDR']) > 0) ? mysqli_real_escape_ssortingng($db,$_SERVER['REMOTE_ADDR']) : mysqli_real_escape_ssortingng($db,getenv('REMOTE_ADDR')); $ipv6 = (isset($_SERVER['REMOTE_ADDR']) && strlen($_SERVER['REMOTE_ADDR']) > 0) ? mysqli_real_escape_ssortingng($db,$_SERVER['REMOTE_ADDR']) : mysqli_real_escape_ssortingng($db,getenv('REMOTE_ADDR')); .
  • Assurez-vous que vos tests utilisent des adresses IP fraîchement testées au lieu de versions potentiellement ratées si vous savez que quelque chose ne fonctionnait pas avant de commencer le débogage.

Excellent exemple cependant j’ai noté ce qui suit. Cela ne fonctionne que si la version de mysql a pour fonction INET6_ATON . Sinon, le message d’erreur pourrait ressembler à DOES : Cette FUNCTION DOES NOT .