9fa0dcfd3c6c81f277975e74aeb708ef6ecc58fe
[sip-router] / modules / tm / t_serial.c
1 /*
2  * Serial forking functions
3  *
4  * Copyright (C) 2008 Juha Heinanen
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  *  1. Redistributions of source code must retain the above copyright notice,
10  *     this list of conditions and the following disclaimer.
11  *  2. Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
18  * EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
19  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * History:
27  * -------
28  *  2008-10-22: Moved functions from lcr module to tm module (jh)
29  */
30
31 #include "../../qvalue.h"
32 #include "../../mem/mem.h"
33 #include "../../socket_info.h"
34 #include "../../usr_avp.h"
35 #include "../../dset.h"
36 #include "../../parser/msg_parser.h"
37 #include "../../ut.h"
38 #include "config.h"
39 #include "t_funcs.h"
40 #include "t_lookup.h"
41
42 /* usr_avp flag for sequential forking */
43 #define Q_FLAG      (1<<2)
44
45 /* module parameter variable */
46 int fr_inv_timer_next = INV_FR_TIME_OUT_NEXT;
47
48 /* Struture where information regarding contacts is stored */
49 struct contact {
50     str uri;
51     qvalue_t q;
52     str dst_uri;
53     str path;
54     unsigned int flags;
55     struct socket_info* sock;
56     unsigned short q_flag;
57     struct contact *next;
58 };
59
60 /* 
61  * Frees contact list used by load_contacts function
62  */
63 static inline void free_contact_list(struct contact *curr) {
64     struct contact *prev;
65     while (curr) {
66                 prev = curr;
67                 curr = curr->next;
68                 pkg_free(prev);
69     }
70 }
71
72 /* Encode branch info from contact struct to str */
73 static inline int encode_branch_info(str *info, struct contact *con)
74 {
75     char *at, *s;
76     int len;
77
78     info->len = con->uri.len + con->dst_uri.len +
79                 con->path.len + MAX_SOCKET_STR + INT2STR_MAX_LEN + 5;
80     info->s = pkg_malloc(info->len);
81     if (!info->s) {
82                 LM_ERR("no memory left for branch info\n");
83                 return 0;
84     }
85     at = info->s;
86     append_str(at, con->uri.s, con->uri.len);
87     append_chr(at, '\n');
88     append_str(at, con->dst_uri.s, con->dst_uri.len);
89     append_chr(at, '\n');
90     append_str(at, con->path.s, con->path.len);
91     append_chr(at, '\n');
92     if (con->sock) {
93                 len = MAX_SOCKET_STR;
94                 if (socket2str(at, &len, con->sock) < 0) {
95                         LM_ERR("failed to convert socket to str\n");
96                         return 0;
97                 }
98     } else {
99                 len = 0;
100     }
101     at = at + len;
102     append_chr(at, '\n');
103     s = int2str(con->flags, &len);
104     append_str(at, s, len);
105     append_chr(at, '\n');
106     info->len = at - info->s + 1;
107
108     return 1;
109 }
110
111
112 /* Encode branch info from str */
113 static inline int decode_branch_info(char *info, str *uri, str *dst, str *path,
114                                                                          struct socket_info **sock,
115                                                                          unsigned int *flags)
116 {
117     str s, host;
118     int port, proto;
119     char *pos, *at, *tmp;
120
121     pos = strchr(info, '\n');
122     uri->len = pos - info;
123     if (uri->len) {
124                 uri->s = info;
125     } else {
126                 uri->s = 0;
127     }
128     at = pos + 1;
129
130     pos = strchr(at, '\n');
131     dst->len = pos - at;
132     if (dst->len) {
133                 dst->s = at;
134     } else {
135                 dst->s = 0;
136     }
137     at = pos + 1;
138
139     pos = strchr(at, '\n');
140     path->len = pos - at;
141     if (path->len) {
142                 path->s = at;
143     } else {
144                 path->s = 0;
145     }
146     at = pos + 1;
147
148     pos = strchr(at, '\n');
149     s.len = pos - at;
150     if (s.len) {
151                 s.s = at;
152                 if ((tmp = as_asciiz(&s)) == NULL) {
153                         ERR("No memory left\n");
154                         return 0;
155                 }
156                 if (parse_phostport(tmp, &host.s, &host.len,
157                                                         &port, &proto) != 0) {
158                         LM_ERR("parsing of socket info <%.*s> failed\n",  s.len, s.s);
159                         pkg_free(tmp);
160                         return 0;
161                 }
162                 pkg_free(tmp);
163                 *sock = grep_sock_info(&host, (unsigned short)port,
164                                                            (unsigned short)proto);
165                 if (*sock == 0) {
166                         LM_ERR("invalid socket <%.*s>\n", s.len, s.s);
167                         return 0;
168                 }
169     } else {
170                 *sock = 0;
171     }
172     at = pos + 1;
173
174     pos = strchr(at, '\n');
175     s.len = pos - at;
176     if (s.len) {
177                 s.s = at;
178                 if (str2int(&s, flags) != 0) {
179                         LM_ERR("failed to decode flags <%.*s>\n", s.len, s.s);
180                         return 0;
181                 }
182     } else {
183                 *flags = 0;
184     }
185
186     return 1;
187 }
188
189
190 /* 
191  * Loads contacts in destination set into contacts_avp in reverse
192  * priority order and associated each contact with Q_FLAG telling if
193  * contact is the last one in its priority class.  Finally, removes
194  * all branches from destination set.
195  */
196 int t_load_contacts(struct sip_msg* msg, char* key, char* value)
197 {
198     str uri, tmp, dst_uri, path, branch_info, *ruri;
199     qvalue_t first_q, q;
200     struct contact *contacts, *next, *prev, *curr;
201     int_str val;
202     int first_idx, idx;
203     struct socket_info* sock;
204     unsigned int flags;
205     struct cell *t;
206
207     /* Check if contacts_avp has been defined */
208     if (contacts_avp.n == 0) {
209                 LM_ERR("feature has been disabled - "
210                            "to enable define contacts_avp module parameter");
211                 return -1;
212     }
213
214     /* Check if anything needs to be done */
215     if (nr_branches == 0) {
216                 LM_DBG("nothing to do - no branches!\n");
217                 return 1;
218     }
219
220     t = get_t();
221     ruri = (str *)0;
222
223     if (!t || (t == T_UNDEFINED)) {
224
225                 /* No transaction yet - take first q from Request-URI */
226                 ruri = GET_RURI(msg);
227                 if (!ruri) {
228                         LM_ERR("no Request-URI found\n");
229                         return -1;
230                 }
231                 first_q = get_ruri_q();
232                 first_idx = 0;
233
234     } else {
235
236                 /* Transaction exists - take first q from first branch */
237         
238                 uri.s = get_branch(0, &uri.len, &first_q, &dst_uri, &path, &flags,
239                                                    &sock);
240                 first_idx = 1;
241
242     }
243
244     /* Check if all q values are equal */
245     for(idx = first_idx; (tmp.s = get_branch(idx, &tmp.len, &q, 0, 0, 0, 0))
246                         != 0; idx++) {
247                 if (q != first_q) {
248                         goto rest;
249                 }
250     }
251
252     LM_DBG("nothing to do - all contacts have same q!\n");
253     return 1;
254
255 rest:
256
257     /* Allocate memory for first contact */
258     contacts = (struct contact *)pkg_malloc(sizeof(struct contact));
259     if (!contacts) {
260                 LM_ERR("no memory for contact info\n");
261                 return -1;
262     }
263
264     if (!t || (t == T_UNDEFINED)) {
265
266                 /* Insert Request-URI branch to first contact */
267                 contacts->uri.s = ruri->s;
268                 contacts->uri.len = ruri->len;
269                 contacts->dst_uri = msg->dst_uri;
270                 contacts->sock = msg->force_send_socket;
271                 getbflagsval(0, &contacts->flags);
272                 contacts->path = msg->path_vec;
273
274     } else {
275         
276                 /* Insert first branch to first contact */
277                 contacts->uri = uri;
278                 contacts->q = first_q;
279                 contacts->dst_uri = dst_uri;
280                 contacts->sock = sock;
281                 contacts->flags = flags;
282                 contacts->path = path;
283     }
284
285     contacts->q = first_q;
286     contacts->next = (struct contact *)0;
287
288     /* Insert (remaining) branches to contact list in increasing q order */
289
290     for(idx = first_idx;
291                 (uri.s = get_branch(idx,&uri.len,&q,&dst_uri,&path,&flags,&sock))
292                         != 0;
293                 idx++ ) {
294                 next = (struct contact *)pkg_malloc(sizeof(struct contact));
295                 if (!next) {
296                         LM_ERR("no memory for contact info\n");
297                         free_contact_list(contacts);
298                         return -1;
299                 }
300                 next->uri = uri;
301                 next->q = q;
302                 next->dst_uri = dst_uri;
303                 next->path = path;
304                 next->flags = flags;
305                 next->sock = sock;
306                 next->next = (struct contact *)0;
307                 prev = (struct contact *)0;
308                 curr = contacts;
309                 while (curr && (curr->q < q)) {
310                         prev = curr;
311                         curr = curr->next;
312                 }
313                 if (!curr) {
314                         next->next = (struct contact *)0;
315                         prev->next = next;
316                 } else {
317                         next->next = curr;
318                         if (prev) {
319                                 prev->next = next;
320                         } else {
321                                 contacts = next;
322                         }
323                 }    
324     }
325
326     /* Assign values for q_flags */
327     curr = contacts;
328     curr->q_flag = 0;
329     while (curr->next) {
330                 if (curr->q < curr->next->q) {
331                         curr->next->q_flag = Q_FLAG;
332                 } else {
333                         curr->next->q_flag = 0;
334                 }
335                 curr = curr->next;
336     }
337
338     /* Add contacts to contacts_avp */
339     curr = contacts;
340     while (curr) {
341                 if (encode_branch_info(&branch_info, curr) == 0) {
342                         LM_ERR("encoding of branch info failed\n");
343                         free_contact_list(contacts);
344                         if (branch_info.s) pkg_free(branch_info.s);
345                         return -1;
346                 }
347                 val.s = branch_info;
348                 add_avp(contacts_avp_type|AVP_VAL_STR|(curr->q_flag),
349                                 contacts_avp, val);
350                 pkg_free(branch_info.s);
351                 LM_DBG("loaded contact <%.*s> with q_flag <%d>\n",
352                            val.s.len, val.s.s, curr->q_flag);
353                 curr = curr->next;
354     }
355
356     /* Clear all branches */
357     clear_branches();
358
359     /* Free contact list */
360     free_contact_list(contacts);
361
362     return 1;
363 }
364
365
366 /*
367  * Adds to request a destination set that includes all highest priority
368  * class contacts in contacts_avp.   If called from a route block,
369  * rewrites the request uri with first contact and adds the remaining
370  * contacts as branches.  If called from failure route block, adds all
371  * contacts as branches.  Removes added contacts from contacts_avp.
372  */
373 int t_next_contacts(struct sip_msg* msg, char* key, char* value)
374 {
375     struct usr_avp *avp, *prev;
376     int_str val;
377     str uri, dst, path;
378     struct socket_info *sock;
379     unsigned int flags;
380     struct cell *t;
381         struct search_state st;
382
383     /* Check if contacts_avp has been defined */
384     if (contacts_avp.n == 0) {
385                 LM_ERR("feature has been disabled - "
386                            "to enable define contacts_avp module parameter");
387                 return -1;
388     }
389
390     t = get_t();
391
392     if (!t || (t == T_UNDEFINED)) {
393
394                 /* no transaction yet => load Request-URI and branches */
395
396                 if (route_type == FAILURE_ROUTE) {
397                         LM_CRIT("BUG - undefined transaction in failure route\n");
398                         return -1;
399                 }
400
401                 /* Find first contacts_avp value */
402                 avp = search_first_avp(contacts_avp_type, contacts_avp, &val, &st);
403                 if (!avp) {
404                         LM_DBG("no AVPs - we are done!\n");
405                         return 1;
406                 }
407
408                 LM_DBG("next contact is <%s>\n", val.s.s);
409
410                 if (decode_branch_info(val.s.s, &uri, &dst, &path, &sock, &flags)
411                         == 0) {
412                         LM_ERR("decoding of branch info <%.*s> failed\n",
413                                    val.s.len, val.s.s);
414                         destroy_avp(avp);
415                         return -1;
416                 }
417
418                 /* Rewrite Request-URI */
419                 rewrite_uri(msg, &uri);
420                 set_dst_uri(msg, &dst);
421                 set_path_vector(msg, &path);
422                 msg->force_send_socket = sock;
423                 setbflagsval(0, flags);
424
425                 if (avp->flags & Q_FLAG) {
426                         destroy_avp(avp);
427                         /* Set fr_inv_timer */
428                         val.n = fr_inv_timer_next;
429                         if (add_avp(fr_inv_timer_avp_type, fr_inv_timer_avp, val) != 0) {
430                                 LM_ERR("setting of fr_inv_timer_avp failed\n");
431                                 return -1;
432                         }
433                         return 1;
434                 }
435
436                 /* Append branches until out of branches or Q_FLAG is set */
437                 prev = avp;
438                 while ((avp = search_next_avp(&st, &val))) {
439                         destroy_avp(prev);
440
441                         LM_DBG("next contact is <%s>\n", val.s.s);
442
443                         if (decode_branch_info(val.s.s, &uri, &dst, &path, &sock, &flags)
444                                 == 0) {
445                                 LM_ERR("decoding of branch info <%.*s> failed\n",
446                                            val.s.len, val.s.s);
447                                 destroy_avp(avp);
448                                 return -1;
449                         }
450
451                         if (append_branch(msg, &uri, &dst, &path, 0, flags, sock) != 1) {
452                                 LM_ERR("appending branch failed\n");
453                                 destroy_avp(avp);
454                                 return -1;
455                         }
456
457                         if (avp->flags & Q_FLAG) {
458                                 destroy_avp(avp);
459                                 val.n = fr_inv_timer_next;
460                                 if (add_avp(fr_inv_timer_avp_type, fr_inv_timer_avp, val)
461                                         != 0) {
462                                         LM_ERR("setting of fr_inv_timer_avp failed\n");
463                                         return -1;
464                                 }
465                                 return 1;
466                         }
467                         prev = avp;
468                 }
469         
470     } else {
471         
472                 /* Transaction exists => only load branches */
473
474                 /* Find first contacts_avp value */
475                 avp = search_first_avp(contacts_avp_type, contacts_avp, &val, &st);
476                 if (!avp) return -1;
477
478                 /* Append branches until out of branches or Q_FLAG is set */
479                 prev = avp;
480                 do {
481
482                         LM_DBG("next contact is <%s>\n", val.s.s);
483
484                         if (decode_branch_info(val.s.s, &uri, &dst, &path, &sock, &flags)
485                                 == 0) {
486                                 LM_ERR("decoding of branch info <%.*s> failed\n",
487                                            val.s.len, val.s.s);
488                                 destroy_avp(avp);
489                                 return -1;
490                         }
491         
492                         if (append_branch(msg, &uri, &dst, &path, 0, flags, sock) != 1) {
493                                 LM_ERR("appending branch failed\n");
494                                 destroy_avp(avp);
495                                 return -1;
496                         }
497
498                         if (avp->flags & Q_FLAG) {
499                                 destroy_avp(avp);
500                                 return 1;
501                         }
502
503                         prev = avp;
504                         avp = search_next_avp(&st, &val);
505                         destroy_avp(prev);
506
507                 } while (avp);
508
509                 /* Restore fr_inv_timer */
510                 val.n = default_tm_cfg.fr_inv_timeout;
511                 if (add_avp(fr_inv_timer_avp_type, fr_inv_timer_avp, val) != 0) {
512                         LM_ERR("setting of fr_inv_timer_avp failed\n");
513                         return -1;
514                 }
515         
516     }
517
518     return 1;
519 }