1 /*
2 * $Id$
3 *
4 * Copyright (C) 2012 Smile Communications, jason.penton@smilecoms.com
5 * Copyright (C) 2012 Smile Communications, richard.good@smilecoms.com
6 *
7 * The initial version of this code was written by Dragos Vingarzan
8 * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
9 * Fruanhofer Institute. It was and still is maintained in a separate
10 * branch of the original SER. We are therefore migrating it to
11 * Kamailio/SR and look forward to maintaining it from here on out.
12 * 2011/2012 Smile Communications, Pty. Ltd.
13 * ported/maintained/improved by
14 * Jason Penton (jason(dot)penton(at)smilecoms.com and
15 * Richard Good (richard(dot)good(at)smilecoms.com) as part of an
16 * effort to add full IMS support to Kamailio/SR using a new and
17 * improved architecture
18 *
19 * NB: Alot of this code was originally part of OpenIMSCore,
20 * FhG Fokus.
21 * Copyright (C) 2004-2006 FhG Fokus
22 * Thanks for great work! This is an effort to
23 * break apart the various CSCF functions into logically separate
24 * components. We hope this will drive wider use. We also feel
25 * that in this way the architecture is more complete and thereby easier
26 * to manage in the Kamailio/SR environment
27 *
28 * This file is part of Kamailio, a free SIP server.
29 *
30 * Kamailio is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version
34 *
35 * Kamailio is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License
41 * along with this program; if not, write to the Free Software
42 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
43 *
44 */
45
46 #include <stdio.h>
47 #include <string.h>
48 #include <stdlib.h>
49 #include <unistd.h>
50 #include "../../core/sr_module.h"
51 #include "../../core/events.h"
52 #include "../../core/dprint.h"
53 #include "../../core/ut.h"
54 #include "../../lib/ims/ims_getters.h"
55 #include "../tm/tm_load.h"
56 #include "../../core/mod_fix.h"
57 #include "../../core/parser/parse_uri.h"
58 #include "../../core/parser/parse_content.h"
59 #include "../ims_usrloc_pcscf/usrloc.h"
60 #include "../../modules/ims_dialog/dlg_load.h"
61 #include "../../modules/ims_dialog/dlg_hash.h"
62 #include "../cdp/cdp_load.h"
63 #include "../cdp_avp/cdp_avp_mod.h"
64 #include "../../core/cfg/cfg_struct.h"
65 #include "cdpeventprocessor.h"
66 #include "rx_authdata.h"
67 #include "rx_asr.h"
68 #include "rx_str.h"
69 #include "rx_aar.h"
70 #include "ims_qos_mod.h"
71 #include "../../core/parser/sdp/sdp.h"
72
73 #include "../../lib/ims/useful_defs.h"
74 #include "ims_qos_stats.h"
75
76 MODULE_VERSION
77
78 extern gen_lock_t* process_lock; /* lock on the process table */
79
80 stat_var* stat_aar_timeouts;
81 stat_var* aar_replies_received;
82 stat_var* aar_replies_response_time;
83
84 str orig_session_key = str_init("originating");
85 str term_session_key = str_init("terminating");
86
87 int rx_auth_expiry = 7200;
88
89 int must_send_str = 1;
90
91 int authorize_video_flow = 1; //by default we authorize resources for video flow descriptions
92
93 struct tm_binds tmb;
94 struct cdp_binds cdpb;
95 ims_dlg_api_t dlgb;
96 bind_usrloc_t bind_usrloc;
97 cdp_avp_bind_t *cdp_avp;
98 usrloc_api_t ul;
99
100 int cdp_event_latency = 1; /*flag: report slow processing of CDP callback events or not - default enabled */
101 int cdp_event_threshold = 500; /*time in ms above which we should report slow processing of CDP callback event - default 500ms*/
102 int cdp_event_latency_loglevel = 0; /*log-level to use to report slow processing of CDP callback event - default ERROR*/
103
104 int audio_default_bandwidth = 64;
105 int video_default_bandwidth = 128;
106
107 //If set then any IP in SDP that does not match this regex then filter is added with any in flow description AVP
108 //Very useful for UEs that change ports mid way through call therefore breaking flow description filters
109 str regex_sdp_ip_prefix_to_maintain_in_fd = {0, 0};
110
111 //If set this will include an additional filter for all existing filters using the next odd port up - as this is the RTCP port
112 int include_rtcp_fd = 0;
113
114 int cdp_event_list_size_threshold = 0; /**Threshold for size of cdp event list after which a warning is logged */
115
116 stat_var *aars;
117 stat_var *strs;
118 stat_var *asrs;
119 stat_var *successful_aars;
120 stat_var *successful_strs;
121
122 static str identifier = {0, 0};
123 static int identifier_size = 0;
124
125 /** module functions */
126 static int mod_init(void);
127 static int mod_child_init(int);
128 static void mod_destroy(void);
129
130 static int fixup_aar_register(void** param, int param_no);
131 static int fixup_aar(void** param, int param_no);
132
133 int * callback_singleton; /*< Callback singleton */
134
135 int terminate_dialog_on_rx_failure = 1; //this specifies whether a dialog is torn down when a media rx session fails - in some cases you might not want the dialog torn down
136 int delete_contact_on_rx_failure = 1; //If this is set we delete the contact if the associated signalling bearer is removed
137
138
139 str early_qosrelease_reason = {"QoS released", 12};
140 str confirmed_qosrelease_headers = {NULL, 0};
141
142
143 /* parameters storage */
144 str rx_dest_realm = str_init("ims.smilecoms.com");
145 /* Only used if we want to force the Rx peer usually this is configured at a stack level and the first request uses realm routing */
146 str rx_forced_peer = str_init("");
147
148 /* P-CSCF IP address to generate the flows for the UE<->PCSCF signaling path */
149 str af_signaling_ip = str_init("127.0.0.1");
150
151
152 /* commands wrappers and fixups */
153 static int w_rx_aar(struct sip_msg *msg, char *route, char* dir, char *id, int id_type);
154 static int w_rx_aar_register(struct sip_msg *msg, char *route, char* str1, char *bar);
155
156 struct _pv_req_data {
157 struct cell *T;
158 struct sip_msg msg;
159 struct sip_msg *tmsgp;
160 char *buf;
161 int buf_size;
162 msg_ctx_id_t msg_ctx;
163 };
164
165 static struct _pv_req_data _pv_treq;
166
pv_tmx_data_init(void)167 static void pv_tmx_data_init(void)
168 {
169 memset(&_pv_treq, 0, sizeof(struct _pv_req_data));
170 }
171
pv_t_copy_msg(struct sip_msg * src,struct sip_msg * dst)172 static int pv_t_copy_msg(struct sip_msg *src, struct sip_msg *dst)
173 {
174 dst->id = src->id;
175 dst->rcv = src->rcv;
176 dst->set_global_address = src->set_global_address;
177 dst->set_global_port = src->set_global_port;
178 dst->flags = src->flags;
179 dst->fwd_send_flags = src->fwd_send_flags;
180 dst->rpl_send_flags = src->rpl_send_flags;
181 dst->force_send_socket = src->force_send_socket;
182
183 if (parse_msg(dst->buf, dst->len, dst) != 0) {
184 LM_ERR("parse msg failed\n");
185 return -1;
186 }
187 return 0;
188 }
189
190
191 static cmd_export_t cmds[] = {
192 { "Rx_AAR", (cmd_function) w_rx_aar, 4, fixup_aar, 0, REQUEST_ROUTE | ONREPLY_ROUTE},
193 { "Rx_AAR_Register", (cmd_function) w_rx_aar_register, 2, fixup_aar_register, 0, REQUEST_ROUTE},
194 { 0, 0, 0, 0, 0, 0}
195 };
196
197 static param_export_t params[] = {
198 { "rx_dest_realm", PARAM_STR, &rx_dest_realm},
199 { "rx_forced_peer", PARAM_STR, &rx_forced_peer},
200 { "rx_auth_expiry", INT_PARAM, &rx_auth_expiry},
201 { "af_signaling_ip", PARAM_STR, &af_signaling_ip}, /* IP of this P-CSCF, to be used in the flow for the AF-signaling */
202 { "cdp_event_latency", INT_PARAM, &cdp_event_latency}, /*flag: report slow processing of CDP callback events or not */
203 { "cdp_event_threshold", INT_PARAM, &cdp_event_threshold}, /*time in ms above which we should report slow processing of CDP callback event*/
204 { "cdp_event_latency_log", INT_PARAM, &cdp_event_latency_loglevel}, /*log-level to use to report slow processing of CDP callback event*/
205 { "authorize_video_flow", INT_PARAM, &authorize_video_flow}, /*whether or not we authorize resources for video flows*/
206 { "cdp_event_list_size_threshold", INT_PARAM, &cdp_event_list_size_threshold}, /**Threshold for size of cdp event list after which a warning is logged */
207 { "audio_default_bandwidth", INT_PARAM, &audio_default_bandwidth},
208 { "video_default_bandwidth", INT_PARAM, &video_default_bandwidth},
209 { "early_qosrelease_reason", PARAM_STR, &early_qosrelease_reason},
210 { "confirmed_qosrelease_headers", PARAM_STR, &confirmed_qosrelease_headers},
211 { "terminate_dialog_on_rx_failure", INT_PARAM, &terminate_dialog_on_rx_failure},
212 { "delete_contact_on_rx_failure", INT_PARAM, &delete_contact_on_rx_failure},
213 { "regex_sdp_ip_prefix_to_maintain_in_fd", PARAM_STR, ®ex_sdp_ip_prefix_to_maintain_in_fd},
214 { "include_rtcp_fd", INT_PARAM, &include_rtcp_fd},
215 { 0, 0, 0}
216 };
217
218
219 /** module exports */
220 struct module_exports exports = {
221 "ims_qos",
222 DEFAULT_DLFLAGS, /* dlopen flags */
223 cmds, /* Exported functions */
224 params,
225 0, /* exported RPC methods */
226 0, /* exported pseudo-variables */
227 0, /* response handling function */
228 mod_init, /* module initialization function */
229 mod_child_init, /* per-child init function */
230 mod_destroy
231 };
232
233 /**
234 * init module function
235 */
mod_init(void)236 static int mod_init(void)
237 {
238
239 callback_singleton = shm_malloc(sizeof(int));
240 *callback_singleton = 0;
241
242 /*register space for event processor*/
243 register_procs(1);
244
245 cdp_avp = 0;
246 /* load the TM API */
247 if (load_tm_api(&tmb) != 0) {
248 LM_ERR("can't load TM API\n");
249 goto error;
250 }
251
252 /* load the CDP API */
253 if (load_cdp_api(&cdpb) != 0) {
254 LM_ERR("can't load CDP API\n");
255 goto error;
256 }
257
258 /* load the dialog API */
259 if (load_ims_dlg_api(&dlgb) != 0) {
260 LM_ERR("can't load Dialog API\n");
261 goto error;
262 }
263
264 cdp_avp = load_cdp_avp();
265 if (!cdp_avp) {
266 LM_ERR("can't load CDP_AVP API\n");
267 goto error;
268 }
269
270 /* load the usrloc API */
271 bind_usrloc = (bind_usrloc_t) find_export("ul_bind_ims_usrloc_pcscf", 1, 0);
272 if (!bind_usrloc) {
273 LM_ERR("can't bind usrloc_pcscf\n");
274 return CSCF_RETURN_FALSE;
275 }
276
277 if (bind_usrloc(&ul) < 0) {
278 LM_ERR("can't bind to usrloc pcscf\n");
279 return CSCF_RETURN_FALSE;
280 }
281 LM_DBG("Successfully bound to PCSCF Usrloc module\n");
282
283 LM_DBG("Diameter RX interface successfully bound to TM, Dialog, Usrloc and CDP modules\n");
284
285 /*init cdb cb event list*/
286 if (!init_cdp_cb_event_list()) {
287 LM_ERR("unable to initialise cdp callback event list\n");
288 return -1;
289 }
290
291 if (ims_qos_init_counters() != 0) {
292 LM_ERR("Failed to register counters for ims_qos module\n");
293 return -1;
294 }
295
296 pv_tmx_data_init();
297
298 return 0;
299 error:
300 LM_ERR("Failed to initialise ims_qos module\n");
301 return CSCF_RETURN_FALSE;
302 }
303
304 /**
305 * Initializes the module in child.
306 */
mod_child_init(int rank)307 static int mod_child_init(int rank)
308 {
309 LM_DBG("Initialization of module in child [%d] \n", rank);
310
311 if (rank == PROC_MAIN) {
312 int pid = fork_process(PROC_MIN, "Rx Event Processor", 1);
313 if (pid < 0)
314 return -1; //error
315 if (pid == 0) {
316 if (cfg_child_init())
317 return -1; //error
318 cdp_cb_event_process();
319 }
320 }
321 /* don't do anything for main process and TCP manager process */
322 if (rank == PROC_MAIN || rank == PROC_TCP_MAIN) {
323 return 0;
324 }
325
326 lock_get(process_lock);
327 if ((*callback_singleton) == 0) {
328 *callback_singleton = 1;
329 cdpb.AAAAddRequestHandler(callback_cdp_request, NULL);
330 }
331 lock_release(process_lock);
332
333 return 0;
334 }
335
mod_destroy(void)336 static void mod_destroy(void)
337 {
338 if (identifier_size > 0 && identifier.s) {
339 pkg_free(identifier.s);
340 }
341 }
342
343 /*callback of CDP session*/
callback_for_cdp_session(int event,void * session)344 void callback_for_cdp_session(int event, void *session)
345 {
346 rx_authsessiondata_t* p_session_data = 0;
347 AAASession *x = session;
348
349 str* rx_session_id = (str*) & x->id;
350 p_session_data = (rx_authsessiondata_t*) x->u.auth.generic_data;
351
352 if (!rx_session_id || rx_session_id->len <= 0 || !rx_session_id->s) {
353 LM_ERR("Invalid Rx session id");
354 return;
355 }
356
357 if (!p_session_data) {
358 LM_ERR("Invalid associated session data\n");
359 return;
360 }
361
362 //only put the events we care about on the event stack
363 if (event == AUTH_EV_SESSION_TIMEOUT ||
364 event == AUTH_EV_SESSION_GRACE_TIMEOUT ||
365 event == AUTH_EV_RECV_ASR ||
366 event == AUTH_EV_SERVICE_TERMINATED) {
367
368 LOG(L_DBG, "callback_for_cdp session(): called with event %d and session id [%.*s]\n", event, rx_session_id->len, rx_session_id->s);
369
370 //create new event to process async
371 cdp_cb_event_t *new_event = new_cdp_cb_event(event, rx_session_id, p_session_data);
372 if (!new_event) {
373 LM_ERR("Unable to create event for cdp callback\n");
374 return;
375 }
376 //push the new event onto the stack (FIFO)
377 push_cdp_cb_event(new_event);
378 } else {
379 LM_DBG("Ignoring event [%d] from CDP session\n", event);
380 }
381 }
382
383 /**
384 * Handler for incoming Diameter requests.
385 * @param request - the received request
386 * @param param - generic pointer
387 * @returns the answer to this request
388 */
callback_cdp_request(AAAMessage * request,void * param)389 AAAMessage* callback_cdp_request(AAAMessage *request, void *param)
390 {
391 if (is_req(request)) {
392
393 switch (request->applicationId) {
394 case IMS_Rx:
395 case IMS_Gq:
396 switch (request->commandCode) {
397 case IMS_RAR:
398 LM_INFO("Rx request handler():- Received an IMS_RAR \n");
399 /* TODO: Add support for Re-Auth Requests */
400 return 0;
401 break;
402 case IMS_ASR:
403 LM_INFO("Rx request handler(): - Received an IMS_ASR \n");
404 return rx_process_asr(request);
405 break;
406 default:
407 LM_ERR("Rx request handler(): - Received unknown request for Rx/Gq command %d, flags %#1x endtoend %u hopbyhop %u\n", request->commandCode, request->flags, request->endtoendId, request->hopbyhopId);
408 return 0;
409 break;
410 }
411 break;
412 default:
413 LM_ERR("Rx request handler(): - Received unknown request for app %d command %d\n", request->applicationId, request->commandCode);
414 return 0;
415 break;
416 }
417 }
418 return 0;
419 }
420
421 const str match_cseq_method = {"INVITE", 6};
422
callback_dialog(struct dlg_cell * dlg,int type,struct dlg_cb_params * params)423 void callback_dialog(struct dlg_cell* dlg, int type, struct dlg_cb_params * params)
424 {
425
426 struct sip_msg* msg = params->rpl;
427 struct cseq_body *parsed_cseq;
428 str *rx_session_id;
429 rx_session_id = (str*) * params->param;
430 AAASession *auth = 0;
431 rx_authsessiondata_t* p_session_data = 0;
432 flow_description_t *current_fd = 0;
433 flow_description_t *new_fd = 0;
434 int current_has_video = 0;
435 int new_has_video = 0;
436 int must_unlock_aaa = 1;
437
438 if (rx_session_id == 0) {
439 LM_WARN("Strange... no rx session ID in callback.... why?\n");
440 return;
441 }
442 //getting session data
443
444 LM_DBG("Dialog callback of type %d received\n", type);
445
446 if (type == DLGCB_TERMINATED || type == DLGCB_DESTROY || type == DLGCB_EXPIRED || type == DLGCB_FAILED) {
447 LM_DBG("Dialog has ended or failed - we need to terminate Rx bearer session\n");
448
449 LM_DBG("Received notification of termination of dialog with Rx session ID: [%.*s]\n",
450 rx_session_id->len, rx_session_id->s);
451
452 LM_DBG("Sending STR\n");
453 rx_send_str(rx_session_id);
454 } else if (type == DLGCB_CONFIRMED) {
455
456 LM_DBG("Callback for confirmed dialog - copy new flow description into current flow description\n");
457 if (!rx_session_id || !rx_session_id->s || !rx_session_id->len) {
458 LM_ERR("Dialog has no Rx session associated\n");
459 goto error;
460 }
461
462 //getting auth session
463 auth = cdpb.AAAGetAuthSession(*rx_session_id);
464 if (!auth) {
465 LM_DBG("Could not get Auth Session for session id: [%.*s]\n", rx_session_id->len, rx_session_id->s);
466 goto error;
467 }
468
469 //getting session data
470 p_session_data = (rx_authsessiondata_t*) auth->u.auth.generic_data;
471 if (!p_session_data) {
472 LM_DBG("Could not get session data on Auth Session for session id: [%.*s]\n", rx_session_id->len, rx_session_id->s);
473 goto error;
474 }
475
476 //check if there is a new flow description - if there is then free the current flow description and replace it with the new flow description
477 if (p_session_data->first_new_flow_description) {
478 //free the current
479 LM_DBG("Free-ing the current fd\n");
480 free_flow_description(p_session_data, 1);
481 //point the current to the new
482 LM_DBG("Point the first current fd to the first new fd\n");
483 p_session_data->first_current_flow_description = p_session_data->first_new_flow_description;
484 //point the new to 0
485 LM_DBG("Point the first new fd to 0\n");
486 p_session_data->first_new_flow_description = 0;
487 } else {
488 LM_ERR("There is no new flow description - this shouldn't happen\n");
489 }
490
491 show_callsessiondata(p_session_data);
492 if (auth) cdpb.AAASessionsUnlock(auth->hash);
493
494 } else if (type == DLGCB_RESPONSE_WITHIN) {
495
496 LM_DBG("Dialog has received a response to a request within dialog\n");
497 if (!rx_session_id || !rx_session_id->s || !rx_session_id->len) {
498 LM_ERR("Dialog has no Rx session associated\n");
499 goto error;
500 }
501
502 //getting auth session
503 auth = cdpb.AAAGetAuthSession(*rx_session_id);
504 if (!auth) {
505 LM_DBG("Could not get Auth Session for session id: [%.*s]\n", rx_session_id->len, rx_session_id->s);
506 goto error;
507 }
508
509 //getting session data
510 p_session_data = (rx_authsessiondata_t*) auth->u.auth.generic_data;
511
512 if (!p_session_data) {
513 LM_DBG("Could not get session data on Auth Session for session id: [%.*s]\n", rx_session_id->len, rx_session_id->s);
514 goto error;
515 }
516
517 show_callsessiondata(p_session_data);
518
519 if (msg->first_line.type == SIP_REPLY) {
520 LM_DBG("This is a SIP REPLY\n");
521 if (msg->cseq && (parsed_cseq = get_cseq(msg)) && memcmp(parsed_cseq->method.s, match_cseq_method.s, match_cseq_method.len) == 0) {
522 LM_DBG("This response has a cseq method [%.*s]\n", match_cseq_method.len, match_cseq_method.s);
523
524 if (msg->first_line.u.reply.statuscode == 200) {
525 LM_DBG("Response is 200 - this is success\n");
526 //check if there is a new flow description - if there is then free the current flow description and replace it with the new flow description
527 if (p_session_data->first_new_flow_description) {
528 //free the current
529 free_flow_description(p_session_data, 1);
530 //point the current to the new
531 p_session_data->first_current_flow_description = p_session_data->first_new_flow_description;
532 //point the new to 0
533 p_session_data->first_new_flow_description = 0;
534 } else {
535 LM_DBG("There is no new flow description - duplicate dialog callback - we ignore.\n");
536 }
537 } else if (msg->first_line.u.reply.statuscode > 299) {
538 LM_DBG("Response is more than 299 so this is an error code\n");
539
540 new_fd = p_session_data->first_new_flow_description;
541 //check if there is video in the new flow description
542 while (new_fd) {
543 if (strncmp(new_fd->media.s, "video", 5) == 0) {
544 LM_DBG("The new flow has a video fd in it\n");
545 new_has_video = 1;
546
547 }
548 new_fd = new_fd->next;
549 }
550 //check if there is video in the current flow description
551 current_fd = p_session_data->first_current_flow_description;
552 while (current_fd) {
553 if (strncmp(current_fd->media.s, "video", 5) == 0) {
554 LM_DBG("The current flow has a video fd in it\n");
555 current_has_video = 1;
556
557 }
558 current_fd = current_fd->next;
559 }
560 if (new_has_video && !current_has_video) {
561 LM_DBG("New flow description has video in it, and current does not - this means we added video and it failed further upstream - "
562 "so we must remove the video\n");
563 //We need to send AAR asynchronously with current fd
564 rx_send_aar_update_no_video(auth);
565 must_unlock_aaa = 0;
566
567 }
568 //free the new flow description
569 free_flow_description(p_session_data, 0);
570 }
571 }
572 }
573
574 show_callsessiondata(p_session_data);
575
576 if (must_unlock_aaa) {
577 LM_DBG("Unlocking AAA session");
578 cdpb.AAASessionsUnlock(auth->hash);
579 }
580 } else {
581 LM_DBG("Callback type not supported - just returning");
582 }
583
584 return;
585
586 error:
587 if (auth) cdpb.AAASessionsUnlock(auth->hash);
588 return;
589 }
590
callback_pcscf_contact_cb(struct pcontact * c,int type,void * param)591 void callback_pcscf_contact_cb(struct pcontact *c, int type, void *param)
592 {
593 LM_DBG("----------------------!\n");
594 LM_DBG("PCSCF Contact Callback!\n");
595 LM_DBG("Contact AOR: [%.*s]\n", c->aor.len, c->aor.s);
596 LM_DBG("Callback type [%d]\n", type);
597
598
599 if (type == PCSCF_CONTACT_EXPIRE || type == PCSCF_CONTACT_DELETE) {
600 // we dont need to send STR if no QoS was ever successfully registered!
601 if (must_send_str && (c->reg_state != PCONTACT_REG_PENDING) && (c->reg_state != PCONTACT_REG_PENDING_AAR)) {
602 LM_DBG("Received notification of contact (in state [%d] deleted for signalling bearer with with Rx session ID: [%.*s]\n",
603 c->reg_state, c->rx_session_id.len, c->rx_session_id.s);
604 LM_DBG("Sending STR\n");
605 rx_send_str(&c->rx_session_id);
606 }
607 }
608 }
609
get_identifier(str * src)610 static int get_identifier(str* src)
611 {
612 char *sep;
613
614 if (src == 0 || src->len == 0) {
615 return -1;
616 }
617
618 if (identifier_size <= src->len) {
619 if (identifier.s) {
620 pkg_free(identifier.s);
621 }
622 identifier.s = (char*) pkg_malloc(src->len + 1);
623 if (!identifier.s) {
624 LM_ERR("no more pkg mem\n");
625 return -1;
626 }
627 memset(identifier.s, 0, src->len + 1);
628 identifier_size = src->len + 1;
629 }
630
631 memcpy(identifier.s, src->s, src->len);
632 identifier.len = src->len;
633 sep = memchr(identifier.s, 59 /* ; */, identifier.len);
634
635 if (sep) identifier.len = (int) (sep - identifier.s);
636
637 return 0;
638 }
639
check_ip_version(str ip)640 uint16_t check_ip_version(str ip)
641 {
642 struct addrinfo hint, *res = NULL;
643 memset(&hint, '\0', sizeof(hint));
644 hint.ai_family = AF_UNSPEC;
645 hint.ai_flags = AI_NUMERICHOST;
646 int getaddrret = getaddrinfo(ip.s, NULL, &hint, &res);
647 if (getaddrret) {
648 LM_ERR("GetAddrInfo returned an error !\n");
649 return 0;
650 }
651 if (res->ai_family == AF_INET) {
652 return AF_INET;
653 } else if (res->ai_family == AF_INET6) {
654 return AF_INET6;
655 } else {
656 LM_ERR("unknown IP format \n");
657 return 0;
658 }
659 }
660
661 /* Wrapper to send AAR from config file - this only allows for AAR for calls - not register, which uses r_rx_aar_register
662 * return: 1 - success, <=0 failure. 2 - message not a AAR generating message (ie proceed without PCC if you wish)
663 */
w_rx_aar(struct sip_msg * msg,char * route,char * dir,char * c_id,int id_type)664 static int w_rx_aar(struct sip_msg *msg, char *route, char* dir, char *c_id, int id_type)
665 {
666
667 int ret = CSCF_RETURN_ERROR;
668 int result = CSCF_RETURN_ERROR;
669 struct cell *t;
670 struct sip_msg* orig_sip_request_msg = NULL;
671
672 AAASession* auth_session = 0;
673 rx_authsessiondata_t* rx_authdata_p = 0;
674 str *rx_session_id = 0;
675 str callid = {0, 0};
676 str ftag = {0, 0};
677 str ttag = {0, 0};
678
679 str route_name;
680 str ip, uri;
681 int identifier_type;
682 int ip_version = 0;
683 sdp_session_cell_t* sdp_session;
684 sdp_stream_cell_t* sdp_stream;
685 str s_id;
686 struct hdr_field *h = 0;
687 struct dlg_cell* dlg = 0;
688
689 cfg_action_t* cfg_action = 0;
690 saved_transaction_t* saved_t_data = 0; //data specific to each contact's AAR async call
691 char* direction = dir;
692 if (fixup_get_svalue(msg, (gparam_t*) route, &route_name) != 0) {
693 LM_ERR("no async route block for assign_server_unreg\n");
694 return result;
695 }
696
697 if (get_str_fparam(&s_id, msg, (fparam_t*) c_id) < 0) {
698 LM_ERR("failed to get s__id\n");
699 return result;
700 }
701
702 LM_DBG("Looking for route block [%.*s]\n", route_name.len, route_name.s);
703 int ri = route_get(&main_rt, route_name.s);
704 if (ri < 0) {
705 LM_ERR("unable to find route block [%.*s]\n", route_name.len, route_name.s);
706 return result;
707 }
708 cfg_action = main_rt.rlist[ri];
709 if (cfg_action == NULL) {
710 LM_ERR("empty action lists in route block [%.*s]\n", route_name.len, route_name.s);
711 return result;
712 }
713
714 LM_DBG("Rx AAR called\n");
715 //create the default return code AVP
716 create_return_code(ret);
717
718 //We don't ever do AAR on request for calling scenario...
719 if (msg->first_line.type != SIP_REPLY) {
720 LM_DBG("Can't do AAR for call session in request\n");
721 return result;
722 }
723
724 //is it appropriate to send AAR at this stage?
725 t = tmb.t_gett();
726 if (t == NULL || t == T_UNDEFINED) {
727 LM_WARN("Cannot get transaction for AAR based on SIP Request\n");
728 //goto aarna;
729 return result;
730 }
731
732 if (t->uas.status >= 200) {
733 LM_DBG("trasaction sent out a final response already - %d\n",
734 t->uas.status);
735 return result;
736 }
737
738
739 /* we may need the request message from here on.. if there are headers we need that were not parsed in the original request
740 (which we cannot assume) then we would pollute the shm_msg t->uas.request if we did any parsing on it. Instead, we need to
741 make a private copy of the message and free it when we are done
742 */
743 if (msg_ctx_id_match(t->uas.request, &_pv_treq.msg_ctx) != 1) {
744
745 /* make a copy */
746 if (_pv_treq.buf == NULL || _pv_treq.buf_size < t->uas.request->len + 1) {
747 if (_pv_treq.buf != NULL)
748 pkg_free(_pv_treq.buf);
749 if (_pv_treq.tmsgp)
750 free_sip_msg(&_pv_treq.msg);
751 _pv_treq.tmsgp = NULL;
752 _pv_treq.msg_ctx.msgid=0;
753 _pv_treq.msg_ctx.pid=0;
754 _pv_treq.T = NULL;
755 _pv_treq.buf_size = t->uas.request->len + 1;
756 _pv_treq.buf = (char*) pkg_malloc(_pv_treq.buf_size * sizeof(char));
757 if (_pv_treq.buf == NULL) {
758 LM_ERR("no more pkg\n");
759 _pv_treq.buf_size = 0;
760 return -1;
761 }
762 }
763 if (_pv_treq.tmsgp)
764 free_sip_msg(&_pv_treq.msg);
765 memset(&_pv_treq.msg, 0, sizeof(struct sip_msg));
766 memcpy(_pv_treq.buf, t->uas.request->buf, t->uas.request->len);
767 _pv_treq.buf[t->uas.request->len] = '\0';
768 _pv_treq.msg.len = t->uas.request->len;
769 _pv_treq.msg.buf = _pv_treq.buf;
770 _pv_treq.tmsgp = t->uas.request;
771 msg_ctx_id_set(t->uas.request, &_pv_treq.msg_ctx);
772 _pv_treq.T = t;
773
774
775 if (pv_t_copy_msg(t->uas.request, &_pv_treq.msg) != 0) {
776 pkg_free(_pv_treq.buf);
777 _pv_treq.buf_size = 0;
778 _pv_treq.buf = NULL;
779 _pv_treq.tmsgp = NULL;
780 _pv_treq.T = NULL;
781 return -1;
782 }
783 }
784
785 orig_sip_request_msg = &_pv_treq.msg;
786
787
788 //we dont apply QoS if its not a reply to an INVITE! or UPDATE or PRACK!
789 if ((t->method.len == 5 && memcmp(t->method.s, "PRACK", 5) == 0)
790 || (t->method.len == 6 && (memcmp(t->method.s, "INVITE", 6) == 0
791 || memcmp(t->method.s, "UPDATE", 6) == 0))) {
792 if (cscf_get_content_length(msg) == 0
793 || cscf_get_content_length(orig_sip_request_msg) == 0) {
794 LM_DBG("No SDP offer answer -> therefore we can not do Rx AAR");
795 //goto aarna; //AAR na if we dont have offer/answer pair
796 return result;
797 }
798 } else {
799 LM_DBG("Message is not response to INVITE, PRACK or UPDATE -> therefore we do not Rx AAR");
800 return result;
801 }
802
803 /* get callid, from and to tags to be able to identify dialog */
804 callid = cscf_get_call_id(msg, 0);
805 if (callid.len <= 0 || !callid.s) {
806 LM_ERR("unable to get callid\n");
807 return result;
808 }
809 if (!cscf_get_from_tag(msg, &ftag)) {
810 LM_ERR("Unable to get ftag\n");
811 return result;
812 }
813 if (!cscf_get_to_tag(msg, &ttag)) {
814 LM_ERR("Unable to get ttag\n");
815 return result;
816 }
817
818 //check to see that this is not a result of a retransmission in reply route only
819 if (msg->cseq == NULL
820 && ((parse_headers(msg, HDR_CSEQ_F, 0) == -1) || (msg->cseq == NULL))) {
821 LM_ERR("No Cseq header found - aborting\n");
822 return result;
823 }
824
825 saved_t_data = (saved_transaction_t*) shm_malloc(sizeof(saved_transaction_t));
826 if (!saved_t_data) {
827 LM_ERR("Unable to allocate memory for transaction data, trying to send AAR\n");
828 return result;
829 }
830 memset(saved_t_data, 0, sizeof(saved_transaction_t));
831 saved_t_data->act = cfg_action;
832 //OTHER parms need after async response set here
833 //store call id
834 saved_t_data->callid.s = (char*) shm_malloc(callid.len + 1);
835 if (!saved_t_data->callid.s) {
836 LM_ERR("no more memory trying to save transaction state : callid\n");
837 shm_free(saved_t_data);
838 return result;
839 }
840 memset(saved_t_data->callid.s, 0, callid.len + 1);
841 memcpy(saved_t_data->callid.s, callid.s, callid.len);
842 saved_t_data->callid.len = callid.len;
843
844 //store ttag
845 saved_t_data->ttag.s = (char*) shm_malloc(ttag.len + 1);
846 if (!saved_t_data->ttag.s) {
847 LM_ERR("no more memory trying to save transaction state : ttag\n");
848 shm_free(saved_t_data);
849 return result;
850 }
851 memset(saved_t_data->ttag.s, 0, ttag.len + 1);
852 memcpy(saved_t_data->ttag.s, ttag.s, ttag.len);
853 saved_t_data->ttag.len = ttag.len;
854
855 //store ftag
856 saved_t_data->ftag.s = (char*) shm_malloc(ftag.len + 1);
857 if (!saved_t_data->ftag.s) {
858 LM_ERR("no more memory trying to save transaction state : ftag\n");
859 shm_free(saved_t_data);
860 return result;
861 }
862 memset(saved_t_data->ftag.s, 0, ftag.len + 1);
863 memcpy(saved_t_data->ftag.s, ftag.s, ftag.len);
864 saved_t_data->ftag.len = ftag.len;
865
866 saved_t_data->aar_update = 0; //by default we say this is not an aar update - if it is we set it below
867
868 //store branch
869 int branch;
870 if (tmb.t_check(msg, &branch) == -1) {
871 LOG(L_ERR, "ERROR: t_suspend: failed find UAC branch\n");
872 return result;
873 }
874
875 //Check that we dont already have an auth session for this specific dialog
876 //if not we create a new one and attach it to the dialog (via session ID).
877 enum dialog_direction dlg_direction = get_dialog_direction(direction);
878 if (dlg_direction == DLG_MOBILE_ORIGINATING) {
879 rx_session_id = dlgb.get_dlg_var(&callid, &ftag, &ttag,
880 &orig_session_key);
881 } else {
882 rx_session_id = dlgb.get_dlg_var(&callid, &ftag, &ttag,
883 &term_session_key);
884 }
885 if (rx_session_id && rx_session_id->len > 0 && rx_session_id->s) {
886 auth_session = cdpb.AAAGetAuthSession(*rx_session_id);
887 if (auth_session && auth_session->u.auth.state != AUTH_ST_OPEN) {
888 LM_DBG("This session is not state open - so we will create a new session");
889 if (auth_session) cdpb.AAASessionsUnlock(auth_session->hash);
890 auth_session = 0;
891 }
892 }
893
894 if (!auth_session) {
895 LM_DBG("New AAR session for this dialog in mode %s\n", direction);
896
897
898 //get ip and subscription_id and store them in the call session data
899
900 //SUBSCRIPTION-ID
901
902 //if subscription-id and identifier_type is passed from config file we use them - if not we use default behaviour of
903
904 //if its mo we use p_asserted_identity in request - if that not there we use from_uri
905 //if its mt we use p_asserted_identity in reply - if that not there we use to_uri
906 if (s_id.len > 0 && id_type > -1) {
907 get_identifier(&s_id);
908 identifier_type = id_type;
909 LM_DBG("Passed in subscription_id [%.*s] and subscription_id_type [%d]\n", identifier.len, identifier.s, identifier_type);
910 } else {
911 if (dlg_direction == DLG_MOBILE_ORIGINATING) {
912 LM_DBG("originating direction\n");
913 uri = cscf_get_asserted_identity(orig_sip_request_msg, 0);
914 if (uri.len == 0) {
915 LM_ERR("No P-Asserted-Identity hdr found in request. Using From hdr in req - we shouldn't have to do this");
916
917 if (!cscf_get_from_uri(orig_sip_request_msg, &uri)) {
918 LM_ERR("Error assigning P-Asserted-Identity using From hdr in req");
919 goto error;
920 }
921 LM_DBG("going to remove parameters if any from identity: [%.*s]\n", uri.len, uri.s);
922 get_identifier(&uri);
923 LM_DBG("identifier from uri : [%.*s]\n", identifier.len, identifier.s);
924
925 } else {
926 get_identifier(&uri);
927 //free this cscf_get_asserted_identity allocates it
928 // pkg_free(uri.s);
929 }
930 } else {
931 LM_DBG("terminating direction\n");
932 uri = cscf_get_asserted_identity(msg, 0);
933 if (uri.len == 0) {
934 LM_DBG("No P-Asserted-Identity hdr found in response. Using Called party id in resp");
935 //get identity from called party id
936 //getting called asserted identity
937 uri = cscf_get_public_identity_from_called_party_id(orig_sip_request_msg, &h);
938 if (uri.len == 0) {
939 LM_ERR("No P-Called-Party hdr found in response. Using req URI from dlg - we shouldn't have to do this");
940 //get dialog and get the req URI from there
941 dlg = dlgb.get_dlg(msg);
942 if (!dlg) {
943 if (!cscf_get_to_uri(orig_sip_request_msg, &uri)) {
944 LM_ERR("Error assigning P-Asserted-Identity using To hdr in req");
945 goto error;
946 }
947 LM_DBG("going to remove parameters if any from identity: [%.*s]\n", uri.len, uri.s);
948 get_identifier(&uri);
949 LM_DBG("identifier from uri : [%.*s]\n", identifier.len, identifier.s);
950 }else{
951 LM_DBG("dlg req uri : [%.*s] going to remove parameters if any\n", dlg->req_uri.len, dlg->req_uri.s);
952
953 if (get_identifier(&dlg->req_uri) != 0) {
954 dlgb.release_dlg(dlg);
955 goto error;
956 }
957 dlgb.release_dlg(dlg);
958 LM_DBG("identifier from dlg req uri : [%.*s]\n", identifier.len, identifier.s);
959 }
960 } else {
961 get_identifier(&uri);
962 }
963 } else {
964 get_identifier(&uri);
965 }
966 }
967 if (strncasecmp(identifier.s, "tel:", 4) == 0) {
968 identifier_type = AVP_Subscription_Id_Type_E164; //
969 } else {
970 identifier_type = AVP_Subscription_Id_Type_SIP_URI; //default is END_USER_SIP_URI
971 }
972 }
973 //IP
974 //if its mo we use request SDP
975 //if its mt we use reply SDP
976 if (dlg_direction == DLG_MOBILE_ORIGINATING) {
977 LM_DBG("originating direction\n");
978 //get ip from request sdp (we use first SDP session)
979 if (parse_sdp(orig_sip_request_msg) < 0) {
980 LM_ERR("Unable to parse req SDP\n");
981 goto error;
982 }
983
984 sdp_session = get_sdp_session(orig_sip_request_msg, 0);
985 if (!sdp_session) {
986 LM_ERR("Missing SDP session information from req\n");
987 goto error;
988 }
989 ip = sdp_session->ip_addr;
990 ip_version = sdp_session->pf;
991
992 LM_DBG("IP retrieved from Request SDP to use for framed IP address: [%.*s]", ip.len, ip.s);
993
994 if (ip.len <= 0) {
995 LM_DBG("Request SDP connection IP could not be retrieved, so we use SDP stream IP");
996 sdp_stream = get_sdp_stream(orig_sip_request_msg, 0, 0);
997 if (!sdp_stream) {
998 LM_ERR("Missing SDP stream information from request\n");
999 goto error;
1000 }
1001
1002 ip = sdp_stream->ip_addr;
1003 if (ip.len <= 0) {
1004 LM_ERR("Request SDP IP information could not be retrieved");
1005 goto error;
1006 }
1007 ip_version = check_ip_version(ip);
1008 if (!ip_version) {
1009 LM_ERR("check_ip_version returned 0 \n");
1010 goto error;
1011 }
1012
1013 }
1014
1015 free_sdp((sdp_info_t**) (void*) &t->uas.request->body);
1016
1017 } else {
1018 LM_DBG("terminating direction\n");
1019 //get ip from reply sdp (we use first SDP session)
1020 if (parse_sdp(msg) < 0) {
1021 LM_ERR("Unable to parse reply SDP\n");
1022 goto error;
1023 }
1024
1025 sdp_session = get_sdp_session(msg, 0);
1026 if (!sdp_session) {
1027 LM_ERR("Missing SDP session information from reply\n");
1028 goto error;
1029 }
1030 ip = sdp_session->ip_addr;
1031 ip_version = sdp_session->pf;
1032
1033 LM_DBG("IP retrieved from Reply SDP to use for framed IP address: [%.*s]", ip.len, ip.s);
1034
1035 if (ip.len <= 0) {
1036 LM_DBG("Reply SDP connection IP could not be retrieved, so we use SDP stream IP");
1037 sdp_stream = get_sdp_stream(msg, 0, 0);
1038 if (!sdp_stream) {
1039 LM_ERR("Missing SDP stream information from reply\n");
1040 goto error;
1041 }
1042
1043 ip = sdp_stream->ip_addr;
1044 if (ip.len <= 0) {
1045 LM_ERR("Reply SDP IP information could not be retrieved");
1046 goto error;
1047 }
1048 ip_version = check_ip_version(ip);
1049 if (!ip_version) {
1050 LM_ERR("check_ip_version returned 0 \n");
1051 goto error;
1052 }
1053
1054 }
1055
1056 free_sdp((sdp_info_t**) (void*) &msg->body);
1057 }
1058
1059 int ret = create_new_callsessiondata(&callid, &ftag, &ttag, &identifier, identifier_type, &ip, ip_version, &rx_authdata_p);
1060 if (!ret) {
1061 LM_DBG("Unable to create new media session data parcel\n");
1062 goto error;
1063 }
1064
1065 //create new diameter auth session
1066 auth_session = cdpb.AAACreateClientAuthSession(1, callback_for_cdp_session, rx_authdata_p); //returns with a lock
1067 if (!auth_session) {
1068 LM_ERR("Rx: unable to create new Rx Media Session\n");
1069 if (auth_session) cdpb.AAASessionsUnlock(auth_session->hash);
1070 if (rx_authdata_p) {
1071 free_callsessiondata(rx_authdata_p);
1072 }
1073 goto error;
1074 }
1075 auth_session->u.auth.class = AUTH_CLASS_RXMEDIA;
1076
1077 //attach new cdp auth session to dlg for this direction
1078 if (dlg_direction == DLG_MOBILE_ORIGINATING) {
1079 dlgb.set_dlg_var(&callid, &ftag, &ttag,
1080 &orig_session_key, &auth_session->id);
1081 } else {
1082 dlgb.set_dlg_var(&callid, &ftag, &ttag,
1083 &term_session_key, &auth_session->id);
1084 }
1085 LM_DBG("Attached CDP auth session [%.*s] for Rx to dialog in %s mode\n", auth_session->id.len, auth_session->id.s, direction);
1086 } else {
1087 LM_DBG("Update AAR session for this dialog in mode %s\n", direction);
1088 //check if this is triggered by a 183 - if so break here as its probably a re-transmit
1089 if ((msg->first_line).u.reply.statuscode == 183) {
1090 LM_DBG("Received a 183 for a diameter session that already exists - just going to ignore this\n");
1091 cdpb.AAASessionsUnlock(auth_session->hash);
1092 result = CSCF_RETURN_TRUE;
1093 goto ignore;
1094 }
1095 saved_t_data->aar_update = 1; //this is an update aar - we set this so on async_aar we know this is an update and act accordingly
1096 }
1097
1098 dlg = dlgb.get_dlg(msg);
1099 if (!dlg) {
1100 LM_ERR("Unable to find dialog and cannot do Rx without it\n");
1101 goto error;
1102 }
1103 saved_t_data->dlg = dlg;
1104
1105 LM_DBG("Suspending SIP TM transaction\n");
1106 if (tmb.t_suspend(msg, &saved_t_data->tindex, &saved_t_data->tlabel) != 0) {
1107 LM_ERR("failed to suspend the TM processing\n");
1108 if (auth_session) cdpb.AAASessionsUnlock(auth_session->hash);
1109 goto error;
1110 }
1111
1112 LM_DBG("Sending Rx AAR");
1113 ret = rx_send_aar(orig_sip_request_msg, msg, auth_session, direction, saved_t_data);
1114
1115 if (!ret) {
1116 LM_ERR("Failed to send AAR\n");
1117 tmb.t_cancel_suspend(saved_t_data->tindex, saved_t_data->tlabel);
1118 goto error;
1119
1120
1121 } else {
1122 LM_DBG("Successful async send of AAR\n");
1123 result = CSCF_RETURN_BREAK;
1124 return result; //on success we break - because rest of cfg file will be executed by async process
1125 }
1126
1127 error:
1128 LM_ERR("Error trying to send AAR (calling)\n");
1129 if (auth_session != NULL) {
1130 cdpb.AAASessionsUnlock(auth_session->hash);
1131 cdpb.AAADropAuthSession(auth_session);
1132 }
1133 ignore:
1134 if (saved_t_data)
1135 free_saved_transaction_global_data(saved_t_data); //only free global data if no AARs were sent. if one was sent we have to rely on the callback (CDP) to free
1136 //otherwise the callback will segfault
1137 return result;
1138 }
1139
1140 /* Wrapper to send AAR from config file - only used for registration */
w_rx_aar_register(struct sip_msg * msg,char * route,char * str1,char * bar)1141 static int w_rx_aar_register(struct sip_msg *msg, char* route, char* str1, char* bar)
1142 {
1143
1144 int ret = CSCF_RETURN_ERROR;
1145 struct pcontact_info ci;
1146 struct cell *t;
1147 contact_t* c;
1148 struct hdr_field* h;
1149 pcontact_t* pcontact;
1150 pcontact_info_t contact_info;
1151 contact_body_t* cb = 0;
1152 AAASession* auth;
1153 rx_authsessiondata_t* rx_regsession_data_p;
1154 cfg_action_t* cfg_action = 0;
1155 str route_name;
1156 char* p;
1157 int aar_sent = 0;
1158 saved_transaction_local_t* local_data = 0; //data to be shared across all async calls
1159 saved_transaction_t* saved_t_data = 0; //data specific to each contact's AAR async call
1160 str recv_ip;
1161 int recv_port;
1162 unsigned short recv_proto;
1163 uint16_t ip_version;
1164
1165 struct via_body* vb;
1166 unsigned short via_port;
1167 unsigned short via_proto;
1168
1169 if (fixup_get_svalue(msg, (gparam_t*) route, &route_name) != 0) {
1170 LM_ERR("no async route block for assign_server_unreg\n");
1171 return -1;
1172 }
1173
1174 LM_DBG("Looking for route block [%.*s]\n", route_name.len, route_name.s);
1175 int ri = route_get(&main_rt, route_name.s);
1176 if (ri < 0) {
1177 LM_ERR("unable to find route block [%.*s]\n", route_name.len, route_name.s);
1178 return -1;
1179 }
1180 cfg_action = main_rt.rlist[ri];
1181 if (cfg_action == NULL) {
1182 LM_ERR("empty action lists in route block [%.*s]\n", route_name.len, route_name.s);
1183 return -1;
1184 }
1185
1186 udomain_t* domain_t = (udomain_t*) str1;
1187
1188 int is_rereg = 0; //is this a reg/re-reg
1189
1190 LM_DBG("Rx AAR Register called\n");
1191
1192 //create the default return code AVP
1193 create_return_code(ret);
1194
1195 memset(&ci, 0, sizeof(struct pcontact_info));
1196
1197 /** If this is a response then let's check the status before we try and do an AAR.
1198 * We will only do AAR for register on success response and of course if message is register
1199 */
1200 if (msg->first_line.type == SIP_REPLY) {
1201 //check this is a response to a register
1202 /* Get the SIP request from this transaction */
1203 t = tmb.t_gett();
1204 if (!t) {
1205 LM_ERR("Cannot get transaction for AAR based on SIP Request\n");
1206 goto error;
1207 }
1208 if ((strncmp(t->method.s, "REGISTER", 8) != 0)) {
1209 LM_ERR("Method is not a response to a REGISTER\n");
1210 goto error;
1211 }
1212 if (msg->first_line.u.reply.statuscode < 200
1213 || msg->first_line.u.reply.statuscode >= 300) {
1214 LM_DBG("Message is not a 2xx OK response to a REGISTER\n");
1215 goto error;
1216 }
1217 tmb.t_release(msg);
1218 } else { //SIP Request
1219 /* in case of request make sure it is a REGISTER */
1220 if (msg->first_line.u.request.method_value != METHOD_REGISTER) {
1221 LM_DBG("This is not a register request\n");
1222 goto error;
1223 }
1224
1225 if ((cscf_get_max_expires(msg, 0) == 0)) {
1226 //if ((cscf_get_expires(msg) == 0)) {
1227 LM_DBG("This is a de registration\n");
1228 LM_DBG("We ignore it as these are dealt with by usrloc callbacks \n");
1229 create_return_code(CSCF_RETURN_TRUE);
1230 return CSCF_RETURN_TRUE;
1231 }
1232 }
1233
1234 vb = cscf_get_ue_via(msg);
1235 via_port = vb->port ? vb->port : 5060;
1236 via_proto = vb->proto;
1237
1238 //before we continue, make sure we have a transaction to work with (viz. cdp async)
1239 t = tmb.t_gett();
1240 if (t == NULL || t == T_UNDEFINED) {
1241 if (tmb.t_newtran(msg) < 0) {
1242 LM_ERR("cannot create the transaction for UAR async\n");
1243 return CSCF_RETURN_ERROR;
1244 }
1245 t = tmb.t_gett();
1246 if (t == NULL || t == T_UNDEFINED) {
1247 LM_ERR("cannot lookup the transaction\n");
1248 return CSCF_RETURN_ERROR;
1249 }
1250 }
1251
1252 saved_t_data = (saved_transaction_t*) shm_malloc(sizeof(saved_transaction_t));
1253 if (!saved_t_data) {
1254 LM_ERR("Unable to allocate memory for transaction data, trying to send AAR\n");
1255 return CSCF_RETURN_ERROR;
1256 }
1257 memset(saved_t_data, 0, sizeof(saved_transaction_t));
1258 saved_t_data->act = cfg_action;
1259 saved_t_data->domain = domain_t;
1260 saved_t_data->lock = lock_alloc();
1261 if (saved_t_data->lock == NULL) {
1262 LM_ERR("unable to allocate init lock for saved_t_transaction reply counter\n");
1263 return CSCF_RETURN_ERROR;
1264 }
1265 if (lock_init(saved_t_data->lock) == NULL) {
1266 LM_ERR("unable to init lock for saved_t_transaction reply counter\n");
1267 return CSCF_RETURN_ERROR;
1268 }
1269
1270 LM_DBG("Suspending SIP TM transaction\n");
1271 if (tmb.t_suspend(msg, &saved_t_data->tindex, &saved_t_data->tlabel) != 0) {
1272 LM_ERR("failed to suspend the TM processing\n");
1273 free_saved_transaction_global_data(saved_t_data);
1274 return CSCF_RETURN_ERROR;
1275 }
1276
1277 LM_DBG("Successfully suspended transaction\n");
1278
1279 //now get the contacts in the REGISTER and do AAR for each one.
1280 cb = cscf_parse_contacts(msg);
1281 if (!cb || (!cb->contacts && !cb->star)) {
1282 LM_DBG("No contact headers in Register message\n");
1283 goto error;
1284 }
1285
1286 //we use the received IP address for the framed_ip_address
1287 recv_ip.s = ip_addr2a(&msg->rcv.src_ip);
1288 recv_ip.len = strlen(ip_addr2a(&msg->rcv.src_ip));
1289
1290 ip_version = check_ip_version(recv_ip);
1291 if (!ip_version) {
1292 LM_ERR("check_ip_version returned 0 \n");
1293 goto error;
1294 }
1295
1296 recv_port = msg->rcv.src_port;
1297 recv_proto = msg->rcv.proto;
1298
1299 LM_DBG("Message received IP address is: [%.*s]\n", recv_ip.len, recv_ip.s);
1300 LM_DBG("Message via is [%d://%.*s:%d]\n", vb->proto, vb->host.len, vb->host.s, via_port);
1301
1302 lock_get(saved_t_data->lock); //we lock here to make sure we send all requests before processing replies asynchronously
1303 for (h = msg->contact; h; h = h->next) {
1304 if (h->type == HDR_CONTACT_T && h->parsed) {
1305 for (c = ((contact_body_t*) h->parsed)->contacts; c; c = c->next) {
1306 ul.lock_udomain(domain_t, &vb->host, vb->port, vb->proto);
1307 memset(&contact_info, 0, sizeof(struct pcontact_info));
1308 contact_info.aor = c->uri;
1309 contact_info.via_host = vb->host;
1310 contact_info.via_port = vb->port;
1311 contact_info.via_prot = vb->proto;
1312 contact_info.searchflag = SEARCH_NORMAL;
1313 contact_info.received_host.s = 0;
1314 contact_info.received_host.len = 0;
1315 contact_info.reg_state = PCONTACT_ANY; //search for any state
1316
1317 if (ul.get_pcontact(domain_t, &contact_info, &pcontact) != 0) {
1318 LM_ERR("This contact does not exist in PCSCF usrloc - error in cfg file\n");
1319 ul.unlock_udomain(domain_t, &vb->host, vb->port, vb->proto);
1320 lock_release(saved_t_data->lock);
1321 goto error;
1322 } else if (pcontact->reg_state == PCONTACT_REG_PENDING
1323 || pcontact->reg_state == PCONTACT_REGISTERED) { //NEW reg request
1324 LM_DBG("Contact [%.*s] exists and is in state PCONTACT_REG_PENDING or PCONTACT_REGISTERED\n"
1325 , pcontact->aor.len, pcontact->aor.s);
1326
1327 //check for existing Rx session
1328 if (pcontact->rx_session_id.len > 0
1329 && pcontact->rx_session_id.s
1330 && (auth = cdpb.AAAGetAuthSession(pcontact->rx_session_id))) {
1331 LM_DBG("Rx session already exists for this user\n");
1332 if (memcmp(pcontact->rx_session_id.s, auth->id.s, auth->id.len) != 0) {
1333 LM_ERR("Rx session mismatch for rx_session_id [%.*s].......Aborting\n", pcontact->rx_session_id.len, pcontact->rx_session_id.s);
1334 if (auth) cdpb.AAASessionsUnlock(auth->hash);
1335 lock_release(saved_t_data->lock);
1336 goto error;
1337 }
1338 //re-registration - update auth lifetime
1339 auth->u.auth.lifetime = time(NULL) + rx_auth_expiry;
1340 is_rereg = 1;
1341 } else {
1342 LM_DBG("Creating new Rx session for contact <%.*s>\n", pcontact->aor.len, pcontact->aor.s);
1343 int ret = create_new_regsessiondata(domain_t->name, &pcontact->aor, &recv_ip, ip_version, recv_port, recv_proto, &vb->host, vb->port, vb->proto, &rx_regsession_data_p);
1344 if (!ret) {
1345 LM_ERR("Unable to create regsession data parcel for rx_session_id [%.*s]...Aborting\n", pcontact->rx_session_id.len, pcontact->rx_session_id.s);
1346 ul.unlock_udomain(domain_t, &vb->host, vb->port, vb->proto);
1347 if (rx_regsession_data_p) {
1348 shm_free(rx_regsession_data_p);
1349 rx_regsession_data_p = 0;
1350 }
1351 lock_release(saved_t_data->lock);
1352 goto error;
1353 }
1354 auth = cdpb.AAACreateClientAuthSession(1, callback_for_cdp_session, rx_regsession_data_p); //returns with a lock
1355 if (!auth) {
1356 LM_ERR("Rx: unable to create new Rx Reg Session for rx_session_id is [%.*s]\n", pcontact->rx_session_id.len, pcontact->rx_session_id.s);
1357 if (rx_regsession_data_p) {
1358 shm_free(rx_regsession_data_p);
1359 rx_regsession_data_p = 0;
1360 }
1361 ul.unlock_udomain(domain_t, &vb->host, via_port, via_proto);
1362 if (auth) cdpb.AAASessionsUnlock(auth->hash);
1363 if (rx_regsession_data_p) {
1364 shm_free(rx_regsession_data_p);
1365 rx_regsession_data_p = 0;
1366 }
1367 lock_release(saved_t_data->lock);
1368 goto error;
1369 }
1370 auth->u.auth.class = AUTH_CLASS_RXREG;
1371 }
1372
1373 //we are ready to send the AAR async. lets save the local data data
1374 int local_data_len = sizeof(saved_transaction_local_t) + c->uri.len + auth->id.len + vb->host.len + recv_ip.len;
1375 local_data = shm_malloc(local_data_len);
1376 if (!local_data) {
1377 LM_ERR("unable to alloc memory for local data, trying to send AAR Register\n");
1378 lock_release(saved_t_data->lock);
1379 goto error;
1380 }
1381 memset(local_data, 0, local_data_len);
1382
1383 local_data->is_rereg = is_rereg;
1384 local_data->global_data = saved_t_data;
1385 p = (char*) (local_data + 1);
1386
1387 local_data->contact.s = p;
1388 local_data->contact.len = c->uri.len;
1389 memcpy(p, c->uri.s, c->uri.len);
1390 p += c->uri.len;
1391
1392 local_data->auth_session_id.s = p;
1393 local_data->auth_session_id.len = auth->id.len;
1394 memcpy(p, auth->id.s, auth->id.len);
1395 p += auth->id.len;
1396
1397 local_data->via_host.s = p;
1398 local_data->via_host.len = vb->host.len;
1399 memcpy(p, vb->host.s, vb->host.len);
1400 p += vb->host.len;
1401
1402 local_data->recv_host.s = p;
1403 local_data->recv_host.len = recv_ip.len;
1404 memcpy(p, recv_ip.s, recv_ip.len);
1405 p += recv_ip.len;
1406
1407 local_data->via_port = via_port;
1408 local_data->via_proto = via_proto;
1409 local_data->recv_port = recv_port;
1410 local_data->recv_proto = recv_proto;
1411
1412 if (p != (((char*) local_data) + local_data_len)) {
1413 LM_CRIT("buffer overflow\n");
1414 free_saved_transaction_data(local_data);
1415 goto error;
1416 }
1417
1418 LM_DBG("Calling send aar register");
1419
1420 //TODOD remove - no longer user AOR parm
1421 //ret = rx_send_aar_register(msg, auth, &puri.host, &ip_version, &c->uri, local_data); //returns a locked rx auth object
1422 ret = rx_send_aar_register(msg, auth, local_data); //returns a locked rx auth object
1423
1424 ul.unlock_udomain(domain_t, &vb->host, via_port, via_proto);
1425
1426 if (!ret) {
1427 LM_ERR("Failed to send AAR\n");
1428 lock_release(saved_t_data->lock);
1429 free_saved_transaction_data(local_data); //free the local data becuase the CDP async request was not successful (we must free here)
1430 goto error;
1431 } else {
1432 aar_sent = 1;
1433 //before we send - bump up the reply counter
1434 saved_t_data->answers_not_received++; //we dont need to lock as we already hold the lock above
1435 }
1436 } else {
1437 //contact exists - this is a re-registration, for now we just ignore this
1438 LM_DBG("This contact exists and is not in state REGISTER PENDING - we assume re (or de) registration and ignore\n");
1439 ul.unlock_udomain(domain_t, &vb->host, via_port, via_proto);
1440 //now we loop for any other contacts.
1441 }
1442 }
1443 } else {
1444 if (h->type == HDR_CONTACT_T) { //means we couldnt parse the contact - this is an error
1445 LM_ERR("Failed to parse contact header\n");
1446 lock_release(saved_t_data->lock);
1447 goto error;
1448 }
1449 }
1450 }
1451 //all requests sent at this point - we can unlock the reply lock
1452 lock_release(saved_t_data->lock);
1453
1454 /*if we get here, we have either:
1455 * 1. Successfully sent AAR's for ALL contacts, or
1456 * 2. haven't needed to send ANY AAR's for ANY contacts
1457 */
1458 if (aar_sent) {
1459 LM_DBG("Successful async send of AAR\n");
1460 return CSCF_RETURN_BREAK; //on success we break - because rest of cfg file will be executed by async process
1461 } else {
1462 create_return_code(CSCF_RETURN_TRUE);
1463 tmb.t_cancel_suspend(saved_t_data->tindex, saved_t_data->tlabel);
1464 if (saved_t_data) {
1465 free_saved_transaction_global_data(saved_t_data); //no aar sent so we must free the global data
1466 }
1467 //return CSCF_RETURN_ERROR;
1468 return CSCF_RETURN_TRUE;
1469 }
1470 error:
1471 LM_ERR("Error trying to send AAR\n");
1472 if (!aar_sent) {
1473 tmb.t_cancel_suspend(saved_t_data->tindex, saved_t_data->tlabel);
1474 if (saved_t_data) {
1475
1476 free_saved_transaction_global_data(saved_t_data); //only free global data if no AARs were sent. if one was sent we have to rely on the callback (CDP) to free
1477 //otherwise the callback will segfault
1478 }
1479 }
1480 return CSCF_RETURN_ERROR;
1481 //return CSCF_RETURN_FALSE;
1482 }
1483
fixup_aar_register(void ** param,int param_no)1484 static int fixup_aar_register(void** param, int param_no)
1485 {
1486 // udomain_t* d;
1487 // aar_param_t *ap;
1488 //
1489 // if (param_no != 1)
1490 // return 0;
1491 // ap = (aar_param_t*) pkg_malloc(sizeof (aar_param_t));
1492 // if (ap == NULL) {
1493 // LM_ERR("no more pkg\n");
1494 // return -1;
1495 // }
1496 // memset(ap, 0, sizeof (aar_param_t));
1497 // ap->paction = get_action_from_param(param, param_no);
1498 //
1499 // if (ul.register_udomain((char*) *param, &d) < 0) {
1500 // LM_ERR("failed to register domain\n");
1501 // return E_UNSPEC;
1502 // }
1503 // ap->domain = d;
1504 //
1505 // *param = (void*) ap;
1506 // return 0;
1507 if (strlen((char*) *param) <= 0) {
1508 LM_ERR("empty parameter %d not allowed\n", param_no);
1509 return -1;
1510 }
1511
1512 if (param_no == 1) { //route name - static or dynamic string (config vars)
1513 if (fixup_spve_null(param, param_no) < 0)
1514 return -1;
1515 return 0;
1516 } else if (param_no == 2) {
1517 udomain_t* d;
1518
1519 if (ul.register_udomain((char*) *param, &d) < 0) {
1520 LM_ERR("Error doing fixup on assign save");
1521
1522 return -1;
1523 }
1524 *param = (void*) d;
1525 }
1526
1527 return 0;
1528 }
1529
fixup_aar(void ** param,int param_no)1530 static int fixup_aar(void** param, int param_no)
1531 {
1532 str s;
1533 int num;
1534
1535 //param 3 can be empty
1536 if (param_no != 3 && strlen((char*) *param) <= 0) {
1537 LM_ERR("empty parameter %d not allowed\n", param_no);
1538 return -1;
1539 }
1540
1541 if (param_no == 1) { //route name - static or dynamic string (config vars)
1542 if (fixup_spve_null(param, param_no) < 0)
1543 return -1;
1544 return 0;
1545 } else if (param_no == 3) {
1546 return fixup_var_str_12(param, param_no);
1547 } else if (param_no == 4) {
1548 /*convert to int */
1549 s.s = (char*) *param;
1550 s.len = strlen(s.s);
1551 if (str2sint(&s, &num) == 0) {
1552 pkg_free(*param);
1553 *param = (void*) (unsigned long) num;
1554 return 0;
1555 }
1556 LM_ERR("Bad subscription id: <%s>n", (char*) (*param));
1557
1558 return E_CFG;
1559 }
1560
1561 return 0;
1562 }
1563
1564 /*create a return code to be passed back into config file*/
create_return_code(int result)1565 int create_return_code(int result)
1566 {
1567 int rc;
1568 int_str avp_val, avp_name;
1569 avp_name.s.s = "aar_return_code";
1570 avp_name.s.len = 15;
1571
1572 LM_DBG("Creating return code of [%d] for aar_return_code\n", result);
1573 //build avp spec for uaa_return_code
1574 avp_val.n = result;
1575
1576 rc = add_avp(AVP_NAME_STR, avp_name, avp_val);
1577
1578 if (rc < 0)
1579 LM_ERR("couldn't create [aar_return_code] AVP\n");
1580 else
1581 LM_DBG("created AVP successfully : [%.*s]\n", avp_name.s.len, avp_name.s.s);
1582
1583 return rc;
1584 }
1585