mirror of
https://github.com/curl/curl.git
synced 2026-08-24 17:53:33 +03:00
tests: fix a race condition in ftp server disconnect
If a client disconnected and reconnected quickly, before the ftp server had a chance to respond, the protocol message/ack (ping/pong) sequence got out of sync, causing messages sent to the old client to be delivered to the new. A disconnect must now be acknowledged and intermediate requests thrown out until it is, which ensures that such synchronization problems can't occur. This problem could affect ftp, pop3, imap and smtp tests. Fixes #12002 Closes #12049
This commit is contained in:
parent
500f28f414
commit
f6513b9982
2 changed files with 146 additions and 26 deletions
|
|
@ -670,6 +670,51 @@ sub protocolsetup {
|
|||
}
|
||||
}
|
||||
|
||||
# Perform the disconnecgt handshake with sockfilt on the secondary connection
|
||||
# (the only connection we actively disconnect).
|
||||
# This involves waiting for the disconnect acknowledgmeent after the DISC
|
||||
# command, while throwing away anything else that might come in before
|
||||
# that.
|
||||
sub disc_handshake {
|
||||
print DWRITE "DISC\n";
|
||||
my $line;
|
||||
my $nr;
|
||||
while (5 == ($nr = sysread DREAD, $line, 5)) {
|
||||
if($line eq "DATA\n") {
|
||||
# Must read the data bytes to stay in sync
|
||||
my $i;
|
||||
sysread DREAD, $i, 5;
|
||||
|
||||
my $size = 0;
|
||||
if($i =~ /^([0-9a-fA-F]{4})\n/) {
|
||||
$size = hex($1);
|
||||
}
|
||||
|
||||
read_datasockf(\$line, $size);
|
||||
|
||||
logmsg "> Throwing away $size bytes on closed connection\n";
|
||||
}
|
||||
elsif($line eq "DISC\n") {
|
||||
logmsg "Fancy that; client wants to DISC, too\n";
|
||||
printf DWRITE "ACKD\n";
|
||||
}
|
||||
elsif($line eq "ACKD\n") {
|
||||
# Got the ack we were waiting for
|
||||
last;
|
||||
}
|
||||
else {
|
||||
logmsg "Ignoring: $line";
|
||||
# sockfilt should not be sending us any other commands
|
||||
}
|
||||
}
|
||||
if(!defined($nr)) {
|
||||
logmsg "Error: pipe read error ($!) while waiting for ACKD";
|
||||
}
|
||||
elsif($nr <= 0) {
|
||||
logmsg "Error: pipe EOF while waiting for ACKD";
|
||||
}
|
||||
}
|
||||
|
||||
sub close_dataconn {
|
||||
my ($closed)=@_; # non-zero if already disconnected
|
||||
|
||||
|
|
@ -680,9 +725,7 @@ sub close_dataconn {
|
|||
if(!$closed) {
|
||||
if($datapid > 0) {
|
||||
logmsg "Server disconnects $datasockf_mode DATA connection\n";
|
||||
print DWRITE "DISC\n";
|
||||
my $i;
|
||||
sysread DREAD, $i, 5;
|
||||
disc_handshake();
|
||||
logmsg "Server disconnected $datasockf_mode DATA connection\n";
|
||||
}
|
||||
else {
|
||||
|
|
@ -940,6 +983,7 @@ sub DATA_smtp {
|
|||
elsif($line eq "DISC\n") {
|
||||
# disconnect!
|
||||
$disc=1;
|
||||
printf SFWRITE "ACKD\n";
|
||||
last;
|
||||
}
|
||||
else {
|
||||
|
|
@ -1286,6 +1330,7 @@ sub APPEND_imap {
|
|||
}
|
||||
elsif($line eq "DISC\n") {
|
||||
logmsg "Unexpected disconnect!\n";
|
||||
printf SFWRITE "ACKD\n";
|
||||
last;
|
||||
}
|
||||
else {
|
||||
|
|
@ -2405,6 +2450,7 @@ sub STOR_ftp {
|
|||
elsif($line eq "DISC\n") {
|
||||
# disconnect!
|
||||
$disc=1;
|
||||
printf DWRITE "ACKD\n";
|
||||
last;
|
||||
}
|
||||
else {
|
||||
|
|
@ -3156,6 +3202,7 @@ while(1) {
|
|||
logmsg "MAIN sockfilt said $i";
|
||||
if($i =~ /^DISC/) {
|
||||
# disconnect
|
||||
printf SFWRITE "ACKD\n";
|
||||
last;
|
||||
}
|
||||
next;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue