[asterisk-commits] branch oej/peermatch r10860 - in /team/oej/peermatch: ./ channels/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Thu Feb 23 00:30:46 MST 2006


Author: oej
Date: Thu Feb 23 01:30:42 2006
New Revision: 10860

URL: http://svn.digium.com/view/asterisk?rev=10860&view=rev
Log:
- Removing the sip_user structure
- Still using a separate object list of sip_users, but using the same structure definition
- Defining a friend once, linking to both the peer and the user list
  Might turn into a problem with re-configuration of a peer, but want to test this
- This also improves the subscribe status, since we now have *one* call limit for
  a friend - both for incoming and outbound calls. Subscriptions will now work as expected,
  regardless if the call is incoming or outgoing


Added:
    team/oej/peermatch/README.peermatch   (with props)
Modified:
    team/oej/peermatch/channels/chan_sip.c

Added: team/oej/peermatch/README.peermatch
URL: http://svn.digium.com/view/asterisk/team/oej/peermatch/README.peermatch?rev=10860&view=auto
==============================================================================
--- team/oej/peermatch/README.peermatch (added)
+++ team/oej/peermatch/README.peermatch Thu Feb 23 01:30:42 2006
@@ -1,0 +1,14 @@
+This branch implements these changes:
+
+- Removes the sip_user code object. To simplify the code, we now always use the
+  same memory structure for all devices, regardless if they are a peer or a user
+
+- Matches incoming calls on 
+ 	- SIP_USER From: name 
+	- SIP_PEER From: name
+	- SIP_PEER IP/port
+
+- Creates only one in-memory object for a friend, thus improving the
+  subscribe functionality. A call limit now applies to both incoming and
+  outgoing calls, since we have only ONE memory object.
+

Propchange: team/oej/peermatch/README.peermatch
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/oej/peermatch/README.peermatch
------------------------------------------------------------------------------
    svn:keywords = Author Id Date Revision

Propchange: team/oej/peermatch/README.peermatch
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/oej/peermatch/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/peermatch/channels/chan_sip.c?rev=10860&r1=10859&r2=10860&view=diff
==============================================================================
--- team/oej/peermatch/channels/chan_sip.c (original)
+++ team/oej/peermatch/channels/chan_sip.c Thu Feb 23 01:30:42 2006
@@ -170,6 +170,12 @@
    submitting a patch. If these two lists do not match properly
    bad things will happen.
 */
+
+enum objecttype {
+	SIP_USER = (1 << 0),		/* USER places calls to the PBX */
+	SIP_PEER = (1 << 1),		/* Peer receives calls from PBX (and places calls) */
+	SIP_FRIEND = (1 << 2),		/* Friend receives calls from PBX (and places calls) */
+};
 
 enum subscriptiontype { 
 	NONE = 0,
@@ -739,39 +745,11 @@
 	char data[0];
 };	
 
-/*! \brief Structure for SIP user data. User's place calls to us */
-struct sip_user {
-	/* Users who can access various contexts */
-	ASTOBJ_COMPONENTS(struct sip_user);
-	char secret[80];		/*!< Password */
-	char md5secret[80];		/*!< Password in md5 */
-	char context[AST_MAX_CONTEXT];	/*!< Default context for incoming calls */
-	char subscribecontext[AST_MAX_CONTEXT];	/* Default context for subscriptions */
-	char cid_num[80];		/*!< Caller ID num */
-	char cid_name[80];		/*!< Caller ID name */
-	char accountcode[AST_MAX_ACCOUNT_CODE];	/* Account code */
-	char language[MAX_LANGUAGE];	/*!< Default language for this user */
-	char musicclass[MAX_MUSICCLASS];/*!< Music on Hold class */
-	char useragent[256];		/*!< User agent in SIP request */
-	struct ast_codec_pref prefs;	/*!< codec prefs */
-	ast_group_t callgroup;		/*!< Call group */
-	ast_group_t pickupgroup;	/*!< Pickup Group */
-	unsigned int flags;		/*!< SIP flags */	
-	unsigned int sipoptions;	/*!< Supported SIP options */
-	struct ast_flags flags_page2;	/*!< SIP_PAGE2 flags */
-	int amaflags;			/*!< AMA flags for billing */
-	int callingpres;		/*!< Calling id presentation */
-	int capability;			/*!< Codec capability */
-	int inUse;			/*!< Number of calls in use */
-	int call_limit;			/*!< Limit of concurrent calls */
-	struct ast_ha *ha;		/*!< ACL setting */
-	struct ast_variable *chanvars;	/*!< Variables to set for channel created by user */
-};
-
 /*! \brief Structure for SIP peer data, we place calls to peers if registered  or fixed IP address (host) */
 struct sip_peer {
 	ASTOBJ_COMPONENTS(struct sip_peer);	/*!< name, refcount, objflags,  object pointers */
 					/*!< peer->name is the unique name of this object */
+	enum objecttype type;		/*!< SIP_PEER or SIP_USER */
 	char secret[80];		/*!< Password */
 	char md5secret[80];		/*!< Password in MD5 */
 	struct sip_auth *auth;		/*!< Realm authentication list */
@@ -872,7 +850,7 @@
 
 /*! \brief  The user list: Users and friends */
 static struct ast_user_list {
-	ASTOBJ_CONTAINER_COMPONENTS(struct sip_user);
+	ASTOBJ_CONTAINER_COMPONENTS(struct sip_peer);
 } userl;
 
 /*! \brief  The peer list: Peers and Friends */
@@ -927,7 +905,7 @@
 static int build_reply_digest(struct sip_pvt *p, int method, char *digest, int digest_len);
 static int update_call_counter(struct sip_pvt *fup, int event);
 static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int realtime);
