Takes a SIP msg and makes of a clone on it in shared memory; the clone * is in a single memory chunks (all headers, lumps, etc). * Param "updatable" can be : * 0 - msg cannot be updated -> everything in the single mem chunk * 1 - msg can be updated -> new/dst URI, PATH, lumps are in separate * mem chunks, so they can be updated later * 2 - msg can be upd
| 402 | * 2 - msg can be updated, but do not copy updatable part at cloning |
| 403 | */ |
| 404 | struct sip_msg* sip_msg_cloner( struct sip_msg *org_msg, int *sip_msg_len, |
| 405 | int updatable) |
| 406 | { |
| 407 | unsigned int len, l1_len, l2_len, l3_len; |
| 408 | struct hdr_field *hdr,*new_hdr,*last_hdr; |
| 409 | struct via_body *via; |
| 410 | struct via_param *prm; |
| 411 | struct to_param *to_prm,*new_to_prm; |
| 412 | struct sip_msg *new_msg; |
| 413 | char *p; |
| 414 | |
| 415 | /*computing the length of entire sip_msg structure*/ |
| 416 | len = ROUND4(sizeof( struct sip_msg )); |
| 417 | /*we will keep only the original msg +ZT */ |
| 418 | len += ROUND4(org_msg->len + 1); |
| 419 | |
| 420 | /*all the headers*/ |
| 421 | for( hdr=org_msg->headers ; hdr ; hdr=hdr->next ) |
| 422 | { |
| 423 | /*size of header struct*/ |
| 424 | len += ROUND4(sizeof( struct hdr_field)); |
| 425 | switch (hdr->type) |
| 426 | { |
| 427 | case HDR_VIA_T: |
| 428 | for (via=(struct via_body*)hdr->parsed;via;via=via->next) |
| 429 | { |
| 430 | len+=ROUND4(sizeof(struct via_body)); |
| 431 | /*via param*/ |
| 432 | for(prm=via->param_lst;prm;prm=prm->next) |
| 433 | len+=ROUND4(sizeof(struct via_param )); |
| 434 | } |
| 435 | break; |
| 436 | |
| 437 | case HDR_TO_T: |
| 438 | case HDR_FROM_T: |
| 439 | /* From header might be unparsed */ |
| 440 | if (hdr->parsed) { |
| 441 | len+=ROUND4(sizeof(struct to_body)); |
| 442 | /*to param*/ |
| 443 | to_prm = ((struct to_body*)(hdr->parsed))->param_lst; |
| 444 | for(;to_prm;to_prm=to_prm->next) |
| 445 | len+=ROUND4(sizeof(struct to_param )); |
| 446 | } |
| 447 | break; |
| 448 | |
| 449 | case HDR_CSEQ_T: |
| 450 | len+=ROUND4(sizeof(struct cseq_body)); |
| 451 | break; |
| 452 | |
| 453 | case HDR_AUTHORIZATION_T: |
| 454 | case HDR_PROXYAUTH_T: |
| 455 | if (hdr->parsed) { |
| 456 | len += ROUND4(AUTH_BODY_SIZE); |
| 457 | } |
| 458 | break; |
| 459 | |
| 460 | case HDR_CALLID_T: |
| 461 | case HDR_CONTACT_T: |
no test coverage detected