--- loncom/LondConnection.pm 2003/04/18 05:52:43 1.2 +++ loncom/LondConnection.pm 2003/04/18 06:07:27 1.3 @@ -1,7 +1,7 @@ # This module defines and implements a class that represents # a connection to a lond daemon. # -# $Id: LondConnection.pm,v 1.2 2003/04/18 05:52:43 albertel Exp $ +# $Id: LondConnection.pm,v 1.3 2003/04/18 06:07:27 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -59,8 +59,13 @@ sub Debug { print($message."\n"); } } -=pod - Dump the internal state of the object: For debugging purposes. + +=pod + +=head2 Dump + +Dump the internal state of the object: For debugging purposes. + =cut sub Dump { @@ -73,9 +78,13 @@ sub Dump { } =pod - Local function to do a state transition. If the state transition callback - is defined it is called with two parameters: the self and the old state. + +Local function to do a state transition. If the state transition +callback is defined it is called with two parameters: the self and the +old state. + =cut + sub Transition { my $self = shift; my $newstate = shift; @@ -87,13 +96,25 @@ sub Transition { } } + =pod - Construct a new lond connection. - Parameters (besides the class name) include: -=item hostname - host the remote lond is on. - This host is a host in the hosts.tab file -=item port - port number the remote lond is listening on. + +=head2 new + +Construct a new lond connection. + +Parameters (besides the class name) include: + +=item hostname + +host the remote lond is on. This host is a host in the hosts.tab file + +=item port + + port number the remote lond is listening on. + =cut + sub new { my $class = shift; # class name. my $Hostname = shift; # Name of host to connect to. @@ -160,19 +181,33 @@ sub new { return $self; } + =pod - This member should be called when the Socket becomes readable. - Until the read completes, action is state independet. Data are accepted - into the TransactionReply until a newline character is received. At that - time actionis state dependent: -=item Connected: in this case we received challenge, the state changes - to ChallengeReceived, and we initiate a send with the challenge response. -=item ReceivingReply: In this case a reply has been received for a transaction, - the state goes to Idle and we disable write and read notification. -=item ChallengeReeived: we just got what should be an ok\n and the - connection can now handle transactions. + +=head2 Readable + +This member should be called when the Socket becomes readable. Until +the read completes, action is state independet. Data are accepted into +the TransactionReply until a newline character is received. At that +time actionis state dependent: + +=item Connected + +in this case we received challenge, the state changes to +ChallengeReceived, and we initiate a send with the challenge response. + +=item ReceivingReply + +In this case a reply has been received for a transaction, the state +goes to Idle and we disable write and read notification. + +=item ChallengeReeived + +we just got what should be an ok\n and the connection can now handle +transactions. =cut + sub Readable { my $self = shift; my $socket = $self->{Socket}; @@ -280,13 +315,15 @@ sub Readable { =pod - This member should be called when the Socket becomes writable. -The action is state independent. An attempt is made to drain the contents of -the TransactionRequest member. Once this is drained, we mark the object -as waiting for readability. + +This member should be called when the Socket becomes writable. + +The action is state independent. An attempt is made to drain the +contents of the TransactionRequest member. Once this is drained, we +mark the object as waiting for readability. Returns 0 if successful, or -1 if not. - + =cut sub Writable { my $self = shift; # Get reference to the object. @@ -338,10 +375,14 @@ sub Writable { } =pod + +=head2 Tick + Tick is called every time unit by the event framework. It - 1. decrements the remaining timeout. - 2. If the timeout is zero, calls TimedOut indicating that the - current operation timed out. + +=item 1 decrements the remaining timeout. + +=item 2 If the timeout is zero, calls TimedOut indicating that the current operation timed out. =cut @@ -352,11 +393,16 @@ sub Tick { $self->TimedOut(); } } + =pod - TimedOut - called on a timeout. If the timeout callback is defined, - it is called with $self as its parameters. -=cut +=head2 TimedOut + +called on a timeout. If the timeout callback is defined, it is called +with $self as its parameters. + +=cut + sub TimedOut { my $self = shift; @@ -366,14 +412,20 @@ sub TimedOut { &$callback(@args); } } + =pod - Called to initiate a transaction. A transaction can only be initiated - when the object is idle... otherwise an error is returned. - A transaction consists of a request to the server that will have a reply. - This member sets the request data in the TransactionRequest member, - makes the state SendingRequest and sets the data to allow a timout, - and to request writability notification. + +=head2 InitiateTransaction + +Called to initiate a transaction. A transaction can only be initiated +when the object is idle... otherwise an error is returned. A +transaction consists of a request to the server that will have a +reply. This member sets the request data in the TransactionRequest +member, makes the state SendingRequest and sets the data to allow a +timout, and to request writability notification. + =cut + sub InitiateTransaction { my $self = shift; my $data = shift; @@ -400,19 +452,30 @@ sub InitiateTransaction { =pod - Sets a callback for state transitions. Returns a reference to any - prior established callback, or undef if there was none: + +=head2 SetStateTransitionCallback + +Sets a callback for state transitions. Returns a reference to any +prior established callback, or undef if there was none: + =cut + sub SetStateTransitionCallback { my $self = shift; my $oldCallback = $self->{TransitionCallback}; $self->{TransitionCallback} = shift; return $oldCallback; } + =pod - Sets the timeout callback. Returns a reference to any prior established - callback or undef if there was none. + +=head2 SetTimeoutCallback + +Sets the timeout callback. Returns a reference to any prior +established callback or undef if there was none. + =cut + sub SetTimeoutCallback { my $self = shift; my $callback = shift; @@ -422,61 +485,103 @@ sub SetTimeoutCallback { } =pod - GetState - selector for the object state. + +=head2 GetState + +selector for the object state. + =cut + sub GetState { my $self = shift; return $self->{State}; } + =pod - GetSocket - selector for the object socket. + +=head2 GetSocket + +selector for the object socket. + =cut + sub GetSocket { my $self = shift; return $self->{Socket}; } + =pod - Return the state of the flag that indicates the object wants to be - called when readable. + +=head2 WantReadable + +Return the state of the flag that indicates the object wants to be +called when readable. + =cut + sub WantReadable { my $self = shift; return $self->{InformReadable}; } + =pod - Return the state of the flag that indicates the object wants write - notification. + +=head2 WantWritable + +Return the state of the flag that indicates the object wants write +notification. + =cut + sub WantWritable { my $self = shift; return $self->{InformWritable}; } + =pod - return the state of the flag that indicates the object wants to be informed - of timeouts. + +=head2 WantTimeout + +return the state of the flag that indicates the object wants to be +informed of timeouts. + =cut + sub WantTimeout { my $self = shift; return $self->{Timeoutable}; } =pod - Returns the reply from the last transaction. + +=head2 GetReply + +Returns the reply from the last transaction. + =cut + sub GetReply { my $self = shift; return $self->{TransactionReply}; } =pod - Returns the encrypted version of the command string. - The command input string is of the form: + +=head2 Encrypt + +Returns the encrypted version of the command string. + +The command input string is of the form: + encrypt:command - The output string can be directly sent to lond as it's of the form: + +The output string can be directly sent to lond as it is of the form: + enc:length: -' + =cut + sub Encrypt { my $self = shift; # Reference to the object. my $request = shift; # Text to send. @@ -509,11 +614,17 @@ sub Encrypt { } -=pod - Decrypt - Decrypt a response from the server. The response is in the form: - enc:: + +=pod + +=head2 Decrypt + +Decrypt a response from the server. The response is in the form: + + enc:: + =cut + sub Decrypt { my $self = shift; # Recover reference to object my $encrypted = shift; # This is the encrypted data. @@ -545,24 +656,25 @@ sub Decrypt { } =pod -=head GetHostIterator + +=head2 GetHostIterator Returns a hash iterator to the host information. Each get from this iterator returns a reference to an array that contains information read from the hosts configuration file. Array elements are used as follows: -[0] - LonCapa host name. -[1] - LonCapa domain name. -[2] - Loncapa role (e.g. library or access). -[3] - DNS name server hostname. -[4] - IP address (result of e.g. nslooup [3]). -[5] - Maximum connection count. -[6] - Idle timeout for reducing connection count. -[7] - Minimum connection count. - + [0] - LonCapa host name. + [1] - LonCapa domain name. + [2] - Loncapa role (e.g. library or access). + [3] - DNS name server hostname. + [4] - IP address (result of e.g. nslooup [3]). + [5] - Maximum connection count. + [6] - Idle timeout for reducing connection count. + [7] - Minimum connection count. =cut + sub GetHostIterator { return HashIterator->new(\%hostshash); @@ -571,68 +683,183 @@ sub GetHostIterator { 1; =pod + =head1 Theory - The lond object is a state machine. It lives through the following states: -=item Connected: a TCP connection has been formed, but the passkey has not yet - been negotiated. -=item Initialized: "init" sent. -=item ChallengeReceived: lond sent its challenge to us. -=item ChallengeReplied: We replied to lond's challenge waiting for lond's ok. -=item RequestingKey: We are requesting an encryption key. -=item ReceivingKey: We are receiving an encryption key. -=item Idle: Connection was negotiated but no requests are active. -=item SendingRequest: A request is being sent to the peer. -=item ReceivingReply: Waiting for an entire reply from the peer. -=item Disconnected: For whatever reason, the connection was dropped. - - When we need to be writing data, we have a writable -event. When we need to be reading data, a readable event established. -Events dispatch through the class functions Readable and Writable, and the -watcher contains a reference to the associated object to allow object context -to be reached. +The lond object is a state machine. It lives through the following states: + +=item Connected: + +a TCP connection has been formed, but the passkey has not yet been +negotiated. + +=item Initialized: + +"init" sent. + +=item ChallengeReceived: + +lond sent its challenge to us. + +=item ChallengeReplied: + +We replied to lond's challenge waiting for lond's ok. + +=item RequestingKey: + +We are requesting an encryption key. + +=item ReceivingKey: + +We are receiving an encryption key. + +=item Idle: + +Connection was negotiated but no requests are active. + +=item SendingRequest: + +A request is being sent to the peer. + +=item ReceivingReply: + +Waiting for an entire reply from the peer. + +=item Disconnected: + +For whatever reason, the connection was dropped. + +When we need to be writing data, we have a writable event. When we +need to be reading data, a readable event established. Events +dispatch through the class functions Readable and Writable, and the +watcher contains a reference to the associated object to allow object +context to be reached. =head2 Member data. -Host - Host socket is connected to. -Port - The port the remote lond is listening on. -Socket - Socket open on the connection. -State - The current state. -TransactionRequest - The request being transmitted. -TransactionReply - The reply being received from the transaction. -InformReadable - True if we want to be called when socket is readable. -InformWritable - True if we want to be informed if the socket is writable. -Timeoutable - True if the current operation is allowed to timeout. -TimeoutValue - Number of seconds in the timeout. -TimeoutRemaining - Number of seconds left in the timeout. -CipherKey - The key that was negotiated with the peer. -Cipher - The cipher obtained via the key. +=item Host + +Host socket is connected to. + +=item Port + +The port the remote lond is listening on. + +=item Socket + +Socket open on the connection. + +=item State + +The current state. + +=item TransactionRequest + +The request being transmitted. + +=item TransactionReply + +The reply being received from the transaction. + +=item InformReadable + +True if we want to be called when socket is readable. + +=item InformWritable + +True if we want to be informed if the socket is writable. + +=item Timeoutable + +True if the current operation is allowed to timeout. + +=item TimeoutValue + +Number of seconds in the timeout. + +=item TimeoutRemaining + +Number of seconds left in the timeout. + +=item CipherKey + +The key that was negotiated with the peer. + +=item Cipher + +The cipher obtained via the key. =head2 The following are callback like members: -=item Tick: Called in response to a timer tick. Used to managed timeouts etc. -=item Readable: Called when the socket becomes readable. -=item Writable: Called when the socket becomes writable. -=item TimedOut: Called when a timed operation timed out. + +=item Tick: + +Called in response to a timer tick. Used to managed timeouts etc. + +=item Readable: + +Called when the socket becomes readable. + +=item Writable: + +Called when the socket becomes writable. + +=item TimedOut: + +Called when a timed operation timed out. + =head2 The following are operational member functions. -=item InitiateTransaction: Called to initiate a new transaction -=item SetStateTransitionCallback: Called to establish a function that is called - whenever the object goes through a state transition. This is used by - The client to manage the work flow for the object. -=item SetTimeoutCallback -Set a function to be called when a transaction times - out. The function will be called with the object as its sole parameter. -=item Encrypt - Encrypts a block of text according to the cipher negotiated - with the peer (assumes the text is a command). -=item Decrypt - Decrypts a block of text according to the cipher negotiated - with the peer (assumes the block was a reply. + +=item InitiateTransaction: + +Called to initiate a new transaction + +=item SetStateTransitionCallback: + +Called to establish a function that is called whenever the object goes +through a state transition. This is used by The client to manage the +work flow for the object. + +=item SetTimeoutCallback: + +Set a function to be called when a transaction times out. The +function will be called with the object as its sole parameter. + +=item Encrypt: + +Encrypts a block of text according to the cipher negotiated with the +peer (assumes the text is a command). + +=item Decrypt: + +Decrypts a block of text according to the cipher negotiated with the +peer (assumes the block was a reply. =head2 The following are selector member functions: -=item GetState: Returns the current state -=item GetSocket: Gets the socekt open on the connection to lond. -=item WantReadable: true if the current state requires a readable event. -=item WantWritable: true if the current state requires a writable event. -=item WantTimeout: true if the current state requires timeout support. -=item GetHostIterator: Returns an iterator into the host file hash. +=item GetState: + +Returns the current state + +=item GetSocket: + +Gets the socekt open on the connection to lond. + +=item WantReadable: + +true if the current state requires a readable event. + +=item WantWritable: + +true if the current state requires a writable event. + +=item WantTimeout: + +true if the current state requires timeout support. + +=item GetHostIterator: + +Returns an iterator into the host file hash. + =cut