Bodger has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to do an IPV4 SSL socket. I am following an example and it does not allow my client to connect because of the following error :cannot connect to the server :IO::Socket::INET6 configuration failed:. I do not want IPV6 and metacpan.org says to do something but does not tell me how to do that.

Here is what metacpan says

Please be aware, that with the IPv6 capable super classes, it will lookup first for the IPv6 address of a given hostname. If the resolver provides an IPv6 address, but the host cannot be reached by IPv6, there will be no automatic fallback to IPv4. To avoid these problems you can either force IPv4 by specifying and AF_INET as Domain of the socket or globally enforce IPv4 by loading IO::Socket::SSL with the option 'inet4'.

How do I specify AF_INET as Domain?

How do I load IO::Socket::SSL with the option 'inet4'?

Code

server

use strict; use warnings; use IO::Socket::SSL; # auto-flush on socket $| = 1; # creating a listening socket my $socket = new IO::Socket::SSL ( LocalHost => '0.0.0.0', LocalPort => '7777', Proto => 'tcp', Listen => 5, Reuse => 1, SSL_cert_file => 'cert.pem', SSL_key_file => 'key.pem', ); die "cannot create socket $!\n" unless $socket; print "server waiting for client connection on port 7777\n"; while(1) { # waiting for a new client connection my $client_socket = $socket->accept() or die "SSL_ERROR = :$SSL_ER +ROR:\n"; # get information about a newly connected client #my $client_address = $client_socket->peerhost(); #my $client_port = $client_socket->peerport(); #print "connection from $client_address:$client_port\n"; # read up to 1024 characters from the connected client my $data = ""; $client_socket->recv($data, 1024); print "received data: $data\n"; # write response data to the connected client $data = "ok"; $client_socket->send($data); # notify client that response has been sent shutdown($client_socket, 1); } $socket->close();

Client

use strict; use warnings; use IO::Socket::INET; use IO::Socket::SSL; # auto-flush on socket $| = 1; # create a connecting socket my $socket = new IO::Socket::SSL ( PeerAddr => '192.168.1.59', PeerPort => '7777', Proto => 'tcp', Domain => AF_INET, ); die "cannot connect to the server :$!: :$SSL_ERROR:\n" unless $socket; print "connected to the server\n"; # data to send to a server my $req = 'hello world'; my $size = $socket->send($req); print "sent data of length $size\n"; # notify server that request has been sent shutdown($socket, 1); # receive a response of up to 1024 characters from server my $response = ""; $socket->recv($response, 1024); print "received response: $response\n"; $socket->close();

When I do a netstat -anop | grep LISTEN it shows that my server is sitting on 0.0.0.0 port 7777 which is IPV4.

When the client does start it must do some communication to the server as the server dies at the accept line with this error

SSL accept attempt failed because of handshake problems error:14094418 +:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca

Any help would be appreciated.

Bodger

Replies are listed 'Best First'.
Re: IO::Socket::SSL as IPV4
by Athanasius (Cardinal) on Feb 15, 2015 at 03:22 UTC
Re: IO::Socket::SSL as IPV4
by noxxi (Pilgrim) on Feb 15, 2015 at 08:30 UTC

    Both IO::Socket::IP and IO::Socket::INET6 are capable of doing IPv4 and IPv6. And since you are explicitly giving a IPv4 address as target and even set AF_INET as domain your problem is not the use of IPv6 and you will have the same problem when disabling it.

    If you look at the error it clearly says what the real problem is:

    SSL accept attempt failed because of handshake problems error:14094418
    +:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca
    

    This means, that the certificate is not signed by a trusted CA. And I guess the name in the certificate will not match the name you gave in the client (i.e. the IP address). And since it complains about the certificate from the server it means that it successfully created a TCP connection to the server and got the certificate inside the SSL handshake. If IPv4 vs. IPv6 would be the problem it would already fail in establishing the TCP connection, so use of IPv6 is not your problem here.

Re: IO::Socket::SSL as IPV4
by Khen1950fx (Canon) on Feb 15, 2015 at 05:17 UTC
    First, follow Athanasius' advice. Second, you can undef IO::Socket::IP. For example:
    #!/usr/bin/perl BEGIN { $INC{'IO::Socket::INET6'} = undef; } use strict; use warnings; use IO::Socket::SSL 'inet4';
    Do that for both the server and client.