00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00029 #include <time.h>
00030 #include <sys/types.h>
00031 #include <signal.h>
00032 #include "ver.h"
00033 #include "mem/mem.h"
00034 #include "mem/shm_mem.h"
00035 #include "sr_module.h"
00036 #include "rpc_lookup.h"
00037 #include "dprint.h"
00038 #include "core_cmd.h"
00039 #include "globals.h"
00040 #include "forward.h"
00041 #include "socket_info.h"
00042 #include "name_alias.h"
00043 #include "pt.h"
00044 #include "ut.h"
00045 #include "tcp_info.h"
00046 #include "tcp_conn.h"
00047 #include "tcp_options.h"
00048 #include "core_cmd.h"
00049 #include "cfg_core.h"
00050 #ifdef USE_SCTP
00051 #include "sctp_options.h"
00052 #include "sctp_server.h"
00053 #endif
00054
00055 #ifdef USE_DNS_CACHE
00056 void dns_cache_debug(rpc_t* rpc, void* ctx);
00057 void dns_cache_debug_all(rpc_t* rpc, void* ctx);
00058 void dns_cache_mem_info(rpc_t* rpc, void* ctx);
00059 void dns_cache_view(rpc_t* rpc, void* ctx);
00060 void dns_cache_rpc_lookup(rpc_t* rpc, void* ctx);
00061 void dns_cache_delete_all(rpc_t* rpc, void* ctx);
00062 void dns_cache_delete_all_force(rpc_t* rpc, void* ctx);
00063 void dns_cache_add_a(rpc_t* rpc, void* ctx);
00064 void dns_cache_add_aaaa(rpc_t* rpc, void* ctx);
00065 void dns_cache_add_srv(rpc_t* rpc, void* ctx);
00066 void dns_cache_delete_a(rpc_t* rpc, void* ctx);
00067 void dns_cache_delete_aaaa(rpc_t* rpc, void* ctx);
00068 void dns_cache_delete_srv(rpc_t* rpc, void* ctx);
00069 void dns_cache_delete_naptr(rpc_t* rpc, void* ctx);
00070 void dns_cache_delete_cname(rpc_t* rpc, void* ctx);
00071 void dns_cache_delete_txt(rpc_t* rpc, void* ctx);
00072 void dns_cache_delete_ebl(rpc_t* rpc, void* ctx);
00073 void dns_cache_delete_ptr(rpc_t* rpc, void* ctx);
00074
00075
00076 static const char* dns_cache_mem_info_doc[] = {
00077 "dns cache memory info.",
00078 0
00079 };
00080 static const char* dns_cache_debug_doc[] = {
00081 "dns debug info.",
00082 0
00083 };
00084
00085 static const char* dns_cache_debug_all_doc[] = {
00086 "complete dns debug dump",
00087 0
00088 };
00089
00090 static const char* dns_cache_view_doc[] = {
00091 "dns cache dump in a human-readable format",
00092 0
00093 };
00094
00095 static const char* dns_cache_rpc_lookup_doc[] = {
00096 "perform a dns lookup",
00097 0
00098 };
00099
00100 static const char* dns_cache_delete_all_doc[] = {
00101 "deletes all the non-permanent entries from the DNS cache",
00102 0
00103 };
00104
00105 static const char* dns_cache_delete_all_force_doc[] = {
00106 "deletes all the entries from the DNS cache including the permanent ones",
00107 0
00108 };
00109
00110 static const char* dns_cache_add_a_doc[] = {
00111 "adds an A record to the DNS cache",
00112 0
00113 };
00114
00115 static const char* dns_cache_add_aaaa_doc[] = {
00116 "adds an AAAA record to the DNS cache",
00117 0
00118 };
00119 static const char* dns_cache_add_srv_doc[] = {
00120 "adds an SRV record to the DNS cache",
00121 0
00122 };
00123
00124 static const char* dns_cache_delete_a_doc[] = {
00125 "deletes an A record from the DNS cache",
00126 0
00127 };
00128
00129 static const char* dns_cache_delete_aaaa_doc[] = {
00130 "deletes an AAAA record from the DNS cache",
00131 0
00132 };
00133
00134 static const char* dns_cache_delete_srv_doc[] = {
00135 "deletes an SRV record from the DNS cache",
00136 0
00137 };
00138
00139 static const char* dns_cache_delete_naptr_doc[] = {
00140 "deletes a NAPTR record from the DNS cache",
00141 0
00142 };
00143
00144 static const char* dns_cache_delete_cname_doc[] = {
00145 "deletes a CNAME record from the DNS cache",
00146 0
00147 };
00148
00149 static const char* dns_cache_delete_txt_doc[] = {
00150 "deletes a TXT record from the DNS cache",
00151 0
00152 };
00153
00154 static const char* dns_cache_delete_ebl_doc[] = {
00155 "deletes an EBL record from the DNS cache",
00156 0
00157 };
00158
00159
00160 static const char* dns_cache_delete_ptr_doc[] = {
00161 "deletes an PTR record from the DNS cache",
00162 0
00163 };
00164
00165
00166 #ifdef USE_DNS_CACHE_STATS
00167 void dns_cache_stats_get(rpc_t* rpc, void* ctx);
00168
00169 static const char* dns_cache_stats_get_doc[] = {
00170 "returns the dns measurement counters.",
00171 0
00172 };
00173 #endif
00174 #ifdef DNS_WATCHDOG_SUPPORT
00175 void dns_set_server_state_rpc(rpc_t* rpc, void* ctx);
00176
00177 static const char* dns_set_server_state_doc[] = {
00178 "sets the state of the DNS servers " \
00179 "(0: all the servers are down, 1: at least one server is up)",
00180 0
00181 };
00182
00183 void dns_get_server_state_rpc(rpc_t* rpc, void* ctx);
00184
00185 static const char* dns_get_server_state_doc[] = {
00186 "prints the state of the DNS servers " \
00187 "(0: all the servers are down, 1: at least one server is up)",
00188 0
00189 };
00190
00191 #endif
00192 #endif
00193 #ifdef USE_DST_BLACKLIST
00194 void dst_blst_debug(rpc_t* rpc, void* ctx);
00195 void dst_blst_mem_info(rpc_t* rpc, void* ctx);
00196 void dst_blst_view(rpc_t* rpc, void* ctx);
00197 void dst_blst_delete_all(rpc_t* rpc, void* ctx);
00198 void dst_blst_add(rpc_t* rpc, void* ctx);
00199
00200 static const char* dst_blst_mem_info_doc[] = {
00201 "dst blacklist memory usage info.",
00202 0
00203 };
00204 static const char* dst_blst_debug_doc[] = {
00205 "dst blacklist debug info.",
00206 0
00207 };
00208 static const char* dst_blst_view_doc[] = {
00209 "dst blacklist dump in human-readable format.",
00210 0
00211 };
00212 static const char* dst_blst_delete_all_doc[] = {
00213 "Deletes all the entries from the dst blacklist except the permanent ones.",
00214 0
00215 };
00216 static const char* dst_blst_add_doc[] = {
00217 "Adds a new entry to the dst blacklist.",
00218 0
00219 };
00220 #ifdef USE_DST_BLACKLIST_STATS
00221 void dst_blst_stats_get(rpc_t* rpc, void* ctx);
00222
00223 static const char* dst_blst_stats_get_doc[] = {
00224 "returns the dst blacklist measurement counters.",
00225 0
00226 };
00227 #endif
00228
00229 #endif
00230
00231
00232
00233 #define MAX_CTIME_LEN 128
00234
00235
00236 static char up_since_ctime[MAX_CTIME_LEN];
00237
00238
00239 static const char* system_listMethods_doc[] = {
00240 "Lists all RPC methods supported by the server.",
00241 0
00242 };
00243
00244 static void system_listMethods(rpc_t* rpc, void* c)
00245 {
00246 int i;
00247
00248 for(i=0; i<rpc_sarray_crt_size; i++){
00249 if (rpc->add(c, "s", rpc_sarray[i]->name) < 0) return;
00250 }
00251 }
00252
00253 static const char* system_methodSignature_doc[] = {
00254 "Returns signature of given method.",
00255 0
00256 };
00257
00258 static void system_methodSignature(rpc_t* rpc, void* c)
00259 {
00260 rpc->fault(c, 500, "Not Implemented Yet");
00261 }
00262
00263
00264 static const char* system_methodHelp_doc[] = {
00265 "Print the help string for given method.",
00266 0
00267 };
00268
00269 static void system_methodHelp(rpc_t* rpc, void* c)
00270 {
00271 rpc_export_t* r;
00272 char* name;
00273
00274 if (rpc->scan(c, "s", &name) < 1) {
00275 rpc->fault(c, 400, "Method Name Expected");
00276 return;
00277 }
00278
00279 r=rpc_lookup(name, strlen(name));
00280 if (r==0){
00281 rpc->fault(c, 400, "command not found");
00282 }else{
00283 if (r->doc_str && r->doc_str[0]) {
00284 rpc->add(c, "s", r->doc_str[0]);
00285 } else {
00286 rpc->add(c, "s", "undocumented");
00287 }
00288 }
00289 return;
00290 }
00291
00292
00293 static const char* core_prints_doc[] = {
00294 "Returns the strings given as parameters.",
00295 0
00296 };
00297
00298
00299 static void core_prints(rpc_t* rpc, void* c)
00300 {
00301 char* string = 0;
00302 while((rpc->scan(c, "*s", &string)>0))
00303 rpc->add(c, "s", string);
00304 }
00305
00306
00307 static const char* core_printi_doc[] = {
00308 "Returns the integers given as parameters.",
00309 0
00310 };
00311
00312
00313 static void core_printi(rpc_t* rpc, void* c)
00314 {
00315 int i;
00316 while((rpc->scan(c, "*d", &i)>0))
00317 rpc->add(c, "d", i);
00318 }
00319
00320
00321 static const char* core_echo_doc[] = {
00322 "Returns back its parameters.",
00323 0
00324 };
00325
00326
00327 static void core_echo(rpc_t* rpc, void* c)
00328 {
00329 char* string = 0;
00330 while((rpc->scan(c, "*.s", &string)>0))
00331 rpc->add(c, "s", string);
00332 }
00333
00334
00335 static const char* core_version_doc[] = {
00336 "Returns the version string of the server.",
00337 0
00338 };
00339
00340 static void core_version(rpc_t* rpc, void* c)
00341 {
00342 rpc->add(c, "s", full_version);
00343 }
00344
00345
00346
00347 static const char* core_flags_doc[] = {
00348 "Returns the compile flags.",
00349 0
00350 };
00351
00352 static void core_flags(rpc_t* rpc, void* c)
00353 {
00354 rpc->add(c, "s", ver_flags);
00355 }
00356
00357
00358
00359 static const char* core_info_doc[] = {
00360 "Verbose info, including version number, compile flags, compiler,"
00361 "repository hash a.s.o.",
00362 0
00363 };
00364
00365 static void core_info(rpc_t* rpc, void* c)
00366 {
00367 void* s;
00368
00369 if (rpc->add(c, "{", &s) < 0) return;
00370 rpc->struct_printf(s, "version", "%s %s", ver_name, ver_version);
00371 rpc->struct_add(s, "s", "id", ver_id);
00372 rpc->struct_add(s, "s", "compiler", ver_compiler);
00373 rpc->struct_add(s, "s", "compiled", ver_compiled_time);
00374 rpc->struct_add(s, "s", "flags", ver_flags);
00375 }
00376
00377
00378
00379 static const char* core_uptime_doc[] = {
00380 "Returns uptime of SER server.",
00381 0
00382 };
00383
00384
00385 static void core_uptime(rpc_t* rpc, void* c)
00386 {
00387 void* s;
00388 time_t now;
00389
00390 time(&now);
00391
00392 if (rpc->add(c, "{", &s) < 0) return;
00393 rpc->struct_add(s, "s", "now", ctime(&now));
00394 rpc->struct_add(s, "s", "up_since", up_since_ctime);
00395
00396
00397
00398
00399 rpc->struct_add(s, "d", "uptime", (int)(now-up_since));
00400 }
00401
00402
00403 static const char* core_ps_doc[] = {
00404 "Returns the description of running SER processes.",
00405 0
00406 };
00407
00408
00409 static void core_ps(rpc_t* rpc, void* c)
00410 {
00411 int p;
00412
00413 for (p=0; p<*process_count;p++) {
00414 rpc->add(c, "d", pt[p].pid);
00415 rpc->add(c, "s", pt[p].desc);
00416 }
00417 }
00418
00419 static const char* core_psx_doc[] = {
00420 "Returns the detailed description of running SER processes.",
00421
00422 0
00423 };
00424
00425
00426 static void core_psx(rpc_t* rpc, void* c)
00427 {
00428 int p;
00429 void *handle;
00430
00431 for (p=0; p<*process_count;p++) {
00432 rpc->add(c, "{", &handle);
00433 rpc->struct_add(handle, "dds",
00434 "IDX", p,
00435 "PID", pt[p].pid,
00436 "DSC", pt[p].desc);
00437 }
00438 }
00439
00440
00441 static const char* core_pwd_doc[] = {
00442 "Returns the working directory of SER server.",
00443 0
00444 };
00445
00446
00447 static void core_pwd(rpc_t* rpc, void* c)
00448 {
00449 char *cwd_buf;
00450 int max_len;
00451
00452 max_len = pathmax();
00453 cwd_buf = pkg_malloc(max_len);
00454 if (!cwd_buf) {
00455 ERR("core_pwd: No memory left\n");
00456 rpc->fault(c, 500, "Server Ran Out of Memory");
00457 return;
00458 }
00459
00460 if (getcwd(cwd_buf, max_len)) {
00461 rpc->add(c, "s", cwd_buf);
00462 } else {
00463 rpc->fault(c, 500, "getcwd Failed");
00464 }
00465 pkg_free(cwd_buf);
00466 }
00467
00468
00469 static const char* core_arg_doc[] = {
00470 "Returns the list of command line arguments used on SER startup.",
00471 0
00472 };
00473
00474
00475 static void core_arg(rpc_t* rpc, void* c)
00476 {
00477 int p;
00478
00479 for (p = 0; p < my_argc; p++) {
00480 if (rpc->add(c, "s", my_argv[p]) < 0) return;
00481 }
00482 }
00483
00484
00485 static const char* core_kill_doc[] = {
00486 "Sends the given signal to SER.",
00487 0
00488 };
00489
00490
00491 static void core_kill(rpc_t* rpc, void* c)
00492 {
00493 int sig_no = 15;
00494 rpc->scan(c, "d", &sig_no);
00495 rpc->send(c);
00496 kill(0, sig_no);
00497 }
00498
00499 static void core_shmmem(rpc_t* rpc, void* c)
00500 {
00501 struct mem_info mi;
00502 void *handle;
00503 char* param;
00504 long rs;
00505
00506 rs=0;
00507
00508 if (rpc->scan(c, "*s", ¶m)>0){
00509 switch(*param){
00510 case 'b':
00511 case 'B':
00512 rs=0;
00513 break;
00514 case 'k':
00515 case 'K':
00516 rs=10;
00517 break;
00518 case 'm':
00519 case 'M':
00520 rs=20;
00521 break;
00522 case 'g':
00523 case 'G':
00524 rs=30;
00525 break;
00526 default:
00527 rpc->fault(c, 500, "bad param, (use b|k|m|g)");
00528 return;
00529 }
00530 if (param[1] && ((param[1]!='b' && param[1]!='B') || param[2])){
00531 rpc->fault(c, 500, "bad param, (use b|k|m|g)");
00532 return;
00533 }
00534 }
00535 shm_info(&mi);
00536 rpc->add(c, "{", &handle);
00537 rpc->struct_add(handle, "dddddd",
00538 "total", (unsigned int)(mi.total_size>>rs),
00539 "free", (unsigned int)(mi.free>>rs),
00540 "used", (unsigned int)(mi.used>>rs),
00541 "real_used",(unsigned int)(mi.real_used>>rs),
00542 "max_used", (unsigned int)(mi.max_used>>rs),
00543 "fragments", (unsigned int)mi.total_frags
00544 );
00545 }
00546
00547 static const char* core_shmmem_doc[] = {
00548 "Returns shared memory info. It has an optional parameter that specifies"
00549 " the measuring unit: b - bytes (default), k or kb, m or mb, g or gb. "
00550 "Note: when using something different from bytes, the value is truncated.",
00551 0
00552 };
00553
00554
00555 #if defined(SF_MALLOC) || defined(LL_MALLOC)
00556 static void core_sfmalloc(rpc_t* rpc, void* c)
00557 {
00558 void *handle;
00559 int i,r;
00560 unsigned long frags, main_s_frags, main_b_frags, pool_frags;
00561 unsigned long misses;
00562 unsigned long max_misses;
00563 unsigned long max_frags;
00564 unsigned long max_mem;
00565 int max_frags_pool, max_frags_hash;
00566 int max_misses_pool, max_misses_hash;
00567 int max_mem_pool, max_mem_hash;
00568 unsigned long mem;
00569
00570 if (rpc->scan(c, "d", &r) >= 1) {
00571 if (r>=(int)SF_HASH_POOL_SIZE){
00572 rpc->fault(c, 500, "invalid hash number %d (max %d)",
00573 r, (unsigned int)SF_HASH_POOL_SIZE-1);
00574 return;
00575 }else if (r<0) goto all;
00576 rpc->add(c, "{", &handle);
00577 rpc->struct_add(handle, "dd",
00578 "hash ", r,
00579 "size ", r*SF_ROUNDTO);
00580 for (i=0; i<SFM_POOLS_NO; i++){
00581 rpc->struct_add(handle, "dddd",
00582 "pool ", i,
00583 "frags ", (unsigned int)shm_block->pool[i].pool_hash[r].no,
00584 "misses", (unsigned int)shm_block->pool[i].pool_hash[r].misses,
00585 "mem ", (unsigned int)shm_block->pool[i].pool_hash[r].no *
00586 r*SF_ROUNDTO
00587 );
00588 }
00589 }
00590 return;
00591 all:
00592 max_frags=max_misses=max_mem=0;
00593 max_frags_pool=max_frags_hash=0;
00594 max_misses_pool=max_misses_hash=0;
00595 max_mem_pool=max_mem_hash=0;
00596 pool_frags=0;
00597 for (i=0; i<SFM_POOLS_NO; i++){
00598 frags=0;
00599 misses=0;
00600 mem=0;
00601 for (r=0; r<SF_HASH_POOL_SIZE; r++){
00602 frags+=shm_block->pool[i].pool_hash[r].no;
00603 misses+=shm_block->pool[i].pool_hash[r].misses;
00604 mem+=shm_block->pool[i].pool_hash[r].no*r*SF_ROUNDTO;
00605 if (shm_block->pool[i].pool_hash[r].no>max_frags){
00606 max_frags=shm_block->pool[i].pool_hash[r].no;
00607 max_frags_pool=i;
00608 max_frags_hash=r;
00609 }
00610 if (shm_block->pool[i].pool_hash[r].misses>max_misses){
00611 max_misses=shm_block->pool[i].pool_hash[r].misses;
00612 max_misses_pool=i;
00613 max_misses_hash=r;
00614 }
00615 if (shm_block->pool[i].pool_hash[r].no*r*SF_ROUNDTO>max_mem){
00616 max_mem=shm_block->pool[i].pool_hash[r].no*r*SF_ROUNDTO;
00617 max_mem_pool=i;
00618 max_mem_hash=r;
00619 }
00620 }
00621 rpc->add(c, "{", &handle);
00622 rpc->struct_add(handle, "dddddd",
00623 "pool ", i,
00624 "frags ", (unsigned int)frags,
00625 "t. misses", (unsigned int)misses,
00626 "mem ", (unsigned int)mem,
00627 "missed", (unsigned int)shm_block->pool[i].missed,
00628 "hits", (unsigned int)shm_block->pool[i].hits
00629 );
00630 pool_frags+=frags;
00631 }
00632 main_s_frags=0;
00633 for (r=0; r<SF_HASH_POOL_SIZE; r++){
00634 main_s_frags+=shm_block->free_hash[r].no;
00635 }
00636 main_b_frags=0;
00637 for (; r<SF_HASH_SIZE; r++){
00638 main_b_frags+=shm_block->free_hash[r].no;
00639 }
00640 rpc->add(c, "{", &handle);
00641 rpc->struct_add(handle, "ddddddddddddd",
00642 "max_frags ", (unsigned int)max_frags,
00643 "max_frags_pool ", max_frags_pool,
00644 "max_frags_hash", max_frags_hash,
00645 "max_misses ", (unsigned int)max_misses,
00646 "max_misses_pool", max_misses_pool,
00647 "max_misses_hash", max_misses_hash,
00648 "max_mem ", (unsigned int)max_mem,
00649 "max_mem_pool ", max_mem_pool,
00650 "max_mem_hash ", max_mem_hash,
00651 "in_pools_frags ", (unsigned int)pool_frags,
00652 "main_s_frags ", (unsigned int)main_s_frags,
00653 "main_b_frags ", (unsigned int)main_b_frags,
00654 "main_frags ", (unsigned int)(main_b_frags+main_s_frags)
00655 );
00656 }
00657
00658
00659
00660 static const char* core_sfmalloc_doc[] = {
00661 "Returns sfmalloc debugging info.",
00662 0
00663 };
00664
00665 #endif
00666
00667
00668
00669 static const char* core_tcpinfo_doc[] = {
00670 "Returns tcp related info.",
00671 0
00672 };
00673
00674 static void core_tcpinfo(rpc_t* rpc, void* c)
00675 {
00676 #ifdef USE_TCP
00677 void *handle;
00678 struct tcp_gen_info ti;
00679
00680 if (!tcp_disable){
00681 tcp_get_info(&ti);
00682 rpc->add(c, "{", &handle);
00683 rpc->struct_add(handle, "dddddd",
00684 "readers", ti.tcp_readers,
00685 "max_connections", ti.tcp_max_connections,
00686 "max_tls_connections", ti.tls_max_connections,
00687 "opened_connections", ti.tcp_connections_no,
00688 "opened_tls_connections", ti.tls_connections_no,
00689 "write_queued_bytes", ti.tcp_write_queued
00690 );
00691 }else{
00692 rpc->fault(c, 500, "tcp support disabled");
00693 }
00694 #else
00695 rpc->fault(c, 500, "tcp support not compiled");
00696 #endif
00697 }
00698
00699
00700
00701 static const char* core_tcp_options_doc[] = {
00702 "Returns active tcp options.",
00703 0
00704 };
00705
00706 static void core_tcp_options(rpc_t* rpc, void* c)
00707 {
00708 #ifdef USE_TCP
00709 void *handle;
00710 struct cfg_group_tcp t;
00711
00712 if (!tcp_disable){
00713 tcp_options_get(&t);
00714 rpc->add(c, "{", &handle);
00715 rpc->struct_add(handle, "ddddddddddddddddddddddd",
00716 "connect_timeout", t.connect_timeout_s,
00717 "send_timeout", TICKS_TO_S(t.send_timeout),
00718 "connection_lifetime", TICKS_TO_S(t.con_lifetime),
00719 "max_connections(soft)", t.max_connections,
00720 "max_tls_connections(soft)", t.max_tls_connections,
00721 "no_connect", t.no_connect,
00722 "fd_cache", t.fd_cache,
00723 "async", t.async,
00724 "connect_wait", t.tcp_connect_wait,
00725 "conn_wq_max", t.tcpconn_wq_max,
00726 "wq_max", t.tcp_wq_max,
00727 "defer_accept", t.defer_accept,
00728 "delayed_ack", t.delayed_ack,
00729 "syncnt", t.syncnt,
00730 "linger2", t.linger2,
00731 "keepalive", t.keepalive,
00732 "keepidle", t.keepidle,
00733 "keepintvl", t.keepintvl,
00734 "keepcnt", t.keepcnt,
00735 "crlf_ping", t.crlf_ping,
00736 "accept_aliases", t.accept_aliases,
00737 "alias_flags", t.alias_flags,
00738 "new_conn_alias_flags", t.new_conn_alias_flags
00739 );
00740 }else{
00741 rpc->fault(c, 500, "tcp support disabled");
00742 }
00743 #else
00744 rpc->fault(c, 500, "tcp support not compiled");
00745 #endif
00746 }
00747
00748
00749 static const char* core_tcp_list_doc[] = {
00750 "Returns tcp connections details.",
00751 0
00752 };
00753
00754 extern gen_lock_t* tcpconn_lock;
00755 extern struct tcp_connection** tcpconn_id_hash;
00756
00757 static void core_tcp_list(rpc_t* rpc, void* c)
00758 {
00759 #ifdef USE_TCP
00760 char src_ip[IP_ADDR_MAX_STR_SIZE];
00761 char dst_ip[IP_ADDR_MAX_STR_SIZE];
00762 void* handle;
00763 char* state;
00764 char* type;
00765 struct tcp_connection* con;
00766 int i, len, timeout;
00767
00768 TCPCONN_LOCK;
00769 for(i = 0; i < TCP_ID_HASH_SIZE; i++) {
00770 for (con = tcpconn_id_hash[i]; con; con = con->id_next) {
00771 rpc->add(c, "{", &handle);
00772
00773 if (con->rcv.proto == PROTO_TCP)
00774 type = "TCP";
00775 else if (con->rcv.proto == PROTO_TCP)
00776 type = "TLS";
00777 else
00778 type = "UNKNOWN";
00779
00780 if ((len = ip_addr2sbuf(&con->rcv.src_ip, src_ip, sizeof(src_ip)))
00781 == 0)
00782 BUG("failed to convert source ip");
00783 src_ip[len] = 0;
00784 if ((len = ip_addr2sbuf(&con->rcv.dst_ip, dst_ip, sizeof(dst_ip)))
00785 == 0)
00786 BUG("failed to convert destination ip");
00787 dst_ip[len] = 0;
00788 timeout = TICKS_TO_S(con->timeout - get_ticks_raw());
00789 switch(con->state) {
00790 case S_CONN_ERROR:
00791 state = "CONN_ERROR";
00792 break;
00793 case S_CONN_BAD:
00794 state = "CONN_BAD";
00795 break;
00796 case S_CONN_OK:
00797 state = "CONN_OK";
00798 break;
00799 case S_CONN_INIT:
00800 state = "CONN_INIT";
00801 break;
00802 case S_CONN_EOF:
00803 state = "CONN_EOF";
00804 break;
00805 case S_CONN_ACCEPT:
00806 state = "CONN_ACCEPT";
00807 break;
00808 case S_CONN_CONNECT:
00809 state = "CONN_CONNECT";
00810 break;
00811 default:
00812 state = "UNKNOWN";
00813 }
00814 rpc->struct_add(handle, "dssdsdsd",
00815 "id", con->id,
00816 "type", type,
00817 "state", state,
00818 "timeout", timeout,
00819 "src_ip", src_ip,
00820 "src_port", con->rcv.src_port,
00821 "dst_ip", dst_ip,
00822 "dst_port", con->rcv.dst_port);
00823 }
00824 }
00825 TCPCONN_UNLOCK;
00826 #else
00827 rpc->fault(c, 500, "tcp support not compiled");
00828 #endif
00829 }
00830
00831
00832
00833 static const char* core_sctp_options_doc[] = {
00834 "Returns active sctp options. With one parameter"
00835 " it returns the sctp options set in the kernel for a specific socket"
00836 "(debugging), with 0 filled in for non-kernel related options."
00837 " The parameter can be: \"default\" | \"first\" | address[:port] ."
00838 " With no parameters it returns ser's idea of the current sctp options"
00839 " (intended non-debugging use).",
00840
00841 0
00842 };
00843
00844 static void core_sctp_options(rpc_t* rpc, void* c)
00845 {
00846 #ifdef USE_SCTP
00847 void *handle;
00848 struct cfg_group_sctp t;
00849 char* param;
00850 struct socket_info* si;
00851 char* host;
00852 str hs;
00853 int hlen;
00854 int port;
00855 int proto;
00856
00857 param=0;
00858 if (!sctp_disable){
00859
00860 if (rpc->scan(c, "*s", ¶m)>0){
00861 si=0;
00862 if (strcasecmp(param, "default")==0){
00863 si=sendipv4_sctp?sendipv4_sctp:sendipv6_sctp;
00864 }else if (strcasecmp(param, "first")==0){
00865 si=sctp_listen;
00866 }else{
00867 if (parse_phostport(param, &host, &hlen, &port, &proto)!=0){
00868 rpc->fault(c, 500, "bad param (use address, address:port,"
00869 " default or first)");
00870 return;
00871 }
00872 if (proto && proto!=PROTO_SCTP){
00873 rpc->fault(c, 500, "bad protocol in param (only SCTP"
00874 " allowed)");
00875 return;
00876 }
00877 hs.s=host;
00878 hs.len=hlen;
00879 si=grep_sock_info(&hs, port, PROTO_SCTP);
00880 if (si==0){
00881 rpc->fault(c, 500, "not listening on sctp %s", param);
00882 return;
00883 }
00884 }
00885 if (si==0 || si->socket==-1){
00886 rpc->fault(c, 500, "could not find a sctp socket");
00887 return;
00888 }
00889 memset(&t, 0, sizeof(t));
00890 if (sctp_get_cfg_from_sock(si->socket, &t)!=0){
00891 rpc->fault(c, 500, "failed to get socket options");
00892 return;
00893 }
00894 }else{
00895 sctp_options_get(&t);
00896 }
00897 rpc->add(c, "{", &handle);
00898 rpc->struct_add(handle, "ddddddddddddddddddd",
00899 "sctp_socket_rcvbuf", t.so_rcvbuf,
00900 "sctp_socket_sndbuf", t.so_sndbuf,
00901 "sctp_autoclose", t.autoclose,
00902 "sctp_send_ttl", t.send_ttl,
00903 "sctp_send_retries", t.send_retries,
00904 "sctp_assoc_tracking", t.assoc_tracking,
00905 "sctp_assoc_reuse", t.assoc_reuse,
00906 "sctp_max_assocs", t.max_assocs,
00907 "sctp_srto_initial", t.srto_initial,
00908 "sctp_srto_max", t.srto_max,
00909 "sctp_srto_min", t.srto_min,
00910 "sctp_asocmaxrxt", t.asocmaxrxt,
00911 "sctp_init_max_attempts", t.init_max_attempts,
00912 "sctp_init_max_timeo",t.init_max_timeo,
00913 "sctp_hbinterval", t.hbinterval,
00914 "sctp_pathmaxrxt", t.pathmaxrxt,
00915 "sctp_sack_delay", t.sack_delay,
00916 "sctp_sack_freq", t.sack_freq,
00917 "sctp_max_burst", t.max_burst
00918 );
00919 }else{
00920 rpc->fault(c, 500, "sctp support disabled");
00921 }
00922 #else
00923 rpc->fault(c, 500, "sctp support not compiled");
00924 #endif
00925 }
00926
00927
00928
00929 static const char* core_sctpinfo_doc[] = {
00930 "Returns sctp related info.",
00931 0
00932 };
00933
00934 static void core_sctpinfo(rpc_t* rpc, void* c)
00935 {
00936 #ifdef USE_SCTP
00937 void *handle;
00938 struct sctp_gen_info i;
00939
00940 if (!sctp_disable){
00941 sctp_get_info(&i);
00942 rpc->add(c, "{", &handle);
00943 rpc->struct_add(handle, "ddd",
00944 "opened_connections", i.sctp_connections_no,
00945 "tracked_connections", i.sctp_tracked_no,
00946 "total_connections", i.sctp_total_connections
00947 );
00948 }else{
00949 rpc->fault(c, 500, "sctp support disabled");
00950 }
00951 #else
00952 rpc->fault(c, 500, "sctp support not compiled");
00953 #endif
00954 }
00955
00956
00957
00958
00959 static const char* core_udp4rawinfo_doc[] = {
00960 "Returns udp4_raw related info.",
00961 0
00962 };
00963
00964 static void core_udp4rawinfo(rpc_t* rpc, void* c)
00965 {
00966 #ifdef USE_RAW_SOCKS
00967 void *handle;
00968
00969 rpc->add(c, "{", &handle);
00970 rpc->struct_add(handle, "ddd",
00971 "udp4_raw", cfg_get(core, core_cfg, udp4_raw),
00972 "udp4_raw_mtu", cfg_get(core, core_cfg, udp4_raw_mtu),
00973 "udp4_raw_ttl", cfg_get(core, core_cfg, udp4_raw_ttl)
00974 );
00975 #else
00976 rpc->fault(c, 500, "udp4_raw mode support not compiled");
00977 #endif
00978 }
00979
00983 static const char* core_aliases_list_doc[] = {
00984 "List local SIP server host aliases",
00985 0
00986 };
00987
00991 static void core_aliases_list(rpc_t* rpc, void* c)
00992 {
00993 void *hr;
00994 void *ha;
00995 struct host_alias* a;
00996
00997 rpc->add(c, "{", &hr);
00998 rpc->struct_add(hr, "s",
00999 "myself_callbacks", is_check_self_func_list_set()?"yes":"no");
01000 for(a=aliases; a; a=a->next) {
01001 rpc->struct_add(hr, "{", "alias", &ha);
01002 rpc->struct_add(ha, "sS",
01003 "proto", proto2a(a->proto),
01004 "address", &a->alias
01005 );
01006 if (a->port)
01007 rpc->struct_add(ha, "d",
01008 "port", a->port);
01009 else
01010 rpc->struct_add(ha, "s",
01011 "port", "*");
01012 }
01013 }
01014
01018 static const char* core_sockets_list_doc[] = {
01019 "List local SIP server listen sockets",
01020 0
01021 };
01022
01026 static void core_sockets_list(rpc_t* rpc, void* c)
01027 {
01028 void *hr;
01029 void *ha;
01030 struct socket_info *si;
01031 struct socket_info** list;
01032 struct addr_info* ai;
01033 unsigned short proto;
01034
01035 proto=PROTO_UDP;
01036 rpc->add(c, "{", &hr);
01037 do{
01038 list=get_sock_info_list(proto);
01039 for(si=list?*list:0; si; si=si->next){
01040 rpc->struct_add(hr, "{", "socket", &ha);
01041 if (si->addr_info_lst){
01042 rpc->struct_add(ha, "ss",
01043 "proto", get_proto_name(proto),
01044 "address", si->address_str.s);
01045 for (ai=si->addr_info_lst; ai; ai=ai->next)
01046 rpc->struct_add(ha, "ss",
01047 "address", ai->address_str.s);
01048 rpc->struct_add(ha, "sss",
01049 "proto", si->port_no_str.s,
01050 "mcast", si->flags & SI_IS_MCAST ? "yes" : "no",
01051 "mhomed", si->flags & SI_IS_MHOMED ? "yes" : "no");
01052 } else {
01053 printf(" %s: %s",
01054 get_proto_name(proto),
01055 si->name.s);
01056 rpc->struct_add(ha, "ss",
01057 "proto", get_proto_name(proto),
01058 "address", si->name.s);
01059 if (!si->flags & SI_IS_IP)
01060 rpc->struct_add(ha, "ss",
01061 "ipaddress", si->address_str.s);
01062 rpc->struct_add(ha, "sss",
01063 "proto", si->port_no_str.s,
01064 "mcast", si->flags & SI_IS_MCAST ? "yes" : "no",
01065 "mhomed", si->flags & SI_IS_MHOMED ? "yes" : "no");
01066 }
01067 }
01068 } while((proto=next_proto(proto)));
01069 }
01070
01071
01072
01073
01074
01075 static rpc_export_t core_rpc_methods[] = {
01076 {"system.listMethods", system_listMethods, system_listMethods_doc, RET_ARRAY},
01077 {"system.methodSignature", system_methodSignature, system_methodSignature_doc, 0 },
01078 {"system.methodHelp", system_methodHelp, system_methodHelp_doc, 0 },
01079 {"core.prints", core_prints, core_prints_doc,
01080 RET_ARRAY},
01081 {"core.printi", core_printi, core_printi_doc,
01082 RET_ARRAY},
01083 {"core.echo", core_echo, core_echo_doc,
01084 RET_ARRAY},
01085 {"core.version", core_version, core_version_doc,
01086 0 },
01087 {"core.flags", core_flags, core_flags_doc,
01088 0 },
01089 {"core.info", core_info, core_info_doc,
01090 0 },
01091 {"core.uptime", core_uptime, core_uptime_doc, 0 },
01092 {"core.ps", core_ps, core_ps_doc, RET_ARRAY},
01093 {"core.psx", core_psx, core_psx_doc, 0},
01094 {"core.pwd", core_pwd, core_pwd_doc, RET_ARRAY},
01095 {"core.arg", core_arg, core_arg_doc, RET_ARRAY},
01096 {"core.kill", core_kill, core_kill_doc, 0 },
01097 {"core.shmmem", core_shmmem, core_shmmem_doc, 0 },
01098 #if defined(SF_MALLOC) || defined(LL_MALLOC)
01099 {"core.sfmalloc", core_sfmalloc, core_sfmalloc_doc, 0},
01100 #endif
01101 {"core.tcp_info", core_tcpinfo, core_tcpinfo_doc, 0},
01102 {"core.tcp_options", core_tcp_options, core_tcp_options_doc,0},
01103 {"core.tcp_list", core_tcp_list, core_tcp_list_doc,0},
01104 {"core.sctp_options", core_sctp_options, core_sctp_options_doc,
01105 0},
01106 {"core.sctp_info", core_sctpinfo, core_sctpinfo_doc, 0},
01107 {"core.udp4_raw_info", core_udp4rawinfo, core_udp4rawinfo_doc,
01108 0},
01109 {"core.aliases_list", core_aliases_list, core_aliases_list_doc, 0},
01110 {"core.sockets_list", core_sockets_list, core_sockets_list_doc, 0},
01111 #ifdef USE_DNS_CACHE
01112 {"dns.mem_info", dns_cache_mem_info, dns_cache_mem_info_doc,
01113 0 },
01114 {"dns.debug", dns_cache_debug, dns_cache_debug_doc,
01115 0 },
01116 {"dns.debug_all", dns_cache_debug_all, dns_cache_debug_all_doc,
01117 0 },
01118 {"dns.view", dns_cache_view, dns_cache_view_doc,
01119 0 },
01120 {"dns.lookup", dns_cache_rpc_lookup, dns_cache_rpc_lookup_doc,
01121 0 },
01122 {"dns.delete_all", dns_cache_delete_all, dns_cache_delete_all_doc,
01123 0 },
01124 {"dns.delete_all_force", dns_cache_delete_all_force, dns_cache_delete_all_force_doc,
01125 0 },
01126 {"dns.add_a", dns_cache_add_a, dns_cache_add_a_doc,
01127 0 },
01128 {"dns.add_aaaa", dns_cache_add_aaaa, dns_cache_add_aaaa_doc,
01129 0 },
01130 {"dns.add_srv", dns_cache_add_srv, dns_cache_add_srv_doc,
01131 0 },
01132 {"dns.delete_a", dns_cache_delete_a, dns_cache_delete_a_doc,
01133 0 },
01134 {"dns.delete_aaaa", dns_cache_delete_aaaa,
01135 dns_cache_delete_aaaa_doc, 0 },
01136 {"dns.delete_srv", dns_cache_delete_srv,
01137 dns_cache_delete_srv_doc, 0 },
01138 {"dns.delete_naptr", dns_cache_delete_naptr,
01139 dns_cache_delete_naptr_doc, 0 },
01140 {"dns.delete_cname", dns_cache_delete_cname,
01141 dns_cache_delete_cname_doc, 0 },
01142 {"dns.delete_txt", dns_cache_delete_txt,
01143 dns_cache_delete_txt_doc, 0 },
01144 {"dns.delete_ebl", dns_cache_delete_ebl,
01145 dns_cache_delete_ebl_doc, 0 },
01146 {"dns.delete_ptr", dns_cache_delete_ptr,
01147 dns_cache_delete_ptr_doc, 0 },
01148 #ifdef USE_DNS_CACHE_STATS
01149 {"dns.stats_get", dns_cache_stats_get, dns_cache_stats_get_doc,
01150 0 },
01151 #endif
01152 #ifdef DNS_WATCHDOG_SUPPORT
01153 {"dns.set_server_state", dns_set_server_state_rpc,
01154 dns_set_server_state_doc, 0 },
01155 {"dns.get_server_state", dns_get_server_state_rpc,
01156 dns_get_server_state_doc, 0 },
01157 #endif
01158 #endif
01159 #ifdef USE_DST_BLACKLIST
01160 {"dst_blacklist.mem_info", dst_blst_mem_info, dst_blst_mem_info_doc,
01161 0 },
01162 {"dst_blacklist.debug", dst_blst_debug, dst_blst_debug_doc,
01163 0 },
01164 {"dst_blacklist.view", dst_blst_view, dst_blst_view_doc,
01165 0 },
01166 {"dst_blacklist.delete_all", dst_blst_delete_all, dst_blst_delete_all_doc,
01167 0 },
01168 {"dst_blacklist.add", dst_blst_add, dst_blst_add_doc,
01169 0 },
01170 #ifdef USE_DST_BLACKLIST_STATS
01171 {"dst_blacklist.stats_get", dst_blst_stats_get, dst_blst_stats_get_doc, 0},
01172 #endif
01173 #endif
01174 {0, 0, 0, 0}
01175 };
01176
01177
01178
01179 int register_core_rpcs(void)
01180 {
01181 int i;
01182
01183 i=rpc_register_array(core_rpc_methods);
01184 if (i<0){
01185 BUG("failed to register core RPCs\n");
01186 goto error;
01187 }else if (i>0){
01188 ERR("%d duplicate RPCs name detected while registering core RPCs\n",
01189 i);
01190 goto error;
01191 }
01192 return 0;
01193 error:
01194 return -1;
01195 }
01196
01197
01198
01199 int rpc_init_time(void)
01200 {
01201 char *t;
01202 t=ctime(&up_since);
01203 if (strlen(t)+1>=MAX_CTIME_LEN) {
01204 ERR("Too long data %d\n", (int)strlen(t));
01205 return -1;
01206 }
01207 memcpy(up_since_ctime,t,strlen(t)+1);
01208 return 0;
01209 }