Browse code

debugger: add a new dbg_sip_msg() config function

Added a config function which prints how the sip message would look like
if it were to be sent out at that point in config. Displays how the message
looks after apllying all the lumps; but it is just printing, not actual
lump application. Updated doku.

Stefan Mititelu authored on 10/06/2015 12:10:00
Showing 5 changed files
... ...
@@ -98,6 +98,9 @@
98 98
 #define L_INFO   	2
99 99
 #define L_DBG    	3
100 100
 #define L_MAX    	3
101
+#define L_OFFSET   42 /* needs to be added and then substracted
102
+                        because L_WARN may be confused with NULL pointer
103
+                        (e.g. fixup_dbg_sip_msg) */
101 104
 
102 105
 /** @brief This is the facility value used to indicate that the caller of the macro
103 106
  * did not override the facility. Value 0 (the defaul) is LOG_KERN on Linux
... ...
@@ -34,13 +34,14 @@
34 34
 #include "../../parser/parse_param.h"
35 35
 #include "../../shm_init.h"
36 36
 #include "../../script_cb.h"
37
+#include "../../msg_translator.h"
37 38
 
38 39
 #include "debugger_api.h"
39 40
 #include "debugger_config.h"
40 41
 
41 42
 MODULE_VERSION
42 43
 
43
-static int  mod_init(void);
44
+static int mod_init(void);
44 45
 static int child_init(int rank);
45 46
 static void mod_destroy(void);
46 47
 
... ...
@@ -52,6 +53,12 @@ static int dbg_mod_facility_param(modparam_t type, void *val);
52 52
 static int fixup_dbg_pv_dump(void** param, int param_no);
53 53
 static int w_dbg_dump(struct sip_msg* msg, char* mask, char* level);
54 54
 
55
+static struct action *dbg_fixup_get_action(void **param, int param_no);
56
+static int fixup_dbg_sip_msg(void** param, int param_no);
57
+static int w_dbg_sip_msg(struct sip_msg* msg, char *level, char *facility);
58
+
59
+extern char* dump_lump_list(struct lump *list, int s_offset, char *s_buf);
60
+
55 61
 /* parameters */
56 62
 extern int _dbg_cfgtrace;
57 63
 extern int _dbg_cfgpkgcheck;
... ...
@@ -64,6 +71,7 @@ extern int _dbg_step_usleep;
64 64
 extern int _dbg_step_loops;
65 65
 extern int _dbg_reset_msgid;
66 66
 
67
+static int _dbg_sip_msg_cline;
67 68
 static char * _dbg_cfgtrace_facility_str = 0;
68 69
 static int _dbg_log_assign = 0;
69 70
 
... ...
@@ -76,6 +84,12 @@ static cmd_export_t cmds[]={
76 76
 		fixup_dbg_pv_dump, 0, ANY_ROUTE},
77 77
 	{"dbg_pv_dump", (cmd_function)w_dbg_dump, 2,
78 78
 		fixup_dbg_pv_dump, 0, ANY_ROUTE},
79
+    {"dbg_sip_msg", (cmd_function)w_dbg_sip_msg, 0,
80
+        fixup_dbg_sip_msg, 0, REQUEST_ROUTE},
81
+    {"dbg_sip_msg", (cmd_function)w_dbg_sip_msg, 1,
82
+        fixup_dbg_sip_msg, 0, REQUEST_ROUTE},
83
+    {"dbg_sip_msg", (cmd_function)w_dbg_sip_msg, 2,
84
+        fixup_dbg_sip_msg, 0, REQUEST_ROUTE},
79 85
 	{0, 0, 0, 0, 0, 0}
80 86
 };
81 87
 
... ...
@@ -370,6 +384,161 @@ static int dbg_mod_facility_param(modparam_t type, void *val)
370 370
 		return -1;
371 371
 	}
372 372
 	return 0;
373
+}
373 374
 
