Reputation: 10509
I wrote a minuscule script to test an SMTP connection with Net::SMTP
:
#!/usr/bin/perl -w
use strict;
use Net::SMTP;
my $smtp = Net::SMTP->new( 'mypc', Port => 10025, Timeout => 30, Debug => 1 );
die "Couldn't connect to SMTP server" unless $smtp;
An SMTP server is running on mypc:10025
and dumps all I/O it does. When I execute the script from a Debian Linux machine (64bit, Perl v5.20.2), the SMTP server shows I/O activity and everything works as expected:
zb226@debian8:~$ ./net_smtp.pl
Net::SMTP>>> Net::SMTP(2.33)
Net::SMTP>>> Net::Cmd(2.30)
Net::SMTP>>> Exporter(5.71)
Net::SMTP>>> IO::Socket::INET(1.35)
Net::SMTP>>> IO::Socket(1.38)
Net::SMTP>>> IO::Handle(1.35)
Net::SMTP=GLOB(0x118adc0)<<< 220 Hi
Net::SMTP=GLOB(0x118adc0)>>> EHLO localhost.localdomain
Net::SMTP=GLOB(0x118adc0)<<< 250 OK
When I execute this on the Windows 8 machine (64bit, Strawberry Perl 5.22.0), no connection is established. I can see this by the total absence of I/O in the SMTP server. Net::SMTP
does not connect. The script just dies, as is expected in this case:
C:\test>perl -w net_smtp.pl
Couldn't connect to SMTP server at net_smtp.pl line 5.
Observations:
telnet.exe
to connect to the SMTP server and it shows I/O activity.I'm not sure what to try next.
Edit: Tried a small IO::Socket::INET
script to verify perl can actually connect on this Windows PC:
#!/usr/bin/perl
use strict;
use IO::Socket::INET;
my @hosts = qw/ mypc:10025 /;
foreach my $host ( @hosts ) {
my $open = defined IO::Socket::INET->new(PeerAddr => $host, Timeout => 5) || 0;
printf "Probed %s -> %s \n", $host, $open ? 'ok' : 'NOK';
}
I see I/O in the SMTP server and it works as expected:
C:\test>perl -w io_socket.pl
Probed mypc:10025 -> ok
Upvotes: 2
Views: 142
Reputation: 123461
Based on the information from the other answer the underlying problem is, that
Because if the IPv6 support and the commonly used preference for the newer IPv6 against IPv4 Net::SMTP will resolve the hostname and then try the IPv6 address - and fail to connect. Direct use of IO::Socket::INET instead works because it is doing only IPv4 (contrary to IO::Socket::IP used by Net::SMTP).
The reason it works on Linux and not on Windows is probably the different version of Perl: the new version of Net::SMTP with built-in IPv6 (and SSL) support ships only since Perl 5.22 as a CORE module, i.e. the Perl on Windows (5.22) has the version with IPv6 support while the Perl on Linux (5.20) does not.
There are several ways to fix the problem:
my $smtp = Net::SMTP->new( 'mypc', ..., Domain => AF_INET );
Upvotes: 2
Reputation: 10509
Following this discussion, I found that the problem is related to IPv6. Opening C:\strawberry\perl\lib\Net\SMTP.pm
and changing the line...
our @ISA = ('Net::Cmd', $inet6_class || 'IO::Socket::INET');
...to...
our @ISA = ('Net::Cmd', 'IO::Socket::INET');
...makes the original script run:
C:\test>perl -w net_smtp.pl
Net::SMTP>>> Net::SMTP(3.08)
Net::SMTP>>> Net::Cmd(3.08)
Net::SMTP>>> Exporter(5.72)
Net::SMTP>>> IO::Socket::INET(1.35)
Net::SMTP>>> IO::Socket(1.38)
Net::SMTP>>> IO::Handle(1.36)
Net::SMTP=GLOB(0x58e8fc)<<< 220 Hi
Net::SMTP=GLOB(0x58e8fc)>>> EHLO localhost.localdomain
Net::SMTP=GLOB(0x58e8fc)<<< 250 OK
For now, I'm relieved because I can continue my work, but if anybody has further clues as to how to avoid this ugly patch, I'll happily accept an elaborated answer.
Edit: Correspondingly and without patching, disabling IPv6 does the trick as well.
Upvotes: 0