janssonrpc_srv.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. /**
  2. * Copyright (C) 2013 Flowroute LLC (flowroute.com)
  3. *
  4. * This file is part of Kamailio, a free SIP server.
  5. *
  6. * This file is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version
  10. *
  11. *
  12. * This file is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. *
  21. */
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <stdbool.h>
  25. #include <errno.h>
  26. #include <string.h>
  27. #include <fcntl.h>
  28. #include "../../sr_module.h"
  29. #include "../../route.h"
  30. #include "../../route_struct.h"
  31. #include "../../resolve.h"
  32. #include "../../parser/parse_param.h"
  33. #include "../../mem/mem.h"
  34. #include "../../lvalue.h"
  35. #include "../../str.h"
  36. #include "janssonrpc.h"
  37. #include "janssonrpc_srv.h"
  38. #include "janssonrpc_request.h"
  39. #include "janssonrpc_io.h"
  40. #include "janssonrpc_server.h"
  41. int refresh_srv(jsonrpc_srv_t* srv_obj)
  42. {
  43. DEBUG("Refreshing SRV for %.*s\n", STR(srv_obj->srv));
  44. int retval = 0;
  45. if(!srv_obj) {
  46. ERR("Trying to refresh NULL SRV\n");
  47. return -1;
  48. }
  49. unsigned int ttl = ABSOLUTE_MIN_SRV_TTL;
  50. str srv = srv_obj->srv;
  51. jsonrpc_server_group_t* conn_group = srv_obj->cgroup;
  52. if(!conn_group) {
  53. ERR("SRV (%.*s) has no connections\n", STR(srv));
  54. return -1;
  55. }
  56. struct rdata *l, *head;
  57. struct srv_rdata *srv_record;
  58. str name;
  59. jsonrpc_server_group_t* new_grp = NULL;
  60. // dns lookup
  61. head = get_record(srv.s, T_SRV, RES_AR);
  62. if (head == NULL) {
  63. ERR("No SRV record returned for %.*s\n", STR(srv));
  64. return -1;
  65. }
  66. // get all the servers from the srv record
  67. server_list_t* new_servers = NULL;
  68. jsonrpc_server_t* new_server = NULL;
  69. server_list_t* rm_servers = NULL;
  70. jsonrpc_server_t* rm_server = NULL;
  71. int iter = 0;
  72. for (l=head, iter=0; l; l=l->next, iter++) {
  73. if (l->type != T_SRV)
  74. continue;
  75. srv_record = (struct srv_rdata*)l->rdata;
  76. if (srv_record == NULL) {
  77. ERR("BUG: null rdata\n");
  78. return -1;
  79. }
  80. if (l->ttl < jsonrpc_min_srv_ttl) {
  81. ttl = jsonrpc_min_srv_ttl;
  82. } else {
  83. ttl = l->ttl;
  84. }
  85. srv_obj->ttl = ttl;
  86. name.s = srv_record->name;
  87. name.len = srv_record->name_len;
  88. DBG("server %s\n", srv_record->name);
  89. jsonrpc_server_group_t* cgroup = NULL;
  90. for(cgroup=conn_group; cgroup!=NULL; cgroup=cgroup->next) {
  91. new_server = create_server();
  92. CHECK_MALLOC(new_server);
  93. new_server->conn = shm_strdup(cgroup->conn);
  94. CHECK_MALLOC(new_server->conn.s);
  95. new_server->addr = shm_strdup(name);
  96. CHECK_MALLOC(new_server->addr.s);
  97. new_server->srv = shm_strdup(srv);
  98. CHECK_MALLOC(new_server->srv.s);
  99. new_server->port = srv_record->port;
  100. new_server->priority = srv_record->priority;
  101. new_server->weight = srv_record->weight;
  102. new_server->ttl = ttl;
  103. new_server->added = false;
  104. addto_server_list(new_server, &new_servers);
  105. }
  106. }
  107. if(iter <= 0) goto end;
  108. /* aquire global_server_group lock */
  109. /* this lock is only released when the old global_server_group
  110. * is freed in the IO process */
  111. lock_get(jsonrpc_server_group_lock); /* blocking */
  112. //print_group(global_server_group); /* debug */
  113. INIT_SERVER_LOOP
  114. // copy existing servers
  115. server_list_t* node;
  116. FOREACH_SERVER_IN(global_server_group)
  117. server->added = false;
  118. if(STR_EQ(server->srv, srv)) {
  119. for(node=new_servers; node!=NULL; node=node->next) {
  120. new_server = node->server;
  121. if(server_eq(new_server, server)) {
  122. new_server->added = true;
  123. server->added = true;
  124. server->ttl = srv_obj->ttl;
  125. jsonrpc_add_server(server, &new_grp);
  126. }
  127. }
  128. } else {
  129. server->added = true;
  130. jsonrpc_add_server(server, &new_grp);
  131. }
  132. ENDFOR
  133. FOREACH_SERVER_IN(global_server_group)
  134. if(server->added == false) {
  135. addto_server_list(server, &rm_servers);
  136. }
  137. ENDFOR
  138. // add and connect new servers
  139. for(node=new_servers; node!=NULL; node=node->next) {
  140. new_server = node->server;
  141. if(new_server->added == false) {
  142. jsonrpc_add_server(new_server, &new_grp);
  143. if(send_pipe_cmd(CMD_CONNECT, new_server) <0) {
  144. print_server(new_server);
  145. }
  146. } else {
  147. free_server(new_server);
  148. }
  149. }
  150. // close old servers
  151. for(node=rm_servers; node!=NULL; node=node->next) {
  152. rm_server = node->server;
  153. if(send_pipe_cmd(CMD_CLOSE, rm_server) <0) {
  154. print_server(rm_server);
  155. }
  156. }
  157. if(send_pipe_cmd(CMD_UPDATE_SERVER_GROUP, new_grp)<0) {
  158. free_server_group(&new_grp);
  159. lock_release(jsonrpc_server_group_lock);
  160. }
  161. end:
  162. // free server lists
  163. free_server_list(new_servers);
  164. free_server_list(rm_servers);
  165. return retval;
  166. }
  167. void free_srv(jsonrpc_srv_t* srv)
  168. {
  169. if(!srv)
  170. return;
  171. CHECK_AND_FREE(srv->srv.s);
  172. free_server_group(&(srv->cgroup));
  173. }
  174. jsonrpc_srv_t* create_srv(str srv, str conn, unsigned int ttl)
  175. {
  176. jsonrpc_srv_t* new_srv = shm_malloc(sizeof(jsonrpc_srv_t));
  177. if(!new_srv) goto error;
  178. new_srv->srv = shm_strdup(srv);
  179. if (ttl < jsonrpc_min_srv_ttl) {
  180. new_srv->ttl = jsonrpc_min_srv_ttl;
  181. } else {
  182. new_srv->ttl = ttl;
  183. }
  184. if(create_server_group(CONN_GROUP, &(new_srv->cgroup))<0) goto error;
  185. new_srv->cgroup->conn = shm_strdup(conn);
  186. if(!(new_srv->cgroup->conn.s)) return NULL;
  187. return new_srv;
  188. error:
  189. ERR("create_srv failed\n");
  190. free_srv(new_srv);
  191. return NULL;
  192. }
  193. void refresh_srv_cb(unsigned int ticks, void* params)
  194. {
  195. if(!params) {
  196. ERR("params is (null)\n");
  197. return;
  198. }
  199. if(!global_srv_list) {
  200. return;
  201. }
  202. srv_cb_params_t* p = (srv_cb_params_t*)params;
  203. cmd_pipe = p->cmd_pipe;
  204. jsonrpc_min_srv_ttl = p->srv_ttl;
  205. if(cmd_pipe == 0) {
  206. ERR("cmd_pipe is not set\n");
  207. return;
  208. }
  209. jsonrpc_srv_t* srv;
  210. for(srv=global_srv_list; srv!=NULL; srv=srv->next) {
  211. if(ticks % srv->ttl == 0) {
  212. refresh_srv(srv);
  213. }
  214. }
  215. }
  216. void addto_srv_list(jsonrpc_srv_t* srv, jsonrpc_srv_t** list)
  217. {
  218. if (*list == NULL) {
  219. *list = srv;
  220. return;
  221. }
  222. jsonrpc_srv_t* node = *list;
  223. jsonrpc_srv_t* prev = *list;
  224. jsonrpc_server_group_t* cgroup;
  225. jsonrpc_server_group_t* cprev;
  226. for(node=*list; node!=NULL; prev=node, node=node->next) {
  227. if(STR_EQ(srv->srv, node->srv)) {
  228. for(cgroup=node->cgroup, cprev=node->cgroup;
  229. cgroup!=NULL;
  230. cprev=cgroup, cgroup=cgroup->next) {
  231. if(STR_EQ(cgroup->conn, srv->cgroup->conn)) {
  232. INFO("Trying to add identical srv\n");
  233. goto clean;
  234. }
  235. }
  236. if(create_server_group(CONN_GROUP, &(cprev->next))<0) goto clean;
  237. cprev->next->conn = shm_strdup(srv->cgroup->conn);
  238. CHECK_MALLOC_GOTO(cprev->next->conn.s, clean);
  239. node->ttl = srv->ttl;
  240. goto clean;
  241. }
  242. }
  243. prev->next = srv;
  244. return;
  245. clean:
  246. free_srv(srv);
  247. }
  248. void print_srv(jsonrpc_srv_t* list)
  249. {
  250. INFO("------SRV list------\n");
  251. jsonrpc_srv_t* node = NULL;
  252. for(node=list; node!=NULL; node=node->next) {
  253. INFO("-----------------\n");
  254. INFO("| srv: %.*s\n", STR(node->srv));
  255. INFO("| ttl: %d\n", node->ttl);
  256. print_group(&(node->cgroup));
  257. INFO("-----------------\n");
  258. }
  259. }