375
+static int fixup_dbg_sip_msg(void** param, int param_no)
376
+{
377
+    int facility;
378
+    int level;
379
+    struct action *dbg_sip_msg_action;
380
+
381
+    switch(param_no)
382
+    {
383
+        case 2:
384
+            facility = str2facility((char*)*(param));
385
+            if (facility == -1) {
386
+                LM_ERR("invalid log facility configured");
387
+                return E_UNSPEC;
388
+            }
389
+
390
+                         *param = (void*)(long)facility;    
391
+        break;
392
+        case 1:
393
+            switch(((char*)(*param))[2])
394
+            {
395
+                /* add L_OFFSET because L_WARN is consdered null pointer */
396
+                case 'A': level = L_ALERT + L_OFFSET; break;
397
+                case 'B': level = L_BUG + L_OFFSET; break;
398
+                case 'C': level = L_CRIT2 + L_OFFSET; break;
399
+                case 'E': level = L_ERR + L_OFFSET; break;
400
+                case 'W': level = L_WARN + L_OFFSET; break;
401
+                case 'N': level = L_NOTICE + L_OFFSET; break;
402
+                case 'I': level = L_INFO + L_OFFSET; break;
403
+                case 'D': level = L_DBG + L_OFFSET; break;
404
+                default:
405
+                    LM_ERR("unknown log level\n");
406
+                    return E_UNSPEC;
407
+            }
408
+
409
+            *param = (void*)(long)level;
410
+        break;
411
+    }
412
+
413
+    /* save the config line where this config function was called */
414
+    dbg_sip_msg_action = dbg_fixup_get_action(param, param_no);
415
+    _dbg_sip_msg_cline = dbg_sip_msg_action->cline;
416
+
417
+     return 0;
374 418
 }
375 419
 
420
+/**
421
+  * dump current SIP message and a diff lump list
422
+  * part of the code taken from msg_apply_changes_f
423
+  */
424
+static int w_dbg_sip_msg(struct sip_msg* msg, char *level, char *facility)
425
+{
426
+    int ilevel = cfg_get(core, core_cfg, debug);
427
+    int ifacility= cfg_get(core, core_cfg, log_facility);
428
+    int flag = FLAG_MSG_LUMPS_ONLY; // copy lumps only, not the whole message
429
+    unsigned int new_buf_offs=0, orig_offs = 0;
430
+    char *hdr_lumps = NULL;
431
+    char *bdy_lumps = NULL;
432
+    const char *start_txt = "------------------------- START OF SIP message debug --------------------------\n";
433
+    const char *hdr_txt =   "------------------------------ SIP header diffs -------------------------------\n";
434
+    const char *bdy_txt =   "------------------------------- SIP body diffs --------------------------------\n";
435
+    const char *end_txt =   "-------------------------- END OF SIP message debug ---------------------------\n\n";
436
+    struct dest_info send_info;
437
+    str obuf;
438
+
439
+    if (level != NULL) {
440
+        /* substract L_OFFSET previously added */
441
+        ilevel = (int)(long)level - L_OFFSET;
442
+    }
443
+
444
+    if (facility != NULL) {
445
+        ifacility = (int)(long)facility;
446
+    }
447
+
448
+    /* msg_apply_changes_f code needed to get the current msg */
449
+    init_dest_info(&send_info);
450
+    send_info.proto = PROTO_UDP;
451
+    if(msg->first_line.type == SIP_REPLY) {
452
+        obuf.s = generate_res_buf_from_sip_res(msg,
453
+                (unsigned int*)&obuf.len, BUILD_NO_VIA1_UPDATE);
454
+    } else {
455
+        obuf.s = build_req_buf_from_sip_req(msg,
456
+                (unsigned int*)&obuf.len, &send_info,
457
+                BUILD_NO_PATH|BUILD_NO_LOCAL_VIA|BUILD_NO_VIA1_UPDATE);
458
+    }
459
+
460
+    if(obuf.s == NULL)
461
+    {
462
+        LM_ERR("couldn't update msg buffer content\n");
463
+        return -1;
464
+    }
465
+
466
+    if(obuf.len >= BUF_SIZE)
467
+    {
468
+        LM_ERR("new buffer overflow (%d)\n", obuf.len);
469
+        pkg_free(obuf.s);
470
+        return -1;
471
+    }
472
+
473
+    /* skip original uri */
474
+    if (msg->new_uri.s){
475
+        orig_offs=msg->first_line.u.request.uri.s - msg->buf;
476
+        orig_offs=msg->first_line.u.request.uri.len;
477
+    }
478
+
479
+    /* alloc private mem and copy lumps */
480
+    hdr_lumps = pkg_malloc(BUF_SIZE);
481
+    bdy_lumps = pkg_malloc(BUF_SIZE);
482
+
483
+    new_buf_offs = 0;
484
+    process_lumps(msg, msg->add_rm, hdr_lumps, &new_buf_offs, &orig_offs, &send_info, flag);
485
+
486
+    new_buf_offs = 0;
487
+    process_lumps(msg, msg->body_lumps, bdy_lumps, &new_buf_offs, &orig_offs, &send_info, flag);
488
+
489
+    /* do the print */
490
+    if (hdr_lumps != NULL && bdy_lumps != NULL) {
491
+        LOG_FC(ifacility, ilevel, "CONFIG LINE %d\n%s%.*s%s%s%s%s%s",
492
+            _dbg_sip_msg_cline,
493
+            start_txt,
494
+            obuf.len, obuf.s,
495
+            hdr_txt, hdr_lumps,
496
+            bdy_txt, bdy_lumps,
497
+            end_txt);
498
+    } else if (hdr_lumps != NULL) {
499
+        LOG_FC(ifacility, ilevel, "CONFIG LINE %d\n%s%.*s%s%s%s",
500
+            _dbg_sip_msg_cline,
501
+            start_txt,
502
+            obuf.len, obuf.s,
503
+            hdr_txt, hdr_lumps,
504
+            end_txt);
505
+    } else if (bdy_lumps != NULL) {
506
+        LOG_FC(ifacility, ilevel, "CONFIG LINE %d\n%s%.*s%s%s%s",
507
+            _dbg_sip_msg_cline,
508
+            start_txt,
509
+            obuf.len, obuf.s,
510
+            bdy_txt, bdy_lumps,
511
+            end_txt);
512
+    } else {
513
+        LOG_FC(ifacility, ilevel, "CONFIG LINE %d\n%s%.*s%s",
514
+            _dbg_sip_msg_cline,
515
+            start_txt,
516
+            obuf.len, obuf.s,
517
+            end_txt);
518
+    }
519
+
520
+    /* free lumps */
521
+    if (hdr_lumps) {
522
+        pkg_free(hdr_lumps);
523
+    }
524
+
525
+    if (bdy_lumps) {
526
+        pkg_free(bdy_lumps);
527
+    }
528
+
529
+    return 1;
530
+}
... ...
@@ -531,8 +531,69 @@ dbg_pv_dump(30, "L_DBG");
531 531
 	    </example>
