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