/** * Registers tm callback to apply privacy to replies. * @param msg - the SIP message * @param str1 - not used * @param str2 - not used * @returns #CSCF_RETURN_TRUE */ int S_privacy_hook(struct sip_msg* msg, char* str1, char* str2) { unsigned int a,b; cscf_get_transaction(msg,&a,&b); #ifdef SER_MOD_INTERFACE tmb.register_tmcb(msg,0,TMCB_RESPONSE_IN,privacy_reply_cb,0,0); #else tmb.register_tmcb(msg,0,TMCB_RESPONSE_IN,privacy_reply_cb,0); #endif return CSCF_RETURN_TRUE; }
/** * Forwards the message to the application server. * - Marks the message * - fills routes * - replaces dst_uri * @param msg - the SIP message * @param m - the isc_match that matched with info about where to forward it * @param mark - the isc_mark that should be used to mark the message * @returns #ISC_RETURN_TRUE if OK, #ISC_RETURN_ERROR if not */ int isc_forward( struct sip_msg *msg, isc_match *m,isc_mark *mark) { struct cell *t; unsigned int hash,label; ticks_t fr_timeout,fr_inv_timeout; DBG( "DEBUG:"M_NAME":isc_forward(): marking for AS <%.*s>\n", m->server_name.len, m->server_name.s ); isc_mark_set(msg,m,mark); /* change destination so it forwards to the app server */ if (msg->dst_uri.s) pkg_free(msg->dst_uri.s); msg->dst_uri.s = pkg_malloc(m->server_name.len); if (!msg->dst_uri.s) { LOG(L_ERR,"ERR:"M_NAME":isc_forward(): error allocating %d bytes\n",m->server_name.len); return ISC_RETURN_ERROR; } msg->dst_uri.len = m->server_name.len; memcpy(msg->dst_uri.s,m->server_name.s,m->server_name.len); /* append branch if last trigger failed */ if (*isc_tmb.route_mode == MODE_ONFAILURE) append_branch(msg,msg->first_line.u.request.uri.s,msg->first_line.u.request.uri.len, msg->dst_uri.s,msg->dst_uri.len,0,0); /* set the timeout timers to a lower value */ cscf_get_transaction(msg,&hash,&label); t = isc_tmb.t_gett(); fr_timeout = t->fr_timeout; fr_inv_timeout = t->fr_inv_timeout; t->fr_timeout=S_TO_TICKS(isc_fr_timeout)/1000; t->fr_inv_timeout=S_TO_TICKS(isc_fr_inv_timeout)/1000; /* send it */ isc_tmb.t_relay(msg,0,0); /* recover the timeouts */ t->fr_timeout=fr_timeout; t->fr_inv_timeout=fr_inv_timeout; LOG(L_INFO,"INFO:"M_NAME">> msg was fwded to AS\n"); // LOG(L_INFO,"INFO:"M_NAME":isc_forward: fw relayed with marking [%8X]\n",rc->mark.cnt); // DBG( "DEBUG:"M_NAME":isc_forward: Forward sending finished, resuming operation\n" ); return ISC_RETURN_TRUE; }
/* Send the OPTIONS response to the E-CSCF * could be used after a LOCSIP NOTIFY is received * @param msg - the OPTIONS request from the ECSCF * @param str1 - not used * @param str2 - not used * @return CSCF_RETURN_TRUE if ok, or CSCF_RETURN_FALSE if error */ int LRF_call_query_resp(struct sip_msg* msg, char*str1, char*str2){ str user_uri; user_d * d= NULL; str service; struct cell * trans = NULL; str resp_body = {0,0}; str headers = {0,0}; unsigned int hash_index, label; LOG(L_INFO, "INFO:"M_NAME":LRF_call_query_resp\n"); if (msg->first_line.u.request.method.len!=7|| memcmp(msg->first_line.u.request.method.s,"OPTIONS",7)!=0){ LOG(L_WARN,"WARN:"M_NAME":LRF_call_query_resp: The method is not an OPTIONS, trying to replace the message\n"); msg = cscf_get_request_from_reply(NULL); if(! msg || msg->first_line.type!=SIP_REQUEST || msg->first_line.u.request.method.len!=7|| memcmp(msg->first_line.u.request.method.s,"OPTIONS",7)!=0){ LOG(L_ERR,"BUG:"M_NAME":LRF_call_query_resp: The new message is not an OPTIONS request either\n"); return CSCF_RETURN_ERROR; } } service = cscf_get_headers_content(msg, service_hdr_name); if(!service.len || !service.s){ LOG(L_ERR, "ERR:"M_NAME":LRF_call_query_resp: could not find the service header in the OPTIONS, or could not be parsed\n"); return CSCF_RETURN_FALSE; } str callid = cscf_get_call_id(msg, NULL); if(!callid.s || !callid.len){ LOG(L_ERR, "ERR:"M_NAME":LRF_get_psap: could not find the callid header in the OPTIONS request\n"); return CSCF_RETURN_FALSE; } user_uri = msg->first_line.u.request.uri; d = get_user_data(user_uri, service, callid); if(!d) { LOG(L_ERR, "ERR:"M_NAME":LRF_call_query_resp: could not found user data for uri %.*s and service %.*s\n", user_uri.len, user_uri.s, service.len, service.s); goto error; } if(!d->psap_uri.len || !d->psap_uri.s){ LOG(L_ERR, "ERR: "M_NAME":LRF_call_query_resp: null psap uri\n"); goto error; } if(d->loc && d->locsip_loc){ LOG(L_DBG, "DBG: "M_NAME":LRF_call_query_resp: LRF has location information from the LOCSIP server\n"); if(get_options_resp_body(&resp_body, d)){ LOG(L_ERR, "ERR:"M_NAME":LRF_call_query_resp:could not get the OPTIONS response body\n"); goto error; } } if(get_options_resp_headers(&headers, d)){ LOG(L_ERR, "ERR:"M_NAME":LRF_call_query_resp:could not get the OPTIONS response headers\n"); goto error; } //get crt trans if(cscf_get_transaction(msg, &hash_index, &label)<0){ LOG(L_ERR, "ERR:"M_NAME":LRF_call_query_resp: could not get the trans from the message\n"); goto error; } if(tmb.t_lookup_ident(&trans, hash_index, label)!=1){ LOG(L_ERR, "ERR:"M_NAME":LRF_call_query_resp: could not get the trans from the hash and index\n"); goto error; } if(tmb.t_reply_with_body(trans, 200, "OK - PSAP found", resp_body.s, headers.s, "lrf" )!= 1){ LOG(L_ERR, "ERR:"M_NAME":LRF_call_query_resp: could not send the response\n"); goto error2; } #ifndef TM_DEL_UNREF LOG(L_ERR, "ERR:"M_NAME":LRF_call_query_resp: options ref count %i\n", trans->ref_count); #endif lrf_unlock(d->hash); if(resp_body.s) pkg_free(resp_body.s); if(headers.s) pkg_free(headers.s); return CSCF_RETURN_TRUE; error2: //tmb.t_unref_ident(trans->hash_index, trans->label); error: LOG(L_DBG, "DBG: "M_NAME":LRF_call_query_resp: error label\n"); if(d) lrf_unlock(d->hash); LOG(L_DBG, "DBG: "M_NAME":LRF_call_query_resp: error label\n"); //if(resp_body.s) pkg_free(resp_body.s); LOG(L_DBG, "DBG: "M_NAME":LRF_call_query_resp: error label\n"); //if(headers.s) pkg_free(headers.s); LOG(L_DBG, "DBG: "M_NAME":LRF_call_query_resp: error label\n"); return CSCF_RETURN_FALSE; }