diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 372d8d942221f42eaf88a443aac19cdbe79e20b1..5e777b4c3f4b30b25d8c42d56c4442f8ebe1e025 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -1187,6 +1187,7 @@ struct sip_settings {
 	int callevents;			/*!< Whether we send manager events or not */
 	int regextenonqualify;  	/*!< Whether to add/remove regexten when qualifying peers */
 	int matchexterniplocally;	/*!< Match externip/externhost setting against localnet setting */
+	unsigned int disallowed_methods; /*!< methods that we should never try to use */
 	int notifyringing;		/*!< Send notifications on ringing */
 	int notifyhold;			/*!< Send notifications on hold */
 	enum notifycid_setting notifycid; /*!< Send CID with ringing notifications */
@@ -1817,11 +1818,15 @@ struct sip_pvt {
 	int hangupcause;			/*!< Storage of hangupcause copied from our owner before we disconnect from the AST channel (only used at hangup) */
 
 	struct sip_subscription_mwi *mwi;       /*!< If this is a subscription MWI dialog, to which subscription */
-	/*! The SIP methods allowed on this dialog. We get this information from the Allow header present in 
-	 * the peer's REGISTER. If peer does not register with us, then we will use the first transaction we
-	 * have with this peer to determine its allowed methods.
+	/*! The SIP methods supported by this peer. We get this information from the Allow header of the first
+	 * message we receive from an endpoint during a dialog.
 	 */
 	unsigned int allowed_methods;
+	/*! Some peers are not trustworthy with their Allow headers, and so we need to override their wicked
+	 * ways through configuration. This is a copy of the peer's disallowed_methods, so that we can apply them
+	 * to the sip_pvt at various stages of dialog establishment
+	 */
+	unsigned int disallowed_methods;
 	/*! When receiving an SDP offer, it is important to take note of what media types were offered.
 	 * By doing this, even if we don't want to answer a particular media stream with something meaningful, we can
 	 * still put an m= line in our answer with the port set to 0.
@@ -2027,7 +2032,7 @@ struct sip_peer {
 	
 	/*XXX Seems like we suddenly have two flags with the same content. Why? To be continued... */
 	enum sip_peer_type type; /*!< Distinguish between "user" and "peer" types. This is used solely for CLI and manager commands */
-	unsigned int allowed_methods;
+	unsigned int disallowed_methods;
 };
 
 
@@ -5107,7 +5112,7 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
 	dialog->rtptimeout = peer->rtptimeout;
 	dialog->peerauth = peer->auth;
 	dialog->maxcallbitrate = peer->maxcallbitrate;
-	dialog->allowed_methods = peer->allowed_methods;
+	dialog->disallowed_methods = peer->disallowed_methods;
 	if (ast_strlen_zero(dialog->tohost))
 		ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr));
 	if (!ast_strlen_zero(peer->fromdomain)) {
@@ -5201,6 +5206,7 @@ static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockadd
 	}
 
 	ast_string_field_set(dialog, tohost, peername);
+	dialog->allowed_methods &= ~sip_cfg.disallowed_methods;
 
 	/* Get the outbound proxy information */
 	ref_proxy(dialog, obproxy_get(dialog, NULL));
