dset.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879
  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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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. LOG(L_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->new_uri.s)
  299. luri = msg->new_uri;
  300. else
  301. luri = msg->first_line.u.request.uri;
  302. } else {
  303. luri = *uri;
  304. }
  305. if (unlikely(luri.len > MAX_URI_SIZE - 1)) {
  306. LOG(L_ERR, "too long uri: %.*s\n", luri.len, luri.s);
  307. return -1;
  308. }
  309. /* copy the dst_uri */
  310. if (dst_uri && dst_uri->len && dst_uri->s) {
  311. if (unlikely(dst_uri->len > MAX_URI_SIZE - 1)) {
  312. LOG(L_ERR, "too long dst_uri: %.*s\n", dst_uri->len, dst_uri->s);
  313. return -1;
  314. }
  315. memcpy(branches[nr_branches].dst_uri, dst_uri->s, dst_uri->len);
  316. branches[nr_branches].dst_uri[dst_uri->len] = 0;
  317. branches[nr_branches].dst_uri_len = dst_uri->len;
  318. } else {
  319. branches[nr_branches].dst_uri[0] = '\0';
  320. branches[nr_branches].dst_uri_len = 0;
  321. }
  322. /* copy the path string */
  323. if (unlikely(path && path->len && path->s)) {
  324. if (unlikely(path->len > MAX_PATH_SIZE - 1)) {
  325. LOG(L_ERR, "too long path: %.*s\n", path->len, path->s);
  326. return -1;
  327. }
  328. memcpy(branches[nr_branches].path, path->s, path->len);
  329. branches[nr_branches].path[path->len] = 0;
  330. branches[nr_branches].path_len = path->len;
  331. } else {
  332. branches[nr_branches].path[0] = '\0';
  333. branches[nr_branches].path_len = 0;
  334. }
  335. /* copy the ruri */
  336. memcpy(branches[nr_branches].uri, luri.s, luri.len);
  337. branches[nr_branches].uri[luri.len] = 0;
  338. branches[nr_branches].len = luri.len;
  339. branches[nr_branches].q = q;
  340. branches[nr_branches].force_send_socket = force_socket;
  341. branches[nr_branches].flags = flags;
  342. /* copy instance string */
  343. if (unlikely(instance && instance->len && instance->s)) {
  344. if (unlikely(instance->len > MAX_INSTANCE_SIZE - 1)) {
  345. LOG(L_ERR, "too long instance: %.*s\n",
  346. instance->len, instance->s);
  347. return -1;
  348. }
  349. memcpy(branches[nr_branches].instance, instance->s,
  350. instance->len);
  351. branches[nr_branches].instance[instance->len] = 0;
  352. branches[nr_branches].instance_len = instance->len;
  353. } else {
  354. branches[nr_branches].instance[0] = '\0';
  355. branches[nr_branches].instance_len = 0;
  356. }
  357. /* copy reg_id */
  358. branches[nr_branches].reg_id = reg_id;
  359. /* copy ruid string */
  360. if (unlikely(ruid && ruid->len && ruid->s)) {
  361. if (unlikely(ruid->len > MAX_RUID_SIZE - 1)) {
  362. LOG(L_ERR, "too long ruid: %.*s\n",
  363. ruid->len, ruid->s);
  364. return -1;
  365. }
  366. memcpy(branches[nr_branches].ruid, ruid->s,
  367. ruid->len);
  368. branches[nr_branches].ruid[ruid->len] = 0;
  369. branches[nr_branches].ruid_len = ruid->len;
  370. } else {
  371. branches[nr_branches].ruid[0] = '\0';
  372. branches[nr_branches].ruid_len = 0;
  373. }
  374. if (unlikely(location_ua && location_ua->len && location_ua->s)) {
  375. if (unlikely(location_ua->len > MAX_UA_SIZE)) {
  376. LOG(L_ERR, "too long location_ua: %.*s\n",
  377. location_ua->len, location_ua->s);
  378. return -1;
  379. }
  380. memcpy(branches[nr_branches].location_ua, location_ua->s,
  381. location_ua->len);
  382. branches[nr_branches].location_ua[location_ua->len] = 0;
  383. branches[nr_branches].location_ua_len = location_ua->len;
  384. } else {
  385. branches[nr_branches].location_ua[0] = '\0';
  386. branches[nr_branches].location_ua_len = 0;
  387. }
  388. nr_branches++;
  389. return 1;
  390. }
  391. /*
  392. * Create a Contact header field from the dset
  393. * array
  394. */
  395. char* print_dset(struct sip_msg* msg, int* len)
  396. {
  397. int cnt, i;
  398. unsigned int qlen;
  399. qvalue_t q;
  400. str uri;
  401. char* p, *qbuf;
  402. int crt_branch;
  403. static char dset[MAX_REDIRECTION_LEN];
  404. if (msg->new_uri.s) {
  405. cnt = 1;
  406. *len = msg->new_uri.len + 1 /*'<'*/;
  407. if (ruri_q != Q_UNSPECIFIED) {
  408. *len += Q_PARAM_LEN + len_q(ruri_q);
  409. } else {
  410. *len += 1 /*'>'*/;
  411. }
  412. } else {
  413. cnt = 0;
  414. *len = 0;
  415. }
  416. /* backup current branch index to restore it later */
  417. crt_branch = get_branch_iterator();
  418. init_branch_iterator();
  419. while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0, 0, 0, 0, 0))) {
  420. cnt++;
  421. *len += uri.len + 1 /*'<'*/;
  422. if (q != Q_UNSPECIFIED) {
  423. *len += Q_PARAM_LEN + len_q(q);
  424. } else {
  425. *len += 1 /*'>'*/;
  426. }
  427. }
  428. if (cnt == 0) return 0;
  429. *len += CONTACT_LEN + CRLF_LEN + (cnt - 1) * CONTACT_DELIM_LEN;
  430. if (*len + 1 > MAX_REDIRECTION_LEN) {
  431. LOG(L_ERR, "ERROR: redirection buffer length exceed\n");
  432. goto error;
  433. }
  434. memcpy(dset, CONTACT, CONTACT_LEN);
  435. p = dset + CONTACT_LEN;
  436. if (msg->new_uri.s) {
  437. *p++ = '<';
  438. memcpy(p, msg->new_uri.s, msg->new_uri.len);
  439. p += msg->new_uri.len;
  440. if (ruri_q != Q_UNSPECIFIED) {
  441. memcpy(p, Q_PARAM, Q_PARAM_LEN);
  442. p += Q_PARAM_LEN;
  443. qbuf = q2str(ruri_q, &qlen);
  444. memcpy(p, qbuf, qlen);
  445. p += qlen;
  446. } else {
  447. *p++ = '>';
  448. }
  449. i = 1;
  450. } else {
  451. i = 0;
  452. }
  453. init_branch_iterator();
  454. while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0, 0, 0, 0, 0))) {
  455. if (i) {
  456. memcpy(p, CONTACT_DELIM, CONTACT_DELIM_LEN);
  457. p += CONTACT_DELIM_LEN;
  458. }
  459. *p++ = '<';
  460. memcpy(p, uri.s, uri.len);
  461. p += uri.len;
  462. if (q != Q_UNSPECIFIED) {
  463. memcpy(p, Q_PARAM, Q_PARAM_LEN);
  464. p += Q_PARAM_LEN;
  465. qbuf = q2str(q, &qlen);
  466. memcpy(p, qbuf, qlen);
  467. p += qlen;
  468. } else {
  469. *p++ = '>';
  470. }
  471. i++;
  472. }
  473. memcpy(p, CRLF " ", CRLF_LEN + 1);
  474. set_branch_iterator(crt_branch);
  475. return dset;
  476. error:
  477. set_branch_iterator(crt_branch);
  478. return 0;
  479. }
  480. /*
  481. * Sets the q parameter of the Request-URI
  482. */
  483. void set_ruri_q(qvalue_t q)
  484. {
  485. ruri_q = q;
  486. }
  487. /*
  488. * Return the q value of the Request-URI
  489. */
  490. qvalue_t get_ruri_q(void)
  491. {
  492. return ruri_q;
  493. }
  494. /*
  495. * Rewrite Request-URI
  496. */
  497. int rewrite_uri(struct sip_msg* _m, str* _s)
  498. {
  499. char *buf = NULL;
  500. if(_m->new_uri.s==NULL || _m->new_uri.len<_s->len) {
  501. buf = (char*)pkg_malloc(_s->len + 1);
  502. if (!buf) {
  503. LM_ERR("No memory left to rewrite r-uri\n");
  504. return -1;
  505. }
  506. }
  507. if(buf!=NULL) {
  508. if(_m->new_uri.s)
  509. pkg_free(_m->new_uri.s);
  510. } else {
  511. buf = _m->new_uri.s;
  512. }
  513. memcpy(buf, _s->s, _s->len);
  514. buf[_s->len] = '\0';
  515. _m->parsed_uri_ok = 0;
  516. _m->new_uri.s = buf;
  517. _m->new_uri.len = _s->len;
  518. /* mark ruri as new and available for forking */
  519. ruri_mark_new();
  520. return 1;
  521. }
  522. /**
  523. * return src ip, port and proto as a SIP uri or proxy address
  524. * - value stored in a static buffer
  525. * - mode=0 return uri, mode=1 return proxy address
  526. */
  527. int msg_get_src_addr(sip_msg_t *msg, str *uri, int mode)
  528. {
  529. static char buf[80];
  530. char* p;
  531. str ip, port;
  532. int len;
  533. str proto;
  534. if (msg==NULL || uri==NULL) {
  535. LM_ERR("invalid parameter value\n");
  536. return -1;
  537. }
  538. ip.s = ip_addr2a(&msg->rcv.src_ip);
  539. ip.len = strlen(ip.s);
  540. port.s = int2str(msg->rcv.src_port, &port.len);
  541. switch(msg->rcv.proto) {
  542. case PROTO_NONE:
  543. case PROTO_UDP:
  544. if(mode==0) {
  545. proto.s = 0; /* Do not add transport parameter, UDP is default */
  546. proto.len = 0;
  547. } else {
  548. proto.s = "udp";
  549. proto.len = 3;
  550. }
  551. break;
  552. case PROTO_TCP:
  553. proto.s = "tcp";
  554. proto.len = 3;
  555. break;
  556. case PROTO_TLS:
  557. proto.s = "tls";
  558. proto.len = 3;
  559. break;
  560. case PROTO_SCTP:
  561. proto.s = "sctp";
  562. proto.len = 4;
  563. break;
  564. case PROTO_WS:
  565. case PROTO_WSS:
  566. proto.s = "ws";
  567. proto.len = 2;
  568. break;
  569. default:
  570. LM_ERR("unknown transport protocol\n");
  571. return -1;
  572. }
  573. len = ip.len + 2*(msg->rcv.src_ip.af==AF_INET6)+ 1 + port.len;
  574. if (mode==0) {
  575. len += 4;
  576. if(proto.s) {
  577. len += TRANSPORT_PARAM_LEN;
  578. len += proto.len;
  579. }
  580. } else {
  581. len += proto.len + 1;
  582. }
  583. if (len > 79) {
  584. LM_ERR("buffer too small\n");
  585. return -1;
  586. }
  587. p = buf;
  588. if(mode==0) {
  589. memcpy(p, "sip:", 4);
  590. p += 4;
  591. } else {
  592. memcpy(p, proto.s, proto.len);
  593. p += proto.len;
  594. *p++ = ':';
  595. }
  596. if (msg->rcv.src_ip.af==AF_INET6)
  597. *p++ = '[';
  598. memcpy(p, ip.s, ip.len);
  599. p += ip.len;
  600. if (msg->rcv.src_ip.af==AF_INET6)
  601. *p++ = ']';
  602. *p++ = ':';
  603. memcpy(p, port.s, port.len);
  604. p += port.len;
  605. if (mode==0 && proto.s) {
  606. memcpy(p, TRANSPORT_PARAM, TRANSPORT_PARAM_LEN);
  607. p += TRANSPORT_PARAM_LEN;
  608. memcpy(p, proto.s, proto.len);
  609. p += proto.len;
  610. }
  611. uri->s = buf;
  612. uri->len = len;
  613. uri->s[uri->len] = '\0';
  614. return 0;
  615. }
  616. /**
  617. * add alias parameter with encoding of source address
  618. * - nuri->s must point to a buffer of nuri->len size
  619. */
  620. int uri_add_rcv_alias(sip_msg_t *msg, str *uri, str *nuri)
  621. {
  622. char* p;
  623. str ip, port;
  624. int len;
  625. if (msg==NULL || uri==NULL || nuri==NULL) {
  626. LM_ERR("invalid parameter value\n");
  627. return -1;
  628. }
  629. ip.s = ip_addr2a(&msg->rcv.src_ip);
  630. ip.len = strlen(ip.s);
  631. port.s = int2str(msg->rcv.src_port, &port.len);
  632. /*uri;alias=[ip]~port~proto*/
  633. len = uri->len+ip.len+port.len+12;
  634. if(len>=nuri->len) {
  635. LM_ERR("not enough space for new uri: %d\n", len);
  636. return -1;
  637. }
  638. p = nuri->s;
  639. memcpy(p, uri->s, uri->len);
  640. p += uri->len;
  641. memcpy(p, ";alias=", 7);
  642. p += 7;
  643. if (msg->rcv.src_ip.af == AF_INET6)
  644. *p++ = '[';
  645. memcpy(p, ip.s, ip.len);
  646. p += ip.len;
  647. if (msg->rcv.src_ip.af == AF_INET6)
  648. *p++ = ']';
  649. *p++ = '~';
  650. memcpy(p, port.s, port.len);
  651. p += port.len;
  652. *p++ = '~';
  653. *p++ = msg->rcv.proto + '0';
  654. nuri->len = p - nuri->s;
  655. nuri->s[nuri->len] = '\0';
  656. LM_DBG("encoded <%.*s> => [%.*s]\n",
  657. uri->len, uri->s, nuri->len, nuri->s);
  658. return 0;
  659. }
  660. /**
  661. * restore from alias parameter with encoding of source address
  662. * - nuri->s must point to a buffer of nuri->len size
  663. * - suri->s must point to a buffer of suri->len size
  664. */
  665. int uri_restore_rcv_alias(str *uri, str *nuri, str *suri)
  666. {
  667. char* p;
  668. str skip;
  669. str ip, port, sproto;
  670. int proto;
  671. if (uri==NULL || nuri==NULL || suri==NULL) {
  672. LM_ERR("invalid parameter value\n");
  673. return -1;
  674. }
  675. /* sip:x;alias=1.1.1.1~0~0 */
  676. if(uri->len < 23) {
  677. /* no alias possible */
  678. return -2;
  679. }
  680. p = uri->s + uri->len-18;
  681. skip.s = 0;
  682. while(p>uri->s+5) {
  683. if(strncmp(p, ";alias=", 7)==0) {
  684. skip.s = p;
  685. break;
  686. }
  687. p--;
  688. }
  689. if(skip.s==0) {
  690. /* alias parameter not found */
  691. return -2;
  692. }
  693. p += 7;
  694. ip.s = p;
  695. p = (char*)memchr(ip.s, '~', (size_t)(uri->s+uri->len-ip.s));
  696. if(p==NULL) {
  697. /* proper alias parameter not found */
  698. return -2;
  699. }
  700. ip.len = p - ip.s;
  701. p++;
  702. if(p>=uri->s+uri->len) {
  703. /* proper alias parameter not found */
  704. return -2;
  705. }
  706. port.s = p;
  707. p = (char*)memchr(port.s, '~', (size_t)(uri->s+uri->len-port.s));
  708. if(p==NULL) {
  709. /* proper alias parameter not found */
  710. return -2;
  711. }
  712. port.len = p - port.s;
  713. p++;
  714. if(p>=uri->s+uri->len) {
  715. /* proper alias parameter not found */
  716. return -2;
  717. }
  718. proto = (int)(*p - '0');
  719. p++;
  720. if(p!=uri->s+uri->len && *p!=';') {
  721. /* proper alias parameter not found */
  722. return -2;
  723. }
  724. skip.len = (int)(p - skip.s);
  725. if(suri->len<=4+ip.len+1+port.len+11/*;transport=*/+4) {
  726. LM_ERR("address buffer too small\n");
  727. return -1;
  728. }
  729. if(nuri->len<=uri->len - skip.len) {
  730. LM_ERR("uri buffer too small\n");
  731. return -1;
  732. }
  733. p = nuri->s;
  734. memcpy(p, uri->s, (size_t)(skip.s-uri->s));
  735. p += skip.s-uri->s;
  736. memcpy(p, skip.s+skip.len, (size_t)(uri->s+uri->len - skip.s - skip.len));
  737. p += uri->s+uri->len - skip.s - skip.len;
  738. nuri->len = p - nuri->s;
  739. p = suri->s;
  740. strncpy(p, "sip:", 4);
  741. p += 4;
  742. strncpy(p, ip.s, ip.len);
  743. p += ip.len;
  744. *p++ = ':';
  745. strncpy(p, port.s, port.len);
  746. p += port.len;
  747. proto_type_to_str((unsigned short)proto, &sproto);
  748. if(sproto.len>0 && proto!=PROTO_UDP) {
  749. strncpy(p, ";transport=", 11);
  750. p += 11;
  751. strncpy(p, sproto.s, sproto.len);
  752. p += sproto.len;
  753. }
  754. suri->len = p - suri->s;
  755. LM_DBG("decoded <%.*s> => [%.*s] [%.*s]\n",
  756. uri->len, uri->s, nuri->len, nuri->s, suri->len, suri->s);
  757. return 0;
  758. }