File: sysread_write.t

package info (click to toggle)
libio-socket-ssl-perl 2.002-2%2Bdeb8u3
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 1,348 kB
  • sloc: perl: 14,412; makefile: 4
file content (144 lines) | stat: -rw-r--r-- 3,798 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#!perl
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl t/sysread_write.t'

# This tests that sysread/syswrite behave different to read/write, e.g.
# that the latter ones are blocking until they read/write everything while
# the sys* function also can read/write partial data.

use strict;
use warnings;
use Net::SSLeay;
use Socket;
use IO::Socket::SSL;
do './testlib.pl' || do './t/testlib.pl' || die "no testlib";

$|=1;
print "1..9\n";

#################################################################
# create Server socket before forking client, so that it is
# guaranteed to be listening
#################################################################

# first create simple ssl-server
my $ID = 'server';
my $server = IO::Socket::SSL->new(
    LocalAddr => '127.0.0.1',
    LocalPort => 0,
    Listen => 2,
    SSL_cert_file => "certs/client-cert.pem",
    SSL_key_file => "certs/client-key.pem",
);
print "not ok: $!\n", exit if !$server;
ok("Server Initialization");

my $saddr = $server->sockhost.':'.$server->sockport;

defined( my $pid = fork() ) || die $!;
if ( $pid == 0 ) {

    ############################################################
    # CLIENT == child process
    ############################################################

    close($server);
    $ID = 'client';

    my $to_server = IO::Socket::SSL->new(
	PeerAddr => $saddr,
	SSL_ca_file => "certs/test-ca.pem",
    ) || do {
	print "not ok: connect failed: $!\n";
	exit
    };

    ok( "client connected" );

    # write 512 byte, server reads it in 66 byte chunks which
    # should cause at least the last read to be less then 66 bytes
    # (and not block).
    alarm(10);
    $SIG{ALRM} = sub {
	print "not ok: timed out\n";
	exit;
    };
    #DEBUG( "send 2x512 byte" );
    unless ( syswrite( $to_server, 'x' x 512 ) == 512
	and syswrite( $to_server, 'x' x 512 ) == 512 ) {
	print "not ok: write to small: $!\n";
	exit;
    }

    sysread( $to_server,my $ack,1 ) || print "not ";
    ok( "received ack" );

    alarm(0);
    ok( "send in time" );

    # make a syswrite with a buffer length greater than the
    # ssl message block size (16k for sslv3). It should send
    # only a partial packet of 16k
    my $n = syswrite( $to_server, 'x' x 18000 );
    #DEBUG( "send $n bytes" );
    print "not " if $n != 16384;
    ok( "partial write in syswrite" );

    # TODO does not work on Win32!!!
    print "ok # TODO(win32): " if $^O=~m{mswin32}i;
    # but write should send everything because it does ssl_write_all
    $n = $to_server->write( 'x' x 18000 );
    #DEBUG( "send $n bytes" );
    print "not " if $n != 18000;
    ok( "full write in write ($n)" );

    exit;

} else {

    ############################################################
    # SERVER == parent process
    ############################################################

    my $to_client = $server->accept || do {
	print "not ok: accept failed: $!\n";
	kill(9,$pid);
	exit;
    };
    ok( "Server accepted" );

    my $total = 1024;
    my $partial;
    while ( $total > 0 ) {
	#DEBUG( "reading 66 of $total bytes pending=".$to_client->pending() );
	my $n = sysread( $to_client, my $buf,66 );
	#DEBUG( "read $n bytes" );
	if ( !$n ) {
	    print "not ok: read failed: $!\n";
	    kill(9,$pid);
	    exit;
	} elsif ( $n != 66 ) {
	    $partial++;
	}
	$total -= $n;
    }
    print "not " if !$partial;
    ok( "partial read in sysread" );

    # send ack back
    print "not " if !syswrite( $to_client, 'x' );
    ok( "send ack back" );

    # just read so that the writes will not block
    $to_client->read( my $buf,18000 );
    $to_client->read( $buf,18000 );


    # wait until client exits
    wait;
}

exit;


sub ok { print "ok # [$ID] @_\n"; }