mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-10 14:51:09 +00:00
Add *preliminary* per-peer outbound proxy (bug #2859, new patch though)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4383 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
18
acl.c
18
acl.c
@@ -23,6 +23,7 @@
|
|||||||
#include <asterisk/channel.h>
|
#include <asterisk/channel.h>
|
||||||
#include <asterisk/utils.h>
|
#include <asterisk/utils.h>
|
||||||
#include <asterisk/lock.h>
|
#include <asterisk/lock.h>
|
||||||
|
#include <asterisk/srv.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
@@ -186,10 +187,20 @@ int ast_apply_ha(struct ast_ha *ha, struct sockaddr_in *sin)
|
|||||||
return res;
|
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 hostent *hp;
|
||||||
struct ast_hostent ahp;
|
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);
|
hp = ast_gethostbyname(value, &ahp);
|
||||||
if (hp) {
|
if (hp) {
|
||||||
memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
|
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;
|
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 */
|
/* iface is the interface (e.g. eth0); address is the return value */
|
||||||
int ast_lookup_iface(char *iface, struct in_addr *address) {
|
int ast_lookup_iface(char *iface, struct in_addr *address) {
|
||||||
int mysock, res = 0;
|
int mysock, res = 0;
|
||||||
|
@@ -186,6 +186,7 @@ static int noncodeccapability = AST_RTP_DTMF;
|
|||||||
|
|
||||||
static char ourhost[256];
|
static char ourhost[256];
|
||||||
static struct in_addr __ourip;
|
static struct in_addr __ourip;
|
||||||
|
static struct sockaddr_in outboundproxyip;
|
||||||
static int ourport;
|
static int ourport;
|
||||||
|
|
||||||
static int sipdebug = 0;
|
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 sip_peer *prev;
|
||||||
struct ast_ha *oldha = NULL;
|
struct ast_ha *oldha = NULL;
|
||||||
int maskfound=0;
|
int maskfound=0;
|
||||||
|
int obproxyfound=0;
|
||||||
int found=0;
|
int found=0;
|
||||||
|
|
||||||
prev = NULL;
|
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);
|
ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n", v->value);
|
||||||
peer->dtmfmode = SIP_DTMF_RFC2833;
|
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")) {
|
if (!strcasecmp(v->value, "dynamic")) {
|
||||||
/* They'll register with us */
|
if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) {
|
||||||
peer->dynamic = 1;
|
ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno);
|
||||||
if (!found) {
|
} else {
|
||||||
/* Initialize stuff iff we're not found, otherwise
|
/* They'll register with us */
|
||||||
we keep going with what we had */
|
peer->dynamic = 1;
|
||||||
memset(&peer->addr.sin_addr, 0, 4);
|
if (!found) {
|
||||||
if (peer->addr.sin_port) {
|
/* Initialize stuff iff we're not found, otherwise
|
||||||
/* If we've already got a port, make it the default rather than absolute */
|
we keep going with what we had */
|
||||||
peer->defaddr.sin_port = peer->addr.sin_port;
|
memset(&peer->addr.sin_addr, 0, 4);
|
||||||
peer->addr.sin_port = 0;
|
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 {
|
} 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);
|
ast_sched_del(sched, peer->expire);
|
||||||
peer->expire = -1;
|
peer->expire = -1;
|
||||||
peer->dynamic = 0;
|
peer->dynamic = 0;
|
||||||
if (ast_get_ip(&peer->addr, v->value)) {
|
if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) {
|
||||||
destroy_peer(peer);
|
if (ast_get_ip_or_srv(&peer->addr, v->value, "_sip._udp")) {
|
||||||
return NULL;
|
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)
|
if (!maskfound)
|
||||||
inet_aton("255.255.255.255", &peer->mask);
|
inet_aton("255.255.255.255", &peer->mask);
|
||||||
@@ -8652,6 +8663,9 @@ static int reload_config(void)
|
|||||||
global_realm[sizeof(global_realm)-1] = '\0';
|
global_realm[sizeof(global_realm)-1] = '\0';
|
||||||
strncpy(global_musicclass, "default", sizeof(global_musicclass) - 1);
|
strncpy(global_musicclass, "default", sizeof(global_musicclass) - 1);
|
||||||
strncpy(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid) - 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;
|
global_canreinvite = REINVITE_INVITE;
|
||||||
videosupport = 0;
|
videosupport = 0;
|
||||||
compactheaders = 0;
|
compactheaders = 0;
|
||||||
@@ -8748,6 +8762,13 @@ static int reload_config(void)
|
|||||||
global_nat = SIP_NAT_ALWAYS;
|
global_nat = SIP_NAT_ALWAYS;
|
||||||
else
|
else
|
||||||
global_nat = SIP_NAT_NEVER;
|
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")) {
|
} else if (!strcasecmp(v->name, "autocreatepeer")) {
|
||||||
autocreatepeer = ast_true(v->value);
|
autocreatepeer = ast_true(v->value);
|
||||||
} else if (!strcasecmp(v->name, "srvlookup")) {
|
} else if (!strcasecmp(v->name, "srvlookup")) {
|
||||||
|
@@ -31,7 +31,8 @@ struct ast_ha;
|
|||||||
extern void ast_free_ha(struct ast_ha *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 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_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_ouraddrfor(struct in_addr *them, struct in_addr *us);
|
||||||
extern int ast_lookup_iface(char *iface, struct in_addr *address);
|
extern int ast_lookup_iface(char *iface, struct in_addr *address);
|
||||||
extern struct ast_ha *ast_duplicate_ha_list(struct ast_ha *original);
|
extern struct ast_ha *ast_duplicate_ha_list(struct ast_ha *original);
|
||||||
|
Reference in New Issue
Block a user