rpc: added register function and switched to hash table
[sip-router] / core_cmd.c
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2005 iptelorg GmbH
5  *
6  * This file is part of ser, a free SIP server.
7  *
8  * ser 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  * For a license to use the ser software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * ser is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27
28 #include <time.h>
29 #include <sys/types.h>
30 #include <signal.h>
31 #include "mem/mem.h"
32 #include "mem/shm_mem.h"
33 #include "sr_module.h"
34 #include "rpc_lookup.h"
35 #include "dprint.h"
36 #include "core_cmd.h"
37 #include "globals.h"
38 #include "pt.h"
39 #include "ut.h"
40 #include "tcp_info.h"
41 #include "tcp_options.h"
42 #include "core_cmd.h"
43 #ifdef USE_SCTP
44 #include "sctp_options.h"
45 #include "sctp_server.h"
46 #endif
47
48 #ifdef USE_DNS_CACHE
49 void dns_cache_debug(rpc_t* rpc, void* ctx);
50 void dns_cache_debug_all(rpc_t* rpc, void* ctx);
51 void dns_cache_mem_info(rpc_t* rpc, void* ctx);
52 void dns_cache_view(rpc_t* rpc, void* ctx);
53 void dns_cache_rpc_lookup(rpc_t* rpc, void* ctx);
54 void dns_cache_delete_all(rpc_t* rpc, void* ctx);
55 void dns_cache_add_a(rpc_t* rpc, void* ctx);
56 void dns_cache_add_aaaa(rpc_t* rpc, void* ctx);
57 void dns_cache_add_srv(rpc_t* rpc, void* ctx);
58 void dns_cache_delete_a(rpc_t* rpc, void* ctx);
59 void dns_cache_delete_aaaa(rpc_t* rpc, void* ctx);
60 void dns_cache_delete_srv(rpc_t* rpc, void* ctx);
61 void dns_cache_delete_naptr(rpc_t* rpc, void* ctx);
62 void dns_cache_delete_cname(rpc_t* rpc, void* ctx);
63 void dns_cache_delete_txt(rpc_t* rpc, void* ctx);
64 void dns_cache_delete_ebl(rpc_t* rpc, void* ctx);
65 void dns_cache_delete_ptr(rpc_t* rpc, void* ctx);
66
67
68 static const char* dns_cache_mem_info_doc[] = {
69         "dns cache memory info.",    /* Documentation string */
70         0                      /* Method signature(s) */
71 };
72 static const char* dns_cache_debug_doc[] = {
73         "dns debug  info.",    /* Documentation string */
74         0                      /* Method signature(s) */
75 };
76
77 static const char* dns_cache_debug_all_doc[] = {
78         "complete dns debug  dump",    /* Documentation string */
79         0                              /* Method signature(s) */
80 };
81
82 static const char* dns_cache_view_doc[] = {
83         "dns cache dump in a human-readable format",
84         0
85 };
86
87 static const char* dns_cache_rpc_lookup_doc[] = {
88         "perform a dns lookup",
89         0
90 };
91
92 static const char* dns_cache_delete_all_doc[] = {
93         "deletes all the entries from the DNS cache",
94         0
95 };
96
97 static const char* dns_cache_add_a_doc[] = {
98         "adds an A record to the DNS cache",
99         0
100 };
101
102 static const char* dns_cache_add_aaaa_doc[] = {
103         "adds an AAAA record to the DNS cache",
104         0
105 };
106 static const char* dns_cache_add_srv_doc[] = {
107         "adds an SRV record to the DNS cache",
108         0
109 };
110
111 static const char* dns_cache_delete_a_doc[] = {
112         "deletes an A record from the DNS cache",
113         0
114 };
115
116 static const char* dns_cache_delete_aaaa_doc[] = {
117         "deletes an AAAA record from the DNS cache",
118         0
119 };
120
121 static const char* dns_cache_delete_srv_doc[] = {
122         "deletes an SRV record from the DNS cache",
123         0
124 };
125
126 static const char* dns_cache_delete_naptr_doc[] = {
127         "deletes a NAPTR record from the DNS cache",
128         0
129 };
130
131 static const char* dns_cache_delete_cname_doc[] = {
132         "deletes a CNAME record from the DNS cache",
133         0
134 };
135
136 static const char* dns_cache_delete_txt_doc[] = {
137         "deletes a TXT record from the DNS cache",
138         0
139 };
140
141 static const char* dns_cache_delete_ebl_doc[] = {
142         "deletes an EBL record from the DNS cache",
143         0
144 };
145
146
147 static const char* dns_cache_delete_ptr_doc[] = {
148         "deletes an PTR record from the DNS cache",
149         0
150 };
151
152
153 #ifdef USE_DNS_CACHE_STATS
154 void dns_cache_stats_get(rpc_t* rpc, void* ctx);
155
156 static const char* dns_cache_stats_get_doc[] = {
157         "returns the dns measurement counters.",
158         0
159 };
160 #endif /* USE_DNS_CACHE_STATS */
161 #ifdef DNS_WATCHDOG_SUPPORT
162 void dns_set_server_state_rpc(rpc_t* rpc, void* ctx);
163
164 static const char* dns_set_server_state_doc[] = {
165         "sets the state of the DNS servers " \
166         "(0: all the servers are down, 1: at least one server is up)",    /* Documentation string */
167         0                              /* Method signature(s) */
168 };
169
170 void dns_get_server_state_rpc(rpc_t* rpc, void* ctx);
171
172 static const char* dns_get_server_state_doc[] = {
173         "prints the state of the DNS servers " \
174         "(0: all the servers are down, 1: at least one server is up)",  /* Documentation string */
175         0                               /* Method signature(s) */
176 };
177
178 #endif /* DNS_WATCHDOG_SUPPORT */
179 #endif /* USE_DNS_CACHE */
180 #ifdef USE_DST_BLACKLIST
181 void dst_blst_debug(rpc_t* rpc, void* ctx);
182 void dst_blst_mem_info(rpc_t* rpc, void* ctx);
183 void dst_blst_view(rpc_t* rpc, void* ctx);
184 void dst_blst_delete_all(rpc_t* rpc, void* ctx);
185 void dst_blst_add(rpc_t* rpc, void* ctx);
186
187 static const char* dst_blst_mem_info_doc[] = {
188         "dst blacklist memory usage info.",  /* Documentation string */
189         0                                    /* Method signature(s) */
190 };
191 static const char* dst_blst_debug_doc[] = {
192         "dst blacklist  debug  info.",  /* Documentation string */
193         0                               /* Method signature(s) */
194 };
195 static const char* dst_blst_view_doc[] = {
196         "dst blacklist dump in human-readable format.",  /* Documentation string */
197         0                               /* Method signature(s) */
198 };
199 static const char* dst_blst_delete_all_doc[] = {
200         "Deletes all the entries from the dst blacklist except the permanent ones.",  /* Documentation string */
201         0                               /* Method signature(s) */
202 };
203 static const char* dst_blst_add_doc[] = {
204         "Adds a new entry to the dst blacklist.",  /* Documentation string */
205         0                               /* Method signature(s) */
206 };
207 #ifdef USE_DST_BLACKLIST_STATS
208 void dst_blst_stats_get(rpc_t* rpc, void* ctx);
209
210 static const char* dst_blst_stats_get_doc[] = {
211         "returns the dst blacklist measurement counters.",
212         0
213 };
214 #endif /* USE_DST_BLACKLIST_STATS */
215
216 #endif
217
218
219
220 #define MAX_CTIME_LEN 128
221
222 /* up time */
223 static char up_since_ctime[MAX_CTIME_LEN];
224
225
226 static const char* system_listMethods_doc[] = {
227         "Lists all RPC methods supported by the server.",  /* Documentation string */
228         0                                                  /* Method signature(s) */
229 };
230
231 static void system_listMethods(rpc_t* rpc, void* c)
232 {
233         int i;
234         
235         for(i=0; i<rpc_sarray_crt_size; i++){
236                 if (rpc->add(c, "s", rpc_sarray[i]->name) < 0) return;
237         }
238 }
239
240 static const char* system_methodSignature_doc[] = {
241         "Returns signature of given method.",  /* Documentation string */
242         0                                      /* Method signature(s) */
243 };
244
245 static void system_methodSignature(rpc_t* rpc, void* c)
246 {
247         rpc->fault(c, 500, "Not Implemented Yet");
248 }
249
250
251 static const char* system_methodHelp_doc[] = {
252         "Print the help string for given method.",  /* Documentation string */
253         0                                           /* Method signature(s) */
254 };
255
256 static void system_methodHelp(rpc_t* rpc, void* c)
257 {
258         rpc_export_t* r;
259         char* name;
260
261         if (rpc->scan(c, "s", &name) < 1) {
262                 rpc->fault(c, 400, "Method Name Expected");
263                 return;
264         }
265         
266         r=rpc_lookup(name, strlen(name));
267         if (r==0){
268                 rpc->fault(c, 400, "command not found");
269         }else{
270                 if (r->doc_str && r->doc_str[0]) {
271                         rpc->add(c, "s", r->doc_str[0]);
272                 } else {
273                         rpc->add(c, "s", "undocumented");
274                 }
275         }
276         return;
277 }
278
279
280 static const char* core_prints_doc[] = {
281         "Returns the string given as parameter.",   /* Documentation string */
282         0                                           /* Method signature(s) */
283 };
284
285
286 static void core_prints(rpc_t* rpc, void* c)
287 {
288         char* string = 0;
289         if (rpc->scan(c, "s", &string)>0)
290                 rpc->add(c, "s", string);
291 }
292
293
294 static const char* core_version_doc[] = {
295         "Returns the version string of the server.", /* Documentation string */
296         0                                           /* Method signature(s) */
297 };
298
299 static void core_version(rpc_t* rpc, void* c)
300 {
301         rpc->add(c, "s", SERVER_HDR);
302 }
303
304
305
306 static const char* core_uptime_doc[] = {
307         "Returns uptime of SER server.",  /* Documentation string */
308         0                                 /* Method signature(s) */
309 };
310
311
312 static void core_uptime(rpc_t* rpc, void* c)
313 {
314         void* s;
315         time_t now;
316
317         time(&now);
318
319         if (rpc->add(c, "{", &s) < 0) return;
320         rpc->struct_add(s, "s", "now", ctime(&now));
321         rpc->struct_add(s, "s", "up_since", up_since_ctime);
322         /* no need for a float here (unless you're concerned that your uptime)
323         rpc->struct_add(s, "f", "uptime",  difftime(now, up_since));
324         */
325         /* on posix system we can substract time_t directly */
326         rpc->struct_add(s, "d", "uptime",  (int)(now-up_since));
327 }
328
329
330 static const char* core_ps_doc[] = {
331         "Returns the description of running SER processes.",  /* Documentation string */
332         0                                                     /* Method signature(s) */
333 };
334
335
336 static void core_ps(rpc_t* rpc, void* c)
337 {
338         int p;
339
340         for (p=0; p<*process_count;p++) {
341                 rpc->add(c, "d", pt[p].pid);
342                 rpc->add(c, "s", pt[p].desc);
343         }
344 }
345
346
347 static const char* core_pwd_doc[] = {
348         "Returns the working directory of SER server.",    /* Documentation string */
349         0                                                  /* Method signature(s) */
350 };
351
352
353 static void core_pwd(rpc_t* rpc, void* c)
354 {
355         char *cwd_buf;
356         int max_len;
357
358         max_len = pathmax();
359         cwd_buf = pkg_malloc(max_len);
360         if (!cwd_buf) {
361                 ERR("core_pwd: No memory left\n");
362                 rpc->fault(c, 500, "Server Ran Out of Memory");
363                 return;
364         }
365
366         if (getcwd(cwd_buf, max_len)) {
367                 rpc->add(c, "s", cwd_buf);
368         } else {
369                 rpc->fault(c, 500, "getcwd Failed");
370         }
371         pkg_free(cwd_buf);
372 }
373
374
375 static const char* core_arg_doc[] = {
376         "Returns the list of command line arguments used on SER startup.",  /* Documentation string */
377         0                                                                   /* Method signature(s) */
378 };
379
380
381 static void core_arg(rpc_t* rpc, void* c)
382 {
383         int p;
384
385         for (p = 0; p < my_argc; p++) {
386                 if (rpc->add(c, "s", my_argv[p]) < 0) return;
387         }
388 }
389
390
391 static const char* core_kill_doc[] = {
392         "Sends the given signal to SER.",  /* Documentation string */
393         0                                  /* Method signature(s) */
394 };
395
396
397 static void core_kill(rpc_t* rpc, void* c)
398 {
399         int sig_no = 15;
400         rpc->scan(c, "d", &sig_no);
401         rpc->send(c);
402         kill(0, sig_no);
403 }
404
405 static void core_shmmem(rpc_t* rpc, void* c)
406 {
407         struct mem_info mi;
408         void *handle;
409
410         shm_info(&mi);
411         rpc->add(c, "{", &handle);
412         rpc->struct_add(handle, "dddddd",
413                 "total", (unsigned int)mi.total_size,
414                 "free", (unsigned int)mi.free,
415                 "used", (unsigned int)mi.used,
416                 "real_used",(unsigned int)mi.real_used,
417                 "max_used", (unsigned int)mi.max_used,
418                 "fragments", (unsigned int)mi.total_frags
419         );
420 }
421
422 static const char* core_shmmem_doc[] = {
423         "Returns shared memory info.",  /* Documentation string */
424         0                               /* Method signature(s) */
425 };
426
427
428 #if defined(SF_MALLOC) || defined(LL_MALLOC)
429 static void core_sfmalloc(rpc_t* rpc, void* c)
430 {
431         void *handle;
432         int i,r;
433         unsigned long frags, main_s_frags, main_b_frags, pool_frags;
434         unsigned long misses;
435         unsigned long max_misses;
436         unsigned long max_frags;
437         unsigned long max_mem;
438         int max_frags_pool, max_frags_hash;
439         int max_misses_pool, max_misses_hash;
440         int max_mem_pool, max_mem_hash;
441         unsigned long mem;
442
443         if (rpc->scan(c, "d", &r) >= 1) {
444                 if (r>=(int)SF_HASH_POOL_SIZE){
445                         rpc->fault(c, 500, "invalid hash number %d (max %d)",
446                                                                 r, (unsigned int)SF_HASH_POOL_SIZE-1);
447                         return;
448                 }else if (r<0) goto all;
449                 rpc->add(c, "{", &handle);
450                 rpc->struct_add(handle, "dd",
451                                 "hash  ", r,
452                                 "size  ", r*SF_ROUNDTO);
453                 for (i=0; i<SFM_POOLS_NO; i++){
454                         rpc->struct_add(handle, "dddd",
455                                 "pool  ", i,
456                                 "frags ", (unsigned int)shm_block->pool[i].pool_hash[r].no,
457                                 "misses", (unsigned int)shm_block->pool[i].pool_hash[r].misses,
458                                 "mem   ",   (unsigned int)shm_block->pool[i].pool_hash[r].no *
459                                                         r*SF_ROUNDTO
460                         );
461                 }
462         }
463         return;
464 all:
465         max_frags=max_misses=max_mem=0;
466         max_frags_pool=max_frags_hash=0;
467         max_misses_pool=max_misses_hash=0;
468         max_mem_pool=max_mem_hash=0;
469         pool_frags=0;
470         for (i=0; i<SFM_POOLS_NO; i++){
471                 frags=0;
472                 misses=0;
473                 mem=0;
474                 for (r=0; r<SF_HASH_POOL_SIZE; r++){
475                         frags+=shm_block->pool[i].pool_hash[r].no;
476                         misses+=shm_block->pool[i].pool_hash[r].misses;
477                         mem+=shm_block->pool[i].pool_hash[r].no*r*SF_ROUNDTO;
478                         if (shm_block->pool[i].pool_hash[r].no>max_frags){
479                                 max_frags=shm_block->pool[i].pool_hash[r].no;
480                                 max_frags_pool=i;
481                                 max_frags_hash=r;
482                         }
483                         if (shm_block->pool[i].pool_hash[r].misses>max_misses){
484                                 max_misses=shm_block->pool[i].pool_hash[r].misses;
485                                 max_misses_pool=i;
486                                 max_misses_hash=r;
487                         }
488                         if (shm_block->pool[i].pool_hash[r].no*r*SF_ROUNDTO>max_mem){
489                                 max_mem=shm_block->pool[i].pool_hash[r].no*r*SF_ROUNDTO;
490                                 max_mem_pool=i;
491                                 max_mem_hash=r;
492                         }
493                 }
494                 rpc->add(c, "{", &handle);
495                 rpc->struct_add(handle, "dddddd",
496                         "pool  ", i,
497                         "frags ", (unsigned int)frags,
498                         "t. misses", (unsigned int)misses,
499                         "mem   ", (unsigned int)mem,
500                         "missed", (unsigned int)shm_block->pool[i].missed,
501                         "hits",   (unsigned int)shm_block->pool[i].hits
502                 );
503                 pool_frags+=frags;
504         }
505         main_s_frags=0;
506         for (r=0; r<SF_HASH_POOL_SIZE; r++){
507                 main_s_frags+=shm_block->free_hash[r].no;
508         }
509         main_b_frags=0;
510         for (; r<SF_HASH_SIZE; r++){
511                 main_b_frags+=shm_block->free_hash[r].no;
512         }
513         rpc->add(c, "{", &handle);
514         rpc->struct_add(handle, "ddddddddddddd",
515                 "max_frags      ", (unsigned int)max_frags,
516                 "max_frags_pool ", max_frags_pool,
517                 "max_frags_hash", max_frags_hash,
518                 "max_misses     ", (unsigned int)max_misses,
519                 "max_misses_pool", max_misses_pool,
520                 "max_misses_hash", max_misses_hash,
521                 "max_mem        ", (unsigned int)max_mem,
522                 "max_mem_pool   ", max_mem_pool,
523                 "max_mem_hash   ", max_mem_hash,
524                 "in_pools_frags ", (unsigned int)pool_frags,
525                 "main_s_frags   ", (unsigned int)main_s_frags,
526                 "main_b_frags   ", (unsigned int)main_b_frags,
527                 "main_frags     ", (unsigned int)(main_b_frags+main_s_frags)
528         );
529 }
530
531
532
533 static const char* core_sfmalloc_doc[] = {
534         "Returns sfmalloc debugging  info.",  /* Documentation string */
535         0                                     /* Method signature(s) */
536 };
537
538 #endif
539
540
541
542 static const char* core_tcpinfo_doc[] = {
543         "Returns tcp related info.",    /* Documentation string */
544         0                               /* Method signature(s) */
545 };
546
547 static void core_tcpinfo(rpc_t* rpc, void* c)
548 {
549 #ifdef USE_TCP
550         void *handle;
551         struct tcp_gen_info ti;
552
553         if (!tcp_disable){
554                 tcp_get_info(&ti);
555                 rpc->add(c, "{", &handle);
556                 rpc->struct_add(handle, "dddd",
557                         "readers", ti.tcp_readers,
558                         "max_connections", ti.tcp_max_connections,
559                         "opened_connections", ti.tcp_connections_no,
560                         "write_queued_bytes", ti.tcp_write_queued
561                 );
562         }else{
563                 rpc->fault(c, 500, "tcp support disabled");
564         }
565 #else
566         rpc->fault(c, 500, "tcp support not compiled");
567 #endif
568 }
569
570
571
572 static const char* core_tcp_options_doc[] = {
573         "Returns active tcp options.",    /* Documentation string */
574         0                                 /* Method signature(s) */
575 };
576
577 static void core_tcp_options(rpc_t* rpc, void* c)
578 {
579 #ifdef USE_TCP
580         void *handle;
581         struct cfg_group_tcp t;
582
583         if (!tcp_disable){
584                 tcp_options_get(&t);
585                 rpc->add(c, "{", &handle);
586                 rpc->struct_add(handle, "dddddddddddddddddddddd",
587                         "connect_timeout", t.connect_timeout_s,
588                         "send_timeout",  TICKS_TO_S(t.send_timeout),
589                         "connection_lifetime",  TICKS_TO_S(t.con_lifetime),
590                         "max_connections(soft)", t.max_connections,
591                         "no_connect",   t.no_connect,
592                         "fd_cache",             t.fd_cache,
593                         "async",                t.async,
594                         "connect_wait", t.tcp_connect_wait,
595                         "conn_wq_max",  t.tcpconn_wq_max,
596                         "wq_max",               t.tcp_wq_max,
597                         "defer_accept", t.defer_accept,
598                         "delayed_ack",  t.delayed_ack,
599                         "syncnt",               t.syncnt,
600                         "linger2",              t.linger2,
601                         "keepalive",    t.keepalive,
602                         "keepidle",             t.keepidle,
603                         "keepintvl",    t.keepintvl,
604                         "keepcnt",              t.keepcnt,
605                         "crlf_ping",    t.crlf_ping,
606                         "accept_aliases", t.accept_aliases,
607                         "alias_flags",  t.alias_flags,
608                         "new_conn_alias_flags", t.new_conn_alias_flags
609                 );
610         }else{
611                 rpc->fault(c, 500, "tcp support disabled");
612         }
613 #else
614         rpc->fault(c, 500, "tcp support not compiled");
615 #endif
616 }
617
618
619
620 static const char* core_sctp_options_doc[] = {
621         "Returns active sctp options.",    /* Documentation string */
622         0                                 /* Method signature(s) */
623 };
624
625 static void core_sctp_options(rpc_t* rpc, void* c)
626 {
627 #ifdef USE_SCTP
628         void *handle;
629         struct sctp_cfg_options t;
630
631         if (!sctp_disable){
632                 sctp_options_get(&t);
633                 rpc->add(c, "{", &handle);
634                 rpc->struct_add(handle, "dddd",
635                         "sctp_autoclose",               t.sctp_autoclose,
636                         "sctp_send_ttl",        t.sctp_autoclose,
637                         "sctp_socket_rcvbuf",   t.sctp_so_rcvbuf,
638                         "sctp_socket_sndbuf",   t.sctp_so_sndbuf
639                 );
640         }else{
641                 rpc->fault(c, 500, "sctp support disabled");
642         }
643 #else
644         rpc->fault(c, 500, "sctp support not compiled");
645 #endif
646 }
647
648
649
650 static const char* core_sctpinfo_doc[] = {
651         "Returns sctp related info.",    /* Documentation string */
652         0                               /* Method signature(s) */
653 };
654
655 static void core_sctpinfo(rpc_t* rpc, void* c)
656 {
657 #ifdef USE_SCTP
658         void *handle;
659         struct sctp_gen_info i;
660
661         if (!sctp_disable){
662                 sctp_get_info(&i);
663                 rpc->add(c, "{", &handle);
664                 rpc->struct_add(handle, "ddd",
665                         "opened_connections", i.sctp_connections_no,
666                         "tracked_connections", i.sctp_tracked_no,
667                         "total_connections", i.sctp_total_connections
668                 );
669         }else{
670                 rpc->fault(c, 500, "sctp support disabled");
671         }
672 #else
673         rpc->fault(c, 500, "sctp support not compiled");
674 #endif
675 }
676
677
678
679 /*
680  * RPC Methods exported by this module
681  */
682 static rpc_export_t core_rpc_methods[] = {
683         {"system.listMethods",     system_listMethods,     system_listMethods_doc,     RET_ARRAY},
684         {"system.methodSignature", system_methodSignature, system_methodSignature_doc, 0        },
685         {"system.methodHelp",      system_methodHelp,      system_methodHelp_doc,      0        },
686         {"core.prints",            core_prints,            core_prints_doc,            0        },
687         {"core.version",           core_version,           core_version_doc,           0        },
688         {"core.uptime",            core_uptime,            core_uptime_doc,            0        },
689         {"core.ps",                core_ps,                core_ps_doc,                RET_ARRAY},
690         {"core.pwd",               core_pwd,               core_pwd_doc,               RET_ARRAY},
691         {"core.arg",               core_arg,               core_arg_doc,               RET_ARRAY},
692         {"core.kill",              core_kill,              core_kill_doc,              0        },
693         {"core.shmmem",            core_shmmem,            core_shmmem_doc,            0        },
694 #if defined(SF_MALLOC) || defined(LL_MALLOC)
695         {"core.sfmalloc",          core_sfmalloc,          core_sfmalloc_doc,   0},
696 #endif
697         {"core.tcp_info",          core_tcpinfo,           core_tcpinfo_doc,    0},
698         {"core.tcp_options",       core_tcp_options,       core_tcp_options_doc,0},
699         {"core.sctp_options",      core_sctp_options,      core_sctp_options_doc,
700                 0},
701         {"core.sctp_info",         core_sctpinfo,          core_sctpinfo_doc,   0},
702 #ifdef USE_DNS_CACHE
703         {"dns.mem_info",          dns_cache_mem_info,     dns_cache_mem_info_doc,
704                 0       },
705         {"dns.debug",          dns_cache_debug,           dns_cache_debug_doc,
706                 0       },
707         {"dns.debug_all",      dns_cache_debug_all,       dns_cache_debug_all_doc,
708                 0       },
709         {"dns.view",               dns_cache_view,        dns_cache_view_doc,
710                 0       },
711         {"dns.lookup",             dns_cache_rpc_lookup,  dns_cache_rpc_lookup_doc,
712                 0       },
713         {"dns.delete_all",         dns_cache_delete_all,  dns_cache_delete_all_doc,
714                 0       },
715         {"dns.add_a",              dns_cache_add_a,       dns_cache_add_a_doc,
716                 0       },
717         {"dns.add_aaaa",           dns_cache_add_aaaa,    dns_cache_add_aaaa_doc,
718                 0       },
719         {"dns.add_srv",            dns_cache_add_srv,     dns_cache_add_srv_doc,
720                 0       },
721         {"dns.delete_a",           dns_cache_delete_a,    dns_cache_delete_a_doc,
722                 0       },
723         {"dns.delete_aaaa",        dns_cache_delete_aaaa,
724                 dns_cache_delete_aaaa_doc, 0    },
725         {"dns.delete_srv",         dns_cache_delete_srv,
726                 dns_cache_delete_srv_doc,  0    },
727         {"dns.delete_naptr",         dns_cache_delete_naptr,
728                 dns_cache_delete_naptr_doc,  0  },
729         {"dns.delete_cname",         dns_cache_delete_cname,
730                 dns_cache_delete_cname_doc,  0  },
731         {"dns.delete_txt",         dns_cache_delete_txt,
732                 dns_cache_delete_txt_doc,  0    },
733         {"dns.delete_ebl",         dns_cache_delete_ebl,
734                 dns_cache_delete_ebl_doc,  0    },
735         {"dns.delete_ptr",         dns_cache_delete_ptr,
736                 dns_cache_delete_ptr_doc,  0    },
737 #ifdef USE_DNS_CACHE_STATS
738         {"dns.stats_get",    dns_cache_stats_get,   dns_cache_stats_get_doc,
739                 0       },
740 #endif /* USE_DNS_CACHE_STATS */
741 #ifdef DNS_WATCHDOG_SUPPORT
742         {"dns.set_server_state",   dns_set_server_state_rpc,
743                 dns_set_server_state_doc, 0 },
744         {"dns.get_server_state",   dns_get_server_state_rpc,
745                 dns_get_server_state_doc, 0 },
746 #endif
747 #endif
748 #ifdef USE_DST_BLACKLIST
749         {"dst_blacklist.mem_info",  dst_blst_mem_info,     dst_blst_mem_info_doc,
750                 0       },
751         {"dst_blacklist.debug",    dst_blst_debug,         dst_blst_debug_doc,
752                 0       },
753         {"dst_blacklist.view",     dst_blst_view,         dst_blst_view_doc,
754                 0       },
755         {"dst_blacklist.delete_all", dst_blst_delete_all, dst_blst_delete_all_doc,
756                 0       },
757         {"dst_blacklist.add",      dst_blst_add,          dst_blst_add_doc,
758                 0       },
759 #ifdef USE_DST_BLACKLIST_STATS
760         {"dst_blacklist.stats_get", dst_blst_stats_get, dst_blst_stats_get_doc, 0},
761 #endif /* USE_DST_BLACKLIST_STATS */
762 #endif
763         {0, 0, 0, 0}
764 };
765
766
767
768 int register_core_rpcs(void)
769 {
770         int i;
771         
772         i=rpc_register_array(core_rpc_methods);
773         if (i<0){
774                 BUG("failed to register core RPCs\n");
775                 goto error;
776         }else if (i>0){
777                 ERR("%d duplicate RPCs name detected while registering core RPCs\n",
778                          i);
779                 goto error;
780         }
781         return 0;
782 error:
783         return -1;
784 }
785
786
787
788 int rpc_init_time(void)
789 {
790         char *t;
791         t=ctime(&up_since);
792         if (strlen(t)+1>=MAX_CTIME_LEN) {
793                 ERR("Too long data %d\n", (int)strlen(t));
794                 return -1;
795         }
796         memcpy(up_since_ctime,t,strlen(t)+1);
797         return 0;
798 }