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 #include "data_lump.h"
00041 #include "dprint.h"
00042 #include "mem/mem.h"
00043 #include "globals.h"
00044 #include "error.h"
00045
00046 #include <stdlib.h>
00047 #include <string.h>
00048
00049 #ifdef DEBUG_DMALLOC
00050 #include <dmalloc.h>
00051 #endif
00052
00053
00054
00055
00056 enum lump_dir { LD_NEXT, LD_BEFORE, LD_AFTER };
00057
00058 int init_lump_flags = 0;
00059
00060
00061
00062 struct lump* append_new_lump(struct lump** list, char* new_hdr,
00063 unsigned int len, enum _hdr_types_t type)
00064 {
00065 struct lump** t;
00066 struct lump* tmp;
00067
00068 for (t=list;*t;t=&((*t)->next));
00069
00070 tmp=pkg_malloc(sizeof(struct lump));
00071 if (tmp==0){
00072 LM_ERR("out of pkg memory\n");
00073 return 0;
00074 }
00075
00076 memset(tmp,0,sizeof(struct lump));
00077 tmp->type=type;
00078 tmp->flags=init_lump_flags;
00079 tmp->op=LUMP_ADD;
00080 tmp->u.value=new_hdr;
00081 tmp->len=len;
00082 *t=tmp;
00083 return tmp;
00084 }
00085
00086
00087
00088
00089
00090 struct lump* insert_new_lump(struct lump** list, char* new_hdr,
00091 unsigned int len, enum _hdr_types_t type)
00092 {
00093 struct lump* tmp;
00094
00095 tmp=pkg_malloc(sizeof(struct lump));
00096 if (tmp==0){
00097 LM_ERR("out of pkg memory\n");
00098 return 0;
00099 }
00100 memset(tmp,0,sizeof(struct lump));
00101 tmp->next=*list;
00102 tmp->type=type;
00103 tmp->flags=init_lump_flags;
00104 tmp->op=LUMP_ADD;
00105 tmp->u.value=new_hdr;
00106 tmp->len=len;
00107 *list=tmp;
00108 return tmp;
00109 }
00110
00111
00112
00113
00114
00115 struct lump* insert_new_lump_after( struct lump* after, char* new_hdr,
00116 unsigned int len, enum _hdr_types_t type)
00117 {
00118 struct lump* tmp;
00119
00120 tmp=pkg_malloc(sizeof(struct lump));
00121 if (tmp==0){
00122 ser_error=E_OUT_OF_MEM;
00123 LM_ERR("out of pkg memory\n");
00124 return 0;
00125 }
00126 memset(tmp,0,sizeof(struct lump));
00127 tmp->after=after->after;
00128 tmp->type=type;
00129 tmp->flags=init_lump_flags;
00130 tmp->op=LUMP_ADD;
00131 tmp->u.value=new_hdr;
00132 tmp->len=len;
00133 after->after=tmp;
00134 return tmp;
00135 }
00136
00137
00138
00139
00140
00141 struct lump* insert_new_lump_before( struct lump* before, char* new_hdr,
00142 unsigned int len, enum _hdr_types_t type)
00143 {
00144 struct lump* tmp;
00145
00146 tmp=pkg_malloc(sizeof(struct lump));
00147 if (tmp==0){
00148 ser_error=E_OUT_OF_MEM;
00149 LM_ERR("out of pkg memory\n");
00150 return 0;
00151 }
00152 memset(tmp,0,sizeof(struct lump));
00153 tmp->before=before->before;
00154 tmp->type=type;
00155 tmp->flags=init_lump_flags;
00156 tmp->op=LUMP_ADD;
00157 tmp->u.value=new_hdr;
00158 tmp->len=len;
00159 before->before=tmp;
00160 return tmp;
00161 }
00162
00163
00164
00165
00166
00167 struct lump* insert_subst_lump_after( struct lump* after,enum lump_subst subst,
00168 enum _hdr_types_t type)
00169 {
00170 struct lump* tmp;
00171
00172 tmp=pkg_malloc(sizeof(struct lump));
00173 if (tmp==0){
00174 ser_error=E_OUT_OF_MEM;
00175 LM_ERR("out of pkg memory\n");
00176 return 0;
00177 }
00178 memset(tmp,0,sizeof(struct lump));
00179 tmp->after=after->after;
00180 tmp->type=type;
00181 tmp->flags=init_lump_flags;
00182 tmp->op=LUMP_ADD_SUBST;
00183 tmp->u.subst=subst;
00184 tmp->len=0;
00185 after->after=tmp;
00186 return tmp;
00187 }
00188
00189
00190
00191
00192
00193 struct lump* insert_subst_lump_before( struct lump* before,
00194 enum lump_subst subst,
00195 enum _hdr_types_t type)
00196 {
00197 struct lump* tmp;
00198
00199 tmp=pkg_malloc(sizeof(struct lump));
00200 if (tmp==0){
00201 ser_error=E_OUT_OF_MEM;
00202 LM_ERR("out of pkg memory\n");
00203 return 0;
00204 }
00205 memset(tmp,0,sizeof(struct lump));
00206 tmp->before=before->before;
00207 tmp->type=type;
00208 tmp->flags=init_lump_flags;
00209 tmp->op=LUMP_ADD_SUBST;
00210 tmp->u.subst=subst;
00211 tmp->len=0;
00212 before->before=tmp;
00213 return tmp;
00214 }
00215
00216
00217
00218
00219
00220 struct lump* insert_cond_lump_after( struct lump* after,enum lump_conditions c,
00221 enum _hdr_types_t type)
00222 {
00223 struct lump* tmp;
00224
00225 tmp=pkg_malloc(sizeof(struct lump));
00226 if (tmp==0){
00227 ser_error=E_OUT_OF_MEM;
00228 LM_ERR("out of pkg memory\n");
00229 return 0;
00230 }
00231 memset(tmp,0,sizeof(struct lump));
00232 tmp->after=after->after;
00233 tmp->type=type;
00234 tmp->flags=init_lump_flags;
00235 tmp->op=LUMP_ADD_OPT;
00236 tmp->u.cond=c;
00237 tmp->len=0;
00238 after->after=tmp;
00239 return tmp;
00240 }
00241
00242
00243
00244
00245
00246 struct lump* insert_cond_lump_before( struct lump* before,
00247 enum lump_conditions c,
00248 enum _hdr_types_t type)
00249 {
00250 struct lump* tmp;
00251
00252 tmp=pkg_malloc(sizeof(struct lump));
00253 if (tmp==0){
00254 ser_error=E_OUT_OF_MEM;
00255 LM_ERR("out of pkg memory\n");
00256 return 0;
00257 }
00258 memset(tmp,0,sizeof(struct lump));
00259 tmp->before=before->before;
00260 tmp->type=type;
00261 tmp->flags=init_lump_flags;
00262 tmp->op=LUMP_ADD_OPT;
00263 tmp->u.cond=c;
00264 tmp->len=0;
00265 before->before=tmp;
00266 return tmp;
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276 struct lump* del_lump(struct sip_msg* msg, unsigned int offset,
00277 unsigned int len, enum _hdr_types_t type)
00278 {
00279 struct lump* tmp;
00280 struct lump* prev, *t;
00281 struct lump** list;
00282
00283
00284 if (offset>msg->len){
00285 LM_CRIT("offset exceeds message size (%d > %d)"
00286 " aborting...\n", offset, msg->len);
00287 abort();
00288 }
00289 if (offset+len>msg->len){
00290 LM_CRIT("offset + len exceeds message"
00291 " size (%d + %d > %d)\n", offset, len, msg->len);
00292 abort();
00293 }
00294 if (len==0){
00295 LM_WARN("called with 0 len (offset =%d)\n", offset);
00296 }
00297
00298 tmp=pkg_malloc(sizeof(struct lump));
00299 if (tmp==0){
00300 LM_ERR("out of pkg memory\n");
00301 return 0;
00302 }
00303 memset(tmp,0,sizeof(struct lump));
00304 tmp->op=LUMP_DEL;
00305 tmp->type=type;
00306 tmp->flags=init_lump_flags;
00307 tmp->u.offset=offset;
00308 tmp->len=len;
00309 prev=0;
00310
00311 if ((msg->eoh) && (offset>(unsigned long)(msg->eoh-msg->buf)))
00312 list=&msg->body_lumps;
00313 else
00314 list=&msg->add_rm;
00315 for (t=*list;t; prev=t, t=t->next){
00316
00317 if (((t->op==LUMP_DEL)||(t->op==LUMP_NOP))&&(t->u.offset>offset))
00318 break;
00319 }
00320 tmp->next=t;
00321 if (prev) prev->next=tmp;
00322 else *list=tmp;
00323 return tmp;
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333 struct lump* anchor_lump(struct sip_msg* msg, unsigned int offset,
00334 int unsigned len, enum _hdr_types_t type)
00335 {
00336 struct lump* tmp;
00337 struct lump* prev, *t;
00338 struct lump** list;
00339
00340
00341
00342 if (offset>msg->len){
00343 LM_ERR("offset exceeds message size (%d > %d)...\n",
00344 offset, msg->len);
00345 return 0;
00346 }
00347 if (len){
00348 LM_WARN("called with len !=0 (%d)\n", len);
00349 if (offset+len>msg->len)
00350 LM_WARN("offset + len exceeds message"
00351 " size (%d + %d > %d)\n", offset, len, msg->len);
00352 }
00353
00354 tmp=pkg_malloc(sizeof(struct lump));
00355 if (tmp==0){
00356 ser_error=E_OUT_OF_MEM;
00357 LM_ERR("out of pkg memory\n");
00358 return 0;
00359 }
00360 memset(tmp,0,sizeof(struct lump));
00361 tmp->op=LUMP_NOP;
00362 tmp->type=type;
00363 tmp->flags=init_lump_flags;
00364 tmp->u.offset=offset;
00365 tmp->len=len;
00366 prev=0;
00367
00368 if ((msg->eoh) && (offset> (unsigned long)(msg->eoh-msg->buf)))
00369 list=&msg->body_lumps;
00370 else
00371 list=&msg->add_rm;
00372
00373 for (t=*list;t; prev=t, t=t->next){
00374
00375 if (((t->op==LUMP_DEL)||(t->op==LUMP_NOP))&&(t->u.offset>offset))
00376 break;
00377 }
00378 tmp->next=t;
00379
00380 if (prev) prev->next=tmp;
00381 else *list=tmp;
00382 return tmp;
00383 }
00384
00385
00386
00387 void free_lump(struct lump* lmp)
00388 {
00389 if (lmp && (lmp->op==LUMP_ADD)){
00390 if (lmp->u.value){
00391 if (lmp->flags &(LUMPFLAG_DUPED|LUMPFLAG_SHMEM)){
00392 LM_CRIT("called on a not free-able lump:"
00393 "%p flags=%x\n", lmp, lmp->flags);
00394 abort();
00395 }else{
00396 pkg_free(lmp->u.value);
00397 lmp->u.value=0;
00398 lmp->len=0;
00399 }
00400 }
00401 }
00402 }
00403
00404
00405
00406 void free_lump_list(struct lump* l)
00407 {
00408 struct lump* t, *r, *foo,*crt;
00409 t=l;
00410 while(t){
00411 crt=t;
00412 t=t->next;
00413
00414 r=crt->before;
00415 while(r){
00416 foo=r; r=r->before;
00417 free_lump(foo);
00418 pkg_free(foo);
00419 }
00420 r=crt->after;
00421 while(r){
00422 foo=r; r=r->after;
00423 free_lump(foo);
00424 pkg_free(foo);
00425 }
00426
00427
00428 free_lump(crt);
00429 pkg_free(crt);
00430 }
00431 }
00432
00433
00434 static void free_shallow_lump( struct lump *l )
00435 {
00436 struct lump *r, *foo;
00437
00438 r=l->before;
00439 while(r){
00440 foo=r; r=r->before;
00441 pkg_free(foo);
00442 }
00443 r=l->after;
00444 while(r){
00445 foo=r; r=r->after;
00446 pkg_free(foo);
00447 }
00448 pkg_free(l);
00449 }
00450
00451
00452 static struct lump *dup_lump_list_r( struct lump *l,
00453 enum lump_dir dir, int *error)
00454 {
00455 int deep_error;
00456 struct lump *new_lump;
00457
00458 deep_error=0;
00459
00460 if (!l) { *error=0; return 0; }
00461
00462 new_lump=pkg_malloc(sizeof(struct lump));
00463 if (!new_lump) { *error=1; return 0; }
00464
00465 memcpy(new_lump, l, sizeof(struct lump));
00466 new_lump->flags=init_lump_flags|LUMPFLAG_DUPED;
00467 new_lump->next=new_lump->before=new_lump->after=0;
00468
00469 switch(dir) {
00470 case LD_NEXT:
00471 new_lump->before=dup_lump_list_r(l->before,
00472 LD_BEFORE, &deep_error);
00473 if (deep_error) goto deeperror;
00474 new_lump->after=dup_lump_list_r(l->after,
00475 LD_AFTER, &deep_error);
00476 if (deep_error) goto deeperror;
00477 new_lump->next=dup_lump_list_r(l->next,
00478 LD_NEXT, &deep_error);
00479 break;
00480 case LD_BEFORE:
00481 new_lump->before=dup_lump_list_r(l->before,
00482 LD_BEFORE, &deep_error);
00483 break;
00484 case LD_AFTER:
00485 new_lump->after=dup_lump_list_r(l->after,
00486 LD_AFTER, &deep_error);
00487 break;
00488 default:
00489 LM_CRIT("unknown dir: %d\n", dir );
00490 deep_error=1;
00491 }
00492 if (deep_error) goto deeperror;
00493
00494 *error=0;
00495 return new_lump;
00496
00497 deeperror:
00498 LM_ERR("out of pkg mem\n");
00499 free_shallow_lump(new_lump);
00500 *error=1;
00501 return 0;
00502 }
00503
00504
00505
00506
00507
00508
00509
00510
00511 struct lump* dup_lump_list( struct lump *l )
00512 {
00513 int deep_error;
00514
00515 deep_error=0;
00516 return dup_lump_list_r(l, LD_NEXT, &deep_error);
00517 }
00518
00519
00520
00521
00522
00523 void free_duped_lump_list(struct lump* l)
00524 {
00525 struct lump *r, *foo,*crt;
00526 while(l){
00527 crt=l;
00528 l=l->next;
00529
00530 r=crt->before;
00531 while(r){
00532 foo=r; r=r->before;
00533
00534
00535
00536
00537 if (foo->flags!=LUMPFLAG_DUPED)
00538 free_lump(foo);
00539 pkg_free(foo);
00540 }
00541 r=crt->after;
00542 while(r){
00543 foo=r; r=r->after;
00544 if (foo->flags!=LUMPFLAG_DUPED)
00545 free_lump(foo);
00546 pkg_free(foo);
00547 }
00548
00549
00550 if (crt->flags!=LUMPFLAG_DUPED)
00551 free_lump(crt);
00552 pkg_free(crt);
00553 }
00554 }
00555
00556
00557 static inline int compare_flaged_lumps(const enum lump_flag flag1, const enum lump_flag flag2)
00558 {
00559 return (flag1&flag2);
00560 }
00561
00562
00563 static inline int compare_not_flaged_lumps(const enum lump_flag flag1, const enum lump_flag flag2)
00564 {
00565 return ((~flag1)&flag2);
00566 }
00567
00568
00569
00570
00571
00572
00573
00574
00575 static void del_flaged_lumps_helper(struct lump** lump_list, const enum lump_flag flags,
00576 int (*compare_lump_flags) (const enum lump_flag flag1,
00577 const enum lump_flag flag2))
00578 {
00579 struct lump *r, *foo, *crt, **prev, *prev_r;
00580
00581 prev = lump_list;
00582 crt = *lump_list;
00583
00584 while (crt) {
00585 if (compare_lump_flags(crt->flags, flags)) {
00586
00587 foo = crt;
00588 crt = crt->next;
00589 foo->next = 0;
00590
00591 *prev = crt;
00592
00593 free_lump_list(foo);
00594 } else {
00595
00596 r = crt->after;
00597 prev_r = crt;
00598 while(r){
00599 foo=r; r=r->after;
00600 if (compare_lump_flags(foo->flags, flags)) {
00601 prev_r->after = r;
00602 free_lump(foo);
00603 pkg_free(foo);
00604 } else {
00605 prev_r = foo;
00606 }
00607 }
00608
00609 r = crt->before;
00610 prev_r = crt;
00611 while(r){
00612 foo=r; r=r->before;
00613 if (compare_lump_flags(foo->flags, flags)) {
00614 prev_r->before = r;
00615 free_lump(foo);
00616 pkg_free(foo);
00617 } else {
00618 prev_r = foo;
00619 }
00620 }
00621
00622 prev = &(crt->next);
00623 crt = crt->next;
00624 }
00625 }
00626 }
00627
00628
00629
00630
00631
00632
00633
00634
00635 void del_flaged_lumps(struct lump** lump_list, const enum lump_flag flags)
00636 {
00637 del_flaged_lumps_helper(lump_list, flags, compare_flaged_lumps);
00638 }
00639
00640
00641
00642
00643
00644
00645
00646 void del_notflaged_lumps(struct lump** lump_list, const enum lump_flag not_flags)
00647 {
00648 del_flaged_lumps_helper(lump_list, not_flags, compare_not_flaged_lumps);
00649 }