Index: asterisk/channels/chan_sip.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v
retrieving revision 1.700
diff -u -3 -r1.700 chan_sip.c
--- asterisk/channels/chan_sip.c	30 Mar 2005 16:28:28 -0000	1.700
+++ asterisk/channels/chan_sip.c	2 Apr 2005 06:32:47 -0000
@@ -201,6 +201,7 @@
 static int rpeerobjs = 0;
 static int apeerobjs = 0;
 static int regobjs = 0;
+AST_MUTEX_DEFINE_STATIC(regobjs_lock);
 
 static int global_allowguest = 1;    /* allow unauthenticated users/peers to connect? */
 
@@ -623,7 +624,7 @@
 static struct ast_register_list {
 	ASTOBJ_CONTAINER_COMPONENTS(struct sip_registry);
 	int recheck;
-} regl;
+} regl, tempregl;
 
 
 static int __sip_do_register(struct sip_registry *r);
@@ -1652,7 +1653,9 @@
 		ast_sched_del(sched, reg->expire);
 	if (reg->timeout > -1)
 		ast_sched_del(sched, reg->timeout);
+	ast_mutex_lock(&regobjs_lock);
 	regobjs--;
+	ast_mutex_unlock(&regobjs_lock);
 	free(reg);
 	
 }
@@ -2673,7 +2676,9 @@
 	reg = malloc(sizeof(struct sip_registry));
 	if (reg) {
 		memset(reg, 0, sizeof(struct sip_registry));
+		ast_mutex_lock(&regobjs_lock);
 		regobjs++;
+		ast_mutex_unlock(&regobjs_lock);
 		ASTOBJ_INIT(reg);
 		strncpy(reg->contact, contact, sizeof(reg->contact) - 1);
 		if (username)
@@ -2690,7 +2695,7 @@
 		reg->portno = porta ? atoi(porta) : 0;
 		reg->callid_valid = 0;
 		reg->ocseq = 101;
-		ASTOBJ_CONTAINER_LINK(&regl, reg);
+		ASTOBJ_CONTAINER_LINK(&tempregl, reg);
 		ASTOBJ_UNREF(reg,sip_registry_destroy);
 	} else {
 		ast_log(LOG_ERROR, "Out of memory\n");
@@ -10729,7 +10734,6 @@
 {
 	/* Delete all users */
 	ASTOBJ_CONTAINER_DESTROYALL(&userl,sip_destroy_user);
-	ASTOBJ_CONTAINER_DESTROYALL(&regl,sip_registry_destroy);
 	ASTOBJ_CONTAINER_MARKALL(&peerl);
 }
 
@@ -10754,15 +10758,67 @@
 /*--- sip_send_all_registers: Send all known registrations */
 static void sip_send_all_registers(void)
 {
+	struct sip_registry* item;
 	int ms = (rand() >> 12) & 0x1fff;
-	ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
+	
+	ASTOBJ_CONTAINER_MARKALL(&regl);	
+	ASTOBJ_CONTAINER_TRAVERSE(&tempregl, 1, do {
+		struct sip_registry* found = NULL;
 		ASTOBJ_WRLOCK(iterator);
-		if (iterator->expire > -1)
-			ast_sched_del(sched, iterator->expire);
-		iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
+		item = iterator;
+
+		ASTOBJ_CONTAINER_TRAVERSE(&regl, !found, do {
+			ASTOBJ_WRLOCK(iterator);
+			if ((strcmp(item->username, iterator->username) == 0) &&
+			    (strcmp(item->hostname, iterator->hostname) == 0) &&
+			    (strcmp(item->authuser, iterator->authuser) == 0) &&
+			    (strcmp(item->secret, iterator->secret) == 0) &&
+			    (strcmp(item->contact, iterator->contact) == 0) &&
+			    (item->portno == iterator->portno))
+			{
+				found = iterator;
+
+				/* Update expiry value */
+				iterator->refresh = default_expiry;
+
+				/* Unmark registration, item is not modified */
+				ASTOBJ_UNMARK(iterator);
+			}
+			ASTOBJ_UNLOCK(iterator);
+    		} while (0)
+		);
+
+		if (!found)
+		{
+			/* User agent added in sip.conf */
+			item = malloc(sizeof(struct sip_registry));
+			if (item) {
+				memset(item, 0, sizeof(struct sip_registry));
+				ast_mutex_lock(&regobjs_lock);
+				regobjs++;
+				ast_mutex_unlock(&regobjs_lock);
+				ASTOBJ_INIT(item);
+				strncpy(item->contact, iterator->contact, sizeof(item->contact) - 1);
+				strncpy(item->username, iterator->username, sizeof(item->username) - 1);
+				strncpy(item->hostname, iterator->hostname, sizeof(item->hostname) - 1);
+				strncpy(item->authuser, iterator->authuser, sizeof(item->authuser) - 1);
+				strncpy(item->secret, iterator->secret, sizeof(item->secret) - 1);
+				item->expire = ast_sched_add(sched, ms, sip_reregister, item);
+		    		item->timeout =  -1;
+		    		item->refresh = default_expiry;
+		    		item->portno = iterator->portno;
+		    		item->callid_valid = 0;
+		    		item->ocseq = 101;
+				ASTOBJ_CONTAINER_LINK(&regl, item);
+				ASTOBJ_UNREF(item, sip_registry_destroy);
+			}		
+		}
 		ASTOBJ_UNLOCK(iterator);
 	} while (0)
 	);
+	
+	ASTOBJ_CONTAINER_DESTROYALL(&tempregl, sip_registry_destroy);
+	ASTOBJ_CONTAINER_PRUNE_MARKED(&regl, sip_registry_destroy);
 }
 
 /*--- sip_do_reload: Reload module */
@@ -10811,6 +10867,7 @@
 	ASTOBJ_CONTAINER_INIT(&userl);
 	ASTOBJ_CONTAINER_INIT(&peerl);
 	ASTOBJ_CONTAINER_INIT(&regl);
+	ASTOBJ_CONTAINER_INIT(&tempregl);
 	sched = sched_context_create();
 	if (!sched) {
 		ast_log(LOG_WARNING, "Unable to create schedule context\n");
@@ -10949,6 +11006,7 @@
 	ASTOBJ_CONTAINER_DESTROY(&userl);
 	ASTOBJ_CONTAINER_DESTROY(&peerl);
 	ASTOBJ_CONTAINER_DESTROY(&regl);
+	ASTOBJ_CONTAINER_DESTROY(&tempregl);
 
 	clear_realm_authentication(authl);
 		
