zb226
zb226

Reputation: 10509

Net::SMTP can't connect on Windows 8

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:

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

Answers (2)

Steffen Ullrich
Steffen Ullrich

Reputation: 123461

Based on the information from the other answer the underlying problem is, that

  • the hostname used resolves to both an IPv4 and IPv6 address,
  • the SMTP server is only listening at the IPv4 address or the IPv6 address is blocked by a firewall,
  • and a recent version of Net::SMTP is in use which contrary to older versions transparently supports IPv6 and IPv4.

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:

  • use the IPv4 address directly instead of the hostname
  • make the SMTP server listen on both IPv4 and IPv6
  • or specify the address family to use, i.e.
    my $smtp = Net::SMTP->new( 'mypc', ..., Domain => AF_INET );

Upvotes: 2

zb226
zb226

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

Related Questions