Module: sip-router
Branch: master
Commit: eec712826c17ba8270e35033d608781ce74940d5
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=eec7128…
Author: Carsten Bock <carsten(a)ng-voice.com>
Committer: Carsten Bock <carsten(a)ng-voice.com>
Date: Wed Sep 10 10:39:34 2014 +0200
ims_registrar_pcscf: Optimization: fallback2ip can be set to "2", in order to
check for the source IP first, before checking the contact-host of the request.
---
modules/ims_registrar_pcscf/service_routes.c | 129 ++++++++++++++++----------
1 files changed, 78 insertions(+), 51 deletions(-)
diff --git a/modules/ims_registrar_pcscf/service_routes.c
b/modules/ims_registrar_pcscf/service_routes.c
index 17328de..d348bba 100644
--- a/modules/ims_registrar_pcscf/service_routes.c
+++ b/modules/ims_registrar_pcscf/service_routes.c
@@ -107,6 +107,52 @@ static inline int find_next_route(struct sip_msg* _m, struct
hdr_field** _hdr)
return 0;
}
+int checkcontact(struct sip_msg* _m, pcontact_t * c) {
+ int security_server_port = -1;
+ str received_host = {0, 0};
+ char srcip[50];
+
+ if (c->security) {
+ switch (c->security->type) {
+ case SECURITY_IPSEC:
+ security_server_port = c->security->data.ipsec->port_uc;
+ break;
+ case SECURITY_TLS:
+ case SECURITY_NONE:
+ break;
+ }
+ } else if (c->security_temp) {
+ switch (c->security->type) {
+ case SECURITY_IPSEC:
+ security_server_port = c->security->data.ipsec->port_uc;
+ break;
+ case SECURITY_TLS:
+ case SECURITY_NONE:
+ break;
+ }
+ }
+
+ if ((c->reg_state == PCONTACT_REGISTERED)
+ && (ignore_contact_rxport_check || (c->received_port ==
_m->rcv.src_port) || (security_server_port == _m->rcv.src_port))
+ && (ignore_contact_rxport_check||(c->received_proto ==
_m->rcv.proto))) {
+
+ received_host.len = ip_addr2sbuf(&_m->rcv.src_ip, srcip, sizeof(srcip));
+ received_host.s = srcip;
+ LM_DBG("Received host len %d (search %d)\n", c->received_host.len,
received_host.len);
+ // Then check the length:
+ if (c->received_host.len == received_host.len) {
+ LM_DBG("Received host %.*s (search %.*s)\n",
+ c->received_host.len, c->received_host.s,
+ received_host.len, received_host.s);
+
+ // Finally really compare the "received_host"
+ if (!memcmp(c->received_host.s, received_host.s, received_host.len))
+ return 0;
+ }
+ }
+ return 1;
+}
+
/**
* get PContact-Structure for message
* (search only once per Request)
@@ -114,73 +160,49 @@ static inline int find_next_route(struct sip_msg* _m, struct
hdr_field** _hdr)
pcontact_t * getContactP(struct sip_msg* _m, udomain_t* _d) {
ppublic_t * p;
contact_body_t *b = 0;
- str received_host = {0, 0};
contact_t *ct;
- char srcip[50];
- int security_server_port = -1;
if (_m->id != current_msg_id) {
current_msg_id = _m->id;
c = NULL;
- b = cscf_parse_contacts(_m);
+ if (is_registered_fallback2ip == 2) {
+ received_host.len = ip_addr2sbuf(&_m->rcv.src_ip, srcip, sizeof(srcip));
+ received_host.s = srcip;
+ if (ul.get_pcontact_by_src(_d, &received_host, _m->rcv.src_port,
_m->rcv.proto, &c) == 1)
+ LM_DBG("No entry in usrloc for %.*s:%i (Proto %i) found!\n",
received_host.len, received_host.s, _m->rcv.src_port, _m->rcv.proto);
+ if (checkcontact(_m, c) != 0) {
+ c = NULL;
+ }
+ }
+
+ if (c == NULL) {
+ b = cscf_parse_contacts(_m);
- if (b && b->contacts) {
- for (ct = b->contacts; ct; ct = ct->next) {
- if (ul.get_pcontact(_d, &ct->uri, &c) == 0) {
- if (c->security) {
- switch (c->security->type) {
- case SECURITY_IPSEC:
- security_server_port = c->security->data.ipsec->port_uc;
- break;
- case SECURITY_TLS:
- case SECURITY_NONE:
- break;
- }
- } else if (c->security_temp) {
- switch (c->security->type) {
- case SECURITY_IPSEC:
- security_server_port = c->security->data.ipsec->port_uc;
+ if (b && b->contacts) {
+ for (ct = b->contacts; ct; ct = ct->next) {
+ if (ul.get_pcontact(_d, &ct->uri, &c) == 0) {
+ if (checkcontact(_m, c) == 0) {
break;
- case SECURITY_TLS:
- case SECURITY_NONE:
- break;
- }
- }
-
- if ((c->reg_state == PCONTACT_REGISTERED)
- && (ignore_contact_rxport_check
|| (c->received_port == _m->rcv.src_port) || (security_server_port ==
_m->rcv.src_port))
- &&
(ignore_contact_rxport_check||(c->received_proto == _m->rcv.proto))) {
-
- received_host.len = ip_addr2sbuf(&_m->rcv.src_ip, srcip, sizeof(srcip));
- received_host.s = srcip;
- LM_DBG("Received host len %d (search %d)\n", c->received_host.len,
received_host.len);
- // Then check the length:
- if (c->received_host.len == received_host.len) {
- LM_DBG("Received host %.*s (search %.*s)\n",
- c->received_host.len, c->received_host.s,
- received_host.len, received_host.s);
-
- // Finally really compare the "received_host"
- if (!memcmp(c->received_host.s, received_host.s, received_host.len))
- break;
+ } else {
c = NULL;
}
- } else {
- c = NULL;
}
}
+ } else {
+ LM_WARN("No contact-header found?!?\n");
}
- } else {
- LM_WARN("No contact-header found\n");
}
- if ((c == NULL) && (is_registered_fallback2ip > 0)) {
- LM_WARN("Contact not found based on Contact-header, trying
IP/Port/Proto\n");
+ if ((c == NULL) && (is_registered_fallback2ip == 1)) {
+ LM_INFO("Contact not found based on Contact-header, trying
IP/Port/Proto\n");
received_host.len = ip_addr2sbuf(&_m->rcv.src_ip, srcip, sizeof(srcip));
received_host.s = srcip;
if (ul.get_pcontact_by_src(_d, &received_host, _m->rcv.src_port,
_m->rcv.proto, &c) == 1)
LM_DBG("No entry in usrloc for %.*s:%i (Proto %i) found!\n",
received_host.len, received_host.s, _m->rcv.src_port, _m->rcv.proto);
+ if (checkcontact(_m, c) != 0) {
+ c = NULL;
+ }
}
}
asserted_identity = NULL;
@@ -327,10 +349,12 @@ error:
return -1;
}
-static str route_start={"Route: <",8};
+static str route_start={": <",8};
static str route_sep={">, <",4};
static str route_end={">\r\n",3};
+extern str route_header;
+
/**
* Force Service routes (upon request)
*/
@@ -348,7 +372,7 @@ int force_service_routes(struct sip_msg* _m, udomain_t* _d) {
/* we need to be sure we have seen all HFs */
parse_headers(_m, HDR_EOH_F, 0);
- /* Savbe current buffer */
+ /* Save current buffer */
buf = _m->buf;
// Delete old Route headers:
@@ -381,7 +405,9 @@ int force_service_routes(struct sip_msg* _m, udomain_t* _d) {
goto error;
}
/* Calculate the length: */
- new_route_header.len = route_start.len + route_end.len + (c->num_service_routes-1) *
route_sep.len;
+ new_route_header.len = route_header.len + route_start.len +
+ route_end.len + (c->num_service_routes-1) * route_sep.len;
+
for(i=0; i< c->num_service_routes; i++)
new_route_header.len+=c->service_routes[i].len;
/* Allocate the memory for this new header: */
@@ -393,6 +419,7 @@ int force_service_routes(struct sip_msg* _m, udomain_t* _d) {
/* Construct new header */
new_route_header.len = 0;
+ STR_APPEND(new_route_header, route_header);
STR_APPEND(new_route_header, route_start);
for(i=0; i < c->num_service_routes; i++) {
if (i) STR_APPEND(new_route_header, route_sep);