-static struct sip_user *build_user(const char *name, struct ast_variable *v, int realtime);
+static struct sip_peer *build_user(const char *name, struct ast_variable *v, int realtime);
 static int sip_do_reload(enum channelreloadreason reason);
 static int expire_register(void *data);
 static struct ast_channel *sip_request_call(const char *type, int format, void *data, int *cause);
@@ -1672,36 +1650,43 @@
 	}
 }
 
-/*! \brief Destroy peer object from memory */
-static void sip_destroy_peer(struct sip_peer *peer)
+/*! \brief Destroy device object from memory */
+static void sip_destroy_device(struct sip_peer *device)
 {
 	if (option_debug > 2)
-		ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name);
+		ast_log(LOG_DEBUG, "Destroying SIP %s %s\n", device->type == SIP_USER ? "user" : "peer", device->name);
 
 	/* Delete it, it needs to disappear */
-	if (peer->call)
-		sip_destroy(peer->call);
-	if (peer->chanvars) {
-		ast_variables_destroy(peer->chanvars);
-		peer->chanvars = NULL;
-	}
-	if (peer->expire > -1)
-		ast_sched_del(sched, peer->expire);
-	if (peer->pokeexpire > -1)
-		ast_sched_del(sched, peer->pokeexpire);
-	register_peer_exten(peer, 0);
-	ast_free_ha(peer->ha);
-	if (ast_test_flag((&peer->flags_page2), SIP_PAGE2_SELFDESTRUCT))
-		apeerobjs--;
-	else if (ast_test_flag(peer, SIP_REALTIME))
-		rpeerobjs--;
-	else
-		speerobjs--;
-	clear_realm_authentication(peer->auth);
-	peer->auth = (struct sip_auth *) NULL;
-	if (peer->dnsmgr)
-		ast_dnsmgr_release(peer->dnsmgr);
-	free(peer);
+	if (device->call)
+		sip_destroy(device->call);
+	if (device->chanvars) {
+		ast_variables_destroy(device->chanvars);
+		device->chanvars = NULL;
+	}
+	if (device->expire > -1)
+		ast_sched_del(sched, device->expire);
+	if (device->pokeexpire > -1)
+		ast_sched_del(sched, device->pokeexpire);
+	ast_free_ha(device->ha);
+	if ( device->type == SIP_PEER) {
+		register_peer_exten(device, FALSE);
+		clear_realm_authentication(device->auth);
+		if (ast_test_flag((&device->flags_page2), SIP_PAGE2_SELFDESTRUCT))
+			apeerobjs--;
+		else if (ast_test_flag(device, SIP_REALTIME))
+			rpeerobjs--;
+		else
+			speerobjs--;
+	} else {	/* SIP_USER */
+		if (ast_test_flag(device, SIP_REALTIME))
+			ruserobjs--;
+		else
+			suserobjs--;
+	}
+	device->auth = (struct sip_auth *) NULL;
+	if (device->dnsmgr)
+		ast_dnsmgr_release(device->dnsmgr);
+	free(device);
 }
 
 /*! \brief Update peer data in database (if used) */
@@ -1813,31 +1798,14 @@
 	return p;
 }
 
-/*! \brief Remove user object from in-memory storage */
-static void sip_destroy_user(struct sip_user *user)
-{
-	if (option_debug > 2)
-		ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name);
-	ast_free_ha(user->ha);
-	if (user->chanvars) {
-		ast_variables_destroy(user->chanvars);
-		user->chanvars = NULL;
-	}
-	if (ast_test_flag(user, SIP_REALTIME))
-		ruserobjs--;
-	else
-		suserobjs--;
-	free(user);
-}
-
 /*! \brief Load user from realtime storage
  * Loads user from "sipusers" category in realtime (extconfig.conf)
  * Users are matched on From: user name (the domain in skipped) */
-static struct sip_user *realtime_user(const char *username)
+static struct sip_peer *realtime_user(const char *username)
 {
 	struct ast_variable *var;
 	struct ast_variable *tmp;
-	struct sip_user *user = NULL;
+	struct sip_peer *user = NULL;
 
 	var = ast_load_realtime("sipusers", "name", username, NULL);
 
@@ -1852,8 +1820,7 @@
 		}
 	}
 
