[asterisk-commits] branch oej/test-this-branch r10688 - in /team/oej/test-this-branch: ./ channe...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue Feb 21 13:34:13 MST 2006


Author: oej
Date: Tue Feb 21 14:34:08 2006
New Revision: 10688

URL: http://svn.digium.com/view/asterisk?rev=10688&view=rev
Log:
- Integrating sipregister branch
- Removing ASTUM from this branch (not ready yet)

Removed:
    team/oej/test-this-branch/include/asterisk/astum.h
    team/oej/test-this-branch/res/res_astum.c
Modified:
    team/oej/test-this-branch/README.test-this-branch
    team/oej/test-this-branch/channels/chan_sip.c
    team/oej/test-this-branch/configs/sip.conf.sample

Modified: team/oej/test-this-branch/README.test-this-branch
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/README.test-this-branch?rev=10688&r1=10687&r2=10688&view=diff
==============================================================================
--- team/oej/test-this-branch/README.test-this-branch (original)
+++ team/oej/test-this-branch/README.test-this-branch Tue Feb 21 14:34:08 2006
@@ -1,3 +1,6 @@
+TESTING BRANCH - WELCOME!!
+--------------------------
+
 Asterisk is developed by the Asterisk.org user community. The
 development team does not only consist of coders, but also
 testers and people that write documentation and check for 
@@ -7,16 +10,18 @@
 bug tracker that needs your testing.  Please test and report
 your results in the bug tracker reports for each patch.
 
