diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 6051fa9ec59e5006a191c6d7dfe930eb3b96ac29..dfde185c5a5de1c8bab71f5cc9e4402355af39ca 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -487,8 +487,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #endif
 
 /* Arguments for find_peer */
-#define	FINDALLDEVICES	FALSE
-#define FINDONLYUSERS	TRUE
+#define FINDUSERS (1 << 0)
+#define FINDPEERS (1 << 1)
+#define FINDALLDEVICES (FINDUSERS | FINDPEERS)
 
 #define	SIPBUFSIZE		512		/*!< Buffer size for many operations */
 
@@ -1898,7 +1899,6 @@ 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 */
-	char onlymatchonip;		/*!< Only match on IP for incoming calls (old type=peer) */
 };
 
 
@@ -2438,7 +2438,7 @@ static void sip_dump_history(struct sip_pvt *dialog);
 
 /*--- Device object handling */
 static struct sip_peer *temp_peer(const char *name);
-static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int ispeer);
+static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime);
 static int update_call_counter(struct sip_pvt *fup, int event);
 static void sip_destroy_peer(struct sip_peer *peer);
 static void sip_destroy_peer_fn(void *peer);
@@ -4471,7 +4471,7 @@ static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_i
 
 
 	/* Peer found in realtime, now build it in memory */
