add tests/test_server_id_func.c
parent
7459f7ded4
commit
81e6455819
|
|
@ -47,6 +47,7 @@ src/tests/test_thourands_seperator
|
||||||
src/tests/test_pthread_lock
|
src/tests/test_pthread_lock
|
||||||
src/tests/test_split_string
|
src/tests/test_split_string
|
||||||
src/tests/test_uniq_skiplist
|
src/tests/test_uniq_skiplist
|
||||||
|
src/tests/test_server_id_func
|
||||||
|
|
||||||
# other
|
# other
|
||||||
*.swp
|
*.swp
|
||||||
|
|
|
||||||
2
HISTORY
2
HISTORY
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
Version 1.44 2020-02-14
|
Version 1.44 2020-02-15
|
||||||
* add test file src/tests/test_pthread_lock.c
|
* add test file src/tests/test_pthread_lock.c
|
||||||
* add uniq_skiplist.[hc]
|
* add uniq_skiplist.[hc]
|
||||||
* add function split_string_ex
|
* add function split_string_ex
|
||||||
|
|
|
||||||
|
|
@ -400,13 +400,13 @@ int conn_pool_parse_server_info(const char *pServerStr,
|
||||||
len = strlen(pServerStr);
|
len = strlen(pServerStr);
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"pServerStr \"%s\" is empty!",
|
"host \"%s\" is empty!",
|
||||||
__LINE__, pServerStr);
|
__LINE__, pServerStr);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
if (len >= sizeof(server_info)) {
|
if (len >= sizeof(server_info)) {
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"pServerStr \"%s\" is too long!",
|
"host \"%s\" is too long!",
|
||||||
__LINE__, pServerStr);
|
__LINE__, pServerStr);
|
||||||
return ENAMETOOLONG;
|
return ENAMETOOLONG;
|
||||||
}
|
}
|
||||||
|
|
@ -423,7 +423,7 @@ int conn_pool_parse_server_info(const char *pServerStr,
|
||||||
pServerInfo->port = (int)strtol(parts[1], &endptr, 10);
|
pServerInfo->port = (int)strtol(parts[1], &endptr, 10);
|
||||||
if ((endptr != NULL && *endptr != '\0') || pServerInfo->port <= 0) {
|
if ((endptr != NULL && *endptr != '\0') || pServerInfo->port <= 0) {
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"pServerStr: %s, invalid port: %s!",
|
"host: %s, invalid port: %s!",
|
||||||
__LINE__, pServerStr, parts[1]);
|
__LINE__, pServerStr, parts[1]);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
@ -433,7 +433,7 @@ int conn_pool_parse_server_info(const char *pServerStr,
|
||||||
sizeof(pServerInfo->ip_addr)) == INADDR_NONE)
|
sizeof(pServerInfo->ip_addr)) == INADDR_NONE)
|
||||||
{
|
{
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"pServerStr: %s, invalid hostname: %s!",
|
"host: %s, invalid hostname: %s!",
|
||||||
__LINE__, pServerStr, parts[0]);
|
__LINE__, pServerStr, parts[0]);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,10 @@ extern "C" {
|
||||||
(strcmp((conn).ip_addr, target_ip) == 0 && \
|
(strcmp((conn).ip_addr, target_ip) == 0 && \
|
||||||
(conn).port == target_port)
|
(conn).port == target_port)
|
||||||
|
|
||||||
|
#define FC_CONNECTION_SERVER_EQUAL1(conn1, conn2) \
|
||||||
|
(strcmp((conn1).ip_addr, (conn2).ip_addr) == 0 && \
|
||||||
|
(conn1).port == (conn2).port)
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int sock;
|
int sock;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,9 @@
|
||||||
#define SERVER_SECTION_PREFIX_STR "server-"
|
#define SERVER_SECTION_PREFIX_STR "server-"
|
||||||
#define SERVER_SECTION_PREFIX_LEN (sizeof(SERVER_SECTION_PREFIX_STR) - 1)
|
#define SERVER_SECTION_PREFIX_LEN (sizeof(SERVER_SECTION_PREFIX_STR) - 1)
|
||||||
|
|
||||||
|
#define SERVER_ITEM_PORT_STR "port"
|
||||||
|
#define SERVER_ITEM_PORT_LEN (sizeof(SERVER_ITEM_PORT_STR) - 1)
|
||||||
|
|
||||||
#define SERVER_ITEM_HOST_STR "host"
|
#define SERVER_ITEM_HOST_STR "host"
|
||||||
#define SERVER_ITEM_HOST_LEN (sizeof(SERVER_ITEM_HOST_STR) - 1)
|
#define SERVER_ITEM_HOST_LEN (sizeof(SERVER_ITEM_HOST_STR) - 1)
|
||||||
|
|
||||||
|
|
@ -34,6 +37,9 @@
|
||||||
#define SUB_NET_TYPE_INNER_172_STR3 "inner172"
|
#define SUB_NET_TYPE_INNER_172_STR3 "inner172"
|
||||||
#define SUB_NET_TYPE_INNER_192_STR3 "inner192"
|
#define SUB_NET_TYPE_INNER_192_STR3 "inner192"
|
||||||
|
|
||||||
|
#define FC_SERVER_GROUP_PORT(group) \
|
||||||
|
(group->server_port > 0 ? group->server_port : group->port)
|
||||||
|
|
||||||
static int fc_server_cmp_server_id(const void *p1, const void *p2)
|
static int fc_server_cmp_server_id(const void *p1, const void *p2)
|
||||||
{
|
{
|
||||||
return ((FCServerInfo *)p1)->id - ((FCServerInfo *)p2)->id;
|
return ((FCServerInfo *)p1)->id - ((FCServerInfo *)p2)->id;
|
||||||
|
|
@ -96,8 +102,8 @@ static int fc_server_calc_ip_port_count(FCServerContext *ctx)
|
||||||
for (server=ctx->sorted_server_arrays.by_id.servers;
|
for (server=ctx->sorted_server_arrays.by_id.servers;
|
||||||
server<send; server++)
|
server<send; server++)
|
||||||
{
|
{
|
||||||
gend = server->group_array.group_addrs + server->group_array.count;
|
gend = server->group_addrs + ctx->group_array.count;
|
||||||
for (gaddr=server->group_array.group_addrs; gaddr<gend; gaddr++) {
|
for (gaddr=server->group_addrs; gaddr<gend; gaddr++) {
|
||||||
count += gaddr->address_array.count;
|
count += gaddr->address_array.count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -138,8 +144,8 @@ static int fc_server_init_ip_port_array(FCServerContext *ctx)
|
||||||
for (server=ctx->sorted_server_arrays.by_id.servers;
|
for (server=ctx->sorted_server_arrays.by_id.servers;
|
||||||
server<send; server++)
|
server<send; server++)
|
||||||
{
|
{
|
||||||
gend = server->group_array.group_addrs + server->group_array.count;
|
gend = server->group_addrs + ctx->group_array.count;
|
||||||
for (gaddr=server->group_array.group_addrs; gaddr<gend; gaddr++) {
|
for (gaddr=server->group_addrs; gaddr<gend; gaddr++) {
|
||||||
for (i=0; i<gaddr->address_array.count; i++) {
|
for (i=0; i<gaddr->address_array.count; i++) {
|
||||||
map->server = server;
|
map->server = server;
|
||||||
FC_SET_STRING(map->ip_addr, gaddr->address_array.
|
FC_SET_STRING(map->ip_addr, gaddr->address_array.
|
||||||
|
|
@ -228,7 +234,7 @@ FCServerInfo *fc_server_get_by_ip_port_ex(FCServerContext *ctx,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void fc_server_set_group_name(FCServerGroupInfo *ginfo,
|
static inline void fc_server_set_group_ptr_name(FCServerGroupInfo *ginfo,
|
||||||
const char *group_name)
|
const char *group_name)
|
||||||
{
|
{
|
||||||
ginfo->group_name.str = ginfo->name_buff;
|
ginfo->group_name.str = ginfo->name_buff;
|
||||||
|
|
@ -291,42 +297,91 @@ static inline void fc_server_set_ip_prefix(FCServerGroupInfo *ginfo,
|
||||||
|
|
||||||
static int fc_server_load_one_group(FCServerContext *ctx,
|
static int fc_server_load_one_group(FCServerContext *ctx,
|
||||||
const char *config_filename, IniContext *ini_context,
|
const char *config_filename, IniContext *ini_context,
|
||||||
const char *section_name)
|
const int group_count, const char *section_name)
|
||||||
{
|
{
|
||||||
FCServerGroupInfo *current;
|
FCServerGroupInfo *group;
|
||||||
char new_name[FAST_INI_ITEM_NAME_SIZE];
|
char new_name[FAST_INI_ITEM_NAME_SIZE];
|
||||||
|
char *port_str;
|
||||||
char *net_type;
|
char *net_type;
|
||||||
char *ip_prefix;
|
char *ip_prefix;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
strcpy(new_name, section_name);
|
strcpy(new_name, section_name);
|
||||||
current = ctx->group_array.groups + ctx->group_array.count;
|
group = ctx->group_array.groups + ctx->group_array.count;
|
||||||
fc_server_set_group_name(current, new_name + GROUP_SECTION_PREFIX_LEN);
|
fc_server_set_group_ptr_name(group, new_name + GROUP_SECTION_PREFIX_LEN);
|
||||||
|
|
||||||
if (current->group_name.len == 0) {
|
if (group->group_name.len == 0) {
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"config filename: %s, section: %s, no group name!",
|
"config filename: %s, section: %s, no group name!",
|
||||||
__LINE__, config_filename, section_name);
|
__LINE__, config_filename, section_name);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
current->port = iniGetIntValue(section_name, "port",
|
port_str = iniGetStrValue(section_name, SERVER_ITEM_PORT_STR, ini_context);
|
||||||
ini_context, ctx->default_port);
|
if (port_str == NULL) {
|
||||||
|
if (group_count == 1) {
|
||||||
|
group->port = ctx->default_port;
|
||||||
|
} else {
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"config filename: %s, section: %s, no item: %s!",
|
||||||
|
__LINE__, config_filename, section_name,
|
||||||
|
SERVER_ITEM_PORT_STR);
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
char *endptr = NULL;
|
||||||
|
group->port = strtol(port_str, &endptr, 10);
|
||||||
|
if (group->port <= 0 || (endptr != NULL && *endptr != '\0')) {
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"config filename: %s, section: %s, item: %s, "
|
||||||
|
"invalid port: %s", __LINE__, config_filename,
|
||||||
|
section_name, SERVER_ITEM_PORT_STR, port_str);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
net_type = iniGetStrValue(section_name, "net_type", ini_context);
|
net_type = iniGetStrValue(section_name, "net_type", ini_context);
|
||||||
if ((result=fc_server_set_net_type(config_filename,
|
if ((result=fc_server_set_net_type(config_filename,
|
||||||
current, net_type)) != 0)
|
group, net_type)) != 0)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ip_prefix = iniGetStrValue(section_name, "ip_prefix", ini_context);
|
ip_prefix = iniGetStrValue(section_name, "ip_prefix", ini_context);
|
||||||
fc_server_set_ip_prefix(current, ip_prefix);
|
fc_server_set_ip_prefix(group, ip_prefix);
|
||||||
|
|
||||||
ctx->group_array.count++;
|
ctx->group_array.count++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int check_group_ports_duplicate(FCServerContext *ctx,
|
||||||
|
const char *config_filename)
|
||||||
|
{
|
||||||
|
FCServerGroupInfo *g1;
|
||||||
|
FCServerGroupInfo *g2;
|
||||||
|
FCServerGroupInfo *end;
|
||||||
|
int port1;
|
||||||
|
int port2;
|
||||||
|
|
||||||
|
end = ctx->group_array.groups + ctx->group_array.count;
|
||||||
|
for (g1=ctx->group_array.groups; g1<end; g1++) {
|
||||||
|
port1 = FC_SERVER_GROUP_PORT(g1);
|
||||||
|
for (g2=g1+1; g2<end; g2++) {
|
||||||
|
port2 = FC_SERVER_GROUP_PORT(g2);
|
||||||
|
if (port1 == port2) {
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"config filename: %s, the port: %d of group: %.*s "
|
||||||
|
"is same to group: %.*s", __LINE__, config_filename,
|
||||||
|
port1, g1->group_name.len, g1->group_name.str,
|
||||||
|
g2->group_name.len, g2->group_name.str);
|
||||||
|
return EEXIST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int fc_server_load_groups(FCServerContext *ctx,
|
static int fc_server_load_groups(FCServerContext *ctx,
|
||||||
const char *config_filename, IniContext *ini_context)
|
const char *config_filename, IniContext *ini_context)
|
||||||
{
|
{
|
||||||
|
|
@ -349,7 +404,7 @@ static int fc_server_load_groups(FCServerContext *ctx,
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
ctx->group_array.count = 1;
|
ctx->group_array.count = 1;
|
||||||
fc_server_set_group_name(ctx->group_array.groups + 0, "");
|
fc_server_set_group_ptr_name(ctx->group_array.groups + 0, "");
|
||||||
ctx->group_array.groups[0].port = iniGetIntValue(NULL, "port",
|
ctx->group_array.groups[0].port = iniGetIntValue(NULL, "port",
|
||||||
ini_context, ctx->default_port);
|
ini_context, ctx->default_port);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -358,7 +413,7 @@ static int fc_server_load_groups(FCServerContext *ctx,
|
||||||
end = sections + count;
|
end = sections + count;
|
||||||
for (section=sections; section<end; section++) {
|
for (section=sections; section<end; section++) {
|
||||||
if ((result=fc_server_load_one_group(ctx, config_filename,
|
if ((result=fc_server_load_one_group(ctx, config_filename,
|
||||||
ini_context, section->section_name)) != 0)
|
ini_context, count, section->section_name)) != 0)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -408,10 +463,252 @@ static inline void fc_server_clear_server_port(FCServerGroupArray *array)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fc_server_load_group_port(FCServerContext *ctx,
|
static FCServerGroupInfo *fc_server_get_group_by_name(FCServerContext *ctx,
|
||||||
const string_t *group_name, char *port_str)
|
const string_t *group_name)
|
||||||
{
|
{
|
||||||
//TODO
|
FCServerGroupInfo *group;
|
||||||
|
FCServerGroupInfo *end;
|
||||||
|
|
||||||
|
end = ctx->group_array.groups + ctx->group_array.count;
|
||||||
|
for (group=ctx->group_array.groups; group<end; group++) {
|
||||||
|
if (fc_string_equal(&group->group_name, group_name)) {
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fc_server_load_group_port(FCServerContext *ctx,
|
||||||
|
const char *config_filename, const char *section_name,
|
||||||
|
const string_t *group_name, IniItem *port_item)
|
||||||
|
{
|
||||||
|
FCServerGroupInfo *group;
|
||||||
|
char *endptr;
|
||||||
|
|
||||||
|
if ((group=fc_server_get_group_by_name(ctx, group_name)) == NULL) {
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"config filename: %s, section: %s, group: %.*s "
|
||||||
|
"in item: %s not found!", __LINE__, config_filename,
|
||||||
|
section_name, group_name->len, group_name->str,
|
||||||
|
port_item->name);
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
endptr = NULL;
|
||||||
|
group->server_port = strtol(port_item->value, &endptr, 10);
|
||||||
|
if (group->server_port <= 0 || (endptr != NULL && *endptr != '\0')) {
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"config filename: %s, section: %s, item: %s, "
|
||||||
|
"invalid port: %s", __LINE__, config_filename,
|
||||||
|
section_name, port_item->name, port_item->value);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int check_server_addresses_duplicate(FCServerContext *ctx,
|
||||||
|
const char *config_filename, const char *section_name,
|
||||||
|
const FCAddressInfo *addresses, const int count)
|
||||||
|
{
|
||||||
|
const FCAddressInfo *addr1;
|
||||||
|
const FCAddressInfo *addr2;
|
||||||
|
const FCAddressInfo *end;
|
||||||
|
char port_caption[32];
|
||||||
|
char port_prompt[16];
|
||||||
|
|
||||||
|
end = addresses + count;
|
||||||
|
for (addr1=addresses; addr1<end; addr1++) {
|
||||||
|
for (addr2=addr1+1; addr2<end; addr2++) {
|
||||||
|
if (FC_CONNECTION_SERVER_EQUAL1(addr1->conn, addr2->conn)) {
|
||||||
|
if (addr1->conn.port > 0) {
|
||||||
|
strcpy(port_caption, " and port");
|
||||||
|
sprintf(port_prompt, ":%d", addr1->conn.port);
|
||||||
|
} else {
|
||||||
|
*port_caption = *port_prompt = '\0';
|
||||||
|
}
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"config filename: %s, section: %s, duplicate ip%s %s%s",
|
||||||
|
__LINE__, config_filename, section_name, port_caption,
|
||||||
|
addr1->conn.ip_addr, port_prompt);
|
||||||
|
return EEXIST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int check_server_group_addresses_duplicate(FCServerContext *ctx,
|
||||||
|
FCServerInfo *server, const char *config_filename,
|
||||||
|
const char *section_name)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
FCGroupAddresses *gaddr;
|
||||||
|
FCGroupAddresses *end;
|
||||||
|
|
||||||
|
end = server->group_addrs + ctx->group_array.count;
|
||||||
|
for (gaddr=server->group_addrs; gaddr<end; gaddr++) {
|
||||||
|
if ((result=check_server_addresses_duplicate(ctx, config_filename,
|
||||||
|
section_name, gaddr->address_array.addrs,
|
||||||
|
gaddr->address_array.count)) != 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool fc_server_group_match(const FCServerGroupInfo *group,
|
||||||
|
const FCAddressInfo *addr)
|
||||||
|
{
|
||||||
|
int ip_len;
|
||||||
|
|
||||||
|
if ((addr->conn.port > 0) && (addr->conn.port !=
|
||||||
|
FC_SERVER_GROUP_PORT(group)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((group->filter.net_type != FC_NET_TYPE_NONE) &&
|
||||||
|
((addr->net_type & group->filter.net_type) !=
|
||||||
|
group->filter.net_type))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (group->filter.ip_prefix.len > 0) {
|
||||||
|
ip_len = strlen(addr->conn.ip_addr);
|
||||||
|
if (!(ip_len >= group->filter.ip_prefix.len &&
|
||||||
|
memcmp(addr->conn.ip_addr,
|
||||||
|
group->filter.ip_prefix.str,
|
||||||
|
group->filter.ip_prefix.len) == 0))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fc_server_set_host(FCServerContext *ctx, FCServerInfo *server,
|
||||||
|
const char *config_filename, const char *section_name,
|
||||||
|
FCAddressInfo *addr)
|
||||||
|
{
|
||||||
|
FCServerGroupInfo *group;
|
||||||
|
FCServerGroupInfo *end;
|
||||||
|
FCGroupAddresses *group_addr;
|
||||||
|
FCAddressInfo *current;
|
||||||
|
int count;
|
||||||
|
int group_index;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
end = ctx->group_array.groups + ctx->group_array.count;
|
||||||
|
for (group=ctx->group_array.groups; group<end; group++) {
|
||||||
|
if (fc_server_group_match(group, addr)) {
|
||||||
|
group_index = group - ctx->group_array.groups;
|
||||||
|
group_addr = server->group_addrs + group_index;
|
||||||
|
|
||||||
|
current = group_addr->address_array.addrs + group_addr->
|
||||||
|
address_array.count++;
|
||||||
|
*current = *addr;
|
||||||
|
if (addr->conn.port == 0) {
|
||||||
|
current->conn.port = FC_SERVER_GROUP_PORT(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count == 0) {
|
||||||
|
char port_prompt[16];
|
||||||
|
if (addr->conn.port > 0) {
|
||||||
|
sprintf(port_prompt, ":%d", addr->conn.port);
|
||||||
|
} else {
|
||||||
|
*port_prompt = '\0';
|
||||||
|
}
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"config filename: %s, section: %s, "
|
||||||
|
"host %s%s not belong to any group",
|
||||||
|
__LINE__, config_filename, section_name,
|
||||||
|
addr->conn.ip_addr, port_prompt);
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ctx->share_between_groups && (count > 1 && addr->conn.port > 0)) {
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"config filename: %s, section: %s, "
|
||||||
|
"host %s:%d belongs to %d groups",
|
||||||
|
__LINE__, config_filename, section_name,
|
||||||
|
addr->conn.ip_addr, addr->conn.port, count);
|
||||||
|
return EEXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fc_server_set_hosts(FCServerContext *ctx, FCServerInfo *server,
|
||||||
|
const char *config_filename, const char *section_name,
|
||||||
|
char **hosts, const int host_count)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
FCAddressInfo addresses[FC_MAX_SERVER_IP_COUNT];
|
||||||
|
FCAddressInfo *addr;
|
||||||
|
FCAddressInfo *addr_end;
|
||||||
|
char **host;
|
||||||
|
char **hend;
|
||||||
|
int no_port_count;
|
||||||
|
|
||||||
|
no_port_count = 0;
|
||||||
|
addr = addresses;
|
||||||
|
hend = hosts + host_count;
|
||||||
|
for (host=hosts; host<hend; host++) {
|
||||||
|
if ((result=conn_pool_parse_server_info(*host,
|
||||||
|
&addr->conn, 0)) != 0)
|
||||||
|
{
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"config filename: %s, section: %s, "
|
||||||
|
"invalid host: %s", __LINE__,
|
||||||
|
config_filename, section_name, *host);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr->net_type = fc_get_net_type(addr->conn.ip_addr);
|
||||||
|
if (addr->conn.port == 0) {
|
||||||
|
no_port_count++;
|
||||||
|
}
|
||||||
|
addr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((result=check_server_addresses_duplicate(ctx, config_filename,
|
||||||
|
section_name, addresses, host_count)) != 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (no_port_count > 0 && !ctx->share_between_groups) {
|
||||||
|
if ((result=check_group_ports_duplicate(ctx, config_filename)) != 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addr_end = addresses + host_count;
|
||||||
|
for (addr=addresses; addr<addr_end; addr++) {
|
||||||
|
if ((result=fc_server_set_host(ctx, server, config_filename,
|
||||||
|
section_name, addr)) != 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((result=check_server_group_addresses_duplicate(ctx, server,
|
||||||
|
config_filename, section_name)) != 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -449,12 +746,12 @@ static int fc_server_load_hosts(FCServerContext *ctx, FCServerInfo *server,
|
||||||
{
|
{
|
||||||
group_name.str = it->name;
|
group_name.str = it->name;
|
||||||
group_name.len = name_len - SERVER_ITEM_PORT_AFFIX_LEN;
|
group_name.len = name_len - SERVER_ITEM_PORT_AFFIX_LEN;
|
||||||
if ((result=fc_server_load_group_port(ctx,
|
if ((result=fc_server_load_group_port(ctx, config_filename,
|
||||||
&group_name, it->value)) != 0)
|
section_name, &group_name, it)) != 0)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
} else if (name_len > SERVER_ITEM_HOST_LEN && memcmp(it->name,
|
} else if (name_len == SERVER_ITEM_HOST_LEN && memcmp(it->name,
|
||||||
SERVER_ITEM_HOST_STR, SERVER_ITEM_HOST_LEN) == 0)
|
SERVER_ITEM_HOST_STR, SERVER_ITEM_HOST_LEN) == 0)
|
||||||
{
|
{
|
||||||
if (host_count >= FC_MAX_SERVER_IP_COUNT) {
|
if (host_count >= FC_MAX_SERVER_IP_COUNT) {
|
||||||
|
|
@ -483,23 +780,32 @@ static int fc_server_load_hosts(FCServerContext *ctx, FCServerInfo *server,
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
if ((result=fc_server_set_hosts(ctx, server, config_filename,
|
||||||
inner-port = 5106
|
section_name, hosts, host_count)) != 0)
|
||||||
outer-port = 5107
|
{
|
||||||
|
return result;
|
||||||
current->port = iniGetIntValue(section_name, "port",
|
}
|
||||||
ini_context, ctx->default_port);
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fc_server_set_group_ptr(FCServerContext *ctx, FCServerInfo *server)
|
||||||
|
{
|
||||||
|
FCGroupAddresses *gaddr;
|
||||||
|
FCGroupAddresses *end;
|
||||||
|
|
||||||
|
end = server->group_addrs + ctx->group_array.count;
|
||||||
|
for (gaddr=server->group_addrs; gaddr<end; gaddr++) {
|
||||||
|
gaddr->server_group = ctx->group_array.groups + (gaddr -
|
||||||
|
server->group_addrs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int fc_server_load_one_server(FCServerContext *ctx,
|
static int fc_server_load_one_server(FCServerContext *ctx,
|
||||||
const char *config_filename, IniContext *ini_context,
|
const char *config_filename, IniContext *ini_context,
|
||||||
const char *section_name)
|
const char *section_name)
|
||||||
{
|
{
|
||||||
FCServerInfo *current;
|
FCServerInfo *server;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
|
@ -509,12 +815,13 @@ static int fc_server_load_one_server(FCServerContext *ctx,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
current = ctx->sorted_server_arrays.by_id.servers +
|
server = ctx->sorted_server_arrays.by_id.servers +
|
||||||
ctx->sorted_server_arrays.by_id.count;
|
ctx->sorted_server_arrays.by_id.count;
|
||||||
|
|
||||||
endptr = NULL;
|
endptr = NULL;
|
||||||
current->id = strtol(section_name + SERVER_SECTION_PREFIX_LEN, &endptr, 10);
|
server->id = strtol(section_name + SERVER_SECTION_PREFIX_LEN,
|
||||||
if (current->id <= 0 || endptr != NULL) {
|
&endptr, 10);
|
||||||
|
if (server->id <= 0 || (endptr != NULL && *endptr != '\0')) {
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"config filename: %s, section: %s, invalid server id! "
|
"config filename: %s, section: %s, invalid server id! "
|
||||||
"server section format is [%s$id]",
|
"server section format is [%s$id]",
|
||||||
|
|
@ -523,7 +830,9 @@ static int fc_server_load_one_server(FCServerContext *ctx,
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result=fc_server_load_hosts(ctx, current, config_filename,
|
fc_server_set_group_ptr(ctx, server);
|
||||||
|
|
||||||
|
if ((result=fc_server_load_hosts(ctx, server, config_filename,
|
||||||
ini_context, section_name)) != 0)
|
ini_context, section_name)) != 0)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -625,19 +934,21 @@ int fc_server_load_data(FCServerContext *ctx, IniContext *ini_context,
|
||||||
return fc_server_check_ip_port(ctx, config_filename);
|
return fc_server_check_ip_port(ctx, config_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FC_SERVER_INIT_CONTEXT(ctx, port) \
|
#define FC_SERVER_INIT_CONTEXT(ctx, port, shared) \
|
||||||
do { \
|
do { \
|
||||||
memset(ctx, 0, sizeof(FCServerContext)); \
|
memset(ctx, 0, sizeof(FCServerContext)); \
|
||||||
ctx->default_port = port; \
|
ctx->default_port = port; \
|
||||||
|
ctx->share_between_groups = shared; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
int fc_server_load_from_file_ex(FCServerContext *ctx,
|
int fc_server_load_from_file_ex(FCServerContext *ctx,
|
||||||
const char *config_filename, const int default_port)
|
const char *config_filename, const int default_port,
|
||||||
|
const bool share_between_groups)
|
||||||
{
|
{
|
||||||
IniContext ini_context;
|
IniContext ini_context;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
FC_SERVER_INIT_CONTEXT(ctx, default_port);
|
FC_SERVER_INIT_CONTEXT(ctx, default_port, share_between_groups);
|
||||||
if ((result=iniLoadFromFile(config_filename, &ini_context)) != 0) {
|
if ((result=iniLoadFromFile(config_filename, &ini_context)) != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -648,12 +959,13 @@ int fc_server_load_from_file_ex(FCServerContext *ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
int fc_server_load_from_buffer_ex(FCServerContext *ctx, char *content,
|
int fc_server_load_from_buffer_ex(FCServerContext *ctx, char *content,
|
||||||
const char *caption, const int default_port)
|
const char *caption, const int default_port,
|
||||||
|
const bool share_between_groups)
|
||||||
{
|
{
|
||||||
IniContext ini_context;
|
IniContext ini_context;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
FC_SERVER_INIT_CONTEXT(ctx, default_port);
|
FC_SERVER_INIT_CONTEXT(ctx, default_port, share_between_groups);
|
||||||
if ((result=iniLoadFromBuffer(content, &ini_context)) != 0) {
|
if ((result=iniLoadFromBuffer(content, &ini_context)) != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -677,3 +989,50 @@ void fc_server_destroy(FCServerContext *ctx)
|
||||||
ctx->sorted_server_arrays.by_id.count = 0;
|
ctx->sorted_server_arrays.by_id.count = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fc_server_log_groups(FCServerContext *ctx)
|
||||||
|
{
|
||||||
|
FCServerGroupInfo *group;
|
||||||
|
FCServerGroupInfo *end;
|
||||||
|
|
||||||
|
end = ctx->group_array.groups + ctx->group_array.count;
|
||||||
|
for (group=ctx->group_array.groups; group<end; group++) {
|
||||||
|
logInfo("group_name: %.*s, port: %d, net_type: %s, ip_prefix: %.*s",
|
||||||
|
group->group_name.len, group->group_name.str, group->port,
|
||||||
|
get_net_type_caption(group->filter.net_type),
|
||||||
|
group->filter.ip_prefix.len, group->filter.ip_prefix.str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fc_server_log_one_server(FCServerContext *ctx, FCServerInfo *server)
|
||||||
|
{
|
||||||
|
FCGroupAddresses *gaddr;
|
||||||
|
FCGroupAddresses *end;
|
||||||
|
|
||||||
|
logInfo("server id: %d", server->id);
|
||||||
|
|
||||||
|
end = server->group_addrs + ctx->group_array.count;
|
||||||
|
for (gaddr=server->group_addrs; gaddr<end; gaddr++) {
|
||||||
|
logInfo("[group-%.*s]", FC_PRINTF_STAR_STRING_PARAMS(
|
||||||
|
gaddr->server_group->group_name));
|
||||||
|
//TODO log server ip and port
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fc_server_log_servers(FCServerContext *ctx)
|
||||||
|
{
|
||||||
|
FCServerInfo *server;
|
||||||
|
FCServerInfo *end;
|
||||||
|
|
||||||
|
end = ctx->sorted_server_arrays.by_id.servers +
|
||||||
|
ctx->sorted_server_arrays.by_id.count;
|
||||||
|
for (server=ctx->sorted_server_arrays.by_id.servers; server<end; server++) {
|
||||||
|
fc_server_log_one_server(ctx, server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fc_server_to_log(FCServerContext *ctx)
|
||||||
|
{
|
||||||
|
fc_server_log_groups(ctx);
|
||||||
|
fc_server_log_servers(ctx);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,10 +51,7 @@ typedef struct
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int id; //server id
|
int id; //server id
|
||||||
struct {
|
|
||||||
int count;
|
|
||||||
FCGroupAddresses group_addrs[FC_MAX_GROUP_COUNT];
|
FCGroupAddresses group_addrs[FC_MAX_GROUP_COUNT];
|
||||||
} group_array;
|
|
||||||
} FCServerInfo;
|
} FCServerInfo;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
@ -80,6 +77,7 @@ typedef struct
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int default_port;
|
int default_port;
|
||||||
|
bool share_between_groups; //if an address shared between different groups
|
||||||
FCServerGroupArray group_array;
|
FCServerGroupArray group_array;
|
||||||
struct {
|
struct {
|
||||||
FCServerInfoArray by_id; //sorted by server id
|
FCServerInfoArray by_id; //sorted by server id
|
||||||
|
|
@ -102,28 +100,36 @@ static inline FCServerInfo *fc_server_get_by_ip_port(FCServerContext *ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
int fc_server_load_from_file_ex(FCServerContext *ctx,
|
int fc_server_load_from_file_ex(FCServerContext *ctx,
|
||||||
const char *config_filename, const int default_port);
|
const char *config_filename, const int default_port,
|
||||||
|
const bool share_between_groups);
|
||||||
|
|
||||||
static inline int fc_server_load_from_file(FCServerContext *ctx,
|
static inline int fc_server_load_from_file(FCServerContext *ctx,
|
||||||
const char *config_filename)
|
const char *config_filename)
|
||||||
{
|
{
|
||||||
const int default_port = 0;
|
const int default_port = 0;
|
||||||
return fc_server_load_from_file_ex(ctx, config_filename, default_port);
|
const bool share_between_groups = false;
|
||||||
|
return fc_server_load_from_file_ex(ctx, config_filename,
|
||||||
|
default_port, share_between_groups);
|
||||||
}
|
}
|
||||||
|
|
||||||
int fc_server_load_from_buffer_ex(FCServerContext *ctx, char *content,
|
int fc_server_load_from_buffer_ex(FCServerContext *ctx, char *content,
|
||||||
const char *caption, const int default_port);
|
const char *caption, const int default_port,
|
||||||
|
const bool share_between_groups);
|
||||||
|
|
||||||
static inline int fc_server_load_from_buffer(FCServerContext *ctx,
|
static inline int fc_server_load_from_buffer(FCServerContext *ctx,
|
||||||
char *content)
|
char *content)
|
||||||
{
|
{
|
||||||
const char *caption = "from-buffer";
|
const char *caption = "from-buffer";
|
||||||
const int default_port = 0;
|
const int default_port = 0;
|
||||||
return fc_server_load_from_buffer_ex(ctx, content, caption, default_port);
|
const bool share_between_groups = false;
|
||||||
|
return fc_server_load_from_buffer_ex(ctx, content, caption,
|
||||||
|
default_port, share_between_groups);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fc_server_destroy(FCServerContext *ctx);
|
void fc_server_destroy(FCServerContext *ctx);
|
||||||
|
|
||||||
|
void fc_server_to_log(FCServerContext *ctx);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -2242,3 +2242,32 @@ int getifconfigs(FastIFConfig *if_configs, const int max_count, int *count)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int fc_get_net_type(const char *ip)
|
||||||
|
{
|
||||||
|
if (ip == NULL || (int)strlen(ip) < 8)
|
||||||
|
{
|
||||||
|
return FC_NET_TYPE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(ip, "10.", 3) == 0)
|
||||||
|
{
|
||||||
|
return FC_SUB_NET_TYPE_INNER_10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(ip, "192.168.", 8) == 0)
|
||||||
|
{
|
||||||
|
return FC_SUB_NET_TYPE_INNER_192;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(ip, "172.", 4) == 0)
|
||||||
|
{
|
||||||
|
int b;
|
||||||
|
b = atoi(ip + 4);
|
||||||
|
if (b >= 16 && b < 32)
|
||||||
|
{
|
||||||
|
return FC_SUB_NET_TYPE_INNER_172;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FC_NET_TYPE_OUTER;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -587,6 +587,8 @@ static inline void tcp_dont_try_again_when_interrupt()
|
||||||
tcp_set_try_again_when_interrupt(false);
|
tcp_set_try_again_when_interrupt(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fc_get_net_type(const char *ip);
|
||||||
|
|
||||||
static inline bool is_network_error(const int err_no)
|
static inline bool is_network_error(const int err_no)
|
||||||
{
|
{
|
||||||
switch (err_no)
|
switch (err_no)
|
||||||
|
|
@ -610,6 +612,27 @@ static inline bool is_network_error(const int err_no)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline const char *get_net_type_caption(const int net_type)
|
||||||
|
{
|
||||||
|
switch (net_type)
|
||||||
|
{
|
||||||
|
case FC_NET_TYPE_NONE:
|
||||||
|
return "none";
|
||||||
|
case FC_NET_TYPE_OUTER:
|
||||||
|
return "outer";
|
||||||
|
case FC_NET_TYPE_INNER:
|
||||||
|
return "inner";
|
||||||
|
case FC_SUB_NET_TYPE_INNER_10:
|
||||||
|
return "inner-10";
|
||||||
|
case FC_SUB_NET_TYPE_INNER_172:
|
||||||
|
return "inner-172";
|
||||||
|
case FC_SUB_NET_TYPE_INNER_192:
|
||||||
|
return "inner-192";
|
||||||
|
default:
|
||||||
|
return "UNKOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ LIB_PATH = -lfastcommon -lpthread
|
||||||
ALL_PRGS = test_allocator test_skiplist test_multi_skiplist test_mblock test_blocked_queue \
|
ALL_PRGS = test_allocator test_skiplist test_multi_skiplist test_mblock test_blocked_queue \
|
||||||
test_id_generator test_ini_parser test_char_convert test_char_convert_loader \
|
test_id_generator test_ini_parser test_char_convert test_char_convert_loader \
|
||||||
test_logger test_skiplist_set test_crc32 test_thourands_seperator test_sched_thread \
|
test_logger test_skiplist_set test_crc32 test_thourands_seperator test_sched_thread \
|
||||||
test_json_parser test_pthread_lock test_uniq_skiplist test_split_string
|
test_json_parser test_pthread_lock test_uniq_skiplist test_split_string \
|
||||||
|
test_server_id_func
|
||||||
|
|
||||||
all: $(ALL_PRGS)
|
all: $(ALL_PRGS)
|
||||||
.c:
|
.c:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include "fastcommon/logger.h"
|
||||||
|
#include "fastcommon/shared_func.h"
|
||||||
|
#include "fastcommon/server_id_func.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
const char *config_filename = "servers.conf";
|
||||||
|
FCServerContext ctx;
|
||||||
|
const int default_port = 1111;
|
||||||
|
const bool share_between_groups = false;
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
config_filename = argv[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
log_init();
|
||||||
|
|
||||||
|
if ((result=fc_server_load_from_file_ex(&ctx, config_filename,
|
||||||
|
default_port, share_between_groups)) != 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
fc_server_to_log(&ctx);
|
||||||
|
|
||||||
|
fc_server_destroy(&ctx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue