add KEEPALIVE to TCP connections
[spider.git] / perl / Msg.pm
index 3f52e39dfe8057d4fb202f364be81eb36567ceb3..f2881c8ff9a947932c926bb1c4f5a0cf9e57fac1 100644 (file)
@@ -208,10 +208,6 @@ sub disconnect {
        $call ||= 'unallocated';
        dbg("Connection $conn->{cnum} $call disconnected") if isdbg('connll');
        
-       unless ($main::is_win) {
-               kill 'TERM', $conn->{pid} if exists $conn->{pid};
-       }
-
        # get rid of any references
        for (keys %$conn) {
                if (ref($conn->{$_})) {
@@ -219,10 +215,16 @@ sub disconnect {
                }
        }
 
-       return unless defined($sock);
-    set_event_handler ($sock, read => undef, write => undef, error => undef);
-    shutdown($sock, 3);
-       close($sock);
+       if (defined($sock)) {
+               set_event_handler ($sock, read => undef, write => undef, error => undef);
+               shutdown($sock, 3);
+               close($sock);
+       }
+       
+       unless ($main::is_win) {
+               kill 'TERM', $conn->{pid} if exists $conn->{pid};
+       }
+
 }
 
 sub send_now {
@@ -344,16 +346,32 @@ sub new_server {
        my $self = $pkg->new($login_proc);
        
     $self->{sock} = IO::Socket::INET->new (
-                                          LocalAddr => $my_host,
-                                          LocalPort => $my_port,
+                                          LocalAddr => "$my_host:$my_port",
+#                                          LocalPort => $my_port,
                                           Listen    => SOMAXCONN,
                                           Proto     => 'tcp',
-                                          Reuse     => 1);
+                                          Reuse => 1);
     die "Could not create socket: $! \n" unless $self->{sock};
     set_event_handler ($self->{sock}, read => sub { $self->new_client }  );
        return $self;
 }
 
+sub nolinger
+{
+       my $conn = shift;
+       my $buf;
+       if (isdbg('sock') && ($buf = getsockopt($conn->{sock}, SOL_SOCKET, SO_LINGER))) {
+               my ($l, $t) = unpack("ll", $buf);
+               dbg("Linger is: $buf = $l $t");
+       }
+       setsockopt($conn->{sock}, SOL_SOCKET, SO_LINGER, pack("ll", 0, 0)) or confess "setsockopt linger: $!";
+       setsockopt($conn->{sock}, SOL_SOCKET, SO_KEEPALIVE, 1) or confess "setsockopt keepalive: $!";
+       if (isdbg('sock') && ($buf = getsockopt($conn->{sock}, SOL_SOCKET, SO_LINGER))) {
+               my ($l, $t) = unpack("ll", $buf);
+               dbg("Linger is: $buf = $l $t");
+       }
+}
+
 sub dequeue
 {
        my $conn = shift;
@@ -386,11 +404,29 @@ sub _rcv {                     # Complement to _send
        $bytes_read = sysread ($sock, $msg, 1024, 0);
        if (defined ($bytes_read)) {
                if ($bytes_read > 0) {
-                       $conn->{msg} .= $msg;
                        if (isdbg('raw')) {
                                my $call = $conn->{call} || 'none';
                                dbgdump('raw', "$call read $bytes_read: ", $msg);
                        }
+                       if ($conn->{echo}) {
+                               my @ch = split //, $msg;
+                               my $out;
+                               for (@ch) {
+                                       if (/[\cH\x7f]/) {
+                                               $out .= "\cH \cH";
+                                               $conn->{msg} =~ s/.$//;
+                                       } else {
+                                               $out .= $_;
+                                               $conn->{msg} .= $_;
+                                       }
+                               }
+                               if (defined $out) {
+                                       set_event_handler ($sock, write => sub{$conn->_send(0)});
+                                       push @{$conn->{outqueue}}, $out;
+                               }
+                       } else {
+                               $conn->{msg} .= $msg;
+                       }
                } 
        } else {
                if (_err_will_block($!)) {
@@ -418,6 +454,7 @@ sub new_client {
                my $conn = $server_conn->new($server_conn->{rproc});
                $conn->{sock} = $sock;
                blocking($sock, 0);
+               $conn->nolinger;
                $conn->{blocking} = 0;
                my ($rproc, $eproc) = &{$server_conn->{rproc}} ($conn, $conn->{peerhost} = $sock->peerhost(), $conn->{peerport} = $sock->peerport());
                $conn->{sort} = 'Incoming';