+What's in this branch?
+----------------------
 This branch includes the following branches
 - sipdiversion: Additional support for the Diversion: header
 - jitterbuffer: Jitterbuffer for RTP in chan_sip (#3854)
 - videosupport: Improved support for video (#5427)
 - peermatch: New peer matching algorithm (no bug report yet)
 - rtcp: Improved support for RTCP (#2863)
-- astum: The Asterisk User manager (no bug report yet)
+- dialplan-ami-events: Report dialplan reload in manager (#5741)
+- sipregister: A new registration architecture (#5834)
 
 Coming here soon:
-- sipregister: A new registration architecture (#5834)
 - iptos: New IPtos support, separate audio and signalling (#6355)
 - metermaids: Subscription support for parking lots (#5779)
 - multiparking: Multiple parking lots (#6113)
@@ -24,7 +29,6 @@
 And the following stand-alone patches
 - New CLI commands for global variables (#6506)
 - Additional options for the CHANNEL dialplan function
-- Report dialplan reload in manager (#5741)
 
 All of these exist in the bug tracker
 

Modified: team/oej/test-this-branch/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/channels/chan_sip.c?rev=10688&r1=10687&r2=10688&view=diff
==============================================================================
--- team/oej/test-this-branch/channels/chan_sip.c (original)
+++ team/oej/test-this-branch/channels/chan_sip.c Tue Feb 21 14:34:08 2006
@@ -134,6 +134,8 @@
 static int max_expiry = DEFAULT_MAX_EXPIRY;	/*!< Maximum accepted registration time */
 static int default_expiry = DEFAULT_DEFAULT_EXPIRY;
 static int expiry = DEFAULT_EXPIRY;
+
+#define REG_MAGICMARKER		"ASTZVXW"	/*!< Magic marker for outbound registrations */
 
 #ifndef MAX
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
@@ -613,6 +615,7 @@
 #define SIP_PAGE2_DYNAMIC		(1 << 7)	/*!< Dynamic Peers register with Asterisk */
 #define SIP_PAGE2_SELFDESTRUCT		(1 << 8)	/*!< Automatic peers need to destruct themselves */
 #define SIP_PAGE2_VIDEOSUPPORT		(1 << 10)
+#define SIP_PAGE2_PEER_REGISTER		(1 << 11)
 
 #define SIP_PAGE2_FLAGS_TO_COPY \
 	(SIP_PAGE2_VIDEOSUPPORT)
@@ -732,7 +735,8 @@
 	struct ast_dsp *vad;			/*!< Voice Activation Detection dsp */
 	
 	struct sip_peer *peerpoke;		/*!< If this dialog is to poke a peer, which one */
-	struct sip_registry *registry;		/*!< If this is a REGISTER dialog, to which registry */
+	struct sip_registry *registry;		/*!< If this is a REGISTER dialog, to which registry
+							If this is an INVITE, to which registry */
 	struct ast_rtp *rtp;			/*!< RTP Session */
 	struct ast_rtp *vrtp;			/*!< Video RTP session */
 	struct sip_pkt *packets;		/*!< Packets scheduled for re-transmission */
@@ -847,6 +851,7 @@
 	struct sockaddr_in defaddr;	/*!<  Default IP address, used until registration */
 	struct ast_ha *ha;		/*!<  Access control list */
 	struct ast_variable *chanvars;	/*!<  Variables to set for channel created by user */
+	struct sip_registry *registry;	/*!< If this peer registers with outside service */
 	int lastmsg;
 };
 
@@ -877,7 +882,8 @@
 		AST_STRING_FIELD(hostname);	/*!< Domain or host we register to */
 		AST_STRING_FIELD(secret);	/*!< Password in clear text */	
 		AST_STRING_FIELD(md5secret);	/*!< Password in md5 */
-		AST_STRING_FIELD(contact);	/*!< Contact extension */
+		AST_STRING_FIELD(contact);	/*!< Contact used for this registry entry */
+		AST_STRING_FIELD(extension);	/*!< Extension to place incoming calls to */
 		AST_STRING_FIELD(random);
 	);
 	int portno;			/*!<  Optional port override */
@@ -892,6 +898,7 @@
 	struct sockaddr_in us;		/*!< Who the server thinks we are */
 	int noncecount;			/*!< Nonce-count */
 	char lastmsg[256];		/*!< Last Message sent/received */
+	struct sip_peer *peer;		/*!< If we ahve a known peer for this registry entry, use it for incoming calls */
 };
 
 /* --- Linked lists of various objects --------*/
@@ -992,6 +999,7 @@
 static int sip_poke_peer(struct sip_peer *peer);
 static int __sip_do_register(struct sip_registry *r);
 static int restart_monitor(void);
+static char *generate_random_string(char *buf, size_t size);
 static void set_peer_defaults(struct sip_peer *peer);
 static struct sip_peer *temp_peer(const char *name);
 
@@ -1731,6 +1739,11 @@
 	peer->auth = (struct sip_auth *) NULL;
 	if (peer->dnsmgr)
 		ast_dnsmgr_release(peer->dnsmgr);
+	if (peer->registry) {
+		/* OEJ - NEeds to do a proper OBJECT dereference and delinking here */
+		//
+		//sip_registry_destroy(peer->registry);
+	}
 	free(peer);
 }
 
@@ -2183,6 +2196,8 @@
 		ast_sched_del(sched, reg->expire);
 	if (reg->timeout > -1)
 		ast_sched_del(sched, reg->timeout);
+	if (reg->peer)
+		reg->peer->registry = NULL;
 	ast_string_field_free_all(reg);
 	regobjs--;
 	free(reg);
@@ -3392,53 +3407,65 @@
 }
 
 /*! \brief Parse register=> line in sip.conf and add to registry */
-static int sip_register(char *value, int lineno)
+static int sip_register(const char *value, int lineno, struct sip_peer *peer)
 {
 	struct sip_registry *reg;
-	char copy[256];
-	char *username=NULL, *hostname=NULL, *secret=NULL, *authuser=NULL;
-	char *porta=NULL;
-	char *contact=NULL;
-	char *stringp=NULL;
-	
-	if (!value)
+	char username[256];
+	char randomcontact[33];
+	char *hostname = NULL, *secret = NULL, *authuser = NULL;
+	char *porta = NULL;
+	char *extension = NULL;
+	int portnum = 0;
+
+	if (peer) {	/* build string from peer info */
+		/* XXX authuser ? port ? contact is regexten... */
+		snprintf(username, sizeof(username), "%s:%s@%s/%s",
+			peer->username, peer->secret, peer->tohost, peer->regexten);
+	} else if (value)
+		ast_copy_string(username, value, sizeof(username));
+	else
+		username[0] = '\0';
+	/* First split around the last '@' then parse the two components. */
+	hostname = strrchr(username, '@'); /* allow @ in the first part */
+	if (hostname)
+		*hostname++ = '\0';
+	if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) {
+		ast_log(LOG_WARNING, "Format for registration is %s at line %d\n",
+			"user[:secret[:authuser]]@host[:port][/extension]",
+			lineno);
 		return -1;
-	ast_copy_string(copy, value, sizeof(copy));
-	stringp=copy;
-	username = stringp;
-	hostname = strrchr(stringp, '@');
-	if (hostname) {
-		*hostname = '\0';
-		hostname++;
-	}
-	if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) {
-		ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno);
-		return -1;
-	}
-	stringp = username;
-	username = strsep(&stringp, ":");
-	if (username) {
-		secret = strsep(&stringp, ":");
-		if (secret) 
-			authuser = strsep(&stringp, ":");
-	}
-	stringp = hostname;
-	hostname = strsep(&stringp, "/");
-	if (hostname) 
-		contact = strsep(&stringp, "/");
-	if (ast_strlen_zero(contact))
-		contact = "s";
-	stringp=hostname;
-	hostname = strsep(&stringp, ":");
-	porta = strsep(&stringp, ":");
-	
-	if (porta && !atoi(porta)) {
-		ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
-		return -1;
+	}
+	/* split user[:secret[:authuser]] */
+	secret = strchr(username, ':');
+	if (secret) {
+		*secret++ = '\0';
+		authuser = strchr(secret, ':');
+		if (authuser)
+			*authuser++ = '\0';
+	}
+	/* split host[:port][/contact] */
+	extension = strchr(hostname, '/');
+	if (extension)
+		*extension++ = '\0';
+	if (ast_strlen_zero(extension))
+		extension = "s";
+	porta = strchr(hostname, ':');
+	if (porta) {
+		*porta++ = '\0';
+		portnum = atoi(porta);
+		if (portnum == 0) {
+			ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n",
+				porta, lineno);
+			return -1;
+		}
 	}
 	if (!(reg = ast_calloc(1, sizeof(*reg)))) {
 		ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
 		return -1;
+	}
+	if (peer) {
+		reg->peer = (struct sip_peer * ) peer;	/* Save SIP peer binding for incoming calls */
+		peer->registry = reg;
 	}
 
 	if (ast_string_field_init(reg, 256)) {
@@ -3449,7 +3476,6 @@
 
 	regobjs++;
 	ASTOBJ_INIT(reg);
-	ast_string_field_set(reg, contact, contact);
 	if (username)
 		ast_string_field_set(reg, username, username);
 	if (hostname)
@@ -3458,13 +3484,20 @@
 		ast_string_field_set(reg, authuser, authuser);
 	if (secret)
 		ast_string_field_set(reg, secret, secret);
+
+	ast_string_field_set(reg, extension, extension);
+
+	/* Build a random contact string for this registration entry */
+	generate_random_string(randomcontact, sizeof(randomcontact));
+	ast_string_field_build(reg, contact, "%s-%s", REG_MAGICMARKER, randomcontact);
+	
 	reg->expire = -1;
 	reg->timeout =  -1;
 	reg->refresh = default_expiry;
-	reg->portno = porta ? atoi(porta) : 0;
+	reg->portno = portnum;
 	reg->callid_valid = FALSE;
 	reg->ocseq = 101;
-	ASTOBJ_CONTAINER_LINK(&regl, reg);	/* Add the new registry entry to the list */
+	ASTOBJ_CONTAINER_LINK(&regl, reg);		/* Add the new registry entry to the list */
 	ASTOBJ_UNREF(reg,sip_registry_destroy);
 	return 0;
 }
@@ -5499,7 +5532,7 @@
 	} else {
 		r->regstate = REG_STATE_UNREGISTERED;
 		r->timeout = -1;
-		res=transmit_register(r, SIP_REGISTER, NULL, NULL);
+		res = transmit_register(r, SIP_REGISTER, NULL, NULL);
 	}
 	manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate));
 	ASTOBJ_UNREF(r, sip_registry_destroy);
@@ -5538,7 +5571,7 @@
 			r->callid_valid = TRUE;
 		}
 		/* Allocate SIP packet for registration */
