00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #include <stdio.h>
00059 #include "sip_msg.h"
00060 #include "../../dprint.h"
00061 #include "../../mem/mem.h"
00062 #include "../../data_lump.h"
00063 #include "../../data_lump_rpl.h"
00064 #include "../../ut.h"
00065 #include "../../parser/digest/digest.h"
00066
00067
00068
00069
00070 #define ROUND4(s) \
00071 (((s)+(sizeof(char*)-1))&(~(sizeof(char*)-1)))
00072
00073 #define lump_len( _lump) \
00074 (ROUND4(sizeof(struct lump)) +\
00075 ROUND4(((_lump)->op==LUMP_ADD)?(_lump)->len:0))
00076 #define lump_clone( _new,_old,_ptr) \
00077 {\
00078 (_new) = (struct lump*)(_ptr);\
00079 memcpy( (_new), (_old), sizeof(struct lump) );\
00080 (_new)->flags|=LUMPFLAG_SHMEM; \
00081 (_ptr)+=ROUND4(sizeof(struct lump));\
00082 if ( (_old)->op==LUMP_ADD) {\
00083 (_new)->u.value = (char*)(_ptr);\
00084 memcpy( (_new)->u.value , (_old)->u.value , (_old)->len);\
00085 (_ptr)+=ROUND4((_old)->len);}\
00086 }
00087
00088
00089
00090
00091 inline static struct via_body* via_body_cloner( char* new_buf,
00092 char *org_buf, struct via_body *param_org_via, char **p)
00093 {
00094 struct via_body *new_via;
00095 struct via_body *first_via, *last_via;
00096 struct via_body *org_via;
00097
00098 first_via = last_via = 0;
00099 org_via = param_org_via;
00100
00101 do
00102 {
00103
00104 new_via = (struct via_body*)(*p);
00105 memcpy( new_via , org_via , sizeof( struct via_body) );
00106 (*p) += ROUND4(sizeof( struct via_body ));
00107
00108
00109 new_via->hdr.s=translate_pointer(new_buf,org_buf,org_via->hdr.s);
00110
00111 new_via->name.s=translate_pointer(new_buf,org_buf,org_via->name.s);
00112
00113 new_via->version.s=
00114 translate_pointer(new_buf,org_buf,org_via->version.s);
00115
00116 new_via->transport.s=
00117 translate_pointer(new_buf,org_buf,org_via->transport.s);
00118
00119 new_via->host.s=translate_pointer(new_buf,org_buf,org_via->host.s);
00120
00121 new_via->port_str.s=
00122 translate_pointer(new_buf,org_buf,org_via->port_str.s);
00123
00124 new_via->params.s=translate_pointer(new_buf,org_buf,org_via->params.s);
00125
00126 new_via->tid.s=
00127 translate_pointer(new_buf, org_buf, org_via->tid.s);
00128
00129 new_via->comment.s=
00130 translate_pointer(new_buf,org_buf,org_via->comment.s);
00131
00132 if ( org_via->param_lst )
00133 {
00134 struct via_param *vp, *new_vp, *last_new_vp;
00135 for( vp=org_via->param_lst, last_new_vp=0 ; vp ; vp=vp->next )
00136 {
00137 new_vp = (struct via_param*)(*p);
00138 memcpy( new_vp , vp , sizeof(struct via_param));
00139 (*p) += ROUND4(sizeof(struct via_param));
00140 new_vp->name.s=translate_pointer(new_buf,org_buf,vp->name.s);
00141 new_vp->value.s=translate_pointer(new_buf,org_buf,vp->value.s);
00142 new_vp->start=translate_pointer(new_buf,org_buf,vp->start);
00143
00144
00145 switch(new_vp->type){
00146 case PARAM_BRANCH:
00147 new_via->branch = new_vp;
00148 break;
00149 case PARAM_RECEIVED:
00150 new_via->received = new_vp;
00151 break;
00152 case PARAM_RPORT:
00153 new_via->rport = new_vp;
00154 break;
00155 case PARAM_I:
00156 new_via->i = new_vp;
00157 break;
00158 case PARAM_ALIAS:
00159 new_via->alias = new_vp;
00160 break;
00161 case PARAM_MADDR:
00162 new_via->maddr = new_vp;
00163 break;
00164 }
00165
00166 if (last_new_vp)
00167 last_new_vp->next = new_vp;
00168 else
00169 new_via->param_lst = new_vp;
00170
00171 last_new_vp = new_vp;
00172 last_new_vp->next = NULL;
00173 }
00174 new_via->last_param = new_vp;
00175 }
00176
00177 if (last_via)
00178 last_via->next = new_via;
00179 else
00180 first_via = new_via;
00181 last_via = new_via;
00182 org_via = org_via->next;
00183 }while(org_via);
00184
00185 return first_via;
00186 }
00187
00188
00189 static void uri_trans(char *new_buf, char *org_buf, struct sip_uri *uri)
00190 {
00191 uri->user.s=translate_pointer(new_buf,org_buf,uri->user.s);
00192 uri->passwd.s=translate_pointer(new_buf,org_buf,uri->passwd.s);
00193 uri->host.s=translate_pointer(new_buf,org_buf,uri->host.s);
00194 uri->port.s=translate_pointer(new_buf,org_buf,uri->port.s);
00195 uri->params.s=translate_pointer(new_buf,org_buf,uri->params.s);
00196 uri->headers.s=translate_pointer(new_buf,org_buf,uri->headers.s);
00197
00198 uri->transport.s=translate_pointer(new_buf,org_buf,uri->transport.s);
00199 uri->ttl.s=translate_pointer(new_buf,org_buf,uri->ttl.s);
00200 uri->user_param.s=translate_pointer(new_buf,org_buf,uri->user_param.s);
00201 uri->maddr.s=translate_pointer(new_buf,org_buf,uri->maddr.s);
00202 uri->method.s=translate_pointer(new_buf,org_buf,uri->method.s);
00203 uri->lr.s=translate_pointer(new_buf,org_buf,uri->lr.s);
00204 uri->r2.s=translate_pointer(new_buf,org_buf,uri->r2.s);
00205
00206
00207 uri->transport_val.s
00208 =translate_pointer(new_buf,org_buf,uri->transport_val.s);
00209 uri->ttl_val.s=translate_pointer(new_buf,org_buf,uri->ttl_val.s);
00210 uri->user_param_val.s
00211 =translate_pointer(new_buf,org_buf,uri->user_param_val.s);
00212 uri->maddr_val.s=translate_pointer(new_buf,org_buf,uri->maddr_val.s);
00213 uri->method_val.s=translate_pointer(new_buf,org_buf,uri->method_val.s);
00214 uri->lr_val.s=translate_pointer(new_buf,org_buf,uri->lr_val.s);
00215
00216 uri->r2_val.s=translate_pointer(new_buf,org_buf,uri->r2_val.s);
00217 }
00218
00219
00220 static inline struct auth_body* auth_body_cloner(char* new_buf, char *org_buf, struct auth_body *auth, char **p)
00221 {
00222 struct auth_body* new_auth;
00223
00224 new_auth = (struct auth_body*)(*p);
00225 memcpy(new_auth , auth , sizeof(struct auth_body));
00226 (*p) += ROUND4(sizeof(struct auth_body));
00227
00228
00229 new_auth->digest.username.whole.s =
00230 translate_pointer(new_buf, org_buf, auth->digest.username.whole.s);
00231 new_auth->digest.username.user.s =
00232 translate_pointer(new_buf, org_buf, auth->digest.username.user.s);
00233 new_auth->digest.username.domain.s =
00234 translate_pointer(new_buf, org_buf, auth->digest.username.domain.s);
00235 new_auth->digest.realm.s =
00236 translate_pointer(new_buf, org_buf, auth->digest.realm.s);
00237 new_auth->digest.nonce.s =
00238 translate_pointer(new_buf, org_buf, auth->digest.nonce.s);
00239 new_auth->digest.uri.s =
00240 translate_pointer(new_buf, org_buf, auth->digest.uri.s);
00241 new_auth->digest.response.s =
00242 translate_pointer(new_buf, org_buf, auth->digest.response.s);
00243 new_auth->digest.alg.alg_str.s =
00244 translate_pointer(new_buf, org_buf, auth->digest.alg.alg_str.s);
00245 new_auth->digest.cnonce.s =
00246 translate_pointer(new_buf, org_buf, auth->digest.cnonce.s);
00247 new_auth->digest.opaque.s =
00248 translate_pointer(new_buf, org_buf, auth->digest.opaque.s);
00249 new_auth->digest.qop.qop_str.s =
00250 translate_pointer(new_buf, org_buf, auth->digest.qop.qop_str.s);
00251 new_auth->digest.nc.s =
00252 translate_pointer(new_buf, org_buf, auth->digest.nc.s);
00253 return new_auth;
00254 }
00255
00256
00257 static inline int clone_authorized_hooks(struct sip_msg* new,
00258 struct sip_msg* old)
00259 {
00260 struct hdr_field* ptr, *new_ptr, *hook1, *hook2;
00261 char stop = 0;
00262
00263 get_authorized_cred(old->authorization, &hook1);
00264 if (!hook1) stop = 1;
00265
00266 get_authorized_cred(old->proxy_auth, &hook2);
00267 if (!hook2) stop |= 2;
00268
00269 ptr = old->headers;
00270 new_ptr = new->headers;
00271
00272 while(ptr) {
00273 if (ptr == hook1) {
00274 if (!new->authorization || !new->authorization->parsed) {
00275 LM_CRIT("message cloner (authorization) failed\n");
00276 return -1;
00277 }
00278 ((struct auth_body*)new->authorization->parsed)->authorized =
00279 new_ptr;
00280 stop |= 1;
00281 }
00282
00283 if (ptr == hook2) {
00284 if (!new->proxy_auth || !new->proxy_auth->parsed) {
00285 LM_CRIT("message cloner (proxy_auth) failed\n");
00286 return -1;
00287 }
00288 ((struct auth_body*)new->proxy_auth->parsed)->authorized =
00289 new_ptr;
00290 stop |= 2;
00291 }
00292
00293 if (stop == 3) break;
00294
00295 ptr = ptr->next;
00296 new_ptr = new_ptr->next;
00297 }
00298 return 0;
00299 }
00300
00301
00302 #define AUTH_BODY_SIZE sizeof(struct auth_body)
00303
00304 #define HOOK_NOT_SET(hook) (new_msg->hook == org_msg->hook)
00305
00306
00307 #define LINK_SIBLING_HEADER(_hook, _hdr) \
00308 do { \
00309 struct hdr_field *_itr; \
00310 for (_itr=new_msg->_hook; _itr->sibling; _itr=_itr->sibling); \
00311 _itr->sibling = _hdr; \
00312 } while(0)
00313
00314
00315 struct sip_msg* sip_msg_cloner( struct sip_msg *org_msg, int *sip_msg_len )
00316 {
00317 unsigned int len;
00318 struct hdr_field *hdr,*new_hdr,*last_hdr;
00319 struct via_body *via;
00320 struct via_param *prm;
00321 struct to_param *to_prm,*new_to_prm;
00322 struct sip_msg *new_msg;
00323 struct lump_rpl *rpl_lump, **rpl_lump_anchor;
00324 char *p;
00325
00326
00327
00328 len = ROUND4(sizeof( struct sip_msg ));
00329
00330 len += ROUND4(org_msg->len + 1);
00331
00332 if (org_msg->new_uri.s && org_msg->new_uri.len)
00333 len+= ROUND4(org_msg->new_uri.len);
00334
00335 for( hdr=org_msg->headers ; hdr ; hdr=hdr->next )
00336 {
00337
00338 len += ROUND4(sizeof( struct hdr_field));
00339 switch (hdr->type)
00340 {
00341 case HDR_VIA_T:
00342 for (via=(struct via_body*)hdr->parsed;via;via=via->next)
00343 {
00344 len+=ROUND4(sizeof(struct via_body));
00345
00346 for(prm=via->param_lst;prm;prm=prm->next)
00347 len+=ROUND4(sizeof(struct via_param ));
00348 }
00349 break;
00350
00351 case HDR_TO_T:
00352 case HDR_FROM_T:
00353
00354 if (hdr->parsed) {
00355 len+=ROUND4(sizeof(struct to_body));
00356
00357 to_prm = ((struct to_body*)(hdr->parsed))->param_lst;
00358 for(;to_prm;to_prm=to_prm->next)
00359 len+=ROUND4(sizeof(struct to_param ));
00360 }
00361 break;
00362
00363 case HDR_CSEQ_T:
00364 len+=ROUND4(sizeof(struct cseq_body));
00365 break;
00366
00367 case HDR_AUTHORIZATION_T:
00368 case HDR_PROXYAUTH_T:
00369 if (hdr->parsed) {
00370 len += ROUND4(AUTH_BODY_SIZE);
00371 }
00372 break;
00373
00374 case HDR_CALLID_T:
00375 case HDR_CONTACT_T:
00376 case HDR_MAXFORWARDS_T:
00377 case HDR_ROUTE_T:
00378 case HDR_RECORDROUTE_T:
00379 case HDR_CONTENTTYPE_T:
00380 case HDR_CONTENTLENGTH_T:
00381 case HDR_EXPIRES_T:
00382 case HDR_SUPPORTED_T:
00383 case HDR_PROXYREQUIRE_T:
00384 case HDR_UNSUPPORTED_T:
00385 case HDR_ALLOW_T:
00386 case HDR_EVENT_T:
00387 case HDR_ACCEPT_T:
00388 case HDR_ACCEPTLANGUAGE_T:
00389 case HDR_ORGANIZATION_T:
00390 case HDR_PRIORITY_T:
00391 case HDR_SUBJECT_T:
00392 case HDR_USERAGENT_T:
00393 case HDR_ACCEPTDISPOSITION_T:
00394 case HDR_CONTENTDISPOSITION_T:
00395 case HDR_DIVERSION_T:
00396 case HDR_RPID_T:
00397 case HDR_REFER_TO_T:
00398 case HDR_SESSION_EXPIRES_T:
00399 case HDR_MIN_SE_T:
00400 case HDR_PPI_T:
00401 case HDR_PAI_T:
00402 case HDR_PRIVACY_T:
00403 case HDR_RETRY_AFTER_T:
00404 case HDR_PATH_T:
00405
00406 break;
00407
00408 default:
00409 if (hdr->parsed) {
00410 LM_WARN("header body ignored: %d\n", hdr->type );
00411 }
00412 break;
00413 }
00414 }
00415
00416
00417 #define LUMP_LIST_LEN(len, list) \
00418 do { \
00419 struct lump* tmp, *chain; \
00420 chain = (list); \
00421 while (chain) \
00422 { \
00423 (len) += lump_len(chain); \
00424 tmp = chain->before; \
00425 while ( tmp ) \
00426 { \
00427 (len) += lump_len( tmp ); \
00428 tmp = tmp->before; \
00429 } \
00430 tmp = chain->after; \
00431 while ( tmp ) \
00432 { \
00433 (len) += lump_len( tmp ); \
00434 tmp = tmp->after; \
00435 } \
00436 chain = chain->next; \
00437 } \
00438 } while(0);
00439
00440 LUMP_LIST_LEN(len, org_msg->add_rm);
00441 LUMP_LIST_LEN(len, org_msg->body_lumps);
00442
00443
00444 for(rpl_lump=org_msg->reply_lump;rpl_lump;rpl_lump=rpl_lump->next)
00445 len+=ROUND4(sizeof(struct lump_rpl))+ROUND4(rpl_lump->text.len);
00446
00447 p=(char *)shm_malloc(len);
00448 if (!p)
00449 {
00450 LM_ERR("no more share memory\n" );
00451 return 0;
00452 }
00453 if (sip_msg_len)
00454 *sip_msg_len = len;
00455
00456
00457 new_msg = (struct sip_msg*)p;
00458
00459 memcpy( new_msg , org_msg , sizeof(struct sip_msg) );
00460
00461
00462 new_msg->sdp = 0;
00463
00464 new_msg->msg_flags |= FL_SHM_CLONE;
00465 p += ROUND4(sizeof(struct sip_msg));
00466 new_msg->add_rm = 0;
00467 new_msg->body_lumps = 0;
00468
00469 if (org_msg->new_uri.s && org_msg->new_uri.len)
00470 {
00471 new_msg->new_uri.s = p;
00472 memcpy( p , org_msg->new_uri.s , org_msg->new_uri.len);
00473 p += ROUND4(org_msg->new_uri.len);
00474 }
00475
00476 new_msg->dst_uri.s = 0;
00477 new_msg->dst_uri.len = 0;
00478
00479 new_msg->path_vec.s = 0;
00480 new_msg->path_vec.len = 0;
00481
00482 memcpy( p , org_msg->buf, org_msg->len);
00483
00484 *(p+org_msg->len)=0;
00485 new_msg->buf = p;
00486 p += ROUND4(new_msg->len+1);
00487
00488 new_msg->unparsed = translate_pointer(new_msg->buf ,org_msg->buf,
00489 org_msg->unparsed );
00490 new_msg->eoh = translate_pointer(new_msg->buf,org_msg->buf,org_msg->eoh);
00491
00492 if ( org_msg->first_line.type==SIP_REQUEST )
00493 {
00494 new_msg->first_line.u.request.method.s =
00495 translate_pointer( new_msg->buf , org_msg->buf ,
00496 org_msg->first_line.u.request.method.s );
00497 new_msg->first_line.u.request.uri.s =
00498 translate_pointer( new_msg->buf , org_msg->buf ,
00499 org_msg->first_line.u.request.uri.s );
00500 new_msg->first_line.u.request.version.s =
00501 translate_pointer( new_msg->buf , org_msg->buf ,
00502 org_msg->first_line.u.request.version.s );
00503 if(new_msg->parsed_orig_ruri_ok)
00504 uri_trans(new_msg->buf, org_msg->buf, &new_msg->parsed_orig_ruri);
00505 if(new_msg->parsed_uri_ok)
00506 uri_trans(new_msg->buf, org_msg->buf, &new_msg->parsed_uri);
00507 }
00508 else if ( org_msg->first_line.type==SIP_REPLY )
00509 {
00510 new_msg->first_line.u.reply.version.s =
00511 translate_pointer( new_msg->buf , org_msg->buf ,
00512 org_msg->first_line.u.reply.version.s );
00513 new_msg->first_line.u.reply.status.s =
00514 translate_pointer( new_msg->buf , org_msg->buf ,
00515 org_msg->first_line.u.reply.status.s );
00516 new_msg->first_line.u.reply.reason.s =
00517 translate_pointer( new_msg->buf , org_msg->buf ,
00518 org_msg->first_line.u.reply.reason.s );
00519 }
00520
00521
00522 new_msg->via1=0;
00523 new_msg->via2=0;
00524 for( hdr=org_msg->headers,last_hdr=0 ; hdr ; hdr=hdr->next )
00525 {
00526 new_hdr = (struct hdr_field*)p;
00527 memcpy(new_hdr, hdr, sizeof(struct hdr_field) );
00528 p += ROUND4(sizeof( struct hdr_field));
00529 new_hdr->name.s = translate_pointer(new_msg->buf, org_msg->buf,
00530 hdr->name.s);
00531 new_hdr->body.s = translate_pointer(new_msg->buf, org_msg->buf,
00532 hdr->body.s);
00533
00534
00535
00536
00537 new_hdr->parsed=0;
00538
00539 new_hdr->sibling=0;
00540
00541 switch (hdr->type)
00542 {
00543 case HDR_VIA_T:
00544
00545
00546
00547 if ( !new_msg->via1 )
00548 {
00549 new_msg->h_via1 = new_hdr;
00550 new_msg->via1 = via_body_cloner(new_msg->buf,
00551 org_msg->buf, (struct via_body*)hdr->parsed, &p);
00552 new_hdr->parsed = (void*)new_msg->via1;
00553
00554
00555
00556 if ( new_msg->via1->next )
00557 new_msg->via2 = new_msg->via1->next;
00558 }
00559 else if ( !new_msg->via2 )
00560 {
00561 LINK_SIBLING_HEADER(h_via1, new_hdr);
00562 new_msg->h_via2 = new_hdr;
00563 new_msg->via2 = via_body_cloner( new_msg->buf,
00564 org_msg->buf, (struct via_body*)hdr->parsed, &p);
00565 new_hdr->parsed = (void*)new_msg->via2;
00566 }
00567 else
00568 {
00569 LINK_SIBLING_HEADER(h_via1, new_hdr);
00570 new_hdr->parsed =
00571 via_body_cloner( new_msg->buf , org_msg->buf ,
00572 (struct via_body*)hdr->parsed , &p);
00573 }
00574 break;
00575 case HDR_CSEQ_T:
00576 new_hdr->parsed = p;
00577 p +=ROUND4(sizeof(struct cseq_body));
00578 memcpy(new_hdr->parsed, hdr->parsed, sizeof(struct cseq_body));
00579 ((struct cseq_body*)new_hdr->parsed)->number.s =
00580 translate_pointer(new_msg->buf ,org_msg->buf,
00581 ((struct cseq_body*)hdr->parsed)->number.s );
00582 ((struct cseq_body*)new_hdr->parsed)->method.s =
00583 translate_pointer(new_msg->buf ,org_msg->buf,
00584 ((struct cseq_body*)hdr->parsed)->method.s );
00585 if (HOOK_NOT_SET(cseq)) new_msg->cseq = new_hdr;
00586 break;
00587 case HDR_TO_T:
00588 case HDR_FROM_T:
00589 if (hdr->type == HDR_TO_T) {
00590 if (HOOK_NOT_SET(to)) new_msg->to = new_hdr;
00591 } else {
00592 if (HOOK_NOT_SET(from)) new_msg->from = new_hdr;
00593 }
00594
00595 if (!hdr->parsed) break;
00596 new_hdr->parsed = p;
00597 p +=ROUND4(sizeof(struct to_body));
00598 memcpy(new_hdr->parsed, hdr->parsed, sizeof(struct to_body));
00599 ((struct to_body*)new_hdr->parsed)->body.s =
00600 translate_pointer( new_msg->buf , org_msg->buf ,
00601 ((struct to_body*)hdr->parsed)->body.s );
00602 ((struct to_body*)new_hdr->parsed)->uri.s =
00603 translate_pointer( new_msg->buf , org_msg->buf ,
00604 ((struct to_body*)hdr->parsed)->uri.s );
00605 if ( ((struct to_body*)hdr->parsed)->display.s )
00606 ((struct to_body*)new_hdr->parsed)->display.s =
00607 translate_pointer( new_msg->buf , org_msg->buf ,
00608 ((struct to_body*)hdr->parsed)->display.s );
00609 if ( ((struct to_body*)hdr->parsed)->tag_value.s )
00610 ((struct to_body*)new_hdr->parsed)->tag_value.s =
00611 translate_pointer( new_msg->buf , org_msg->buf ,
00612 ((struct to_body*)hdr->parsed)->tag_value.s );
00613 if ( (((struct to_body*)new_hdr->parsed)->parsed_uri.user.s)
00614 || (((struct to_body*)new_hdr->parsed)->parsed_uri.host.s) )
00615 uri_trans(new_msg->buf, org_msg->buf,
00616 &((struct to_body*)new_hdr->parsed)->parsed_uri);
00617
00618
00619 to_prm = ((struct to_body*)(hdr->parsed))->param_lst;
00620 for(;to_prm;to_prm=to_prm->next)
00621 {
00622
00623 new_to_prm = (struct to_param*)p;
00624 p +=ROUND4(sizeof(struct to_param ));
00625
00626 memcpy( new_to_prm, to_prm, sizeof(struct to_param ));
00627 ((struct to_body*)new_hdr->parsed)->param_lst = 0;
00628 new_to_prm->name.s = translate_pointer( new_msg->buf,
00629 org_msg->buf , to_prm->name.s );
00630 new_to_prm->value.s = translate_pointer( new_msg->buf,
00631 org_msg->buf , to_prm->value.s );
00632
00633 if ( !((struct to_body*)new_hdr->parsed)->param_lst )
00634 ((struct to_body*)new_hdr->parsed)->param_lst
00635 = new_to_prm;
00636 else
00637 ((struct to_body*)new_hdr->parsed)->last_param->next
00638 = new_to_prm;
00639 ((struct to_body*)new_hdr->parsed)->last_param
00640 = new_to_prm;
00641 }
00642 break;
00643 case HDR_CALLID_T:
00644 if (HOOK_NOT_SET(callid)) {
00645 new_msg->callid = new_hdr;
00646 }
00647 break;
00648 case HDR_CONTACT_T:
00649 if (HOOK_NOT_SET(contact)) {
00650 new_msg->contact = new_hdr;
00651 } else {
00652 LINK_SIBLING_HEADER(contact, new_hdr);
00653 }
00654 break;
00655 case HDR_MAXFORWARDS_T :
00656 if (HOOK_NOT_SET(maxforwards)) {
00657 new_msg->maxforwards = new_hdr;
00658 }
00659 break;
00660 case HDR_ROUTE_T :
00661 if (HOOK_NOT_SET(route)) {
00662 new_msg->route = new_hdr;
00663 } else {
00664 LINK_SIBLING_HEADER(route, new_hdr);
00665 }
00666 break;
00667 case HDR_RECORDROUTE_T :
00668 if (HOOK_NOT_SET(record_route)) {
00669 new_msg->record_route = new_hdr;
00670 } else {
00671 LINK_SIBLING_HEADER(record_route, new_hdr);
00672 }
00673 break;
00674 case HDR_CONTENTTYPE_T :
00675 if (HOOK_NOT_SET(content_type)) {
00676 new_msg->content_type = new_hdr;
00677 new_msg->content_type->parsed = hdr->parsed;
00678 }
00679 break;
00680 case HDR_CONTENTLENGTH_T :
00681 if (HOOK_NOT_SET(content_length)) {
00682 new_msg->content_length = new_hdr;
00683 new_msg->content_length->parsed = hdr->parsed;
00684 }
00685 break;
00686 case HDR_AUTHORIZATION_T :
00687 if (HOOK_NOT_SET(authorization)) {
00688 new_msg->authorization = new_hdr;
00689 } else {
00690 LINK_SIBLING_HEADER(authorization, new_hdr);
00691 }
00692 if (hdr->parsed) {
00693 new_hdr->parsed = auth_body_cloner(new_msg->buf ,
00694 org_msg->buf , (struct auth_body*)hdr->parsed , &p);
00695 }
00696 break;
00697 case HDR_EXPIRES_T :
00698 if (HOOK_NOT_SET(expires)) {
00699 new_msg->expires = new_hdr;
00700 }
00701 break;
00702 case HDR_PROXYAUTH_T :
00703 if (HOOK_NOT_SET(proxy_auth)) {
00704 new_msg->proxy_auth = new_hdr;
00705 } else {
00706 LINK_SIBLING_HEADER(proxy_auth, new_hdr);
00707 }
00708 if (hdr->parsed) {
00709 new_hdr->parsed = auth_body_cloner(new_msg->buf ,
00710 org_msg->buf , (struct auth_body*)hdr->parsed , &p);
00711 }
00712 break;
00713 case HDR_SUPPORTED_T :
00714 if (HOOK_NOT_SET(supported)) {
00715 new_msg->supported = new_hdr;
00716 } else {
00717 LINK_SIBLING_HEADER(supported, new_hdr);
00718 }
00719 break;
00720 case HDR_PROXYREQUIRE_T :
00721 if (HOOK_NOT_SET(proxy_require)) {
00722 new_msg->proxy_require = new_hdr;
00723 } else {
00724 LINK_SIBLING_HEADER(proxy_require, new_hdr);
00725 }
00726 break;
00727 case HDR_UNSUPPORTED_T :
00728 if (HOOK_NOT_SET(unsupported)) {
00729 new_msg->unsupported = new_hdr;
00730 } else {
00731 LINK_SIBLING_HEADER(unsupported, new_hdr);
00732 }
00733 break;
00734 case HDR_ALLOW_T :
00735 if (HOOK_NOT_SET(allow)) {
00736 new_msg->allow = new_hdr;
00737 } else {
00738 LINK_SIBLING_HEADER(allow, new_hdr);
00739 }
00740 break;
00741 case HDR_EVENT_T:
00742 if (HOOK_NOT_SET(event)) {
00743 new_msg->event = new_hdr;
00744 } else {
00745 LINK_SIBLING_HEADER(event, new_hdr);
00746 }
00747 break;
00748 case HDR_ACCEPT_T:
00749 if (HOOK_NOT_SET(accept)) {
00750 new_msg->accept = new_hdr;
00751 } else {
00752 LINK_SIBLING_HEADER(accept, new_hdr);
00753 }
00754 break;
00755 case HDR_ACCEPTLANGUAGE_T:
00756 if (HOOK_NOT_SET(accept_language)) {
00757 new_msg->accept_language = new_hdr;
00758 } else {
00759 LINK_SIBLING_HEADER(accept_language, new_hdr);
00760 }
00761 break;
00762 case HDR_ORGANIZATION_T:
00763 if (HOOK_NOT_SET(organization)) {
00764 new_msg->organization = new_hdr;
00765 }
00766 break;
00767 case HDR_PRIORITY_T:
00768 if (HOOK_NOT_SET(priority)) {
00769 new_msg->priority = new_hdr;
00770 }
00771 break;
00772 case HDR_SUBJECT_T:
00773 if (HOOK_NOT_SET(subject)) {
00774 new_msg->subject = new_hdr;
00775 }
00776 break;
00777 case HDR_USERAGENT_T:
00778 if (HOOK_NOT_SET(user_agent)) {
00779 new_msg->user_agent = new_hdr;
00780 }
00781 break;
00782 case HDR_ACCEPTDISPOSITION_T:
00783 if (HOOK_NOT_SET(accept_disposition)) {
00784 new_msg->accept_disposition = new_hdr;
00785 } else {
00786 LINK_SIBLING_HEADER(accept_disposition, new_hdr);
00787 }
00788 break;
00789 case HDR_CONTENTDISPOSITION_T:
00790 if (HOOK_NOT_SET(content_disposition)) {
00791 new_msg->content_disposition = new_hdr;
00792 }
00793 break;
00794 case HDR_DIVERSION_T:
00795 if (HOOK_NOT_SET(diversion)) {
00796 new_msg->diversion = new_hdr;
00797 } else {
00798 LINK_SIBLING_HEADER(diversion, new_hdr);
00799 }
00800 break;
00801 case HDR_RPID_T:
00802 if (HOOK_NOT_SET(rpid)) {
00803 new_msg->rpid = new_hdr;
00804 }
00805 break;
00806 case HDR_PPI_T:
00807 if (HOOK_NOT_SET(ppi)) {
00808 new_msg->ppi = new_hdr;
00809 }
00810 break;
00811 case HDR_PAI_T:
00812 if (HOOK_NOT_SET(pai)) {
00813 new_msg->pai = new_hdr;
00814 }
00815 break;
00816 case HDR_REFER_TO_T:
00817 if (HOOK_NOT_SET(refer_to)) {
00818 new_msg->refer_to = new_hdr;
00819 }
00820 break;
00821 case HDR_PRIVACY_T:
00822 if (HOOK_NOT_SET(privacy)) {
00823 new_msg->privacy = new_hdr;
00824 }
00825 break;
00826 case HDR_SESSION_EXPIRES_T:
00827 if (HOOK_NOT_SET(session_expires)) {
00828 new_msg->session_expires = new_hdr;
00829 }
00830 break;
00831 case HDR_MIN_SE_T:
00832 if (HOOK_NOT_SET(min_se)) {
00833 new_msg->min_se = new_hdr;
00834 }
00835 break;
00836 case HDR_PATH_T:
00837 if (HOOK_NOT_SET(path)) {
00838 new_msg->path = new_hdr;
00839 } else {
00840 LINK_SIBLING_HEADER(path, new_hdr);
00841 }
00842 break;
00843 default:
00844
00845 ;
00846 }
00847
00848 if ( last_hdr )
00849 {
00850 last_hdr->next = new_hdr;
00851 last_hdr=last_hdr->next;
00852 }
00853 else
00854 {
00855 last_hdr=new_hdr;
00856 new_msg->headers =new_hdr;
00857 }
00858 last_hdr->next = 0;
00859 new_msg->last_header = last_hdr;
00860 }
00861
00862
00863 #define CLONE_LUMP_LIST(anchor, list) \
00864 do { \
00865 struct lump* lump_tmp, *l; \
00866 struct lump** lump_anchor2, **a; \
00867 a = (anchor); \
00868 l = (list); \
00869 while (l) \
00870 { \
00871 lump_clone( (*a) , l , p ); \
00872 \
00873 lump_tmp = l->before; \
00874 lump_anchor2 = &((*a)->before); \
00875 while ( lump_tmp ) \
00876 { \
00877 lump_clone( (*lump_anchor2) , lump_tmp , p ); \
00878 lump_anchor2 = &((*lump_anchor2)->before); \
00879 lump_tmp = lump_tmp->before; \
00880 } \
00881 \
00882 lump_tmp = l->after; \
00883 lump_anchor2 = &((*a)->after); \
00884 while ( lump_tmp ) \
00885 { \
00886 lump_clone( (*lump_anchor2) , lump_tmp , p ); \
00887 lump_anchor2 = &((*lump_anchor2)->after); \
00888 lump_tmp = lump_tmp->after; \
00889 } \
00890 a = &((*a)->next); \
00891 l = l->next; \
00892 } \
00893 } while(0)
00894
00895 CLONE_LUMP_LIST(&(new_msg->add_rm), org_msg->add_rm);
00896 CLONE_LUMP_LIST(&(new_msg->body_lumps), org_msg->body_lumps);
00897
00898
00899 rpl_lump_anchor = &(new_msg->reply_lump);
00900 for(rpl_lump=org_msg->reply_lump;rpl_lump;rpl_lump=rpl_lump->next)
00901 {
00902 *(rpl_lump_anchor)=(struct lump_rpl*)p;
00903 p+=ROUND4(sizeof( struct lump_rpl ));
00904 (*rpl_lump_anchor)->flags = LUMP_RPL_SHMEM |
00905 (rpl_lump->flags&(~(LUMP_RPL_NODUP|LUMP_RPL_NOFREE)));
00906 (*rpl_lump_anchor)->text.len = rpl_lump->text.len;
00907 (*rpl_lump_anchor)->text.s=p;
00908 p+=ROUND4(rpl_lump->text.len);
00909 memcpy((*rpl_lump_anchor)->text.s,rpl_lump->text.s,rpl_lump->text.len);
00910 (*rpl_lump_anchor)->next=0;
00911 rpl_lump_anchor = &((*rpl_lump_anchor)->next);
00912 }
00913
00914 if (clone_authorized_hooks(new_msg, org_msg) < 0) {
00915 shm_free(new_msg);
00916 return 0;
00917 }
00918
00919 return new_msg;
00920 }
00921
00922
00923
00924
00925