我有一个给定的application which uses Perl's gethostbyname
to check if a hostname exists in DNS。我不想修补那些不是我写的应用程序的源代码。但我想在其中一个Perl编写的配置文件中覆盖gethostbyname
。
所以我想知道是否有机会通过猴子修补它以某种方式覆盖该功能。
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
而不是add
。replace
如下所示:Replacing *::gethostbyname: must already exist at /usr/share/perl5/Monkey/Patch/Action.pm line 31.
)< / p>
答案 0 :(得分:3)
TL; TR:这不是解释如何覆盖gethostbyname
(现有的评论应该有助于这样做),而是解释这并不能解决使这个特定代码IPv6准备就绪的实际问题。
首先,IPv6准备gethostbyname
应该返回什么?使用IPv4,它返回一个打包的IPv4地址,这是代码调用gethostbyname
所期望的。此类代码通常会使用sockaddr_in
,PF_INET
套接字等。但使用IPv6时,此代码需要使用sockaddr_in6
和PF_INET6
,这意味着它不够补丁gethostbyname
。
而且,进一步研究代码,你必须解决这个问题。您只是将问题链接到gethostbyname
的调用,该调用仅检查它是否返回定义的值。但是,如果您查看further in the code,您会看到明确使用inet_aton
,PF_INET
套接字等,即所有假定IPv4仅为地址的内容。