532 532
 	</section>
533 533
 
534
+ 	<section id="dbg.f.dbg_sip_msg">
535
+	    <title>
536
+		<function moreinfo="none">dbg_sip_msg([log_level], [facility])</function>
537
+	    </title>
538
+	    <para>
539
+            Prints how the sip message <emphasis>would look</emphasis> like if it <emphasis>would be sent</emphasis> out
540
+            at that point in the config(i.e. if the current lump lists would
541
+            have been applied at that point in the config).
542
+
543
+            It also prints a diff list for both header and body of sip msg
544
+            which contain the lump lists content. The lumps deleted are printed
545
+            with "-" sign whereas the lumps added have no sign. The config line
546
+            where the function has been called is also printed.
547
+	    </para>
548
+	    <para>
549
+            NOTE that dbg_sip_msg function does not modify the initially received SIP message.
550
+            Just displays how it WOULD look like if it were to send it at that point.
551
+	    </para>
552
+		<para>
553
+			NOTE that the lump lists are usually applied only once, just before sending, to spare message reparse processing.
554
+            All the changes present in lump list are applied on the <emphasis>initially received</emphasis> SIP message.
555
+            One can force the lump application using msg_apply_changes() function from textopsx module.
556
+	    </para>
557
+		<para>
558
+	    </para>
559
+		<example>
560
+		<title><function>dbg_sip_msg</function> usage</title>
561
+		<programlisting format="linespecific">
562
+...
563
+    dbg_sip_msg();
564
+    dbg_sip_msg("L_ERR");
565
+    dbg_sip_msg("L_ERR", "LOG_LOCAL0");
566
+...
567
+        </programlisting>
568
+
569
+		<para>Output when dbg_sip_msg("L_ERR") is called after <emphasis>append_hf("P-Hint: My hint\r\n"); remove_hf("Contact");</emphasis></para>
570
+		<programlisting format="linespecific">
571
+ERROR: debugger [debugger_mod.c:467]: w_dbg_sip_msg(): CONFIG LINE 338
572
+------------------------- START OF SIP message debug --------------------------
573
+OPTIONS sip:nobody@127.0.0.1 SIP/2.0
574
+Via: SIP/2.0/UDP 127.0.1.1:56872;branch=z9hG4bK.6d7c487a;rport;alias
575
+From: sip:sipsak@127.0.1.1:56872;tag=188b7433
576
+To: sip:nobody@127.0.0.1
577
+Call-ID: 411792435@127.0.1.1
578
+CSeq: 1 OPTIONS
579
+Content-Length: 0
580
+Max-Forwards: 70
581
+User-Agent: sipsak 0.9.6
582
+Accept: text/plain
583
+P-Hint: My hintt
584
+
585
+------------------------------ SIP header diffs -------------------------------
586
+- Contact: sip:sipsak@127.0.1.1:56872
587
+P-Hint: My hint
588
+------------------------------- SIP body diffs --------------------------------
589
+-------------------------- END OF SIP message debug ---------------------------
590
+        </programlisting>
591
+	    </example>
592
+    </section>
593
+
534 594
     </section>
535
-	
595
+
596
+
536 597
 	<section>
537 598
 		<title>Exported RPC Functions</title>
538 599
 
... ...
@@ -890,12 +890,13 @@ skip_after:
890 890
 /* another helper functions, adds/Removes the lump,
891 891
 	code moved form build_req_from_req  */
892 892
 
893
-static inline void process_lumps(	struct sip_msg* msg,
894
-					                                struct lump* lumps,
895
-									char* new_buf,
896
-									unsigned int* new_buf_offs,
897
-									unsigned int* orig_offs,
898
-									struct dest_info* send_info)
893
+void process_lumps( struct sip_msg* msg,
894
+                    struct lump* lumps,
895
+                    char* new_buf,
896
+                    unsigned int* new_buf_offs,
897
+                    unsigned int* orig_offs,
898
+                    struct dest_info* send_info,
899
+                    int flag)
899 900
 {
900 901
 	struct lump *t;
901 902
 	struct lump *r;
... ...
@@ -1356,11 +1357,21 @@ skip_after:
1356 1356
 					break;
1357 1357
 				}
1358 1358
 				size=t->u.offset-s_offset;
1359
-				if (size){
1359
+                if (size > 0 && flag == FLAG_MSG_ALL){
1360 1360
 					memcpy(new_buf+offset, orig+s_offset,size);
1361 1361
 					offset+=size;
1362 1362
 					s_offset+=size;
1363
-				}
1363
+                } else if (flag == FLAG_MSG_LUMPS_ONLY) {
1364
+                    /* do not copy the whole message, jump to the lumps offs */
1365
+                    s_offset+=size;
1366
+                }
1367
+
1368
+                /* the LUMP_DELs are printed with "- " before them */
1369
+                if (t->op==LUMP_DEL && flag == FLAG_MSG_LUMPS_ONLY) {
1370
+                    new_buf[offset++] = '-';
1371
+                    new_buf[offset++] = ' ';
1372
+                }
1373
+
1364 1374
 				/* process before  */
1365 1375
 				for(r=t->before;r;r=r->before){
1366 1376
 					switch (r->op){
... ...
@@ -1384,11 +1395,22 @@ skip_after:
1384 1384
 					}
1385 1385
 				}
1386 1386
 skip_nop_before:
1387
-				/* process main (del only) */
1388
-				if (t->op==LUMP_DEL){
1389
-					/* skip len bytes from orig msg */
1390
-					s_offset+=t->len;
1391
-				}
1387
+                /* process main (del only) */
1388
+                if (t->op==LUMP_DEL && flag == FLAG_MSG_ALL){
1389
+                    /* skip len bytes from orig msg */
1390
+                    s_offset+=t->len;
1391
+                } else if (t->op==LUMP_DEL && flag == FLAG_MSG_LUMPS_ONLY) {
1392
+                    /* copy lump value and indent as necessarely */
1393
+                    memcpy(new_buf+offset, orig + t->u.offset, t->len);
1394
+                    offset+=t->len;
1395
+                    if (new_buf[offset-1] != '\n') {
1396
+                        new_buf[offset] = '\n';
1397
+                        offset+=1;
1398
+                    }
1399
+                    /* skip len bytes from orig msg */
1400
+                    s_offset+=t->len;
1401
+                 }
1402
+
1392 1403
 				/* process after */
1393 1404
 				for(r=t->after;r;r=r->after){
1394 1405
 					switch (r->op){
... ...
@@ -1419,6 +1441,11 @@ skip_nop_after:
1419 1419
 	}
1420 1420
 	*new_buf_offs=offset;
1421 1421
 	*orig_offs=s_offset;
1422
+
1423
+    /* add '\0' to char* lump list to print it smoothly */
1424
+    if (flag == FLAG_MSG_LUMPS_ONLY) {
1425
+        new_buf[offset] = '\0';
1426
+    }
1422 1427
 #undef RCVCOMP_PARAM_ADD 
1423 1428
 #undef SENDCOMP_PARAM_ADD
1424 1429
 }