-	user = build_user(username, var, !ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS));
-	
+	user = build_user(username, var, !ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)); 
 	if (!user) {	/* No user found */
 		ast_variables_destroy(var);
 		return NULL;
@@ -1877,9 +1844,9 @@
  * Locates user by name (From: sip uri user name part) first
  * from in-memory list (static configuration) then from 
  * realtime storage (defined in extconfig.conf) */
-static struct sip_user *find_user(const char *name, int realtime)
-{
-	struct sip_user *u = NULL;
+static struct sip_peer *find_user(const char *name, int realtime)
+{
+	struct sip_peer *u = NULL;
 	u = ASTOBJ_CONTAINER_FIND(&userl,name);
 	if (!u && realtime) {
 		u = realtime_user(name);
@@ -1997,7 +1964,7 @@
 	if (p) {
 		found++;
 		if (create_addr_from_peer(dialog, p))
-			ASTOBJ_UNREF(p, sip_destroy_peer);
+			ASTOBJ_UNREF(p, sip_destroy_device);
 	}
 	if (!p) {
 		if (found)
@@ -2031,7 +1998,7 @@
 			return -1;
 		}
 	} else {
-		ASTOBJ_UNREF(p, sip_destroy_peer);
+		ASTOBJ_UNREF(p, sip_destroy_device);
 		return 0;
 	}
 }
@@ -2267,10 +2234,8 @@
 static int update_call_counter(struct sip_pvt *fup, int event)
 {
 	char name[256];
-	int *inuse, *call_limit;
 	int outgoing = ast_test_flag(fup, SIP_OUTGOING);
-	struct sip_user *u = NULL;
-	struct sip_peer *p = NULL;
+	struct sip_peer *device = NULL;
 
 	if (option_debug > 2)
 		ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming");
@@ -2283,63 +2248,49 @@
 
 	/* Check the list of users */
 	if (!outgoing)	/* Only check users for incoming calls */
-		u = find_user(name, 1);
-
-	if (u) {
-		inuse = &u->inUse;
-		call_limit = &u->call_limit;
-		p = NULL;
-	} else {
+		device = find_user(name, 1);
+
+	if (!device) {
 		/* Try to find peer */
-		if (!p)
-			p = find_peer(fup->peername, NULL, 1);
-		if (p) {
-			inuse = &p->inUse;
-			call_limit = &p->call_limit;
-			ast_copy_string(name, fup->peername, sizeof(name));
-		} else {
+		device = find_peer(fup->peername, NULL, 1);
+		if (!device) {
 			if (option_debug > 1)
-				ast_log(LOG_DEBUG, "%s is not a local user, no call limit\n", name);
+				ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name);
 			return 0;
 		}
+		ast_copy_string(name, fup->peername, sizeof(name));
 	}
 	switch(event) {
 		/* incoming and outgoing affects the inUse counter */
 		case DEC_CALL_LIMIT:
-			if ( *inuse > 0 ) {
+			if ( device->inUse > 0 ) {
 				if (ast_test_flag(fup, SIP_INC_COUNT))
-					(*inuse)--;
+					device->inUse--;
 			} else {
-				*inuse = 0;
+				device->inUse= 0;
 			}
 			if (option_debug > 1 || sipdebug) {
-				ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
+				ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", device->type == SIP_USER ? "user":"peer", name, device->call_limit);
 			}
 			break;
 		case INC_CALL_LIMIT:
-			if (*call_limit > 0 ) {
-				if (*inuse >= *call_limit) {
-					ast_log(LOG_ERROR, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit);
-					if (u)
-						ASTOBJ_UNREF(u, sip_destroy_user);
-					else
-						ASTOBJ_UNREF(p, sip_destroy_peer);
+			if (device->call_limit > 0 ) {
+				if (device->inUse >= device->call_limit) {
+					ast_log(LOG_ERROR, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", device->type == SIP_USER ? "user":"peer", name, device->call_limit);
+					ASTOBJ_UNREF(device, sip_destroy_device);
 					return -1; 
 				}
 			}
-			(*inuse)++;
+			device->inUse++;
 			ast_set_flag(fup, SIP_INC_COUNT);
 			if (option_debug > 1 || sipdebug) {
-				ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit);
+				ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", device->type == SIP_USER ? "user":"peer", name, device->inUse, device->call_limit);
 			}
 			break;
 		default:
 			ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event);
 	}
-	if (u)
-		ASTOBJ_UNREF(u, sip_destroy_user);
-	else
-		ASTOBJ_UNREF(p, sip_destroy_peer);
+	ASTOBJ_UNREF(device, sip_destroy_device);
 	return 0;
 }
 
@@ -5774,7 +5725,7 @@
 	ast_device_state_changed("SIP/%s", peer->name);
 	if (ast_test_flag((&peer->flags_page2), SIP_PAGE2_SELFDESTRUCT) || ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTAUTOCLEAR)) {
 		peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer);
-		ASTOBJ_UNREF(peer, sip_destroy_peer);
+		ASTOBJ_UNREF(peer, sip_destroy_device);
 	}
 
 	return 0;
@@ -6501,7 +6452,7 @@
 	peer = find_peer(name, NULL, 1);
 	if (!(peer && ast_apply_ha(peer->ha, sin))) {
 		if (peer)
-			ASTOBJ_UNREF(peer, sip_destroy_peer);
+			ASTOBJ_UNREF(peer, sip_destroy_device);
 	}
 	if (peer) {
 		if (!ast_test_flag((&peer->flags_page2), SIP_PAGE2_DYNAMIC)) {
@@ -6587,7 +6538,7 @@
 		}
 	}
 	if (peer)
-		ASTOBJ_UNREF(peer, sip_destroy_peer);
+		ASTOBJ_UNREF(peer, sip_destroy_device);
 
 	return res;
 }
@@ -7055,8 +7006,7 @@
 */
 static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, int reliable, struct sockaddr_in *sin, int ignore, char *mailbox, int mailboxlen)
 {
-	struct sip_user *user = NULL;
-	struct sip_peer *peer;
+	struct sip_peer *device = NULL;
 	char *of, from[256], *c;
 	char *rpid, rpid_num[50];
 	char iabuf[INET_ADDRSTRLEN];
@@ -7123,224 +7073,172 @@
 		return 0;
 
 	if (!mailbox)	/* If it's a mailbox SUBSCRIBE, don't check users */
-		user = find_user(of, 1);
-
-	/* Find user based on user name in the from header */
-	if (user && ast_apply_ha(user->ha, sin)) {
-		ast_copy_flags(p, user, SIP_FLAGS_TO_COPY);
+		device = find_user(of, 1);
+	if (device && !ast_apply_ha(device->ha, sin)) {
+		ast_verbose("Found user '%s', but fails host access\n", device->name);
+		ASTOBJ_UNREF(device,sip_destroy_device);
+		device = NULL;
+	}
+
+	if (!device) {
+		/* Secondly, match on peer name */
+		device = find_peer(of, NULL, 1);
+		if (device && !ast_apply_ha(device->ha, sin)) {
+			ASTOBJ_UNREF(device,sip_destroy_device);
+			device = NULL;
+		}
+
+		/* Thirdly match on IP/port */
+		if (!device) {
+			/* Look for peer based on the IP address we received data from */
+			/* If peer is registered from this IP address or have this as a default
+			   IP address, this call is from the peer 
+			*/
+			device = find_peer(NULL, &p->recv, 1);
+		}
+		if (device && !ast_apply_ha(device->ha, sin)) {
+			ASTOBJ_UNREF(device,sip_destroy_device);
+			device = NULL;
+		}
+	}
+
+	/* No user or peer found */
+	if (!device) {
+		if (debug)
+			ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port));
+
+		/* do we allow guests? */
+		if (!global_allowguest)
+			res = -1;  /* we don't want any guests, authentication will fail */
+#ifdef OSP_SUPPORT			
+		else if (global_allowguest == 2) {
+			ast_copy_flags(p, &global_flags, SIP_OSPAUTH);
+			res = check_auth(p, req, "", "", "", sipmethod, uri, reliable, ignore); 
+		}
+#endif
+		return res;
+	}
+
+	/* Ok, we have a device, let's check authentication if needed */
+	ast_copy_flags(p, device, SIP_FLAGS_TO_COPY);
+
+	/* Copy SIP extensions profile to peer */
+	if (p->sipoptions)
+		device->sipoptions = p->sipoptions;
+
+	/* copy channel vars */
+	for (v = device->chanvars ; v ; v = v->next) {
+		if ((tmpvar = ast_variable_new(v->name, v->value))) {
+			tmpvar->next = p->chanvars; 
+			p->chanvars = tmpvar;
+		}
+	}
+	p->prefs = device->prefs;
+	/* replace callerid if rpid found, and not restricted */
+	if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) {
+		char *tmp;
+		if (*calleridname)
+			ast_string_field_set(p, cid_name, calleridname);
+		tmp = ast_strdupa(rpid_num);
+		if (tmp) {
+			ast_shrink_phone_number(tmp);
+			ast_string_field_set(p, cid_num, tmp);
+		} else {
+			ast_string_field_set(p, cid_num, rpid_num);
+		}
+	}
+
+	if (p->rtp) {
+		if (option_debug)
+			ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
+		ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
+	}
+	if (p->vrtp) {
+		if (option_debug)
+			ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
+		ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
+	}
+	if (device->maxms && device->lastms)
+		p->timer_t1 = device->lastms;
+	if (ast_test_flag(device, SIP_INSECURE_INVITE)) {
+		/* Pretend there is no required authentication */
+		ast_string_field_free(p, peersecret);
+		ast_string_field_free(p, peermd5secret);
+	}
+
+	/* Now, check auth */
+	if (!(res = check_auth(p, req, device->name, device->secret, device->md5secret, sipmethod, uri, reliable, ignore))) {
+		/* We have positive authentication, let's configure this SIP session */
+		sip_cancel_destroy(p);
+		ast_copy_flags(p, device, SIP_FLAGS_TO_COPY);
+		/* Copy SIP extensions profile from INVITE */
+		if (p->sipoptions)
+			device->sipoptions = p->sipoptions;
+
+		/* If we have a call limit, set flag */
+		if (device->call_limit)
+			ast_set_flag(p, SIP_CALL_LIMIT);
+		if (!ast_strlen_zero(device->context))
+			ast_string_field_set(p, context, device->context);
+		if (!ast_strlen_zero(device->cid_num) && !ast_strlen_zero(p->cid_num)) {
+			char *tmp = ast_strdupa(device->cid_num);
+			if (tmp) {
+				ast_shrink_phone_number(tmp);
+				ast_string_field_set(p, cid_num, tmp);
+			} else {
+				ast_string_field_set(p, cid_num, device->cid_num);
+			}
+		}
+		if (!ast_strlen_zero(device->cid_name) && !ast_strlen_zero(p->cid_num))
+			ast_string_field_set(p, cid_name, device->cid_name);
+		if (device->type == SIP_USER) {
+			ast_string_field_set(p, username, device->name);
+		} else { /* SIP_PEER */
+			ast_string_field_set(p, peersecret, device->secret);
+			ast_string_field_set(p, peermd5secret, device->md5secret);
+			ast_string_field_set(p, fullcontact, device->fullcontact);
+			ast_string_field_set(p, peername, device->name);
+			ast_string_field_set(p, authname, device->name);
+			if (!ast_strlen_zero(device->username)) {
+				ast_string_field_set(p, username, device->username);
+				/* Use the default username for authentication on outbound calls */
+				ast_string_field_set(p, authname, device->username);
+			}
+		}
+		ast_string_field_set(p, subscribecontext, device->subscribecontext);
+		ast_string_field_set(p, accountcode, device->accountcode);
+		ast_string_field_set(p, language, device->language);
+		ast_string_field_set(p, musicclass, device->musicclass);
+		p->amaflags = device->amaflags;
+		p->callgroup = device->callgroup;
+		p->pickupgroup = device->pickupgroup;
+		p->callingpres = device->callingpres;
+		p->capability = device->capability;
+		p->jointcapability = device->capability;
+		p->prefs = device->prefs;
+		if (p->peercapability)
+			p->jointcapability &= p->peercapability;
+		if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
+			p->noncodeccapability |= AST_RTP_DTMF;
+		else
+			p->noncodeccapability &= ~AST_RTP_DTMF;
+
 		/* copy channel vars */
-		for (v = user->chanvars ; v ; v = v->next) {
+		for (v = device->chanvars ; v ; v = v->next) {
 			if ((tmpvar = ast_variable_new(v->name, v->value))) {
 				tmpvar->next = p->chanvars; 
 				p->chanvars = tmpvar;
 			}
 		}
-		p->prefs = user->prefs;
-		/* replace callerid if rpid found, and not restricted */
-		if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) {
-			char *tmp;
-			if (*calleridname)
-				ast_string_field_set(p, cid_name, calleridname);
-			tmp = ast_strdupa(rpid_num);
-			if (tmp) {
-				ast_shrink_phone_number(tmp);
-				ast_string_field_set(p, cid_num, tmp);
-			} else {
-				ast_string_field_set(p, cid_num, rpid_num);
-			}
-		}
-
-		if (p->rtp) {
-			if (option_debug)
-				ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
-			ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
-		}
-		if (p->vrtp) {
-			if (option_debug)
-				ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
-			ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
-		}
-		if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri, reliable, ignore))) {
-			sip_cancel_destroy(p);
-			ast_copy_flags(p, user, SIP_FLAGS_TO_COPY);
-			/* Copy SIP extensions profile from INVITE */
-			if (p->sipoptions)
-				user->sipoptions = p->sipoptions;
-
-			/* If we have a call limit, set flag */
-			if (user->call_limit)
-				ast_set_flag(p, SIP_CALL_LIMIT);
-			if (!ast_strlen_zero(user->context))
-				ast_string_field_set(p, context, user->context);
-			if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num)) {
-				char *tmp = ast_strdupa(user->cid_num);
-				if (tmp) {
-					ast_shrink_phone_number(tmp);
-					ast_string_field_set(p, cid_num, tmp);
-				} else {
-					ast_string_field_set(p, cid_num, user->cid_num);
-				}
-			}
-			if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num))
-				ast_string_field_set(p, cid_name, user->cid_name);
-			ast_string_field_set(p, username, user->name);
-			ast_string_field_set(p, peersecret, user->secret);
-			ast_string_field_set(p, peermd5secret, user->md5secret);
-			ast_string_field_set(p, subscribecontext, user->subscribecontext);
-			ast_string_field_set(p, accountcode, user->accountcode);
-			ast_string_field_set(p, language, user->language);
-			ast_string_field_set(p, musicclass, user->musicclass);
-			p->amaflags = user->amaflags;
-			p->callgroup = user->callgroup;
-			p->pickupgroup = user->pickupgroup;
-			p->callingpres = user->callingpres;
-			p->capability = user->capability;
-			p->jointcapability = user->capability;
-			if (p->peercapability)
-				p->jointcapability &= p->peercapability;
-			if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
-				p->noncodeccapability |= AST_RTP_DTMF;
-			else
-				p->noncodeccapability &= ~AST_RTP_DTMF;
-		}
-		if (user && debug)
-			ast_verbose("Found user '%s'\n", user->name);
-	} else {
-		if (user) {
-			if (!mailbox && debug)
-				ast_verbose("Found user '%s', but fails host access\n", user->name);
-			ASTOBJ_UNREF(user,sip_destroy_user);
-		}
-		user = NULL;
-	}
-
-	if (!user) {
-		/* Secondly, match on peer name */
-		peer = find_peer(of, NULL, 1);
-
-		/* Thirdly match on IP/port */
-		if (!peer) {
-			/* Look for peer based on the IP address we received data from */
-			/* If peer is registered from this IP address or have this as a default
-			   IP address, this call is from the peer 
-			*/
-			peer = find_peer(NULL, &p->recv, 1);
-		}
-
-		if (peer) {
-			if (debug)
-				ast_verbose("Found peer '%s'\n", peer->name);
-			/* Take the peer */
-			ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY);
-
-			/* Copy SIP extensions profile to peer */
-			if (p->sipoptions)
-				peer->sipoptions = p->sipoptions;
-
-			/* replace callerid if rpid found, and not restricted */
-			if (!ast_strlen_zero(rpid_num) && ast_test_flag(p, SIP_TRUSTRPID)) {
-				char *tmp = ast_strdupa(rpid_num);
-				if (*calleridname)
-					ast_string_field_set(p, cid_name, calleridname);
-				if (tmp) {
-					ast_shrink_phone_number(tmp);
-					ast_string_field_set(p, cid_num, tmp);
-				} else {
-					ast_string_field_set(p, cid_num, rpid_num);
-				}
-			}
-			if (p->rtp) {
-				ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
-				ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
-			}
-			if (p->vrtp) {
-				ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
-				ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
-			}
-			ast_string_field_set(p, peersecret, peer->secret);
-			ast_string_field_set(p, peermd5secret, peer->md5secret);
-			ast_string_field_set(p, subscribecontext, peer->subscribecontext);
-			p->callingpres = peer->callingpres;
-			if (peer->maxms && peer->lastms)
-				p->timer_t1 = peer->lastms;
-			if (ast_test_flag(peer, SIP_INSECURE_INVITE)) {
-				/* Pretend there is no required authentication */
-				ast_string_field_free(p, peersecret);
-				ast_string_field_free(p, peermd5secret);
-			}
-			if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri, reliable, ignore))) {
-				ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY);
-				/* If we have a call limit, set flag */
-				if (peer->call_limit)
-					ast_set_flag(p, SIP_CALL_LIMIT);
-				ast_string_field_set(p, peername, peer->name);
-				ast_string_field_set(p, authname, peer->name);
-
-				/* copy channel vars */
-				for (v = peer->chanvars ; v ; v = v->next) {
-					if ((tmpvar = ast_variable_new(v->name, v->value))) {
-						tmpvar->next = p->chanvars; 
-						p->chanvars = tmpvar;
-					}
-				}
-				if (mailbox)
-					snprintf(mailbox, mailboxlen, ",%s,", peer->mailbox);
-				if (!ast_strlen_zero(peer->username)) {
-					ast_string_field_set(p, username, peer->username);
-					/* Use the default username for authentication on outbound calls */
-					ast_string_field_set(p, authname, peer->username);
-				}
-				if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num)) {
-					char *tmp = ast_strdupa(peer->cid_num);
-					if (tmp) {
-						ast_shrink_phone_number(tmp);
-						ast_string_field_set(p, cid_num, tmp);
-					} else {
-						ast_string_field_set(p, cid_num, peer->cid_num);
-					}
-				}
-				if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) 
-					ast_string_field_set(p, cid_name, peer->cid_name);
-				ast_string_field_set(p, fullcontact, peer->fullcontact);
-				if (!ast_strlen_zero(peer->context))
-					ast_string_field_set(p, context, peer->context);
-				ast_string_field_set(p, peersecret, peer->secret);
-				ast_string_field_set(p, peermd5secret, peer->md5secret);
-				ast_string_field_set(p, language, peer->language);
-				ast_string_field_set(p, accountcode, peer->accountcode);
-				p->amaflags = peer->amaflags;
-				p->callgroup = peer->callgroup;
-				p->pickupgroup = peer->pickupgroup;
-				p->capability = peer->capability;
-				p->prefs = peer->prefs;
-				p->jointcapability = peer->capability;
-				if (p->peercapability)
-					p->jointcapability &= p->peercapability;
-				if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
-					p->noncodeccapability |= AST_RTP_DTMF;
-				else
-					p->noncodeccapability &= ~AST_RTP_DTMF;
-			}
-			ASTOBJ_UNREF(peer, sip_destroy_peer);
-		} else { 
-			if (debug)
-				ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port));
-
-			/* do we allow guests? */
-			if (!global_allowguest)
-				res = -1;  /* we don't want any guests, authentication will fail */
-#ifdef OSP_SUPPORT			
-			else if (global_allowguest == 2) {
-				ast_copy_flags(p, &global_flags, SIP_OSPAUTH);
-				res = check_auth(p, req, "", "", "", sipmethod, uri, reliable, ignore); 
-			}
-#endif
-		}
-
-	}
-
-	if (user)
-		ASTOBJ_UNREF(user, sip_destroy_user);
+		if (mailbox)
+			snprintf(mailbox, mailboxlen, ",%s,", device->mailbox);
+	}
+	if (device && debug)
+		ast_verbose("Found %s '%s'\n", device->type == SIP_USER ? "user" : "peer", device->name);
+
+	if (device)
+		ASTOBJ_UNREF(device, sip_destroy_device);
+
 	return res;
 }
 