-	peer = build_peer(newpeername, var, varregs, TRUE, FALSE);
+	peer = build_peer(newpeername, var, varregs, TRUE);
 	if (!peer) {
 		if(peerlist)
 			ast_config_destroy(peerlist);
@@ -4513,38 +4513,52 @@ static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_i
 static int find_by_name(void *obj, void *arg, void *data, int flags)
 {
 	struct sip_peer *search = obj, *match = arg;
-	int *forcenamematch = data;
+	int *which_objects = data;
 
 	/* Usernames in SIP uri's are case sensitive. Domains are not */
 	if (strcmp(search->name, match->name)) {
 		return 0;
 	}
 
-	/* If we're only looking for name matches, we should avoid type=peer devices,
-	   since these should not match on any name-based search */
-	if (*forcenamematch && search->onlymatchonip) {
-		return 0;
+	switch (*which_objects) {
+	case FINDUSERS:
+		if (!(search->type & SIP_TYPE_USER)) {
+			return 0;
+		}
+		break;
+	case FINDPEERS:
+		if (!(search->type & SIP_TYPE_PEER)) {
+			return 0;
+		}
+		break;
+	case FINDALLDEVICES:
+		break;
 	}
 
 	return CMP_MATCH | CMP_STOP;
 }
 
-/*! \brief Locate device by name or ip address 
+/*! 
+ * \brief Locate device by name or ip address 
+ *
+ * \param which_objects Define which objects should be matched when doing a lookup
+ *        by name.  Valid options are FINDUSERS, FINDPEERS, or FINDALLDEVICES.
+ *        Note that this option is not used at all when doing a lookup by IP.
+ *
  *	This is used on find matching device on name or ip/port.
-	If the device was declared as type=peer, we don't match on peer name on incoming INVITEs.
-	
-	\note Avoid using this function in new functions if there is a way to avoid it,
-	since it might cause a database lookup.
-
-*/
-static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime, int forcenamematch, int devstate_only)
+ * If the device was declared as type=peer, we don't match on peer name on incoming INVITEs.
+ *
+ * \note Avoid using this function in new functions if there is a way to avoid it,
+ * since it might cause a database lookup.
+ */
+static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime, int which_objects, int devstate_only)
 {
 	struct sip_peer *p = NULL;
 	struct sip_peer tmp_peer;
 
 	if (peer) {
 		ast_copy_string(tmp_peer.name, peer, sizeof(tmp_peer.name));
-		p = ao2_t_callback_data(peers, OBJ_POINTER, find_by_name, &tmp_peer, &forcenamematch, "ao2_find in peers table");
+		p = ao2_t_callback_data(peers, OBJ_POINTER, find_by_name, &tmp_peer, &which_objects, "ao2_find in peers table");
 	} else if (sin) { /* search by addr? */
 		tmp_peer.addr.sin_addr.s_addr = sin->sin_addr.s_addr;
 		tmp_peer.addr.sin_port = sin->sin_port;
@@ -4839,7 +4853,7 @@ static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockadd
 	dialog->sa.sin_family = AF_INET;
 	dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
 	dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
-	peer = find_peer(peername, NULL, TRUE, FINDALLDEVICES, FALSE);
+	peer = find_peer(peername, NULL, TRUE, FINDPEERS, FALSE);
 
 	if (peer) {
 		int res;
@@ -11972,7 +11986,7 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr
 
 	ast_string_field_set(p, exten, name);
 	build_contact(p);
-	peer = find_peer(name, NULL, TRUE, FINDALLDEVICES, FALSE);
+	peer = find_peer(name, NULL, TRUE, FINDPEERS, FALSE);
 	if (!(peer && ast_apply_ha(peer->ha, sin))) {
 		/* Peer fails ACL check */
 		if (peer) {
@@ -12884,11 +12898,11 @@ static enum check_auth_result check_peer_ok(struct sip_pvt *p, char *of,
 		peer = find_peer(of, NULL, TRUE, FINDALLDEVICES, FALSE);
 	} else {
 		/* First find devices based on username (avoid all type=peer's) */
-		peer = find_peer(of, NULL, TRUE, FINDONLYUSERS, FALSE);
+		peer = find_peer(of, NULL, TRUE, FINDUSERS, FALSE);
 
 		/* Then find devices based on IP */
 		if (!peer) {
-			peer = find_peer(NULL, &p->recv, TRUE, FINDALLDEVICES, FALSE);
+			peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE);
 		}
 	}
 
@@ -14226,7 +14240,7 @@ static char *_sip_qualify_peer(int type, int fd, struct mansession *s, const str
 		return CLI_SHOWUSAGE;
 
 	load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
-	if ((peer = find_peer(argv[3], NULL, load_realtime, FINDALLDEVICES, FALSE))) {
+	if ((peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE))) {
 		sip_poke_peer(peer, 1);
 		unref_peer(peer, "qualify: done with peer");
 	} else if (type == 0) {
@@ -14308,7 +14322,8 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
 		return CLI_SHOWUSAGE;
 
 	load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
-	peer = find_peer(argv[3], NULL, load_realtime, FINDALLDEVICES, FALSE);
+	peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE);
+
 	if (s) { 	/* Manager */
 		if (peer) {
 			const char *id = astman_get_header(m, "ActionID");
@@ -14590,7 +14605,7 @@ static char *sip_show_user(struct ast_cli_entry *e, int cmd, struct ast_cli_args
 	/* Load from realtime storage? */
 	load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? TRUE : FALSE;
 
-	if ((user = find_peer(a->argv[3], NULL, load_realtime, TRUE, FALSE))) {
+	if ((user = find_peer(a->argv[3], NULL, load_realtime, FINDUSERS, FALSE))) {
 		ao2_lock(user);
 		ast_cli(a->fd, "\n\n");
 		ast_cli(a->fd, "  * Name       : %s\n", user->name);
@@ -14748,7 +14763,7 @@ static char *sip_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
 	if (a->argc != 3)
 		return CLI_SHOWUSAGE;
 	
-	if ((peer = find_peer(a->argv[2], NULL, load_realtime, FINDALLDEVICES, TRUE))) {
+	if ((peer = find_peer(a->argv[2], NULL, load_realtime, FINDPEERS, TRUE))) {
 		if (peer->expire > 0) {
 			expire_register(ref_peer(peer, "ref for expire_register"));
 			ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]);
@@ -15758,7 +15773,7 @@ static char *sip_do_debug_ip(int fd, char *arg)
 /*! \brief  Turn on SIP debugging for a given peer */
 static char *sip_do_debug_peer(int fd, char *arg)
 {
-	struct sip_peer *peer = find_peer(arg, NULL, TRUE, FINDALLDEVICES, FALSE);
+	struct sip_peer *peer = find_peer(arg, NULL, TRUE, FINDPEERS, FALSE);
 	if (!peer)
 		ast_cli(fd, "No such peer '%s'\n", arg);
 	else if (peer->addr.sin_addr.s_addr == 0)
@@ -16213,7 +16228,7 @@ static int function_sippeer(struct ast_channel *chan, const char *cmd, char *dat
 	else
 		colname = "ip";
 
-	if (!(peer = find_peer(data, NULL, TRUE, FINDALLDEVICES, FALSE)))
+	if (!(peer = find_peer(data, NULL, TRUE, FINDPEERS, FALSE)))
 		return -1;
 
 	if (!strcasecmp(colname, "ip")) {
@@ -21571,7 +21586,7 @@ int st_get_se(struct sip_pvt *p, int max)
 		if (p->stimer->st_cached_max_se) {
 			return p->stimer->st_cached_max_se;
 		} else if (p->peername) {
-			struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDALLDEVICES, FALSE);
+			struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDPEERS, FALSE);
 			if (pp) {
 				p->stimer->st_cached_max_se = pp->stimer.st_max_se;
 				unref_peer(pp, "unref peer pointer from find_peer call in st_get_se");
@@ -21584,7 +21599,7 @@ int st_get_se(struct sip_pvt *p, int max)
 		if (p->stimer->st_cached_min_se) {
 			return p->stimer->st_cached_min_se;
 		} else if (p->peername) {
-			struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDALLDEVICES, FALSE);
+			struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDPEERS, FALSE);
 			if (pp) {
 				p->stimer->st_cached_min_se = pp->stimer.st_min_se;
 				unref_peer(pp, "unref peer pointer from find_peer call in st_get_se (2)");
@@ -21606,7 +21621,7 @@ enum st_refresher st_get_refresher(struct sip_pvt *p)
 		return p->stimer->st_cached_ref;
 
 	if (p->peername) {
-		struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDALLDEVICES, FALSE);
+		struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDPEERS, FALSE);
 		if (pp) {
 			p->stimer->st_cached_ref = pp->stimer.st_ref;
 			unref_peer(pp, "unref peer pointer from find_peer call in st_get_refresher");
@@ -21631,7 +21646,7 @@ enum st_mode st_get_mode(struct sip_pvt *p)
 		return p->stimer->st_cached_mode;
 
 	if (p->peername) {
-		struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDALLDEVICES, FALSE);
+		struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDPEERS, FALSE);
 		if (pp) {
 			p->stimer->st_cached_mode = pp->stimer.st_mode_oper;
 			unref_peer(pp, "unref peer pointer from find_peer call in st_get_mode");
@@ -22473,7 +22488,7 @@ static void add_peer_mailboxes(struct sip_peer *peer, const char *value)
 }
 
 /*! \brief Build peer from configuration (file or realtime static/dynamic) */
-static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int ispeer)
+static struct sip_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
 {
 	struct sip_peer *peer = NULL;
 	struct ast_ha *oldha = NULL;
@@ -22488,7 +22503,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
 	const char *srvlookup = NULL;
 	static int deprecation_warning = 1;
 	struct ast_str *fullcontact = ast_str_alloca(512);
-	
+
 	if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
 		/* Note we do NOT use find_peer here, to avoid realtime recursion */
 		/* We also use a case-sensitive comparison (unlike find_peer) so
@@ -22498,13 +22513,13 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
 		ast_copy_string(tmp_peer.name, name, sizeof(tmp_peer.name));
 		peer = ao2_t_find(peers, &tmp_peer, OBJ_POINTER | OBJ_UNLINK, "find and unlink peer from peers table");
 	}
-	
+
 	if (peer) {
 		/* Already in the list, remove it and it will be added back (or FREE'd)  */
 		found++;
 		if (!(peer->the_mark))
 			firstpass = 0;
- 	} else {
+	} else {
 		if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct")))
 			return NULL;
 
@@ -22520,17 +22535,16 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
 			ast_atomic_fetchadd_int(&speerobjs, 1);
 	}
 
-	peer->onlymatchonip = ispeer;		/* If type=peer, don't match on caller ID for incoming calls */
-
 	/* Note that our peer HAS had its reference count increased */
 	if (firstpass) {
 		peer->lastmsgssent = -1;
 		oldha = peer->ha;
 		peer->ha = NULL;
 		set_peer_defaults(peer);	/* Set peer defaults */
+		peer->type = 0;
 	}
 	if (!found && name)
-			ast_copy_string(peer->name, name, sizeof(peer->name));
+		ast_copy_string(peer->name, name, sizeof(peer->name));
 
 	/* If we have channel variables, remove them (reload) */
 	if (peer->chanvars) {
@@ -22584,13 +22598,10 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
 			}
 		} else if (!strcasecmp(v->name, "type")) {
 			if (!strcasecmp(v->value, "peer")) {
-				peer->onlymatchonip = TRUE;		/* For realtime support, add type=peer in the table */
-				peer->type = SIP_TYPE_PEER;
+				peer->type |= SIP_TYPE_PEER;
 			} else if (!strcasecmp(v->value, "user")) {
-				peer->onlymatchonip = FALSE;
-				peer->type = SIP_TYPE_USER;
+				peer->type |= SIP_TYPE_USER;
 			} else if (!strcasecmp(v->value, "friend")) {
-				peer->onlymatchonip = FALSE;
 				peer->type = SIP_TYPE_USER | SIP_TYPE_PEER;
 			}
 		} else if (!strcasecmp(v->name, "remotesecret")) {
@@ -23667,10 +23678,10 @@ static int reload_config(enum channelreloadreason reason)
 				hassip = ast_variable_retrieve(ucfg, cat, "hassip");
 				registersip = ast_variable_retrieve(ucfg, cat, "registersip");
 				if (ast_true(hassip) || (!hassip && genhassip)) {
-					peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0, FALSE);
+					peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
 					if (peer) {
 						ao2_t_link(peers, peer, "link peer into peer table");
-						if (peer->addr.sin_addr.s_addr) {
+						if ((peer->type & SIP_TYPE_PEER) && peer->addr.sin_addr.s_addr) {
 							ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
 						}
 						
@@ -23719,27 +23730,24 @@ static int reload_config(enum channelreloadreason reason)
 			ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
 			continue;
 		} else {
-			int is_peer = 0;
 			if (!strcasecmp(utype, "user")) {
-				is_peer = 1;
+				;
 			} else if (!strcasecmp(utype, "friend")) {
-				is_peer = 1;
-			} else if (!strcasecmp(utype, "peer"))
-				is_peer = 2;
-			else {
+				;
+			} else if (!strcasecmp(utype, "peer")) {
+				;
+			} else {
 				ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
 				continue;
 			}
-			if (is_peer) {
-				peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, is_peer == 2);
-				if (peer) {
-					ao2_t_link(peers, peer, "link peer into peers table");
-					if (peer->addr.sin_addr.s_addr) {
-						ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
-					}
-					unref_peer(peer, "unref the result of the build_peer call. Now, the links from the tables are the only ones left.");
-					peer_count++;
+			peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
+			if (peer) {
+				ao2_t_link(peers, peer, "link peer into peers table");
+				if ((peer->type & SIP_TYPE_PEER) && peer->addr.sin_addr.s_addr) {
+					ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
 				}
+				unref_peer(peer, "unref the result of the build_peer call. Now, the links from the tables are the only ones left.");
+				peer_count++;
 			}
 		}
 	}