--- chan_sip.c.orig	2010-02-02 11:58:14.000000000 -0800
+++ chan_sip.c	2010-02-19 15:44:02.031250000 -0800
@@ -2507,6 +2507,7 @@
 static void set_insecure_flags(struct ast_flags *flags, const char *value, int lineno);
 static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v);
 static void set_socket_transport(struct sip_socket *socket, int transport);
+static void unregister_peer(struct sip_peer *peer, const char* mgr_cause);
 
 /* Realtime device support */
 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, const char *useragent, int expirey, int deprecated_username, int lastms);
@@ -12020,8 +12021,23 @@
 	if (!peer)		/* Hmmm. We have no peer. Weird. */
 		return 0;
 
+	unregister_peer(peer, "Expired");
+
+	unref_peer(peer, "removing peer ref for expire_register");
+
+	return 0;
+}
+
+/*! \brief Unregister, report and optionally unlink a SIP peer */
+static void unregister_peer(struct sip_peer *peer, const char* mgr_cause)
+{
 	peer->expire = -1;
 	peer->portinuri = 0;
+	peer->sipoptions = 0;
+	peer->lastms = 0;
+	ast_string_field_set(peer, fullcontact, "");
+	ast_string_field_set(peer, useragent, "");
+
 	memset(&peer->addr, 0, sizeof(peer->addr));
 
 	destroy_association(peer);	/* remove registration data from storage */
@@ -12032,10 +12048,16 @@
 		peer->socket.tcptls_session = NULL;
 	}
 
-	manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
 	register_peer_exten(peer, FALSE);	/* Remove regexten */
 	ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
 
+	if (mgr_cause)
+		manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: %s\r\n", peer->name, mgr_cause);
+	else
+		manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name);
+
+	ast_verb(3, "Unregistered SIP '%s'\n", peer->name);
+
 	/* Do we need to release this peer from memory? 
 		Only for realtime peers and autocreated peers
 	*/
@@ -12048,11 +12070,8 @@
 		if (peer->addr.sin_addr.s_addr) {
 			ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
 		}
+		ast_verb(3, "Unlinked SIP peer '%s'\n", peer->name);
 	}
-
-	unref_peer(peer, "removing peer ref for expire_register");
-
-	return 0;
 }
 
 /*! \brief Poke peer (send qualify to check if peer is alive and well) */
@@ -12265,25 +12284,12 @@
 		return PARSE_REGISTER_QUERY;
 	} else if (!strcasecmp(curi, "*") || !expire) {	/* Unregister this peer */
 		/* This means remove all registrations and return OK */
-		memset(&peer->addr, 0, sizeof(peer->addr));
-		set_socket_transport(&peer->socket, peer->default_outbound_transport);
-
 		AST_SCHED_DEL_UNREF(sched, peer->expire,
 				unref_peer(peer, "remove register expire ref"));
 
-		destroy_association(peer);
-
-		register_peer_exten(peer, FALSE);	/* Remove extension from regexten= setting in sip.conf */
-		ast_string_field_set(peer, fullcontact, "");
-		ast_string_field_set(peer, useragent, "");
-		peer->sipoptions = 0;
-		peer->lastms = 0;
-		peer->portinuri = 0;
+		unregister_peer(peer, NULL);
 		pvt->expiry = 0;
 
-		ast_verb(3, "Unregistered SIP '%s'\n", peer->name);
-
-		manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name);
 		return PARSE_REGISTER_UPDATE;
 	}
 
@@ -15812,10 +15818,10 @@
 		if (peer->expire > 0) {
 			AST_SCHED_DEL_UNREF(sched, peer->expire,
 				unref_peer(peer, "remove register expire ref"));
-			expire_register(ref_peer(peer, "ref for expire_register"));
-			ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]);
+			unregister_peer(peer, NULL);
+			ast_cli(a->fd, "Unregistered peer \'%s\'\n", a->argv[2]);
 		} else {
-			ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
+			ast_cli(a->fd, "Peer \'%s\' not registered\n", a->argv[2]);
 		}
 		unref_peer(peer, "sip_unregister: unref_peer via sip_unregister: done with peer from find_peer call");
 	} else {
