2
0

core_cmd.c 32 KB

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