dset.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884
  1. /*
  2. * $Id$
  3. *
  4. * destination set
  5. *
  6. * Copyright (C) 2001-2004 FhG FOKUS
  7. *
  8. * This file is part of ser, a free SIP server.
  9. *
  10. * ser is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version
  14. *
  15. * For a license to use the ser software under conditions
  16. * other than those described here, or to purchase support for this
  17. * software, please contact iptel.org by e-mail at the following addresses:
  18. * [email protected]
  19. *
  20. * ser is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU General Public License
  26. * along with this program; if not, write to the Free Software
  27. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  28. */
  29. /** destination set / branches support.
  30. * @file dset.c
  31. * @ingroup core
  32. * Module: @ref core
  33. */
  34. #include <string.h>
  35. #include "dprint.h"
  36. #include "config.h"
  37. #include "parser/parser_f.h"
  38. #include "parser/parse_uri.h"
  39. #include "parser/msg_parser.h"
  40. #include "ut.h"
  41. #include "hash_func.h"
  42. #include "error.h"
  43. #include "dset.h"
  44. #include "mem/mem.h"
  45. #include "ip_addr.h"
  46. #define CONTACT "Contact: "
  47. #define CONTACT_LEN (sizeof(CONTACT) - 1)
  48. #define CONTACT_DELIM ", "
  49. #define CONTACT_DELIM_LEN (sizeof(CONTACT_DELIM) - 1)
  50. #define Q_PARAM ">;q="
  51. #define Q_PARAM_LEN (sizeof(Q_PARAM) - 1)
  52. /*
  53. * Where we store URIs of additional transaction branches
  54. * (-1 because of the default branch, #0)
  55. */
  56. static struct branch branches[MAX_BRANCHES - 1];
  57. /* how many of them we have */
  58. unsigned int nr_branches = 0;
  59. /* branch iterator */
  60. static int branch_iterator = 0;
  61. /* used to mark ruris "consumed" when branching (1 new, 0 consumed) */
  62. int ruri_is_new = 0;
  63. /* The q parameter of the Request-URI */
  64. static qvalue_t ruri_q = Q_UNSPECIFIED;
  65. /* Branch flags of the Request-URI */
  66. static flag_t ruri_bflags;
  67. /*! \brief
  68. * Return pointer to branch[idx] structure
  69. * @param idx - branch index
  70. *
  71. * @return pointer to branch or NULL if invalid branch
  72. */
  73. branch_t *get_sip_branch(int idx)
  74. {
  75. if(nr_branches==0)
  76. return NULL;
  77. if(idx<0)
  78. {
  79. if((int)nr_branches + idx >= 0)
  80. return &branches[nr_branches+idx];
  81. return NULL;
  82. }
  83. if(idx < nr_branches)
  84. return &branches[idx];
  85. return 0;
  86. }
  87. /*! \brief
  88. * Drop branch[idx]
  89. * @param idx - branch index
  90. *
  91. * @return 0 on success, -1 on error
  92. */
  93. int drop_sip_branch(int idx)
  94. {
  95. if(nr_branches==0 || idx>=nr_branches)
  96. return 0;
  97. if(idx<0 && (int)nr_branches+idx<0)
  98. return 0;
  99. /* last branch */
  100. if(idx==nr_branches-1)
  101. {
  102. nr_branches--;
  103. return 0;
  104. }
  105. if(idx<0)
  106. idx = nr_branches+idx;
  107. /* shift back one position */
  108. for(; idx<nr_branches-1; idx++)
  109. memcpy(&branches[idx], &branches[idx+1], sizeof(branch_t));
  110. nr_branches--;
  111. return 0;
  112. }
  113. static inline flag_t* get_bflags_ptr(unsigned int branch)
  114. {
  115. if (branch == 0) return &ruri_bflags;
  116. if (branch - 1 < nr_branches) return &branches[branch - 1].flags;
  117. return NULL;
  118. }
  119. int setbflag(unsigned int branch, flag_t flag)
  120. {
  121. flag_t* flags;
  122. if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
  123. (*flags) |= 1 << flag;
  124. return 1;
  125. }
  126. int isbflagset(unsigned int branch, flag_t flag)
  127. {
  128. flag_t* flags;
  129. if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
  130. return ((*flags) & (1 << flag)) ? 1 : -1;
  131. }
  132. int resetbflag(unsigned int branch, flag_t flag)
  133. {
  134. flag_t* flags;
  135. if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
  136. (*flags) &= ~ (1 << flag);
  137. return 1;
  138. }
  139. int getbflagsval(unsigned int branch, flag_t* res)
  140. {
  141. flag_t* flags;
  142. if (res == NULL) return -1;
  143. if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
  144. *res = *flags;
  145. return 1;
  146. }
  147. int setbflagsval(unsigned int branch, flag_t val)
  148. {
  149. flag_t* flags;
  150. if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
  151. *flags = val;
  152. return 1;
  153. }
  154. /*
  155. * Initialize the branch iterator, the next
  156. * call to next_branch will return the first
  157. * contact from the dset array
  158. */
  159. void init_branch_iterator(void)
  160. {
  161. branch_iterator = 0;
  162. }
  163. /**
  164. * return the value of current branch iterator
  165. */
  166. int get_branch_iterator(void)
  167. {
  168. return branch_iterator;
  169. }
  170. /**
  171. * set the value of current branch interator
  172. */
  173. void set_branch_iterator(int n)
  174. {
  175. branch_iterator = n;
  176. }
  177. /** \brief Get a branch from the destination set
  178. * \return Return the 'i' branch from the dset
  179. * array, 0 is returned if there are no
  180. * more branches
  181. */
  182. char* get_branch(unsigned int i, int* len, qvalue_t* q, str* dst_uri,
  183. str* path, unsigned int *flags,
  184. struct socket_info** force_socket,
  185. str *ruid, str *instance, str *location_ua)
  186. {
  187. if (i < nr_branches) {
  188. *len = branches[i].len;
  189. *q = branches[i].q;
  190. if (dst_uri) {
  191. dst_uri->len = branches[i].dst_uri_len;
  192. dst_uri->s = (dst_uri->len)?branches[i].dst_uri:0;
  193. }
  194. if (path) {
  195. path->len = branches[i].path_len;
  196. path->s = (path->len)?branches[i].path:0;
  197. }
  198. if (force_socket)
  199. *force_socket = branches[i].force_send_socket;
  200. if (flags)
  201. *flags = branches[i].flags;
  202. if (ruid) {
  203. ruid->len = branches[i].ruid_len;
  204. ruid->s = (ruid->len)?branches[i].ruid:0;
  205. }
  206. if (instance) {
  207. instance->len = branches[i].instance_len;
  208. instance->s = (instance->len)?branches[i].instance:0;
  209. }
  210. if (location_ua) {
  211. location_ua->len = branches[i].location_ua_len;
  212. location_ua->s
  213. = (location_ua->len)?branches[i].location_ua:0;
  214. }
  215. return branches[i].uri;
  216. } else {
  217. *len = 0;
  218. *q = Q_UNSPECIFIED;
  219. if (dst_uri) {
  220. dst_uri->s = 0;
  221. dst_uri->len = 0;
  222. }
  223. if (path) {
  224. path->s = 0;
  225. path->len = 0;
  226. }
  227. if (force_socket)
  228. *force_socket = 0;
  229. if (flags)
  230. *flags = 0;
  231. if (ruid) {
  232. ruid->s = 0;
  233. ruid->len = 0;
  234. }
  235. if (instance) {
  236. instance->s = 0;
  237. instance->len = 0;
  238. }
  239. if (location_ua) {
  240. location_ua->s = 0;
  241. location_ua->len = 0;
  242. }
  243. return 0;
  244. }
  245. }
  246. /** Return the next branch from the dset array.
  247. * 0 is returned if there are no more branches
  248. */
  249. char* next_branch(int* len, qvalue_t* q, str* dst_uri, str* path,
  250. unsigned int* flags, struct socket_info** force_socket,
  251. str* ruid, str *instance, str *location_ua)
  252. {
  253. char* ret;
  254. ret=get_branch(branch_iterator, len, q, dst_uri, path, flags,
  255. force_socket, ruid, instance, location_ua);
  256. if (likely(ret))
  257. branch_iterator++;
  258. return ret;
  259. }
  260. /*
  261. * Empty the dset array
  262. */
  263. void clear_branches(void)
  264. {
  265. nr_branches = 0;
  266. ruri_q = Q_UNSPECIFIED;
  267. ruri_bflags = 0;
  268. ruri_mark_consumed();
  269. }
  270. /** Add a new branch to the current transaction.
  271. * @param msg - sip message, used for getting the uri if not specified (0).
  272. * @param uri - uri, can be 0 (in which case the uri is taken from msg)
  273. * @param dst_uri - destination uri, can be 0.
  274. * @param path - path vector (passed in a string), can be 0.
  275. * @param q - q value.
  276. * @param flags - per branch flags.
  277. * @param force_socket - socket that should be used when sending.
  278. *
  279. * @return <0 (-1) on failure, 1 on success (script convention).
  280. */
  281. int append_branch(struct sip_msg* msg, str* uri, str* dst_uri, str* path,
  282. qvalue_t q, unsigned int flags,
  283. struct socket_info* force_socket,
  284. str* instance, unsigned int reg_id,
  285. str* ruid, str* location_ua)
  286. {
  287. str luri;
  288. /* if we have already set up the maximum number
  289. * of branches, don't try new ones
  290. */
  291. if (unlikely(nr_branches == MAX_BRANCHES - 1)) {
  292. LM_ERR("max nr of branches exceeded\n");
  293. ser_error = E_TOO_MANY_BRANCHES;
  294. return -1;
  295. }
  296. /* if not parameterized, take current uri */
  297. if (uri==0 || uri->len==0 || uri->s==0) {
  298. if(msg==NULL) {
  299. LM_ERR("no new uri and no msg to take r-uri\n");
  300. ser_error = E_INVALID_PARAMS;
  301. return -1;
  302. }
  303. if (msg->new_uri.s)
  304. luri = msg->new_uri;
  305. else
  306. luri = msg->first_line.u.request.uri;
  307. } else {
  308. luri = *uri;
  309. }
  310. if (unlikely(luri.len > MAX_URI_SIZE - 1)) {
  311. LM_ERR("too long uri: %.*s\n", luri.len, luri.s);
  312. return -1;
  313. }
  314. /* copy the dst_uri */
  315. if (dst_uri && dst_uri->len && dst_uri->s) {
  316. if (unlikely(dst_uri->len > MAX_URI_SIZE - 1)) {
  317. LM_ERR("too long dst_uri: %.*s\n", dst_uri->len, dst_uri->s);
  318. return -1;
  319. }
  320. memcpy(branches[nr_branches].dst_uri, dst_uri->s, dst_uri->len);
  321. branches[nr_branches].dst_uri[dst_uri->len] = 0;
  322. branches[nr_branches].dst_uri_len = dst_uri->len;
  323. } else {
  324. branches[nr_branches].dst_uri[0] = '\0';
  325. branches[nr_branches].dst_uri_len = 0;
  326. }
  327. /* copy the path string */
  328. if (unlikely(path && path->len && path->s)) {
  329. if (unlikely(path->len > MAX_PATH_SIZE - 1)) {
  330. LM_ERR("too long path: %.*s\n", path->len, path->s);
  331. return -1;
  332. }
  333. memcpy(branches[nr_branches].path, path->s, path->len);
  334. branches[nr_branches].path[path->len] = 0;
  335. branches[nr_branches].path_len = path->len;
  336. } else {
  337. branches[nr_branches].path[0] = '\0';
  338. branches[nr_branches].path_len = 0;
  339. }
  340. /* copy the ruri */
  341. memcpy(branches[nr_branches].uri, luri.s, luri.len);
  342. branches[nr_branches].uri[luri.len] = 0;
  343. branches[nr_branches].len = luri.len;
  344. branches[nr_branches].q = q;
  345. branches[nr_branches].force_send_socket = force_socket;
  346. branches[nr_branches].flags = flags;
  347. /* copy instance string */
  348. if (unlikely(instance && instance->len && instance->s)) {
  349. if (unlikely(instance->len > MAX_INSTANCE_SIZE - 1)) {
  350. LM_ERR("too long instance: %.*s\n",
  351. instance->len, instance->s);
  352. return -1;
  353. }
  354. memcpy(branches[nr_branches].instance, instance->s,
  355. instance->len);
  356. branches[nr_branches].instance[instance->len] = 0;
  357. branches[nr_branches].instance_len = instance->len;
  358. } else {
  359. branches[nr_branches].instance[0] = '\0';
  360. branches[nr_branches].instance_len = 0;
  361. }
  362. /* copy reg_id */
  363. branches[nr_branches].reg_id = reg_id;
  364. /* copy ruid string */
  365. if (unlikely(ruid && ruid->len && ruid->s)) {
  366. if (unlikely(ruid->len > MAX_RUID_SIZE - 1)) {
  367. LM_ERR("too long ruid: %.*s\n",
  368. ruid->len, ruid->s);
  369. return -1;
  370. }
  371. memcpy(branches[nr_branches].ruid, ruid->s,
  372. ruid->len);
  373. branches[nr_branches].ruid[ruid->len] = 0;
  374. branches[nr_branches].ruid_len = ruid->len;
  375. } else {
  376. branches[nr_branches].ruid[0] = '\0';
  377. branches[nr_branches].ruid_len = 0;
  378. }
  379. if (unlikely(location_ua && location_ua->len && location_ua->s)) {
  380. if (unlikely(location_ua->len > MAX_UA_SIZE)) {
  381. LM_ERR("too long location_ua: %.*s\n",
  382. location_ua->len, location_ua->s);
  383. return -1;
  384. }
  385. memcpy(branches[nr_branches].location_ua, location_ua->s,
  386. location_ua->len);
  387. branches[nr_branches].location_ua[location_ua->len] = 0;
  388. branches[nr_branches].location_ua_len = location_ua->len;
  389. } else {
  390. branches[nr_branches].location_ua[0] = '\0';
  391. branches[nr_branches].location_ua_len = 0;
  392. }
  393. nr_branches++;
  394. return 1;
  395. }
  396. /*
  397. * Create a Contact header field from the dset
  398. * array
  399. */
  400. char* print_dset(struct sip_msg* msg, int* len)
  401. {
  402. int cnt, i;
  403. unsigned int qlen;
  404. qvalue_t q;
  405. str uri;
  406. char* p, *qbuf;
  407. int crt_branch;
  408. static char dset[MAX_REDIRECTION_LEN];
  409. if (msg->new_uri.s) {
  410. cnt = 1;
  411. *len = msg->new_uri.len + 1 /*'<'*/;
  412. if (ruri_q != Q_UNSPECIFIED) {
  413. *len += Q_PARAM_LEN + len_q(ruri_q);
  414. } else {
  415. *len += 1 /*'>'*/;
  416. }
  417. } else {
  418. cnt = 0;
  419. *len = 0;
  420. }
  421. /* backup current branch index to restore it later */
  422. crt_branch = get_branch_iterator();
  423. init_branch_iterator();
  424. while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0, 0, 0, 0, 0))) {
  425. cnt++;
  426. *len += uri.len + 1 /*'<'*/;
  427. if (q != Q_UNSPECIFIED) {
  428. *len += Q_PARAM_LEN + len_q(q);
  429. } else {
  430. *len += 1 /*'>'*/;
  431. }
  432. }
  433. if (cnt == 0) return 0;
  434. *len += CONTACT_LEN + CRLF_LEN + (cnt - 1) * CONTACT_DELIM_LEN;
  435. if (*len + 1 > MAX_REDIRECTION_LEN) {
  436. LM_ERR("redirection buffer length exceed\n");
  437. goto error;
  438. }
  439. memcpy(dset, CONTACT, CONTACT_LEN);
  440. p = dset + CONTACT_LEN;
  441. if (msg->new_uri.s) {
  442. *p++ = '<';
  443. memcpy(p, msg->new_uri.s, msg->new_uri.len);
  444. p += msg->new_uri.len;
  445. if (ruri_q != Q_UNSPECIFIED) {
  446. memcpy(p, Q_PARAM, Q_PARAM_LEN);
  447. p += Q_PARAM_LEN;
  448. qbuf = q2str(ruri_q, &qlen);
  449. memcpy(p, qbuf, qlen);
  450. p += qlen;
  451. } else {
  452. *p++ = '>';
  453. }
  454. i = 1;
  455. } else {
  456. i = 0;
  457. }
  458. init_branch_iterator();
  459. while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0, 0, 0, 0, 0))) {
  460. if (i) {
  461. memcpy(p, CONTACT_DELIM, CONTACT_DELIM_LEN);
  462. p += CONTACT_DELIM_LEN;
  463. }
  464. *p++ = '<';
  465. memcpy(p, uri.s, uri.len);
  466. p += uri.len;
  467. if (q != Q_UNSPECIFIED) {
  468. memcpy(p, Q_PARAM, Q_PARAM_LEN);
  469. p += Q_PARAM_LEN;
  470. qbuf = q2str(q, &qlen);
  471. memcpy(p, qbuf, qlen);
  472. p += qlen;
  473. } else {
  474. *p++ = '>';
  475. }
  476. i++;
  477. }
  478. memcpy(p, CRLF " ", CRLF_LEN + 1);
  479. set_branch_iterator(crt_branch);
  480. return dset;
  481. error:
  482. set_branch_iterator(crt_branch);
  483. return 0;
  484. }
  485. /*
  486. * Sets the q parameter of the Request-URI
  487. */
  488. void set_ruri_q(qvalue_t q)
  489. {
  490. ruri_q = q;
  491. }
  492. /*
  493. * Return the q value of the Request-URI
  494. */
  495. qvalue_t get_ruri_q(void)
  496. {
  497. return ruri_q;
  498. }
  499. /*
  500. * Rewrite Request-URI
  501. */
  502. int rewrite_uri(struct sip_msg* _m, str* _s)
  503. {
  504. char *buf = NULL;
  505. if(_m->new_uri.s==NULL || _m->new_uri.len<_s->len) {
  506. buf = (char*)pkg_malloc(_s->len + 1);
  507. if (!buf) {
  508. LM_ERR("No memory left to rewrite r-uri\n");
  509. return -1;
  510. }
  511. }
  512. if(buf!=NULL) {
  513. if(_m->new_uri.s)
  514. pkg_free(_m->new_uri.s);
  515. } else {
  516. buf = _m->new_uri.s;
  517. }
  518. memcpy(buf, _s->s, _s->len);
  519. buf[_s->len] = '\0';
  520. _m->parsed_uri_ok = 0;
  521. _m->new_uri.s = buf;
  522. _m->new_uri.len = _s->len;
  523. /* mark ruri as new and available for forking */
  524. ruri_mark_new();
  525. return 1;
  526. }
  527. /**
  528. * return src ip, port and proto as a SIP uri or proxy address
  529. * - value stored in a static buffer
  530. * - mode=0 return uri, mode=1 return proxy address
  531. */
  532. int msg_get_src_addr(sip_msg_t *msg, str *uri, int mode)
  533. {
  534. static char buf[80];
  535. char* p;
  536. str ip, port;
  537. int len;
  538. str proto;
  539. if (msg==NULL || uri==NULL) {
  540. LM_ERR("invalid parameter value\n");
  541. return -1;
  542. }
  543. ip.s = ip_addr2a(&msg->rcv.src_ip);
  544. ip.len = strlen(ip.s);
  545. port.s = int2str(msg->rcv.src_port, &port.len);
  546. switch(msg->rcv.proto) {
  547. case PROTO_NONE:
  548. case PROTO_UDP:
  549. if(mode==0) {
  550. proto.s = 0; /* Do not add transport parameter, UDP is default */
  551. proto.len = 0;
  552. } else {
  553. proto.s = "udp";
  554. proto.len = 3;
  555. }
  556. break;
  557. case PROTO_TCP:
  558. proto.s = "tcp";
  559. proto.len = 3;
  560. break;
  561. case PROTO_TLS:
  562. proto.s = "tls";
  563. proto.len = 3;
  564. break;
  565. case PROTO_SCTP:
  566. proto.s = "sctp";
  567. proto.len = 4;
  568. break;
  569. case PROTO_WS:
  570. case PROTO_WSS:
  571. proto.s = "ws";
  572. proto.len = 2;
  573. break;
  574. default:
  575. LM_ERR("unknown transport protocol\n");
  576. return -1;
  577. }
  578. len = ip.len + 2*(msg->rcv.src_ip.af==AF_INET6)+ 1 + port.len;
  579. if (mode==0) {
  580. len += 4;
  581. if(proto.s) {
  582. len += TRANSPORT_PARAM_LEN;
  583. len += proto.len;
  584. }
  585. } else {
  586. len += proto.len + 1;
  587. }
  588. if (len > 79) {
  589. LM_ERR("buffer too small\n");
  590. return -1;
  591. }
  592. p = buf;
  593. if(mode==0) {
  594. memcpy(p, "sip:", 4);
  595. p += 4;
  596. } else {
  597. memcpy(p, proto.s, proto.len);
  598. p += proto.len;
  599. *p++ = ':';
  600. }
  601. if (msg->rcv.src_ip.af==AF_INET6)
  602. *p++ = '[';
  603. memcpy(p, ip.s, ip.len);
  604. p += ip.len;
  605. if (msg->rcv.src_ip.af==AF_INET6)
  606. *p++ = ']';
  607. *p++ = ':';
  608. memcpy(p, port.s, port.len);
  609. p += port.len;
  610. if (mode==0 && proto.s) {
  611. memcpy(p, TRANSPORT_PARAM, TRANSPORT_PARAM_LEN);
  612. p += TRANSPORT_PARAM_LEN;
  613. memcpy(p, proto.s, proto.len);
  614. p += proto.len;
  615. }
  616. uri->s = buf;
  617. uri->len = len;
  618. uri->s[uri->len] = '\0';
  619. return 0;
  620. }
  621. /**
  622. * add alias parameter with encoding of source address
  623. * - nuri->s must point to a buffer of nuri->len size
  624. */
  625. int uri_add_rcv_alias(sip_msg_t *msg, str *uri, str *nuri)
  626. {
  627. char* p;
  628. str ip, port;
  629. int len;
  630. if (msg==NULL || uri==NULL || nuri==NULL) {
  631. LM_ERR("invalid parameter value\n");
  632. return -1;
  633. }
  634. ip.s = ip_addr2a(&msg->rcv.src_ip);
  635. ip.len = strlen(ip.s);
  636. port.s = int2str(msg->rcv.src_port, &port.len);
  637. /*uri;alias=[ip]~port~proto*/
  638. len = uri->len+ip.len+port.len+12;
  639. if(len>=nuri->len) {
  640. LM_ERR("not enough space for new uri: %d\n", len);
  641. return -1;
  642. }
  643. p = nuri->s;
  644. memcpy(p, uri->s, uri->len);
  645. p += uri->len;
  646. memcpy(p, ";alias=", 7);
  647. p += 7;
  648. if (msg->rcv.src_ip.af == AF_INET6)
  649. *p++ = '[';
  650. memcpy(p, ip.s, ip.len);
  651. p += ip.len;
  652. if (msg->rcv.src_ip.af == AF_INET6)
  653. *p++ = ']';
  654. *p++ = '~';
  655. memcpy(p, port.s, port.len);
  656. p += port.len;
  657. *p++ = '~';
  658. *p++ = msg->rcv.proto + '0';
  659. nuri->len = p - nuri->s;
  660. nuri->s[nuri->len] = '\0';
  661. LM_DBG("encoded <%.*s> => [%.*s]\n",
  662. uri->len, uri->s, nuri->len, nuri->s);
  663. return 0;
  664. }
  665. /**
  666. * restore from alias parameter with encoding of source address
  667. * - nuri->s must point to a buffer of nuri->len size
  668. * - suri->s must point to a buffer of suri->len size
  669. */
  670. int uri_restore_rcv_alias(str *uri, str *nuri, str *suri)
  671. {
  672. char* p;
  673. str skip;
  674. str ip, port, sproto;
  675. int proto;
  676. if (uri==NULL || nuri==NULL || suri==NULL) {
  677. LM_ERR("invalid parameter value\n");
  678. return -1;
  679. }
  680. /* sip:x;alias=1.1.1.1~0~0 */
  681. if(uri->len < 23) {
  682. /* no alias possible */
  683. return -2;
  684. }
  685. p = uri->s + uri->len-18;
  686. skip.s = 0;
  687. while(p>uri->s+5) {
  688. if(strncmp(p, ";alias=", 7)==0) {
  689. skip.s = p;
  690. break;
  691. }
  692. p--;
  693. }
  694. if(skip.s==0) {
  695. /* alias parameter not found */
  696. return -2;
  697. }
  698. p += 7;
  699. ip.s = p;
  700. p = (char*)memchr(ip.s, '~', (size_t)(uri->s+uri->len-ip.s));
  701. if(p==NULL) {
  702. /* proper alias parameter not found */
  703. return -2;
  704. }
  705. ip.len = p - ip.s;
  706. p++;
  707. if(p>=uri->s+uri->len) {
  708. /* proper alias parameter not found */
  709. return -2;
  710. }
  711. port.s = p;
  712. p = (char*)memchr(port.s, '~', (size_t)(uri->s+uri->len-port.s));
  713. if(p==NULL) {
  714. /* proper alias parameter not found */
  715. return -2;
  716. }
  717. port.len = p - port.s;
  718. p++;
  719. if(p>=uri->s+uri->len) {
  720. /* proper alias parameter not found */
  721. return -2;
  722. }
  723. proto = (int)(*p - '0');
  724. p++;
  725. if(p!=uri->s+uri->len && *p!=';') {
  726. /* proper alias parameter not found */
  727. return -2;
  728. }
  729. skip.len = (int)(p - skip.s);
  730. if(suri->len<=4+ip.len+1+port.len+11/*;transport=*/+4) {
  731. LM_ERR("address buffer too small\n");
  732. return -1;
  733. }
  734. if(nuri->len<=uri->len - skip.len) {
  735. LM_ERR("uri buffer too small\n");
  736. return -1;
  737. }
  738. p = nuri->s;
  739. memcpy(p, uri->s, (size_t)(skip.s-uri->s));
  740. p += skip.s-uri->s;
  741. memcpy(p, skip.s+skip.len, (size_t)(uri->s+uri->len - skip.s - skip.len));
  742. p += uri->s+uri->len - skip.s - skip.len;
  743. nuri->len = p - nuri->s;
  744. p = suri->s;
  745. strncpy(p, "sip:", 4);
  746. p += 4;
  747. strncpy(p, ip.s, ip.len);
  748. p += ip.len;
  749. *p++ = ':';
  750. strncpy(p, port.s, port.len);
  751. p += port.len;
  752. proto_type_to_str((unsigned short)proto, &sproto);
  753. if(sproto.len>0 && proto!=PROTO_UDP) {
  754. strncpy(p, ";transport=", 11);
  755. p += 11;
  756. strncpy(p, sproto.s, sproto.len);
  757. p += sproto.len;
  758. }
  759. suri->len = p - suri->s;
  760. LM_DBG("decoded <%.*s> => [%.*s] [%.*s]\n",
  761. uri->len, uri->s, nuri->len, nuri->s, suri->len, suri->s);
  762. return 0;
  763. }