@@ -7096,6 +7102,7 @@ static struct sip_pvt *sip_alloc(ast_string_field callid, struct sockaddr_in *si
 	p->branch = ast_random();	
 	make_our_tag(p->tag, sizeof(p->tag));
 	p->ocseq = INITIAL_CSEQ;
+	p->allowed_methods = UINT_MAX;
 
 	if (sip_methods[intended_method].need_rtp) {
 		if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && (p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr))) {
@@ -7521,6 +7528,17 @@ static int is_method_allowed(unsigned int *allowed_methods, enum sipmethod metho
 	return ((*allowed_methods) >> method) & 1;
 }
 
+static void mark_parsed_methods(unsigned int *methods, char *methods_str)
+{
+	char *method;
+	for (method = strsep(&methods_str, ","); !ast_strlen_zero(method); method = strsep(&methods_str, ",")) {
+		int id = find_sip_method(ast_skip_blanks(method));
+		if (id == SIP_UNKNOWN) {
+			continue;
+		}
+		mark_method_allowed(methods, id);
+	}
+}
 /*!
  * \brief parse the Allow header to see what methods the endpoint we
  * are communicating with allows.
@@ -7540,7 +7558,6 @@ static int is_method_allowed(unsigned int *allowed_methods, enum sipmethod metho
 static unsigned int parse_allowed_methods(struct sip_request *req)
 {
 	char *allow = ast_strdupa(get_header(req, "Allow"));
-	char *method;
 	unsigned int allowed_methods = SIP_UNKNOWN;
 
 	if (ast_strlen_zero(allow)) {
@@ -7567,13 +7584,7 @@ static unsigned int parse_allowed_methods(struct sip_request *req)
 		}
 		allow = ast_strip_quoted(methods + 9, "\"", "\"");
 	}
-	for (method = strsep(&allow, ","); !ast_strlen_zero(method); method = strsep(&allow, ",")) {
-		int id = find_sip_method(ast_skip_blanks(method));
-		if (id == SIP_UNKNOWN) {
-			continue;
-		}
-		mark_method_allowed(&allowed_methods, id);
-	}
+	mark_parsed_methods(&allowed_methods, allow);
 	return allowed_methods;
 }
 
@@ -7593,6 +7604,7 @@ static unsigned int set_pvt_allowed_methods(struct sip_pvt *pvt, struct sip_requ
 	if (ast_test_flag(&pvt->flags[1], SIP_PAGE2_RPID_UPDATE)) {
 		mark_method_allowed(&pvt->allowed_methods, SIP_UPDATE);
 	}
+	pvt->allowed_methods &= ~(pvt->disallowed_methods);
 
 	return pvt->allowed_methods;
 }
@@ -11876,7 +11888,6 @@ static int expire_register(const void *data)
 	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);
-	peer->allowed_methods = SIP_UNKNOWN;
 
 	/* Do we need to release this peer from memory? 
 		Only for realtime peers and autocreated peers
@@ -11919,13 +11930,11 @@ static void reg_source_db(struct sip_peer *peer)
 	int expire;
 	int port;
 	char *scan, *addr, *port_str, *expiry_str, *username, *contact;
-	char allowed_methods_str[256] = "";
 
 	if (peer->rt_fromcontact) 
 		return;
 	if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data)))
 		return;
-	ast_db_get("SIP/PeerMethods", peer->name, allowed_methods_str, sizeof(allowed_methods_str));
 
 	scan = data;
 	addr = strsep(&scan, ":");
@@ -11952,10 +11961,6 @@ static void reg_source_db(struct sip_peer *peer)
 	if (contact)
 		ast_string_field_set(peer, fullcontact, contact);
 
-	if (!ast_strlen_zero(allowed_methods_str)) {
-		peer->allowed_methods = atoi(allowed_methods_str);
-	}
-
 	ast_debug(2, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n",
 	    peer->name, peer->username, ast_inet_ntoa(in), port, expire);
 
@@ -13003,16 +13008,6 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr
 		}
 	}
 	if (peer) {
-		ao2_lock(peer);
-		if (peer->allowed_methods == SIP_UNKNOWN) {
-			peer->allowed_methods = set_pvt_allowed_methods(p, req);
-		}
-		if (!peer->rt_fromcontact) {
-			char allowed_methods_str[256];
-			snprintf(allowed_methods_str, sizeof(allowed_methods_str), "%u", peer->allowed_methods);
-			ast_db_put("SIP/PeerMethods", peer->name, allowed_methods_str);
-		}
-		ao2_unlock(peer);
 		unref_peer(peer, "register_verify: unref_peer: tossing stack peer pointer at end of func");
 	}
 
@@ -13988,11 +13983,8 @@ static enum check_auth_result check_peer_ok(struct sip_pvt *p, char *of,
 	ast_string_field_set(p, mohsuggest, peer->mohsuggest);
 	ast_string_field_set(p, parkinglot, peer->parkinglot);
 	ast_string_field_set(p, engine, peer->engine);
-	if (peer->allowed_methods == SIP_UNKNOWN) {
-		set_pvt_allowed_methods(p, req);
-	} else {
-		p->allowed_methods = peer->allowed_methods;
-	}
+	p->disallowed_methods = peer->disallowed_methods;
+	set_pvt_allowed_methods(p, req);
 	if (peer->callingpres)	/* Peer calling pres setting will override RPID */
 		p->callingpres = peer->callingpres;
 	if (peer->maxms && peer->lastms)
@@ -17677,21 +17669,6 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
 	else
 		ast_debug(4, "SIP response %d to standard invite\n", resp);
 
-	/* If this is a response to our initial INVITE, we need to set what we can use
-	 * for this peer.
-	 */
-	if (!reinvite && p->allowed_methods == SIP_UNKNOWN) {
-		struct sip_peer *peer = find_peer(p->peername, NULL, 1, FINDPEERS, FALSE);
-		if (!peer || peer->allowed_methods == SIP_UNKNOWN) {
-			set_pvt_allowed_methods(p, req);
-		} else {
-			p->allowed_methods = peer->allowed_methods;
-		}
-		if (peer) {
-			unref_peer(peer, "handle_response_invite: Getting supported methods from peer");
-		}
-	}
-
 	if (p->alreadygone) { /* This call is already gone */
 		ast_debug(1, "Got response on call that is already terminated: %s (ignoring)\n", p->callid);
 		return;
@@ -17719,6 +17696,13 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
 	if ((resp == 200 || resp >= 300) && p->pendinginvite && seqno == p->pendinginvite)
 		p->pendinginvite = 0;
 
+	/* If this is a response to our initial INVITE, we need to set what we can use
+	 * for this peer.
+	 */
+	if (!reinvite) {
+		set_pvt_allowed_methods(p, req);
+	}		
+
 	switch (resp) {
 	case 100:	/* Trying */
 	case 101:	/* Dialog establishment */
@@ -18087,7 +18071,6 @@ static void handle_response_notify(struct sip_pvt *p, int resp, const char *rest
 /* \brief Handle SIP response in SUBSCRIBE transaction */
 static void handle_response_subscribe(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
 {
-	struct sip_peer *peer;
 	if (!p->mwi) {
 		return;
 	}
@@ -18095,15 +18078,7 @@ static void handle_response_subscribe(struct sip_pvt *p, int resp, const char *r
 	switch (resp) {
 	case 200: /* Subscription accepted */
 		ast_debug(3, "Got 200 OK on subscription for MWI\n");
-		peer = find_peer(p->peername, NULL, 1, FINDPEERS, FALSE);
-		if (!peer || peer->allowed_methods == SIP_UNKNOWN) {
-			set_pvt_allowed_methods(p, req);
-		} else {
-			p->allowed_methods = peer->allowed_methods;
-		}
-		if (peer) {
-			unref_peer(peer, "handle_response_subscribe: Getting supported methods");
-		}
+		set_pvt_allowed_methods(p, req);
 		if (p->options) {
 			ast_free(p->options);
 			p->options = NULL;
@@ -18422,12 +18397,6 @@ static void handle_response_peerpoke(struct sip_pvt *p, int resp, struct sip_req
 		manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
 			"ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n",
 			peer->name, s, pingtime);
-		if (!is_reachable) {
-			peer->allowed_methods = SIP_UNKNOWN;
-		} else {
-			set_pvt_allowed_methods(p, req);
-			peer->allowed_methods = p->allowed_methods;
-		}
 		if (is_reachable && sip_cfg.regextenonqualify)
 			register_peer_exten(peer, TRUE);
 	}
@@ -18682,7 +18651,7 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
 		case 501: /* Not Implemented */
 			mark_method_unallowed(&p->allowed_methods, sipmethod);
 			if ((peer = find_peer(p->peername, 0, 1, FINDPEERS, FALSE))) {
-				peer->allowed_methods = p->allowed_methods;
+				mark_method_allowed(&peer->disallowed_methods, sipmethod);
 				unref_peer(peer, "handle_response: marking a specific method as unallowed");
 			}
 			if (sipmethod == SIP_INVITE)
@@ -20209,6 +20178,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
 		/* This is a new invite */
 		/* Handle authentication if this is our first invite */
 		struct ast_party_redirecting redirecting = {{0,},};
+		set_pvt_allowed_methods(p, req);
 		res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin);
 		if (res == AUTH_CHALLENGE_SENT) {
 			p->invitestate = INV_COMPLETED;		/* Needs to restart in another INVITE transaction */
@@ -21494,6 +21464,7 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
 	if (!req->ignore && !resubscribe) {	/* Set up dialog, new subscription */
 		const char *to = get_header(req, "To");
 		char totag[128];
+		set_pvt_allowed_methods(p, req);
 
 		/* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */
 		if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) {
@@ -23830,6 +23801,7 @@ static void set_peer_defaults(struct sip_peer *peer)
 	peer->timer_t1 = global_t1;
 	peer->timer_b = global_timer_b;
 	clear_peer_mailboxes(peer);
+	peer->disallowed_methods = sip_cfg.disallowed_methods;
 }
 
 /*! \brief Create temporary peer (used in autocreatepeer mode) */
@@ -24285,6 +24257,9 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
 			} else {
 				peer->stimer.st_ref = i;
 			}
+		} else if (!strcasecmp(v->name, "disallowed_methods")) {
+			char *disallow = ast_strdupa(v->value);
+			mark_parsed_methods(&peer->disallowed_methods, disallow);
 		}
 	}
 
@@ -24572,6 +24547,7 @@ static int reload_config(enum channelreloadreason reason)
 	sip_cfg.directrtpsetup = FALSE;		/* Experimental feature, disabled by default */
 	sip_cfg.alwaysauthreject = DEFAULT_ALWAYSAUTHREJECT;
 	sip_cfg.allowsubscribe = FALSE;
+	sip_cfg.disallowed_methods = SIP_UNKNOWN;
 	snprintf(global_useragent, sizeof(global_useragent), "%s %s", DEFAULT_USERAGENT, ast_get_version());
 	snprintf(global_sdpsession, sizeof(global_sdpsession), "%s %s", DEFAULT_SDPSESSION, ast_get_version());
 	snprintf(global_sdpowner, sizeof(global_sdpowner), "%s", DEFAULT_SDPOWNER);
@@ -25064,6 +25040,9 @@ static int reload_config(enum channelreloadreason reason)
 				ast_log(LOG_WARNING, "Invalid pokepeers '%s' at line %d of %s\n", v->value, v->lineno, config);
 				global_qualify_peers = DEFAULT_QUALIFY_PEERS;
 			}
+		} else if (!strcasecmp(v->name, "disallowed_methods")) {
+			char *disallow = ast_strdupa(v->value);
+			mark_parsed_methods(&sip_cfg.disallowed_methods, disallow);
 		}
 	}