00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "../../qvalue.h"
00028 #include "../../mem/mem.h"
00029 #include "../../socket_info.h"
00030 #include "../../usr_avp.h"
00031 #include "../../dset.h"
00032 #include "../../parser/msg_parser.h"
00033 #include "../../ut.h"
00034 #include "config.h"
00035 #include "t_funcs.h"
00036 #include "t_lookup.h"
00037
00038
00039 #define Q_FLAG (1<<2)
00040
00041
00042 int fr_inv_timer_next = INV_FR_TIME_OUT_NEXT;
00043
00044
00045 struct contact {
00046 str uri;
00047 qvalue_t q;
00048 str dst_uri;
00049 str path;
00050 unsigned int flags;
00051 struct socket_info* sock;
00052 unsigned short q_flag;
00053 struct contact *next;
00054 };
00055
00056
00057
00058
00059 static inline void free_contact_list(struct contact *curr) {
00060 struct contact *prev;
00061 while (curr) {
00062 prev = curr;
00063 curr = curr->next;
00064 pkg_free(prev);
00065 }
00066 }
00067
00068
00069 static inline int encode_branch_info(str *info, struct contact *con)
00070 {
00071 char *at, *s;
00072 int len;
00073
00074 info->len = con->uri.len + con->dst_uri.len +
00075 con->path.len + MAX_SOCKET_STR + INT2STR_MAX_LEN + 5;
00076 info->s = pkg_malloc(info->len);
00077 if (!info->s) {
00078 LM_ERR("no memory left for branch info\n");
00079 return 0;
00080 }
00081 at = info->s;
00082 append_str(at, con->uri.s, con->uri.len);
00083 append_chr(at, '\n');
00084 append_str(at, con->dst_uri.s, con->dst_uri.len);
00085 append_chr(at, '\n');
00086 append_str(at, con->path.s, con->path.len);
00087 append_chr(at, '\n');
00088 if (con->sock) {
00089 len = MAX_SOCKET_STR;
00090 if (!socket2str(con->sock, at, &len)) {
00091 LM_ERR("failed to convert socket to str\n");
00092 return 0;
00093 }
00094 } else {
00095 len = 0;
00096 }
00097 at = at + len;
00098 append_chr(at, '\n');
00099 s = int2str(con->flags, &len);
00100 append_str(at, s, len);
00101 append_chr(at, '\n');
00102 info->len = at - info->s + 1;
00103
00104 return 1;
00105 }
00106
00107
00108
00109 static inline int decode_branch_info(char *info, str *uri, str *dst, str *path,
00110 struct socket_info **sock,
00111 unsigned int *flags)
00112 {
00113 str s, host;
00114 int port, proto;
00115 char *pos, *at;
00116
00117 pos = strchr(info, '\n');
00118 uri->len = pos - info;
00119 if (uri->len) {
00120 uri->s = info;
00121 } else {
00122 uri->s = 0;
00123 }
00124 at = pos + 1;
00125
00126 pos = strchr(at, '\n');
00127 dst->len = pos - at;
00128 if (dst->len) {
00129 dst->s = at;
00130 } else {
00131 dst->s = 0;
00132 }
00133 at = pos + 1;
00134
00135 pos = strchr(at, '\n');
00136 path->len = pos - at;
00137 if (path->len) {
00138 path->s = at;
00139 } else {
00140 path->s = 0;
00141 }
00142 at = pos + 1;
00143
00144 pos = strchr(at, '\n');
00145 s.len = pos - at;
00146 if (s.len) {
00147 s.s = at;
00148 if (parse_phostport(s.s, s.len, &host.s, &host.len,
00149 &port, &proto) != 0) {
00150 LM_ERR("parsing of socket info <%.*s> failed\n", s.len, s.s);
00151 return 0;
00152 }
00153 *sock = grep_sock_info(&host, (unsigned short)port,
00154 (unsigned short)proto);
00155 if (*sock == 0) {
00156 LM_ERR("invalid socket <%.*s>\n", s.len, s.s);
00157 return 0;
00158 }
00159 } else {
00160 *sock = 0;
00161 }
00162 at = pos + 1;
00163
00164 pos = strchr(at, '\n');
00165 s.len = pos - at;
00166 if (s.len) {
00167 s.s = at;
00168 if (str2int(&s, flags) != 0) {
00169 LM_ERR("failed to decode flags <%.*s>\n", s.len, s.s);
00170 return 0;
00171 }
00172 } else {
00173 *flags = 0;
00174 }
00175
00176 return 1;
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186 int t_load_contacts(struct sip_msg* msg, char* key, char* value)
00187 {
00188 str uri, tmp, dst_uri, path, branch_info, *ruri;
00189 qvalue_t first_q, q;
00190 struct contact *contacts, *next, *prev, *curr;
00191 int_str val;
00192 int first_idx, idx;
00193 struct socket_info* sock;
00194 unsigned int flags;
00195 struct cell *t;
00196
00197
00198 if (contacts_avp.n == 0) {
00199 LM_ERR("feature has been disabled - "
00200 "to enable define contacts_avp module parameter");
00201 return -1;
00202 }
00203
00204
00205 if (nr_branches == 0) {
00206 LM_DBG("nothing to do - no branches!\n");
00207 return 1;
00208 }
00209
00210 t = get_t();
00211 ruri = (str *)0;
00212
00213 if (!t || (t == T_UNDEFINED)) {
00214
00215
00216 ruri = GET_RURI(msg);
00217 if (!ruri) {
00218 LM_ERR("no Request-URI found\n");
00219 return -1;
00220 }
00221 first_q = get_ruri_q();
00222 first_idx = 0;
00223
00224 } else {
00225
00226
00227
00228 uri.s = get_branch(0, &uri.len, &first_q, &dst_uri, &path, &flags,
00229 &sock);
00230 first_idx = 1;
00231
00232 }
00233
00234
00235 for(idx = first_idx; (tmp.s = get_branch(idx, &tmp.len, &q, 0, 0, 0, 0))
00236 != 0; idx++) {
00237 if (q != first_q) {
00238 goto rest;
00239 }
00240 }
00241
00242 LM_DBG("nothing to do - all contacts have same q!\n");
00243 return 1;
00244
00245 rest:
00246
00247
00248 contacts = (struct contact *)pkg_malloc(sizeof(struct contact));
00249 if (!contacts) {
00250 LM_ERR("no memory for contact info\n");
00251 return -1;
00252 }
00253
00254 if (!t || (t == T_UNDEFINED)) {
00255
00256
00257 contacts->uri.s = ruri->s;
00258 contacts->uri.len = ruri->len;
00259 contacts->dst_uri = msg->dst_uri;
00260 contacts->sock = msg->force_send_socket;
00261 contacts->flags = getb0flags();
00262 contacts->path = msg->path_vec;
00263
00264 } else {
00265
00266
00267 contacts->uri = uri;
00268 contacts->q = first_q;
00269 contacts->dst_uri = dst_uri;
00270 contacts->sock = sock;
00271 contacts->flags = flags;
00272 contacts->path = path;
00273 }
00274
00275 contacts->q = first_q;
00276 contacts->next = (struct contact *)0;
00277
00278
00279
00280 for(idx = first_idx;
00281 (uri.s = get_branch(idx,&uri.len,&q,&dst_uri,&path,&flags,&sock))
00282 != 0;
00283 idx++ ) {
00284 next = (struct contact *)pkg_malloc(sizeof(struct contact));
00285 if (!next) {
00286 LM_ERR("no memory for contact info\n");
00287 free_contact_list(contacts);
00288 return -1;
00289 }
00290 next->uri = uri;
00291 next->q = q;
00292 next->dst_uri = dst_uri;
00293 next->path = path;
00294 next->flags = flags;
00295 next->sock = sock;
00296 next->next = (struct contact *)0;
00297 prev = (struct contact *)0;
00298 curr = contacts;
00299 while (curr && (curr->q < q)) {
00300 prev = curr;
00301 curr = curr->next;
00302 }
00303 if (!curr) {
00304 next->next = (struct contact *)0;
00305 prev->next = next;
00306 } else {
00307 next->next = curr;
00308 if (prev) {
00309 prev->next = next;
00310 } else {
00311 contacts = next;
00312 }
00313 }
00314 }
00315
00316
00317 curr = contacts;
00318 curr->q_flag = 0;
00319 while (curr->next) {
00320 if (curr->q < curr->next->q) {
00321 curr->next->q_flag = Q_FLAG;
00322 } else {
00323 curr->next->q_flag = 0;
00324 }
00325 curr = curr->next;
00326 }
00327
00328
00329 curr = contacts;
00330 while (curr) {
00331 if (encode_branch_info(&branch_info, curr) == 0) {
00332 LM_ERR("encoding of branch info failed\n");
00333 free_contact_list(contacts);
00334 if (branch_info.s) pkg_free(branch_info.s);
00335 return -1;
00336 }
00337 val.s = branch_info;
00338 add_avp(contacts_avp_type|AVP_VAL_STR|(curr->q_flag),
00339 contacts_avp, val);
00340 pkg_free(branch_info.s);
00341 LM_DBG("loaded contact <%.*s> with q_flag <%d>\n",
00342 val.s.len, val.s.s, curr->q_flag);
00343 curr = curr->next;
00344 }
00345
00346
00347 clear_branches();
00348
00349
00350 free_contact_list(contacts);
00351
00352 return 1;
00353 }
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 int t_next_contacts(struct sip_msg* msg, char* key, char* value)
00364 {
00365 struct usr_avp *avp, *prev;
00366 int_str val;
00367 str uri, dst, path;
00368 struct socket_info *sock;
00369 unsigned int flags;
00370 struct cell *t;
00371
00372
00373 if (contacts_avp.n == 0) {
00374 LM_ERR("feature has been disabled - "
00375 "to enable define contacts_avp module parameter");
00376 return -1;
00377 }
00378
00379 t = get_t();
00380
00381 if (!t || (t == T_UNDEFINED)) {
00382
00383
00384
00385 if (route_type == FAILURE_ROUTE) {
00386 LM_CRIT("BUG - undefined transaction in failure route\n");
00387 return -1;
00388 }
00389
00390
00391 avp = search_first_avp(contacts_avp_type, contacts_avp, &val, 0);
00392 if (!avp) {
00393 LM_DBG("no AVPs - we are done!\n");
00394 return 1;
00395 }
00396
00397 LM_DBG("next contact is <%s>\n", val.s.s);
00398
00399 if (decode_branch_info(val.s.s, &uri, &dst, &path, &sock, &flags)
00400 == 0) {
00401 LM_ERR("decoding of branch info <%.*s> failed\n",
00402 val.s.len, val.s.s);
00403 destroy_avp(avp);
00404 return -1;
00405 }
00406
00407
00408 rewrite_uri(msg, &uri);
00409 set_dst_uri(msg, &dst);
00410 set_path_vector(msg, &path);
00411 msg->force_send_socket = sock;
00412 setb0flags(flags);
00413
00414 if (avp->flags & Q_FLAG) {
00415 destroy_avp(avp);
00416
00417 val.n = fr_inv_timer_next;
00418 if (add_avp(fr_inv_timer_avp_type, fr_inv_timer_avp, val) != 0) {
00419 LM_ERR("setting of fr_inv_timer_avp failed\n");
00420 return -1;
00421 }
00422 return 1;
00423 }
00424
00425
00426 prev = avp;
00427 while ((avp = search_next_avp(avp, &val))) {
00428 destroy_avp(prev);
00429
00430 LM_DBG("next contact is <%s>\n", val.s.s);
00431
00432 if (decode_branch_info(val.s.s, &uri, &dst, &path, &sock, &flags)
00433 == 0) {
00434 LM_ERR("decoding of branch info <%.*s> failed\n",
00435 val.s.len, val.s.s);
00436 destroy_avp(avp);
00437 return -1;
00438 }
00439
00440 if (append_branch(msg, &uri, &dst, &path, 0, flags, sock) != 1) {
00441 LM_ERR("appending branch failed\n");
00442 destroy_avp(avp);
00443 return -1;
00444 }
00445
00446 if (avp->flags & Q_FLAG) {
00447 destroy_avp(avp);
00448 val.n = fr_inv_timer_next;
00449 if (add_avp(fr_inv_timer_avp_type, fr_inv_timer_avp, val)
00450 != 0) {
00451 LM_ERR("setting of fr_inv_timer_avp failed\n");
00452 return -1;
00453 }
00454 return 1;
00455 }
00456 prev = avp;
00457 }
00458
00459 } else {
00460
00461
00462
00463
00464 avp = search_first_avp(contacts_avp_type, contacts_avp, &val, 0);
00465 if (!avp) return -1;
00466
00467
00468 prev = avp;
00469 do {
00470
00471 LM_DBG("next contact is <%s>\n", val.s.s);
00472
00473 if (decode_branch_info(val.s.s, &uri, &dst, &path, &sock, &flags)
00474 == 0) {
00475 LM_ERR("decoding of branch info <%.*s> failed\n",
00476 val.s.len, val.s.s);
00477 destroy_avp(avp);
00478 return -1;
00479 }
00480
00481 if (append_branch(msg, &uri, &dst, &path, 0, flags, sock) != 1) {
00482 LM_ERR("appending branch failed\n");
00483 destroy_avp(avp);
00484 return -1;
00485 }
00486
00487 if (avp->flags & Q_FLAG) {
00488 destroy_avp(avp);
00489 return 1;
00490 }
00491
00492 prev = avp;
00493 avp = search_next_avp(avp, &val);
00494 destroy_avp(prev);
00495
00496 } while (avp);
00497
00498
00499 val.n = timer_id2timeout[FR_INV_TIMER_LIST];
00500 if (add_avp(fr_inv_timer_avp_type, fr_inv_timer_avp, val) != 0) {
00501 LM_ERR("setting of fr_inv_timer_avp failed\n");
00502 return -1;
00503 }
00504
00505 }
00506
00507 return 1;
00508 }