sip_msg_clone.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2009 iptelorg GmbH
  5. *
  6. * Permission to use, copy, modify, and distribute this software for any
  7. * purpose with or without fee is hereby granted, provided that the above
  8. * copyright notice and this permission notice appear in all copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. /*
  19. * sip_msg_clone.c - moved sip msg clone-in-shm functions from tm
  20. */
  21. /*
  22. * History:
  23. * --------
  24. * 2009-07-22 initial version: functions moved from tm/sip_msg.c (andrei)
  25. */
  26. /** SIP-router core :: sip message shared memory cloner.
  27. * @file
  28. * @ingroup core
  29. * Module: @ref core
  30. */
  31. #include "sip_msg_clone.h"
  32. #include "dprint.h"
  33. #include "mem/mem.h"
  34. #include "data_lump.h"
  35. #include "data_lump_rpl.h"
  36. #include "ut.h"
  37. #include "parser/digest/digest.h"
  38. #include "parser/parse_to.h"
  39. #include "atomic_ops.h"
  40. /* rounds to the first 4 byte multiple on 32 bit archs
  41. * and to the first 8 byte multiple on 64 bit archs */
  42. #define ROUND4(s) \
  43. (((s)+(sizeof(char*)-1))&(~(sizeof(char*)-1)))
  44. #define lump_len( _lump) \
  45. (ROUND4(sizeof(struct lump)) +\
  46. ROUND4(((_lump)->op==LUMP_ADD)?(_lump)->len:0))
  47. #define lump_clone( _new,_old,_ptr) \
  48. {\
  49. (_new) = (struct lump*)(_ptr);\
  50. memcpy( (_new), (_old), sizeof(struct lump) );\
  51. (_new)->flags|=LUMPFLAG_SHMEM; \
  52. (_ptr)+=ROUND4(sizeof(struct lump));\
  53. if ( (_old)->op==LUMP_ADD) {\
  54. (_new)->u.value = (char*)(_ptr);\
  55. memcpy( (_new)->u.value , (_old)->u.value , (_old)->len);\
  56. (_ptr)+=ROUND4((_old)->len);}\
  57. }
  58. /* length of the data lump structures */
  59. #define LUMP_LIST_LEN(len, list) \
  60. do { \
  61. struct lump* tmp, *chain; \
  62. chain = (list); \
  63. while (chain) \
  64. { \
  65. (len) += lump_len(chain); \
  66. tmp = chain->before; \
  67. while ( tmp ) \
  68. { \
  69. (len) += lump_len( tmp ); \
  70. tmp = tmp->before; \
  71. } \
  72. tmp = chain->after; \
  73. while ( tmp ) \
  74. { \
  75. (len) += lump_len( tmp ); \
  76. tmp = tmp->after; \
  77. } \
  78. chain = chain->next; \
  79. } \
  80. } while(0);
  81. /* length of the reply lump structure */
  82. #define RPL_LUMP_LIST_LEN(len, list) \
  83. do { \
  84. struct lump_rpl* rpl_lump; \
  85. for(rpl_lump=(list);rpl_lump;rpl_lump=rpl_lump->next) \
  86. (len)+=ROUND4(sizeof(struct lump_rpl))+ROUND4(rpl_lump->text.len); \
  87. } while(0);
  88. /* clones data lumps */
  89. #define CLONE_LUMP_LIST(anchor, list, _ptr) \
  90. do { \
  91. struct lump* lump_tmp, *l; \
  92. struct lump** lump_anchor2, **a; \
  93. a = (anchor); \
  94. l = (list); \
  95. while (l) \
  96. { \
  97. lump_clone( (*a) , l , (_ptr) ); \
  98. /*before list*/ \
  99. lump_tmp = l->before; \
  100. lump_anchor2 = &((*a)->before); \
  101. while ( lump_tmp ) \
  102. { \
  103. lump_clone( (*lump_anchor2) , lump_tmp , (_ptr) ); \
  104. lump_anchor2 = &((*lump_anchor2)->before); \
  105. lump_tmp = lump_tmp->before; \
  106. } \
  107. /*after list*/ \
  108. lump_tmp = l->after; \
  109. lump_anchor2 = &((*a)->after); \
  110. while ( lump_tmp ) \
  111. { \
  112. lump_clone( (*lump_anchor2) , lump_tmp , (_ptr) ); \
  113. lump_anchor2 = &((*lump_anchor2)->after); \
  114. lump_tmp = lump_tmp->after; \
  115. } \
  116. a = &((*a)->next); \
  117. l = l->next; \
  118. } \
  119. } while(0)
  120. /* clones reply lumps */
  121. #define CLONE_RPL_LUMP_LIST(anchor, list, _ptr) \
  122. do { \
  123. struct lump_rpl* rpl_lump; \
  124. struct lump_rpl** rpl_lump_anchor; \
  125. rpl_lump_anchor = (anchor); \
  126. for(rpl_lump=(list);rpl_lump;rpl_lump=rpl_lump->next) \
  127. { \
  128. *(rpl_lump_anchor)=(struct lump_rpl*)(_ptr); \
  129. (_ptr)+=ROUND4(sizeof( struct lump_rpl )); \
  130. (*rpl_lump_anchor)->flags = LUMP_RPL_SHMEM | \
  131. (rpl_lump->flags&(~(LUMP_RPL_NODUP|LUMP_RPL_NOFREE))); \
  132. (*rpl_lump_anchor)->text.len = rpl_lump->text.len; \
  133. (*rpl_lump_anchor)->text.s=(_ptr); \
  134. (_ptr)+=ROUND4(rpl_lump->text.len); \
  135. memcpy((*rpl_lump_anchor)->text.s,rpl_lump->text.s,rpl_lump->text.len); \
  136. (*rpl_lump_anchor)->next=0; \
  137. rpl_lump_anchor = &((*rpl_lump_anchor)->next); \
  138. } \
  139. } while (0)
  140. static inline struct via_body* via_body_cloner( char* new_buf,
  141. char *org_buf, struct via_body *param_org_via, char **p)
  142. {
  143. struct via_body *new_via;
  144. struct via_body *first_via, *last_via;
  145. struct via_body *org_via;
  146. first_via = last_via = 0;
  147. org_via = param_org_via;
  148. do
  149. {
  150. /* clones the via_body structure */
  151. new_via = (struct via_body*)(*p);
  152. memcpy( new_via , org_via , sizeof( struct via_body) );
  153. (*p) += ROUND4(sizeof( struct via_body ));
  154. /* hdr (str type) */
  155. new_via->hdr.s=translate_pointer(new_buf,org_buf,org_via->hdr.s);
  156. /* name (str type) */
  157. new_via->name.s=translate_pointer(new_buf,org_buf,org_via->name.s);
  158. /* version (str type) */
  159. new_via->version.s=
  160. translate_pointer(new_buf,org_buf,org_via->version.s);
  161. /* transport (str type) */
  162. new_via->transport.s=
  163. translate_pointer(new_buf,org_buf,org_via->transport.s);
  164. /* host (str type) */
  165. new_via->host.s=translate_pointer(new_buf,org_buf,org_via->host.s);
  166. /* port_str (str type) */
  167. new_via->port_str.s=
  168. translate_pointer(new_buf,org_buf,org_via->port_str.s);
  169. /* params (str type) */
  170. new_via->params.s=translate_pointer(new_buf,org_buf,org_via->params.s);
  171. /* transaction id */
  172. new_via->tid.s=
  173. translate_pointer(new_buf, org_buf, org_via->tid.s);
  174. /* comment (str type) */
  175. new_via->comment.s=
  176. translate_pointer(new_buf,org_buf,org_via->comment.s);
  177. if ( org_via->param_lst )
  178. {
  179. struct via_param *vp, *new_vp, *last_new_vp;
  180. for( vp=org_via->param_lst, last_new_vp=0 ; vp ; vp=vp->next )
  181. {
  182. new_vp = (struct via_param*)(*p);
  183. memcpy( new_vp , vp , sizeof(struct via_param));
  184. (*p) += ROUND4(sizeof(struct via_param));
  185. new_vp->name.s=translate_pointer(new_buf,org_buf,vp->name.s);
  186. new_vp->value.s=translate_pointer(new_buf,org_buf,vp->value.s);
  187. new_vp->start=translate_pointer(new_buf,org_buf,vp->start);
  188. /* "translate" the shortcuts */
  189. switch(new_vp->type){
  190. case PARAM_BRANCH:
  191. new_via->branch = new_vp;
  192. break;
  193. case PARAM_RECEIVED:
  194. new_via->received = new_vp;
  195. break;
  196. case PARAM_RPORT:
  197. new_via->rport = new_vp;
  198. break;
  199. case PARAM_I:
  200. new_via->i = new_vp;
  201. break;
  202. case PARAM_ALIAS:
  203. new_via->alias = new_vp;
  204. break;
  205. #ifdef USE_COMP
  206. case PARAM_COMP:
  207. new_via->comp = new_vp;
  208. break;
  209. #endif
  210. }
  211. if (last_new_vp)
  212. last_new_vp->next = new_vp;
  213. else
  214. new_via->param_lst = new_vp;
  215. last_new_vp = new_vp;
  216. last_new_vp->next = NULL;
  217. }
  218. new_via->last_param = new_vp;
  219. }/*end if via has params */
  220. if (last_via)
  221. last_via->next = new_via;
  222. else
  223. first_via = new_via;
  224. last_via = new_via;
  225. org_via = org_via->next;
  226. }while(org_via);
  227. return first_via;
  228. }
  229. static void uri_trans(char *new_buf, char *org_buf, struct sip_uri *uri)
  230. {
  231. uri->user.s=translate_pointer(new_buf,org_buf,uri->user.s);
  232. uri->passwd.s=translate_pointer(new_buf,org_buf,uri->passwd.s);
  233. uri->host.s=translate_pointer(new_buf,org_buf,uri->host.s);
  234. uri->port.s=translate_pointer(new_buf,org_buf,uri->port.s);
  235. uri->params.s=translate_pointer(new_buf,org_buf,uri->params.s);
  236. uri->headers.s=translate_pointer(new_buf,org_buf,uri->headers.s);
  237. /* parameters */
  238. uri->transport.s=translate_pointer(new_buf,org_buf,uri->transport.s);
  239. uri->ttl.s=translate_pointer(new_buf,org_buf,uri->ttl.s);
  240. uri->user_param.s=translate_pointer(new_buf,org_buf,uri->user_param.s);
  241. uri->maddr.s=translate_pointer(new_buf,org_buf,uri->maddr.s);
  242. uri->method.s=translate_pointer(new_buf,org_buf,uri->method.s);
  243. uri->lr.s=translate_pointer(new_buf,org_buf,uri->lr.s);
  244. uri->r2.s=translate_pointer(new_buf,org_buf,uri->r2.s);
  245. /* values */
  246. uri->transport_val.s
  247. =translate_pointer(new_buf,org_buf,uri->transport_val.s);
  248. uri->ttl_val.s=translate_pointer(new_buf,org_buf,uri->ttl_val.s);
  249. uri->user_param_val.s
  250. =translate_pointer(new_buf,org_buf,uri->user_param_val.s);
  251. uri->maddr_val.s=translate_pointer(new_buf,org_buf,uri->maddr_val.s);
  252. uri->method_val.s=translate_pointer(new_buf,org_buf,uri->method_val.s);
  253. uri->lr_val.s=translate_pointer(new_buf,org_buf,uri->lr_val.s);
  254. uri->r2_val.s=translate_pointer(new_buf,org_buf,uri->r2_val.s);
  255. }
  256. static inline struct auth_body* auth_body_cloner(char* new_buf, char *org_buf, struct auth_body *auth, char **p)
  257. {
  258. struct auth_body* new_auth;
  259. new_auth = (struct auth_body*)(*p);
  260. memcpy(new_auth , auth , sizeof(struct auth_body));
  261. (*p) += ROUND4(sizeof(struct auth_body));
  262. /* authorized field must be cloned elsewhere */
  263. new_auth->digest.username.whole.s =
  264. translate_pointer(new_buf, org_buf, auth->digest.username.whole.s);
  265. new_auth->digest.username.user.s =
  266. translate_pointer(new_buf, org_buf, auth->digest.username.user.s);
  267. new_auth->digest.username.domain.s =
  268. translate_pointer(new_buf, org_buf, auth->digest.username.domain.s);
  269. new_auth->digest.realm.s =
  270. translate_pointer(new_buf, org_buf, auth->digest.realm.s);
  271. new_auth->digest.nonce.s =
  272. translate_pointer(new_buf, org_buf, auth->digest.nonce.s);
  273. new_auth->digest.uri.s =
  274. translate_pointer(new_buf, org_buf, auth->digest.uri.s);
  275. new_auth->digest.response.s =
  276. translate_pointer(new_buf, org_buf, auth->digest.response.s);
  277. new_auth->digest.alg.alg_str.s =
  278. translate_pointer(new_buf, org_buf, auth->digest.alg.alg_str.s);
  279. new_auth->digest.cnonce.s =
  280. translate_pointer(new_buf, org_buf, auth->digest.cnonce.s);
  281. new_auth->digest.opaque.s =
  282. translate_pointer(new_buf, org_buf, auth->digest.opaque.s);
  283. new_auth->digest.qop.qop_str.s =
  284. translate_pointer(new_buf, org_buf, auth->digest.qop.qop_str.s);
  285. new_auth->digest.nc.s =
  286. translate_pointer(new_buf, org_buf, auth->digest.nc.s);
  287. return new_auth;
  288. }
  289. static inline int clone_authorized_hooks(struct sip_msg* new,
  290. struct sip_msg* old)
  291. {
  292. struct hdr_field* ptr, *new_ptr, *hook1, *hook2;
  293. char stop = 0;
  294. get_authorized_cred(old->authorization, &hook1);
  295. if (!hook1) stop = 1;
  296. get_authorized_cred(old->proxy_auth, &hook2);
  297. if (!hook2) stop |= 2;
  298. ptr = old->headers;
  299. new_ptr = new->headers;
  300. while(ptr) {
  301. if (ptr == hook1) {
  302. if (!new->authorization || !new->authorization->parsed) {
  303. LM_CRIT("Error in message cloner (authorization)\n");
  304. return -1;
  305. }
  306. ((struct auth_body*)new->authorization->parsed)->authorized =
  307. new_ptr;
  308. stop |= 1;
  309. }
  310. if (ptr == hook2) {
  311. if (!new->proxy_auth || !new->proxy_auth->parsed) {
  312. LM_CRIT("Error in message cloner (proxy_auth)\n");
  313. return -1;
  314. }
  315. ((struct auth_body*)new->proxy_auth->parsed)->authorized =
  316. new_ptr;
  317. stop |= 2;
  318. }
  319. if (stop == 3) break;
  320. ptr = ptr->next;
  321. new_ptr = new_ptr->next;
  322. }
  323. return 0;
  324. }
  325. #define AUTH_BODY_SIZE sizeof(struct auth_body)
  326. #define HOOK_SET(hook) (new_msg->hook != org_msg->hook)
  327. /** Creates a shm clone for a sip_msg.
  328. * org_msg is cloned along with most of its headers and lumps into one
  329. * shm memory block (so that a shm_free() on the result will free everything)
  330. * @return shm malloced sip_msg on success, 0 on error
  331. * Warning: Cloner does not clone all hdr_field headers (From, To, etc.).
  332. */
  333. struct sip_msg* sip_msg_shm_clone( struct sip_msg *org_msg, int *sip_msg_len,
  334. int clone_lumps)
  335. {
  336. unsigned int len;
  337. struct hdr_field *hdr,*new_hdr,*last_hdr;
  338. struct via_body *via;
  339. struct via_param *prm;
  340. struct to_param *to_prm,*new_to_prm;
  341. struct sip_msg *new_msg;
  342. char *p;
  343. /*computing the length of entire sip_msg structure*/
  344. len = ROUND4(sizeof( struct sip_msg ));
  345. /*we will keep only the original msg +ZT */
  346. len += ROUND4(org_msg->len + 1);
  347. /*the new uri (if any)*/
  348. if (org_msg->new_uri.s && org_msg->new_uri.len)
  349. len+= ROUND4(org_msg->new_uri.len);
  350. /*the dst uri (if any)*/
  351. if (org_msg->dst_uri.s && org_msg->dst_uri.len)
  352. len+= ROUND4(org_msg->dst_uri.len);
  353. if (org_msg->path_vec.s && org_msg->path_vec.len)
  354. len+= ROUND4(org_msg->path_vec.len);
  355. /*all the headers*/
  356. for( hdr=org_msg->headers ; hdr ; hdr=hdr->next )
  357. {
  358. /*size of header struct*/
  359. len += ROUND4(sizeof( struct hdr_field));
  360. switch (hdr->type) {
  361. /* Safely ignore auxiliary header types */
  362. case HDR_ERROR_T:
  363. case HDR_OTHER_T:
  364. case HDR_VIA2_T:
  365. case HDR_EOH_T:
  366. break;
  367. case HDR_VIA_T:
  368. for (via=(struct via_body*)hdr->parsed;via;via=via->next) {
  369. len+=ROUND4(sizeof(struct via_body));
  370. /*via param*/
  371. for(prm=via->param_lst;prm;prm=prm->next)
  372. len+=ROUND4(sizeof(struct via_param ));
  373. }
  374. break;
  375. case HDR_TO_T:
  376. case HDR_FROM_T:
  377. /* From header might be unparsed */
  378. if (hdr->parsed) {
  379. len+=ROUND4(sizeof(struct to_body));
  380. /*to param*/
  381. to_prm = ((struct to_body*)(hdr->parsed))->param_lst;
  382. for(;to_prm;to_prm=to_prm->next)
  383. len+=ROUND4(sizeof(struct to_param ));
  384. }
  385. break;
  386. case HDR_CSEQ_T:
  387. len+=ROUND4(sizeof(struct cseq_body));
  388. break;
  389. case HDR_AUTHORIZATION_T:
  390. case HDR_PROXYAUTH_T:
  391. if (hdr->parsed) {
  392. len += ROUND4(AUTH_BODY_SIZE);
  393. }
  394. break;
  395. case HDR_CALLID_T:
  396. case HDR_CONTACT_T:
  397. case HDR_MAXFORWARDS_T:
  398. case HDR_ROUTE_T:
  399. case HDR_RECORDROUTE_T:
  400. case HDR_CONTENTTYPE_T:
  401. case HDR_CONTENTLENGTH_T:
  402. case HDR_RETRY_AFTER_T:
  403. case HDR_EXPIRES_T:
  404. case HDR_SUPPORTED_T:
  405. case HDR_REQUIRE_T:
  406. case HDR_PROXYREQUIRE_T:
  407. case HDR_UNSUPPORTED_T:
  408. case HDR_ALLOW_T:
  409. case HDR_EVENT_T:
  410. case HDR_ACCEPT_T:
  411. case HDR_ACCEPTLANGUAGE_T:
  412. case HDR_ORGANIZATION_T:
  413. case HDR_PRIORITY_T:
  414. case HDR_SUBJECT_T:
  415. case HDR_USERAGENT_T:
  416. case HDR_SERVER_T:
  417. case HDR_CONTENTDISPOSITION_T:
  418. case HDR_DIVERSION_T:
  419. case HDR_RPID_T:
  420. case HDR_REFER_TO_T:
  421. case HDR_SIPIFMATCH_T:
  422. case HDR_SESSIONEXPIRES_T:
  423. case HDR_MIN_SE_T:
  424. case HDR_SUBSCRIPTION_STATE_T:
  425. case HDR_ACCEPTCONTACT_T:
  426. case HDR_ALLOWEVENTS_T:
  427. case HDR_CONTENTENCODING_T:
  428. case HDR_REFERREDBY_T:
  429. case HDR_REJECTCONTACT_T:
  430. case HDR_REQUESTDISPOSITION_T:
  431. case HDR_WWW_AUTHENTICATE_T:
  432. case HDR_PROXY_AUTHENTICATE_T:
  433. case HDR_DATE_T:
  434. case HDR_IDENTITY_T:
  435. case HDR_IDENTITY_INFO_T:
  436. case HDR_PPI_T:
  437. case HDR_PAI_T:
  438. case HDR_PATH_T:
  439. case HDR_PRIVACY_T:
  440. case HDR_REASON_T:
  441. /* we ignore them for now even if they have something parsed*/
  442. break;
  443. }/*switch*/
  444. }/*for all headers*/
  445. if (clone_lumps) {
  446. /* calculate the length of the data and reply lump structures */
  447. LUMP_LIST_LEN(len, org_msg->add_rm);
  448. LUMP_LIST_LEN(len, org_msg->body_lumps);
  449. RPL_LUMP_LIST_LEN(len, org_msg->reply_lump);
  450. }
  451. p=(char *)shm_malloc(len);
  452. if (!p)
  453. {
  454. LM_ERR("cannot allocate memory\n" );
  455. return 0;
  456. }
  457. if (sip_msg_len)
  458. *sip_msg_len = len;
  459. /* filling up the new structure */
  460. new_msg = (struct sip_msg*)p;
  461. /* sip msg structure */
  462. memcpy( new_msg , org_msg , sizeof(struct sip_msg) );
  463. new_msg->msg_flags |= FL_SHM_CLONE;
  464. p += ROUND4(sizeof(struct sip_msg));
  465. new_msg->body = 0;
  466. new_msg->add_rm = 0;
  467. new_msg->body_lumps = 0;
  468. new_msg->reply_lump = 0;
  469. /* zero *uri.s, in case len is 0 but org_msg->*uris!=0 (just to be safe)*/
  470. new_msg->new_uri.s = 0;
  471. new_msg->dst_uri.s = 0;
  472. new_msg->path_vec.s = 0;
  473. /* new_uri */
  474. if (org_msg->new_uri.s && org_msg->new_uri.len)
  475. {
  476. new_msg->new_uri.s = p;
  477. memcpy( p , org_msg->new_uri.s , org_msg->new_uri.len);
  478. p += ROUND4(org_msg->new_uri.len);
  479. }
  480. /* dst_uri */
  481. if (org_msg->dst_uri.s && org_msg->dst_uri.len)
  482. {
  483. new_msg->dst_uri.s = p;
  484. memcpy( p , org_msg->dst_uri.s , org_msg->dst_uri.len);
  485. p += ROUND4(org_msg->dst_uri.len);
  486. }
  487. /* path vector */
  488. if (org_msg->path_vec.s && org_msg->path_vec.len) {
  489. new_msg->path_vec.s = p;
  490. memcpy(p, org_msg->path_vec.s, org_msg->path_vec.len);
  491. p += ROUND4(org_msg->path_vec.len);
  492. }
  493. /* instance is not cloned (it's reset instead) */
  494. new_msg->instance.s=0;
  495. new_msg->instance.len=0;
  496. /* ruid is not cloned (it's reset instead) */
  497. new_msg->ruid.s=0;
  498. new_msg->ruid.len=0;
  499. /* location ua is not cloned (it's reset instead) */
  500. new_msg->location_ua.s=0;
  501. new_msg->location_ua.len=0;
  502. /* reg_id is not cloned (it's reset instead) */
  503. new_msg->reg_id=0;
  504. /* local data struct is not cloned (it's reset instead) */
  505. memset(&new_msg->ldv, 0, sizeof(msg_ldata_t));
  506. /* message buffers(org and scratch pad) */
  507. memcpy( p , org_msg->buf, org_msg->len);
  508. /* ZT to be safer */
  509. *(p+org_msg->len)=0;
  510. new_msg->buf = p;
  511. p += ROUND4(new_msg->len+1);
  512. /* unparsed and eoh pointer */
  513. new_msg->unparsed = translate_pointer(new_msg->buf ,org_msg->buf,
  514. org_msg->unparsed );
  515. new_msg->eoh = translate_pointer(new_msg->buf,org_msg->buf,org_msg->eoh);
  516. /* first line, updating the pointers*/
  517. if ( org_msg->first_line.type==SIP_REQUEST )
  518. {
  519. new_msg->first_line.u.request.method.s =
  520. translate_pointer( new_msg->buf , org_msg->buf ,
  521. org_msg->first_line.u.request.method.s );
  522. new_msg->first_line.u.request.uri.s =
  523. translate_pointer( new_msg->buf , org_msg->buf ,
  524. org_msg->first_line.u.request.uri.s );
  525. new_msg->first_line.u.request.version.s =
  526. translate_pointer( new_msg->buf , org_msg->buf ,
  527. org_msg->first_line.u.request.version.s );
  528. uri_trans(new_msg->buf, org_msg->buf, &new_msg->parsed_orig_ruri);
  529. if (org_msg->new_uri.s && org_msg->new_uri.len)
  530. uri_trans(new_msg->new_uri.s, org_msg->new_uri.s,
  531. &new_msg->parsed_uri);
  532. else
  533. uri_trans(new_msg->buf, org_msg->buf, &new_msg->parsed_uri);
  534. }
  535. else if ( org_msg->first_line.type==SIP_REPLY )
  536. {
  537. new_msg->first_line.u.reply.version.s =
  538. translate_pointer( new_msg->buf , org_msg->buf ,
  539. org_msg->first_line.u.reply.version.s );
  540. new_msg->first_line.u.reply.status.s =
  541. translate_pointer( new_msg->buf , org_msg->buf ,
  542. org_msg->first_line.u.reply.status.s );
  543. new_msg->first_line.u.reply.reason.s =
  544. translate_pointer( new_msg->buf , org_msg->buf ,
  545. org_msg->first_line.u.reply.reason.s );
  546. }
  547. /*headers list*/
  548. new_msg->via1=0;
  549. new_msg->via2=0;
  550. for( hdr=org_msg->headers,last_hdr=0 ; hdr ; hdr=hdr->next )
  551. {
  552. new_hdr = (struct hdr_field*)p;
  553. memcpy(new_hdr, hdr, sizeof(struct hdr_field) );
  554. p += ROUND4(sizeof( struct hdr_field));
  555. new_hdr->name.s = translate_pointer(new_msg->buf, org_msg->buf,
  556. hdr->name.s);
  557. new_hdr->body.s = translate_pointer(new_msg->buf, org_msg->buf,
  558. hdr->body.s);
  559. /* by default, we assume we don't understand this header in TM
  560. and better set it to zero; if we do, we will set a specific
  561. value in the following switch statement
  562. */
  563. new_hdr->parsed=0;
  564. switch (hdr->type)
  565. {
  566. /* Ignore auxiliary header types */
  567. case HDR_ERROR_T:
  568. case HDR_OTHER_T:
  569. case HDR_VIA2_T:
  570. case HDR_EOH_T:
  571. case HDR_ACCEPTCONTACT_T:
  572. case HDR_ALLOWEVENTS_T:
  573. case HDR_CONTENTENCODING_T:
  574. case HDR_REFERREDBY_T:
  575. case HDR_REJECTCONTACT_T:
  576. case HDR_REQUESTDISPOSITION_T:
  577. case HDR_WWW_AUTHENTICATE_T:
  578. case HDR_PROXY_AUTHENTICATE_T:
  579. case HDR_DATE_T:
  580. case HDR_IDENTITY_T:
  581. case HDR_IDENTITY_INFO_T:
  582. case HDR_RETRY_AFTER_T:
  583. case HDR_REASON_T:
  584. break;
  585. case HDR_VIA_T:
  586. if ( !new_msg->via1 ) {
  587. new_msg->h_via1 = new_hdr;
  588. new_msg->via1 = via_body_cloner(new_msg->buf,
  589. org_msg->buf, (struct via_body*)hdr->parsed, &p);
  590. new_hdr->parsed = (void*)new_msg->via1;
  591. if ( new_msg->via1->next ) {
  592. new_msg->via2 = new_msg->via1->next;
  593. }
  594. } else if ( !new_msg->via2 && new_msg->via1 ) {
  595. new_msg->h_via2 = new_hdr;
  596. if ( new_msg->via1->next ) {
  597. new_hdr->parsed = (void*)new_msg->via1->next;
  598. } else {
  599. new_msg->via2 = via_body_cloner( new_msg->buf,
  600. org_msg->buf, (struct via_body*)hdr->parsed, &p);
  601. new_hdr->parsed = (void*)new_msg->via2;
  602. }
  603. } else if ( new_msg->via2 && new_msg->via1 ) {
  604. new_hdr->parsed = via_body_cloner( new_msg->buf , org_msg->buf ,
  605. (struct via_body*)hdr->parsed , &p);
  606. }
  607. break;
  608. case HDR_CSEQ_T:
  609. new_hdr->parsed = p;
  610. p +=ROUND4(sizeof(struct cseq_body));
  611. memcpy(new_hdr->parsed, hdr->parsed, sizeof(struct cseq_body));
  612. ((struct cseq_body*)new_hdr->parsed)->number.s =
  613. translate_pointer(new_msg->buf ,org_msg->buf,
  614. ((struct cseq_body*)hdr->parsed)->number.s );
  615. ((struct cseq_body*)new_hdr->parsed)->method.s =
  616. translate_pointer(new_msg->buf ,org_msg->buf,
  617. ((struct cseq_body*)hdr->parsed)->method.s );
  618. if (!HOOK_SET(cseq)) new_msg->cseq = new_hdr;
  619. break;
  620. case HDR_TO_T:
  621. case HDR_FROM_T:
  622. if (hdr->type == HDR_TO_T) {
  623. if (!HOOK_SET(to)) new_msg->to = new_hdr;
  624. } else {
  625. if (!HOOK_SET(from)) new_msg->from = new_hdr;
  626. }
  627. /* From header might be unparsed */
  628. if (!hdr->parsed) break;
  629. new_hdr->parsed = p;
  630. p +=ROUND4(sizeof(struct to_body));
  631. memcpy(new_hdr->parsed, hdr->parsed, sizeof(struct to_body));
  632. ((struct to_body*)new_hdr->parsed)->body.s =
  633. translate_pointer( new_msg->buf , org_msg->buf ,
  634. ((struct to_body*)hdr->parsed)->body.s );
  635. ((struct to_body*)new_hdr->parsed)->display.s =
  636. translate_pointer( new_msg->buf, org_msg->buf,
  637. ((struct to_body*)hdr->parsed)->display.s);
  638. ((struct to_body*)new_hdr->parsed)->uri.s =
  639. translate_pointer( new_msg->buf , org_msg->buf ,
  640. ((struct to_body*)hdr->parsed)->uri.s );
  641. if ( ((struct to_body*)hdr->parsed)->tag_value.s )
  642. ((struct to_body*)new_hdr->parsed)->tag_value.s =
  643. translate_pointer( new_msg->buf , org_msg->buf ,
  644. ((struct to_body*)hdr->parsed)->tag_value.s );
  645. if ( (((struct to_body*)new_hdr->parsed)->parsed_uri.user.s)
  646. || (((struct to_body*)new_hdr->parsed)->parsed_uri.host.s) )
  647. uri_trans(new_msg->buf, org_msg->buf,
  648. &((struct to_body*)new_hdr->parsed)->parsed_uri);
  649. /*to params*/
  650. to_prm = ((struct to_body*)(hdr->parsed))->param_lst;
  651. for(;to_prm;to_prm=to_prm->next) {
  652. /*alloc*/
  653. new_to_prm = (struct to_param*)p;
  654. p +=ROUND4(sizeof(struct to_param ));
  655. /*coping*/
  656. memcpy( new_to_prm, to_prm, sizeof(struct to_param ));
  657. ((struct to_body*)new_hdr->parsed)->param_lst = 0;
  658. new_to_prm->name.s = translate_pointer( new_msg->buf,
  659. org_msg->buf , to_prm->name.s );
  660. new_to_prm->value.s = translate_pointer( new_msg->buf,
  661. org_msg->buf , to_prm->value.s );
  662. /*linking*/
  663. if ( !((struct to_body*)new_hdr->parsed)->param_lst )
  664. ((struct to_body*)new_hdr->parsed)->param_lst
  665. = new_to_prm;
  666. else
  667. ((struct to_body*)new_hdr->parsed)->last_param->next
  668. = new_to_prm;
  669. ((struct to_body*)new_hdr->parsed)->last_param
  670. = new_to_prm;
  671. }
  672. break;
  673. case HDR_CALLID_T:
  674. if (!HOOK_SET(callid)) {
  675. new_msg->callid = new_hdr;
  676. }
  677. break;
  678. case HDR_CONTACT_T:
  679. if (!HOOK_SET(contact)) {
  680. new_msg->contact = new_hdr;
  681. }
  682. break;
  683. case HDR_MAXFORWARDS_T:
  684. if (!HOOK_SET(maxforwards)) {
  685. new_msg->maxforwards = new_hdr;
  686. new_msg->maxforwards->parsed = hdr->parsed;
  687. }
  688. break;
  689. case HDR_ROUTE_T:
  690. if (!HOOK_SET(route)) {
  691. new_msg->route = new_hdr;
  692. }
  693. break;
  694. case HDR_RECORDROUTE_T:
  695. if (!HOOK_SET(record_route)) {
  696. new_msg->record_route = new_hdr;
  697. }
  698. break;
  699. case HDR_CONTENTTYPE_T:
  700. if (!HOOK_SET(content_type)) {
  701. new_msg->content_type = new_hdr;
  702. new_msg->content_type->parsed = hdr->parsed;
  703. }
  704. break;
  705. case HDR_CONTENTLENGTH_T:
  706. if (!HOOK_SET(content_length)) {
  707. new_msg->content_length = new_hdr;
  708. new_msg->content_length->parsed = hdr->parsed;
  709. }
  710. break;
  711. case HDR_AUTHORIZATION_T:
  712. if (!HOOK_SET(authorization)) {
  713. new_msg->authorization = new_hdr;
  714. }
  715. if (hdr->parsed) {
  716. new_hdr->parsed = auth_body_cloner(new_msg->buf ,
  717. org_msg->buf , (struct auth_body*)hdr->parsed , &p);
  718. }
  719. break;
  720. case HDR_EXPIRES_T:
  721. if (!HOOK_SET(expires)) {
  722. new_msg->expires = new_hdr;
  723. }
  724. break;
  725. case HDR_PROXYAUTH_T:
  726. if (!HOOK_SET(proxy_auth)) {
  727. new_msg->proxy_auth = new_hdr;
  728. }
  729. if (hdr->parsed) {
  730. new_hdr->parsed = auth_body_cloner(new_msg->buf ,
  731. org_msg->buf , (struct auth_body*)hdr->parsed , &p);
  732. }
  733. break;
  734. case HDR_SUPPORTED_T:
  735. if (!HOOK_SET(supported)) {
  736. new_msg->supported = new_hdr;
  737. }
  738. break;
  739. case HDR_REQUIRE_T:
  740. if (!HOOK_SET(require)) {
  741. new_msg->require = new_hdr;
  742. }
  743. break;
  744. case HDR_PROXYREQUIRE_T:
  745. if (!HOOK_SET(proxy_require)) {
  746. new_msg->proxy_require = new_hdr;
  747. }
  748. break;
  749. case HDR_UNSUPPORTED_T:
  750. if (!HOOK_SET(unsupported)) {
  751. new_msg->unsupported = new_hdr;
  752. }
  753. break;
  754. case HDR_ALLOW_T:
  755. if (!HOOK_SET(allow)) {
  756. new_msg->allow = new_hdr;
  757. }
  758. break;
  759. case HDR_EVENT_T:
  760. if (!HOOK_SET(event)) {
  761. new_msg->event = new_hdr;
  762. }
  763. break;
  764. case HDR_ACCEPT_T:
  765. if (!HOOK_SET(accept)) {
  766. new_msg->accept = new_hdr;
  767. }
  768. break;
  769. case HDR_ACCEPTLANGUAGE_T:
  770. if (!HOOK_SET(accept_language)) {
  771. new_msg->accept_language = new_hdr;
  772. }
  773. break;
  774. case HDR_ORGANIZATION_T:
  775. if (!HOOK_SET(organization)) {
  776. new_msg->organization = new_hdr;
  777. }
  778. break;
  779. case HDR_PRIORITY_T:
  780. if (!HOOK_SET(priority)) {
  781. new_msg->priority = new_hdr;
  782. }
  783. break;
  784. case HDR_SUBJECT_T:
  785. if (!HOOK_SET(subject)) {
  786. new_msg->subject = new_hdr;
  787. }
  788. break;
  789. case HDR_USERAGENT_T:
  790. if (!HOOK_SET(user_agent)) {
  791. new_msg->user_agent = new_hdr;
  792. }
  793. break;
  794. case HDR_SERVER_T:
  795. if (!HOOK_SET(server)) {
  796. new_msg->server = new_hdr;
  797. }
  798. break;
  799. case HDR_CONTENTDISPOSITION_T:
  800. if (!HOOK_SET(content_disposition)) {
  801. new_msg->content_disposition = new_hdr;
  802. }
  803. break;
  804. case HDR_DIVERSION_T:
  805. if (!HOOK_SET(diversion)) {
  806. new_msg->diversion = new_hdr;
  807. }
  808. break;
  809. case HDR_RPID_T:
  810. if (!HOOK_SET(rpid)) {
  811. new_msg->rpid = new_hdr;
  812. }
  813. break;
  814. case HDR_REFER_TO_T:
  815. if (!HOOK_SET(refer_to)) {
  816. new_msg->refer_to = new_hdr;
  817. }
  818. break;
  819. case HDR_SESSIONEXPIRES_T:
  820. if (!HOOK_SET(session_expires)) {
  821. new_msg->session_expires = new_hdr;
  822. }
  823. break;
  824. case HDR_MIN_SE_T:
  825. if (!HOOK_SET(min_se)) {
  826. new_msg->min_se = new_hdr;
  827. }
  828. break;
  829. case HDR_SUBSCRIPTION_STATE_T:
  830. if (!HOOK_SET(subscription_state)) {
  831. new_msg->subscription_state = new_hdr;
  832. }
  833. break;
  834. case HDR_SIPIFMATCH_T:
  835. if (!HOOK_SET(sipifmatch)) {
  836. new_msg->sipifmatch = new_hdr;
  837. }
  838. break;
  839. case HDR_PPI_T:
  840. if (!HOOK_SET(ppi)) {
  841. new_msg->ppi = new_hdr;
  842. }
  843. break;
  844. case HDR_PAI_T:
  845. if (!HOOK_SET(pai)) {
  846. new_msg->pai = new_hdr;
  847. }
  848. break;
  849. case HDR_PATH_T:
  850. if (!HOOK_SET(path)) {
  851. new_msg->path = new_hdr;
  852. }
  853. break;
  854. case HDR_PRIVACY_T:
  855. if (!HOOK_SET(privacy)) {
  856. new_msg->privacy = new_hdr;
  857. }
  858. break;
  859. }/*switch*/
  860. if ( last_hdr )
  861. {
  862. last_hdr->next = new_hdr;
  863. last_hdr=last_hdr->next;
  864. }
  865. else
  866. {
  867. last_hdr=new_hdr;
  868. new_msg->headers =new_hdr;
  869. }
  870. last_hdr->next = 0;
  871. new_msg->last_header = last_hdr;
  872. }
  873. if (clone_lumps) {
  874. /*cloning data and reply lump structures*/
  875. CLONE_LUMP_LIST(&(new_msg->add_rm), org_msg->add_rm, p);
  876. CLONE_LUMP_LIST(&(new_msg->body_lumps), org_msg->body_lumps, p);
  877. CLONE_RPL_LUMP_LIST(&(new_msg->reply_lump), org_msg->reply_lump, p);
  878. }
  879. if (clone_authorized_hooks(new_msg, org_msg) < 0) {
  880. shm_free(new_msg);
  881. return 0;
  882. }
  883. return new_msg;
  884. }
  885. /** clones the data and reply lumps from pkg_msg to shm_msg.
  886. * A new memory block is allocated for the lumps (the lumps will point
  887. * into it).
  888. * Note: the new memory block is linked to add_rm if
  889. * at least one data lump is set, else it is linked to body_lumps
  890. * if at least one body lump is set, otherwise it is linked to
  891. * shm_msg->reply_lump.
  892. * @param pkg_msg - sip msg whoes lumps will be cloned
  893. * @param add_rm - result parameter, filled with the list of cloned
  894. * add_rm lumps (corresp. to msg->add_rm)
  895. * @param body_lumps - result parameter, filled with the list of cloned
  896. * body lumps (corresp. to msg->body_lumps)
  897. * @param reply_lump - result parameter, filled with the list of cloned
  898. * reply lumps (corresp. to msg->reply_lump)
  899. * @return 0 or 1 on success: 0 - lumps cloned), 1 - nothing to do and
  900. * -1 on error
  901. */
  902. int msg_lump_cloner(struct sip_msg *pkg_msg,
  903. struct lump** add_rm,
  904. struct lump** body_lumps,
  905. struct lump_rpl** reply_lump)
  906. {
  907. unsigned int len;
  908. char *p;
  909. *add_rm = *body_lumps = 0;
  910. *reply_lump = 0;
  911. /* calculate the length of the lumps */
  912. len = 0;
  913. LUMP_LIST_LEN(len, pkg_msg->add_rm);
  914. LUMP_LIST_LEN(len, pkg_msg->body_lumps);
  915. RPL_LUMP_LIST_LEN(len, pkg_msg->reply_lump);
  916. if (!len)
  917. return 1; /* nothing to do */
  918. p=(char *)shm_malloc(len);
  919. if (!p)
  920. {
  921. LM_ERR("cannot allocate memory\n" );
  922. return -1;
  923. }
  924. /* clone the lumps */
  925. CLONE_LUMP_LIST(add_rm, pkg_msg->add_rm, p);
  926. CLONE_LUMP_LIST(body_lumps, pkg_msg->body_lumps, p);
  927. CLONE_RPL_LUMP_LIST(reply_lump, pkg_msg->reply_lump, p);
  928. return 0;
  929. }
  930. /* vi: set ts=4 sw=4 tw=79:ai:cindent: */