use warnings; use strict; use IO::Socket::SSL; use constant { BUFSIZE => 16384 }; die 'Invalid BUFSIZE value (must be a multiple of 16)' if(BUFSIZE%16); my $LOCAL_ADDR='0.0.0.0'; my $LOCAL_PORT=1234; my $BUFFER = '0123456789ABCDEF' x (BUFSIZE/16); my $srvSock; $srvSock=IO::Socket::SSL->new( LocalHost => $LOCAL_ADDR, LocalPort => $LOCAL_PORT, ReuseAddr => 1, Listen => 1, SSL_cert_file => 'cert.pem', SSL_key_file => 'key.pem', ) or die "Failed to create listening SSL socket: $!"; print "SSL server listening on $LOCAL_ADDR:$LOCAL_PORT\n"; while() { print "Waiting for client to connect...\n"; my $clientSock = $srvSock->accept() or die "Failed to accept SSL client connection: $!, $SSL_ERROR\n"; print "Client connected, sending data.\n"; while() { my $writeLength=syswrite($clientSock,$BUFFER) or do { print " Failed to write to client: $!, $SSL_ERROR\n"; last; }; if($writeLength != BUFSIZE) { print " Unexpected write length: $writeLength\n"; last; } } } #### use warnings; use strict; use IO::Socket::SSL; use Time::HiRes qw'time'; use constant { BUFSIZE => 16384, INTERVAL => 1, }; my $PEER_ADDR='192.168.1.10'; my $PEER_PORT=1234; print "Connecting to SSL server ($PEER_ADDR:$PEER_PORT)\n"; my $clientSock = IO::Socket::SSL->new( PeerHost => $PEER_ADDR, PeerPort => $PEER_PORT, Proto => 'tcp', SSL_verify_mode => SSL_VERIFY_NONE, ) or die "Failed to connect to SSL server: $!, $SSL_ERROR"; print "Connected, switching to non-blocking mode.\n"; $clientSock->blocking(0); my $sockVec=''; vec($sockVec,fileno($clientSock),1)=1; my ($nbRead,$nbSslWantRead,$nbSslWantWrite,$transferred)=(0,0,0,0); print "Downloading data from server...\n"; my $currentTime=time(); my ($intvlStart,$intvlEnd)=($currentTime,$currentTime+INTERVAL); while() { # There should be no pending data when BUFSIZE = max SSL frame size die 'Unexpected pending data in SSL socket' if($clientSock->pending()); $!=0; select(my $readyVec=$sockVec,undef,undef,undef) > 0 or die "Error in select for read: $!"; my $readLength=sysread($clientSock,my $readData,BUFSIZE); $nbRead++; if(defined $readLength) { die "Connection closed by peer" unless($readLength); die "Unexpected read length: $readLength" unless($readLength == BUFSIZE); }else{ die "Failed to read from SSL socket: $!" unless($!{EWOULDBLOCK} || $!{EAGAIN}); if($SSL_ERROR == SSL_WANT_READ) { $nbSslWantRead++; next; } if($SSL_ERROR == SSL_WANT_WRITE) { $nbSslWantWrite++; select(undef,my $readyVec=$sockVec,undef,undef) > 0 or die "Error in select for write: $!"; next; } die 'Unexpected WOULDBLOCK/EAGAIN status when trying to read'; } $transferred+=BUFSIZE; $currentTime=time(); if($currentTime >= $intvlEnd) { printReport(); initNewInterval(); } } sub printReport { my $speed=formatSize($transferred/($currentTime-$intvlStart)); my $pctSslWantRead=sprintf('%.2f',$nbSslWantRead*100/$nbRead); my $pctSslWantWrite=sprintf('%.2f',$nbSslWantWrite*100/$nbRead); print "Transfer speed: $speed/s\n"; print " Read failure due to SSL_WANT_READ: $pctSslWantRead%\n"; print " Read failure due to SSL_WANT_WRITE: $pctSslWantWrite%\n"; } sub formatSize { my $size=shift; my @UNITS=('',qw'K M G T'); my $unitIdx=0; while($size >= 1000 && $unitIdx < $#UNITS) { $size/=1000; $unitIdx++; } $size=sprintf('%.2f',$size) if(index($size,'.') != -1); return $size.' '.$UNITS[$unitIdx].'B'; } sub initNewInterval { ($nbRead,$nbSslWantRead,$nbSslWantWrite,$transferred)=(0,0,0,0); $intvlStart=$currentTime; $intvlEnd+=INTERVAL while($intvlEnd < $intvlStart+INTERVAL/2); } #### $ perl sslclinb.pl Connecting to SSL server (192.168.1.10:1234) Connected, switching to non-blocking mode. Downloading data from server... Transfer speed: 117.55 MB/s Read failure due to SSL_WANT_READ: 87.46% Read failure due to SSL_WANT_WRITE: 0.00% Transfer speed: 117.61 MB/s Read failure due to SSL_WANT_READ: 90.84% Read failure due to SSL_WANT_WRITE: 0.00% Transfer speed: 117.61 MB/s Read failure due to SSL_WANT_READ: 90.84% Read failure due to SSL_WANT_WRITE: 0.00% Transfer speed: 117.61 MB/s Read failure due to SSL_WANT_READ: 90.88% Read failure due to SSL_WANT_WRITE: 0.00% Transfer speed: 117.61 MB/s Read failure due to SSL_WANT_READ: 90.50% Read failure due to SSL_WANT_WRITE: 0.00% Transfer speed: 117.61 MB/s Read failure due to SSL_WANT_READ: 82.52% Read failure due to SSL_WANT_WRITE: 0.00% Transfer speed: 117.61 MB/s Read failure due to SSL_WANT_READ: 82.63% Read failure due to SSL_WANT_WRITE: 0.00% Transfer speed: 117.61 MB/s Read failure due to SSL_WANT_READ: 82.58% Read failure due to SSL_WANT_WRITE: 0.00% Transfer speed: 117.61 MB/s Read failure due to SSL_WANT_READ: 82.58% Read failure due to SSL_WANT_WRITE: 0.00% Transfer speed: 117.61 MB/s Read failure due to SSL_WANT_READ: 82.57% Read failure due to SSL_WANT_WRITE: 0.00% ^C