Definition in file registration.c.
#include <time.h>
#include "registration.h"
#include "../../data_lump.h"
#include "../../mem/mem.h"
#include "../../locking.h"
#include "../tm/tm_load.h"
#include "mod.h"
#include "sip.h"
#include "registrar.h"
#include "registrar_subscribe.h"
#include "ims_pm_pcscf.h"
#include "e2.h"
#include "e2_avp.h"
Go to the source code of this file.
Functions | |
| int | P_add_path (struct sip_msg *msg, char *str1, char *str2) |
| Inserts the Path header. | |
| int | P_add_require (struct sip_msg *msg, char *str1, char *str2) |
| Inserts the Require header. | |
| int | P_add_p_charging_vector (struct sip_msg *msg, char *str1, char *str2) |
| Inserts the P-Charging-Vector header P-Charging-Vector:. | |
| int | P_is_integrity_protected (struct sip_msg *msg, char *str1, char *str2) |
| Finds out if the message was received over a protected IPSec channel. | |
| int | P_add_integrity_protected (struct sip_msg *msg, char *str1, char *str2) |
| Inserts the integrity protected parameter into the Authorization header. | |
| int | P_add_p_visited_network_id (struct sip_msg *msg, char *str1, char *str2) |
| Inserts the P-Visited-Network-ID header or a field inside if it exists. | |
| int | P_remove_ck_ik (struct sip_msg *msg, char *str1, char *str2) |
| Removes the CK and IK keys from the WWW-Authenticate header. | |
| int | P_is_registered (struct sip_msg *msg, char *str1, char *str2) |
| Finds if the message comes from a registered UE at this P-CSCF. | |
| int | P_assert_identity (struct sip_msg *msg, char *str1, char *str2) |
| Asserts the P-Preferred-Identity if registered and inserts the P-Asserted-Identity. | |
| int | P_assert_called_identity (struct sip_msg *rpl, char *str1, char *str2) |
| Asserts the P-Called-Identity. | |
| int | P_process_notification (struct sip_msg *msg, char *str1, char *str2) |
| Process an incoming NOTIFY for the reg event. | |
| int | P_mobile_terminating (struct sip_msg *msg, char *str1, char *str2) |
| Determines if this is the Mobile Terminating case. | |
| int | P_remove_route (struct sip_msg *msg, char *str1, char *str2) |
| int | P_follows_service_routes (struct sip_msg *msg, char *str1, char *str2) |
| Checks if the message follows Service-Route imposed at registration. | |
| int | P_enforce_service_routes (struct sip_msg *msg, char *str1, char *str2) |
| Inserts the Route header containing the Service-Route to be enforced. | |
| int | P_NAT_relay (struct sip_msg *msg, char *str1, char *str2) |
| Forward a message through the NAT pinhole. | |
| int | P_security_relay (struct sip_msg *msg, char *str1, char *str2) |
| Forward a response through the IPSec SA. | |
| int | P_access_network_info (struct sip_msg *req, char *str1, char *str2) |
| Asserts the P-Access-Network-Info. | |
Variables | |
| tm_binds | tmb |
| Structure with pointers to tm funcs. | |
| str | pcscf_name_str |
| fixed SIP URI of this P-CSCF | |
| str | pcscf_path_hdr_str |
| fixed Path header | |
| str | pcscf_path_str |
| fixed Path URI | |
| str | pcscf_icid_value_prefix_str |
| fixed hexadecimal prefix for the icid-value - must be unique on each node | |
| str | pcscf_icid_gen_addr_str |
| fixed address of the generator of the icid-value | |
| str | pcscf_orig_ioi_str |
| fixed name of the Originating network | |
| str | pcscf_term_ioi_str |
| fixed name of the Terminating network | |
| unsigned int * | pcscf_icid_value_count |
| to keep the number of generated icid-values | |
| gen_lock_t * | pcscf_icid_value_count_lock |
| to lock acces on the above counter | |
| r_hash_slot * | registrar |
| the contacts | |
| int | r_hash_size |
| records tables parameters | |
| int | pcscf_nat_enable |
| whether to enable NAT | |
| int | pcscf_use_ipsec |
| whether to use or not ipsec | |
| int | pcscf_use_tls |
| whether to use or not TLS | |
| int | pcscf_tls_port |
| PORT for TLS server. | |
| cdp_binds | cdpb |
| Structure with pointers to cdp funcs. | |
| int | pcscf_use_e2 |
| if to enable usage of e2 or not | |
| static str | require_hdr = {"Require: path\r\n",15} |
| static str | authorization_s = {"Authorization: ",15} |
| static str | authorization_e = {"\r\n",2} |
| static str | integrity_protected_s = {", integrity-protected=\"",23} |
| static str | integrity_protected_e = {"\"",1} |
| static str | p_visited_network_id_s = {"P-Visited-Network-ID: ",22} |
| static str | p_visited_network_id_1 = {", ",2} |
| static str | p_visited_network_id_e = {"\r\n",2} |
| static str | ck = {"ck=\"",4} |
| static str | ik = {"ik=\"",4} |
| static str | authenticate_s = {"WWW-Authenticate: ",18} |
| static str | authenticate_e = {"\r\n",2} |
| static str | p_asserted_identity_s = {"P-Asserted-Identity: ",21} |
| static str | p_asserted_identity_m = {"<",1} |
| static str | p_asserted_identity_e = {">\r\n",3} |
| static str | reginfo = {"application/reginfo+xml",23} |
| static str | route_s = {"Route: <",8} |
| static str | route_1 = {">, <",4} |
| static str | route_e = {">\r\n",3} |
| static str | sip_s = {"sip:",4} |
| static str | str_a_location_info = {"; dsl-location=",15} |
| static str | str_p_access_network_info = {"P-Access-Network-Info",21} |
| int P_add_path | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Inserts the Path header.
Path: <sip:term@pcscf.name.com;lr>
| msg | - the SIP message to add to | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 104 of file registration.c.
References cscf_add_header(), CSCF_RETURN_ERROR, CSCF_RETURN_TRUE, pcscf_path_hdr_str, and STR_PKG_DUP.
00105 { 00106 str x={0,0}; 00107 00108 STR_PKG_DUP(x,pcscf_path_hdr_str,"pkg"); 00109 if (!x.s) return CSCF_RETURN_ERROR; 00110 if (cscf_add_header(msg,&x,HDR_OTHER_T)) return CSCF_RETURN_TRUE; 00111 else { 00112 pkg_free(x.s); 00113 return CSCF_RETURN_ERROR; 00114 } 00115 out_of_memory: 00116 return CSCF_RETURN_ERROR; 00117 }
| int P_add_require | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Inserts the Require header.
Require: path
| msg | - the SIP message to add to | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 129 of file registration.c.
References cscf_add_header(), CSCF_RETURN_ERROR, CSCF_RETURN_TRUE, require_hdr, and STR_PKG_DUP.
00130 { 00131 str x={0,0}; 00132 00133 STR_PKG_DUP(x,require_hdr,"pkg"); 00134 if (!x.s) return CSCF_RETURN_ERROR; 00135 if (cscf_add_header(msg,&x,HDR_OTHER_T)) return CSCF_RETURN_TRUE; 00136 else { 00137 pkg_free(x.s); 00138 return CSCF_RETURN_ERROR; 00139 } 00140 out_of_memory: 00141 return CSCF_RETURN_ERROR; 00142 }
| int P_add_p_charging_vector | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Inserts the P-Charging-Vector header P-Charging-Vector:.
| msg | - the SIP message to add to | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 153 of file registration.c.
References cscf_add_p_charging_vector().
00154 { 00155 return cscf_add_p_charging_vector(msg); 00156 }
| int P_is_integrity_protected | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Finds out if the message was received over a protected IPSec channel.
| msg | - the SIP to check | |
| str1 | - the realm to look into | |
| str2 | - not used |
Definition at line 166 of file registration.c.
References cscf_get_ue_via(), CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, get_tls_session_hash, M_NAME, pcscf_tls_port, pcscf_use_tls, and r_is_integrity_protected().
00167 { 00168 int ret=CSCF_RETURN_FALSE; 00169 struct via_body *vb; 00170 unsigned long s_hash = 0; 00171 00172 00173 LOG(L_DBG,"DBG:"M_NAME":P_is_integrity_protected: Looking if registered\n"); 00174 // print_r(L_INFO); 00175 00176 vb = cscf_get_ue_via(msg); 00177 00178 LOG(L_DBG,"DBG:"M_NAME":P_is_integrity_protected: Looking for <%d://%.*s:%d,%d>\n", 00179 vb->proto,vb->host.len,vb->host.s,vb->port,msg->rcv.src_port); 00180 if (pcscf_use_tls && msg->rcv.dst_port == pcscf_tls_port){ 00181 s_hash = get_tls_session_hash(msg); 00182 if (!s_hash){ 00183 LOG(L_ERR,"ERR:"M_NAME":P_is_integrity_protected: Session Hash could not be obtained !\n"); 00184 return CSCF_RETURN_FALSE; 00185 } 00186 } 00187 if (r_is_integrity_protected(vb->host,vb->port,msg->rcv.src_port,vb->proto, s_hash)) 00188 ret = CSCF_RETURN_TRUE; 00189 else 00190 ret = CSCF_RETURN_FALSE; 00191 00192 return ret; 00193 }
| int P_add_integrity_protected | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Inserts the integrity protected parameter into the Authorization header.
| msg | - the SIP message to add to | |
| str1 | - the value to insert into integrity protected: ["yes","no"] | |
| str2 | - not used |
Definition at line 207 of file registration.c.
References cscf_get_authorization(), CSCF_RETURN_FALSE, if, integrity_protected_s, and M_NAME.
00208 { 00209 int r = CSCF_RETURN_FALSE; 00210 str x={0,0}; 00211 str v={0,0}; 00212 str auth; 00213 int i; 00214 int s=0,e=0; 00215 struct hdr_field *hdr; 00216 00217 v.s = str1; 00218 v.len = strlen(str1); 00219 00220 auth = cscf_get_authorization(msg,&hdr); 00221 if (!auth.len){ 00222 LOG(L_INFO,"INF:"M_NAME":P_add_integrity_protected: No authorization header found.\n"); 00223 goto done; 00224 } 00225 00226 s=auth.len;e=auth.len; 00227 /* first we look for it */ 00228 for(i=0;i<auth.len-integrity_protected_s.len;i++) 00229 if (strncasecmp(auth.s+i,integrity_protected_s.s,integrity_protected_s.len)==0){ 00230 s = i; 00231 e = i+integrity_protected_s.len; 00232 while(e<auth.len && auth.s[e]!='\"') 00233 e++; 00234 if (e<auth.len) e++; 00235 break; 00236 } 00237 x.len = authorization_s.len+ 00238 auth.len - (e-s)+ 00239 integrity_protected_s.len+v.len+integrity_protected_e.len+ 00240 authorization_e.len; 00241 x.s = pkg_malloc(x.len); 00242 if (!x.s){ 00243 LOG(L_ERR, "ERR"M_NAME":P_add_integrity_protected: Error allocating %d bytes\n", 00244 x.len); 00245 x.len=0; 00246 goto error; 00247 } 00248 x.len=0; 00249 00250 STR_APPEND(x,authorization_s); 00251 memcpy(x.s+x.len,auth.s,s); 00252 x.len += s; 00253 STR_APPEND(x,integrity_protected_s); 00254 STR_APPEND(x,v); 00255 STR_APPEND(x,integrity_protected_e); 00256 memcpy(x.s+x.len,auth.s+e,auth.len-e); 00257 x.len += auth.len-e; 00258 STR_APPEND(x,authorization_e); 00259 00260 if (cscf_add_header(msg,&x,HDR_OTHER_T)) r = CSCF_RETURN_TRUE; 00261 else goto error; 00262 00263 00264 if (!cscf_del_header(msg,hdr)){ 00265 LOG(L_INFO,"INF:"M_NAME":P_add_integrity_protected: Error dropping old authorization header.\n"); 00266 goto error; 00267 } 00268 00269 done: 00270 return r; 00271 error: 00272 r = CSCF_RETURN_ERROR; 00273 if (x.s) pkg_free(x.s); 00274 return r; 00275 }
| int P_add_p_visited_network_id | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Inserts the P-Visited-Network-ID header or a field inside if it exists.
| msg | - the SIP message to add to | |
| str1 | - the value to insert - !!! quoted if needed | |
| str2 | - not used |
Definition at line 289 of file registration.c.
References cscf_add_header(), cscf_del_header(), cscf_get_visited_network_id(), CSCF_RETURN_ERROR, CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, M_NAME, and require_hdr.
00290 { 00291 int r = CSCF_RETURN_FALSE; 00292 str x={0,0}; 00293 str v={0,0}; 00294 str old={0,0}; 00295 struct hdr_field *hdr; 00296 00297 v.s = str1; 00298 v.len = strlen(str1); 00299 00300 old = cscf_get_visited_network_id(msg,&hdr); 00301 00302 x.len = p_visited_network_id_s.len + old.len + v.len + p_visited_network_id_e.len; 00303 if (old.len) x.len+=p_visited_network_id_1.len; 00304 00305 x.s = pkg_malloc(x.len); 00306 if (!x.s){ 00307 LOG(L_ERR, "ERR"M_NAME":P_add_p_visited_network_id: Error allocating %d bytes\n", 00308 require_hdr.len); 00309 x.len=0; 00310 goto error; 00311 } 00312 x.len=0; 00313 memcpy(x.s+x.len,p_visited_network_id_s.s,p_visited_network_id_s.len); 00314 x.len += p_visited_network_id_s.len; 00315 00316 if (old.len) { 00317 memcpy(x.s+x.len,old.s,old.len); 00318 x.len += old.len; 00319 00320 memcpy(x.s+x.len,p_visited_network_id_1.s,p_visited_network_id_1.len); 00321 x.len += p_visited_network_id_1.len; 00322 } 00323 00324 memcpy(x.s+x.len,v.s,v.len); 00325 x.len += v.len; 00326 00327 memcpy(x.s+x.len,p_visited_network_id_e.s,p_visited_network_id_e.len); 00328 x.len += p_visited_network_id_e.len; 00329 00330 00331 if (cscf_add_header(msg,&x,HDR_OTHER_T)) r = CSCF_RETURN_TRUE; 00332 else goto error; 00333 00334 if (!cscf_del_header(msg,hdr)){ 00335 LOG(L_INFO,"INF:"M_NAME":P_add_p_visited_network_id: Error dropping old header.\n"); 00336 goto error; 00337 } 00338 00339 return r; 00340 error: 00341 r = CSCF_RETURN_ERROR; 00342 if (x.s) pkg_free(x.s); 00343 return r; 00344 }
| int P_remove_ck_ik | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Removes the CK and IK keys from the WWW-Authenticate header.
| msg | - the SIP reply message to remove from | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 358 of file registration.c.
References cscf_add_header(), cscf_del_header(), cscf_get_authenticate(), CSCF_RETURN_ERROR, CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, M_NAME, and STR_APPEND.
00359 { 00360 int r = CSCF_RETURN_FALSE; 00361 str auth,x={0,0}; 00362 struct hdr_field *hdr; 00363 int inString = 0; 00364 int mlen,i; 00365 auth = cscf_get_authenticate(msg,&hdr); 00366 if (!auth.len){ 00367 LOG(L_INFO,"INF:"M_NAME":P_remove_ck_ik: No WWW-Authenticate header found.\n"); 00368 goto done; 00369 } 00370 00371 LOG(L_DBG,"DBG:"M_NAME":P_remove_ck_ik: Original: <%.*s>\n", 00372 auth.len,auth.s); 00373 00374 x.s = pkg_malloc(authenticate_s.len+auth.len+authenticate_e.len); 00375 if (!x.s){ 00376 LOG(L_ERR, "ERR"M_NAME":P_remove_ck_ik: Error allocating %d bytes\n", 00377 x.len); 00378 x.len=0; 00379 goto error; 00380 } 00381 x.len=0; 00382 00383 if (ck.len>ik.len) mlen = auth.len - ck.len; 00384 else mlen = auth.len - ik.len; 00385 00386 STR_APPEND(x,authenticate_s); 00387 i=0; 00388 while(i<auth.len){ 00389 if ((auth.s[i] == '\"') &&(i==0||auth.s[i-1]!='\\')) 00390 inString = !inString; 00391 00392 if (!inString && i<mlen && strncasecmp(auth.s+i,ck.s,ck.len)==0){ 00393 i+=ck.len; 00394 while(i<auth.len && auth.s[i]!='\"') 00395 i++; 00396 i++; 00397 while(i<auth.len &&(auth.s[i]==' '||auth.s[i]==','||auth.s[i]=='\t')) 00398 i++; 00399 continue; 00400 } 00401 if (!inString && i<mlen && strncasecmp(auth.s+i,ik.s,ik.len)==0){ 00402 i+=ik.len; 00403 while(i<auth.len && auth.s[i]!='\"') 00404 i++; 00405 i++; 00406 while(i<auth.len &&(auth.s[i]==' '||auth.s[i]==','||auth.s[i]=='\t')) 00407 i++; 00408 continue; 00409 } 00410 x.s[x.len++]=auth.s[i++]; 00411 } 00412 while(x.len>0 && (x.s[x.len-1]==' '||x.s[x.len-1]==','||x.s[x.len-1]=='\t')) 00413 x.len--; 00414 STR_APPEND(x,authenticate_e); 00415 00416 LOG(L_DBG,"DBG:"M_NAME":P_remove_ck_ik: Changed: <%.*s>\n", 00417 x.len,x.s); 00418 00419 if (!cscf_del_header(msg,hdr)){ 00420 LOG(L_INFO,"INF:"M_NAME":P_remove_ck_ik: Error dropping old authorization header.\n"); 00421 goto error; 00422 } 00423 00424 if (cscf_add_header(msg,&x,HDR_OTHER_T)) r = CSCF_RETURN_TRUE; 00425 else goto error; 00426 00427 LOG(L_DBG,"DBG::"M_NAME":P_remove_ck_ik: Final : <%.*s>\n", 00428 x.len,x.s); 00429 00430 done: 00431 return r; 00432 error: 00433 r = CSCF_RETURN_ERROR; 00434 if (x.s) pkg_free(x.s); 00435 return r; 00436 }
| int P_is_registered | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Finds if the message comes from a registered UE at this P-CSCF.
| msg | - the SIP message | |
| str1 | - the realm to look into | |
| str2 | - not used |
Definition at line 448 of file registration.c.
References cscf_get_ue_via(), CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, M_NAME, and r_is_registered().
00449 { 00450 int ret=CSCF_RETURN_FALSE; 00451 struct via_body *vb; 00452 00453 LOG(L_INFO,"DBG:"M_NAME":P_is_registered: Looking if registered\n"); 00454 // print_r(L_INFO); 00455 00456 vb = cscf_get_ue_via(msg); 00457 00458 00459 if (vb->port==0) vb->port=5060; 00460 LOG(L_INFO,"DBG:"M_NAME":P_is_registered: Looking for <%d://%.*s:%d>\n", 00461 vb->proto,vb->host.len,vb->host.s,vb->port); 00462 00463 if (r_is_registered(vb->host,vb->port,vb->proto)) 00464 ret = CSCF_RETURN_TRUE; 00465 else 00466 ret = CSCF_RETURN_FALSE; 00467 00468 return ret; 00469 }
| int P_assert_identity | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Asserts the P-Preferred-Identity if registered and inserts the P-Asserted-Identity.
| msg | - the SIP message | |
| str1 | - the realm to look into | |
| str2 | - not used |
Definition at line 482 of file registration.c.
References cscf_add_header(), cscf_del_header(), cscf_get_preferred_identity(), cscf_get_ue_via(), CSCF_RETURN_ERROR, CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, M_NAME, r_assert_identity(), require_hdr, and STR_APPEND.
00483 { 00484 int ret=CSCF_RETURN_FALSE; 00485 struct via_body *vb; 00486 struct hdr_field *h=0; 00487 name_addr_t preferred,asserted; 00488 str x={0,0}; 00489 00490 LOG(L_INFO,"INF:"M_NAME":P_assert_identity: Asserting Identity\n"); 00491 // print_r(L_INFO); 00492 00493 vb = cscf_get_ue_via(msg); 00494 00495 preferred = cscf_get_preferred_identity(msg,&h); 00496 00497 LOG(L_INFO,"DBG:"M_NAME":P_assert_identity: Looking for <%d://%.*s:%d> Pref: %.*s\n", 00498 vb->proto,vb->host.len,vb->host.s,vb->port, 00499 preferred.len,preferred.name.s); 00500 00501 asserted = r_assert_identity(vb->host,vb->port,vb->proto,preferred); 00502 if (!asserted.uri.len){ 00503 ret = CSCF_RETURN_FALSE; 00504 }else{ 00505 cscf_del_header(msg,h); 00506 x.len = p_asserted_identity_s.len+asserted.name.len+p_asserted_identity_m.len + 00507 asserted.uri.len+p_asserted_identity_e.len; 00508 x.s = pkg_malloc(x.len); 00509 if (!x.s){ 00510 LOG(L_ERR, "ERR"M_NAME":P_assert_identity: Error allocating %d bytes\n", 00511 require_hdr.len); 00512 x.len=0; 00513 goto error; 00514 } 00515 x.len=0; 00516 STR_APPEND(x,p_asserted_identity_s); 00517 STR_APPEND(x,asserted.name); 00518 STR_APPEND(x,p_asserted_identity_m); 00519 STR_APPEND(x,asserted.uri); 00520 STR_APPEND(x,p_asserted_identity_e); 00521 00522 if (cscf_add_header(msg,&x,HDR_OTHER_T)) 00523 ret = CSCF_RETURN_TRUE; 00524 else 00525 ret = CSCF_RETURN_FALSE; 00526 } 00527 00528 00529 return ret; 00530 error: 00531 ret=CSCF_RETURN_ERROR; 00532 return ret; 00533 }
| int P_assert_called_identity | ( | struct sip_msg * | rpl, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Asserts the P-Called-Identity.
| rpl | - the SIP response message | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 542 of file registration.c.
References cscf_add_header(), cscf_del_header(), cscf_get_called_party_id(), cscf_get_preferred_identity(), cscf_get_request_from_reply(), CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, M_NAME, require_hdr, and STR_APPEND.
00543 { 00544 int ret=CSCF_RETURN_FALSE; 00545 struct hdr_field *h=0; 00546 str called={0,0},x={0,0}; 00547 struct sip_msg *req = cscf_get_request_from_reply(rpl); 00548 00549 LOG(L_INFO,"INF:"M_NAME":P_assert_called_identity: Asserting Identity\n"); 00550 00551 cscf_get_preferred_identity(rpl,&h); 00552 cscf_del_header(rpl,h); 00553 00554 if (!req){ 00555 LOG(L_INFO,"INF:"M_NAME":P_assert_called_identity: Error finding correspondent request.\n"); 00556 goto error; 00557 } 00558 00559 called = cscf_get_called_party_id(req,&h); 00560 if (!called.len){ 00561 ret = CSCF_RETURN_FALSE; 00562 }else{ 00563 x.len = p_asserted_identity_s.len+p_asserted_identity_m.len+called.len+p_asserted_identity_e.len; 00564 x.s = pkg_malloc(x.len); 00565 if (!x.s){ 00566 LOG(L_ERR, "ERR"M_NAME":P_assert_called_identity: Error allocating %d bytes\n", 00567 require_hdr.len); 00568 x.len=0; 00569 goto error; 00570 } 00571 x.len=0; 00572 STR_APPEND(x,p_asserted_identity_s); 00573 STR_APPEND(x,p_asserted_identity_m); 00574 STR_APPEND(x,called); 00575 STR_APPEND(x,p_asserted_identity_e); 00576 00577 if (cscf_add_header(rpl,&x,HDR_OTHER_T)) 00578 ret = CSCF_RETURN_TRUE; 00579 else 00580 ret = CSCF_RETURN_FALSE; 00581 } 00582 00583 return ret; 00584 error: 00585 ret=CSCF_RETURN_FALSE; 00586 return ret; 00587 }
| int P_process_notification | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Process an incoming NOTIFY for the reg event.
To be Called when a NOTIFY comes in - checks if for itself. if the NOTIFY is destined for this node, generate an event and respond with 200 OK, and return TRUE. else return FALSE
| msg | - the SIP message | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 601 of file registration.c.
References cscf_get_call_id(), cscf_get_content_len(), cscf_get_content_type(), cscf_get_cseq(), cscf_get_subscription_state(), CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, M_NAME, r_notification_free(), r_notification_parse(), and r_notification_process().
00602 { 00603 int ret=CSCF_RETURN_FALSE; 00604 str content_type,body; 00605 r_notification *n=0; 00606 int expires; 00607 LOG(L_DBG,"DBG:"M_NAME":P_NOTIFY: Checking NOTIFY\n"); 00608 00609 // print_r(L_INFO); 00610 00611 /* check if we received what we should */ 00612 if (msg->first_line.type!=SIP_REQUEST) { 00613 LOG(L_ERR,"ERR:"M_NAME":P_NOTIFY: The message is not a request\n"); 00614 goto error; 00615 } 00616 if (msg->first_line.u.request.method.len!=6|| 00617 memcmp(msg->first_line.u.request.method.s,"NOTIFY",6)!=0) 00618 { 00619 LOG(L_ERR,"ERR:"M_NAME":P_NOTIFY: The method is not a NOTIFY\n"); 00620 goto error; 00621 } 00622 00623 /* update the subscription state */ 00624 expires = cscf_get_subscription_state(msg); 00625 /* treat event */ 00626 content_type = cscf_get_content_type(msg); 00627 if (content_type.len==reginfo.len && 00628 strncasecmp(content_type.s,reginfo.s,reginfo.len)==0) 00629 { 00630 body.s = get_body(msg); 00631 if (!body.s){ 00632 LOG(L_ERR,"ERR:"M_NAME":P_NOTIFY: No body extracted\n"); 00633 goto error; 00634 }else{ 00635 body.len = cscf_get_content_len(msg); 00636 LOG(L_DBG,"DBG:"M_NAME":P_NOTIFY: Found body: %.*s\n", 00637 body.len,body.s); 00638 n = r_notification_parse(body); 00639 if (!n){ 00640 LOG(L_DBG,"DBG:"M_NAME":P_NOTIFY: Error parsing XML\n"); 00641 }else { 00642 #ifdef WITH_IMS_PM 00643 ims_pm_notify_reg(n,cscf_get_call_id(msg,0),cscf_get_cseq(msg,0)); 00644 #endif 00645 if (r_notification_process(n,expires)) 00646 ret = CSCF_RETURN_TRUE; 00647 r_notification_free(n); 00648 } 00649 } 00650 }else{ 00651 LOG(L_ERR,"ERR:"M_NAME":P_NOTIFY: The content should be %.*s but it is %.*s\n", 00652 reginfo.len,reginfo.s,content_type.len,content_type.s); 00653 goto error; 00654 } 00655 00656 00657 return ret; 00658 error: 00659 ret=CSCF_RETURN_FALSE; 00660 return ret; 00661 }
| int P_mobile_terminating | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Determines if this is the Mobile Terminating case.
uses the indication in the first Route header
| msg | - the SIP message | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 672 of file registration.c.
References cscf_get_first_route(), CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, M_NAME, and pcscf_path_str.
00673 { 00674 int ret=CSCF_RETURN_FALSE; 00675 str route={0,0}; 00676 int i; 00677 00678 route = cscf_get_first_route(msg,0); 00679 if (!route.len){ 00680 LOG(L_DBG,"DBG:"M_NAME":P_mobile_terminating: No Route header.\n"); 00681 goto done; 00682 } 00683 i=0; 00684 while(i<route.len && (route.s[i]==' ' ||route.s[i]=='\t'||route.s[i]=='<')) 00685 i++; 00686 route.s += i; 00687 route.len -= i; 00688 i=0; 00689 while(route.s[i]!=';' && route.s[i]!='>' && i<route.len) 00690 i++; 00691 route.len = i; 00692 00693 if (route.len == pcscf_path_str.len && 00694 strncasecmp(route.s,pcscf_path_str.s,pcscf_path_str.len)==0) 00695 { 00696 LOG(L_DBG,"DBG:"M_NAME":P_mobile_terminating: Term indication found.\n"); 00697 ret = CSCF_RETURN_TRUE; 00698 goto done; 00699 }else{ 00700 LOG(L_DBG,"DBG:"M_NAME":P_mobile_terminating: Term indication not found in <%.*s> as <%.*s>.\n", 00701 route.len,route.s,pcscf_path_str.len,pcscf_path_str.s); 00702 } 00703 00704 00705 done: 00706 return ret; 00707 }
| int P_remove_route | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
| msg | - the SIP message | |
| str1 | - if not empty, will look and remove this value instead | |
| str2 | - not used |
Definition at line 718 of file registration.c.
References cscf_remove_first_route(), CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, pcscf_name_str, and pcscf_path_str.
00719 { 00720 int ret=CSCF_RETURN_FALSE; 00721 str x; 00722 00723 if (str1 && strlen(str1)){ 00724 x.s = str1; 00725 x.len =strlen(str1); 00726 if (cscf_remove_first_route(msg,x)) 00727 ret = CSCF_RETURN_TRUE; 00728 else 00729 ret = CSCF_RETURN_FALSE; 00730 }else{ 00731 if (cscf_remove_first_route(msg,pcscf_path_str)+cscf_remove_first_route(msg,pcscf_name_str)) 00732 ret = CSCF_RETURN_TRUE; 00733 else 00734 ret = CSCF_RETURN_FALSE; 00735 } 00736 00737 return ret; 00738 }
| int P_follows_service_routes | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Checks if the message follows Service-Route imposed at registration.
| msg | - the SIP message | |
| str1 | - the realm to look into for the user | |
| str2 | - not used |
Definition at line 749 of file registration.c.
References cscf_get_next_route(), cscf_get_ue_via(), CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, get_r_contact(), _r_contact::hash, if, M_NAME, r_unlock(), _r_contact::service_route, and _r_contact::service_route_cnt.
00750 { 00751 int i; 00752 struct hdr_field *hdr=0; 00753 rr_t *r; 00754 struct via_body *vb; 00755 r_contact *c; 00756 struct sip_uri uri; 00757 00758 vb = cscf_get_ue_via(msg); 00759 00760 if (vb->port==0) vb->port=5060; 00761 c = get_r_contact(vb->host,vb->port,vb->proto); 00762 if (!c) return CSCF_RETURN_FALSE; 00763 00764 hdr = cscf_get_next_route(msg,0); 00765 r = 0; 00766 if (!hdr){ 00767 if (c->service_route_cnt==0) 00768 goto ok; 00769 else 00770 goto nok; 00771 } 00772 r = (rr_t*) hdr->parsed; 00773 /* first let's skip route pointing to myself */ 00774 if (r&&parse_uri(r->nameaddr.uri.s, r->nameaddr.uri.len, &uri)==0 && 00775 check_self(&uri.host,uri.port_no?uri.port_no:SIP_PORT,0)) 00776 { 00777 r = r->next; 00778 if (!r) { 00779 hdr = cscf_get_next_route(msg,hdr); 00780 if (!hdr){ 00781 if (c->service_route_cnt==0) 00782 goto ok; 00783 else 00784 goto nok; 00785 } 00786 r = (rr_t*) hdr->parsed; 00787 } 00788 } 00789 /* then check the others */ 00790 00791 for(i=0;i<c->service_route_cnt;i++){ 00792 LOG(L_DBG,"DBG:"M_NAME":P_follows_service_route: mst %.*s\n", 00793 c->service_route[i].len,c->service_route[i].s); 00794 if (!r) { 00795 hdr = cscf_get_next_route(msg,hdr); 00796 if (!hdr) 00797 goto nok; 00798 r = (rr_t*) hdr->parsed; 00799 } 00800 LOG(L_DBG,"DBG:"M_NAME":P_follows_service_route: src %.*s\n", 00801 r->nameaddr.uri.len,r->nameaddr.uri.s); 00802 if (r->nameaddr.uri.len==c->service_route[i].len && 00803 strncasecmp(r->nameaddr.uri.s, 00804 c->service_route[i].s,c->service_route[i].len)==0) 00805 { 00806 LOG(L_DBG,"DBG:"M_NAME":P_follows_service_route: src match\n"); 00807 } 00808 else goto nok; 00809 00810 r = r->next; 00811 } 00812 if (r) goto nok; 00813 else 00814 if (cscf_get_next_route(msg,hdr)) goto nok; 00815 00816 ok: 00817 if (c) r_unlock(c->hash); 00818 return CSCF_RETURN_TRUE; 00819 nok: 00820 if (c) r_unlock(c->hash); 00821 return CSCF_RETURN_FALSE; 00822 }
| int P_enforce_service_routes | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Inserts the Route header containing the Service-Route to be enforced.