132 lines
4.2 KiB
Diff
132 lines
4.2 KiB
Diff
Index: chan_sip.c
|
|
===================================================================
|
|
--- chan_sip.c (revision 65247)
|
|
+++ chan_sip.c (working copy)
|
|
@@ -1414,6 +1414,8 @@
|
|
static struct sip_peer *temp_peer(const char *name);
|
|
static void register_peer_exten(struct sip_peer *peer, int onoff);
|
|
static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime);
|
|
+/*&&&*/
|
|
+static struct sip_peer *find_peer_siphead(const char *peer, struct sockaddr_in *sin, char *username, int realtime);
|
|
static struct sip_user *find_user(const char *name, int realtime);
|
|
static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req);
|
|
static int expire_register(void *data);
|
|
@@ -2506,6 +2508,7 @@
|
|
(p->addr.sin_addr.s_addr == sin->sin_addr.s_addr)));
|
|
}
|
|
|
|
+
|
|
/*! \brief Locate peer by name or ip address
|
|
* This is used on incoming SIP message to find matching peer on ip
|
|
or outgoing message to find matching peer on name */
|
|
@@ -2524,6 +2527,38 @@
|
|
return p;
|
|
}
|
|
|
|
+/*!&&& \brief Locate peer by username and ip address
|
|
+ * This is used on incoming SIP message to find matching peer on To username and sender IP */
|
|
+static struct sip_peer *find_peer_siphead(const char *peer, struct sockaddr_in *sin, char *username, int realtime)
|
|
+{
|
|
+ struct sip_peer *p = NULL;
|
|
+
|
|
+ if (peer) {
|
|
+ return NULL; /* use find_peer instead */
|
|
+ } else {
|
|
+ typeof((&peerl)->head) found = NULL;
|
|
+ ASTOBJ_CONTAINER_TRAVERSE(&peerl, !found, do {
|
|
+ ASTOBJ_RDLOCK(iterator);
|
|
+ if (!(sip_addrcmp(iterator->name, sin)) &&
|
|
+ !(strcmp(iterator->username, username))) {
|
|
+ found = ASTOBJ_REF(iterator);
|
|
+ }
|
|
+ ASTOBJ_UNLOCK(iterator);
|
|
+ } while (0));
|
|
+ p=found;
|
|
+
|
|
+ /* fallback to old behavior */
|
|
+ if (p == NULL) {
|
|
+ p=find_peer(peer, sin, realtime);
|
|
+ }
|
|
+ } /* if */
|
|
+
|
|
+ if (!p && realtime)
|
|
+ p = realtime_peer(peer, sin);
|
|
+
|
|
+ return p;
|
|
+}
|
|
+
|
|
/*! \brief Remove user object from in-memory storage */
|
|
static void sip_destroy_user(struct sip_user *user)
|
|
{
|
|
@@ -9008,6 +9043,7 @@
|
|
struct sip_user *user = NULL;
|
|
struct sip_peer *peer;
|
|
char from[256], *c;
|
|
+ char to[256], *ot; /*&&&*/
|
|
char *of;
|
|
char rpid_num[50];
|
|
const char *rpid;
|
|
@@ -9024,8 +9060,29 @@
|
|
t++;
|
|
*t = '\0';
|
|
ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */
|
|
- if (pedanticsipchecking)
|
|
+ if (pedanticsipchecking)
|
|
ast_uri_decode(from);
|
|
+
|
|
+ /*&&&start: extract To: username from To field */
|
|
+ ast_copy_string(to, get_header(req, "To"), sizeof(to)); /* &&& */
|
|
+ if (pedanticsipchecking) {
|
|
+ ast_uri_decode(to); /*&&&*/
|
|
+ }
|
|
+ ot = get_in_brackets(to);
|
|
+ if (strncasecmp(ot, "sip:", 4)) {
|
|
+ ast_log(LOG_NOTICE, "To address missing 'sip:', using it anyway\n");
|
|
+ } else {
|
|
+ ot += 4;
|
|
+ }
|
|
+ /* Get just the username part */
|
|
+ if ((c = strchr(ot, '@'))) {
|
|
+ *c = '\0';
|
|
+ if ((c = strchr(ot, ':')))
|
|
+ *c = '\0';
|
|
+ }
|
|
+ /* ot is now the username of the From field */
|
|
+ /*&&&end */
|
|
+
|
|
/* XXX here tries to map the username for invite things */
|
|
memset(calleridname, 0, sizeof(calleridname));
|
|
get_calleridname(from, calleridname, sizeof(calleridname));
|
|
@@ -9184,9 +9241,22 @@
|
|
/* If peer is registered from this IP address or have this as a default
|
|
IP address, this call is from the peer
|
|
*/
|
|
- peer = find_peer(NULL, &p->recv, 1);
|
|
+/*&&& Original code is weak behavior. Lookup must be done viy SIP header data,
|
|
+ then - if all this fails - I may do the lookup via sender IP address.
|
|
+ Imagine different 2 account registered at the same provider - a lookup
|
|
+ purely based on sende IP address will mess up the matching between these
|
|
+ two accounts.
|
|
+*/
|
|
+ peer = find_peer_siphead(NULL, &p->recv, ot, 1);
|
|
|
|
if (peer) {
|
|
+ /*&&&*/
|
|
+ if (debug) {
|
|
+ ast_verbose("Found matching peer for '%s:%d [%s]'\n",
|
|
+ ast_inet_ntoa(p->recv.sin_addr),
|
|
+ ntohs(p->recv.sin_port), peer->name);
|
|
+ }
|
|
+
|
|
/* Set Frame packetization */
|
|
if (p->rtp) {
|
|
ast_rtp_codec_setpref(p->rtp, &peer->prefs);
|
|
@@ -14920,6 +14990,7 @@
|
|
int lockretry;
|
|
|
|
memset(&req, 0, sizeof(req));
|
|
+ memset(&sin, 0, sizeof(sin)); /*&&& just to be sure...*/
|
|
res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
|
|
if (res < 0) {
|
|
#if !defined(__FreeBSD__)
|