[svn-commits] oej: branch oej/codename-pineapple r46488 - in /team/oej/codename-pineapple/c...

svn-commits at lists.digium.com svn-commits at lists.digium.com
Mon Oct 30 12:52:21 MST 2006


Author: oej
Date: Mon Oct 30 13:52:21 2006
New Revision: 46488

URL: http://svn.digium.com/view/asterisk?rev=46488&view=rev
Log:
Merge the sipregister branch code, which is the basis for future type=service objects.

Modified:
    team/oej/codename-pineapple/channels/chan_sip3.c
    team/oej/codename-pineapple/channels/sip3/sip3.h
    team/oej/codename-pineapple/channels/sip3/sip3_config.c
    team/oej/codename-pineapple/channels/sip3/sip3_services.c
    team/oej/codename-pineapple/channels/sip3/sip3funcs.h

Modified: team/oej/codename-pineapple/channels/chan_sip3.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/chan_sip3.c?rev=46488&r1=46487&r2=46488&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/chan_sip3.c (original)
+++ team/oej/codename-pineapple/channels/chan_sip3.c Mon Oct 30 13:52:21 2006
@@ -843,6 +843,10 @@
 	}
 	if (device->dnsmgr)
 		ast_dnsmgr_release(device->dnsmgr);
+	if (device->registry) {
+		device->registry->peer = NULL;
+		ASTOBJ_UNREF(device->registry,sip_registry_destroy);
+	}
 	free(device);
 }
 
@@ -3913,6 +3917,7 @@
 	char tmpf[256] = "", *from;
 	struct sip_request *req;
 	char *colon;
+	int localdomain = TRUE;
 	
 	req = oreq;
 	if (!req)
@@ -3979,16 +3984,48 @@
 
 		domain_context[0] = '\0';
 		if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
+			localdomain = FALSE;
 			if (!global.allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
 				if (option_debug)
 					ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_method2txt(req->method), 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);
 	}
+
+	/* 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))) {
+			int found = FALSE;
+
+			if (option_debug)
+				ast_log(LOG_DEBUG, "Checking for %s in registry\n", uri);
+			/* Traverse the registry to find something */
+			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);
@@ -4243,8 +4280,11 @@
 	if (ast_strlen_zero(of))
 		return AUTH_SUCCESSFUL;
 
-	/* Find device in device list */
-	device = find_device(of, NULL, 1);
+	if (p->registry && p->registry->peer)	/* We already know this device from registry */
+		device = p->registry->peer;
+	else
+		/* Find device in device list */
+		device = find_device(of, NULL, 1);
 	if (device && !ast_apply_ha(device->ha, sin)) {
 		ASTOBJ_UNREF(device,sip_destroy_device);
 		device = NULL;

Modified: team/oej/codename-pineapple/channels/sip3/sip3.h
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3.h?rev=46488&r1=46487&r2=46488&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3.h (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3.h Mon Oct 30 13:52:21 2006
@@ -44,8 +44,6 @@
 #define IPTOS_MINCOST           0x02
 #endif
 
-/* #define VOCAL_DATA_HACK */
-
 #define DEFAULT_DEFAULT_EXPIRY  120
 #define DEFAULT_MIN_EXPIRY      60
 #define DEFAULT_MAX_EXPIRY      3600
@@ -54,6 +52,9 @@
 
 /* These strings needs to be localized */
 #define CALLERID_UNKNOWN	"Unknown"
+
+/*! \brief Magic marker for registration contacts */
+#define REG_MAGICMARKER		"ASTZVXW"
 
 /* guard limit must be larger than guard secs */
 /* guard min must be < 1000, and should be >= 250 */
@@ -608,6 +609,7 @@
 #define SIP_PAGE2_CALL_ONHOLD_ONEDIR	(1 << 23)	/*!< 23: One directional hold */
 #define SIP_PAGE2_CALL_ONHOLD_INACTIVE	(2 << 24)	/*!< 24: Inactive  */
 #define SIP_PAGE2_RFC2833_COMPENSATE    (1 << 26)
+#define SIP_PAGE2_SERVICE               (1 << 27)	/*!< Whether this device is a service or not */
 
 #define SIP_PAGE2_FLAGS_TO_COPY \
 	(SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_VIDEOSUPPORT | SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE)
@@ -895,6 +897,7 @@
 	struct ast_ha *ha;		/*!<  Access control list */
 	struct ast_variable *chanvars;	/*!<  Variables to set for channel created by user */
 	struct sip_dialog *mwipvt;		/*!<  Subscription for MWI */
+	struct sip_registry *registry;	/*!< If this is a service, which registration is connected to this device */
 	int lastmsg;
 	int autoframing;
 };
@@ -916,6 +919,7 @@
 		AST_STRING_FIELD(secret);	/*!< Password in clear text */	
 		AST_STRING_FIELD(md5secret);	/*!< Password in md5 */
 		AST_STRING_FIELD(contact);	/*!< Contact extension */
+		AST_STRING_FIELD(extension);	/*!< Extension for callback */
 		AST_STRING_FIELD(random);
 	);
 	int portno;			/*!<  Optional port override */
