dset.c 19 KB

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