[asterisk-commits] oej: branch oej/codename-pineapple r53951 - in /team/oej/codename-pineapple: ...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Sun Feb 11 13:32:57 MST 2007


Author: oej
Date: Sun Feb 11 14:32:55 2007
New Revision: 53951

URL: http://svn.digium.com/view/asterisk?view=rev&rev=53951
Log:
Integrating SIP outbound proxy support

Modified:
    team/oej/codename-pineapple/   (props changed)
    team/oej/codename-pineapple/channels/chan_sip3.c
    team/oej/codename-pineapple/channels/sip3/sip3.h
    team/oej/codename-pineapple/channels/sip3/sip3_cliami.c
    team/oej/codename-pineapple/channels/sip3/sip3_config.c
    team/oej/codename-pineapple/channels/sip3/sip3_dialog.c
    team/oej/codename-pineapple/channels/sip3/sip3_network.c
    team/oej/codename-pineapple/channels/sip3/sip3_objects.c
    team/oej/codename-pineapple/channels/sip3/sip3_services.c
    team/oej/codename-pineapple/channels/sip3/sip3funcs.h

Propchange: team/oej/codename-pineapple/
------------------------------------------------------------------------------
    automerge = http://edvina.net/training/

Modified: team/oej/codename-pineapple/channels/chan_sip3.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/chan_sip3.c?view=diff&rev=53951&r1=53950&r2=53951
==============================================================================
--- team/oej/codename-pineapple/channels/chan_sip3.c (original)
+++ team/oej/codename-pineapple/channels/chan_sip3.c Sun Feb 11 14:32:55 2007
@@ -768,6 +768,7 @@
 			ast_string_field_build(dialog, callid, "%s@%s", tmpcall, device->extra.fromdomain);
 		}
 	}
+	dialog->outboundproxy = obproxy_get(dialog, device);
 	if (ast_strlen_zero(dialog->tohost))
 		ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr));
 	if (!ast_strlen_zero(device->extra.fromdomain))
@@ -836,6 +837,15 @@
 			return -1;	/* Can't find peer */
 		}
 	}
+	
+	ast_string_field_set(dialog, tohost, domain);
+
+	/* Get the outbound proxy information */
+	dialog->outboundproxy = obproxy_get(dialog, NULL);
+
+	/* If we have an outbound proxy, don't bother with DNS resolution at all */
+	if (dialog->outboundproxy)
+		return 0;
 
 	/* See if we have a port. If we have a given port,
 		disable SRV lookups */
@@ -870,7 +880,6 @@
 		ast_log(LOG_WARNING, "No such host: %s\n", peername);
 		return -2;
 	}
-	ast_string_field_set(dialog, tohost, domain);
 	memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr));
 	dialog->sa.sin_port = htons(portno);
 	dialog->recv = dialog->sa;

Modified: team/oej/codename-pineapple/channels/sip3/sip3.h
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3.h?view=diff&rev=53951&r1=53950&r2=53951
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3.h (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3.h Sun Feb 11 14:32:55 2007
@@ -458,7 +458,6 @@
 	SIP_CONF_NOTIFYMIME,
 	SIP_CONF_NOTIFYRINGING,
 	SIP_CONF_OUTBOUNDPROXY,
-	SIP_CONF_OBPROXYPORT,
 	SIP_CONF_PERMIT,
 	SIP_CONF_PICKUPGROUP,
 	SIP_CONF_PORT,
@@ -708,6 +707,21 @@
 	int rtpkeepalive;		/*!< Send RTP keepalives */
 };
 
+/*! \brief definition of a sip proxy server
+ *
+ * For outbound proxies, this is allocated in the SIP peer dynamically or
+ * statically as the global_outboundproxy. The pointer in a SIP message is just
+ * a pointer and should *not* be de-allocated.
+ */
+struct sip_proxy {
+	char name[MAXHOSTNAMELEN];      /*!< DNS name of domain/host or IP */
+	struct sockaddr_in ip;          /*!< Currently used IP address and port */
+	time_t last_dnsupdate;          /*!< When this was resolved */
+	int force;                      /*!< If it's an outbound proxy, Force use of this outbound proxy for all outbound requests */
+	/* Room for a SRV record chain based on the name */
+};
+
+
 /*! Global settings only apply to the channel */
 struct sip_globals {
 	struct ast_jb_conf jbconf;	/*!< Jitterbuffer configuration */
@@ -765,6 +779,7 @@
 	int default_maxcallbitrate;	/*!< Maximum bitrate for call */
 	struct ast_codec_pref default_prefs;	/*!< Default codec prefs */
 	enum sipdebuglevel debuglevel;	/*!< SIP debug level */
+	struct sip_proxy outboundproxy;	/*!< SIP Outbound proxy for outbound requests */
 };
 
 