@@ -7775,8 +7673,7 @@
 /*! \brief  sip_prune_realtime: Remove temporary realtime objects from memory (CLI) */
 static int sip_prune_realtime(int fd, int argc, char *argv[])
 {
-	struct sip_peer *peer;
-	struct sip_user *user;
+	struct sip_peer *device;
 	int pruneuser = FALSE;
 	int prunepeer = FALSE;
 	int multi = FALSE;
@@ -7862,7 +7759,7 @@
 				ASTOBJ_UNLOCK(iterator);
 			} while (0) );
 			if (pruned) {
-				ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
+				ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_device);
 				ast_cli(fd, "%d peers pruned.\n", pruned);
 			} else
 				ast_cli(fd, "No peers found to prune.\n");
@@ -7885,7 +7782,7 @@
 				ASTOBJ_UNLOCK(iterator);
 			} while (0) );
 			if (pruned) {
-				ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user);
+				ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_device);
 				ast_cli(fd, "%d users pruned.\n", pruned);
 			} else
 				ast_cli(fd, "No users found to prune.\n");
@@ -7893,24 +7790,24 @@
 		}
 	} else {
 		if (prunepeer) {
-			if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) {
-				if (!ast_test_flag((&peer->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
+			if ((device = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) {
+				if (!ast_test_flag((&device->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
 					ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
-					ASTOBJ_CONTAINER_LINK(&peerl, peer);
+					ASTOBJ_CONTAINER_LINK(&peerl, device);
 				} else
 					ast_cli(fd, "Peer '%s' pruned.\n", name);
-				ASTOBJ_UNREF(peer, sip_destroy_peer);
+				ASTOBJ_UNREF(device, sip_destroy_device);
 			} else
 				ast_cli(fd, "Peer '%s' not found.\n", name);
 		}
 		if (pruneuser) {
-			if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) {
-				if (!ast_test_flag((&user->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
+			if ((device = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) {
+				if (!ast_test_flag((&device->flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) {
 					ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name);
-					ASTOBJ_CONTAINER_LINK(&userl, user);
+					ASTOBJ_CONTAINER_LINK(&userl, device);
 				} else
 					ast_cli(fd, "User '%s' pruned.\n", name);
-				ASTOBJ_UNREF(user, sip_destroy_user);
+				ASTOBJ_UNREF(device, sip_destroy_device);
 			} else
 				ast_cli(fd, "User '%s' not found.\n", name);
 		}
@@ -8116,7 +8013,7 @@
  				ast_cli(fd, "                 %s = %s\n", v->name, v->value);
 		}
 		ast_cli(fd,"\n");
-		ASTOBJ_UNREF(peer,sip_destroy_peer);
+		ASTOBJ_UNREF(peer,sip_destroy_device);
 	} else  if (peer && type == 1) { /* manager listing */
 		char *actionid = astman_get_header(m,"ActionID");
 
@@ -8188,7 +8085,7 @@
 			}
 		}
 
-		ASTOBJ_UNREF(peer,sip_destroy_peer);
+		ASTOBJ_UNREF(peer,sip_destroy_device);
 
 	} else {
 		ast_cli(fd,"Peer %s not found.\n", argv[3]);
@@ -8202,7 +8099,7 @@
 static int sip_show_user(int fd, int argc, char *argv[])
 {
 	char cbuf[256];
-	struct sip_user *user;
+	struct sip_peer *user;
 	struct ast_codec_pref *pref;
 	struct ast_variable *v;
 	int x = 0, codec = 0, load_realtime;
@@ -8253,7 +8150,7 @@
  				ast_cli(fd, "                 %s = %s\n", v->name, v->value);
 		}
 		ast_cli(fd,"\n");
-		ASTOBJ_UNREF(user,sip_destroy_user);
+		ASTOBJ_UNREF(user,sip_destroy_device);
 	} else {
 		ast_cli(fd,"User %s not found.\n", argv[3]);
 		ast_cli(fd,"\n");
@@ -8864,7 +8761,7 @@
 			ast_set_flag(&global_flags_page2, SIP_PAGE2_DEBUG_CONSOLE);
 		} else
 			ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[3]);
-		ASTOBJ_UNREF(peer,sip_destroy_peer);
+		ASTOBJ_UNREF(peer,sip_destroy_device);
 	} else
 		ast_cli(fd, "No such peer '%s'\n", argv[3]);
 	return RESULT_SUCCESS;
@@ -9399,7 +9296,7 @@
 		}
 	}
 
-	ASTOBJ_UNREF(peer, sip_destroy_peer);
+	ASTOBJ_UNREF(peer, sip_destroy_device);
 
 	return 0;
 }
@@ -11415,7 +11312,7 @@
 			ASTOBJ_WRLOCK(peer);
 			sip_send_mwi_to_peer(peer);
 			ASTOBJ_UNLOCK(peer);
-			ASTOBJ_UNREF(peer,sip_destroy_peer);
+			ASTOBJ_UNREF(peer,sip_destroy_device);
 		} else {
 			/* Reset where we come from */
 			lastpeernum = -1;
@@ -11595,7 +11492,7 @@
 			/* there is no address, it's unavailable */
 			res = AST_DEVICE_UNAVAILABLE;
 		}
-		ASTOBJ_UNREF(p,sip_destroy_peer);
+		ASTOBJ_UNREF(p,sip_destroy_device);
 	} else {
 		hp = ast_gethostbyname(host, &ahp);
 		if (hp)
@@ -11945,10 +11842,44 @@
 	return a;
 }
 
+/*! \brief Set peer defaults before configuring specific configurations */
+static void set_peer_defaults(struct sip_peer *peer)
+{
+	peer->expire = -1;
+	peer->pokeexpire = -1;
+	ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY);
+	strcpy(peer->context, default_context);
+	strcpy(peer->subscribecontext, default_subscribecontext);
+	strcpy(peer->language, default_language);
+	strcpy(peer->musicclass, default_musicclass);
+	peer->addr.sin_port = htons(DEFAULT_SIP_PORT);
+	peer->addr.sin_family = AF_INET;
+	peer->defaddr.sin_family = AF_INET;
+	peer->capability = global_capability;
+	peer->rtptimeout = global_rtptimeout;
+	peer->rtpholdtimeout = global_rtpholdtimeout;
+	peer->rtpkeepalive = global_rtpkeepalive;
+	strcpy(peer->vmexten, default_vmexten);
+	ast_copy_flags(peer, &global_flags, SIP_USEREQPHONE);
+	peer->secret[0] = '\0';
+	peer->md5secret[0] = '\0';
+	peer->cid_num[0] = '\0';
+	peer->cid_name[0] = '\0';
+	peer->fromdomain[0] = '\0';
+	peer->fromuser[0] = '\0';
+	peer->regexten[0] = '\0';
+	peer->mailbox[0] = '\0';
+	peer->callgroup = 0;
+	peer->pickupgroup = 0;
+	peer->maxms = default_qualify;
+	peer->prefs = default_prefs;
+}
+
+
 /*! \brief Initiate a SIP user structure from configuration (configuration or realtime) */
