}
my %active_connections;
-
-sub mux_connection {
- my $self = shift;
- my $mux = shift;
- my $fh = shift;
-
- my $service;
- my $sockname;
- my ($sockaddr, $port, $proto);
- my $transport;
-
- $self->{config} = $config;
-
- $sockaddr = $self->{net_server}{server}->{sockaddr};
- $port = $self->{net_server}{server}->{sockport};
- $proto = $self->{net_server}{server}->{client}->NS_proto();
-
- syslog('LOG_INFO', "Inbound connection from $sockaddr on port $port and proto $proto");
-
- $self->{service} = $config->find_service( $sockaddr, $port, $proto );
-
- if (! defined($self->{service})) {
- syslog( "LOG_ERR", "process_request: Unrecognized server connection: %s:%s/%s",
- $sockaddr, $port, $proto );
- die "process_request: Bad server connection";
- }
-
- $transport = $transports{ $self->{service}->{transport} };
-
- $active_connections{fileno($fh)} = { complete => 0, transport => $transport, net_server => bless({%$self}, ref($self)) };
-
- if ( !defined($transport) ) {
- syslog("LOG_WARNING", "Unknown transport '%s', dropping", $service->{transport});
- return;
- }
-
-}
-
-
sub mux_input {
my $mself = shift;
my $mux = shift;
my $fh = shift;
+ my $self;
+ my $conn_id = fileno($fh);
+
# check for kids that went away
REAPER();
- my $connection = $active_connections{fileno($fh)};
- my $self = $connection->{net_server};
- if (!$connection->{complete}) { # log them in
- my $transport = $connection->{transport};
+ if (!$active_connections{$conn_id}) { # Brand new connection, log them in
+ $self = $mself->{net_server};
+
+ my ($sockaddr, $port, $proto);
+
+ $self->{config} = $config;
+
+ $sockaddr = $self->{server}->{sockaddr};
+ $port = $self->{server}->{sockport};
+ $proto = $self->{server}->{client}->NS_proto();
+
+ syslog('LOG_INFO', "Inbound connection from $sockaddr on port $port and proto $proto");
+
+ $self->{service} = $config->find_service( $sockaddr, $port, $proto );
+
+ if (! defined($self->{service})) {
+ syslog( "LOG_ERR", "process_request: Unrecognized server connection: %s:%s/%s",
+ $sockaddr, $port, $proto );
+ die "process_request: Bad server connection";
+ }
+
+ my $transport = $transports{ $self->{service}->{transport} };
+
+ if ( !defined($transport) ) {
+ syslog("LOG_WARNING", "Unknown transport, dropping");
+ return;
+ }
- &$transport($self);
+ &$transport($self, $fh);
+ $active_connections{$conn_id} =
+ { id => $conn_id,
+ transport => $transport,
+ net_server => bless({%$self}, ref($self))
+ };
+
+ # Evergreen, at least, needs a chance to clean up before forking for other requests
$self->{ils}->disconnect() if (UNIVERSAL::can($self->{ils},'disconnect'));
- $connection->{ils} = ref($self->{ils});
- delete $$self{ils};
- $connection->{complete} = 1;
+ # Stash the ILS module somewhere handy for later
+ $active_connections{$conn_id}->{ils} = ref($self->{ils});
+ delete $$self{ils};
return;
}
+ $self = $active_connections{$conn_id}->{net_server};
+
my $pid = fork();
die "Cannot fork: $!" unless (defined($pid) && $pid > -1);
+
if ($pid == 0) { # in kid
# build the connection we deleted after logging in
- $self->{ils} = $connection->{ils}->new($self->{institution}, $self->{account});
+ $self->{ils} = $active_connections{$conn_id}->{ils}->new($self->{institution}, $self->{account});
my $input = Sip::read_SIP_packet($fh);
$input =~ s/[\r\n]+$//sm; # Strip off any trailing line ends
sub raw_transport {
my $self = shift;
+ my $fh ||= *STDIN;
my ($uid, $pwd);
my $input;
my $service = $self->{service};
while ($strikes--) {
alarm $timeout;
- $input = Sip::read_SIP_packet(*STDIN);
+ $input = Sip::read_SIP_packet($fh);
alarm 0;
if (!$input) {
sub telnet_transport {
my $self = shift;
+ my $fh ||= *STDIN;
my ($uid, $pwd);
my $strikes = 3;
my $account = undef;
while ($strikes--) {
print "login: ";
alarm $timeout;
- $uid = <STDIN>;
+ $uid = <$fh>;
alarm 0;
print "password: ";
alarm $timeout;
- $pwd = <STDIN>;
+ $pwd = <$fh>;
alarm 0;
$uid =~ s/[\r\n]+$//;