2017-09-19 6 views
0

J'ai un application which uses Perl's gethostbyname to check if a hostname exists in DNS donné. Je ne veux pas patcher le code source de cette application non écrite par moi. Mais je pense à écraser gethostbyname dans l'un des fichiers de configuration écrits en Perl.Est-il possible d'écraser ou d'obtenir gethostbyname de monkey-patch en Perl pour qu'il prenne en charge IPv6?

Alors je me demande s'il y a une chance d'écraser cette fonction en la corrigeant d'une manière ou d'une autre.

Le documentation of that application says that its hostname lookups work as follows:

$ perl -e 'print(gethostbyname("ipv6.google.com") ? "ok\n" : "not found\n");' 
not found 

Jusqu'à présent, j'essayé:

$ perl -E 'use Socket qw(:DEFAULT getaddrinfo); sub gethostbyname { my ($err, @result) = getaddrinfo(@_); return @result; }; print(gethostbyname("ipv6.google.com") ? "ok\n" : "not found\n");' 
not found 

Et:

$ perl -E 'use Socket qw(:DEFAULT getaddrinfo); use Monkey::Patch::Action qw(patch_package); patch_package("*", "gethostbyname", "add", sub { my ($err, @result) = getaddrinfo(@_); return @result; }); print(gethostbyname("ipv6.google.com") ? "ok\n" : "not found\n");' 
not found 

(j'ai aussi essayé main au lieu de * et replace au lieu de add.renflouées comme suit: Replacing *::gethostbyname: must already exist at /usr/share/perl5/Monkey/Patch/Action.pm line 31.)

+2

Dans le deuxième extrait, tout ce dont vous avez besoin est 'use subs qw (gethostbyname);'. – ikegami

+0

Dans le troisième extrait, je pense que l'emballage 'patch_package' avec un' BEGIN' fera l'affaire. – ikegami

+2

Mais vous voulez probablement corriger depuis l'extérieur du module qui a les appels à 'gethostbyname' (ou vous appelleriez simplement le bon sous à la place). Vous pouvez le faire en nommant votre remplacement 'CORE :: GLOBAL :: gethostbyname' (avant que le module utilisant' gethostbyname' soit chargé). Voir [Remplacement des fonctions intégrées] (https://perldoc.perl.org/perlsub.html#Overriding-Built-in-Functions). Vous pouvez utiliser 'caller' pour fournir uniquement le remplacement de certains modules. – ikegami

Répondre

3

TL, TR: Cela ne veut pas expliquer comment remplacer gethostbyname (les commentaires existants devraient aider à le faire), mais plutôt d'expliquer que cela ne résout pas votre problème réel de faire de ce code spécifique IPv6 prêt .


Premièrement, que devrait être un IPv6 prêt gethostbyname? Avec IPv4, il renvoie une adresse IPv4 compressée et cela est attendu par le code appelant gethostbyname. Ce code sera généralement suivi par l'utilisation de sockaddr_in, PF_INET sockets etc. Mais avec IPv6 ce code doit utiliser et PF_INET6 ce qui signifie qu'il ne suffit pas de corriger gethostbyname.

Et, en regardant plus loin dans le code, vous devez corriger cela est en fait le cas. Vous avez juste lié dans votre question à un appel de gethostbyname qui vérifie seulement s'il renvoie une valeur définie. Mais si vous regardez further in the code vous verrez l'utilisation explicite de inet_aton, PF_INET sockets etc., c'est-à-dire tout ce qui suppose des adresses IPv4 seulement.

+0

Merci d'avoir attrapé cela. Je n'ai pas causé que j'étais dans une course, mais c'est pourquoi j'ai posté des commentaires au lieu d'une réponse :) – ikegami

+0

Merci d'avoir creusé cette profondeur. Je pensais en effet qu'il vérifiait seulement si un nom d'hôte résout ou pas et qu'ainsi le type réel de la valeur de retour n'est pas pertinent. –