@@ -1127,6 +1142,7 @@
 
 	/* REGISTER (outbound) */
 	struct sip_registry *registry;		/*!< If this is a REGISTER dialog, to which registry */
+	struct sip_proxy *outboundproxy;	/*!< Outbound proxy for this dialog */
 
 	struct sip_dialog *next;		/*!< Next dialog in chain */
 };
@@ -1217,6 +1233,7 @@
 
 	struct ast_ha *ha;		/*!<  Access control list */
 	struct ast_variable *chanvars;	/*!<  Variables to set for channel created by user */
+	struct sip_proxy *outboundproxy; /*!< Outbound proxy for this device */
 };
 
 
@@ -1268,10 +1285,8 @@
 	struct ast_ha *localaddr;	/*!< Our local addresses (locanet= ) */
 	struct in_addr __ourip;		/*!< Our IP */
 	int ourport;		/*!< Our port */
-	struct sockaddr_in outboundproxyip;	/*!< First SIP route hop */
 	struct sockaddr_in debugaddr;	/*!< Debugging ??? */
 	int *read_id;			/*!< ID of IO entry for sipsock socket FD */
-	char outboundproxy[MAXHOSTNAMELEN];	/*!< Outbound proxy name or IP in text */
 	char networkbuf[SIP_MSG_BUFSIZE];	/*!< Receive buffer */
 	unsigned int req_counter;	/*!< Counter of allocated requests */
 };

