Index: asterisk/channels/chan_sip.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v
retrieving revision 1.771
diff -u -r1.771 chan_sip.c
--- asterisk/channels/chan_sip.c	24 Jun 2005 02:15:04 -0000	1.771
+++ asterisk/channels/chan_sip.c	25 Jun 2005 14:02:30 -0000
@@ -2924,6 +2924,7 @@
 static int sip_register(char *value, int lineno)
 {
 	struct sip_registry *reg;
+	struct sip_registry* found = NULL;
 	char copy[256] = "";
 	char *username=NULL, *hostname=NULL, *secret=NULL, *authuser=NULL;
 	char *porta=NULL;
@@ -2988,7 +2989,29 @@
 	reg->portno = porta ? atoi(porta) : 0;
 	reg->callid_valid = 0;
 	reg->ocseq = 101;
-	ASTOBJ_CONTAINER_LINK(&regl, reg);
+	
+	ASTOBJ_CONTAINER_TRAVERSE(&regl, !found, do {
+		ASTOBJ_WRLOCK(iterator);
+		if ((iterator->objflags & ASTOBJ_FLAG_MARKED) != 0) {
+			if ((strcmp(reg->username, iterator->username) == 0) &&
+			    (strcmp(reg->hostname, iterator->hostname) == 0) &&
+			    (strcmp(reg->authuser, iterator->authuser) == 0) &&
+			    (strcmp(reg->secret, iterator->secret) == 0) &&
+			    (strcmp(reg->contact, iterator->contact) == 0) &&
+			    (reg->portno == iterator->portno)) 
+			{
+				found = iterator;
+				iterator->refresh = default_expiry;
+				ASTOBJ_UNMARK(iterator);
+			}
+		}
+		ASTOBJ_UNLOCK(iterator);
+    	} while (0)
+	);
+
+	if (!found)
+		ASTOBJ_CONTAINER_LINK(&regl, reg);
+
 	ASTOBJ_UNREF(reg,sip_registry_destroy);
 	return 0;
 }
@@ -8122,6 +8145,9 @@
 "Usage: sip show objects\n" 
 "       Shows status of known SIP objects\n";
 
+static char sip_reregistration_usage[] =
+"Usage: sip reregistration\n"
+"       Send all known registrations\n";
 
 static char *func_header_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
 {
@@ -11389,12 +11415,30 @@
 		if (iterator->expire > -1)
 			ast_sched_del(sched, iterator->expire);
 		ms = (rand() >> 12) & 0x1fff;
+		iterator->regstate = REG_STATE_UNREGISTERED;
 		iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
 		ASTOBJ_UNLOCK(iterator);
 	} while (0)
 	);
 }
 
+/*--- sip_send_registers: Send registrations */
+static void sip_send_registers(void)
+{
+        int ms;
+
+        ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
+                ASTOBJ_WRLOCK(iterator);
+                if (iterator->expire == -1) {
+                	ms = (rand() >> 12) & 0x1fff;
+                	iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
+		}
+                ASTOBJ_UNLOCK(iterator);
+        } while (0)
+        );
+}
+
+
 /*--- sip_do_reload: Reload module */
 static int sip_do_reload(void)
 {
@@ -11402,14 +11446,15 @@
 	authl = NULL;
 
 	ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
-	ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
+	ASTOBJ_CONTAINER_MARKALL(&regl);
 	ASTOBJ_CONTAINER_MARKALL(&peerl);
 	reload_config();
 	/* Prune peers who still are supposed to be deleted */
+	ASTOBJ_CONTAINER_PRUNE_MARKED(&regl, sip_registry_destroy);
 	ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
 
 	sip_poke_all_peers();
-	sip_send_all_registers();
+	sip_send_registers();
 
 	return 0;
 }
@@ -11429,6 +11474,20 @@
 	return 0;
 }
 
+/*--- sip_reregistration: Force resend all known registraions ---*/
+static int sip_reregistration(int fd, int argc, char *argv[])
+{
+        ast_mutex_lock(&sip_reload_lock);
+        if (sip_reloading) {
+                ast_verbose("Previous SIP reload not yet done\n");
+        } else
+                sip_send_all_registers();
+        ast_mutex_unlock(&sip_reload_lock);
+
+        return 0;
+}
+
+
 /*--- reload: Part of Asterisk module interface ---*/
 int reload(void)
 {
@@ -11462,6 +11521,7 @@
 	{ { "sip", "no", "history", NULL }, sip_no_history, "Disable SIP history", no_history_usage },
 	{ { "sip", "no", "debug", NULL }, sip_no_debug, "Disable SIP debugging", no_debug_usage },
 	{ { "sip", "reload", NULL }, sip_reload, "Reload SIP configuration", sip_reload_usage },
+	{ { "sip", "reregistration", NULL }, sip_reregistration, "Send all known registrations", sip_reregistration_usage },
 };
 
 /*--- load_module: PBX load module - initialization ---*/
