aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2004-12-03 23:34:45 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2004-12-03 23:34:45 +0000
commit6e02cf8b96c03ec5f79bc77d76e56193c87a5670 (patch)
tree1b2c1c2831fe11e5f38a4cbc4c94c490b1b425b3
parent79a741f2616cc17440b66842899bd142fc9341c6 (diff)
Add *preliminary* per-peer outbound proxy (bug #2859, new patch though)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@4383 f38db490-d61c-443f-a65b-d21fe96a405b
-rwxr-xr-xacl.c18
-rwxr-xr-xchannels/chan_sip.c51
-rwxr-xr-xinclude/asterisk/acl.h3
3 files changed, 55 insertions, 17 deletions
diff --git a/acl.c b/acl.c
index 935ec808d..c7eb34270 100755
--- a/acl.c
+++ b/acl.c
@@ -23,6 +23,7 @@
#include <asterisk/channel.h>
#include <asterisk/utils.h>
#include <asterisk/lock.h>
+#include <asterisk/srv.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
@@ -186,10 +187,20 @@ int ast_apply_ha(struct ast_ha *ha, struct sockaddr_in *sin)
return res;
}
-int ast_get_ip(struct sockaddr_in *sin, char *value)
+int ast_get_ip_or_srv(struct sockaddr_in *sin, const char *value, const char *service)
{
struct hostent *hp;
struct ast_hostent ahp;
+ char srv[256];
+ char host[256];
+ int tportno = ntohs(sin->sin_port);
+ if (service) {
+ snprintf(srv, sizeof(srv), "%s.%s", service, value);
+ if (ast_get_srv(NULL, host, sizeof(host), &tportno, srv) > 0) {
+ sin->sin_port = htons(tportno);
+ value = host;
+ }
+ }
hp = ast_gethostbyname(value, &ahp);
if (hp) {
memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
@@ -200,6 +211,11 @@ int ast_get_ip(struct sockaddr_in *sin, char *value)
return 0;
}
+int ast_get_ip(struct sockaddr_in *sin, const char *value)
+{
+ return ast_get_ip_or_srv(sin, value, NULL);
+}
+
/* iface is the interface (e.g. eth0); address is the return value */
int ast_lookup_iface(char *iface, struct in_addr *address) {
int mysock, res = 0;
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 4220e82ca..dde707e28 100755
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -186,6 +186,7 @@ static int noncodeccapability = AST_RTP_DTMF;
static char ourhost[256];
static struct in_addr __ourip;
+static struct sockaddr_in outboundproxyip;
static int ourport;
static int sipdebug = 0;
@@ -8375,6 +8376,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
struct sip_peer *prev;
struct ast_ha *oldha = NULL;
int maskfound=0;
+ int obproxyfound=0;
int found=0;
prev = NULL;
@@ -8480,18 +8482,22 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n", v->value);
peer->dtmfmode = SIP_DTMF_RFC2833;
}
- } else if (!strcasecmp(v->name, "host")) {
+ } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) {
if (!strcasecmp(v->value, "dynamic")) {
- /* They'll register with us */
- peer->dynamic = 1;
- if (!found) {
- /* Initialize stuff iff we're not found, otherwise
- we keep going with what we had */
- memset(&peer->addr.sin_addr, 0, 4);
- if (peer->addr.sin_port) {
- /* If we've already got a port, make it the default rather than absolute */
- peer->defaddr.sin_port = peer->addr.sin_port;
- peer->addr.sin_port = 0;
+ if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) {
+ ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno);
+ } else {
+ /* They'll register with us */
+ peer->dynamic = 1;
+ if (!found) {
+ /* Initialize stuff iff we're not found, otherwise
+ we keep going with what we had */
+ memset(&peer->addr.sin_addr, 0, 4);
+ if (peer->addr.sin_port) {
+ /* If we've already got a port, make it the default rather than absolute */
+ peer->defaddr.sin_port = peer->addr.sin_port;
+ peer->addr.sin_port = 0;
+ }
}
}
} else {
@@ -8500,11 +8506,16 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
ast_sched_del(sched, peer->expire);
peer->expire = -1;
peer->dynamic = 0;
- if (ast_get_ip(&peer->addr, v->value)) {
- destroy_peer(peer);
- return NULL;
+ if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) {
+ if (ast_get_ip_or_srv(&peer->addr, v->value, "_sip._udp")) {
+ destroy_peer(peer);
+ return NULL;
+ }
}
- strncpy(peer->tohost, v->value, sizeof(peer->tohost) - 1);
+ if (!strcasecmp(v->name, "outboundproxy"))
+ obproxyfound=1;
+ else
+ strncpy(peer->tohost, v->value, sizeof(peer->tohost) - 1);
}
if (!maskfound)
inet_aton("255.255.255.255", &peer->mask);
@@ -8652,6 +8663,9 @@ static int reload_config(void)
global_realm[sizeof(global_realm)-1] = '\0';
strncpy(global_musicclass, "default", sizeof(global_musicclass) - 1);
strncpy(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid) - 1);
+ memset(&outboundproxyip, 0, sizeof(outboundproxyip));
+ outboundproxyip.sin_port = htons(DEFAULT_SIP_PORT);
+ outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */
global_canreinvite = REINVITE_INVITE;
videosupport = 0;
compactheaders = 0;
@@ -8748,6 +8762,13 @@ static int reload_config(void)
global_nat = SIP_NAT_ALWAYS;
else
global_nat = SIP_NAT_NEVER;
+ } else if (!strcasecmp(v->name, "outboundproxy")) {
+ if (ast_get_ip_or_srv(&outboundproxyip, v->value, "_sip._udp") < 0)
+ ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value);
+ } else if (!strcasecmp(v->name, "outboundproxyport")) {
+ /* Port needs to be after IP */
+ sscanf(v->value, "%i", &format);
+ outboundproxyip.sin_port = htons(format);
} else if (!strcasecmp(v->name, "autocreatepeer")) {
autocreatepeer = ast_true(v->value);
} else if (!strcasecmp(v->name, "srvlookup")) {
diff --git a/include/asterisk/acl.h b/include/asterisk/acl.h
index bcc7543d5..87c89bd59 100755
--- a/include/asterisk/acl.h
+++ b/include/asterisk/acl.h
@@ -31,7 +31,8 @@ struct ast_ha;
extern void ast_free_ha(struct ast_ha *ha);
extern struct ast_ha *ast_append_ha(char *sense, char *stuff, struct ast_ha *path);
extern int ast_apply_ha(struct ast_ha *ha, struct sockaddr_in *sin);
-extern int ast_get_ip(struct sockaddr_in *sin, char *value);
+extern int ast_get_ip(struct sockaddr_in *sin, const char *value);
+extern int ast_get_ip_or_srv(struct sockaddr_in *sin, const char *value, const char *service);
extern int ast_ouraddrfor(struct in_addr *them, struct in_addr *us);
extern int ast_lookup_iface(char *iface, struct in_addr *address);
extern struct ast_ha *ast_duplicate_ha_list(struct ast_ha *original);