sip_msg_clone.c 28 KB

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