Modified: team/oej/codename-pineapple/channels/sip3/sip3_cliami.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_cliami.c?view=diff&rev=53951&r1=53950&r2=53951
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_cliami.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_cliami.c Sun Feb 11 14:32:55 2007
@@ -514,6 +514,9 @@
 		ast_cli(fd, "  Send RPID    : %s\n", ast_test_flag(&device->flags[0], SIP_SENDRPID) ? "Yes" : "No");
 		ast_cli(fd, "  Subscriptions: %s\n", ast_test_flag(&device->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
 		ast_cli(fd, "  Overlap dial : %s\n", ast_test_flag(&device->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
+		if (device->outboundproxy)
+			ast_cli(fd, "  Outb. proxy  : %s %s\n", ast_strlen_zero(device->outboundproxy->name) ? "<not set>" : device->outboundproxy->name,
+						device->outboundproxy->force ? "(forced)" : "");
 
 		/* - is enumerated */
 		ast_cli(fd, "  DTMFmode     : %s\n", dtmfmode2str(ast_test_flag(&device->flags[0], SIP_DTMF)));
@@ -770,7 +773,11 @@
 	ast_cli(fd, "  Outbound reg. attempts: %d\n", global.regattempts_max);
 	ast_cli(fd, "  Notify ringing state:   %s\n", global.notifyringing ? "Yes" : "No");
 	ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(global.allowtransfer));
-	ast_cli(fd, "  Max Call Bitrate:       %d kbps\r\n", global.default_maxcallbitrate);
+	ast_cli(fd, "  Max Call Bitrate:       %d kbps\n", global.default_maxcallbitrate);
+	ast_cli(fd, "  Auto-Framing:           %s\n", global.autoframing ? "Yes" : "No");
+	ast_cli(fd, "  Outb. proxy:            %s %s\n", ast_strlen_zero(global.outboundproxy.name) ? "<not set>" : global.outboundproxy.name,
+							global.outboundproxy.force ? "(forced)" : "");
+
 	ast_cli(fd, "\nTimer Settings:\n");
 	ast_cli(fd, "-----------------\n");
 	ast_cli(fd, "  SIP Timer T1 minimum: %d\n", global.t1min);

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?view=diff&rev=53951&r1=53950&r2=53951
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_config.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_config.c Sun Feb 11 14:32:55 2007
@@ -248,7 +248,7 @@
 	"Registrar proxy server for service"},
 	{ SIP_CONF_PROXY,	SIP_CONFCAT_MISC,	"proxy",	SIP_CONFOBJ_SERVICE | SIP_CONFOBJ_TRUNK,
 	"Proxy server for service"},
-	{ SIP_CONF_OUTBOUNDPROXY,	SIP_CONFCAT_MISC,	"outboundproxy",	SIP_CONFOBJ_SERVICE | SIP_CONFOBJ_TRUNK,
+	{ SIP_CONF_OUTBOUNDPROXY,	SIP_CONFCAT_MISC,	"outboundproxy",	SIP_CONFOBJ_GENERAL | SIP_CONFOBJ_SERVICE | SIP_CONFOBJ_TRUNK,
 	"Outbound proxy"},
 	{ SIP_CONF_DEFAULTIP,	SIP_CONFCAT_MISC,	"defaultip",	SIP_CONFOBJ_PHONE,
 	"Default host name or IP address of phone that is not registred"},
@@ -260,8 +260,6 @@
 	"Proxy port address (disables DNS SRV)"},
 	{ SIP_CONF_REGISTRARPORT,	SIP_CONFCAT_MISC,	"registrarport",	SIP_CONFOBJ_SERVICE | SIP_CONFOBJ_TRUNK,
 	"Registrar proxy port address"},
-	{ SIP_CONF_OBPROXYPORT,	SIP_CONFCAT_MISC,	"outboundproxyport",	SIP_CONFOBJ_SERVICE | SIP_CONFOBJ_TRUNK,
-	"Outbound proxy port address"},
 	{ SIP_CONF_LANGUAGE,	SIP_CONFCAT_MISC,	"language",	SIP_CONFOBJ_PHONE | SIP_CONFOBJ_TRUNK | SIP_CONFOBJ_SERVICE | SIP_CONFOBJ_DOMAIN,
 	"Default language for prompts"},
 	{ SIP_CONF_REGEXTEN,	SIP_CONFCAT_MISC,	"regexten",	SIP_CONFOBJ_PHONE,
@@ -957,8 +955,27 @@
 			ast_copy_string(device->extra.mohsuggest, v->value, sizeof(device->extra.mohsuggest));
 			break;
 		case SIP_CONF_OUTBOUNDPROXY:
-			break;
-		case SIP_CONF_OBPROXYPORT:
+			{
+				char *port, *next, *force, *proxyname;
+				int forceopt = FALSE;
+
+				/* Set peer channel variable */
+				next = proxyname = ast_strdupa(v->value);
+				if ((port = strchr(proxyname, ':'))) {
+					*port++ = '\0';
+					next = port;
+				}
+				if ((force = strchr(next, ','))) {
+					*force++ = '\0';
+					forceopt = strcmp(force, "force");
+				}
+				/* Allocate proxy object */
+				device->outboundproxy = proxy_allocate(proxyname, port, forceopt);
+				if (!device->outboundproxy) {
+					ast_log(LOG_WARNING, "Unable to resolve outbound proxy %s\n", proxyname);
+					error++;
+				}
+			}
 			break;
 		case SIP_CONF_PERMIT:
 			if(set_device_acl(device, v) != 0) {
@@ -1284,6 +1301,8 @@
 	global->siptimer_b = SIP_TIMER_B_DEFAULT;		
 	global->siptimer_f = SIP_TIMER_F_DEFAULT;		
 	sipcounters.peers_with_mwi = 0;		/* Reset counter for mwi peers */
+	global->outboundproxy.ip.sin_port = htons(STANDARD_SIP_PORT);
+	global->outboundproxy.ip.sin_family = AF_INET;   /* Type of address: IPv4 */
 }
 
 /*! \brief Re-read SIP.conf config file
@@ -1300,7 +1319,6 @@
 	char *cat, *stringp, *context, *oldregcontext;
 	char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT];
 	struct hostent *hp;
-	int format;
 	struct ast_flags dummy[2];
 	int auto_sip_domains = FALSE;
 	struct sockaddr_in old_bindaddr = sipnet.bindaddr;
@@ -1509,18 +1527,25 @@
 			ast_copy_string(global.default_fromdomain, v->value, sizeof(global.default_fromdomain));
 			break;
 		case SIP_CONF_OUTBOUNDPROXY:
-			/* Save name for re-resolution */
-			ast_copy_string(sipnet.outboundproxy, v->value, sizeof(sipnet.outboundproxy));
-			/* Try to resolve name now */
-			if (ast_get_ip_or_srv(&sipnet.outboundproxyip, v->value, global.srvlookup ? "_sip._udp" : NULL) < 0) {
-				ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value);
-				error++;
-				};
-			break;
-		case SIP_CONF_OBPROXYPORT:
-			/* Port needs to be after IP */
-			sscanf(v->value, "%d", &format);
-			sipnet.outboundproxyip.sin_port = htons(format);
+			{
+				char *name, *port = NULL, *force;
+
+				name = ast_strdupa(v->value);
+				if ((port = strchr(name, ':'))) {
+					*port++ = '\0';
+					global.outboundproxy.ip.sin_port = htons(atoi(port));
+				}
+
+				if ((force = strchr(port ? port : name, ','))) {
+					*force++ = '\0';
+					global.outboundproxy.force = (!strcasecmp(force, "force"));
+				}
+				ast_copy_string(global.outboundproxy.name, name, sizeof(global.outboundproxy.name));
+				if (!proxy_update(&global.outboundproxy)) {
+					ast_log(LOG_ERROR, "Unable to resolve outbound proxy: %s\n", name);
+					error++;
+				}
+			}
 			break;
 		case SIP_CONF_AUTOCREATEPEER:
 			global.autocreatepeer = ast_true(v->value);

Modified: team/oej/codename-pineapple/channels/sip3/sip3_dialog.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_dialog.c?view=diff&rev=53951&r1=53950&r2=53951
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_dialog.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_dialog.c Sun Feb 11 14:32:55 2007
@@ -271,6 +271,14 @@
 	}
 
 	dialog_lock(dialog, TRUE);
+
+	/* If we have an outbound proxy for this dialog, then delete it now since
+	   the rest of the requests in this dialog needs to follow the routing.
+	   If obforcing is set, we will keep the outbound proxy during the whole
+	   dialog, regardless of what the SIP rfc says
+	*/
+	if (dialog->outboundproxy && !dialog->outboundproxy->force)
+		dialog->outboundproxy = NULL;
 
 	/* Find proper transaction */
 	for (cur = dialog->packets; cur; prev = cur, cur = cur->next) {

Modified: team/oej/codename-pineapple/channels/sip3/sip3_network.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_network.c?view=diff&rev=53951&r1=53950&r2=53951
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_network.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_network.c Sun Feb 11 14:32:55 2007
@@ -110,6 +110,65 @@
 /* External variables from chan_sip3.so */
 extern struct sip_globals global;
 
+/*! Resolve DNS srv name or host name in a sip_proxy structure */
+int proxy_update(struct sip_proxy *proxy)
+{
+	/* if it's actually an IP address and not a name,
+           there's no need for a managed lookup */
+        if (!inet_aton(proxy->name, &proxy->ip.sin_addr)) {
+		/* Ok, not an IP address, then let's check if it's a domain or host */
+		/* XXX Todo - if we have proxy port, don't do SRV */
+		if (ast_get_ip_or_srv(&proxy->ip, proxy->name, global.srvlookup ? "_sip._udp" : NULL) < 0) {
+			ast_log(LOG_WARNING, "Unable to locate host '%s'\n", proxy->name);
+			return FALSE;
+		}
+	}
+	proxy->last_dnsupdate = time(NULL);
+	return TRUE;
+}
+
+/*! \brief Allocate and initialize sip proxy */
+struct sip_proxy *proxy_allocate(char *name, char *port, int force)
+{
+	struct sip_proxy *proxy;
+	proxy = ast_calloc(1, sizeof(struct sip_proxy));
+	if (!proxy)
+		return NULL;
+	proxy->force = force;
+	ast_copy_string(proxy->name, name, sizeof(proxy->name));
+	if (!ast_strlen_zero(port))
+		proxy->ip.sin_port = htons(atoi(port));
+	if (!proxy_update(proxy)) {
+		free(proxy);
+		return NULL;
+	}
+
+	return proxy;
+}
+
+/*! \brief Get default outbound proxy or global proxy 
+	\todo XXX need to integrate domain->outboundproxy at some point
+*/
+struct sip_proxy *obproxy_get(struct sip_dialog *dialog, struct sip_device *device)
+{
+	if (device && device->outboundproxy) {
+		if (option_debug && sipdebug)
+			ast_log(LOG_DEBUG, "OBPROXY: Applying device OBproxy to this call\n");
+		append_history(dialog, "OBproxy", "Using device obproxy %s", device->outboundproxy->name);
+		return device->outboundproxy;
+	}
+	if (global.outboundproxy.name[0]) {
+		if (option_debug && sipdebug)
+			ast_log(LOG_DEBUG, "OBPROXY: Applying global OBproxy to this call\n");
+		append_history(dialog, "OBproxy", "Using global obproxy %s", global.outboundproxy.name);
+		return &global.outboundproxy;
+	}
+	if (option_debug && sipdebug)
+		ast_log(LOG_DEBUG, "OBPROXY: Not applying OBproxy to this call\n");
+	return NULL;
+}
+
+
 /*! \brief Initialize network lock */
 static void sipnet_lock_init(struct sip_network *sipnet)
 {
@@ -139,10 +198,6 @@
 	memset(&sipnet->bindaddr, 0, sizeof(sipnet->bindaddr));
 	memset(&sipnet->localaddr, 0, sizeof(sipnet->localaddr));
 	memset(&sipnet->externip, 0, sizeof(sipnet->externip));
-
-	sipnet->outboundproxyip.sin_port = htons(STANDARD_SIP_PORT);
-	sipnet->outboundproxyip.sin_family = AF_INET;	/* Type of address: IPv4 */
-	memset(&sipnet->outboundproxyip, 0, sizeof(sipnet->outboundproxyip));
 
 	sipnet_ourport_set(sipnet, DEFAULT_LISTEN_SIP_PORT);
 	sipnet->externhost[0] = '\0';			/* External host name (for behind NAT DynDNS support) */
@@ -750,6 +805,8 @@
 /*! \brief The real destination address for a write */
 const struct sockaddr_in *sip_real_dst(const struct sip_dialog *p)
 {
+	if (p->outboundproxy)
+		return &p->outboundproxy->ip;
 	return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa;
 }
 

Modified: team/oej/codename-pineapple/channels/sip3/sip3_objects.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_objects.c?view=diff&rev=53951&r1=53950&r2=53951
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_objects.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_objects.c Sun Feb 11 14:32:55 2007
@@ -177,8 +177,9 @@
 GNURK void sip_destroy_device(struct sip_device *device)
 {
 	logdebug(3, "Destroying SIP device %s\n", device->name);
-	//if (option_debug > 2)
-		//ast_log(LOG_DEBUG, "Destroying SIP %s %s\n", device->type & SIP_USER ? "user" : "peer", device->name);
+
+	if (device->outboundproxy)
+		free(device->outboundproxy);
 
 	/* Delete it, it needs to disappear */
 	if (device->call)

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?view=diff&rev=53951&r1=53950&r2=53951
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_services.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_services.c Sun Feb 11 14:32:55 2007
@@ -408,6 +408,10 @@
 		}
 		if (!ast_test_flag(&dialog->flags[0], SIP_NO_HISTORY))
 			append_history(dialog, "RegistryInit", "Account: %s@%s", r->username, r->hostname);
+
+		/* Get outbound proxy */
+		dialog->outboundproxy = obproxy_get(dialog, NULL);
+
 		/* Find address to hostname */
 		if (create_addr(dialog, NULL, r->hostname, NULL)) {
 			/* we have what we hope is a temporary network error,

Modified: team/oej/codename-pineapple/channels/sip3/sip3funcs.h
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3funcs.h?view=diff&rev=53951&r1=53950&r2=53951
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3funcs.h (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3funcs.h Sun Feb 11 14:32:55 2007
@@ -106,6 +106,9 @@
 GNURK int transmit_state_notify(struct sip_dialog *p, int state, int full, int timeout);
 
 /*! sip3_network.c */
+GNURK int proxy_update(struct sip_proxy *proxy);
+GNURK struct sip_proxy *proxy_allocate(char *name, char *port, int force);
+GNURK struct sip_proxy *obproxy_get(struct sip_dialog *dialog, struct sip_device *device);
 GNURK struct sip_request *siprequest_alloc(size_t len, struct sip_network *sipnet);
 GNURK void siprequest_free(struct sip_request *req);
 GNURK int close_sip_sockets(void);



More information about the asterisk-commits mailing list