core_cmd.c 25 KB

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