version 1.23, 2003/11/04 11:23:37
|
version 1.25, 2003/11/04 11:52:06
|
Line 80 my $ServerPort; # Port used to connect
|
Line 80 my $ServerPort; # Port used to connect
|
my $TransitionTimeout = 5; # Poll timeout in seconds. |
my $TransitionTimeout = 5; # Poll timeout in seconds. |
|
|
|
|
LondConnection::SetDebug(10); |
# LondConnection::SetDebug(10); |
|
|
|
|
# |
# |
Line 133 sub MakeLondConnection {
|
Line 133 sub MakeLondConnection {
|
return return $Connection; |
return return $Connection; |
} |
} |
# |
# |
|
# Process the connection state machine until the connection |
|
# becomes idle. This is used both to negotiate the initial |
|
# connection, during which the LondConnection sequences a rather |
|
# complex state machine and during the transaction itself |
|
# for a simpler set of transitions. |
|
# All we really need to be concerned with is whether or not |
|
# we're readable or writable and the final state: |
|
# |
|
# Parameter: |
|
# connection - Represents the LondConnection to be sequenced. |
|
# timeout - Maximum time to wait for readable/writable sockets. |
|
# in seconds. < 0 waits forever. |
|
# Return: |
|
# 'ok' - We got to idle ok. |
|
# 'error:msg' - An error occured. msg describes the error. |
|
# |
|
sub SequenceStateMachine { |
|
my $connection = shift; |
|
my $timeout = shift; |
|
|
|
my $Socket = $connection->GetSocket; |
|
my $returnstatus = "ok"; # optimist!!! |
|
my $error = 0; # Used to force early loop termination |
|
# damned perl has no break!!. |
|
my $state = $connection->GetState; |
|
|
|
while(($connection->GetState ne "Idle") && (!$error)) { |
|
# |
|
# Figure out what the connection wants. read/write and wait for it |
|
# or for the timeout. |
|
# |
|
my $wantread = $connection->WantReadable; |
|
my $poll = new IO::Poll; |
|
$poll->mask($Socket, => $wantread ? POLLIN : POLLOUT); |
|
$poll->poll($timeout); |
|
my $done = $poll->handles(); |
|
if(scalar($done) == 0) { # no handles ready... timeout!! |
|
$returnstatus = "error:"; |
|
$returnstatus .= "Timeout in state $state\n"; |
|
$error = 1; |
|
} else { |
|
my $status; |
|
$status = $wantread ? $connection->Readable : |
|
$connection->Writable; |
|
if($status != 0) { |
|
$returnstatus = "error:"; |
|
$returnstatus .= " I/O failed in state $state\n"; |
|
$error = 1; |
|
} |
|
} |
|
$state = $connection->GetState; |
|
} |
|
return $returnstatus; |
|
} |
|
|
|
# |
# This function runs through the section of the connection |
# This function runs through the section of the connection |
# state machine that has to do with negotiating the startup |
# state machine that has to do with negotiating the startup |
# sequence with lond. The general strategy is to loop |
# sequence with lond. The general strategy is to loop |
Line 163 sub NegotiateStartup {
|
Line 219 sub NegotiateStartup {
|
print "Error: Initial lond connection state: $state should be Connected\n"; |
print "Error: Initial lond connection state: $state should be Connected\n"; |
return "error"; |
return "error"; |
} |
} |
my $Socket = $connection->GetSocket; # This is a IO:Socket::INET object. |
|
|
|
# Ready now to enter the main loop: |
|
# |
|
my $error = 0; |
|
while (($connection->GetState ne "Idle") && (!$error)) { |
|
# |
|
# Wait for the socket to get into the appropriate state: |
|
# |
|
my $wantread = $connection->WantReadable; |
|
my $poll = new IO::Poll; |
|
$poll->mask($Socket => $wantread ? POLLIN : POLLOUT); |
|
$poll->poll($TransitionTimeout); |
|
my $done = $poll->handles(); |
|
if(scalar($done) == 0) { # Timeout!!! |
|
print "Error: Timeout in state : $state negotiating connection\n"; |
|
$returnstatus = "error"; |
|
$error = 1; |
|
} else { |
|
my $status; |
|
$status = $wantread ? $connection->Readable : $connection->Writable; |
|
if ($status != 0) { |
|
print "Error: I/O failed in state : $state negotiating connection\n"; |
|
$returnstatus = "error"; |
|
$error = 1; |
|
} |
|
} |
|
} |
|
|
|
|
return SequenceStateMachine($connection, $TransitionTimeout); |
return $returnstatus; |
|
} |
} |
|
# |
|
# Perform a transaction with the remote lond. |
|
# Paramters: |
|
# connection - the connection object that represents |
|
# a LondConnection to the remote lond. |
|
# command - The request to send to the remote system. |
|
# Returns: |
|
# The 'reaction' of the lond to this command. |
|
# However if the connection to lond is lost during the transaction |
|
# or some other error occurs, the text "error:con_lost" is returned. |
|
# |
sub PerformTransaction { |
sub PerformTransaction { |
my $connection = shift; |
my $connection = shift; |
my $command = shift; |
my $command = shift; |
|
my $retval; # What we'll returnl. |
|
|
|
|
|
# Set up the connection to do the transaction then |
|
# do the I/O until idle or error. |
|
# |
|
$connection->InitiateTransaction($command); |
|
|
|
my $status = SequenceStateMachine($connection, $TransitionTimeout); |
|
if($status eq "ok") { |
|
$retval = $connection->GetReply; |
|
} else { |
|
$retval = $status; |
|
} |
|
|
return "ok"; |
return $retval; |
} |
} |
# |
# |
# Performs a transaction direct to a remote lond. |
# Performs a transaction direct to a remote lond. |
Line 223 sub subreply {
|
Line 275 sub subreply {
|
if($reply ne "ok") { |
if($reply ne "ok") { |
return "connection negotiation failed"; |
return "connection negotiation failed"; |
} |
} |
print "Connection negotiated\n"; |
|
my $reply = PerformTransaction($connection, $cmd); |
my $reply = PerformTransaction($connection, $cmd); |
return $reply; |
return $reply; |
|
|