Skip to content

Commit 75109ad

Browse files
author
zhuchao-hit
committed
command 'add/remove client' of administration
1 parent cb66b04 commit 75109ad

5 files changed

Lines changed: 140 additions & 27 deletions

File tree

lib/admin.lua

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ function read_query(packet)
160160
-- b.uuid, -- the MySQL Server's UUID if it is managed
161161
-- b.connected_clients -- currently connected clients
162162
}
163-
elseif string.find(query:lower(), "^add%s+master%s+.+$") then
163+
elseif string.find(query:lower(), "^add%s+master%s+%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?:%d%d?%d?%d?%d?$") then
164164
local newserver = string.match(query:lower(), "^add%s+master%s+(.+)$")
165165
proxy.global.backends.addmaster = newserver
166166
if proxy.global.config.rwsplit then proxy.global.config.rwsplit.max_weight = -1 end
@@ -169,7 +169,7 @@ function read_query(packet)
169169
{ name = "status",
170170
type = proxy.MYSQL_TYPE_STRING },
171171
}
172-
elseif string.find(query:lower(), "^add%s+slave%s+.+$") then
172+
elseif string.find(query:lower(), "^add%s+slave%s+%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?:%d%d?%d?%d?%d?$") then
173173
local newserver = string.match(query:lower(), "^add%s+slave%s+(.+)$")
174174
proxy.global.backends.addslave = newserver
175175
if proxy.global.config.rwsplit then proxy.global.config.rwsplit.max_weight = -1 end
@@ -192,6 +192,22 @@ function read_query(packet)
192192
type = proxy.MYSQL_TYPE_STRING },
193193
}
194194
end
195+
elseif string.find(query:lower(), "^add%s+client%s+%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?$") then
196+
local client = string.match(query:lower(), "^add%s+client%s+(.+)$")
197+
proxy.global.backends.addclient = client
198+
199+
fields = {
200+
{ name = "status",
201+
type = proxy.MYSQL_TYPE_STRING },
202+
}
203+
elseif string.find(query:lower(), "^remove%s+client%s+%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?$") then
204+
local client = string.match(query:lower(), "^remove%s+client%s+(.+)$")
205+
proxy.global.backends.removeclient = client
206+
207+
fields = {
208+
{ name = "status",
209+
type = proxy.MYSQL_TYPE_STRING },
210+
}
195211
elseif string.find(query:lower(), "^save%s+config+$") then
196212
proxy.global.backends.saveconfig = 0
197213
fields = {
@@ -212,6 +228,8 @@ function read_query(packet)
212228
rows[#rows + 1] = { "ADD MASTER $backend", "example: \"add master 127.0.0.1:3306\", ..." }
213229
rows[#rows + 1] = { "ADD SLAVE $backend", "example: \"add slave 127.0.0.1:3306\", ..." }
214230
rows[#rows + 1] = { "REMOVE BACKEND $backend_id", "example: \"remove backend 1\", ..." }
231+
rows[#rows + 1] = { "ADD CLIENT $client", "example: \"add client 192.168.1.2\", ..." }
232+
rows[#rows + 1] = { "REMOVE CLIENT $client", "example: \"remove client 192.168.1.2\", ..." }
215233
rows[#rows + 1] = { "SAVE CONFIG", "save the backends to config file" }
216234
else
217235
set_error("use 'SELECT * FROM help' to see the supported commands")

plugins/proxy/proxy-plugin.c

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,8 @@ struct chassis_plugin_config {
213213
gint start_proxy;
214214

215215
gchar **client_ips;
216-
GHashTable *ip_table;
216+
GHashTable *ip_table[2];
217+
gint ip_table_index;
217218

218219
gchar **lvs_ips;
219220
GHashTable *lvs_table;
@@ -1941,32 +1942,34 @@ NETWORK_MYSQLD_PLUGIN_PROTO(proxy_read_query_result) {
19411942
* NETWORK_SOCKET_ERROR - no backends available, adds a ERR packet to the client queue
19421943
*/
19431944
NETWORK_MYSQLD_PLUGIN_PROTO(proxy_connect_server) {
1944-
network_mysqld_con_lua_t *st = con->plugin_con_state;
19451945
guint i;
1946-
network_backend_t *cur;
19471946

19481947
guint client_ip = con->client->src->addr.ipv4.sin_addr.s_addr;
19491948
if (!online && g_hash_table_contains(config->lvs_table, &client_ip)) {
19501949
network_mysqld_con_send_error_full(con->client, C("Proxy Warning - Offline Now"), ER_UNKNOWN_ERROR, "07000");
19511950
return NETWORK_SOCKET_SUCCESS;
1952-
} else if (config->client_ips != NULL) {
1953-
for (i = 0; i < 3; ++i) {
1954-
if (g_hash_table_contains(config->ip_table, &client_ip)) break;
1955-
client_ip <<= 8;
1956-
}
1951+
} else {
1952+
GHashTable *ip_table = config->ip_table[config->ip_table_index];
1953+
if (g_hash_table_size(ip_table) != 0) {
1954+
for (i = 0; i < 3; ++i) {
1955+
if (g_hash_table_contains(ip_table, &client_ip)) break;
1956+
client_ip <<= 8;
1957+
}
19571958

1958-
if (i == 3 && !g_hash_table_contains(config->lvs_table, &(con->client->src->addr.ipv4.sin_addr.s_addr))) {
1959-
network_mysqld_con_send_error_full(con->client, C("Proxy Warning - IP Forbidden"), ER_UNKNOWN_ERROR, "07000");
1960-
return NETWORK_SOCKET_SUCCESS;
1961-
}
1959+
if (i == 3 && !g_hash_table_contains(config->lvs_table, &client_ip)) {
1960+
network_mysqld_con_send_error_full(con->client, C("Proxy Warning - IP Forbidden"), ER_UNKNOWN_ERROR, "07000");
1961+
return NETWORK_SOCKET_SUCCESS;
1962+
}
1963+
}
19621964
}
19631965

19641966
network_mysqld_auth_challenge *challenge = network_mysqld_auth_challenge_new();
19651967

19661968
challenge->protocol_version = 0;
19671969
challenge->server_version_str = g_strdup("5.0.81-log");
19681970
challenge->server_version = 50081;
1969-
challenge->thread_id = rand();
1971+
static guint32 thread_id = 0;
1972+
challenge->thread_id = ++thread_id;
19701973

19711974
GString *str = con->challenge;
19721975
for (i = 0; i < 20; ++i) g_string_append_c(str, rand()%127+1);
@@ -2207,7 +2210,9 @@ chassis_plugin_config * network_mysqld_proxy_plugin_new(void) {
22072210
config->start_proxy = 1;
22082211
config->pool_change_user = 1; /* issue a COM_CHANGE_USER to cleanup the connection
22092212
when we get back the connection from the pool */
2210-
config->ip_table = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL);
2213+
config->ip_table[0] = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL);
2214+
config->ip_table[1] = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL);
2215+
config->ip_table_index = 0;
22112216
config->lvs_table = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL);
22122217
config->dt_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
22132218
config->pwd_table = g_hash_table_new(g_str_hash, g_str_equal);
@@ -2250,8 +2255,10 @@ void network_mysqld_proxy_plugin_free(chassis_plugin_config *oldconfig) {
22502255
g_free(config->client_ips);
22512256
}
22522257

2253-
g_hash_table_remove_all(config->ip_table);
2254-
g_hash_table_destroy(config->ip_table);
2258+
g_hash_table_remove_all(config->ip_table[0]);
2259+
g_hash_table_destroy(config->ip_table[0]);
2260+
g_hash_table_remove_all(config->ip_table[1]);
2261+
g_hash_table_destroy(config->ip_table[1]);
22552262

22562263
if (config->lvs_ips) {
22572264
for (i = 0; config->lvs_ips[i]; i++) {
@@ -2489,8 +2496,10 @@ int network_mysqld_proxy_plugin_apply_config(chassis *chas, chassis_plugin_confi
24892496
*sum = (*sum << 8) + atoi(token);
24902497
}
24912498
*sum = htonl(*sum);
2492-
g_hash_table_add(config->ip_table, sum);
2499+
g_hash_table_add(config->ip_table[config->ip_table_index], sum);
24932500
}
2501+
chas->backends->ip_table = config->ip_table;
2502+
chas->backends->ip_table_index = &(config->ip_table_index);
24942503

24952504
for (i = 0; config->lvs_ips && config->lvs_ips[i]; i++) {
24962505
guint* lvs_ip = g_new0(guint, 1);

src/network-backend-lua.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,23 @@ static int proxy_backends_set(lua_State *L) {
150150
const char *key = luaL_checklstring(L, 2, &keysize);
151151

152152
if (strleq(key, keysize, C("addslave"))) {
153-
network_backends_add(bs, g_strdup(lua_tostring(L, -1)), BACKEND_TYPE_RO);
153+
gchar *address = g_strdup(lua_tostring(L, -1));
154+
network_backends_add(bs, g_strdup(lua_tostring(L, -1)), BACKEND_TYPE_RO);
155+
g_free(address);
154156
} else if (strleq(key, keysize, C("addmaster"))) {
155-
network_backends_add(bs, g_strdup(lua_tostring(L, -1)), BACKEND_TYPE_RW);
157+
gchar *address = g_strdup(lua_tostring(L, -1));
158+
network_backends_add(bs, g_strdup(lua_tostring(L, -1)), BACKEND_TYPE_RW);
159+
g_free(address);
156160
} else if (strleq(key, keysize, C("removebackend"))) {
157-
network_backends_remove(bs, lua_tointeger(L, -1));
161+
network_backends_remove(bs, lua_tointeger(L, -1));
162+
} else if (strleq(key, keysize, C("addclient"))) {
163+
gchar *address = g_strdup(lua_tostring(L, -1));
164+
network_backends_addclient(bs, g_strdup(lua_tostring(L, -1)));
165+
g_free(address);
166+
} else if (strleq(key, keysize, C("removeclient"))) {
167+
gchar *address = g_strdup(lua_tostring(L, -1));
168+
network_backends_removeclient(bs, g_strdup(lua_tostring(L, -1)));
169+
g_free(address);
158170
} else if (strleq(key, keysize, C("saveconfig"))) {
159171
network_backends_save(bs);
160172
} else {

src/network-backend.c

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,63 @@ int network_backends_remove(network_backends_t *bs, guint index) {
127127
return 0;
128128
}
129129

130+
void copy_key(guint *key, guint *value, GHashTable *table) {
131+
guint *new_key = g_new0(guint, 1);
132+
*new_key = *key;
133+
g_hash_table_add(table, new_key);
134+
}
135+
136+
int network_backends_addclient(network_backends_t *bs, gchar *address) {
137+
guint* sum = g_new0(guint, 1);
138+
char* token;
139+
while ((token = strsep(&address, ".")) != NULL) {
140+
*sum = (*sum << 8) + atoi(token);
141+
}
142+
*sum = htonl(*sum);
143+
144+
gint index = *(bs->ip_table_index);
145+
GHashTable *old_table = bs->ip_table[index];
146+
GHashTable *new_table = bs->ip_table[1-index];
147+
g_hash_table_remove_all(new_table);
148+
g_hash_table_foreach(old_table, copy_key, new_table);
149+
g_hash_table_add(new_table, sum);
150+
g_atomic_int_set(bs->ip_table_index, 1-index);
151+
152+
return 0;
153+
}
154+
155+
int network_backends_removeclient(network_backends_t *bs, gchar *address) {
156+
guint sum;
157+
char* token;
158+
while ((token = strsep(&address, ".")) != NULL) {
159+
sum = (sum << 8) + atoi(token);
160+
}
161+
sum = htonl(sum);
162+
163+
gint index = *(bs->ip_table_index);
164+
GHashTable *old_table = bs->ip_table[index];
165+
GHashTable *new_table = bs->ip_table[1-index];
166+
g_hash_table_remove_all(new_table);
167+
g_hash_table_foreach(old_table, copy_key, new_table);
168+
g_hash_table_remove(new_table, &sum);
169+
g_atomic_int_set(bs->ip_table_index, 1-index);
170+
171+
return 0;
172+
}
173+
174+
void append_key(guint *key, guint *value, GString *str) {
175+
g_string_append_c(str, ',');
176+
guint sum = *key;
177+
178+
g_string_append_printf(str, "%u", sum & 0x000000FF);
179+
180+
guint i;
181+
for (i = 1; i <= 3; ++i) {
182+
sum >>= 8;
183+
g_string_append_printf(str, ".%u", sum & 0x000000FF);
184+
}
185+
}
186+
130187
int network_backends_save(network_backends_t *bs) {
131188
GKeyFile *keyfile = g_key_file_new();
132189
g_key_file_set_list_separator(keyfile, ',');
@@ -172,6 +229,18 @@ int network_backends_save(network_backends_t *bs) {
172229
g_string_free(master, TRUE);
173230
g_string_free(slave, TRUE);
174231

232+
GString *client_ips = g_string_new(NULL);
233+
GHashTable *ip_table = bs->ip_table[*(bs->ip_table_index)];
234+
g_hash_table_foreach(ip_table, append_key, client_ips);
235+
236+
if (client_ips->len != 0) {
237+
g_key_file_set_value(keyfile, "mysql-proxy", "client-ips", client_ips->str+1);
238+
} else {
239+
g_key_file_set_value(keyfile, "mysql-proxy", "client-ips", "");
240+
}
241+
242+
g_string_free(client_ips, TRUE);
243+
175244
gsize file_size = 0;
176245
gchar *file_buf = g_key_file_to_data(keyfile, &file_size, NULL);
177246
if (FALSE == g_file_set_contents(bs->default_file, file_buf, file_size, &gerr)) {
@@ -199,9 +268,10 @@ int network_backends_add(network_backends_t *bs, /* const */ gchar *address, bac
199268
new_backend = network_backend_new(bs->event_thread_count);
200269
new_backend->type = type;
201270

271+
gchar *p = NULL;
202272
if (type == BACKEND_TYPE_RO) {
203273
guint weight = 1;
204-
gchar *p = strrchr(address, '@');
274+
p = strrchr(address, '@');
205275
if (p != NULL) {
206276
*p = '\0';
207277
weight = atoi(p+1);
@@ -239,8 +309,9 @@ int network_backends_add(network_backends_t *bs, /* const */ gchar *address, bac
239309
}
240310
g_mutex_unlock(bs->backends_mutex); /*remove lock*/
241311

242-
g_message("added %s backend: %s", (type == BACKEND_TYPE_RW) ?
243-
"read/write" : "read-only", address);
312+
g_message("added %s backend: %s", (type == BACKEND_TYPE_RW) ? "read/write" : "read-only", address);
313+
314+
if (p != NULL) *p = '@';
244315

245316
return 0;
246317
}

src/network-backend.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,16 @@ typedef struct {
7575
g_wrr_poll *global_wrr;
7676
guint event_thread_count;
7777
gchar *default_file;
78+
GHashTable **ip_table;
79+
gint *ip_table_index;
7880
} network_backends_t;
7981

8082
NETWORK_API network_backends_t *network_backends_new(guint event_thread_count, gchar *default_file);
8183
NETWORK_API void network_backends_free(network_backends_t *);
82-
NETWORK_API int network_backends_add(network_backends_t *backends, /* const */ gchar *address, backend_type_t type);
84+
NETWORK_API int network_backends_add(network_backends_t *backends, gchar *address, backend_type_t type);
8385
NETWORK_API int network_backends_remove(network_backends_t *backends, guint index);
86+
NETWORK_API int network_backends_addclient(network_backends_t *backends, gchar *address);
87+
NETWORK_API int network_backends_removeclient(network_backends_t *backends, gchar *address);
8488
NETWORK_API int network_backends_check(network_backends_t *backends);
8589
NETWORK_API network_backend_t * network_backends_get(network_backends_t *backends, guint ndx);
8690
NETWORK_API guint network_backends_count(network_backends_t *backends);
@@ -89,4 +93,3 @@ NETWORK_API g_wrr_poll *g_wrr_poll_new();
8993
NETWORK_API void g_wrr_poll_free(g_wrr_poll *global_wrr);
9094

9195
#endif /* _BACKEND_H_ */
92-

0 commit comments

Comments
 (0)