-static struct sip_user *build_user(const char *name, struct ast_variable *v, int realtime)
-{
-	struct sip_user *user;
+static struct sip_peer *build_user(const char *name, struct ast_variable *v, int realtime)
+{
+	struct sip_peer *user;
 	int format;
 	struct ast_ha *oldha = NULL;
 	char *varname = NULL, *varval = NULL;
@@ -11956,22 +11887,16 @@
 	struct ast_flags userflags = {(0)};
 	struct ast_flags mask = {(0)};
 
-
 	if (!(user = ast_calloc(1, sizeof(*user))))
 		return NULL;
 		
 	suserobjs++;
 	ASTOBJ_INIT(user);
+	user-> type = SIP_USER;
 	ast_copy_string(user->name, name, sizeof(user->name));
 	oldha = user->ha;
 	user->ha = NULL;
-	ast_copy_flags(user, &global_flags, SIP_FLAGS_TO_COPY);
-	user->capability = global_capability;
-	user->prefs = default_prefs;
-	/* set default context */
-	strcpy(user->context, default_context);
-	strcpy(user->language, default_language);
-	strcpy(user->musicclass, default_musicclass);
+	set_peer_defaults(user);	/* Set default values for this object */
 	for (; v; v = v->next) {
 		if (handle_common_options(&userflags, &mask, v))
 			continue;
@@ -12035,39 +11960,6 @@
 	return user;
 }
 
-/*! \brief Set peer defaults before configuring specific configurations */
-static void set_peer_defaults(struct sip_peer *peer)
-{
-	peer->expire = -1;
-	peer->pokeexpire = -1;
-	ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY);
-	strcpy(peer->context, default_context);
-	strcpy(peer->subscribecontext, default_subscribecontext);
-	strcpy(peer->language, default_language);
-	strcpy(peer->musicclass, default_musicclass);
-	peer->addr.sin_port = htons(DEFAULT_SIP_PORT);
-	peer->addr.sin_family = AF_INET;
-	peer->defaddr.sin_family = AF_INET;
-	peer->capability = global_capability;
-	peer->rtptimeout = global_rtptimeout;
-	peer->rtpholdtimeout = global_rtpholdtimeout;
-	peer->rtpkeepalive = global_rtpkeepalive;
-	strcpy(peer->vmexten, default_vmexten);
-	ast_copy_flags(peer, &global_flags, SIP_USEREQPHONE);
-	peer->secret[0] = '\0';
-	peer->md5secret[0] = '\0';
-	peer->cid_num[0] = '\0';
-	peer->cid_name[0] = '\0';
-	peer->fromdomain[0] = '\0';
-	peer->fromuser[0] = '\0';
-	peer->regexten[0] = '\0';
-	peer->mailbox[0] = '\0';
-	peer->callgroup = 0;
-	peer->pickupgroup = 0;
-	peer->maxms = default_qualify;
-	peer->prefs = default_prefs;
-}
-
 /*! \brief Create temporary peer (used in autocreatepeer mode) */
 static struct sip_peer *temp_peer(const char *name)
 {
@@ -12128,6 +12020,8 @@
 		peer->expire = -1;
 		peer->pokeexpire = -1;
 	}
+	peer->type = SIP_PEER;
+
 	/* Note that our peer HAS had its reference count incrased */
 
 	peer->lastmsgssent = -1;
@@ -12202,7 +12096,7 @@
 				ast_clear_flag((&peer->flags_page2), SIP_PAGE2_DYNAMIC);
 				if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) {
 					if (ast_get_ip_or_srv(&peer->addr, v->value, "_sip._udp")) {
-						ASTOBJ_UNREF(peer, sip_destroy_peer);
+						ASTOBJ_UNREF(peer, sip_destroy_device);
 						return NULL;
 					}
 				}
