【问题标题】:Is it possible to overwrite or monkey-patch gethostbyname in Perl so that it supports IPv6?是否可以在 Perl 中覆盖或修补 gethostbyname 以支持 IPv6?
【发布时间】:2017-09-19 23:51:49
【问题描述】:

我有一个给定的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 代替addreplace 如下所示:Replacing *::gethostbyname: must already exist at /usr/share/perl5/Monkey/Patch/Action.pm line 31.

【问题讨论】:

  • 在第二个sn-p中,你只需要use subs qw( gethostbyname );
  • 在第三个 sn-p 中,我认为用 BEGIN 包裹 patch_package 就可以了。
  • 但是您可能希望从调用gethostbyname 的模块外部进行修补(或者您只需调用正确的子程序)。您可以通过将覆盖命名为CORE::GLOBAL::gethostbyname 来做到这一点(在加载使用gethostbyname 的模块之前)。见Overriding Built-in Functions。您可以使用caller 仅提供覆盖以选择模块。
  • 其实我也玩过BEGIN { },但我不记得是用patch_package还是只用sub gethostbyname { }。感谢 cmets!

标签: perl ipv6 gethostbyname


【解决方案1】:

TL;TR:这不是解释如何覆盖 gethostbyname(现有的 cmets 应该有助于这样做),而是解释这并不能解决您使这个特定代码准备好 IPv6 的实际问题。


首先,IPv6 就绪的gethostbyname 应该返回什么?对于 IPv4,它返回一个打包的 IPv4 地址,这是调用 gethostbyname 的代码所期望的。此类代码后通常会使用 sockaddr_inPF_INET 套接字等。但对于 IPv6,此代码需要使用 sockaddr_in6PF_INET6,这意味着修补 gethostbyname 是不够的。

而且,进一步研究您必须修复的代码实际上就是这种情况。你刚刚在你的问题中链接到gethostbyname 的调用,它只检查它是否返回一个定义的值。但是,如果您查看further in the code,您会看到inet_atonPF_INET 套接字等的明确使用,即假设所有内容仅使用 IPv4 地址。

【讨论】:

  • 感谢收看这个。我并不是因为我很着急,但这就是我发布 cmets 而不是答案的原因:)
  • 感谢您深入挖掘。我确实认为它只是检查主机名是否解析,因此返回值的实际类型无关紧要。
猜你喜欢
  • 1970-01-01
  • 2018-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-10
  • 2010-12-03
相关资源
最近更新 更多