Index: perl/modules/IRC/lib/BarnOwl/Module/IRC.pm
===================================================================
--- perl/modules/IRC/lib/BarnOwl/Module/IRC.pm	(revision dace02afa8202c17375f083df8247cc4f9307dcb)
+++ perl/modules/IRC/lib/BarnOwl/Module/IRC.pm	(revision 5c6d661cb25bf113e3f1b18aaed92753a61a9f96)
@@ -394,4 +394,5 @@
     my $conn = shift;
     if ($conn->conn->{socket}) {
+        $conn->did_quit(1);
         $conn->conn->disconnect("Goodbye!");
     } elsif ($conn->{reconnect_timer}) {
Index: perl/modules/IRC/lib/BarnOwl/Module/IRC/Connection.pm
===================================================================
--- perl/modules/IRC/lib/BarnOwl/Module/IRC/Connection.pm	(revision ab6d8f007dacc263fe5b6ce55c8c2728fe44bad6)
+++ perl/modules/IRC/lib/BarnOwl/Module/IRC/Connection.pm	(revision 5c6d661cb25bf113e3f1b18aaed92753a61a9f96)
@@ -21,5 +21,7 @@
 use base qw(Class::Accessor);
 use Exporter 'import';
-__PACKAGE__->mk_accessors(qw(conn alias motd names_tmp whois_tmp server autoconnect_channels));
+__PACKAGE__->mk_accessors(qw(conn alias motd names_tmp whois_tmp
+                             server autoconnect_channels
+                             connect_args backoff did_quit));
 our @EXPORT_OK = qw(is_private);
 
@@ -42,9 +44,12 @@
     $self->motd("");
     $self->names_tmp(0);
+    $self->backoff(0);
     $self->whois_tmp("");
+    $self->did_quit(0);
 
     if(delete $args->{SSL}) {
         $conn->enable_ssl;
     }
+    $self->connect_args([$host, $port, $args]);
     $conn->connect($host, $port, $args);
     $conn->{heap}{parent} = $self;
@@ -94,5 +99,5 @@
                         nick_change   => on("nick"),
                         ctcp_action   => on("ctcp_action"),
-                        'irc_*' => sub { BarnOwl::debug("IRC: " . $_[1]->{command} .
+                        'irc_*' => sub { BarnOwl::debug("IRC: " . $_[1]->{command} . " " .
                                                         join(" ", @{$_[1]->{params}})) });
 
@@ -244,14 +249,5 @@
 sub disconnect {
     my $self = shift;
-    delete $BarnOwl::Module::IRC::ircnets{$self->alias};
-    for my $k (keys %BarnOwl::Module::IRC::channels) {
-        my @conns = grep {$_ ne $self} @{$BarnOwl::Module::IRC::channels{$k}};
-        if(@conns) {
-            $BarnOwl::Module::IRC::channels{$k} = \@conns;
-        } else {
-            delete $BarnOwl::Module::IRC::channels{$k};
-        }
-    }
-    $self->motd("");
+    $self->conn->disconnect;
 }
 
@@ -259,8 +255,10 @@
     my ($self, $why) = @_;
     BarnOwl::admin_message('IRC',
-                           "[" . $self->alias . "] Disconnected from server");
-    $self->disconnect;
-    if ($why && $why =~ m{error in connection}) {
+                           "[" . $self->alias . "] Disconnected from server: $why");
+    $self->motd("");
+    if (!$self->did_quit) {
         $self->schedule_reconnect;
+    } else {
+        delete $BarnOwl::Module::IRC::ircnets{$self->alias};
     }
 }
@@ -400,5 +398,12 @@
 sub schedule_reconnect {
     my $self = shift;
-    my $interval = shift || 5;
+    my $interval = $self->backoff;
+    if ($interval) {
+        $interval *= 2;
+        $interval = 60*5 if $interval > 60*5;
+    } else {
+        $interval = 5;
+    }
+    $self->backoff($interval);
 
     my $weak = $self;
@@ -443,23 +448,16 @@
     }
     $self->conn->enable_ping(60, sub {
-                                 $self->disconnect("Connection timed out.");
+                                 $self->on_disconnect("Connection timed out.");
                                  $self->schedule_reconnect;
                              });
+    $self->backoff(0);
 }
 
 sub reconnect {
     my $self = shift;
-    my $backoff = shift;
+    my $backoff = $self->backoff;
 
     $self->autoconnect_channels([keys(%{$self->{channel_list}})]);
-    $self->conn->connect;
-    if ($self->conn->connected) {
-        $self->connected("Reconnected to ".$self->alias);
-        return;
-    }
-
-    $backoff *= 2;
-    $backoff = 60*5 if $backoff > 60*5;
-    $self->schedule_reconnect( $backoff );
+    $self->conn->connect(@{$self->connect_args});
 }
 
