mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-18 15:49:56 +00:00
Merge in changes to return chan_sip to matching based on how it was previously done and how it is done in trunk. It will do name based for users and friends and IP based for peers.
(closes issue #14107) Reported by: jsmith git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.1@165606 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -209,6 +209,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||
|
||||
#define SIPBUFSIZE 512
|
||||
|
||||
/* Arguments for find_peer */
|
||||
#define FINDALLDEVICES FALSE
|
||||
#define FINDONLYUSERS TRUE
|
||||
|
||||
#define XMIT_ERROR -2
|
||||
|
||||
#define SIP_RESERVED ";/?:@&=+$,# "
|
||||
@@ -1690,15 +1694,18 @@ static int peer_ipcmp_cb(void *obj, void *arg, int flags)
|
||||
{
|
||||
struct sip_peer *peer = obj, *peer2 = arg;
|
||||
|
||||
if (peer->addr.sin_addr.s_addr != peer2->addr.sin_addr.s_addr)
|
||||
if (peer->addr.sin_addr.s_addr != peer2->addr.sin_addr.s_addr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT) && !ast_test_flag(&peer2->flags[0], SIP_INSECURE_PORT)) {
|
||||
if (peer->addr.sin_port == peer2->addr.sin_port)
|
||||
if (peer->addr.sin_port == peer2->addr.sin_port) {
|
||||
return CMP_MATCH | CMP_STOP;
|
||||
else
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return CMP_MATCH | CMP_STOP;
|
||||
}
|
||||
|
||||
@@ -4080,6 +4087,31 @@ static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_i
|
||||
return peer;
|
||||
}
|
||||
|
||||
struct peer_finding_info {
|
||||
struct sip_peer tmp_peer;
|
||||
int forcenamematch;
|
||||
};
|
||||
|
||||
/* Function to assist finding peers by name only */
|
||||
static int find_by_name(void *obj, void *arg, int flags)
|
||||
{
|
||||
struct sip_peer *search = obj;
|
||||
struct peer_finding_info *pfi = arg;
|
||||
|
||||
/* Usernames in SIP uri's are case sensitive. Domains are not */
|
||||
if (strcmp(search->name, pfi->tmp_peer.name)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If we're only looking for name matches, we should avoid type=peer devices,
|
||||
since these should not match on any name-based search */
|
||||
if (pfi->forcenamematch && search->onlymatchonip) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return CMP_MATCH | CMP_STOP;
|
||||
}
|
||||
|
||||
/*! \brief Locate device by name or ip address
|
||||
* This is used on find matching device on name or ip/port.
|
||||
If the device was declared as type=peer, we don't match on peer name on incoming INVITEs.
|
||||
@@ -4090,12 +4122,13 @@ static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_i
|
||||
static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime, int forcenamematch, int devstate_only)
|
||||
{
|
||||
struct sip_peer *p = NULL;
|
||||
struct sip_peer tmp_peer;
|
||||
|
||||
|
||||
if (peer) {
|
||||
ast_copy_string(tmp_peer.name, peer, sizeof(tmp_peer.name));
|
||||
p = ao2_t_find(peers, &tmp_peer, OBJ_POINTER, "ao2_find in peers table");
|
||||
struct peer_finding_info pfi = { .forcenamematch = forcenamematch, };
|
||||
ast_copy_string(pfi.tmp_peer.name, peer, sizeof(pfi.tmp_peer.name));
|
||||
p = ao2_t_callback(peers, OBJ_POINTER, find_by_name, &pfi, "ao2_callback in peers table");
|
||||
} else if (sin) { /* search by addr? */
|
||||
struct sip_peer tmp_peer;
|
||||
tmp_peer.addr.sin_addr.s_addr = sin->sin_addr.s_addr;
|
||||
tmp_peer.addr.sin_port = sin->sin_port;
|
||||
tmp_peer.flags[0].flags = 0;
|
||||
@@ -4359,7 +4392,7 @@ static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockadd
|
||||
dialog->sa.sin_family = AF_INET;
|
||||
dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
|
||||
dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
|
||||
peer = find_peer(peername, NULL, TRUE, TRUE, FALSE);
|
||||
peer = find_peer(peername, NULL, TRUE, FINDALLDEVICES, FALSE);
|
||||
|
||||
if (peer) {
|
||||
int res;
|
||||
@@ -4714,7 +4747,7 @@ static int update_call_counter(struct sip_pvt *fup, int event)
|
||||
ast_copy_string(name, fup->username, sizeof(name));
|
||||
|
||||
/* Check the list of devices */
|
||||
if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, TRUE, FALSE, FALSE) ) ) { /* Try to find peer */
|
||||
if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, TRUE, FINDALLDEVICES, FALSE) ) ) { /* Try to find peer */
|
||||
inuse = &p->inUse;
|
||||
call_limit = &p->call_limit;
|
||||
inringing = &p->inRinging;
|
||||
@@ -10892,7 +10925,7 @@ static enum check_auth_result check_auth(struct sip_pvt *p, struct sip_request *
|
||||
/*! \brief Change onhold state of a peer using a pvt structure */
|
||||
static void sip_peer_hold(struct sip_pvt *p, int hold)
|
||||
{
|
||||
struct sip_peer *peer = find_peer(p->peername, NULL, 1, TRUE, FALSE);
|
||||
struct sip_peer *peer = find_peer(p->peername, NULL, 1, FINDALLDEVICES, FALSE);
|
||||
|
||||
if (!peer)
|
||||
return;
|
||||
@@ -11041,7 +11074,7 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr
|
||||
|
||||
ast_string_field_set(p, exten, name);
|
||||
build_contact(p);
|
||||
peer = find_peer(name, NULL, TRUE, TRUE, FALSE);
|
||||
peer = find_peer(name, NULL, TRUE, FINDALLDEVICES, FALSE);
|
||||
if (!(peer && ast_apply_ha(peer->ha, sin))) {
|
||||
/* Peer fails ACL check */
|
||||
if (peer) {
|
||||
@@ -11912,7 +11945,7 @@ static void replace_cid(struct sip_pvt *p, const char *rpid_num, const char *cal
|
||||
}
|
||||
}
|
||||
|
||||
/*! \brief Validate peer authentication */
|
||||
/*! \brief Validate device authentication */
|
||||
static enum check_auth_result check_peer_ok(struct sip_pvt *p, char *of,
|
||||
struct sip_request *req, int sipmethod, struct sockaddr_in *sin,
|
||||
struct sip_peer **authpeer,
|
||||
@@ -11923,10 +11956,20 @@ static enum check_auth_result check_peer_ok(struct sip_pvt *p, char *of,
|
||||
int debug=sip_debug_test_addr(sin);
|
||||
struct sip_peer *peer;
|
||||
|
||||
/* For subscribes, match on device name only; for other methods,
|
||||
* match on IP address-port of the incoming request.
|
||||
*/
|
||||
peer = (sipmethod == SIP_SUBSCRIBE) ? find_peer(of, NULL, TRUE, FALSE, FALSE) : find_peer(NULL, &p->recv, TRUE, FALSE, FALSE);
|
||||
if (sipmethod == SIP_SUBSCRIBE) {
|
||||
/* For subscribes, match on device name only; for other methods,
|
||||
* match on IP address-port of the incoming request.
|
||||
*/
|
||||
peer = find_peer(of, NULL, TRUE, FINDALLDEVICES, FALSE);
|
||||
} else {
|
||||
/* First find devices based on username (avoid all type=peer's) */
|
||||
peer = find_peer(of, NULL, TRUE, FINDONLYUSERS, FALSE);
|
||||
|
||||
/* Then find devices based on IP */
|
||||
if (!peer) {
|
||||
peer = find_peer(NULL, &p->recv, TRUE, FINDALLDEVICES, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (!peer) {
|
||||
if (debug)
|
||||
@@ -13175,7 +13218,7 @@ static char *_sip_qualify_peer(int type, int fd, struct mansession *s, const str
|
||||
return CLI_SHOWUSAGE;
|
||||
|
||||
load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
|
||||
if ((peer = find_peer(argv[3], NULL, load_realtime, FALSE, FALSE))) {
|
||||
if ((peer = find_peer(argv[3], NULL, load_realtime, FINDALLDEVICES, FALSE))) {
|
||||
sip_poke_peer(peer, 1);
|
||||
unref_peer(peer, "qualify: done with peer");
|
||||
} else if (type == 0) {
|
||||
@@ -13257,7 +13300,7 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
|
||||
return CLI_SHOWUSAGE;
|
||||
|
||||
load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
|
||||
peer = find_peer(argv[3], NULL, load_realtime, TRUE, FALSE);
|
||||
peer = find_peer(argv[3], NULL, load_realtime, FINDALLDEVICES, FALSE);
|
||||
if (s) { /* Manager */
|
||||
if (peer) {
|
||||
const char *id = astman_get_header(m, "ActionID");
|
||||
@@ -13578,7 +13621,7 @@ static char *sip_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
|
||||
if (a->argc != 3)
|
||||
return CLI_SHOWUSAGE;
|
||||
|
||||
if ((peer = find_peer(a->argv[2], NULL, load_realtime, TRUE, TRUE))) {
|
||||
if ((peer = find_peer(a->argv[2], NULL, load_realtime, FINDALLDEVICES, TRUE))) {
|
||||
if (peer->expire > 0) {
|
||||
expire_register(ref_peer(peer, "ref for expire_register"));
|
||||
ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]);
|
||||
@@ -14550,7 +14593,7 @@ static char *sip_do_debug_ip(int fd, char *arg)
|
||||
/*! \brief Turn on SIP debugging for a given peer */
|
||||
static char *sip_do_debug_peer(int fd, char *arg)
|
||||
{
|
||||
struct sip_peer *peer = find_peer(arg, NULL, TRUE, TRUE, FALSE);
|
||||
struct sip_peer *peer = find_peer(arg, NULL, TRUE, FINDALLDEVICES, FALSE);
|
||||
if (!peer)
|
||||
ast_cli(fd, "No such peer '%s'\n", arg);
|
||||
else if (peer->addr.sin_addr.s_addr == 0)
|
||||
@@ -15046,7 +15089,7 @@ static int function_sippeer(struct ast_channel *chan, const char *cmd, char *dat
|
||||
else
|
||||
colname = "ip";
|
||||
|
||||
if (!(peer = find_peer(data, NULL, TRUE, TRUE, FALSE)))
|
||||
if (!(peer = find_peer(data, NULL, TRUE, FINDALLDEVICES, FALSE)))
|
||||
return -1;
|
||||
|
||||
if (!strcasecmp(colname, "ip")) {
|
||||
@@ -17374,9 +17417,12 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
|
||||
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
|
||||
return 0;
|
||||
} else {
|
||||
/* This is a spiral. What we need to do is to just change the outgoing INVITE
|
||||
/*! This is a spiral. What we need to do is to just change the outgoing INVITE
|
||||
* so that it now routes to the new Request URI. Since we created the INVITE ourselves
|
||||
* that should be all we need to do.
|
||||
*
|
||||
* \todo XXX This needs to be reviewed. YOu don't change the request URI really, you route the packet
|
||||
* correctly instead...
|
||||
*/
|
||||
char *uri = ast_strdupa(req->rlPart2);
|
||||
char *at = strchr(uri, '@');
|
||||
@@ -20111,7 +20157,7 @@ int st_get_se(struct sip_pvt *p, int max)
|
||||
if (p->stimer->st_cached_max_se) {
|
||||
return p->stimer->st_cached_max_se;
|
||||
} else if (p->peername) {
|
||||
struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, TRUE, FALSE);
|
||||
struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDALLDEVICES, FALSE);
|
||||
if (pp) {
|
||||
p->stimer->st_cached_max_se = pp->stimer.st_max_se;
|
||||
unref_peer(pp, "unref peer pointer from find_peer call in st_get_se");
|
||||
@@ -20124,7 +20170,7 @@ int st_get_se(struct sip_pvt *p, int max)
|
||||
if (p->stimer->st_cached_min_se) {
|
||||
return p->stimer->st_cached_min_se;
|
||||
} else if (p->peername) {
|
||||
struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, TRUE, FALSE);
|
||||
struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDALLDEVICES, FALSE);
|
||||
if (pp) {
|
||||
p->stimer->st_cached_min_se = pp->stimer.st_min_se;
|
||||
unref_peer(pp, "unref peer pointer from find_peer call in st_get_se (2)");
|
||||
@@ -20146,7 +20192,7 @@ enum st_refresher st_get_refresher(struct sip_pvt *p)
|
||||
return p->stimer->st_cached_ref;
|
||||
|
||||
if (p->peername) {
|
||||
struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, TRUE, FALSE);
|
||||
struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDALLDEVICES, FALSE);
|
||||
if (pp) {
|
||||
p->stimer->st_cached_ref = pp->stimer.st_ref;
|
||||
unref_peer(pp, "unref peer pointer from find_peer call in st_get_refresher");
|
||||
@@ -20171,7 +20217,7 @@ enum st_mode st_get_mode(struct sip_pvt *p)
|
||||
return p->stimer->st_cached_mode;
|
||||
|
||||
if (p->peername) {
|
||||
struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, TRUE, FALSE);
|
||||
struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDALLDEVICES, FALSE);
|
||||
if (pp) {
|
||||
p->stimer->st_cached_mode = pp->stimer.st_mode_oper;
|
||||
unref_peer(pp, "unref peer pointer from find_peer call in st_get_mode");
|
||||
@@ -20358,7 +20404,7 @@ static int sip_devicestate(void *data)
|
||||
* load it BACK into memory, thus defeating the point of trying to clear dead
|
||||
* hosts out of memory.
|
||||
*/
|
||||
if ((p = find_peer(host, NULL, FALSE, TRUE, TRUE))) {
|
||||
if ((p = find_peer(host, NULL, FALSE, FINDALLDEVICES, TRUE))) {
|
||||
if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
|
||||
/* we have an address for the peer */
|
||||
|
||||
@@ -22147,7 +22193,7 @@ static int reload_config(enum channelreloadreason reason)
|
||||
if (!strcasecmp(utype, "user")) {
|
||||
is_peer = 1;
|
||||
} else if (!strcasecmp(utype, "friend")) {
|
||||
is_peer = 2;
|
||||
is_peer = 1;
|
||||
} else if (!strcasecmp(utype, "peer"))
|
||||
is_peer = 2;
|
||||
else {
|
||||
|
||||
Reference in New Issue
Block a user