sip_msg_clone.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997
  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. LOG(L_CRIT, "BUG: 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. LOG(L_CRIT, "BUG: 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. /*all the headers*/
  354. for( hdr=org_msg->headers ; hdr ; hdr=hdr->next )
  355. {
  356. /*size of header struct*/
  357. len += ROUND4(sizeof( struct hdr_field));
  358. switch (hdr->type) {
  359. /* Safely ignore auxiliary header types */
  360. case HDR_ERROR_T:
  361. case HDR_OTHER_T:
  362. case HDR_VIA2_T:
  363. case HDR_EOH_T:
  364. break;
  365. case HDR_VIA_T:
  366. for (via=(struct via_body*)hdr->parsed;via;via=via->next) {
  367. len+=ROUND4(sizeof(struct via_body));
  368. /*via param*/
  369. for(prm=via->param_lst;prm;prm=prm->next)
  370. len+=ROUND4(sizeof(struct via_param ));
  371. }
  372. break;
  373. case HDR_TO_T:
  374. case HDR_FROM_T:
  375. /* From header might be unparsed */
  376. if (hdr->parsed) {
  377. len+=ROUND4(sizeof(struct to_body));
  378. /*to param*/
  379. to_prm = ((struct to_body*)(hdr->parsed))->param_lst;
  380. for(;to_prm;to_prm=to_prm->next)
  381. len+=ROUND4(sizeof(struct to_param ));
  382. }
  383. break;
  384. case HDR_CSEQ_T:
  385. len+=ROUND4(sizeof(struct cseq_body));
  386. break;
  387. case HDR_AUTHORIZATION_T:
  388. case HDR_PROXYAUTH_T:
  389. if (hdr->parsed) {
  390. len += ROUND4(AUTH_BODY_SIZE);
  391. }
  392. break;
  393. case HDR_CALLID_T:
  394. case HDR_CONTACT_T:
  395. case HDR_MAXFORWARDS_T:
  396. case HDR_ROUTE_T:
  397. case HDR_RECORDROUTE_T:
  398. case HDR_CONTENTTYPE_T:
  399. case HDR_CONTENTLENGTH_T:
  400. case HDR_RETRY_AFTER_T:
  401. case HDR_EXPIRES_T:
  402. case HDR_SUPPORTED_T:
  403. case HDR_REQUIRE_T:
  404. case HDR_PROXYREQUIRE_T:
  405. case HDR_UNSUPPORTED_T:
  406. case HDR_ALLOW_T:
  407. case HDR_EVENT_T:
  408. case HDR_ACCEPT_T:
  409. case HDR_ACCEPTLANGUAGE_T:
  410. case HDR_ORGANIZATION_T:
  411. case HDR_PRIORITY_T:
  412. case HDR_SUBJECT_T:
  413. case HDR_USERAGENT_T:
  414. case HDR_SERVER_T:
  415. case HDR_CONTENTDISPOSITION_T:
  416. case HDR_DIVERSION_T:
  417. case HDR_RPID_T:
  418. case HDR_REFER_TO_T:
  419. case HDR_SIPIFMATCH_T:
  420. case HDR_SESSIONEXPIRES_T:
  421. case HDR_MIN_SE_T:
  422. case HDR_SUBSCRIPTION_STATE_T:
  423. case HDR_ACCEPTCONTACT_T:
  424. case HDR_ALLOWEVENTS_T:
  425. case HDR_CONTENTENCODING_T:
  426. case HDR_REFERREDBY_T:
  427. case HDR_REJECTCONTACT_T:
  428. case HDR_REQUESTDISPOSITION_T:
  429. case HDR_WWW_AUTHENTICATE_T:
  430. case HDR_PROXY_AUTHENTICATE_T:
  431. case HDR_DATE_T:
  432. case HDR_IDENTITY_T:
  433. case HDR_IDENTITY_INFO_T:
  434. case HDR_PPI_T:
  435. case HDR_PAI_T:
  436. case HDR_PATH_T:
  437. case HDR_PRIVACY_T:
  438. case HDR_REASON_T:
  439. /* we ignore them for now even if they have something parsed*/
  440. break;
  441. }/*switch*/
  442. }/*for all headers*/
  443. if (clone_lumps) {
  444. /* calculate the length of the data and reply lump structures */
  445. LUMP_LIST_LEN(len, org_msg->add_rm);
  446. LUMP_LIST_LEN(len, org_msg->body_lumps);
  447. RPL_LUMP_LIST_LEN(len, org_msg->reply_lump);
  448. }
  449. p=(char *)shm_malloc(len);
  450. if (!p)
  451. {
  452. LOG(L_ERR , "ERROR: sip_msg_cloner: cannot allocate memory\n" );
  453. return 0;
  454. }
  455. if (sip_msg_len)
  456. *sip_msg_len = len;
  457. /* filling up the new structure */
  458. new_msg = (struct sip_msg*)p;
  459. /* sip msg structure */
  460. memcpy( new_msg , org_msg , sizeof(struct sip_msg) );
  461. new_msg->msg_flags |= FL_SHM_CLONE;
  462. p += ROUND4(sizeof(struct sip_msg));
  463. new_msg->body = 0;
  464. new_msg->add_rm = 0;
  465. new_msg->body_lumps = 0;
  466. new_msg->reply_lump = 0;
  467. /* zero *uri.s, in case len is 0 but org_msg->*uris!=0 (just to be safe)*/
  468. new_msg->new_uri.s = 0;
  469. new_msg->dst_uri.s = 0;
  470. /* new_uri */
  471. if (org_msg->new_uri.s && org_msg->new_uri.len)
  472. {
  473. new_msg->new_uri.s = p;
  474. memcpy( p , org_msg->new_uri.s , org_msg->new_uri.len);
  475. p += ROUND4(org_msg->new_uri.len);
  476. }
  477. /* dst_uri */
  478. if (org_msg->dst_uri.s && org_msg->dst_uri.len)
  479. {
  480. new_msg->dst_uri.s = p;
  481. memcpy( p , org_msg->dst_uri.s , org_msg->dst_uri.len);
  482. p += ROUND4(org_msg->dst_uri.len);
  483. }
  484. /* path_vec is not cloned (it's reset instead) */
  485. new_msg->path_vec.s=0;
  486. new_msg->path_vec.len=0;
  487. /* instance is not cloned (it's reset instead) */
  488. new_msg->instance.s=0;
  489. new_msg->instance.len=0;
  490. /* ruid is not cloned (it's reset instead) */
  491. new_msg->ruid.s=0;
  492. new_msg->ruid.len=0;
  493. /* location ua is not cloned (it's reset instead) */
  494. new_msg->location_ua.s=0;
  495. new_msg->location_ua.len=0;
  496. /* reg_id is not cloned (it's reset instead) */
  497. new_msg->reg_id=0;
  498. /* local data struct is not cloned (it's reset instead) */
  499. memset(&new_msg->ldv, 0, sizeof(msg_ldata_t));
  500. /* message buffers(org and scratch pad) */
  501. memcpy( p , org_msg->buf, org_msg->len);
  502. /* ZT to be safer */
  503. *(p+org_msg->len)=0;
  504. new_msg->buf = p;
  505. p += ROUND4(new_msg->len+1);
  506. /* unparsed and eoh pointer */
  507. new_msg->unparsed = translate_pointer(new_msg->buf ,org_msg->buf,
  508. org_msg->unparsed );
  509. new_msg->eoh = translate_pointer(new_msg->buf,org_msg->buf,org_msg->eoh);
  510. /* first line, updating the pointers*/
  511. if ( org_msg->first_line.type==SIP_REQUEST )
  512. {
  513. new_msg->first_line.u.request.method.s =
  514. translate_pointer( new_msg->buf , org_msg->buf ,
  515. org_msg->first_line.u.request.method.s );
  516. new_msg->first_line.u.request.uri.s =
  517. translate_pointer( new_msg->buf , org_msg->buf ,
  518. org_msg->first_line.u.request.uri.s );
  519. new_msg->first_line.u.request.version.s =
  520. translate_pointer( new_msg->buf , org_msg->buf ,
  521. org_msg->first_line.u.request.version.s );
  522. uri_trans(new_msg->buf, org_msg->buf, &new_msg->parsed_orig_ruri);
  523. if (org_msg->new_uri.s && org_msg->new_uri.len)
  524. uri_trans(new_msg->new_uri.s, org_msg->new_uri.s,
  525. &new_msg->parsed_uri);
  526. else
  527. uri_trans(new_msg->buf, org_msg->buf, &new_msg->parsed_uri);
  528. }
  529. else if ( org_msg->first_line.type==SIP_REPLY )
  530. {
  531. new_msg->first_line.u.reply.version.s =
  532. translate_pointer( new_msg->buf , org_msg->buf ,
  533. org_msg->first_line.u.reply.version.s );
  534. new_msg->first_line.u.reply.status.s =
  535. translate_pointer( new_msg->buf , org_msg->buf ,
  536. org_msg->first_line.u.reply.status.s );
  537. new_msg->first_line.u.reply.reason.s =
  538. translate_pointer( new_msg->buf , org_msg->buf ,
  539. org_msg->first_line.u.reply.reason.s );
  540. }
  541. /*headers list*/
  542. new_msg->via1=0;
  543. new_msg->via2=0;
  544. for( hdr=org_msg->headers,last_hdr=0 ; hdr ; hdr=hdr->next )
  545. {
  546. new_hdr = (struct hdr_field*)p;
  547. memcpy(new_hdr, hdr, sizeof(struct hdr_field) );
  548. p += ROUND4(sizeof( struct hdr_field));
  549. new_hdr->name.s = translate_pointer(new_msg->buf, org_msg->buf,
  550. hdr->name.s);
  551. new_hdr->body.s = translate_pointer(new_msg->buf, org_msg->buf,
  552. hdr->body.s);
  553. /* by default, we assume we don't understand this header in TM
  554. and better set it to zero; if we do, we will set a specific
  555. value in the following switch statement
  556. */
  557. new_hdr->parsed=0;
  558. switch (hdr->type)
  559. {
  560. /* Ignore auxiliary header types */
  561. case HDR_ERROR_T:
  562. case HDR_OTHER_T:
  563. case HDR_VIA2_T:
  564. case HDR_EOH_T:
  565. case HDR_ACCEPTCONTACT_T:
  566. case HDR_ALLOWEVENTS_T:
  567. case HDR_CONTENTENCODING_T:
  568. case HDR_REFERREDBY_T:
  569. case HDR_REJECTCONTACT_T:
  570. case HDR_REQUESTDISPOSITION_T:
  571. case HDR_WWW_AUTHENTICATE_T:
  572. case HDR_PROXY_AUTHENTICATE_T:
  573. case HDR_DATE_T:
  574. case HDR_IDENTITY_T:
  575. case HDR_IDENTITY_INFO_T:
  576. case HDR_RETRY_AFTER_T:
  577. case HDR_REASON_T:
  578. break;
  579. case HDR_VIA_T:
  580. if ( !new_msg->via1 ) {
  581. new_msg->h_via1 = new_hdr;
  582. new_msg->via1 = via_body_cloner(new_msg->buf,
  583. org_msg->buf, (struct via_body*)hdr->parsed, &p);
  584. new_hdr->parsed = (void*)new_msg->via1;
  585. if ( new_msg->via1->next ) {
  586. new_msg->via2 = new_msg->via1->next;
  587. }
  588. } else if ( !new_msg->via2 && new_msg->via1 ) {
  589. new_msg->h_via2 = new_hdr;
  590. if ( new_msg->via1->next ) {
  591. new_hdr->parsed = (void*)new_msg->via1->next;
  592. } else {
  593. new_msg->via2 = via_body_cloner( new_msg->buf,
  594. org_msg->buf, (struct via_body*)hdr->parsed, &p);
  595. new_hdr->parsed = (void*)new_msg->via2;
  596. }
  597. } else if ( new_msg->via2 && new_msg->via1 ) {
  598. new_hdr->parsed = via_body_cloner( new_msg->buf , org_msg->buf ,
  599. (struct via_body*)hdr->parsed , &p);
  600. }
  601. break;
  602. case HDR_CSEQ_T:
  603. new_hdr->parsed = p;
  604. p +=ROUND4(sizeof(struct cseq_body));
  605. memcpy(new_hdr->parsed, hdr->parsed, sizeof(struct cseq_body));
  606. ((struct cseq_body*)new_hdr->parsed)->number.s =
  607. translate_pointer(new_msg->buf ,org_msg->buf,
  608. ((struct cseq_body*)hdr->parsed)->number.s );
  609. ((struct cseq_body*)new_hdr->parsed)->method.s =
  610. translate_pointer(new_msg->buf ,org_msg->buf,
  611. ((struct cseq_body*)hdr->parsed)->method.s );
  612. if (!HOOK_SET(cseq)) new_msg->cseq = new_hdr;
  613. break;
  614. case HDR_TO_T:
  615. case HDR_FROM_T:
  616. if (hdr->type == HDR_TO_T) {
  617. if (!HOOK_SET(to)) new_msg->to = new_hdr;
  618. } else {
  619. if (!HOOK_SET(from)) new_msg->from = new_hdr;
  620. }
  621. /* From header might be unparsed */
  622. if (!hdr->parsed) break;
  623. new_hdr->parsed = p;
  624. p +=ROUND4(sizeof(struct to_body));
  625. memcpy(new_hdr->parsed, hdr->parsed, sizeof(struct to_body));
  626. ((struct to_body*)new_hdr->parsed)->body.s =
  627. translate_pointer( new_msg->buf , org_msg->buf ,
  628. ((struct to_body*)hdr->parsed)->body.s );
  629. ((struct to_body*)new_hdr->parsed)->display.s =
  630. translate_pointer( new_msg->buf, org_msg->buf,
  631. ((struct to_body*)hdr->parsed)->display.s);
  632. ((struct to_body*)new_hdr->parsed)->uri.s =
  633. translate_pointer( new_msg->buf , org_msg->buf ,
  634. ((struct to_body*)hdr->parsed)->uri.s );
  635. if ( ((struct to_body*)hdr->parsed)->tag_value.s )
  636. ((struct to_body*)new_hdr->parsed)->tag_value.s =
  637. translate_pointer( new_msg->buf , org_msg->buf ,
  638. ((struct to_body*)hdr->parsed)->tag_value.s );
  639. if ( (((struct to_body*)new_hdr->parsed)->parsed_uri.user.s)
  640. || (((struct to_body*)new_hdr->parsed)->parsed_uri.host.s) )
  641. uri_trans(new_msg->buf, org_msg->buf,
  642. &((struct to_body*)new_hdr->parsed)->parsed_uri);
  643. /*to params*/
  644. to_prm = ((struct to_body*)(hdr->parsed))->param_lst;
  645. for(;to_prm;to_prm=to_prm->next) {
  646. /*alloc*/
  647. new_to_prm = (struct to_param*)p;
  648. p +=ROUND4(sizeof(struct to_param ));
  649. /*coping*/
  650. memcpy( new_to_prm, to_prm, sizeof(struct to_param ));
  651. ((struct to_body*)new_hdr->parsed)->param_lst = 0;
  652. new_to_prm->name.s = translate_pointer( new_msg->buf,
  653. org_msg->buf , to_prm->name.s );
  654. new_to_prm->value.s = translate_pointer( new_msg->buf,
  655. org_msg->buf , to_prm->value.s );
  656. /*linking*/
  657. if ( !((struct to_body*)new_hdr->parsed)->param_lst )
  658. ((struct to_body*)new_hdr->parsed)->param_lst
  659. = new_to_prm;
  660. else
  661. ((struct to_body*)new_hdr->parsed)->last_param->next
  662. = new_to_prm;
  663. ((struct to_body*)new_hdr->parsed)->last_param
  664. = new_to_prm;
  665. }
  666. break;
  667. case HDR_CALLID_T:
  668. if (!HOOK_SET(callid)) {
  669. new_msg->callid = new_hdr;
  670. }
  671. break;
  672. case HDR_CONTACT_T:
  673. if (!HOOK_SET(contact)) {
  674. new_msg->contact = new_hdr;
  675. }
  676. break;
  677. case HDR_MAXFORWARDS_T:
  678. if (!HOOK_SET(maxforwards)) {
  679. new_msg->maxforwards = new_hdr;
  680. }
  681. break;
  682. case HDR_ROUTE_T:
  683. if (!HOOK_SET(route)) {
  684. new_msg->route = new_hdr;
  685. }
  686. break;
  687. case HDR_RECORDROUTE_T:
  688. if (!HOOK_SET(record_route)) {
  689. new_msg->record_route = new_hdr;
  690. }
  691. break;
  692. case HDR_CONTENTTYPE_T:
  693. if (!HOOK_SET(content_type)) {
  694. new_msg->content_type = new_hdr;
  695. new_msg->content_type->parsed = hdr->parsed;
  696. }
  697. break;
  698. case HDR_CONTENTLENGTH_T:
  699. if (!HOOK_SET(content_length)) {
  700. new_msg->content_length = new_hdr;
  701. new_msg->content_length->parsed = hdr->parsed;
  702. }
  703. break;
  704. case HDR_AUTHORIZATION_T:
  705. if (!HOOK_SET(authorization)) {
  706. new_msg->authorization = new_hdr;
  707. }
  708. if (hdr->parsed) {
  709. new_hdr->parsed = auth_body_cloner(new_msg->buf ,
  710. org_msg->buf , (struct auth_body*)hdr->parsed , &p);
  711. }
  712. break;
  713. case HDR_EXPIRES_T:
  714. if (!HOOK_SET(expires)) {
  715. new_msg->expires = new_hdr;
  716. }
  717. break;
  718. case HDR_PROXYAUTH_T:
  719. if (!HOOK_SET(proxy_auth)) {
  720. new_msg->proxy_auth = new_hdr;
  721. }
  722. if (hdr->parsed) {
  723. new_hdr->parsed = auth_body_cloner(new_msg->buf ,
  724. org_msg->buf , (struct auth_body*)hdr->parsed , &p);
  725. }
  726. break;
  727. case HDR_SUPPORTED_T:
  728. if (!HOOK_SET(supported)) {
  729. new_msg->supported = new_hdr;
  730. }
  731. break;
  732. case HDR_REQUIRE_T:
  733. if (!HOOK_SET(require)) {
  734. new_msg->require = new_hdr;
  735. }
  736. break;
  737. case HDR_PROXYREQUIRE_T:
  738. if (!HOOK_SET(proxy_require)) {
  739. new_msg->proxy_require = new_hdr;
  740. }
  741. break;
  742. case HDR_UNSUPPORTED_T:
  743. if (!HOOK_SET(unsupported)) {
  744. new_msg->unsupported = new_hdr;
  745. }
  746. break;
  747. case HDR_ALLOW_T:
  748. if (!HOOK_SET(allow)) {
  749. new_msg->allow = new_hdr;
  750. }
  751. break;
  752. case HDR_EVENT_T:
  753. if (!HOOK_SET(event)) {
  754. new_msg->event = new_hdr;
  755. }
  756. break;
  757. case HDR_ACCEPT_T:
  758. if (!HOOK_SET(accept)) {
  759. new_msg->accept = new_hdr;
  760. }
  761. break;
  762. case HDR_ACCEPTLANGUAGE_T:
  763. if (!HOOK_SET(accept_language)) {
  764. new_msg->accept_language = new_hdr;
  765. }
  766. break;
  767. case HDR_ORGANIZATION_T:
  768. if (!HOOK_SET(organization)) {
  769. new_msg->organization = new_hdr;
  770. }
  771. break;
  772. case HDR_PRIORITY_T:
  773. if (!HOOK_SET(priority)) {
  774. new_msg->priority = new_hdr;
  775. }
  776. break;
  777. case HDR_SUBJECT_T:
  778. if (!HOOK_SET(subject)) {
  779. new_msg->subject = new_hdr;
  780. }
  781. break;
  782. case HDR_USERAGENT_T:
  783. if (!HOOK_SET(user_agent)) {
  784. new_msg->user_agent = new_hdr;
  785. }
  786. break;
  787. case HDR_SERVER_T:
  788. if (!HOOK_SET(server)) {
  789. new_msg->server = new_hdr;
  790. }
  791. break;
  792. case HDR_CONTENTDISPOSITION_T:
  793. if (!HOOK_SET(content_disposition)) {
  794. new_msg->content_disposition = new_hdr;
  795. }
  796. break;
  797. case HDR_DIVERSION_T:
  798. if (!HOOK_SET(diversion)) {
  799. new_msg->diversion = new_hdr;
  800. }
  801. break;
  802. case HDR_RPID_T:
  803. if (!HOOK_SET(rpid)) {
  804. new_msg->rpid = new_hdr;
  805. }
  806. break;
  807. case HDR_REFER_TO_T:
  808. if (!HOOK_SET(refer_to)) {
  809. new_msg->refer_to = new_hdr;
  810. }
  811. break;
  812. case HDR_SESSIONEXPIRES_T:
  813. if (!HOOK_SET(session_expires)) {
  814. new_msg->session_expires = new_hdr;
  815. }
  816. break;
  817. case HDR_MIN_SE_T:
  818. if (!HOOK_SET(min_se)) {
  819. new_msg->min_se = new_hdr;
  820. }
  821. break;
  822. case HDR_SUBSCRIPTION_STATE_T:
  823. if (!HOOK_SET(subscription_state)) {
  824. new_msg->subscription_state = new_hdr;
  825. }
  826. break;
  827. case HDR_SIPIFMATCH_T:
  828. if (!HOOK_SET(sipifmatch)) {
  829. new_msg->sipifmatch = new_hdr;
  830. }
  831. break;
  832. case HDR_PPI_T:
  833. if (!HOOK_SET(ppi)) {
  834. new_msg->ppi = new_hdr;
  835. }
  836. break;
  837. case HDR_PAI_T:
  838. if (!HOOK_SET(pai)) {
  839. new_msg->pai = new_hdr;
  840. }
  841. break;
  842. case HDR_PATH_T:
  843. if (!HOOK_SET(path)) {
  844. new_msg->path = new_hdr;
  845. }
  846. break;
  847. case HDR_PRIVACY_T:
  848. if (!HOOK_SET(privacy)) {
  849. new_msg->privacy = new_hdr;
  850. }
  851. break;
  852. }/*switch*/
  853. if ( last_hdr )
  854. {
  855. last_hdr->next = new_hdr;
  856. last_hdr=last_hdr->next;
  857. }
  858. else
  859. {
  860. last_hdr=new_hdr;
  861. new_msg->headers =new_hdr;
  862. }
  863. last_hdr->next = 0;
  864. new_msg->last_header = last_hdr;
  865. }
  866. if (clone_lumps) {
  867. /*cloning data and reply lump structures*/
  868. CLONE_LUMP_LIST(&(new_msg->add_rm), org_msg->add_rm, p);
  869. CLONE_LUMP_LIST(&(new_msg->body_lumps), org_msg->body_lumps, p);
  870. CLONE_RPL_LUMP_LIST(&(new_msg->reply_lump), org_msg->reply_lump, p);
  871. }
  872. if (clone_authorized_hooks(new_msg, org_msg) < 0) {
  873. shm_free(new_msg);
  874. return 0;
  875. }
  876. return new_msg;
  877. }
  878. /** clones the data and reply lumps from pkg_msg to shm_msg.
  879. * A new memory block is allocated for the lumps (the lumps will point
  880. * into it).
  881. * Note: the new memory block is linked to add_rm if
  882. * at least one data lump is set, else it is linked to body_lumps
  883. * if at least one body lump is set, otherwise it is linked to
  884. * shm_msg->reply_lump.
  885. * @param pkg_msg - sip msg whoes lumps will be cloned
  886. * @param add_rm - result parameter, filled with the list of cloned
  887. * add_rm lumps (corresp. to msg->add_rm)
  888. * @param body_lumps - result parameter, filled with the list of cloned
  889. * body lumps (corresp. to msg->body_lumps)
  890. * @param reply_lump - result parameter, filled with the list of cloned
  891. * reply lumps (corresp. to msg->reply_lump)
  892. * @return 0 or 1 on success: 0 - lumps cloned), 1 - nothing to do and
  893. * -1 on error
  894. */
  895. int msg_lump_cloner(struct sip_msg *pkg_msg,
  896. struct lump** add_rm,
  897. struct lump** body_lumps,
  898. struct lump_rpl** reply_lump)
  899. {
  900. unsigned int len;
  901. char *p;
  902. *add_rm = *body_lumps = 0;
  903. *reply_lump = 0;
  904. /* calculate the length of the lumps */
  905. len = 0;
  906. LUMP_LIST_LEN(len, pkg_msg->add_rm);
  907. LUMP_LIST_LEN(len, pkg_msg->body_lumps);
  908. RPL_LUMP_LIST_LEN(len, pkg_msg->reply_lump);
  909. if (!len)
  910. return 1; /* nothing to do */
  911. p=(char *)shm_malloc(len);
  912. if (!p)
  913. {
  914. LOG(L_ERR, "ERROR: msg_lump_cloner: cannot allocate memory\n" );
  915. return -1;
  916. }
  917. /* clone the lumps */
  918. CLONE_LUMP_LIST(add_rm, pkg_msg->add_rm, p);
  919. CLONE_LUMP_LIST(body_lumps, pkg_msg->body_lumps, p);
  920. CLONE_RPL_LUMP_LIST(reply_lump, pkg_msg->reply_lump, p);
  921. return 0;
  922. }
  923. /* vi: set ts=4 sw=4 tw=79:ai:cindent: */