• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • Directories
  • File List
  • Globals

core_cmd.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * Copyright (C) 2005 iptelorg GmbH
00005  *
00006  * This file is part of SIP-router, a free SIP server.
00007  *
00008  * SIP-router is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * SIP-router is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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.",    /* Documentation string */
00078         0                      /* Method signature(s) */
00079 };
00080 static const char* dns_cache_debug_doc[] = {
00081         "dns debug  info.",    /* Documentation string */
00082         0                      /* Method signature(s) */
00083 };
00084 
00085 static const char* dns_cache_debug_all_doc[] = {
00086         "complete dns debug  dump",    /* Documentation string */
00087         0                              /* Method signature(s) */
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 /* USE_DNS_CACHE_STATS */
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)",    /* Documentation string */
00180         0                              /* Method signature(s) */
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)",  /* Documentation string */
00188         0                               /* Method signature(s) */
00189 };
00190 
00191 #endif /* DNS_WATCHDOG_SUPPORT */
00192 #endif /* USE_DNS_CACHE */
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.",  /* Documentation string */
00202         0                                    /* Method signature(s) */
00203 };
00204 static const char* dst_blst_debug_doc[] = {
00205         "dst blacklist  debug  info.",  /* Documentation string */
00206         0                               /* Method signature(s) */
00207 };
00208 static const char* dst_blst_view_doc[] = {
00209         "dst blacklist dump in human-readable format.",  /* Documentation string */
00210         0                               /* Method signature(s) */
00211 };
00212 static const char* dst_blst_delete_all_doc[] = {
00213         "Deletes all the entries from the dst blacklist except the permanent ones.",  /* Documentation string */
00214         0                               /* Method signature(s) */
00215 };
00216 static const char* dst_blst_add_doc[] = {
00217         "Adds a new entry to the dst blacklist.",  /* Documentation string */
00218         0                               /* Method signature(s) */
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 /* USE_DST_BLACKLIST_STATS */
00228 
00229 #endif
00230 
00231 
00232 
00233 #define MAX_CTIME_LEN 128
00234 
00235 /* up time */
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.",  /* Documentation string */
00241         0                                                  /* Method signature(s) */
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.",  /* Documentation string */
00255         0                                      /* Method signature(s) */
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.",  /* Documentation string */
00266         0                                           /* Method signature(s) */
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.",   /* Documentation string */
00295         0                                             /* Method signature(s) */
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.",  /* Documentation string */
00309         0                                             /* Method signature(s) */
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.",              /* Documentation string */
00323         0                                             /* Method signature(s) */
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.", /* Documentation string */
00337         0                                           /* Method signature(s) */
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.", /* Documentation string */
00349         0                             /* Method signature(s) */
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.",     /* Documentation string */
00362         0                             /* Method signature(s) */
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.",  /* Documentation string */
00381         0                                 /* Method signature(s) */
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         /* no need for a float here (unless you're concerned that your uptime)
00396         rpc->struct_add(s, "f", "uptime",  difftime(now, up_since));
00397         */
00398         /* on posix system we can substract time_t directly */
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.",  /* Documentation string */
00405         0                                                     /* Method signature(s) */
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                 /* Documentation string */
00422         0       /* Method signature(s) */
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.",    /* Documentation string */
00443         0                                                  /* Method signature(s) */
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.",  /* Documentation string */
00471         0                                                                   /* Method signature(s) */
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.",  /* Documentation string */
00487         0                                  /* Method signature(s) */
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         /* look for optional size/divisor parameter */
00508         if (rpc->scan(c, "*s", &param)>0){
00509                 switch(*param){
00510                         case 'b':
00511                         case 'B':
00512                                 rs=0;
00513                                 break;
00514                         case 'k':
00515                         case 'K':
00516                                 rs=10; /* K -> 1024 */
00517                                 break;
00518                         case 'm':
00519                         case 'M':
00520                                 rs=20; /* M -> 1048576 */
00521                                 break;
00522                         case 'g':
00523                         case 'G':
00524                                 rs=30; /* G -> 1024M */
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                               /* Method signature(s) */
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.",  /* Documentation string */
00662         0                                     /* Method signature(s) */
00663 };
00664 
00665 #endif
00666 
00667 
00668 
00669 static const char* core_tcpinfo_doc[] = {
00670         "Returns tcp related info.",    /* Documentation string */
00671         0                               /* Method signature(s) */
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.",    /* Documentation string */
00703         0                                 /* Method signature(s) */
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.",    /* Documentation string */
00751         0                               /* Method signature(s) */
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                         /* tcp data */
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         /* Documentation string */
00841         0                                 /* Method signature(s) */
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                 /* look for optional socket parameter */
00860                 if (rpc->scan(c, "*s", &param)>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.",    /* Documentation string */
00931         0                               /* Method signature(s) */
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.",    /* Documentation string */
00961         0                                     /* Method signature(s) */
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 /* USE_RAW_SOCKS */
00976         rpc->fault(c, 500, "udp4_raw mode support not compiled");
00977 #endif /* USE_RAW_SOCKS */
00978 }
00979 
00983 static const char* core_aliases_list_doc[] = {
00984         "List local SIP server host aliases",    /* Documentation string */
00985         0                                     /* Method signature(s) */
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",    /* Documentation string */
01020         0                                     /* Method signature(s) */
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  * RPC Methods exported by this module
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 /* USE_DNS_CACHE_STATS */
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 /* USE_DST_BLACKLIST_STATS */
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 }

Generated on Tue May 22 2012 13:10:04 for SIP Router by  doxygen 1.7.1