Diff for /loncom/LondConnection.pm between versions 1.41 and 1.53

version 1.41, 2006/08/11 20:07:52 version 1.53, 2012/10/01 11:00:43
Line 43  use LONCAPA::lonssl; Line 43  use LONCAPA::lonssl;
   
   
 my $DebugLevel=0;  my $DebugLevel=0;
 my %hostshash;  
 my %perlvar;  my %perlvar;
 my $LocalDns = ""; # Need not be defined for managers.  
 my $InsecureOk;  my $InsecureOk;
   
 #  #
Line 71  sub ReadConfig { Line 69  sub ReadConfig {
   
     my $perlvarref = read_conf('loncapa.conf');      my $perlvarref = read_conf('loncapa.conf');
     %perlvar    = %{$perlvarref};      %perlvar    = %{$perlvarref};
     my $hoststab   = read_hosts(  
  "$perlvar{lonTabDir}/hosts.tab") ||   
  die "Can't read host table!!";  
     %hostshash  = %{$hoststab};  
     $ConfigRead = 1;      $ConfigRead = 1;
           
     my $myLonCapaName = $perlvar{lonHostID};  
     Debug(8, "My loncapa name is $myLonCapaName");  
       
     if(defined $hostshash{$myLonCapaName}) {  
  Debug(8, "My loncapa name is in hosthash");  
  my @ConfigLine = @{$hostshash{$myLonCapaName}};  
  $LocalDns = $ConfigLine[3];  
  Debug(8, "Got local name $LocalDns");  
     }  
     $InsecureOk = $perlvar{loncAllowInsecure};      $InsecureOk = $perlvar{loncAllowInsecure};
       
     Debug(3, "ReadConfig - LocalDNS = $LocalDns");  
 }  
   
 #  
 #  Read a foreign configuration.  
 #  This sub is intended for the cases where the package  
 #  will be read from outside the LonCAPA environment, in that case  
 #  the client will need to explicitly provide:  
 #   - A file in hosts.tab format.  
 #   - Some idea of the 'lonCAPA' name of the local host (for building  
 #     the encryption key).  
 #  
 #  Parameters:  
 #      MyHost   - Name of this host as far as LonCAPA is concerned.  
 #      Filename - Name of a hosts.tab formatted file that will be used  
 #                 to build up the hosts table.  
 #  
 sub ReadForeignConfig {  
   
     my ($MyHost, $Filename) = @_;  
   
     &Debug(4, "ReadForeignConfig $MyHost $Filename\n");  
   
     $perlvar{lonHostID} = $MyHost; # Rmember my host.  
     my $hosttab = read_hosts($Filename) ||  
  die "Can't read hosts table!!";  
     %hostshash = %{$hosttab};  
     if($DebugLevel > 3) {  
  foreach my $host (keys %hostshash) {  
     print STDERR "host $host => $hostshash{$host}\n";  
  }  
     }  
     $ConfigRead = 1;  
   
     my $myLonCapaName = $perlvar{lonHostID};  
       
     if(defined $hostshash{$myLonCapaName}) {  
  my @ConfigLine = @{$hostshash{$myLonCapaName}};  
  $LocalDns = $ConfigLine[3];  
     }  
     $InsecureOk = $perlvar{loncAllowInsecure};  
       
     Debug(3, "ReadForeignConfig  - LocalDNS = $LocalDns");  
   
 }  }
   
 sub Debug {  sub Debug {
Line 213  host the remote lond is on. This host is Line 153  host the remote lond is on. This host is
 =cut  =cut
   
 sub new {  sub new {
     my ($class, $DnsName, $Port) = @_;      my ($class, $DnsName, $Port, $lonid) = @_;
   
     if (!$ConfigRead) {      if (!$ConfigRead) {
  ReadConfig();   ReadConfig();
  $ConfigRead = 1;   $ConfigRead = 1;
     }      }
     &Debug(4,$class."::new( ".$DnsName.",".$Port.")\n");      &Debug(4,$class."::new( ".$DnsName.",".$Port.",".$lonid.")\n");
   
     # The host must map to an entry in the hosts table:      # The host must map to an entry in the hosts table:
     #  We connect to the dns host that corresponds to that      #  We connect to the dns host that corresponds to that
Line 227  sub new { Line 167  sub new {
     #  negotion.  In the objec these become the Host and      #  negotion.  In the objec these become the Host and
     #  LoncapaHim fields of the object respectively.      #  LoncapaHim fields of the object respectively.
     #      #
     if (!exists $hostshash{$DnsName}) {  
  &Debug(8, "No Such host $DnsName");  
  return undef; # No such host!!!  
     }  
     my @ConfigLine = @{$hostshash{$DnsName}};  
     my $Hostname    = $ConfigLine[0]; # 0'th item is the msu id of host.  
     Debug(5, "Connecting to ".$DnsName);  
     # if it is me use loopback for connection      # if it is me use loopback for connection
     if ($DnsName eq $LocalDns) { $DnsName="127.0.0.1"; }      if ($DnsName eq &main::my_hostname()) { $DnsName="127.0.0.1"; }
     Debug(8, "Connecting to $DnsName I am $LocalDns");      Debug(9, "Connecting to $DnsName");
     # Now create the object...      # Now create the object...
     my $self     = { Host               => $DnsName,      my $self     = { Host               => $DnsName,
                      LoncapaHim         => $Hostname,                       LoncapaHim         => $lonid,
                      Port               => $Port,                       Port               => $Port,
                      State              => "Initialized",                       State              => "Initialized",
      AuthenticationMode => "",       AuthenticationMode => "",
Line 256  sub new { Line 189  sub new {
      LocalKeyFile       => "",       LocalKeyFile       => "",
                      CipherKey          => "",                       CipherKey          => "",
                      LondVersion        => "Unknown",                       LondVersion        => "Unknown",
                      Cipher             => undef};                       Cipher             => undef,
        ClientData         => undef};
     bless($self, $class);      bless($self, $class);
     unless ($self->{Socket} = IO::Socket::INET->new(PeerHost => $self->{Host},      unless ($self->{Socket} = IO::Socket::INET->new(PeerHost => $self->{Host},
        PeerPort => $self->{Port},         PeerPort => $self->{Port},
Line 267  sub new { Line 201  sub new {
  return undef; # Inidicates the socket could not be made.   return undef; # Inidicates the socket could not be made.
     }      }
     my $socket = $self->{Socket}; # For local use only.      my $socket = $self->{Socket}; # For local use only.
       $socket->sockopt(SO_KEEPALIVE, 1); # Turn on keepalive probes when idle.
     #  If we are local, we'll first try local auth mode, otherwise, we'll try      #  If we are local, we'll first try local auth mode, otherwise, we'll try
     #  the ssl auth mode:      #  the ssl auth mode:
   
Line 297  sub new { Line 232  sub new {
     return undef;      return undef;
  }   }
   
     }      } else {
     else {  
  #  Remote peer:  I'd like to do ssl, but if my host key or certificates   #  Remote peer:  I'd like to do ssl, but if my host key or certificates
  #  are not all installed, my only choice is insecure, if that's    #  are not all installed, my only choice is insecure, if that's 
  #  allowed:   #  allowed:
Line 309  sub new { Line 243  sub new {
  if((defined $ca)  && (defined $cert) && (defined $sslkeyfile)) {   if((defined $ca)  && (defined $cert) && (defined $sslkeyfile)) {
   
     $self->{AuthenticationMode} = "ssl";      $self->{AuthenticationMode} = "ssl";
     $self->{TransactionRequest} = "init:ssl\n";      $self->{TransactionRequest} = "init:ssl:$perlvar{'lonVersion'}\n";
  } else {   } else {
     if($InsecureOk) { # Allowed to do insecure:      if($InsecureOk) { # Allowed to do insecure:
  $self->{AuthenticationMode} = "insecure";   $self->{AuthenticationMode} = "insecure";
  $self->{TransactionRequest} = "init\n";   $self->{TransactionRequest} = "init::$perlvar{'lonVersion'}\n";
     }      }
     else { # Not allowed to do insecure...      else { # Not allowed to do insecure...
  $socket->close;   $socket->close;
Line 333  sub new { Line 267  sub new {
     #      #
     # Set socket to nonblocking I/O.      # Set socket to nonblocking I/O.
     #      #
     my $socket = $self->{Socket};  
     my $flags    = fcntl($socket, F_GETFL,0);      my $flags    = fcntl($socket, F_GETFL,0);
     if(!$flags) {      if(!$flags) {
  $socket->close;   $socket->close;
Line 409  sub Readable { Line 342  sub Readable {
  $self->Transition("Disconnected");   $self->Transition("Disconnected");
  return -1;   return -1;
     }      }
       # If we actually got data, reset the timeout.
   
       if (length $data) {
    $self->{TimeoutRemaining}   = $self->{TimeoutValue}; # getting data resets the timeout period.
       }
     #  Append the data to the buffer.  And figure out if the read is done:      #  Append the data to the buffer.  And figure out if the read is done:
   
     &Debug(9,"Received from host: ".$data);      &Debug(9,"Received from host: ".$data);
Line 570  sub Readable { Line 508  sub Readable {
  $self->{InformWritable}     = 1;   $self->{InformWritable}     = 1;
  $self->{InformReadable}     = 0;   $self->{InformReadable}     = 0;
  $self->{Timeoutable}        = 1;   $self->{Timeoutable}        = 1;
  $self->{TimeoutRemaining}   = $self->{TimeoutValue};  
  $self->Transition("SendingRequest");   $self->Transition("SendingRequest");
  return 0;   return 0;
     } else {      } else {
Line 632  sub Writable { Line 569  sub Writable {
  ($errno == POSIX::EAGAIN)         ||   ($errno == POSIX::EAGAIN)         ||
  ($errno == POSIX::EINTR)          ||   ($errno == POSIX::EINTR)          ||
  ($errno ==  0)) {   ($errno ==  0)) {
    $self->{TimeoutRemaining} = $self->{TimeoutValue};
  substr($self->{TransactionRequest}, 0, $nwritten) = ""; # rmv written part   substr($self->{TransactionRequest}, 0, $nwritten) = ""; # rmv written part
       if(length $self->{TransactionRequest} == 0) {   if(length $self->{TransactionRequest} == 0) {
          $self->{InformWritable} = 0;      $self->{InformWritable} = 0;
          $self->{InformReadable} = 1;      $self->{InformReadable} = 1;
          $self->{TransactionReply} = '';      $self->{TransactionReply} = '';
          #      #
          # Figure out the next state:      # Figure out the next state:
          #      #
          if($self->{State} eq "Connected") {      if($self->{State} eq "Connected") {
             $self->Transition("Initialized");   $self->Transition("Initialized");
          } elsif($self->{State} eq "ChallengeReceived") {      } elsif($self->{State} eq "ChallengeReceived") {
             $self->Transition("ChallengeReplied");   $self->Transition("ChallengeReplied");
          } elsif($self->{State} eq "RequestingVersion") {      } elsif($self->{State} eq "RequestingVersion") {
             $self->Transition("ReadingVersionString");   $self->Transition("ReadingVersionString");
          } elsif ($self->{State} eq "SetHost") {      } elsif ($self->{State} eq "SetHost") {
             $self->Transition("HostSet");   $self->Transition("HostSet");
          } elsif($self->{State} eq "RequestingKey") {      } elsif($self->{State} eq "RequestingKey") {
             $self->Transition("ReceivingKey");   $self->Transition("ReceivingKey");
 #            $self->{InformWritable} = 0;  #            $self->{InformWritable} = 0;
 #            $self->{InformReadable} = 1;  #            $self->{InformReadable} = 1;
 #            $self->{TransactionReply} = '';  #            $self->{TransactionReply} = '';
          } elsif ($self->{State} eq "SendingRequest") {      } elsif ($self->{State} eq "SendingRequest") {
             $self->Transition("ReceivingReply");   $self->Transition("ReceivingReply");
             $self->{TimeoutRemaining} = $self->{TimeoutValue};   $self->{TimeoutRemaining} = $self->{TimeoutValue};
          } elsif ($self->{State} eq "Disconnected") {      } elsif ($self->{State} eq "Disconnected") {
             return -1;   return -1;
          }      }
          return 0;      return 0;
       }   }
    } else { # The write failed (e.g. partner disconnected).      } else { # The write failed (e.g. partner disconnected).
       $self->Transition("Disconnected");   $self->Transition("Disconnected");
       $socket->close();   $socket->close();
       return -1;   return -1;
    }      }
       
 }  }
 =pod  =pod
   
Line 813  sub Shutdown { Line 751  sub Shutdown {
     $socket->shutdown(2);      $socket->shutdown(2);
  }   }
     }      }
       $self->{Timeoutable}   = 0; # Shutdown sockets can't timeout.
 }  }
   
 =pod  =pod
Line 1138  sub CompleteInsecure { Line 1077  sub CompleteInsecure {
     }      }
 }  }
   
 =pod  
   
 =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 id.  
  [1]   - LonCapa domain name.  
  [2]   - Loncapa role (e.g. library or access).  
  [3]   - DNS name server hostname.  
  [4]   - IP address (result of e.g. nslookup [3]).  
  [5]   - Maximum connection count.  
  [6]   - Idle timeout for reducing connection count.  
  [7]   - Minimum connection count.  
   
 =cut  
   
 sub GetHostIterator {  
   
     return HashIterator->new(\%hostshash);      
 }  
   
 ###########################################################  ###########################################################
 #  #
 #  The following is an unashamed kludge that is here to  #  The following is an unashamed kludge that is here to
Line 1174  sub GetHostIterator { Line 1088  sub GetHostIterator {
 #  #
   
   
 my $confdir='/etc/httpd/conf/';  my @confdirs=('/etc/httpd/conf/','/etc/apache2/');
   
 # ------------------- Subroutine read_conf: read LON-CAPA server configuration.  # ------------------- Subroutine read_conf: read LON-CAPA server configuration.
 # This subroutine reads PerlSetVar values out of specified web server  # This subroutine reads PerlSetVar values out of specified web server
Line 1182  my $confdir='/etc/httpd/conf/'; Line 1096  my $confdir='/etc/httpd/conf/';
 sub read_conf  sub read_conf
   {    {
     my (@conf_files)=@_;      my (@conf_files)=@_;
     my %perlvar;      my (%perlvar,%configdirs);
     foreach my $filename (@conf_files,'loncapa_apache.conf')      foreach my $filename (@conf_files,'loncapa_apache.conf') {
       {          my $configdir = '';
   if($DebugLevel > 3) {          $configdirs{$filename} = [@confdirs];
       print STDERR ("Going to read $confdir.$filename\n");          while ($configdir eq '' && @{$configdirs{$filename}} > 0) {
   }              my $testdir = shift(@{$configdirs{$filename}});
  open(CONFIG,'<'.$confdir.$filename) or              if (-e $testdir.$filename) {
     die("Can't read $confdir$filename");                  $configdir = $testdir;
  while (my $configline=<CONFIG>)              }
   {          }
     if ($configline =~ /^[^\#]*PerlSetVar/)          if ($configdir eq '') {
       {              die("Couldn't find a directory containing $filename");
  my ($unused,$varname,$varvalue)=split(/\s+/,$configline);          }
    if($DebugLevel > 3) {
       print STDERR ("Going to read $configdir.$filename\n");
    }
    open(CONFIG,'<'.$configdir.$filename) or
       die("Can't read $configdir$filename");
    while (my $configline=<CONFIG>) {
       if ($configline =~ /^[^\#]*PerlSetVar/) {
           my ($unused,$varname,$varvalue)=split(/\s+/,$configline);
  chomp($varvalue);   chomp($varvalue);
  $perlvar{$varname}=$varvalue;   $perlvar{$varname}=$varvalue;
       }      }
   }   }
  close(CONFIG);   close(CONFIG);
       }      }
     if($DebugLevel > 3) {      if($DebugLevel > 3) {
  print STDERR "Dumping perlvar:\n";   print STDERR "Dumping perlvar:\n";
  foreach my $var (keys %perlvar) {   foreach my $var (keys %perlvar) {
Line 1211  sub read_conf Line 1133  sub read_conf
     return $perlvarref;      return $perlvarref;
 }  }
   
 #---------------------- Subroutine read_hosts: Read a LON-CAPA hosts.tab  
 # formatted configuration file.  
 #  
 my $RequiredCount = 4; # Required item count in hosts.tab.  
 my $DefaultMaxCon = 5; # Default value for maximum connections.  
 my $DefaultIdle   = 1000;       # Default connection idle time in seconds.  
 my $DefaultMinCon = 0;          # Default value for minimum connections.  
   
 sub read_hosts {  
     my $Filename = shift;  
     my %HostsTab;  
       
     open(CONFIG,'<'.$Filename) or die("Can't read $Filename");  
     while (my $line = <CONFIG>) {  
  if ($line !~ /^\s*\#/) {  
     $line=~s/\s*$//;  
     my @items = split(/:/, $line);  
     if(scalar @items >= $RequiredCount) {  
  if (scalar @items == $RequiredCount) { # Only required items:  
     $items[$RequiredCount] = $DefaultMaxCon;  
  }  
  if(scalar @items == $RequiredCount + 1) { # up through maxcon.  
     $items[$RequiredCount+1] = $DefaultIdle;  
  }  
  if(scalar @items == $RequiredCount + 2) { # up through idle.  
     $items[$RequiredCount+2] = $DefaultMinCon;  
  }  
  {  
     my @list = @items; # probably not needed but I'm unsure of   
     # about the scope of item so...  
     $HostsTab{$list[3]} = \@list;   
  }  
     }  
  }  
     }  
     close(CONFIG);  
     my $hostref = \%HostsTab;  
     return ($hostref);  
 }  
 #  #
 #   Get the version of our peer.  Note that this is only well  #   Get the version of our peer.  Note that this is only well
 #   defined if the state machine has hit the idle state at least  #   defined if the state machine has hit the idle state at least
Line 1262  sub PeerVersion { Line 1145  sub PeerVersion {
    return $version;     return $version;
 }  }
   
   #
   #  Manipulate the client data field
   #
   sub SetClientData {
       my ($self, $newData) = @_;
       $self->{ClientData} = $newData;
   }
   #
   #  Get the current client data field.
   #
   sub GetClientData {
       my $self = shift;
       return $self->{ClientData};
   }
   
 1;  1;
   
 =pod  =pod
Line 1455  true if the current state requires a wri Line 1353  true if the current state requires a wri
   
 true if the current state requires timeout support.  true if the current state requires timeout support.
   
 =item GetHostIterator:  
   
 Returns an iterator into the host file hash.  
   
 =cut  =cut

Removed from v.1.41  
changed lines
  Added in v.1.53


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.