@@ -932,6 +936,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 have a known peer for this registry entry, use it for incoming calls */
 };
 
 /* Global settings only apply to the channel */

Modified: team/oej/codename-pineapple/channels/sip3/sip3_config.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_config.c?rev=46488&r1=46487&r2=46488&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_config.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_config.c Mon Oct 30 13:52:21 2006
@@ -305,7 +305,7 @@
 	struct ast_variable *tmpvar = NULL;
 	struct ast_flags peerflags[2] = {{(0)}};
 	struct ast_flags mask[2] = {{(0)}};
-
+	int register_lineno = 0;
 
 	if (!realtime)
 		/* Note we do NOT use find_peer here, to avoid realtime recursion */
@@ -517,6 +517,15 @@
 			peer->maxcallbitrate = atoi(v->value);
 			if (peer->maxcallbitrate < 0)
 				peer->maxcallbitrate = global.default_maxcallbitrate;
+		} else if (!strcasecmp(v->name, "register")) {
+			if (ast_true(v->value)) {
+				if (realtime)
+					ast_log(LOG_ERROR, "register=yes is not supported for realtime.\n");
+				else {
+					ast_set_flag(&peer->flags[1], SIP_PAGE2_SERVICE);
+					register_lineno = v->lineno;
+				}
+			}
 		} else if (!strcasecmp(v->name, "t38pt_udptl")) {
 			ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL);
 		} else if (!strcasecmp(v->name, "t38pt_rtp")) {
@@ -543,6 +552,14 @@
 		reg_source_db(peer);
 	ASTOBJ_UNMARK(peer);
 	ast_free_ha(oldha);
+	/* Start registration if needed */
+	if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SERVICE)) {
+		sip_register(NULL, register_lineno, peer);	/* XXX How do we handle this at reload?? */
+	} else if (peer->registry) {
+		/* We have a registry entry for a peer that no longer wished to be registered */
+		ASTOBJ_UNREF(peer->registry,sip_registry_destroy);
+		peer->registry = NULL;
+	}
 	return peer;
 }
 
@@ -925,7 +942,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_sip")) {
 			if (ast_str2tos(v->value, &global.tos_sip))

Modified: team/oej/codename-pineapple/channels/sip3/sip3_services.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_services.c?rev=46488&r1=46487&r2=46488&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_services.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_services.c Mon Oct 30 13:52:21 2006
@@ -159,48 +159,65 @@
 }
 
 /*! \brief Parse register=> line in sip.conf and add to registry */
