curl/0003-curl-7.23.0-e99128a.patch

340 lines
11 KiB
Diff

From 4da66a40bc4c29bb8b1bc325c45525826a6db531 Mon Sep 17 00:00:00 2001
From: Yang Tse <yangsita@gmail.com>
Date: Wed, 28 Dec 2011 23:04:23 +0100
Subject: [PATCH 1/2] ftpserver.pl: arbitrary application data splitting among
TCP packets [I]
Initial step in order to allow our pingpong server to better support arbitrary
application data splitting among TCP packets. This first commit only addresses
reasembly of data that sockfilter processes reads from soockets and pingpong
server later reads from sockfilters stdout.
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/ftpserver.pl | 165 +++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 151 insertions(+), 14 deletions(-)
diff --git a/tests/ftpserver.pl b/tests/ftpserver.pl
index 99722bb..cdd2916 100755
--- a/tests/ftpserver.pl
+++ b/tests/ftpserver.pl
@@ -116,6 +116,8 @@ local *SFWRITE; # used to write to primary connection
local *DREAD; # used to read from secondary connection
local *DWRITE; # used to write to secondary connection
+my $sockfilt_timeout = 5; # default timeout for sockfilter eXsysreads
+
#**********************************************************************
# global vars which depend on server protocol selection
#
@@ -220,6 +222,141 @@ sub ftpmsg {
# better on windows/cygwin
}
+#**********************************************************************
+# eXsysread is a wrapper around perl's sysread() function. This will
+# repeat the call to sysread() until it has actually read the complete
+# number of requested bytes or an unrecoverable condition occurs.
+# On success returns a positive value, the number of bytes requested.
+# On failure or timeout returns zero.
+#
+sub eXsysread {
+ my $FH = shift;
+ my $scalar = shift;
+ my $nbytes = shift;
+ my $timeout = shift; # A zero timeout disables eXsysread() time limit
+ #
+ my $time_limited = 0;
+ my $timeout_rest = 0;
+ my $start_time = 0;
+ my $nread = 0;
+ my $rc;
+
+ $$scalar = "";
+
+ if((not defined $nbytes) || ($nbytes < 1)) {
+ logmsg "Error: eXsysread() failure: " .
+ "length argument must be positive\n";
+ return 0;
+ }
+ if((not defined $timeout) || ($timeout < 0)) {
+ logmsg "Error: eXsysread() failure: " .
+ "timeout argument must be zero or positive\n";
+ return 0;
+ }
+ if($timeout > 0) {
+ # caller sets eXsysread() time limit
+ $time_limited = 1;
+ $timeout_rest = $timeout;
+ $start_time = int(time());
+ }
+
+ while($nread < $nbytes) {
+ if($time_limited) {
+ eval {
+ local $SIG{ALRM} = sub { die "alarm\n"; };
+ alarm $timeout_rest;
+ $rc = sysread($FH, $$scalar, $nbytes - $nread, $nread);
+ alarm 0;
+ };
+ $timeout_rest = $timeout - (int(time()) - $start_time);
+ if($timeout_rest < 1) {
+ logmsg "Error: eXsysread() failure: timed out\n";
+ return 0;
+ }
+ }
+ else {
+ $rc = sysread($FH, $$scalar, $nbytes - $nread, $nread);
+ }
+ if($got_exit_signal) {
+ logmsg "Error: eXsysread() failure: signalled to die\n";
+ return 0;
+ }
+ if(not defined $rc) {
+ if($!{EINTR}) {
+ logmsg "Warning: retrying sysread() interrupted system call\n";
+ next;
+ }
+ if($!{EAGAIN}) {
+ logmsg "Warning: retrying sysread() due to EAGAIN\n";
+ next;
+ }
+ if($!{EWOULDBLOCK}) {
+ logmsg "Warning: retrying sysread() due to EWOULDBLOCK\n";
+ next;
+ }
+ logmsg "Error: sysread() failure: $!\n";
+ return 0;
+ }
+ if($rc < 0) {
+ logmsg "Error: sysread() failure: returned negative value $rc\n";
+ return 0;
+ }
+ if($rc == 0) {
+ logmsg "Error: sysread() failure: read zero bytes\n";
+ return 0;
+ }
+ $nread += $rc;
+ }
+ return $nread;
+}
+
+#**********************************************************************
+# read_mainsockf attempts to read the given amount of output from the
+# sockfilter which is in use for the main or primary connection. This
+# reads untranslated sockfilt lingo which may hold data read from the
+# main or primary socket. On success returns 1, otherwise zero.
+#
+sub read_mainsockf {
+ my $scalar = shift;
+ my $nbytes = shift;
+ my $timeout = shift; # Optional argument, if zero blocks indefinitively
+ my $FH = \*SFREAD;
+
+ if(not defined $timeout) {
+ $timeout = $sockfilt_timeout + ($nbytes >> 12);
+ }
+ if(eXsysread($FH, $scalar, $nbytes, $timeout) != $nbytes) {
+ my ($fcaller, $lcaller) = (caller)[1,2];
+ logmsg "Error: read_mainsockf() failure at $fcaller " .
+ "line $lcaller. Due to eXsysread() failure\n";
+ return 0;
+ }
+ return 1;
+}
+
+#**********************************************************************
+# read_datasockf attempts to read the given amount of output from the
+# sockfilter which is in use for the data or secondary connection. This
+# reads untranslated sockfilt lingo which may hold data read from the
+# data or secondary socket. On success returns 1, otherwise zero.
+#
+sub read_datasockf {
+ my $scalar = shift;
+ my $nbytes = shift;
+ my $timeout = shift; # Optional argument, if zero blocks indefinitively
+ my $FH = \*DREAD;
+
+ if(not defined $timeout) {
+ $timeout = $sockfilt_timeout + ($nbytes >> 12);
+ }
+ if(eXsysread($FH, $scalar, $nbytes, $timeout) != $nbytes) {
+ my ($fcaller, $lcaller) = (caller)[1,2];
+ logmsg "Error: read_datasockf() failure at $fcaller " .
+ "line $lcaller. Due to eXsysread() failure\n";
+ return 0;
+ }
+ return 1;
+}
sub sysread_or_die {
my $FH = shift;
@@ -565,7 +702,7 @@ sub DATA_smtp {
$size = hex($1);
}
- sysread \*SFREAD, $line, $size;
+ read_mainsockf(\$line, $size);
$ulsize += $size;
print FILE $line if(!$nosave);
@@ -1140,7 +1277,7 @@ sub STOR_ftp {
$size = hex($1);
}
- sysread DREAD, $line, $size;
+ read_datasockf(\$line, $size);
#print STDERR " GOT: $size bytes\n";
@@ -1241,7 +1378,7 @@ sub PASV_ftp {
}
# READ the response data
- sysread_or_die(\*DREAD, \$i, $size);
+ read_datasockf(\$i, $size);
# The data is in the format
# IPvX/NNN
@@ -1815,38 +1952,38 @@ while(1) {
}
# data
- sysread SFREAD, $_, $size;
+ read_mainsockf(\$input, $size);
- ftpmsg $_;
+ ftpmsg $input;
# Remove trailing CRLF.
- s/[\n\r]+$//;
+ $input =~ s/[\n\r]+$//;
my $FTPCMD;
my $FTPARG;
- my $full=$_;
+ my $full = $input;
if($proto eq "imap") {
# IMAP is different with its identifier first on the command line
- unless (m/^([^ ]+) ([^ ]+) (.*)/ ||
- m/^([^ ]+) ([^ ]+)/) {
- sendcontrol "$1 '$_': command not understood.\r\n";
+ unless(($input =~ /^([^ ]+) ([^ ]+) (.*)/) ||
+ ($input =~ /^([^ ]+) ([^ ]+)/)) {
+ sendcontrol "$1 '$input': command not understood.\r\n";
last;
}
$cmdid=$1; # set the global variable
$FTPCMD=$2;
$FTPARG=$3;
}
- elsif (m/^([A-Z]{3,4})(\s(.*))?$/i) {
+ elsif($input =~ /^([A-Z]{3,4})(\s(.*))?$/i) {
$FTPCMD=$1;
$FTPARG=$3;
}
- elsif($proto eq "smtp" && m/^[A-Z0-9+\/]{0,512}={0,2}$/i) {
+ elsif(($proto eq "smtp") && ($input =~ /^[A-Z0-9+\/]{0,512}={0,2}$/i)) {
# SMTP long "commands" are base64 authentication data.
- $FTPCMD=$_;
+ $FTPCMD=$input;
$FTPARG="";
}
else {
- sendcontrol "500 '$_': command not understood.\r\n";
+ sendcontrol "500 '$input': command not understood.\r\n";
last;
}
--
1.7.8.1
From 17ef4b9449f434eb105c652a57fea61572c78b5a Mon Sep 17 00:00:00 2001
From: Yang Tse <yangsita@gmail.com>
Date: Thu, 29 Dec 2011 23:40:06 +0100
Subject: [PATCH 2/2] ftpserver.pl: arbitrary application data splitting among
TCP packets [II]
Take in account that 'pingpong' server commands may arrive splitted among
several sockfilt 'DATA' PDU's.
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/ftpserver.pl | 26 +++++++++++++++++---------
1 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/tests/ftpserver.pl b/tests/ftpserver.pl
index cdd2916..85476a2 100755
--- a/tests/ftpserver.pl
+++ b/tests/ftpserver.pl
@@ -1925,6 +1925,8 @@ while(1) {
}
}
+ my $full = "";
+
while(1) {
my $i;
@@ -1956,34 +1958,38 @@ while(1) {
ftpmsg $input;
+ $full .= $input;
+
+ # Loop until command completion
+ next unless($full =~ /\r\n$/);
+
# Remove trailing CRLF.
- $input =~ s/[\n\r]+$//;
+ $full =~ s/[\n\r]+$//;
my $FTPCMD;
my $FTPARG;
- my $full = $input;
if($proto eq "imap") {
# IMAP is different with its identifier first on the command line
- unless(($input =~ /^([^ ]+) ([^ ]+) (.*)/) ||
- ($input =~ /^([^ ]+) ([^ ]+)/)) {
- sendcontrol "$1 '$input': command not understood.\r\n";
+ unless(($full =~ /^([^ ]+) ([^ ]+) (.*)/) ||
+ ($full =~ /^([^ ]+) ([^ ]+)/)) {
+ sendcontrol "$1 '$full': command not understood.\r\n";
last;
}
$cmdid=$1; # set the global variable
$FTPCMD=$2;
$FTPARG=$3;
}
- elsif($input =~ /^([A-Z]{3,4})(\s(.*))?$/i) {
+ elsif($full =~ /^([A-Z]{3,4})(\s(.*))?$/i) {
$FTPCMD=$1;
$FTPARG=$3;
}
- elsif(($proto eq "smtp") && ($input =~ /^[A-Z0-9+\/]{0,512}={0,2}$/i)) {
+ elsif(($proto eq "smtp") && ($full =~ /^[A-Z0-9+\/]{0,512}={0,2}$/i)) {
# SMTP long "commands" are base64 authentication data.
- $FTPCMD=$input;
+ $FTPCMD=$full;
$FTPARG="";
}
else {
- sendcontrol "500 '$input': command not understood.\r\n";
+ sendcontrol "500 '$full': command not understood.\r\n";
last;
}
@@ -1993,6 +1999,8 @@ while(1) {
print STDERR "IN: $full\n";
}
+ $full = "";
+
my $delay = $delayreply{$FTPCMD};
if($delay) {
# just go sleep this many seconds!
--
1.7.8.1