2017-09-19 47 views
0

我給出了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

回答

3

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

感謝您深入挖掘。我確實認爲它只是檢查一個主機名是否解析,因此返回值的實際類型是不相關的。 –

相關問題