是否可以在Perl中覆盖或修改gethostbyname以支持IPv6?

问题描述:

我给出了application which uses Perl's gethostbyname to check if a hostname exists in DNS。我不想修补不是由我写的应用程序的源代码。但我想在Perl编写的配置文件之一中覆盖gethostbyname是否可以在Perl中覆盖或修改gethostbyname以支持IPv6?

所以我想知道是否有机会以某种方式猴子修补它。

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 

到目前为止,我尝试:

$ 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 

而且:

$ 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 

(我也试过main代替*replace代替addreplace跳伞如下:Replacing *::gethostbyname: must already exist at /usr/share/perl5/Monkey/Patch/Action.pm line 31.

+2

在第二个片段中,你所需要的只是'use subs qw(gethostbyname);'。 – ikegami

+0

在第三个片段中,我认为用'BEGIN'包装'patch_package'就可以了。 – ikegami

+2

但是你可能想要从调用'gethostbyname'的模块外面打补丁(或者你只需​​要调用正确的sub)。你可以通过命名你的覆盖'CORE :: GLOBAL :: gethostbyname'(在使用'gethostbyname'的模块被加载之前)来做到这一点。请参阅[覆盖内置函数](https://perldoc.perl.org/perlsub.html#Overriding-Built-in-Functions)。您可以使用'caller'来仅提供覆盖选择模块。 – ikegami

TL; TR:那不是解释如何覆盖gethostbyname(现有的意见应帮助这样做),而是解释说,这不能解决使这一特定代码的实际问题,支持IPv6 。


首先,IPv6准备gethostbyname应该返回什么?使用IPv4时,它将返回一个打包的IPv4地址,代码gethostbyname的预期值就是这样。此类代码通常会使用sockaddr_inPF_INET套接字等。但对于IPv6,此代码需要使用和PF_INET6,这意味着它不足以修补gethostbyname

而且,要进一步研究代码,您必须解决这个问题实际上就是这样。您只需将您的问题链接到gethostbyname的电话,该电话只会检查是否返回定义的值。但是如果你看further in the code,你会看到明确使用inet_atonPF_INET套接字等,即所有假定只有IPv4地址的东西。

+0

感谢您的支持。我没有因为我很忙,但这就是为什么我发表评论,而不是回答:) – ikegami

+0

感谢您深入挖掘。我确实认为它只是检查一个主机名是否解析,因此返回值的实际类型是不相关的。 –