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 
23 #ifndef _JANSSONRPC_SERVER_H_
24 #define _JANSSONRPC_SERVER_H_
25 
26 #include <stdbool.h>
27 #include <event.h>
28 #include <event2/bufferevent.h>
29 #include <event2/buffer.h>
30 #include "../../core/locking.h"
31 #include "netstring.h"
32 
33 /* interval (in seconds) at which failed servers are retried */
34 #define JSONRPC_RECONNECT_INTERVAL  3
35 
36 /* default values */
37 #define JSONRPC_DEFAULT_PRIORITY 0
38 #define JSONRPC_DEFAULT_WEIGHT 1
39 #define JSONRPC_DEFAULT_HWM 0 /* unlimited */
40 
41 typedef struct jsonrpc_server {
42 	str conn, addr, srv; /* shared mem */
43 	int port;
44 	unsigned int  status, ttl, hwm;
45 	unsigned int  req_count;
46 	unsigned int priority, weight;
47 	bool added;
48 	int keep_alive_socket_fd;
49 	struct bufferevent* bev; /* local mem */
50 	netstring_t* buffer;
51 } jsonrpc_server_t;
52 
53 typedef enum {
54 	CONN_GROUP,
55 	PRIORITY_GROUP,
56 	WEIGHT_GROUP
57 } server_group_t;
58 
59 /* servers are organized in the following order:
60  * 1) conn
61  * 2) priority
62  * 3) weight
63  ***/
64 typedef struct jsonrpc_server_group {
65 	server_group_t type;
66 	struct jsonrpc_server_group* sub_group; // NULL when type is WEIGHT_GROUP
67 	union {
68 		str conn; // when type is CONN_GROUP
69 		unsigned int priority; // when type is PRIORITY_GROUP
70 		unsigned int weight; //when type is WEIGHT_GROUP
71 	};
72 	jsonrpc_server_t* server; // only when type is WEIGHT_GROUP
73 	struct jsonrpc_server_group* next;
74 } jsonrpc_server_group_t;
75 
76 extern gen_lock_t* jsonrpc_server_group_lock;
77 
78 typedef struct server_list {
79 	jsonrpc_server_t* server;
80 	struct server_list* next;
81 } server_list_t;
82 
83 /* where all the servers are stored */
84 extern jsonrpc_server_group_t** global_server_group;
85 
86 int jsonrpc_parse_server(char *_server, jsonrpc_server_group_t** group_ptr);
87 int jsonrpc_server_from_srv(str conn, str srv,
88 		unsigned int hwm, jsonrpc_server_group_t** group_ptr);
89 
90 void close_server(jsonrpc_server_t* server);
91 /* Do not call close_server() from outside the IO process.
92  * Server's have a bufferevent that is part of local memory and free'd
93  * at disconnect */
94 
95 jsonrpc_server_t* create_server();
96 void free_server(jsonrpc_server_t* server);
97 int create_server_group(server_group_t type, jsonrpc_server_group_t** new_grp);
98 int jsonrpc_add_server(jsonrpc_server_t* server, jsonrpc_server_group_t** group);
99 unsigned int  server_group_size(jsonrpc_server_group_t* group);
100 void free_server_group(jsonrpc_server_group_t** grp);
101 int server_eq(jsonrpc_server_t* a, jsonrpc_server_t* b);
102 void addto_server_list(jsonrpc_server_t* server, server_list_t** list);
103 void free_server_list(server_list_t* list);
104 
105 #define INIT_SERVER_LOOP  \
106 	jsonrpc_server_group_t* cgroup = NULL; \
107 	jsonrpc_server_group_t* pgroup = NULL; \
108 	jsonrpc_server_group_t* wgroup = NULL; \
109 	jsonrpc_server_t* server = NULL;
110 
111 #define FOREACH_SERVER_IN(ii) \
112 	if(ii == NULL) { \
113 		cgroup = NULL; \
114 	} else { \
115 		cgroup = *(ii); \
116 	} \
117 	pgroup = NULL; \
118 	wgroup = NULL; \
119 	server = NULL; \
120 	for(; cgroup!=NULL; cgroup=cgroup->next) { \
121 		for(pgroup=cgroup->sub_group; pgroup!=NULL; pgroup=pgroup->next) { \
122 			for(wgroup=pgroup->sub_group; wgroup!=NULL; wgroup=wgroup->next) { \
123 				server = wgroup->server;
124 
125 #define ENDFOR }}}
126 
127 /* debugging only */
128 void print_server(jsonrpc_server_t* server);
129 void print_group(jsonrpc_server_group_t** group);
130 
131 #endif /* _JSONRPC_SERVER_H_ */
132