Index: channels/chan_sip.c
===================================================================
--- channels/chan_sip.c	(revision 346643)
+++ channels/chan_sip.c	(working copy)
@@ -229,7 +229,7 @@
    In normal operation, the macros defined will throw away the tags, so they do not
    affect the speed of the program at all. They can be considered to be documentation.
 */
-/* #define  REF_DEBUG 1 */
+#define  REF_DEBUG 1
 #include "asterisk/lock.h"
 #include "asterisk/config.h"
 #include "asterisk/module.h"
@@ -24072,7 +24072,7 @@
 		/* if an authentication response was sent, we are done here */
 		if (res == AUTH_CHALLENGE_SENT)	/* authpeer = NULL here */
 			return 0;
-		if (res < 0) {
+		if (res != AUTH_SUCCESSFUL) {
 			if (res == AUTH_FAKE_AUTH) {
 				ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From"));
 				transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE);
@@ -24086,17 +24086,15 @@
 		}
 	}
 
-	/* At this point, authpeer cannot be NULL. Remember we hold a reference,
-	 * so we must release it when done.
-	 * XXX must remove all the checks for authpeer == NULL.
+	/* At this point, we hold a reference to authpeer (if not NULL).  It
+	 * must be released when done.
 	 */
 
 	/* Check if this device  is allowed to subscribe at all */
 	if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
 		transmit_response(p, "403 Forbidden (policy)", req);
 		pvt_set_needdestroy(p, "subscription not allowed");
-		if (authpeer)
-			unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 1)");
+		unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 1)");
 		return 0;
 	}
 
@@ -24116,8 +24114,7 @@
 			transmit_response(p, "404 Not Found", req);
 		}
 		pvt_set_needdestroy(p, "subscription target not found");
-		if (authpeer)
-			unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)");
+		unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 1)");
 		return 0;
 	}
 
@@ -24132,9 +24129,6 @@
 		enum subscriptiontype subscribed = NONE;
 		const char *unknown_acceptheader = NULL;
 
-		if (authpeer)	/* We do not need the authpeer any more */
-			authpeer = unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)");
-
 		/* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
 		accept = __get_header(req, "Accept", &start);
 		while ((subscribed == NONE) && !ast_strlen_zero(accept)) {
@@ -24172,6 +24166,7 @@
 					p->subscribecontext,
 					p->subscribeuri);
 				pvt_set_needdestroy(p, "no Accept header");
+				unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)");
 				return 0;
 			}
 			/* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least.
@@ -24196,6 +24191,7 @@
 				p->subscribecontext,
 				p->subscribeuri);
 			pvt_set_needdestroy(p, "unrecognized format");
+			unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)");
 			return 0;
 		} else {
 			p->subscribed = subscribed;
@@ -24218,8 +24214,7 @@
 			transmit_response(p, "406 Not Acceptable", req);
 			ast_debug(2, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader);
 			pvt_set_needdestroy(p, "unknown format");
-			if (authpeer)
-				unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 3)");
+			unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 3)");
 			return 0;
 		}
 		/* Looks like they actually want a mailbox status
@@ -24231,8 +24226,7 @@
 			transmit_response(p, "404 Not found (no mailbox)", req);
 			pvt_set_needdestroy(p, "received 404 response");
 			ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", S_OR(authpeer->name, ""));
-			if (authpeer)
-				unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 4)");
+			unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 3)");
 			return 0;
 		}
 
@@ -24246,14 +24240,16 @@
 			/* We only allow one subscription per peer */
 			dialog_unlink_all(authpeer->mwipvt, TRUE, TRUE);
 			authpeer->mwipvt = dialog_unref(authpeer->mwipvt, "unref dialog authpeer->mwipvt");
+			authpeer->mwipvt = dialog_ref(p, "setting peers' mwipvt to p");		/* Link from peer to pvt UH- should this be dialog_ref()? */
 			/* sip_destroy(authpeer->mwipvt); */
 		}
-		if (authpeer->mwipvt)
-			dialog_unref(authpeer->mwipvt, "Unref previously stored mwipvt dialog pointer");
-		authpeer->mwipvt = dialog_ref(p, "setting peers' mwipvt to p");		/* Link from peer to pvt UH- should this be dialog_ref()? */
-		if (p->relatedpeer)
-			unref_peer(p->relatedpeer, "Unref previously stored relatedpeer ptr");
-		p->relatedpeer = ref_peer(authpeer, "setting dialog's relatedpeer pointer");	/* already refcounted...Link from pvt to peer UH- should this be dialog_ref()? */
+
+		if (p->relatedpeer != authpeer) {
+			if (p->relatedpeer) {
+				unref_peer(p->relatedpeer, "Unref previously stored relatedpeer ptr");
+			}
+			p->relatedpeer = ref_peer(authpeer, "setting dialog's relatedpeer pointer");	/* already refcounted...Link from pvt to peer UH- should this be dialog_ref()? */
+		}
 		/* Do not release authpeer here */
 	} else if (!strcmp(event, "call-completion")) {
 		handle_cc_subscribe(p, req);
@@ -24261,16 +24257,10 @@
 		transmit_response(p, "489 Bad Event", req);
 		ast_debug(2, "Received SIP subscribe for unknown event package: %s\n", event);
 		pvt_set_needdestroy(p, "unknown event package");
-		if (authpeer)
-			unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 5)");
+		unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 5)");
 		return 0;
 	}
 
-	/* At this point, if we have an authpeer we should unref it. */
-	if (authpeer) {
-		authpeer = unref_peer(authpeer, "unref pointer into (*authpeer)");
-	}
-
 	/* Add subscription for extension state from the PBX core */
 	if (p->subscribed != MWI_NOTIFICATION  && p->subscribed != CALL_COMPLETION && !resubscribe) {
 		if (p->stateid > -1) {
@@ -24295,6 +24285,7 @@
 				"with Expire header less that 'minexpire' limit. Received \"Expire: %d\" min is %d\n",
 				p->exten, p->context, p->expiry, min_expiry);
 			pvt_set_needdestroy(p, "Expires is less that the min expires allowed.");
+			unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 6)");
 			return 0;
 		}
 
@@ -24329,6 +24320,7 @@
 				ast_log(LOG_NOTICE, "Got SUBSCRIBE for extension %s@%s from %s, but there is no hint for that extension.\n", p->exten, p->context, ast_sockaddr_stringify(&p->sa));
 				transmit_response(p, "404 Not found", req);
 				pvt_set_needdestroy(p, "no extension for SUBSCRIBE");
+				unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 6)");
 				return 0;
 			}
 			ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
@@ -24344,6 +24336,11 @@
 			pvt_set_needdestroy(p, "forcing expiration");
 		}
 	}
+
+	/* At this point, if we have an authpeer we should unref it. */
+	if (authpeer) {
+		authpeer = unref_peer(authpeer, "unref pointer into (*authpeer)");
+	}
 	return 1;
 }
 
Index: channels/sip/include/sip.h
===================================================================
--- channels/sip/include/sip.h	(revision 346643)
+++ channels/sip/include/sip.h	(working copy)
@@ -469,7 +469,7 @@
 	AUTH_PEER_NOT_DYNAMIC = -6,
 	AUTH_ACL_FAILED = -7,
 	AUTH_BAD_TRANSPORT = -8,
-	AUTH_RTP_FAILED = 9,
+	AUTH_RTP_FAILED = -9,
 };
 
 /*! \brief States for outbound registrations (with register= lines in sip.conf */