-		p=sip_alloc( r->callid, NULL, 0, SIP_REGISTER);
+		p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER);
 		if (!p) {
 			ast_log(LOG_WARNING, "Unable to allocate registration call\n");
 			return 0;
@@ -5586,7 +5619,8 @@
 		}
 		if (!ast_strlen_zero(r->username))
 			ast_string_field_set(p, username, r->username);
-		/* Save extension in packet */
+
+		/* Save contact in packet */
 		ast_string_field_set(p, exten, r->contact);
 
 		/*
@@ -6746,12 +6780,13 @@
 	return 0;
 }
 
-/*! \brief Find out who the call is for */
+/*! \brief Find out what extension the call is for */
 static int get_destination(struct sip_pvt *p, struct sip_request *oreq)
 {
 	char tmp[256] = "", *uri, *a;
 	char tmpf[256], *from;
 	struct sip_request *req;
+	int localdomain = TRUE;
 	
 	req = oreq;
 	if (!req)
@@ -6803,12 +6838,13 @@
 
 		domain_context[0] = '\0';
 		if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
+			localdomain = FALSE;
 			if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
 				ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
 				return -2;
 			}
 		}
-		/* If we have a context defined, overwrite the original context */
+		/* If we have a domain context defined, overwrite the original context */
 		if (!ast_strlen_zero(domain_context))
 			ast_string_field_set(p, context, domain_context);
 	}
@@ -6822,6 +6858,36 @@
 		} else
 			ast_string_field_set(p, fromdomain, from);
 	}
