core_cmd.c 29 KB

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