... ...
@@ -2142,8 +2169,8 @@ after_update_via1:
2142 2142
 	}
2143 2143
 	new_buf[new_len]=0;
2144 2144
 	/* copy msg adding/removing lumps */
2145
-	process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, send_info);
2146
-	process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset,send_info);
2145
+	process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, send_info, FLAG_MSG_ALL);
2146
+	process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset,send_info, FLAG_MSG_ALL);
2147 2147
 	/* copy the rest of the message */
2148 2148
 	memcpy(new_buf+offset, buf+s_offset, len-s_offset);
2149 2149
 	new_buf[new_len]=0;
... ...
@@ -2236,8 +2263,8 @@ char * generate_res_buf_from_sip_res( struct sip_msg* msg,
2236 2236
 	new_buf[new_len]=0; /* debug: print the message */
2237 2237
 	offset=s_offset=0;
2238 2238
 	/*FIXME: no send sock*/
2239
-	process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, 0);/*FIXME:*/
2240
-	process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset, 0);
2239
+	process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, 0, FLAG_MSG_ALL);/*FIXME:*/
2240
+	process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset, 0, FLAG_MSG_ALL);
2241 2241
 	/* copy the rest of the message */
2242 2242
 	memcpy(new_buf+offset,
2243 2243
 		buf+s_offset,
... ...
@@ -2916,7 +2943,7 @@ char * build_only_headers( struct sip_msg* msg, int skip_first_line,
2916 2916
 	offset = 0;
2917 2917
 
2918 2918
 	/* copy message lumps */
2919
-	process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, send_info);
2919
+	process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, send_info, FLAG_MSG_ALL);
2920 2920
 	/* copy the rest of the message without body */
2921 2921
 	if (len > s_offset) {
2922 2922
 		memcpy(new_buf+offset, buf+s_offset, len-s_offset);
... ...
@@ -2966,7 +2993,7 @@ char * build_body( struct sip_msg* msg,
2966 2966
 	offset = 0;
2967 2967
 
2968 2968
 	/* copy body lumps */
2969
-	process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset, send_info);
2969
+	process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset, send_info, FLAG_MSG_ALL);
2970 2970
 	/* copy the rest of the message without body */
2971 2971
 	if (len > s_offset) {
2972 2972
 		memcpy(new_buf+offset, buf+s_offset, len-s_offset);
... ...
@@ -3026,9 +3053,9 @@ char * build_all( struct sip_msg* msg, int touch_clen,
3026 3026
 	offset = s_offset = 0;
3027 3027
 
3028 3028
 	/* copy message lumps */
3029
-	process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, send_info);
3029
+	process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, send_info, FLAG_MSG_ALL);
3030 3030
 	/* copy body lumps */
3031
-	process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset, send_info);
3031
+	process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset, send_info, FLAG_MSG_ALL);
3032 3032
 	/* copy the rest of the message */
3033 3033
 	memcpy(new_buf+offset, buf+s_offset, len-s_offset);
3034 3034
 	offset += (len-s_offset);
... ...
@@ -31,6 +31,10 @@
31 31
 #ifndef  _MSG_TRANSLATOR_H
32 32
 #define _MSG_TRANSLATOR_H
33 33
 
34
+/* flags used for process_lumps flag parameter */
35
+#define FLAG_MSG_LUMPS_ONLY     0   /* copy just the lumps */
36
+#define FLAG_MSG_ALL            1   /* copy all the msg */
37
+
34 38
 #define MY_HF_SEP ": "
35 39
 #define MY_HF_SEP_LEN 2
36 40
 
... ...
@@ -163,4 +167,17 @@ int build_sip_msg_from_buf(struct sip_msg *msg, char *buf, int len,
163 163
 
164 164
 /* returns a copy in private memory of the boundary in a multipart body */
165 165
 int get_boundary(struct sip_msg* msg, str* boundary);
166
+
167
+
168
+/* process the lumps of a sip msg
169
+ * flags =  => add also the existing header to new_buf
170
+ * flags =  => add only the lumps (unapplied info) to new_buf
171
+ **/
172
+void process_lumps( struct sip_msg* msg,
173
+                    struct lump* lumps,
174
+                    char* new_buf,
175
+                    unsigned int* new_buf_offs,
176
+                    unsigned int* orig_offs,
177
+                    struct dest_info* send_info,
178
+                    int flag);
166 179
 #endif