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

是否可以在Perl中覆盖或修补gethostbyname以支持IPv6?,perl,ipv6,gethostbyname,Perl,Ipv6,Gethostbyname,我有一个好主意。我不想修补不是我写的应用程序的源代码。但是我考虑在一个Perl编写的配置文件中覆盖gethostbyname 所以我想知道是否有机会通过某种方式对其进行猴子补丁来覆盖该函数 委员会: 到目前为止,我试过: $ perl -E 'use Socket qw(:DEFAULT getaddrinfo); sub gethostbyname { my ($err, @result) = getaddrinfo(@_); return @result; }; print(gethostb

我有一个好主意。我不想修补不是我写的应用程序的源代码。但是我考虑在一个Perl编写的配置文件中覆盖
gethostbyname

所以我想知道是否有机会通过某种方式对其进行猴子补丁来覆盖该函数

委员会:

到目前为止,我试过:

$ 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
以及:


(我还尝试了
main
而不是
*
replace
而不是
add
replace
以如下方式被解救:
replacement*::gethostbyname:必须已经存在于/usr/share/perl5/Monkey/Patch/Action.pm第31行。

TL;TR:这并不是解释如何重写
gethostbyname
(现有的注释应该有助于做到这一点),而是解释这并不能解决准备好此特定代码的实际问题


首先,IPv6就绪
gethostbyname
应该返回什么?对于IPv4,它返回一个压缩的IPv4地址,这是代码调用
gethostbyname
所期望的。这种代码后面通常会使用
sockaddr\u in
PF\u INET
sockets等。但在IPv6中,此代码需要使用
sockaddr\u in 6
PF\u INET6
,这意味着修补
gethostbyname
是不够的


而且,进一步研究代码,您必须修复这一问题,事实上就是这样。您刚刚在问题中链接到一个调用
gethostbyname
,该调用只检查它是否返回定义的值。但是如果你看一下,你会看到显式地使用了
inet\u aton
PF\u inet
套接字等,也就是说,所有东西都假设只有IPv4地址;TR:这并不是解释如何重写
gethostbyname
(现有的注释应该有助于做到这一点),而是解释这并不能解决准备好此特定代码的实际问题


首先,IPv6就绪
gethostbyname
应该返回什么?对于IPv4,它返回一个压缩的IPv4地址,这是代码调用
gethostbyname
所期望的。这种代码后面通常会使用
sockaddr\u in
PF\u INET
sockets等。但在IPv6中,此代码需要使用
sockaddr\u in 6
PF\u INET6
,这意味着修补
gethostbyname
是不够的


而且,进一步研究代码,您必须修复这一问题,事实上就是这样。您刚刚在问题中链接到一个调用
gethostbyname
,该调用只检查它是否返回定义的值。但是如果你看一下,你会看到显式使用
inet\u aton
PF\u inet
sockets等,也就是说,所有东西都假设只有IPv4地址。

在第二个代码片段中,你所需要的就是
使用subs qw(gethostbyname)。在第三个代码段中,我认为用
开始
包装
patch_包
就可以了。但是您可能希望从调用
gethostbyname
的模块外部进行修补(或者您只需调用正确的子模块)。您可以通过命名覆盖
CORE::GLOBAL::gethostbyname
(在加载使用
gethostbyname
的模块之前)来实现这一点。看见您可以使用
调用者
只提供选择模块的覆盖。实际上我也使用了
开始{}
,但我不记得是使用
补丁包
还是仅使用
sub-gethostbyname{}
。谢谢你的评论!在第二个代码段中,您只需要
使用subs qw(gethostbyname)。在第三个代码段中,我认为用
开始
包装
patch_包
就可以了。但是您可能希望从调用
gethostbyname
的模块外部进行修补(或者您只需调用正确的子模块)。您可以通过命名覆盖
CORE::GLOBAL::gethostbyname
(在加载使用
gethostbyname
的模块之前)来实现这一点。看见您可以使用
调用者
只提供选择模块的覆盖。实际上我也使用了
开始{}
,但我不记得是使用
补丁包
还是仅使用
sub-gethostbyname{}
。谢谢你的评论!谢谢你抓到这个。我并不是因为赶时间,但这就是为什么我发表评论而不是回答:)谢谢你深入挖掘。我确实认为这只是检查主机名是否解析,因此返回值的实际类型是不相关的。感谢您捕捉到这一点。我并不是因为赶时间,但这就是为什么我发表评论而不是回答:)谢谢你深入挖掘。我确实认为这只是检查主机名是否解析,因此返回值的实际类型是无关的。
$ 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