@@ -12216,7 +12110,7 @@
 			}
 		} else if (!strcasecmp(v->name, "defaultip")) {
 			if (ast_get_ip(&peer->defaddr, v->value)) {
-				ASTOBJ_UNREF(peer, sip_destroy_peer);
+				ASTOBJ_UNREF(peer, sip_destroy_device);
 				return NULL;
 			}
 		} else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
@@ -12329,8 +12223,7 @@
 {
 	struct ast_config *cfg;
 	struct ast_variable *v;
-	struct sip_peer *peer;
-	struct sip_user *user;
+	struct sip_peer *device;
 	struct ast_hostent ahp;
 	char *cat;
 	struct hostent *hp;
@@ -12629,31 +12522,33 @@
 			ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
 			continue;
 		} else {
-			int is_user = 0, is_peer = 0;
+			enum objecttype type;
 			if (!strcasecmp(utype, "user"))
-				is_user = 1;
+				type = SIP_USER;
 			else if (!strcasecmp(utype, "friend"))
-				is_user = is_peer = 1;
+				type = SIP_FRIEND;
 			else if (!strcasecmp(utype, "peer"))
-				is_peer = 1;
+				type = SIP_PEER;
 			else {
 				ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
 				continue;
 			}
-			if (is_user) {
-				user = build_user(cat, ast_variable_browse(cfg, cat), 0);
-				if (user) {
-					ASTOBJ_CONTAINER_LINK(&userl,user);
-					ASTOBJ_UNREF(user, sip_destroy_user);
-					user_count++;
+			if (type == SIP_PEER || type == SIP_FRIEND) {
+				device = build_peer(cat, ast_variable_browse(cfg, cat), 0);
+				if (device) {
+					ASTOBJ_CONTAINER_LINK(&peerl,device);
+					ASTOBJ_UNREF(device, sip_destroy_device);
+					peer_count++;
 				}
 			}
-			if (is_peer) {
-				peer = build_peer(cat, ast_variable_browse(cfg, cat), 0);
-				if (peer) {
-					ASTOBJ_CONTAINER_LINK(&peerl,peer);
-					ASTOBJ_UNREF(peer, sip_destroy_peer);
-					peer_count++;
+			if (type == SIP_USER || type == SIP_FRIEND) {
+				/* We already have a device for a friend, link it in again */
+				if (type != SIP_FRIEND)
+					device = build_user(cat, ast_variable_browse(cfg, cat), 0);
+				if (device) {
+					ASTOBJ_CONTAINER_LINK(&userl,device);
+					ASTOBJ_UNREF(device, sip_destroy_device);
+					user_count++;
 				}
 			}
 		}
@@ -13044,7 +12939,7 @@
 	} while(0));
 
 	/* Then, actually destroy users and registry */
-	ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
+	ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_device);
 	if (option_debug > 3)
 		ast_log(LOG_DEBUG, "--------------- Done destroying user list\n");
 	ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
@@ -13054,7 +12949,7 @@
 	reload_config(reason);
 
 	/* Prune peers who still are supposed to be deleted */
-	ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
+	ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_device);
 	if (option_debug > 3)
 		ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n");
 
@@ -13255,9 +13150,9 @@

[... 12 lines stripped ...]


More information about the asterisk-commits mailing list