+	
+	/* If the URI starts with our magic marker and has a corresponding
+		entry in the registry, then replace the URI with the extension
+		we want to use */
+	/* We don't have to check this at all if we have no registry entries... */
+	if (localdomain && req->method == SIP_INVITE) {
+		if (option_debug)
+			ast_log(LOG_DEBUG, "Checking %s for magic registry marker \n", uri);
+		/* Check if the incoming URI is a registry entry */
+		/* Need a function in ASTOBJ to check if there are objects
+			in the container at all here to avoid this check 
+			when we have no registry entries */
+		if (!strncmp(uri, REG_MAGICMARKER, strlen(REG_MAGICMARKER))) {
+			if (option_debug)
+				ast_log(LOG_DEBUG, "Checking for %s in registry\n", uri);
+			/* Traverse the registry to find something */
+			int found = FALSE;
+			ASTOBJ_CONTAINER_TRAVERSE(&regl, !found, do {
+				ASTOBJ_RDLOCK(iterator);
+				if (!strcmp(uri, iterator->contact)) {
+					found = TRUE;
+					/* Use the extension of this registry item for the incoming call */
+					uri = (char *) iterator->extension;
+					p->registry = iterator;
+				}
+				ASTOBJ_UNLOCK(iterator);
+			} while(0));
+		}
+	}
+
 	if (sip_debug_test_pvt(p))
 		ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
 
@@ -7362,6 +7428,7 @@
 		if (peer) {
 			if (debug)
 				ast_verbose("Found peer '%s'\n", peer->name);
+
 			/* Take the peer */
 			ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY);
 
@@ -10556,6 +10623,7 @@
 		}
 	} else if (debug)
 		ast_verbose("Ignoring this INVITE request\n");
+
 	if (!p->lastinvite && !ignore && !p->owner) {
 
 		/* Handle authentication if this is our first invite */
@@ -12259,7 +12327,7 @@
 	struct ast_variable *tmpvar = NULL;
 	struct ast_flags peerflags = {(0)};
 	struct ast_flags mask = {(0)};
-
+	int register_lineno = 0;
 
 	if (!realtime)
 		/* Note we do NOT use find_peer here, to avoid realtime recursion */
@@ -12300,6 +12368,7 @@
 	if (peer->chanvars) {
 		ast_variables_destroy(peer->chanvars);
 		peer->chanvars = NULL;
+		/* XXX should unregister ? */
 	}
 	for (; v; v = v->next) {
 		if (handle_common_options(&peerflags, &mask, v))
@@ -12460,6 +12529,11 @@
 					peer->chanvars = tmpvar;
 				}
 			}
+		} else if (!strcasecmp(v->name, "register")) {
+			if (ast_true(v->value)) {
+				ast_set_flag((&peer->flags_page2), SIP_PAGE2_PEER_REGISTER);
+				register_lineno = v->lineno;
+			}
 		} else if (!strcasecmp(v->name, "qualify")) {
 			if (!strcasecmp(v->value, "no")) {
 				peer->maxms = 0;
@@ -12491,6 +12565,10 @@
 		reg_source_db(peer);
 	ASTOBJ_UNMARK(peer);
 	ast_free_ha(oldha);
+	/* Start registration if needed */
+	if (ast_test_flag((&peer->flags_page2), SIP_PAGE2_PEER_REGISTER))
+		sip_register(NULL, register_lineno, peer);
+
 	return peer;
 }
 
@@ -12759,7 +12837,7 @@
 			else
 				add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : "");
 		} else if (!strcasecmp(v->name, "register")) {
-			if (sip_register(v->value, v->lineno) == 0)
+			if (sip_register(v->value, v->lineno, NULL) == 0)
 				registry_count++;
 		} else if (!strcasecmp(v->name, "tos")) {
 			if (ast_str2tos(v->value, &global_tos))

Modified: team/oej/test-this-branch/configs/sip.conf.sample
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/configs/sip.conf.sample?rev=10688&r1=10687&r2=10688&view=diff
==============================================================================
--- team/oej/test-this-branch/configs/sip.conf.sample (original)
+++ team/oej/test-this-branch/configs/sip.conf.sample Tue Feb 21 14:34:08 2006
@@ -358,11 +358,11 @@
 
 ;[sip_proxy]
 ; For incoming calls only. Example: FWD (Free World Dialup)
-; We match on IP address of the proxy for incoming calls 
-; since we can not match on username (caller id)
 ;type=peer
 ;context=from-fwd
 ;host=fwd.pulver.com
+;regexten=300			; Extension to place incoming calls to
+;register=yes			; Enable registration for this service
 
 ;[sip_proxy-out]
 ;type=peer          		; we only want to call out, not be called



More information about the asterisk-commits mailing list