sms(k): delete after merge with the module from ser
[sip-router] / core_cmd.c
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2005 iptelorg GmbH
5  *
6  * This file is part of SIP-router, a free SIP server.
7  *
8  * SIP-router is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * SIP-router is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 /** core rpcs.
24  * @file core_cmd.c
25  * @ingroup core
26  */
27
28
29 #include <time.h>
30 #include <sys/types.h>
31 #include <signal.h>
32 #include "ver.h"
33 #include "mem/mem.h"
34 #include "mem/shm_mem.h"
35 #include "sr_module.h"
36 #include "rpc_lookup.h"
37 #include "dprint.h"
38 #include "core_cmd.h"
39 #include "globals.h"
40 #include "pt.h"
41 #include "ut.h"
42 #include "tcp_info.h"
43 #include "tcp_options.h"
44 #include "core_cmd.h"
45 #include "cfg_core.h"
46 #ifdef USE_SCTP
47 #include "sctp_options.h"
48 #include "sctp_server.h"
49 #endif
50
51 #ifdef USE_DNS_CACHE
52 void dns_cache_debug(rpc_t* rpc, void* ctx);
53 void dns_cache_debug_all(rpc_t* rpc, void* ctx);
54 void dns_cache_mem_info(rpc_t* rpc, void* ctx);
55 void dns_cache_view(rpc_t* rpc, void* ctx);
56 void dns_cache_rpc_lookup(rpc_t* rpc, void* ctx);
57 void dns_cache_delete_all(rpc_t* rpc, void* ctx);
58 void dns_cache_delete_all_force(rpc_t* rpc, void* ctx);
59 void dns_cache_add_a(rpc_t* rpc, void* ctx);
60 void dns_cache_add_aaaa(rpc_t* rpc, void* ctx);
61 void dns_cache_add_srv(rpc_t* rpc, void* ctx);
62 void dns_cache_delete_a(rpc_t* rpc, void* ctx);
63 void dns_cache_delete_aaaa(rpc_t* rpc, void* ctx);
64 void dns_cache_delete_srv(rpc_t* rpc, void* ctx);
65 void dns_cache_delete_naptr(rpc_t* rpc, void* ctx);
66 void dns_cache_delete_cname(rpc_t* rpc, void* ctx);
67 void dns_cache_delete_txt(rpc_t* rpc, void* ctx);
68 void dns_cache_delete_ebl(rpc_t* rpc, void* ctx);
69 void dns_cache_delete_ptr(rpc_t* rpc, void* ctx);
70
71
72 static const char* dns_cache_mem_info_doc[] = {
73         "dns cache memory info.",    /* Documentation string */
74         0                      /* Method signature(s) */
75 };
76 static const char* dns_cache_debug_doc[] = {
77         "dns debug  info.",    /* Documentation string */
78         0                      /* Method signature(s) */
79 };
80
81 static const char* dns_cache_debug_all_doc[] = {
82         "complete dns debug  dump",    /* Documentation string */
83         0                              /* Method signature(s) */
84 };
85
86 static const char* dns_cache_view_doc[] = {
87         "dns cache dump in a human-readable format",
88         0
89 };
90
91 static const char* dns_cache_rpc_lookup_doc[] = {
92         "perform a dns lookup",
93         0
94 };
95
96 static const char* dns_cache_delete_all_doc[] = {
97         "deletes all the non-permanent entries from the DNS cache",
98         0
99 };
100
101 static const char* dns_cache_delete_all_force_doc[] = {
102         "deletes all the entries from the DNS cache including the permanent ones",
103         0
104 };
105
106 static const char* dns_cache_add_a_doc[] = {
107         "adds an A record to the DNS cache",
108         0
109 };
110
111 static const char* dns_cache_add_aaaa_doc[] = {
112         "adds an AAAA record to the DNS cache",
113         0
114 };
115 static const char* dns_cache_add_srv_doc[] = {
116         "adds an SRV record to the DNS cache",
117         0
118 };
119
120 static const char* dns_cache_delete_a_doc[] = {
121         "deletes an A record from the DNS cache",
122         0
123 };
124
125 static const char* dns_cache_delete_aaaa_doc[] = {
126         "deletes an AAAA record from the DNS cache",
127         0
128 };
129
130 static const char* dns_cache_delete_srv_doc[] = {
131         "deletes an SRV record from the DNS cache",
132         0
133 };
134
135 static const char* dns_cache_delete_naptr_doc[] = {
136         "deletes a NAPTR record from the DNS cache",
137         0
138 };
139
140 static const char* dns_cache_delete_cname_doc[] = {
141         "deletes a CNAME record from the DNS cache",
142         0
143 };
144
145 static const char* dns_cache_delete_txt_doc[] = {
146         "deletes a TXT record from the DNS cache",
147         0
148 };
149
150 static const char* dns_cache_delete_ebl_doc[] = {
151         "deletes an EBL record from the DNS cache",
152         0
153 };
154
155
156 static const char* dns_cache_delete_ptr_doc[] = {
157         "deletes an PTR record from the DNS cache",
158         0
159 };
160
161
162 #ifdef USE_DNS_CACHE_STATS
163 void dns_cache_stats_get(rpc_t* rpc, void* ctx);
164
165 static const char* dns_cache_stats_get_doc[] = {
166         "returns the dns measurement counters.",
167         0
168 };
169 #endif /* USE_DNS_CACHE_STATS */
170 #ifdef DNS_WATCHDOG_SUPPORT
171 void dns_set_server_state_rpc(rpc_t* rpc, void* ctx);
172
173 static const char* dns_set_server_state_doc[] = {
174         "sets the state of the DNS servers " \
175         "(0: all the servers are down, 1: at least one server is up)",    /* Documentation string */
176         0                              /* Method signature(s) */
177 };
178
179 void dns_get_server_state_rpc(rpc_t* rpc, void* ctx);
180
181 static const char* dns_get_server_state_doc[] = {
182         "prints the state of the DNS servers " \
183         "(0: all the servers are down, 1: at least one server is up)",  /* Documentation string */
184         0                               /* Method signature(s) */
185 };
186
187 #endif /* DNS_WATCHDOG_SUPPORT */
188 #endif /* USE_DNS_CACHE */
189 #ifdef USE_DST_BLACKLIST
190 void dst_blst_debug(rpc_t* rpc, void* ctx);
191 void dst_blst_mem_info(rpc_t* rpc, void* ctx);
192 void dst_blst_view(rpc_t* rpc, void* ctx);
193 void dst_blst_delete_all(rpc_t* rpc, void* ctx);
194 void dst_blst_add(rpc_t* rpc, void* ctx);
195
196 static const char* dst_blst_mem_info_doc[] = {
197         "dst blacklist memory usage info.",  /* Documentation string */
198         0                                    /* Method signature(s) */
199 };
200 static const char* dst_blst_debug_doc[] = {
201         "dst blacklist  debug  info.",  /* Documentation string */
202         0                               /* Method signature(s) */
203 };
204 static const char* dst_blst_view_doc[] = {
205         "dst blacklist dump in human-readable format.",  /* Documentation string */
206         0                               /* Method signature(s) */
207 };
208 static const char* dst_blst_delete_all_doc[] = {
209         "Deletes all the entries from the dst blacklist except the permanent ones.",  /* Documentation string */
210         0                               /* Method signature(s) */
211 };
212 static const char* dst_blst_add_doc[] = {
213         "Adds a new entry to the dst blacklist.",  /* Documentation string */
214         0                               /* Method signature(s) */
215 };
216 #ifdef USE_DST_BLACKLIST_STATS
217 void dst_blst_stats_get(rpc_t* rpc, void* ctx);
218
219 static const char* dst_blst_stats_get_doc[] = {
220         "returns the dst blacklist measurement counters.",
221         0
222 };
223 #endif /* USE_DST_BLACKLIST_STATS */
224
225 #endif
226
227
228
229 #define MAX_CTIME_LEN 128
230
231 /* up time */
232 static char up_since_ctime[MAX_CTIME_LEN];
233
234
235 static const char* system_listMethods_doc[] = {
236         "Lists all RPC methods supported by the server.",  /* Documentation string */
237         0                                                  /* Method signature(s) */
238 };
239
240 static void system_listMethods(rpc_t* rpc, void* c)
241 {
242         int i;
243         
244         for(i=0; i<rpc_sarray_crt_size; i++){
245                 if (rpc->add(c, "s", rpc_sarray[i]->name) < 0) return;
246         }
247 }
248
249 static const char* system_methodSignature_doc[] = {
250         "Returns signature of given method.",  /* Documentation string */
251         0                                      /* Method signature(s) */
252 };
253
254 static void system_methodSignature(rpc_t* rpc, void* c)
255 {
256         rpc->fault(c, 500, "Not Implemented Yet");
257 }
258
259
260 static const char* system_methodHelp_doc[] = {
261         "Print the help string for given method.",  /* Documentation string */
262         0                                           /* Method signature(s) */
263 };
264
265 static void system_methodHelp(rpc_t* rpc, void* c)
266 {
267         rpc_export_t* r;
268         char* name;
269
270         if (rpc->scan(c, "s", &name) < 1) {
271                 rpc->fault(c, 400, "Method Name Expected");
272                 return;
273         }
274         
275         r=rpc_lookup(name, strlen(name));
276         if (r==0){
277                 rpc->fault(c, 400, "command not found");
278         }else{
279                 if (r->doc_str && r->doc_str[0]) {
280                         rpc->add(c, "s", r->doc_str[0]);
281                 } else {
282                         rpc->add(c, "s", "undocumented");
283                 }
284         }
285         return;
286 }
287
288
289 static const char* core_prints_doc[] = {
290         "Returns the strings given as parameters.",   /* Documentation string */
291         0                                             /* Method signature(s) */
292 };
293
294
295 static void core_prints(rpc_t* rpc, void* c)
296 {
297         char* string = 0;
298         while((rpc->scan(c, "*s", &string)>0))
299                 rpc->add(c, "s", string);
300 }
301
302
303 static const char* core_printi_doc[] = {
304         "Returns the integers given as parameters.",  /* Documentation string */
305         0                                             /* Method signature(s) */
306 };
307
308
309 static void core_printi(rpc_t* rpc, void* c)
310 {
311         int i;
312         while((rpc->scan(c, "*d", &i)>0))
313                 rpc->add(c, "d", i);
314 }
315
316
317 static const char* core_echo_doc[] = {
318         "Returns back its parameters.",              /* Documentation string */
319         0                                             /* Method signature(s) */
320 };
321
322
323 static void core_echo(rpc_t* rpc, void* c)
324 {
325         char* string = 0;
326         while((rpc->scan(c, "*.s", &string)>0))
327                 rpc->add(c, "s", string);
328 }
329
330
331 static const char* core_version_doc[] = {
332         "Returns the version string of the server.", /* Documentation string */
333         0                                           /* Method signature(s) */
334 };
335
336 static void core_version(rpc_t* rpc, void* c)
337 {
338         rpc->add(c, "s", full_version);
339 }
340
341
342
343 static const char* core_flags_doc[] = {
344         "Returns the compile flags.", /* Documentation string */
345         0                             /* Method signature(s) */
346 };
347
348 static void core_flags(rpc_t* rpc, void* c)
349 {
350         rpc->add(c, "s", ver_flags);
351 }
352
353
354
355 static const char* core_info_doc[] = {
356         "Verbose info, including version number, compile flags, compiler,"
357         "repository hash a.s.o.",     /* Documentation string */
358         0                             /* Method signature(s) */
359 };
360
361 static void core_info(rpc_t* rpc, void* c)
362 {
363         void* s;
364         
365         if (rpc->add(c, "{", &s) < 0) return;
366         rpc->struct_printf(s, "version", "%s %s", ver_name, ver_version);
367         rpc->struct_add(s, "s", "id", ver_id);
368         rpc->struct_add(s, "s", "compiler", ver_compiler);
369         rpc->struct_add(s, "s", "compiled", ver_compiled_time);
370         rpc->struct_add(s, "s", "flags", ver_flags);
371 }
372
373
374
375 static const char* core_uptime_doc[] = {
376         "Returns uptime of SER server.",  /* Documentation string */
377         0                                 /* Method signature(s) */
378 };
379
380
381 static void core_uptime(rpc_t* rpc, void* c)
382 {
383         void* s;
384         time_t now;
385
386         time(&now);
387
388         if (rpc->add(c, "{", &s) < 0) return;
389         rpc->struct_add(s, "s", "now", ctime(&now));
390         rpc->struct_add(s, "s", "up_since", up_since_ctime);
391         /* no need for a float here (unless you're concerned that your uptime)
392         rpc->struct_add(s, "f", "uptime",  difftime(now, up_since));
393         */
394         /* on posix system we can substract time_t directly */
395         rpc->struct_add(s, "d", "uptime",  (int)(now-up_since));
396 }
397
398
399 static const char* core_ps_doc[] = {
400         "Returns the description of running SER processes.",  /* Documentation string */
401         0                                                     /* Method signature(s) */
402 };
403
404
405 static void core_ps(rpc_t* rpc, void* c)
406 {
407         int p;
408
409         for (p=0; p<*process_count;p++) {
410                 rpc->add(c, "d", pt[p].pid);
411                 rpc->add(c, "s", pt[p].desc);
412         }
413 }
414
415
416 static const char* core_pwd_doc[] = {
417         "Returns the working directory of SER server.",    /* Documentation string */
418         0                                                  /* Method signature(s) */
419 };
420
421
422 static void core_pwd(rpc_t* rpc, void* c)
423 {
424         char *cwd_buf;
425         int max_len;
426
427         max_len = pathmax();
428         cwd_buf = pkg_malloc(max_len);
429         if (!cwd_buf) {
430                 ERR("core_pwd: No memory left\n");
431                 rpc->fault(c, 500, "Server Ran Out of Memory");
432                 return;
433         }
434
435         if (getcwd(cwd_buf, max_len)) {
436                 rpc->add(c, "s", cwd_buf);
437         } else {
438                 rpc->fault(c, 500, "getcwd Failed");
439         }
440         pkg_free(cwd_buf);
441 }
442
443
444 static const char* core_arg_doc[] = {
445         "Returns the list of command line arguments used on SER startup.",  /* Documentation string */
446         0                                                                   /* Method signature(s) */
447 };
448
449
450 static void core_arg(rpc_t* rpc, void* c)
451 {
452         int p;
453
454         for (p = 0; p < my_argc; p++) {
455                 if (rpc->add(c, "s", my_argv[p]) < 0) return;
456         }
457 }
458
459
460 static const char* core_kill_doc[] = {
461         "Sends the given signal to SER.",  /* Documentation string */
462         0                                  /* Method signature(s) */
463 };
464
465
466 static void core_kill(rpc_t* rpc, void* c)
467 {
468         int sig_no = 15;
469         rpc->scan(c, "d", &sig_no);
470         rpc->send(c);
471         kill(0, sig_no);
472 }
473
474 static void core_shmmem(rpc_t* rpc, void* c)
475 {
476         struct mem_info mi;
477         void *handle;
478         char* param;
479         long rs;
480
481         rs=0;
482         /* look for optional size/divisor parameter */
483         if (rpc->scan(c, "*s", &param)>0){
484                 switch(*param){
485                         case 'b':
486                         case 'B':
487                                 rs=0;
488                                 break;
489                         case 'k':
490                         case 'K':
491                                 rs=10; /* K -> 1024 */
492                                 break;
493                         case 'm':
494                         case 'M':
495                                 rs=20; /* M -> 1048576 */
496                                 break;
497                         case 'g':
498                         case 'G':
499                                 rs=30; /* G -> 1024M */
500                                 break;
501                         default:
502                                 rpc->fault(c, 500, "bad param, (use b|k|m|g)");
503                                 return;
504                 }
505                 if (param[1] && ((param[1]!='b' && param[1]!='B') || param[2])){
506                                 rpc->fault(c, 500, "bad param, (use b|k|m|g)");
507                                 return;
508                 }
509         }
510         shm_info(&mi);
511         rpc->add(c, "{", &handle);
512         rpc->struct_add(handle, "dddddd",
513                 "total", (unsigned int)(mi.total_size>>rs),
514                 "free", (unsigned int)(mi.free>>rs),
515                 "used", (unsigned int)(mi.used>>rs),
516                 "real_used",(unsigned int)(mi.real_used>>rs),
517                 "max_used", (unsigned int)(mi.max_used>>rs),
518                 "fragments", (unsigned int)mi.total_frags
519         );
520 }
521
522 static const char* core_shmmem_doc[] = {
523         "Returns shared memory info. It has an optional parameter that specifies"
524         " the measuring unit: b - bytes (default), k or kb, m or mb, g or gb. "
525         "Note: when using something different from bytes, the value is truncated.",
526         0                               /* Method signature(s) */
527 };
528
529
530 #if defined(SF_MALLOC) || defined(LL_MALLOC)
531 static void core_sfmalloc(rpc_t* rpc, void* c)
532 {
533         void *handle;
534         int i,r;
535         unsigned long frags, main_s_frags, main_b_frags, pool_frags;
536         unsigned long misses;
537         unsigned long max_misses;
538         unsigned long max_frags;
539         unsigned long max_mem;
540         int max_frags_pool, max_frags_hash;
541         int max_misses_pool, max_misses_hash;
542         int max_mem_pool, max_mem_hash;
543         unsigned long mem;
544
545         if (rpc->scan(c, "d", &r) >= 1) {
546                 if (r>=(int)SF_HASH_POOL_SIZE){
547                         rpc->fault(c, 500, "invalid hash number %d (max %d)",
548                                                                 r, (unsigned int)SF_HASH_POOL_SIZE-1);
549                         return;
550                 }else if (r<0) goto all;
551                 rpc->add(c, "{", &handle);
552                 rpc->struct_add(handle, "dd",
553                                 "hash  ", r,
554                                 "size  ", r*SF_ROUNDTO);
555                 for (i=0; i<SFM_POOLS_NO; i++){
556                         rpc->struct_add(handle, "dddd",
557                                 "pool  ", i,
558                                 "frags ", (unsigned int)shm_block->pool[i].pool_hash[r].no,
559                                 "misses", (unsigned int)shm_block->pool[i].pool_hash[r].misses,
560                                 "mem   ",   (unsigned int)shm_block->pool[i].pool_hash[r].no *
561                                                         r*SF_ROUNDTO
562                         );
563                 }
564         }
565         return;
566 all:
567         max_frags=max_misses=max_mem=0;
568         max_frags_pool=max_frags_hash=0;
569         max_misses_pool=max_misses_hash=0;
570         max_mem_pool=max_mem_hash=0;
571         pool_frags=0;
572         for (i=0; i<SFM_POOLS_NO; i++){
573                 frags=0;
574                 misses=0;
575                 mem=0;
576                 for (r=0; r<SF_HASH_POOL_SIZE; r++){
577                         frags+=shm_block->pool[i].pool_hash[r].no;
578                         misses+=shm_block->pool[i].pool_hash[r].misses;
579                         mem+=shm_block->pool[i].pool_hash[r].no*r*SF_ROUNDTO;
580                         if (shm_block->pool[i].pool_hash[r].no>max_frags){
581                                 max_frags=shm_block->pool[i].pool_hash[r].no;
582                                 max_frags_pool=i;
583                                 max_frags_hash=r;
584                         }
585                         if (shm_block->pool[i].pool_hash[r].misses>max_misses){
586                                 max_misses=shm_block->pool[i].pool_hash[r].misses;
587                                 max_misses_pool=i;
588                                 max_misses_hash=r;
589                         }
590                         if (shm_block->pool[i].pool_hash[r].no*r*SF_ROUNDTO>max_mem){
591                                 max_mem=shm_block->pool[i].pool_hash[r].no*r*SF_ROUNDTO;
592                                 max_mem_pool=i;
593                                 max_mem_hash=r;
594                         }
595                 }
596                 rpc->add(c, "{", &handle);
597                 rpc->struct_add(handle, "dddddd",
598                         "pool  ", i,
599                         "frags ", (unsigned int)frags,
600                         "t. misses", (unsigned int)misses,
601                         "mem   ", (unsigned int)mem,
602                         "missed", (unsigned int)shm_block->pool[i].missed,
603                         "hits",   (unsigned int)shm_block->pool[i].hits
604                 );
605                 pool_frags+=frags;
606         }
607         main_s_frags=0;
608         for (r=0; r<SF_HASH_POOL_SIZE; r++){
609                 main_s_frags+=shm_block->free_hash[r].no;
610         }
611         main_b_frags=0;
612         for (; r<SF_HASH_SIZE; r++){
613                 main_b_frags+=shm_block->free_hash[r].no;
614         }
615         rpc->add(c, "{", &handle);
616         rpc->struct_add(handle, "ddddddddddddd",
617                 "max_frags      ", (unsigned int)max_frags,
618                 "max_frags_pool ", max_frags_pool,
619                 "max_frags_hash", max_frags_hash,
620                 "max_misses     ", (unsigned int)max_misses,
621                 "max_misses_pool", max_misses_pool,
622                 "max_misses_hash", max_misses_hash,
623                 "max_mem        ", (unsigned int)max_mem,
624                 "max_mem_pool   ", max_mem_pool,
625                 "max_mem_hash   ", max_mem_hash,
626                 "in_pools_frags ", (unsigned int)pool_frags,
627                 "main_s_frags   ", (unsigned int)main_s_frags,
628                 "main_b_frags   ", (unsigned int)main_b_frags,
629                 "main_frags     ", (unsigned int)(main_b_frags+main_s_frags)
630         );
631 }
632
633
634
635 static const char* core_sfmalloc_doc[] = {
636         "Returns sfmalloc debugging  info.",  /* Documentation string */
637         0                                     /* Method signature(s) */
638 };
639
640 #endif
641
642
643
644 static const char* core_tcpinfo_doc[] = {
645         "Returns tcp related info.",    /* Documentation string */
646         0                               /* Method signature(s) */
647 };
648
649 static void core_tcpinfo(rpc_t* rpc, void* c)
650 {
651 #ifdef USE_TCP
652         void *handle;
653         struct tcp_gen_info ti;
654
655         if (!tcp_disable){
656                 tcp_get_info(&ti);
657                 rpc->add(c, "{", &handle);
658                 rpc->struct_add(handle, "dddd",
659                         "readers", ti.tcp_readers,
660                         "max_connections", ti.tcp_max_connections,
661                         "opened_connections", ti.tcp_connections_no,
662                         "write_queued_bytes", ti.tcp_write_queued
663                 );
664         }else{
665                 rpc->fault(c, 500, "tcp support disabled");
666         }
667 #else
668         rpc->fault(c, 500, "tcp support not compiled");
669 #endif
670 }
671
672
673
674 static const char* core_tcp_options_doc[] = {
675         "Returns active tcp options.",    /* Documentation string */
676         0                                 /* Method signature(s) */
677 };
678
679 static void core_tcp_options(rpc_t* rpc, void* c)
680 {
681 #ifdef USE_TCP
682         void *handle;
683         struct cfg_group_tcp t;
684
685         if (!tcp_disable){
686                 tcp_options_get(&t);
687                 rpc->add(c, "{", &handle);
688                 rpc->struct_add(handle, "dddddddddddddddddddddd",
689                         "connect_timeout", t.connect_timeout_s,
690                         "send_timeout",  TICKS_TO_S(t.send_timeout),
691                         "connection_lifetime",  TICKS_TO_S(t.con_lifetime),
692                         "max_connections(soft)", t.max_connections,
693                         "no_connect",   t.no_connect,
694                         "fd_cache",             t.fd_cache,
695                         "async",                t.async,
696                         "connect_wait", t.tcp_connect_wait,
697                         "conn_wq_max",  t.tcpconn_wq_max,
698                         "wq_max",               t.tcp_wq_max,
699                         "defer_accept", t.defer_accept,
700                         "delayed_ack",  t.delayed_ack,
701                         "syncnt",               t.syncnt,
702                         "linger2",              t.linger2,
703                         "keepalive",    t.keepalive,
704                         "keepidle",             t.keepidle,
705                         "keepintvl",    t.keepintvl,
706                         "keepcnt",              t.keepcnt,
707                         "crlf_ping",    t.crlf_ping,
708                         "accept_aliases", t.accept_aliases,
709                         "alias_flags",  t.alias_flags,
710                         "new_conn_alias_flags", t.new_conn_alias_flags
711                 );
712         }else{
713                 rpc->fault(c, 500, "tcp support disabled");
714         }
715 #else
716         rpc->fault(c, 500, "tcp support not compiled");
717 #endif
718 }
719
720
721
722 static const char* core_sctp_options_doc[] = {
723         "Returns active sctp options. With one parameter"
724         " it returns the sctp options set in the kernel for a specific socket"
725         "(debugging), with 0 filled in for non-kernel related options."
726         " The parameter can be: \"default\" | \"first\" | address[:port] ."
727         " With no parameters it returns ser's idea of the current sctp options"
728          " (intended non-debugging use).",
729         /* Documentation string */
730         0                                 /* Method signature(s) */
731 };
732
733 static void core_sctp_options(rpc_t* rpc, void* c)
734 {
735 #ifdef USE_SCTP
736         void *handle;
737         struct cfg_group_sctp t;
738         char* param;
739         struct socket_info* si;
740         char* host;
741         str hs;
742         int hlen;
743         int port;
744         int proto;
745
746         param=0;
747         if (!sctp_disable){
748                 /* look for optional socket parameter */
749                 if (rpc->scan(c, "*s", &param)>0){
750                         si=0;
751                         if (strcasecmp(param, "default")==0){
752                                 si=sendipv4_sctp?sendipv4_sctp:sendipv6_sctp;
753                         }else if (strcasecmp(param, "first")==0){
754                                 si=sctp_listen;
755                         }else{
756                                 if (parse_phostport(param, &host, &hlen, &port, &proto)!=0){
757                                         rpc->fault(c, 500, "bad param (use address, address:port,"
758                                                                                 " default or first)");
759                                         return;
760                                 }
761                                 if (proto && proto!=PROTO_SCTP){
762                                         rpc->fault(c, 500, "bad protocol in param (only SCTP"
763                                                                                 " allowed)");
764                                         return;
765                                 }
766                                 hs.s=host;
767                                 hs.len=hlen;
768                                 si=grep_sock_info(&hs, port, PROTO_SCTP);
769                                 if (si==0){
770                                         rpc->fault(c, 500, "not listening on sctp %s", param);
771                                         return;
772                                 }
773                         }
774                         if (si==0 || si->socket==-1){
775                                 rpc->fault(c, 500, "could not find a sctp socket");
776                                 return;
777                         }
778                         memset(&t, 0, sizeof(t));
779                         if (sctp_get_cfg_from_sock(si->socket, &t)!=0){
780                                 rpc->fault(c, 500, "failed to get socket options");
781                                 return;
782                         }
783                 }else{
784                         sctp_options_get(&t);
785                 }
786                 rpc->add(c, "{", &handle);
787                 rpc->struct_add(handle, "ddddddddddddddddddd",
788                         "sctp_socket_rcvbuf",   t.so_rcvbuf,
789                         "sctp_socket_sndbuf",   t.so_sndbuf,
790                         "sctp_autoclose",               t.autoclose,
791                         "sctp_send_ttl",        t.send_ttl,
792                         "sctp_send_retries",    t.send_retries,
793                         "sctp_assoc_tracking",  t.assoc_tracking,
794                         "sctp_assoc_reuse",     t.assoc_reuse,
795                         "sctp_max_assocs", t.max_assocs,
796                         "sctp_srto_initial",    t.srto_initial,
797                         "sctp_srto_max",                t.srto_max,
798                         "sctp_srto_min",                t.srto_min,
799                         "sctp_asocmaxrxt",      t.asocmaxrxt,
800                         "sctp_init_max_attempts",       t.init_max_attempts,
801                         "sctp_init_max_timeo",t.init_max_timeo,
802                         "sctp_hbinterval",      t.hbinterval,
803                         "sctp_pathmaxrxt",      t.pathmaxrxt,
804                         "sctp_sack_delay",      t.sack_delay,
805                         "sctp_sack_freq",       t.sack_freq,
806                         "sctp_max_burst",       t.max_burst
807                 );
808         }else{
809                 rpc->fault(c, 500, "sctp support disabled");
810         }
811 #else
812         rpc->fault(c, 500, "sctp support not compiled");
813 #endif
814 }
815
816
817
818 static const char* core_sctpinfo_doc[] = {
819         "Returns sctp related info.",    /* Documentation string */
820         0                               /* Method signature(s) */
821 };
822
823 static void core_sctpinfo(rpc_t* rpc, void* c)
824 {
825 #ifdef USE_SCTP
826         void *handle;
827         struct sctp_gen_info i;
828
829         if (!sctp_disable){
830                 sctp_get_info(&i);
831                 rpc->add(c, "{", &handle);
832                 rpc->struct_add(handle, "ddd",
833                         "opened_connections", i.sctp_connections_no,
834                         "tracked_connections", i.sctp_tracked_no,
835                         "total_connections", i.sctp_total_connections
836                 );
837         }else{
838                 rpc->fault(c, 500, "sctp support disabled");
839         }
840 #else
841         rpc->fault(c, 500, "sctp support not compiled");
842 #endif
843 }
844
845
846
847
848 static const char* core_udp4rawinfo_doc[] = {
849         "Returns udp4_raw related info.",    /* Documentation string */
850         0                                     /* Method signature(s) */
851 };
852
853 static void core_udp4rawinfo(rpc_t* rpc, void* c)
854 {
855 #ifdef USE_RAW_SOCKS
856         void *handle;
857
858         rpc->add(c, "{", &handle);
859         rpc->struct_add(handle, "ddd",
860                 "udp4_raw", cfg_get(core, core_cfg, udp4_raw),
861                 "udp4_raw_mtu", cfg_get(core, core_cfg, udp4_raw_mtu),
862                 "udp4_raw_ttl", cfg_get(core, core_cfg, udp4_raw_ttl)
863         );
864 #else /* USE_RAW_SOCKS */
865         rpc->fault(c, 500, "udp4_raw mode support not compiled");
866 #endif /* USE_RAW_SOCKS */
867 }
868
869
870
871 /*
872  * RPC Methods exported by this module
873  */
874 static rpc_export_t core_rpc_methods[] = {
875         {"system.listMethods",     system_listMethods,     system_listMethods_doc,     RET_ARRAY},
876         {"system.methodSignature", system_methodSignature, system_methodSignature_doc, 0        },
877         {"system.methodHelp",      system_methodHelp,      system_methodHelp_doc,      0        },
878         {"core.prints",            core_prints,            core_prints_doc,
879         RET_ARRAY},
880         {"core.printi",            core_printi,            core_printi_doc,
881         RET_ARRAY},
882         {"core.echo",              core_echo,              core_echo_doc,
883         RET_ARRAY},
884         {"core.version",           core_version,           core_version_doc,
885                 0        },
886         {"core.flags",             core_flags,             core_flags_doc,
887                 0        },
888         {"core.info",              core_info,              core_info_doc,
889                 0        },
890         {"core.uptime",            core_uptime,            core_uptime_doc,            0        },
891         {"core.ps",                core_ps,                core_ps_doc,                RET_ARRAY},
892         {"core.pwd",               core_pwd,               core_pwd_doc,               RET_ARRAY},
893         {"core.arg",               core_arg,               core_arg_doc,               RET_ARRAY},
894         {"core.kill",              core_kill,              core_kill_doc,              0        },
895         {"core.shmmem",            core_shmmem,            core_shmmem_doc,            0        },
896 #if defined(SF_MALLOC) || defined(LL_MALLOC)
897         {"core.sfmalloc",          core_sfmalloc,          core_sfmalloc_doc,   0},
898 #endif
899         {"core.tcp_info",          core_tcpinfo,           core_tcpinfo_doc,    0},
900         {"core.tcp_options",       core_tcp_options,       core_tcp_options_doc,0},
901         {"core.sctp_options",      core_sctp_options,      core_sctp_options_doc,
902                 0},
903         {"core.sctp_info",         core_sctpinfo,          core_sctpinfo_doc,   0},
904         {"core.udp4_raw_info",     core_udp4rawinfo,       core_udp4rawinfo_doc,
905                 0},
906 #ifdef USE_DNS_CACHE
907         {"dns.mem_info",          dns_cache_mem_info,     dns_cache_mem_info_doc,
908                 0       },
909         {"dns.debug",          dns_cache_debug,           dns_cache_debug_doc,
910                 0       },
911         {"dns.debug_all",      dns_cache_debug_all,       dns_cache_debug_all_doc,
912                 0       },
913         {"dns.view",               dns_cache_view,        dns_cache_view_doc,
914                 0       },
915         {"dns.lookup",             dns_cache_rpc_lookup,  dns_cache_rpc_lookup_doc,
916                 0       },
917         {"dns.delete_all",         dns_cache_delete_all,  dns_cache_delete_all_doc,
918                 0       },
919         {"dns.delete_all_force",   dns_cache_delete_all_force, dns_cache_delete_all_force_doc,
920                 0       },
921         {"dns.add_a",              dns_cache_add_a,       dns_cache_add_a_doc,
922                 0       },
923         {"dns.add_aaaa",           dns_cache_add_aaaa,    dns_cache_add_aaaa_doc,
924                 0       },
925         {"dns.add_srv",            dns_cache_add_srv,     dns_cache_add_srv_doc,
926                 0       },
927         {"dns.delete_a",           dns_cache_delete_a,    dns_cache_delete_a_doc,
928                 0       },
929         {"dns.delete_aaaa",        dns_cache_delete_aaaa,
930                 dns_cache_delete_aaaa_doc, 0    },
931         {"dns.delete_srv",         dns_cache_delete_srv,
932                 dns_cache_delete_srv_doc,  0    },
933         {"dns.delete_naptr",         dns_cache_delete_naptr,
934                 dns_cache_delete_naptr_doc,  0  },
935         {"dns.delete_cname",         dns_cache_delete_cname,
936                 dns_cache_delete_cname_doc,  0  },
937         {"dns.delete_txt",         dns_cache_delete_txt,
938                 dns_cache_delete_txt_doc,  0    },
939         {"dns.delete_ebl",         dns_cache_delete_ebl,
940                 dns_cache_delete_ebl_doc,  0    },
941         {"dns.delete_ptr",         dns_cache_delete_ptr,
942                 dns_cache_delete_ptr_doc,  0    },
943 #ifdef USE_DNS_CACHE_STATS
944         {"dns.stats_get",    dns_cache_stats_get,   dns_cache_stats_get_doc,
945                 0       },
946 #endif /* USE_DNS_CACHE_STATS */
947 #ifdef DNS_WATCHDOG_SUPPORT
948         {"dns.set_server_state",   dns_set_server_state_rpc,
949                 dns_set_server_state_doc, 0 },
950         {"dns.get_server_state",   dns_get_server_state_rpc,
951                 dns_get_server_state_doc, 0 },
952 #endif
953 #endif
954 #ifdef USE_DST_BLACKLIST
955         {"dst_blacklist.mem_info",  dst_blst_mem_info,     dst_blst_mem_info_doc,
956                 0       },
957         {"dst_blacklist.debug",    dst_blst_debug,         dst_blst_debug_doc,
958                 0       },
959         {"dst_blacklist.view",     dst_blst_view,         dst_blst_view_doc,
960                 0       },
961         {"dst_blacklist.delete_all", dst_blst_delete_all, dst_blst_delete_all_doc,
962                 0       },
963         {"dst_blacklist.add",      dst_blst_add,          dst_blst_add_doc,
964                 0       },
965 #ifdef USE_DST_BLACKLIST_STATS
966         {"dst_blacklist.stats_get", dst_blst_stats_get, dst_blst_stats_get_doc, 0},
967 #endif /* USE_DST_BLACKLIST_STATS */
968 #endif
969         {0, 0, 0, 0}
970 };
971
972
973
974 int register_core_rpcs(void)
975 {
976         int i;
977         
978         i=rpc_register_array(core_rpc_methods);
979         if (i<0){
980                 BUG("failed to register core RPCs\n");
981                 goto error;
982         }else if (i>0){
983                 ERR("%d duplicate RPCs name detected while registering core RPCs\n",
984                          i);
985                 goto error;
986         }
987         return 0;
988 error:
989         return -1;
990 }
991
992
993
994 int rpc_init_time(void)
995 {
996         char *t;
997         t=ctime(&up_since);
998         if (strlen(t)+1>=MAX_CTIME_LEN) {
999                 ERR("Too long data %d\n", (int)strlen(t));
1000                 return -1;
1001         }
1002         memcpy(up_since_ctime,t,strlen(t)+1);
1003         return 0;
1004 }