-int sip_register(char *value, int lineno)
+int sip_register(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;
+	char username[256] = "";
+	char randomcontact[256];
+	char *hostname = NULL, *secret = NULL, *authuser = NULL;
+	char *porta = NULL;
+	char *contact = NULL;
+	char *extension = NULL;
+	int portnum = 0;
 	
-	if (!value)
-		return -1;
-	ast_copy_string(copy, value, sizeof(copy));
-	stringp=copy;
-	username = stringp;
-	hostname = strrchr(stringp, '@');
+	if (peer != NULL) {	/* Build registration string from peer info */
+		/* Need to copy port number as well */
+		if (ast_strlen_zero(peer->fromuser))
+			snprintf(username, sizeof(username), "%s:%s@%s/%s",
+				peer->username, peer->secret, peer->tohost, peer->regexten);
+		else
+			snprintf(username, sizeof(username), "%s:%s:%s@%s/%s",
+				peer->username, peer->secret, peer->fromuser, peer->tohost, peer->regexten);
+	} else if (value)
+		ast_copy_string(username, value, sizeof(username));
+	else
+		username[0] = '\0';
+
+	
+	/* ------ Parse registration string ----------- */
+	/* 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 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, "/");
+	/* split user[:secret[:authuser]] */
+	secret = strchr(username, ':');
+	if (secret) {
+		*secret++ = '\0';
+		authuser = strchr(secret, ':');
+		if (authuser)
+			*authuser++ = '\0';
+	}
+	/* split host[:port][/contact] */
+	contact = strchr(hostname, '/');
+	if (contact)
+		*contact++ = '\0';
 	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;
-	}
+	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;
+		}
+	}
+
+	/* Allocate data */
 	if (!(reg = ast_calloc(1, sizeof(*reg)))) {
 		ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
 		return -1;
@@ -212,9 +229,14 @@
 		return -1;
 	}
 
+	if (peer) {
+		reg->peer = peer;
+		peer->registry = reg;
+		// xxx?? ASTOBJ_REF(peer);		/* Add reference counter to peer */
+	}
+
 	sipcounters.registry_objects++;
 	ASTOBJ_INIT(reg);
-	ast_string_field_set(reg, contact, contact);
 	if (username)
 		ast_string_field_set(reg, username, username);
 	if (hostname)
@@ -223,6 +245,16 @@
 		ast_string_field_set(reg, authuser, authuser);
 	if (secret)
 		ast_string_field_set(reg, secret, secret);
+
+	if (extension)
+		ast_string_field_set(reg, extension, extension);
+	/* Build a random contact string for this registration entry */
+	generate_random_string(randomcontact, sizeof(randomcontact));
+	if (sipdebug)
+		ast_string_field_build(reg, contact, "%s-%s-%s-debug", REG_MAGICMARKER, randomcontact, extension);
+	else
+		ast_string_field_build(reg, contact, "%s-%s", REG_MAGICMARKER, randomcontact);
+
 	reg->expire = -1;
 	reg->expiry = expiry.default_expiry;
 	reg->timeout =  -1;
@@ -255,6 +287,8 @@
 		ast_sched_del(sched, reg->expire);
 	if (reg->timeout > -1)
 		ast_sched_del(sched, reg->timeout);
+	if (reg->peer)
+		reg->peer->registry = NULL;		/* XXX ASTOBJ_UNREF ??? */
 	ast_string_field_free_pools(reg);
 	sipcounters.registry_objects--;
 	free(reg);
@@ -415,6 +449,13 @@
 		if (!ast_strlen_zero(r->username))
 			ast_string_field_set(p, username, r->username);
 		/* Save extension in packet */
+	
+		/* If we have a peer relationship, fetch som more data from taht peer.
+		*/
+		if (r->peer) {
+			if (!ast_strlen_zero(r->peer->fromdomain))
+				ast_string_field_set(p, fromdomain, r->peer->fromdomain);
+		}
 		ast_string_field_set(p, exten, r->contact);
 
 		/*

Modified: team/oej/codename-pineapple/channels/sip3/sip3funcs.h
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3funcs.h?rev=46488&r1=46487&r2=46488&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3funcs.h (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3funcs.h Mon Oct 30 13:52:21 2006
@@ -217,7 +217,7 @@
 /* sip3_services.c - outbound registration for services from other servers/providers  */
 
 GNURK void sip_send_all_registers(void);
-GNURK int sip_register(char *value, int lineno);
+GNURK int sip_register(char *value, int lineno, struct sip_peer *peer);
 GNURK void sip_registry_destroy(struct sip_registry *reg);
 GNURK char *regstate2str(enum sipregistrystate regstate) attribute_const;
 GNURK int handle_response_register(struct sip_dialog *p, int resp, char *rest, struct sip_request *req, int seqno);



More information about the svn-commits mailing list