diff options
author | Olle Johansson <oej@edvina.net> | 2008-10-26 10:23:01 +0000 |
---|---|---|
committer | Olle Johansson <oej@edvina.net> | 2008-10-26 10:23:01 +0000 |
commit | 0fdde26109dff999d0ca19f0c0db55baf164f2b0 (patch) | |
tree | d929b431ebd2164000201d282dcb1c0b217a42fd /channels | |
parent | 9137733e1124335c20b777520e2698611d932a48 (diff) |
Trying to fix the user/peer matching correctly. This will need some testing before
getting merged into 1.6.1
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@152020 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_sip.c | 63 |
1 files changed, 42 insertions, 21 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 37b279804..9739ab3eb 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -286,6 +286,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif +/* Arguments for find_peer */ +#define FINDALLDEVICES FALSE +#define FINDONLYUSERS TRUE + #define SIPBUFSIZE 512 /*!< Buffer size for many operations */ @@ -4251,16 +4255,20 @@ static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int struct sip_peer *p = NULL; struct sip_peer tmp_peer; + /* Inline function to assist finding peers by name only */ auto int find_by_name(void *obj, void *arg, int flags); int find_by_name(void *obj, void *arg, int flags) { struct sip_peer *search = obj, *match = arg; - if (strcasecmp(search->name, match->name)) { + /* Usernames in SIP uri's are case sensitive. Domains are not */ + if (strcmp(search->name, match->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 (forcenamematch && search->onlymatchonip) { return 0; } @@ -4536,7 +4544,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; @@ -4903,7 +4911,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; @@ -11251,7 +11259,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; @@ -11403,7 +11411,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) { @@ -12315,7 +12323,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, @@ -12326,10 +12334,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) { + find_peer(NULL, &p->recv, TRUE, FINDALLDEVICES, FALSE); + } + } if (!peer) { if (debug) @@ -13582,7 +13600,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) { @@ -13664,7 +13682,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"); @@ -13986,7 +14004,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(peer); ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]); @@ -14990,7 +15008,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) @@ -15486,7 +15504,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")) { @@ -17934,9 +17952,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, '@'); @@ -20699,7 +20720,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"); @@ -20712,7 +20733,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)"); @@ -20734,7 +20755,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"); @@ -20759,7 +20780,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"); @@ -20931,7 +20952,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 */ |