registration.c File Reference


Detailed Description

Proxy-CSCF -Registration Related Operations.

Author:
Dragos Vingarzan vingarzan -at- fokus dot fraunhofer dot de

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_slotregistrar
 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}


Function Documentation

int P_add_path ( struct sip_msg *  msg,
char *  str1,
char *  str2 
)

Inserts the Path header.

Path: <sip:term@pcscf.name.com;lr>

Parameters:
msg - the SIP message to add to
str1 - not used
str2 - not used
Returns:
CSCF_RETURN_TRUE if ok or CSCF_RETURN_FALSE on error

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

Parameters:
msg - the SIP message to add to
str1 - not used
str2 - not used
Returns:
CSCF_RETURN_TRUE if ok or CSCF_RETURN_FALSE on error

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:.

Parameters:
msg - the SIP message to add to
str1 - not used
str2 - not used
Returns:
CSCF_RETURN_TRUE if ok or CSCF_RETURN_FALSE on error

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.

Parameters:
msg - the SIP to check
str1 - the realm to look into
str2 - not used
Returns:
CSCF_RETURN_TRUE if ok, CSCF_RETURN_FALSE if no auth header found or CSCF_RETURN_FALSE on error

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.

Parameters:
msg - the SIP message to add to
str1 - the value to insert into integrity protected: ["yes","no"]
str2 - not used
Returns:
CSCF_RETURN_TRUE if ok, CSCF_RETURN_FALSE if no auth header found or CSCF_RETURN_FALSE on error

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.

Parameters:
msg - the SIP message to add to
str1 - the value to insert - !!! quoted if needed
str2 - not used
Returns:
CSCF_RETURN_TRUE if okor CSCF_RETURN_FALSE on error

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.

Parameters:
msg - the SIP reply message to remove from
str1 - not used
str2 - not used
Returns:
CSCF_RETURN_TRUE if ok, CSCF_RETURN_FALSE if no auth header found or CSCF_RETURN_FALSE on error

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.

Parameters:
msg - the SIP message
str1 - the realm to look into
str2 - not used
Returns:
CSCF_RETURN_TRUE if registered, CSCF_RETURN_FALSE if not

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.

Parameters:
msg - the SIP message
str1 - the realm to look into
str2 - not used
Returns:
CSCF_RETURN_TRUE if asseted, CSCF_RETURN_FALSE if not, CSCF_RETURN_ERROR on error

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.

Parameters:
rpl - the SIP response message
str1 - not used
str2 - not used
Returns:
CSCF_RETURN_TRUE if asseted, CSCF_RETURN_FALSE if not, CSCF_RETURN_ERROR on error

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

Parameters:
msg - the SIP message
str1 - not used
str2 - not used
Returns:
CSCF_RETURN_TRUE if ok, CSCF_RETURN_FALSE if not

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

Parameters:
msg - the SIP message
str1 - not used
str2 - not used
Returns:
CSCF_RETURN_TRUE if terminating case, CSCF_RETURN_FALSE if not

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 
)

Deprecated:
Removes header pointing to itself.
Parameters:
msg - the SIP message
str1 - if not empty, will look and remove this value instead
str2 - not used
Returns:
CSCF_RETURN_TRUE if ok, CSCF_RETURN_FALSE if not

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.

Parameters:
msg - the SIP message
str1 - the realm to look into for the user
str2 - not used
Returns:
CSCF_RETURN_TRUE if ok, CSCF_RETURN_FALSE if not

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.

Parameters: