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
00028
00029 #include <string.h>
00030 #include "dprint.h"
00031 #include "config.h"
00032 #include "parser/parser_f.h"
00033 #include "parser/msg_parser.h"
00034 #include "ut.h"
00035 #include "hash_func.h"
00036 #include "error.h"
00037 #include "dset.h"
00038 #include "mem/mem.h"
00039 #include "ip_addr.h"
00040
00041 #define CONTACT "Contact: "
00042 #define CONTACT_LEN (sizeof(CONTACT) - 1)
00043
00044 #define CONTACT_DELIM ", "
00045 #define CONTACT_DELIM_LEN (sizeof(CONTACT_DELIM) - 1)
00046
00047 #define Q_PARAM ">;q="
00048 #define Q_PARAM_LEN (sizeof(Q_PARAM) - 1)
00049
00050 struct branch
00051 {
00052 char uri[MAX_URI_SIZE];
00053 unsigned int len;
00054
00055
00056 char dst_uri[MAX_URI_SIZE];
00057 unsigned int dst_uri_len;
00058
00059
00060 char path[MAX_PATH_SIZE];
00061 unsigned int path_len;
00062
00063 int q;
00064 struct socket_info* force_send_socket;
00065 unsigned int flags;
00066 };
00067
00068
00069
00070
00071
00072
00073 static struct branch branches[MAX_BRANCHES - 1];
00074
00075 #ifdef USE_LOCAL_ROUTE
00076 static unsigned char dset_state = 1 ;
00077 #endif
00078
00079
00080 unsigned int nr_branches = 0;
00081
00082
00083 static qvalue_t ruri_q = Q_UNSPECIFIED;
00084
00085
00086
00087 static unsigned int ruri_bflags = 0;
00088
00089
00090
00091 static inline unsigned int* get_ptr_bflags(unsigned int b_idx)
00092 {
00093 if (b_idx==0) {
00094 return &ruri_bflags;
00095 } else {
00096 if (b_idx-1<nr_branches) {
00097 return &branches[b_idx-1].flags;
00098 } else {
00099 return 0;
00100 }
00101 }
00102 }
00103
00104
00105
00106
00107
00108 unsigned int getb0flags(void)
00109 {
00110 return ruri_bflags;
00111 }
00112
00113
00114 unsigned int setb0flags( unsigned int flags)
00115 {
00116 ruri_bflags = flags;
00117 return 0;
00118 }
00119
00120
00121 int setbflag(unsigned int b_idx, unsigned int mask)
00122 {
00123 unsigned int *flags;
00124
00125 flags = get_ptr_bflags( b_idx );
00126 if (flags==0)
00127 return -1;
00128
00129 (*flags) |= mask;
00130 return 1;
00131 }
00132
00133
00134
00135
00136
00137 int isbflagset(unsigned int b_idx, unsigned int mask)
00138 {
00139 unsigned int *flags;
00140
00141 flags = get_ptr_bflags( b_idx );
00142 if (flags==0)
00143 return -1;
00144
00145 return ( (*flags) & mask) ? 1 : -1;
00146 }
00147
00148
00149
00150
00151
00152 int resetbflag(unsigned int b_idx, unsigned int mask)
00153 {
00154 unsigned int *flags;
00155
00156 flags = get_ptr_bflags( b_idx );
00157 if (flags==0)
00158 return -1;
00159
00160 (*flags) &= ~mask;
00161 return 1;
00162 }
00163
00164
00165 #ifdef USE_LOCAL_ROUTE
00166
00167
00168 void set_dset_state(unsigned char enable)
00169 {
00170 static unsigned int bk_nr_branches;
00171 static qvalue_t bk_ruri_q;
00172 static unsigned int bk_ruri_bflags;
00173
00174 if (enable) {
00175
00176 if (dset_state==1) return;
00177
00178 nr_branches = bk_nr_branches;
00179 bk_nr_branches = 0;
00180 ruri_q = bk_ruri_q;
00181 bk_ruri_q = Q_UNSPECIFIED;
00182 ruri_bflags = bk_ruri_bflags;
00183 bk_ruri_bflags = 0;
00184
00185 dset_state = 1;
00186 } else {
00187
00188 if (dset_state==0) return;
00189
00190 bk_nr_branches = nr_branches;
00191 nr_branches = 0;
00192 bk_ruri_q = ruri_q;
00193 ruri_q = Q_UNSPECIFIED;
00194 bk_ruri_bflags = ruri_bflags;
00195 ruri_bflags = 0;
00196
00197 dset_state = 0;
00198 }
00199 }
00200 #endif
00201
00202
00203
00204
00205
00206
00207
00208 char* get_branch(unsigned int idx, int* len, qvalue_t* q, str* dst_uri,
00209 str* path, unsigned int *flags, struct socket_info** force_socket)
00210 {
00211 if (idx < nr_branches) {
00212 *len = branches[idx].len;
00213 *q = branches[idx].q;
00214 if (dst_uri) {
00215 dst_uri->len = branches[idx].dst_uri_len;
00216 dst_uri->s = (dst_uri->len)?branches[idx].dst_uri:0;
00217 }
00218 if (path) {
00219 path->len = branches[idx].path_len;
00220 path->s = (path->len)?branches[idx].path:0;
00221 }
00222 if (force_socket)
00223 *force_socket = branches[idx].force_send_socket;
00224 if (flags)
00225 *flags = branches[idx].flags;
00226 return branches[idx].uri;
00227 } else {
00228 *len = 0;
00229 *q = Q_UNSPECIFIED;
00230 if (dst_uri) {
00231 dst_uri->s = 0;
00232 dst_uri->len = 0;
00233 }
00234 if (force_socket)
00235 *force_socket = 0;
00236 if (flags)
00237 *flags = 0;
00238 return 0;
00239 }
00240 }
00241
00242
00243
00244
00245
00246 void clear_branches(void)
00247 {
00248 nr_branches = 0;
00249 ruri_q = Q_UNSPECIFIED;
00250 ruri_bflags = 0;
00251 }
00252
00253
00254
00255
00256
00257 int append_branch(struct sip_msg* msg, str* uri, str* dst_uri, str* path,
00258 qvalue_t q, unsigned int flags, struct socket_info* force_socket)
00259 {
00260 str luri;
00261
00262 #ifdef USE_LOCAL_ROUTE
00263 if (dset_state==0)
00264 return -1;
00265 #endif
00266
00267
00268
00269
00270 if (nr_branches == MAX_BRANCHES - 1) {
00271 LM_ERR("max nr of branches exceeded\n");
00272 ser_error = E_TOO_MANY_BRANCHES;
00273 return -1;
00274 }
00275
00276
00277 if (uri==0 || uri->len==0 || uri->s==0) {
00278 if (msg->new_uri.s)
00279 luri = msg->new_uri;
00280 else
00281 luri = msg->first_line.u.request.uri;
00282 } else {
00283 luri = *uri;
00284 }
00285
00286 if (luri.len > MAX_URI_SIZE - 1) {
00287 LM_ERR("too long uri: %.*s\n", luri.len, luri.s);
00288 return -1;
00289 }
00290
00291
00292 if (dst_uri && dst_uri->len && dst_uri->s) {
00293 if (dst_uri->len > MAX_URI_SIZE - 1) {
00294 LM_ERR("too long dst_uri: %.*s\n",
00295 dst_uri->len, dst_uri->s);
00296 return -1;
00297 }
00298 memcpy(branches[nr_branches].dst_uri, dst_uri->s, dst_uri->len);
00299 branches[nr_branches].dst_uri[dst_uri->len] = 0;
00300 branches[nr_branches].dst_uri_len = dst_uri->len;
00301 } else {
00302 branches[nr_branches].dst_uri[0] = '\0';
00303 branches[nr_branches].dst_uri_len = 0;
00304 }
00305
00306
00307 if (path && path->len && path->s) {
00308 if (path->len > MAX_PATH_SIZE - 1) {
00309 LM_ERR("too long path: %.*s\n", path->len, path->s);
00310 return -1;
00311 }
00312 memcpy(branches[nr_branches].path, path->s, path->len);
00313 branches[nr_branches].path[path->len] = 0;
00314 branches[nr_branches].path_len = path->len;
00315 } else {
00316 branches[nr_branches].path[0] = '\0';
00317 branches[nr_branches].path_len = 0;
00318 }
00319
00320
00321 memcpy(branches[nr_branches].uri, luri.s, luri.len);
00322 branches[nr_branches].uri[luri.len] = 0;
00323 branches[nr_branches].len = luri.len;
00324 branches[nr_branches].q = q;
00325
00326 branches[nr_branches].force_send_socket = force_socket;
00327 branches[nr_branches].flags = flags;
00328
00329 nr_branches++;
00330 return 1;
00331 }
00332
00333
00334
00335
00336
00337
00338 char* print_dset(struct sip_msg* msg, int* len)
00339 {
00340 int cnt, i, idx;
00341 unsigned int qlen;
00342 qvalue_t q;
00343 str uri;
00344 char* p, *qbuf;
00345 static char dset[MAX_REDIRECTION_LEN];
00346
00347 if (msg->new_uri.s) {
00348 cnt = 1;
00349 *len = msg->new_uri.len;
00350 if (ruri_q != Q_UNSPECIFIED) {
00351 *len += 1 + Q_PARAM_LEN + len_q(ruri_q);
00352 }
00353 } else {
00354 cnt = 0;
00355 *len = 0;
00356 }
00357
00358 for( idx=0 ; (uri.s=get_branch(idx,&uri.len,&q,0,0,0,0))!=0 ; idx++ ) {
00359 cnt++;
00360 *len += uri.len;
00361 if (q != Q_UNSPECIFIED) {
00362 *len += 1 + Q_PARAM_LEN + len_q(q);
00363 }
00364 }
00365
00366 if (cnt == 0) return 0;
00367
00368 *len += CONTACT_LEN + CRLF_LEN + (cnt - 1) * CONTACT_DELIM_LEN;
00369
00370 if (*len + 1 > MAX_REDIRECTION_LEN) {
00371 LM_ERR("redirection buffer length exceed\n");
00372 return 0;
00373 }
00374
00375 memcpy(dset, CONTACT, CONTACT_LEN);
00376 p = dset + CONTACT_LEN;
00377 if (msg->new_uri.s) {
00378 if (ruri_q != Q_UNSPECIFIED) {
00379 *p++ = '<';
00380 }
00381
00382 memcpy(p, msg->new_uri.s, msg->new_uri.len);
00383 p += msg->new_uri.len;
00384
00385 if (ruri_q != Q_UNSPECIFIED) {
00386 memcpy(p, Q_PARAM, Q_PARAM_LEN);
00387 p += Q_PARAM_LEN;
00388
00389 qbuf = q2str(ruri_q, &qlen);
00390 memcpy(p, qbuf, qlen);
00391 p += qlen;
00392 }
00393 i = 1;
00394 } else {
00395 i = 0;
00396 }
00397
00398 for( idx=0 ; (uri.s=get_branch(idx,&uri.len,&q,0,0,0,0))!=0 ; idx++ ) {
00399 if (i) {
00400 memcpy(p, CONTACT_DELIM, CONTACT_DELIM_LEN);
00401 p += CONTACT_DELIM_LEN;
00402 }
00403
00404 if (q != Q_UNSPECIFIED) {
00405 *p++ = '<';
00406 }
00407
00408 memcpy(p, uri.s, uri.len);
00409 p += uri.len;
00410 if (q != Q_UNSPECIFIED) {
00411 memcpy(p, Q_PARAM, Q_PARAM_LEN);
00412 p += Q_PARAM_LEN;
00413
00414 qbuf = q2str(q, &qlen);
00415 memcpy(p, qbuf, qlen);
00416 p += qlen;
00417 }
00418 i++;
00419 }
00420
00421 memcpy(p, CRLF " ", CRLF_LEN + 1);
00422 return dset;
00423 }
00424
00425
00426
00427
00428
00429 void set_ruri_q(qvalue_t q)
00430 {
00431 ruri_q = q;
00432 }
00433
00434
00435
00436
00437
00438 qvalue_t get_ruri_q(void)
00439 {
00440 return ruri_q;
00441 }
00442
00443
00444
00445
00446
00447
00448 int get_request_uri(struct sip_msg* _m, str* _u)
00449 {
00450
00451 if (_m->new_uri.s) {
00452 _u->s = _m->new_uri.s;
00453 _u->len = _m->new_uri.len;
00454 } else {
00455 _u->s = _m->first_line.u.request.uri.s;
00456 _u->len = _m->first_line.u.request.uri.len;
00457 }
00458
00459 return 0;
00460 }
00461
00462
00463
00464
00465
00466 int rewrite_uri(struct sip_msg* _m, str* _s)
00467 {
00468 char* buf;
00469
00470 buf = (char*)pkg_malloc(_s->len + 1);
00471 if (!buf) {
00472 LM_ERR("No pkg memory left\n");
00473 return -1;
00474 }
00475
00476 memcpy(buf, _s->s, _s->len);
00477 buf[_s->len] = '\0';
00478
00479 _m->parsed_uri_ok = 0;
00480 if (_m->new_uri.s) {
00481 pkg_free(_m->new_uri.s);
00482 }
00483
00484 _m->new_uri.s = buf;
00485 _m->new_uri.len = _s->len;
00486
00487 LM_DBG("rewriting Request-URI with '%.*s'\n", _s->len, buf);
00488 return 1;
00489 }
00490
00491
00492
00493
00494 int branch_uri2dset( str *new_uri )
00495 {
00496 unsigned int b;
00497
00498 if (new_uri->len+1 > MAX_URI_SIZE) {
00499 LM_ERR("new uri too long (%d)\n",new_uri->len);
00500 return -1;
00501 }
00502
00503 for( b=0 ; b<nr_branches ; b++ ) {
00504
00505 memcpy( branches[b].dst_uri, branches[b].uri, branches[b].len+1);
00506 branches[b].dst_uri_len = branches[b].len;
00507
00508 memcpy( branches[b].uri, new_uri->s, new_uri->len);
00509 branches[b].len = new_uri->len;
00510 branches[b].uri[new_uri->len] = 0;
00511 }
00512
00513 return 0;
00514 }