From 1bd6901c72b4c740fcde6925946d9e91c03c3097 Mon Sep 17 00:00:00 2001 From: bustico Date: Tue, 20 Mar 2007 16:09:56 +0000 Subject: Bug fix: Do not die on disconnect of unamed apps --- Ivy.pm | 63 +++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 22 deletions(-) (limited to 'Ivy.pm') diff --git a/Ivy.pm b/Ivy.pm index ae2bba4..e0c5855 100644 --- a/Ivy.pm +++ b/Ivy.pm @@ -44,7 +44,7 @@ use vars qw($VERSION); use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK); # to compute the VERSION from the CVS tag (or if no tag, as the cvs file revision) -my $TAG= q$Name$; +my $TAG= q$Name: $; my $REVISION = q$Revision$ ; $VERSION = '1.47' ; # for Makefile.PL ($VERSION) = $TAG =~ /^\D*([\d_]+)/ ; @@ -1372,8 +1372,10 @@ sub _getBonjour ($) if ($appSock) { my $flags = fcntl($appSock, F_GETFL, 0); - $flags = fcntl($appSock, F_SETFL, $flags | O_NONBLOCK) - or die "Can't set flags for the socket: $!\n"; + unless (fcntl($appSock, F_SETFL, $flags | O_NONBLOCK)) { + carp "Can't set flags for the socket: $!\n"; + return; + } # on cree une entree pour $appSock dans la liste des regexp $nameByHandle{$appSock}=_getHostByAddr($addr) .":$peerPort"; @@ -1387,8 +1389,7 @@ sub _getBonjour ($) # on balance les regexps qui nous interessent a l'appli distante $self->_sendWantedRegexp ($appSock); - } - else { + } else { carp "Warning in Ivy::_getBonjour, connection to " . "$peerName:$peerPort is impossible" ; } @@ -1401,21 +1402,23 @@ sub _getConnections ($) my $self = shift; my $appSock = $self->[connSock]->accept(); - if ($appSock) { - my $flags = fcntl($appSock, F_GETFL, 0); - $flags = fcntl($appSock, F_SETFL, $flags | O_NONBLOCK) - or die "Can't set flags for the socket: $!\n"; - } unless (defined $appSock) { carp "Warning in Ivy::_getConnections, \$appSock not defined"; return; + } else { + my $flags = fcntl($appSock, F_GETFL, 0); + unless (fcntl($appSock, F_SETFL, $flags | O_NONBLOCK)) { + carp "Can't set flags for the socket: $!\n"; + return; + } } - else { + + # printf "accepting connection from %s:%d\n", # (gethostbyaddr ($appSock->peeraddr(),AF_INET))[0], # $appSock->peerport() if $^W; - } + # callback pour traiter la reception des messages &$fileEventFunc ($appSock, [\&_getMessages, $self, $appSock]) ; @@ -1494,10 +1497,10 @@ sub _getMessages ($$) my $method = shift @cb; # on split sur ETX $cb->$method($senderName, @cb, split ("\003", $valeurs)) ; - } - else { + } else { &$cb ($senderName, @cb, split ("\003", $valeurs)) ; } + if ($self->[recCbList][$id]->[2] == BIND_ONCE) { # on vire la regexp des regexps verifiées # print ("DBG> receive BIND ONCE message\n"); @@ -1507,17 +1510,18 @@ sub _getMessages ($$) _univSend ($self, $fd, sprintf (MSG_FMT, DELREGEXP, $id, "")); } } - } - else { + } else { #_sendErrorTo ($appSock, "REEGXP ID $id inconnue"); - carp ("Warning in Ivy::_getMessages, received an unknown or double one shot message ". + carp ("Warning in Ivy::_getMessages, received an unknown message or double one shot message ". "with id $id from $senderName :\n\"$mess\"") if $^W; } } + elsif ($type == BYE) { #print "reception d'un bye\n"; $self->_removeFileDescriptor ($appSock); # B Y E } + elsif ($type == REGEXP) { # R E G E X P # on ajoute une fonction traitant la regexp et envoyant le # message sur le bon fd dans la liste des fonctions de filtrage @@ -1561,10 +1565,12 @@ sub _getMessages ($$) # } # _EOL_ } + elsif ($type == ERROR) { # E R R O R carp ("Warning in Ivy::_getMessages, error message received from ". "$senderName : \"$valeurs\""); } + elsif ($type == DELREGEXP) { # D E L R E G E X P # on vire la regexp des regexps verifiées $self->[sendRegList]{$appSock}->[$id] = undef ; @@ -1573,6 +1579,7 @@ sub _getMessages ($$) my $host = _getHostByAddr ($addr); &_scanConnStatus ($self, $senderName, 'unsubscribing', "$host:$peerPort" , $regexp); } + elsif ($type == ENDREGEXP) { # E N D R E G E X P # on envoie le message ready uniquement a celui qui nous # a envoye le message endregexp @@ -1591,6 +1598,7 @@ sub _getMessages ($$) my $host = _getHostByAddr ($addr); $self->_scanConnStatus ($senderName, "new", "$host:$peerPort", undef); } + elsif ($type == APP_NAME) { # etat Connecte1558 if (($self->[appName] eq $valeurs) && $^W) { @@ -1602,6 +1610,7 @@ sub _getMessages ($$) $self->[cnnxion]{"$addr:$peerPort"} = "\004$valeurs"; $nameByHandle{$appSock}=_getHostByAddr($addr) .":$peerPort"; } + elsif ($type == DIRECT_MSG) { if (defined $self->[directCbList][$id]) { @@ -1620,7 +1629,9 @@ sub _getMessages ($$) carp "Warning in Ivy::_getMessages, received a DIRECT message with ". "unknown id $id from $senderName :\n\"$mess\""; } - } elsif ($type == DIE) { + } + + elsif ($type == DIE) { # il faut quitter # on commence par appeler la callback de fin my @cb = @{$onDieFunc}; @@ -1639,10 +1650,12 @@ sub _getMessages ($$) Ivy::exit (); } + elsif ($type == PING) { # si on recois un ping, on envoie un pong $self->_pong ($appSock, $id); } + elsif ($type == PONG) { if (exists $self->[pongQueue]->{$appSock}) { my ($pingid, $time, $funcRef) = @{$self->[pongQueue]->{$appSock}}; @@ -1652,6 +1665,7 @@ sub _getMessages ($$) delete $self->[pongQueue]->{$appSock}; } } + else { _$self->sendErrorTo ($appSock, "TYPE DE MESS $type inconnu"); warn ("Warning in Ivy::_getMessages, received a message of unknown ". @@ -1740,7 +1754,7 @@ sub _removeFileDescriptor ($$) keys %{$self->[cnnxion]}))[0]; unless (defined $addrInet) { - croak "Error in Ivy::_removeFileDescriptor, disconnection of $diedAppName with ". + carp "Warning in Ivy::_removeFileDescriptor, disconnection of $diedAppName with ". "addrInet not defined\n"; return; } @@ -2158,6 +2172,11 @@ sub _getHostByAddr ($) { my $addr = shift; + unless (defined $addr) { + warn "_getHostByAddr : invalid argument\n"; + return "EMPTY_ADDR"; + } + $hostNameByAddr{$addr} = gethostbyaddr ($addr, AF_INET) || inet_ntoa($addr) unless exists $hostNameByAddr{$addr}; @@ -2208,8 +2227,8 @@ sub _regexpGen ($$$) sub _strictPosRegexpGen ($$$$) { my ($min, $max, $decimalPart,$boundDecimalPart) = @_; - die "min[$min] sould be <= max[$max]\n " unless ($min <= $max); - die "min[$min] and max[$max] should be strictly positive\n " unless (($min >0) && ($max > 0)); + carp "min[$min] sould be <= max[$max]\n " unless ($min <= $max); + carp "min[$min] and max[$max] should be strictly positive\n " unless (($min >0) && ($max > 0)); # my $fixBound ; # $max -- if ($fixBound = ($decimalPart ne '') && ((int ($max /10) *10) != $max)); @@ -2299,7 +2318,7 @@ sub _genPreRank ($$$) $max = $max + 0; # instead string (eliminate leading zeroes) my $a = substr ($min, 0, (length ($min) - $rank)); my $b = substr ($max, 0, (length ($max) - $rank)); - die "genPreRank error $min, $max are not invariant @ rank $rank\n" if $a ne $b; + carp "genPreRank error $min, $max are not invariant @ rank $rank\n" if $a ne $b; return $a; } -- cgit v1.1