ctl.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  26. */
  27. /* History:
  28. * --------
  29. * 2006-02-08 created by andrei
  30. * 2007-01-18 use PROC_RPC rank when forking (andrei)
  31. */
  32. #include "../../sr_module.h"
  33. #include "../../ut.h"
  34. #include "../../dprint.h"
  35. #include "../../pt.h"
  36. #include "../../cfg/cfg_struct.h"
  37. #include "ctrl_socks.h"
  38. #include "io_listener.h"
  39. #include <sys/types.h>
  40. #include <sys/socket.h> /* socketpair */
  41. #include <unistd.h> /* close, fork, getpid */
  42. #include <stdio.h> /* snprintf */
  43. #include <string.h> /* strerror */
  44. #include <errno.h>
  45. MODULE_VERSION
  46. #include "ctl_defaults.h"
  47. #include "binrpc_run.h"
  48. #ifdef USE_FIFO
  49. #include "fifo_server.h"
  50. #endif
  51. static int mod_init(void);
  52. static int mod_child(int rank);
  53. static void mod_destroy(void);
  54. static cmd_export_t cmds[]={
  55. {0,0,0,0,0}
  56. };
  57. static int usock_mode=0600; /* permissions, default rw-------*/
  58. static int usock_uid=-1; /* username and group for the unix sockets*/
  59. static int usock_gid=-1;
  60. /* if set try to automatically convert values to the requested type in
  61. rpc->scan (default: not set) */
  62. extern int autoconvert;
  63. extern int binrpc_max_body_size;
  64. extern int binrpc_struct_max_body_size;
  65. static int add_binrpc_socket(modparam_t type, void * val);
  66. #ifdef USE_FIFO
  67. static int add_fifo_socket(modparam_t type, void * val);
  68. #endif
  69. static int fix_user(modparam_t type, void * val);
  70. static int fix_group(modparam_t type, void * val);
  71. static void ctrl_listen_ls_rpc(rpc_t* rpc, void* ctx);
  72. void io_listen_who_rpc(rpc_t* rpc, void* ctx);
  73. void io_listen_conn_rpc(rpc_t* rpc, void* ctx);
  74. static char* io_listen_who_doc[]={ "list open connections", 0 };
  75. static char* io_listen_conn_doc[]={ "returns number of open connections", 0 };
  76. static char* ctl_listen_ls_doc[]={ "list ctl listen sockets", 0 };
  77. static rpc_export_t ctl_rpc[]={
  78. {"ctl.who", io_listen_who_rpc, (const char**)io_listen_who_doc, 0},
  79. {"ctl.connections", io_listen_conn_rpc,(const char**)io_listen_conn_doc,0},
  80. {"ctl.listen", ctrl_listen_ls_rpc,(const char**)ctl_listen_ls_doc, 0},
  81. { 0, 0, 0, 0}
  82. };
  83. static param_export_t params[]={
  84. #ifdef USE_FIFO
  85. {"fifo", PARAM_STRING|PARAM_USE_FUNC, (void*) add_fifo_socket },
  86. #endif
  87. {"binrpc", PARAM_STRING|PARAM_USE_FUNC, (void*) add_binrpc_socket},
  88. {"mode", PARAM_INT, &usock_mode },
  89. {"user", PARAM_STRING|PARAM_USE_FUNC, fix_user },
  90. {"group", PARAM_STRING|PARAM_USE_FUNC, fix_group },
  91. {"autoconversion", PARAM_INT, &autoconvert },
  92. {"binrpc_max_body_size", PARAM_INT, &binrpc_max_body_size },
  93. {"binrpc_struct_max_body_size", PARAM_INT, &binrpc_struct_max_body_size },
  94. {0,0,0}
  95. }; /* no params */
  96. struct module_exports exports= {
  97. "ctl",
  98. cmds,
  99. ctl_rpc, /* RPC methods */
  100. params,
  101. mod_init, /* module initialization function */
  102. 0, /* response function */
  103. mod_destroy, /* destroy function */
  104. 0, /* on_cancel function */
  105. mod_child, /* per-child init function */
  106. };
  107. static struct id_list* listen_lst=0; /* binrpc sockets name list */
  108. static struct ctrl_socket* ctrl_sock_lst=0;
  109. static int fd_no=0; /* number of fd used */
  110. static int add_binrpc_socket(modparam_t type, void * val)
  111. {
  112. char *s;
  113. struct id_list* id;
  114. if ((type & PARAM_STRING)==0){
  115. LOG(L_CRIT, "BUG: ctl: add_binrpc_socket: bad parameter type %d\n",
  116. type);
  117. goto error;
  118. }
  119. s=(char*)val;
  120. id=parse_listen_id(s, strlen(s), UDP_SOCK); /* default udp proto */
  121. if (id==0){
  122. LOG(L_ERR, "ERROR: ctl: bad listen socket: \"%s\"\n", s);
  123. goto error;
  124. }
  125. id->data_proto=P_BINRPC;
  126. id->next=listen_lst;
  127. listen_lst=id;
  128. return 0;
  129. error:
  130. return -1;
  131. }
  132. #ifdef USE_FIFO
  133. static int add_fifo_socket(modparam_t type, void * val)
  134. {
  135. char *s;
  136. struct id_list* id;
  137. if ((type & PARAM_STRING)==0){
  138. LOG(L_CRIT, "BUG: ctl: add_fifo: bad parameter type %d\n",
  139. type);
  140. goto error;
  141. }
  142. s=(char*)val;
  143. id=parse_listen_id(s, strlen(s), FIFO_SOCK); /* default udp proto */
  144. if (id==0){
  145. LOG(L_ERR, "ERROR: ctl: bad fifo: \"%s\"\n", s);
  146. goto error;
  147. }
  148. id->data_proto=P_FIFO;
  149. id->next=listen_lst;
  150. listen_lst=id;
  151. return 0;
  152. error:
  153. return -1;
  154. }
  155. #endif
  156. static int fix_user(modparam_t type, void * val)
  157. {
  158. char* s;
  159. if ((type & PARAM_STRING)==0){
  160. LOG(L_CRIT, "BUG: ctl: fix_user: bad parameter type %d\n",
  161. type);
  162. goto error;
  163. }
  164. s=(char*)val;
  165. if (user2uid(&usock_uid, 0, s)<0){
  166. LOG(L_ERR, "ERROR: ctl: bad user name/uid number %s\n", s);
  167. goto error;
  168. }
  169. return 0;
  170. error:
  171. return -1;
  172. }
  173. static int fix_group(modparam_t type, void * val)
  174. {
  175. char* s;
  176. if ((type & PARAM_STRING)==0){
  177. LOG(L_CRIT, "BUG: ctl: fix_group: bad parameter type %d\n",
  178. type);
  179. goto error;
  180. }
  181. s=(char*)val;
  182. if (group2gid(&usock_gid, s)<0){
  183. LOG(L_ERR, "ERROR: ctl: bad group name/gid number %s\n", s);
  184. goto error;
  185. }
  186. return 0;
  187. error:
  188. return -1;
  189. }
  190. static int mod_init(void)
  191. {
  192. struct id_list* l;
  193. binrpc_callbacks_init();
  194. if(binrpc_max_body_size<=0)
  195. binrpc_max_body_size = 4;
  196. if(binrpc_struct_max_body_size<=0)
  197. binrpc_struct_max_body_size = 1;
  198. binrpc_max_body_size *= 1024;
  199. binrpc_struct_max_body_size *= 1024;
  200. if (listen_lst==0) {
  201. add_binrpc_socket(PARAM_STRING, DEFAULT_CTL_SOCKET);
  202. }
  203. DBG("listening on:\n");
  204. for (l=listen_lst; l; l=l->next){
  205. fd_no++;
  206. switch(l->proto){
  207. case UNIXD_SOCK:
  208. DBG(" [%s:unix dgram] %s\n",
  209. payload_proto_name(l->data_proto), l->name);
  210. break;
  211. case UNIXS_SOCK:
  212. DBG(" [%s:unix stream] %s\n",
  213. payload_proto_name(l->data_proto), l->name);
  214. break;
  215. case UDP_SOCK:
  216. DBG(" [%s:udp] %s:%d\n",
  217. payload_proto_name(l->data_proto), l->name,
  218. l->port?l->port:DEFAULT_CTL_PORT);
  219. break;
  220. case TCP_SOCK:
  221. DBG(" [%s:tcp] %s:%d\n",
  222. payload_proto_name(l->data_proto), l->name,
  223. l->port?l->port:DEFAULT_CTL_PORT);
  224. break;
  225. #ifdef USE_FIFO
  226. case FIFO_SOCK:
  227. DBG(" [%s:fifo] %s\n",
  228. payload_proto_name(l->data_proto), l->name);
  229. fd_no++; /* fifos use 2 fds */
  230. break;
  231. #endif
  232. default:
  233. LOG(L_CRIT, "BUG: ctrl: listen protocol %d not supported\n",
  234. l->proto);
  235. goto error;
  236. }
  237. }
  238. /* open socket now, before suid */
  239. if (init_ctrl_sockets(&ctrl_sock_lst, listen_lst, DEFAULT_CTL_PORT,
  240. usock_mode, usock_uid, usock_gid)<0){
  241. LOG(L_ERR, "ERROR: ctl: mod_init: init ctrl. sockets failed\n");
  242. goto error;
  243. }
  244. if (ctrl_sock_lst){
  245. /* we will fork */
  246. register_procs(1); /* we will be creating an extra process */
  247. register_fds(fd_no);
  248. /* The child process will keep updating its local configuration */
  249. cfg_register_child(1);
  250. }
  251. #ifdef USE_FIFO
  252. fifo_rpc_init();
  253. #endif
  254. return 0;
  255. error:
  256. return -1;
  257. }
  258. static int mod_child(int rank)
  259. {
  260. int pid;
  261. struct ctrl_socket* cs;
  262. static int rpc_handler=0;
  263. /* do nothing from PROC_INIT, is the same as PROC_MAIN */
  264. if (rank==PROC_INIT)
  265. return 0;
  266. /* we want to fork(), but only from one process */
  267. if ((rank == PROC_MAIN ) && (ctrl_sock_lst)){ /* FIXME: no fork ?? */
  268. DBG("ctl: mod_child(%d), ctrl_sock_lst=%p\n", rank, ctrl_sock_lst);
  269. /* fork, but make sure we know not to close our own sockets when
  270. * ctl child_init will be called for the new child */
  271. rpc_handler=1;
  272. /* child should start with a correct estimated used fds number*/
  273. register_fds(MAX_IO_READ_CONNECTIONS);
  274. pid=fork_process(PROC_RPC, "ctl handler", 1);
  275. DBG("ctl: mod_child(%d), fork_process=%d, csl=%p\n",
  276. rank, pid, ctrl_sock_lst);
  277. if (pid<0){
  278. goto error;
  279. }
  280. if (pid == 0){ /* child */
  281. is_main=0;
  282. DBG("ctl: %d io_listen_loop(%d, %p)\n",
  283. rank, fd_no, ctrl_sock_lst);
  284. io_listen_loop(fd_no, ctrl_sock_lst);
  285. }else{ /* parent */
  286. /* not used in parent */
  287. register_fds(-MAX_IO_READ_CONNECTIONS);
  288. rpc_handler=0;
  289. }
  290. }
  291. if (rank!=PROC_RPC || !rpc_handler){
  292. /* close all the opened fds, we don't need them here */
  293. for (cs=ctrl_sock_lst; cs; cs=cs->next){
  294. close(cs->fd);
  295. cs->fd=-1;
  296. if (cs->write_fd!=-1){
  297. close(cs->write_fd);
  298. cs->write_fd=-1;
  299. }
  300. }
  301. if (rank!=PROC_MAIN){ /* we need the lists in main for on_exit cleanup,
  302. see mod_destroy */
  303. /* free memory, we don't need the lists anymore */
  304. free_ctrl_socket_list(ctrl_sock_lst);
  305. ctrl_sock_lst=0;
  306. free_id_list(listen_lst);
  307. listen_lst=0;
  308. }
  309. }
  310. return 0;
  311. error:
  312. return -1;
  313. }
  314. static void mod_destroy(void)
  315. {
  316. struct ctrl_socket* cs;
  317. /* close all the opened fds & unlink the files */
  318. for (cs=ctrl_sock_lst; cs; cs=cs->next){
  319. switch(cs->transport){
  320. case UNIXS_SOCK:
  321. case UNIXD_SOCK:
  322. close(cs->fd);
  323. cs->fd=-1;
  324. if (cs->write_fd!=-1){
  325. close(cs->write_fd);
  326. cs->write_fd=-1;
  327. }
  328. if (cs->name){
  329. if (unlink(cs->name)<0){
  330. LOG(L_ERR, "ERROR: ctl: could not delete unix"
  331. " socket %s: %s (%d)\n",
  332. cs->name, strerror(errno), errno);
  333. }
  334. }
  335. break;
  336. #ifdef USE_FIFO
  337. case FIFO_SOCK:
  338. destroy_fifo(cs->fd, cs->write_fd, cs->name);
  339. break;
  340. #endif
  341. default:
  342. close(cs->fd);
  343. cs->fd=-1;
  344. if (cs->write_fd!=-1){
  345. close(cs->write_fd);
  346. cs->write_fd=-1;
  347. }
  348. }
  349. }
  350. if (listen_lst){
  351. free_id_list(listen_lst);
  352. listen_lst=0;
  353. }
  354. if (ctrl_sock_lst){
  355. free_ctrl_socket_list(ctrl_sock_lst);
  356. ctrl_sock_lst=0;
  357. }
  358. }
  359. static void ctrl_listen_ls_rpc(rpc_t* rpc, void* ctx)
  360. {
  361. struct ctrl_socket* cs;
  362. for (cs=ctrl_sock_lst; cs; cs=cs->next){
  363. rpc->add(ctx, "ssss", payload_proto_name(cs->p_proto),
  364. socket_proto_name(cs->transport),
  365. cs->name, (cs->port)?int2str(cs->port, 0):"");
  366. }
  367. }