add files: server_id_func.[hc]
parent
5d3c3c576c
commit
7459f7ded4
3
HISTORY
3
HISTORY
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
Version 1.44 2020-02-12
|
||||
Version 1.44 2020-02-14
|
||||
* add test file src/tests/test_pthread_lock.c
|
||||
* add uniq_skiplist.[hc]
|
||||
* add function split_string_ex
|
||||
|
|
@ -8,6 +8,7 @@ Version 1.44 2020-02-12
|
|||
* add function fc_memrchr
|
||||
* add function is_network_error
|
||||
* add function fast_mpool_log_stats
|
||||
* add files: server_id_func.[hc]
|
||||
|
||||
Version 1.43 2019-12-25
|
||||
* replace function call system to getExecResult,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ FAST_SHARED_OBJS = hash.lo chain.lo shared_func.lo ini_file_reader.lo \
|
|||
system_info.lo fast_blocked_queue.lo id_generator.lo \
|
||||
char_converter.lo char_convert_loader.lo common_blocked_queue.lo \
|
||||
multi_socket_client.lo skiplist_set.lo uniq_skiplist.lo \
|
||||
json_parser.lo buffered_file_writer.lo
|
||||
json_parser.lo buffered_file_writer.lo server_id_func.lo
|
||||
|
||||
FAST_STATIC_OBJS = hash.o chain.o shared_func.o ini_file_reader.o \
|
||||
logger.o sockopt.o base64.o sched_thread.o \
|
||||
|
|
@ -27,7 +27,7 @@ FAST_STATIC_OBJS = hash.o chain.o shared_func.o ini_file_reader.o \
|
|||
system_info.o fast_blocked_queue.o id_generator.o \
|
||||
char_converter.o char_convert_loader.o common_blocked_queue.o \
|
||||
multi_socket_client.o skiplist_set.o uniq_skiplist.o \
|
||||
json_parser.o buffered_file_writer.o
|
||||
json_parser.o buffered_file_writer.o server_id_func.lo
|
||||
|
||||
HEADER_FILES = common_define.h hash.h chain.h logger.h base64.h \
|
||||
shared_func.h pthread_func.h ini_file_reader.h _os_define.h \
|
||||
|
|
@ -40,7 +40,7 @@ HEADER_FILES = common_define.h hash.h chain.h logger.h base64.h \
|
|||
php7_ext_wrapper.h id_generator.h char_converter.h \
|
||||
char_convert_loader.h common_blocked_queue.h \
|
||||
multi_socket_client.h skiplist_set.h uniq_skiplist.h \
|
||||
fc_list.h json_parser.h buffered_file_writer.h
|
||||
fc_list.h json_parser.h buffered_file_writer.h server_id_func.h
|
||||
|
||||
ALL_OBJS = $(FAST_STATIC_OBJS) $(FAST_SHARED_OBJS)
|
||||
|
||||
|
|
|
|||
|
|
@ -2968,16 +2968,18 @@ void iniPrintItems(IniContext *pContext)
|
|||
hash_walk(&pContext->sections, iniPrintHashData, NULL);
|
||||
}
|
||||
|
||||
struct section_walk_arg {
|
||||
struct section_name_walk_arg {
|
||||
IniSectionInfo *sections;
|
||||
IniSectionNameFilterFunc filter_func;
|
||||
void *args;
|
||||
int count;
|
||||
int size;
|
||||
};
|
||||
|
||||
static int iniSectionWalkCallback(const int index, const HashData *data,
|
||||
void *args)
|
||||
static int iniSectionNameWalkCallback(const int index,
|
||||
const HashData *data, void *args)
|
||||
{
|
||||
struct section_walk_arg *walk_arg;
|
||||
struct section_name_walk_arg *walk_arg;
|
||||
IniSection *pSection;
|
||||
char *section_name;
|
||||
int section_len;
|
||||
|
|
@ -2988,7 +2990,13 @@ static int iniSectionWalkCallback(const int index, const HashData *data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
walk_arg = (struct section_walk_arg *)args;
|
||||
walk_arg = (struct section_name_walk_arg *)args;
|
||||
if (walk_arg->filter_func != NULL && !walk_arg->
|
||||
filter_func(data->key, data->key_len, walk_arg->args))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (walk_arg->count >= walk_arg->size)
|
||||
{
|
||||
return ENOSPC;
|
||||
|
|
@ -3009,20 +3017,101 @@ static int iniSectionWalkCallback(const int index, const HashData *data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int iniGetSectionNames(IniContext *pContext, IniSectionInfo *sections,
|
||||
int iniGetSectionNamesEx(IniContext *pContext, IniSectionNameFilterFunc
|
||||
filter_func, void *args, IniSectionInfo *sections,
|
||||
const int max_size, int *nCount)
|
||||
{
|
||||
struct section_walk_arg walk_arg;
|
||||
struct section_name_walk_arg walk_arg;
|
||||
int result;
|
||||
|
||||
walk_arg.sections = sections;
|
||||
walk_arg.count = 0;
|
||||
walk_arg.filter_func = filter_func;
|
||||
walk_arg.args = args;
|
||||
walk_arg.size = max_size;
|
||||
result = hash_walk(&pContext->sections, iniSectionWalkCallback, &walk_arg);
|
||||
walk_arg.count = 0;
|
||||
result = hash_walk(&pContext->sections, iniSectionNameWalkCallback,
|
||||
&walk_arg);
|
||||
*nCount = walk_arg.count;
|
||||
return result;
|
||||
}
|
||||
|
||||
int iniGetSectionNames(IniContext *pContext, IniSectionInfo *sections,
|
||||
const int max_size, int *nCount)
|
||||
{
|
||||
return iniGetSectionNamesEx(pContext, NULL, NULL,
|
||||
sections, max_size, nCount);
|
||||
}
|
||||
|
||||
static bool iniSectionNameFilterByPrefix(const char *section_name,
|
||||
const int name_len, void *args)
|
||||
{
|
||||
string_t *prefix;
|
||||
|
||||
prefix = (string_t *)args;
|
||||
if (name_len < prefix->len) {
|
||||
return false;
|
||||
}
|
||||
return memcmp(section_name, prefix->str, prefix->len) == 0;
|
||||
}
|
||||
|
||||
int iniGetSectionNamesByPrefix(IniContext *pContext, const char *szPrefix,
|
||||
IniSectionInfo *sections, const int max_size, int *nCount)
|
||||
{
|
||||
string_t prefix;
|
||||
|
||||
FC_SET_STRING(prefix, (char *)szPrefix);
|
||||
return iniGetSectionNamesEx(pContext, iniSectionNameFilterByPrefix,
|
||||
&prefix, sections, max_size, nCount);
|
||||
}
|
||||
|
||||
struct section_count_walk_arg {
|
||||
IniSectionNameFilterFunc filter_func;
|
||||
void *args;
|
||||
int count;
|
||||
};
|
||||
|
||||
static int iniSectionCountWalkCallback(const int index,
|
||||
const HashData *data, void *args)
|
||||
{
|
||||
struct section_count_walk_arg *walk_arg;
|
||||
IniSection *pSection;
|
||||
|
||||
pSection = (IniSection *)data->value;
|
||||
if (pSection == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
walk_arg = (struct section_count_walk_arg *)args;
|
||||
if (walk_arg->filter_func == NULL || walk_arg->
|
||||
filter_func(data->key, data->key_len, walk_arg->args))
|
||||
{
|
||||
walk_arg->count++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iniGetSectionCountEx(IniContext *pContext, IniSectionNameFilterFunc
|
||||
filter_func, void *args)
|
||||
{
|
||||
struct section_count_walk_arg walk_arg;
|
||||
|
||||
walk_arg.filter_func = filter_func;
|
||||
walk_arg.args = args;
|
||||
walk_arg.count = 0;
|
||||
hash_walk(&pContext->sections, iniSectionCountWalkCallback, &walk_arg);
|
||||
return walk_arg.count;
|
||||
}
|
||||
|
||||
int iniGetSectionCountByPrefix(IniContext *pContext, const char *szPrefix)
|
||||
{
|
||||
string_t prefix;
|
||||
|
||||
FC_SET_STRING(prefix, (char *)szPrefix);
|
||||
return iniGetSectionCountEx(pContext, iniSectionNameFilterByPrefix, &prefix);
|
||||
}
|
||||
|
||||
IniItem *iniGetSectionItems(const char *szSectionName, IniContext *pContext,
|
||||
int *nCount)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
#include "common_define.h"
|
||||
#include "hash.h"
|
||||
|
||||
#define FAST_INI_ITEM_NAME_LEN 64
|
||||
#define FAST_INI_ITEM_VALUE_LEN 256
|
||||
#define FAST_INI_ITEM_NAME_LEN 63
|
||||
#define FAST_INI_ITEM_VALUE_LEN 255
|
||||
#define FAST_INI_ITEM_NAME_SIZE (FAST_INI_ITEM_NAME_LEN + 1)
|
||||
#define FAST_INI_ITEM_VALUE_SIZE (FAST_INI_ITEM_VALUE_LEN + 1)
|
||||
|
||||
|
|
@ -29,6 +29,9 @@
|
|||
#define FAST_INI_FLAGS_NONE 0
|
||||
#define FAST_INI_FLAGS_SHELL_EXECUTE 1
|
||||
|
||||
typedef bool (*IniSectionNameFilterFunc)(const char *section_name,
|
||||
const int name_len, void *args);
|
||||
|
||||
typedef struct ini_item
|
||||
{
|
||||
char name[FAST_INI_ITEM_NAME_SIZE];
|
||||
|
|
@ -244,7 +247,7 @@ static inline const char *iniGetConfigPath(IniContext *pContext)
|
|||
return pContext->config_path;
|
||||
}
|
||||
|
||||
/** return the items of global section
|
||||
/** return the section names
|
||||
* parameters:
|
||||
* pContext: the ini context
|
||||
* sections: the section array
|
||||
|
|
@ -255,6 +258,60 @@ static inline const char *iniGetConfigPath(IniContext *pContext)
|
|||
int iniGetSectionNames(IniContext *pContext, IniSectionInfo *sections,
|
||||
const int max_size, int *nCount);
|
||||
|
||||
/** return the section names
|
||||
* parameters:
|
||||
* pContext: the ini context
|
||||
* prefix: the prefix of section name
|
||||
* sections: the section array
|
||||
* max_size: the max size of sections
|
||||
* nCount: return the section count
|
||||
* return: errno, 0 for success, != 0 for fail
|
||||
*/
|
||||
int iniGetSectionNamesByPrefix(IniContext *pContext, const char *szPrefix,
|
||||
IniSectionInfo *sections, const int max_size, int *nCount);
|
||||
|
||||
/** return the section names
|
||||
* parameters:
|
||||
* pContext: the ini context
|
||||
* filter_func: the section name filter function
|
||||
* args: the extra data pointer
|
||||
* sections: the section array
|
||||
* max_size: the max size of sections
|
||||
* nCount: return the section count
|
||||
* return: errno, 0 for success, != 0 for fail
|
||||
*/
|
||||
int iniGetSectionNamesEx(IniContext *pContext, IniSectionNameFilterFunc
|
||||
filter_func, void *args, IniSectionInfo *sections,
|
||||
const int max_size, int *nCount);
|
||||
|
||||
/** get matched section count
|
||||
* parameters:
|
||||
* pContext: the ini context
|
||||
* filter_func: the section name filter function
|
||||
* args: the extra data pointer
|
||||
* return: matched section count
|
||||
*/
|
||||
int iniGetSectionCountEx(IniContext *pContext, IniSectionNameFilterFunc
|
||||
filter_func, void *args);
|
||||
|
||||
/** get matched section count
|
||||
* parameters:
|
||||
* pContext: the ini context
|
||||
* prefix: the prefix of section name
|
||||
* return: matched section count
|
||||
*/
|
||||
int iniGetSectionCountByPrefix(IniContext *pContext, const char *szPrefix);
|
||||
|
||||
/** get section count
|
||||
* parameters:
|
||||
* pContext: the ini context
|
||||
* return: section count
|
||||
*/
|
||||
static inline int iniGetSectionCount(IniContext *pContext)
|
||||
{
|
||||
return pContext->sections.item_count;
|
||||
}
|
||||
|
||||
/** return the items of global section
|
||||
* parameters:
|
||||
* pContext: the ini context
|
||||
|
|
|
|||
|
|
@ -0,0 +1,679 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include "logger.h"
|
||||
#include "shared_func.h"
|
||||
#include "sockopt.h"
|
||||
#include "server_id_func.h"
|
||||
|
||||
#define GROUP_SECTION_PREFIX_STR "group-"
|
||||
#define GROUP_SECTION_PREFIX_LEN (sizeof(GROUP_SECTION_PREFIX_STR) - 1)
|
||||
|
||||
#define SERVER_SECTION_PREFIX_STR "server-"
|
||||
#define SERVER_SECTION_PREFIX_LEN (sizeof(SERVER_SECTION_PREFIX_STR) - 1)
|
||||
|
||||
#define SERVER_ITEM_HOST_STR "host"
|
||||
#define SERVER_ITEM_HOST_LEN (sizeof(SERVER_ITEM_HOST_STR) - 1)
|
||||
|
||||
#define SERVER_ITEM_PORT_AFFIX_STR "-port"
|
||||
#define SERVER_ITEM_PORT_AFFIX_LEN (sizeof(SERVER_ITEM_PORT_AFFIX_STR) - 1)
|
||||
|
||||
#define NET_TYPE_OUTER_STR "outer"
|
||||
#define NET_TYPE_INNER_STR "inner"
|
||||
|
||||
#define SUB_NET_TYPE_INNER_10_STR1 "inner-10"
|
||||
#define SUB_NET_TYPE_INNER_172_STR1 "inner-172"
|
||||
#define SUB_NET_TYPE_INNER_192_STR1 "inner-192"
|
||||
|
||||
#define SUB_NET_TYPE_INNER_10_STR2 "inner_10"
|
||||
#define SUB_NET_TYPE_INNER_172_STR2 "inner_172"
|
||||
#define SUB_NET_TYPE_INNER_192_STR2 "inner_192"
|
||||
|
||||
#define SUB_NET_TYPE_INNER_10_STR3 "inner10"
|
||||
#define SUB_NET_TYPE_INNER_172_STR3 "inner172"
|
||||
#define SUB_NET_TYPE_INNER_192_STR3 "inner192"
|
||||
|
||||
static int fc_server_cmp_server_id(const void *p1, const void *p2)
|
||||
{
|
||||
return ((FCServerInfo *)p1)->id - ((FCServerInfo *)p2)->id;
|
||||
}
|
||||
|
||||
static int fc_server_cmp_ip_and_port(const void *p1, const void *p2)
|
||||
{
|
||||
FCServerMap *m1;
|
||||
FCServerMap *m2;
|
||||
int result;
|
||||
int sub;
|
||||
int min;
|
||||
|
||||
m1 = (FCServerMap *)p1;
|
||||
m2 = (FCServerMap *)p2;
|
||||
|
||||
sub = m1->ip_addr.len - m2->ip_addr.len;
|
||||
if (sub < 0) {
|
||||
min = m1->ip_addr.len;
|
||||
} else {
|
||||
min = m2->ip_addr.len;
|
||||
}
|
||||
|
||||
if (min > 0) {
|
||||
result = memcmp(m1->ip_addr.str, m2->ip_addr.str, min);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (sub != 0) {
|
||||
return sub;
|
||||
}
|
||||
|
||||
return m1->port - m2->port;
|
||||
}
|
||||
|
||||
FCServerInfo *fc_server_get_by_id(FCServerContext *ctx,
|
||||
const int server_id)
|
||||
{
|
||||
FCServerInfo target;
|
||||
|
||||
target.id = server_id;
|
||||
return (FCServerInfo *)bsearch(&target,
|
||||
ctx->sorted_server_arrays.by_id.servers,
|
||||
ctx->sorted_server_arrays.by_id.count,
|
||||
sizeof(FCServerInfo), fc_server_cmp_server_id);
|
||||
}
|
||||
|
||||
static int fc_server_calc_ip_port_count(FCServerContext *ctx)
|
||||
{
|
||||
FCServerInfo *server;
|
||||
FCServerInfo *send;
|
||||
FCGroupAddresses *gaddr;
|
||||
FCGroupAddresses *gend;
|
||||
int count;
|
||||
|
||||
count = 0;
|
||||
send = ctx->sorted_server_arrays.by_id.servers +
|
||||
ctx->sorted_server_arrays.by_id.count;
|
||||
for (server=ctx->sorted_server_arrays.by_id.servers;
|
||||
server<send; server++)
|
||||
{
|
||||
gend = server->group_array.group_addrs + server->group_array.count;
|
||||
for (gaddr=server->group_array.group_addrs; gaddr<gend; gaddr++) {
|
||||
count += gaddr->address_array.count;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int fc_server_init_ip_port_array(FCServerContext *ctx)
|
||||
{
|
||||
int result;
|
||||
int alloc_bytes;
|
||||
int i;
|
||||
FCServerMapArray *map_array;
|
||||
FCServerMap *map;
|
||||
FCServerInfo *server;
|
||||
FCServerInfo *send;
|
||||
FCGroupAddresses *gaddr;
|
||||
FCGroupAddresses *gend;
|
||||
|
||||
map_array = &ctx->sorted_server_arrays.by_ip_port;
|
||||
|
||||
map_array->count = fc_server_calc_ip_port_count(ctx);
|
||||
alloc_bytes = sizeof(FCServerMap) * map_array->count;
|
||||
map_array->maps = (FCServerMap *)malloc(alloc_bytes);
|
||||
if (map_array->maps == NULL) {
|
||||
result = errno != 0 ? errno : ENOMEM;
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"malloc %d bytes fail, "
|
||||
"errno: %d, error info: %s", __LINE__,
|
||||
alloc_bytes, result, STRERROR(result));
|
||||
return result;
|
||||
}
|
||||
memset(map_array->maps, 0, alloc_bytes);
|
||||
|
||||
send = ctx->sorted_server_arrays.by_id.servers +
|
||||
ctx->sorted_server_arrays.by_id.count;
|
||||
map = map_array->maps;
|
||||
for (server=ctx->sorted_server_arrays.by_id.servers;
|
||||
server<send; server++)
|
||||
{
|
||||
gend = server->group_array.group_addrs + server->group_array.count;
|
||||
for (gaddr=server->group_array.group_addrs; gaddr<gend; gaddr++) {
|
||||
for (i=0; i<gaddr->address_array.count; i++) {
|
||||
map->server = server;
|
||||
FC_SET_STRING(map->ip_addr, gaddr->address_array.
|
||||
addrs[i].conn.ip_addr);
|
||||
map->port = gaddr->address_array.addrs[i].conn.port;
|
||||
map++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qsort(map_array->maps, map_array->count, sizeof(FCServerMap),
|
||||
fc_server_cmp_ip_and_port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc_server_check_id_duplicated(FCServerContext *ctx,
|
||||
const char *config_filename)
|
||||
{
|
||||
FCServerInfo *previous;
|
||||
FCServerInfo *current;
|
||||
FCServerInfo *send;
|
||||
|
||||
previous = ctx->sorted_server_arrays.by_id.servers + 0;
|
||||
send = ctx->sorted_server_arrays.by_id.servers +
|
||||
ctx->sorted_server_arrays.by_id.count;
|
||||
for (current=ctx->sorted_server_arrays.by_id.servers + 1;
|
||||
current<send; current++)
|
||||
{
|
||||
if (current->id == previous->id) {
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config file: %s, duplicate server id: %d",
|
||||
__LINE__, config_filename, current->id);
|
||||
return EEXIST;
|
||||
}
|
||||
previous = current;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc_server_check_ip_port(FCServerContext *ctx,
|
||||
const char *config_filename)
|
||||
{
|
||||
FCServerMap *previous;
|
||||
FCServerMap *current;
|
||||
FCServerMap *end;
|
||||
|
||||
previous = ctx->sorted_server_arrays.by_ip_port.maps + 0;
|
||||
end = ctx->sorted_server_arrays.by_ip_port.maps +
|
||||
ctx->sorted_server_arrays.by_ip_port.count;
|
||||
for (current=ctx->sorted_server_arrays.by_ip_port.maps+1;
|
||||
current<end; current++)
|
||||
{
|
||||
if (fc_server_cmp_ip_and_port(current, previous) == 0) {
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config file: %s, duplicate ip:port %s:%d, "
|
||||
"the server ids are %d and %d", __LINE__,
|
||||
config_filename, previous->ip_addr.str, previous->port,
|
||||
previous->server->id, current->server->id);
|
||||
|
||||
return EEXIST;
|
||||
}
|
||||
|
||||
previous = current;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
FCServerInfo *fc_server_get_by_ip_port_ex(FCServerContext *ctx,
|
||||
const string_t *ip_addr, const int port)
|
||||
{
|
||||
FCServerMap target;
|
||||
FCServerMap *found;
|
||||
|
||||
target.ip_addr = *ip_addr;
|
||||
target.port = port;
|
||||
found = (FCServerMap *)bsearch(&target,
|
||||
ctx->sorted_server_arrays.by_ip_port.maps,
|
||||
ctx->sorted_server_arrays.by_ip_port.count,
|
||||
sizeof(FCServerMap), fc_server_cmp_ip_and_port);
|
||||
if (found != NULL) {
|
||||
return found->server;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void fc_server_set_group_name(FCServerGroupInfo *ginfo,
|
||||
const char *group_name)
|
||||
{
|
||||
ginfo->group_name.str = ginfo->name_buff;
|
||||
ginfo->group_name.len = snprintf(ginfo->name_buff,
|
||||
sizeof(ginfo->name_buff) - 1, "%s", group_name);
|
||||
if (ginfo->group_name.len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
fc_trim(ginfo->group_name.str);
|
||||
ginfo->group_name.len = strlen(ginfo->group_name.str);
|
||||
}
|
||||
|
||||
static int fc_server_set_net_type(const char *config_filename,
|
||||
FCServerGroupInfo *ginfo, const char *net_type)
|
||||
{
|
||||
if (net_type == NULL || *net_type == '\0') {
|
||||
ginfo->filter.net_type = FC_NET_TYPE_NONE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcasecmp(net_type, NET_TYPE_OUTER_STR) == 0) {
|
||||
ginfo->filter.net_type = FC_NET_TYPE_OUTER;
|
||||
} else if (strcasecmp(net_type, NET_TYPE_INNER_STR) == 0) {
|
||||
ginfo->filter.net_type = FC_NET_TYPE_INNER;
|
||||
} else if (strcasecmp(net_type, SUB_NET_TYPE_INNER_10_STR1) == 0 ||
|
||||
strcasecmp(net_type, SUB_NET_TYPE_INNER_10_STR2) == 0 ||
|
||||
strcasecmp(net_type, SUB_NET_TYPE_INNER_10_STR3) == 0)
|
||||
{
|
||||
ginfo->filter.net_type = FC_SUB_NET_TYPE_INNER_10;
|
||||
} else if (strcasecmp(net_type, SUB_NET_TYPE_INNER_172_STR1) == 0 ||
|
||||
strcasecmp(net_type, SUB_NET_TYPE_INNER_172_STR2) == 0 ||
|
||||
strcasecmp(net_type, SUB_NET_TYPE_INNER_172_STR3) == 0)
|
||||
{
|
||||
ginfo->filter.net_type = FC_SUB_NET_TYPE_INNER_172;
|
||||
} else if (strcasecmp(net_type, SUB_NET_TYPE_INNER_192_STR1) == 0 ||
|
||||
strcasecmp(net_type, SUB_NET_TYPE_INNER_192_STR2) == 0 ||
|
||||
strcasecmp(net_type, SUB_NET_TYPE_INNER_192_STR3) == 0)
|
||||
{
|
||||
ginfo->filter.net_type = FC_SUB_NET_TYPE_INNER_192;
|
||||
} else {
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config filename: %s, section: %s, invalid net_type: %s",
|
||||
__LINE__, config_filename, ginfo->group_name.str, net_type);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void fc_server_set_ip_prefix(FCServerGroupInfo *ginfo,
|
||||
const char *ip_prefix)
|
||||
{
|
||||
ginfo->filter.ip_prefix.str = ginfo->filter.prefix_buff;
|
||||
if (ip_prefix != NULL) {
|
||||
ginfo->filter.ip_prefix.len = snprintf(ginfo->filter.prefix_buff,
|
||||
sizeof(ginfo->filter.prefix_buff) - 1, "%s", ip_prefix);
|
||||
}
|
||||
}
|
||||
|
||||
static int fc_server_load_one_group(FCServerContext *ctx,
|
||||
const char *config_filename, IniContext *ini_context,
|
||||
const char *section_name)
|
||||
{
|
||||
FCServerGroupInfo *current;
|
||||
char new_name[FAST_INI_ITEM_NAME_SIZE];
|
||||
char *net_type;
|
||||
char *ip_prefix;
|
||||
int result;
|
||||
|
||||
strcpy(new_name, section_name);
|
||||
current = ctx->group_array.groups + ctx->group_array.count;
|
||||
fc_server_set_group_name(current, new_name + GROUP_SECTION_PREFIX_LEN);
|
||||
|
||||
if (current->group_name.len == 0) {
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config filename: %s, section: %s, no group name!",
|
||||
__LINE__, config_filename, section_name);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
current->port = iniGetIntValue(section_name, "port",
|
||||
ini_context, ctx->default_port);
|
||||
|
||||
net_type = iniGetStrValue(section_name, "net_type", ini_context);
|
||||
if ((result=fc_server_set_net_type(config_filename,
|
||||
current, net_type)) != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
ip_prefix = iniGetStrValue(section_name, "ip_prefix", ini_context);
|
||||
fc_server_set_ip_prefix(current, ip_prefix);
|
||||
|
||||
ctx->group_array.count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc_server_load_groups(FCServerContext *ctx,
|
||||
const char *config_filename, IniContext *ini_context)
|
||||
{
|
||||
int result;
|
||||
int count;
|
||||
IniSectionInfo sections[FC_MAX_GROUP_COUNT];
|
||||
IniSectionInfo *section;
|
||||
IniSectionInfo *end;
|
||||
|
||||
if ((result=iniGetSectionNamesByPrefix(ini_context,
|
||||
GROUP_SECTION_PREFIX_STR, sections,
|
||||
FC_MAX_GROUP_COUNT, &count)) != 0)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config filename: %s, get sections by prefix %s fail, "
|
||||
"errno: %d, error info: %s", __LINE__, config_filename,
|
||||
GROUP_SECTION_PREFIX_STR, result, STRERROR(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
ctx->group_array.count = 1;
|
||||
fc_server_set_group_name(ctx->group_array.groups + 0, "");
|
||||
ctx->group_array.groups[0].port = iniGetIntValue(NULL, "port",
|
||||
ini_context, ctx->default_port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
end = sections + count;
|
||||
for (section=sections; section<end; section++) {
|
||||
if ((result=fc_server_load_one_group(ctx, config_filename,
|
||||
ini_context, section->section_name)) != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc_server_check_alloc_servers(FCServerInfoArray *array)
|
||||
{
|
||||
int new_alloc;
|
||||
int bytes;
|
||||
FCServerInfo *new_servers;
|
||||
|
||||
if (array->count < array->alloc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
new_alloc = array->alloc > 0 ? 2 * array->alloc : 2;
|
||||
bytes = sizeof(FCServerInfo) * new_alloc;
|
||||
new_servers = (FCServerInfo *)malloc(bytes);
|
||||
if (new_servers == NULL) {
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"malloc %d bytes fail", __LINE__, bytes);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
if (array->servers != NULL) {
|
||||
memcpy(new_servers, array->servers,
|
||||
sizeof(FCServerInfo) * array->count);
|
||||
free(array->servers);
|
||||
}
|
||||
|
||||
array->servers = new_servers;
|
||||
array->alloc = new_alloc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void fc_server_clear_server_port(FCServerGroupArray *array)
|
||||
{
|
||||
FCServerGroupInfo *group;
|
||||
FCServerGroupInfo *end;
|
||||
|
||||
end = array->groups + array->count;
|
||||
for (group=array->groups; group<end; group++) {
|
||||
group->server_port = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int fc_server_load_group_port(FCServerContext *ctx,
|
||||
const string_t *group_name, char *port_str)
|
||||
{
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc_server_load_hosts(FCServerContext *ctx, FCServerInfo *server,
|
||||
const char *config_filename, IniContext *ini_context,
|
||||
const char *section_name)
|
||||
{
|
||||
IniItem *items;
|
||||
IniItem *it;
|
||||
IniItem *end;
|
||||
char *hosts[FC_MAX_SERVER_IP_COUNT];
|
||||
int item_count;
|
||||
int host_count;
|
||||
int name_len;
|
||||
int result;
|
||||
string_t group_name;
|
||||
|
||||
items = iniGetSectionItems(section_name, ini_context, &item_count);
|
||||
if (item_count == 0) {
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config filename: %s, section: %s, no items!",
|
||||
__LINE__, config_filename, section_name);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
fc_server_clear_server_port(&ctx->group_array);
|
||||
|
||||
host_count = 0;
|
||||
end = items + item_count;
|
||||
for (it=items; it<end; it++) {
|
||||
name_len = strlen(it->name);
|
||||
if (name_len > SERVER_ITEM_PORT_AFFIX_LEN &&
|
||||
memcmp(it->name + name_len - SERVER_ITEM_PORT_AFFIX_LEN,
|
||||
SERVER_ITEM_PORT_AFFIX_STR, SERVER_ITEM_PORT_AFFIX_LEN) == 0)
|
||||
{
|
||||
group_name.str = it->name;
|
||||
group_name.len = name_len - SERVER_ITEM_PORT_AFFIX_LEN;
|
||||
if ((result=fc_server_load_group_port(ctx,
|
||||
&group_name, it->value)) != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
} else if (name_len > SERVER_ITEM_HOST_LEN && memcmp(it->name,
|
||||
SERVER_ITEM_HOST_STR, SERVER_ITEM_HOST_LEN) == 0)
|
||||
{
|
||||
if (host_count >= FC_MAX_SERVER_IP_COUNT) {
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config filename: %s, section: %s, "
|
||||
"too many %s items exceeds %d", __LINE__,
|
||||
config_filename, section_name,
|
||||
SERVER_ITEM_HOST_STR, FC_MAX_SERVER_IP_COUNT);
|
||||
return ENOSPC;
|
||||
}
|
||||
|
||||
hosts[host_count++] = it->value;
|
||||
} else {
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config filename: %s, section: %s, unkown item name: %s",
|
||||
__LINE__, config_filename, section_name, it->name);
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (host_count == 0) {
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config filename: %s, section: %s, no item: %s!",
|
||||
__LINE__, config_filename, section_name,
|
||||
SERVER_ITEM_HOST_STR);
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
/*
|
||||
inner-port = 5106
|
||||
outer-port = 5107
|
||||
|
||||
current->port = iniGetIntValue(section_name, "port",
|
||||
ini_context, ctx->default_port);
|
||||
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc_server_load_one_server(FCServerContext *ctx,
|
||||
const char *config_filename, IniContext *ini_context,
|
||||
const char *section_name)
|
||||
{
|
||||
FCServerInfo *current;
|
||||
char *endptr;
|
||||
int result;
|
||||
|
||||
if ((result=fc_server_check_alloc_servers(&ctx->
|
||||
sorted_server_arrays.by_id)) != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
current = ctx->sorted_server_arrays.by_id.servers +
|
||||
ctx->sorted_server_arrays.by_id.count;
|
||||
|
||||
endptr = NULL;
|
||||
current->id = strtol(section_name + SERVER_SECTION_PREFIX_LEN, &endptr, 10);
|
||||
if (current->id <= 0 || endptr != NULL) {
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config filename: %s, section: %s, invalid server id! "
|
||||
"server section format is [%s$id]",
|
||||
__LINE__, config_filename, section_name,
|
||||
SERVER_SECTION_PREFIX_STR);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if ((result=fc_server_load_hosts(ctx, current, config_filename,
|
||||
ini_context, section_name)) != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
ctx->sorted_server_arrays.by_id.count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc_server_load_servers(FCServerContext *ctx,
|
||||
const char *config_filename, IniContext *ini_context)
|
||||
{
|
||||
#define FIXED_SECTION_COUNT 16
|
||||
int result;
|
||||
int count;
|
||||
IniSectionInfo *sections;
|
||||
IniSectionInfo fixed[FIXED_SECTION_COUNT];
|
||||
IniSectionInfo *section;
|
||||
IniSectionInfo *end;
|
||||
int alloc_bytes;
|
||||
|
||||
count = iniGetSectionCountByPrefix(ini_context, SERVER_SECTION_PREFIX_STR);
|
||||
if (count == 0) {
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config filename: %s, no server section such as [%s$id]",
|
||||
__LINE__, config_filename, SERVER_SECTION_PREFIX_STR);
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
if (count < FIXED_SECTION_COUNT) {
|
||||
sections = fixed;
|
||||
} else {
|
||||
alloc_bytes = sizeof(IniSectionInfo) * count;
|
||||
sections = (IniSectionInfo *)malloc(alloc_bytes);
|
||||
if (sections == NULL) {
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"malloc %d bytes fail", __LINE__, alloc_bytes);
|
||||
return ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
if ((result=iniGetSectionNamesByPrefix(ini_context,
|
||||
SERVER_SECTION_PREFIX_STR, sections,
|
||||
count, &count)) != 0)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"config filename: %s, get sections by prefix %s fail, "
|
||||
"errno: %d, error info: %s", __LINE__, config_filename,
|
||||
SERVER_SECTION_PREFIX_STR, result, STRERROR(result));
|
||||
break;
|
||||
}
|
||||
|
||||
end = sections + count;
|
||||
for (section=sections; section<end; section++) {
|
||||
if ((result=fc_server_load_one_server(ctx, config_filename,
|
||||
ini_context, section->section_name)) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (sections != fixed) {
|
||||
free(sections);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int fc_server_load_data(FCServerContext *ctx, IniContext *ini_context,
|
||||
const char *config_filename)
|
||||
{
|
||||
int result;
|
||||
|
||||
if ((result=fc_server_load_groups(ctx, config_filename,
|
||||
ini_context)) != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if ((result=fc_server_load_servers(ctx, config_filename,
|
||||
ini_context)) != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
qsort(ctx->sorted_server_arrays.by_id.servers,
|
||||
ctx->sorted_server_arrays.by_id.count,
|
||||
sizeof(FCServerInfo), fc_server_cmp_server_id);
|
||||
if ((result=fc_server_check_id_duplicated(ctx, config_filename)) != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if ((result=fc_server_init_ip_port_array(ctx)) != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return fc_server_check_ip_port(ctx, config_filename);
|
||||
}
|
||||
|
||||
#define FC_SERVER_INIT_CONTEXT(ctx, port) \
|
||||
do { \
|
||||
memset(ctx, 0, sizeof(FCServerContext)); \
|
||||
ctx->default_port = port; \
|
||||
} while (0)
|
||||
|
||||
int fc_server_load_from_file_ex(FCServerContext *ctx,
|
||||
const char *config_filename, const int default_port)
|
||||
{
|
||||
IniContext ini_context;
|
||||
int result;
|
||||
|
||||
FC_SERVER_INIT_CONTEXT(ctx, default_port);
|
||||
if ((result=iniLoadFromFile(config_filename, &ini_context)) != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = fc_server_load_data(ctx, &ini_context, config_filename);
|
||||
iniFreeContext(&ini_context);
|
||||
return result;
|
||||
}
|
||||
|
||||
int fc_server_load_from_buffer_ex(FCServerContext *ctx, char *content,
|
||||
const char *caption, const int default_port)
|
||||
{
|
||||
IniContext ini_context;
|
||||
int result;
|
||||
|
||||
FC_SERVER_INIT_CONTEXT(ctx, default_port);
|
||||
if ((result=iniLoadFromBuffer(content, &ini_context)) != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = fc_server_load_data(ctx, &ini_context, caption);
|
||||
iniFreeContext(&ini_context);
|
||||
return result;
|
||||
}
|
||||
|
||||
void fc_server_destroy(FCServerContext *ctx)
|
||||
{
|
||||
if (ctx->sorted_server_arrays.by_ip_port.maps != NULL) {
|
||||
free(ctx->sorted_server_arrays.by_ip_port.maps);
|
||||
ctx->sorted_server_arrays.by_ip_port.maps = NULL;
|
||||
ctx->sorted_server_arrays.by_ip_port.count = 0;
|
||||
}
|
||||
|
||||
if (ctx->sorted_server_arrays.by_id.servers != NULL) {
|
||||
free(ctx->sorted_server_arrays.by_id.servers);
|
||||
ctx->sorted_server_arrays.by_id.servers = NULL;
|
||||
ctx->sorted_server_arrays.by_id.count = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
//server_id_func.h
|
||||
|
||||
#ifndef _SERVER_ID_FUNC_H
|
||||
#define _SERVER_ID_FUNC_H
|
||||
|
||||
#include "common_define.h"
|
||||
#include "connection_pool.h"
|
||||
#include "ini_file_reader.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define FC_MAX_SERVER_IP_COUNT 8
|
||||
#define FC_MAX_GROUP_COUNT 4
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int net_type;
|
||||
ConnectionInfo conn;
|
||||
} FCAddressInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
string_t group_name;
|
||||
int port; //default port
|
||||
int server_port; //port in server section
|
||||
struct {
|
||||
int net_type;
|
||||
string_t ip_prefix;
|
||||
char prefix_buff[IP_ADDRESS_SIZE];
|
||||
} filter;
|
||||
char name_buff[FAST_INI_ITEM_NAME_SIZE]; //group_name string holder
|
||||
} FCServerGroupInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int count;
|
||||
FCServerGroupInfo groups[FC_MAX_GROUP_COUNT];
|
||||
} FCServerGroupArray;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FCServerGroupInfo *server_group;
|
||||
struct {
|
||||
int count;
|
||||
FCAddressInfo addrs[FC_MAX_SERVER_IP_COUNT];
|
||||
} address_array;
|
||||
} FCGroupAddresses;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int id; //server id
|
||||
struct {
|
||||
int count;
|
||||
FCGroupAddresses group_addrs[FC_MAX_GROUP_COUNT];
|
||||
} group_array;
|
||||
} FCServerInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
string_t ip_addr;
|
||||
int port;
|
||||
FCServerInfo *server;
|
||||
} FCServerMap;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int alloc;
|
||||
int count;
|
||||
FCServerInfo *servers;
|
||||
} FCServerInfoArray;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int count;
|
||||
FCServerMap *maps;
|
||||
} FCServerMapArray;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int default_port;
|
||||
FCServerGroupArray group_array;
|
||||
struct {
|
||||
FCServerInfoArray by_id; //sorted by server id
|
||||
FCServerMapArray by_ip_port; //sorted by IP and port
|
||||
} sorted_server_arrays;
|
||||
} FCServerContext;
|
||||
|
||||
FCServerInfo *fc_server_get_by_id(FCServerContext *ctx,
|
||||
const int server_id);
|
||||
|
||||
FCServerInfo *fc_server_get_by_ip_port_ex(FCServerContext *ctx,
|
||||
const string_t *ip_addr, const int port);
|
||||
|
||||
static inline FCServerInfo *fc_server_get_by_ip_port(FCServerContext *ctx,
|
||||
const char *ip_addr, const int port)
|
||||
{
|
||||
string_t saddr;
|
||||
FC_SET_STRING(saddr, (char *)ip_addr);
|
||||
return fc_server_get_by_ip_port_ex(ctx, &saddr, port);
|
||||
}
|
||||
|
||||
int fc_server_load_from_file_ex(FCServerContext *ctx,
|
||||
const char *config_filename, const int default_port);
|
||||
|
||||
static inline int fc_server_load_from_file(FCServerContext *ctx,
|
||||
const char *config_filename)
|
||||
{
|
||||
const int default_port = 0;
|
||||
return fc_server_load_from_file_ex(ctx, config_filename, default_port);
|
||||
}
|
||||
|
||||
int fc_server_load_from_buffer_ex(FCServerContext *ctx, char *content,
|
||||
const char *caption, const int default_port);
|
||||
|
||||
static inline int fc_server_load_from_buffer(FCServerContext *ctx,
|
||||
char *content)
|
||||
{
|
||||
const char *caption = "from-buffer";
|
||||
const int default_port = 0;
|
||||
return fc_server_load_from_buffer_ex(ctx, content, caption, default_port);
|
||||
}
|
||||
|
||||
void fc_server_destroy(FCServerContext *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -19,6 +19,14 @@
|
|||
#include <sys/socket.h>
|
||||
#include "common_define.h"
|
||||
|
||||
#define FC_NET_TYPE_NONE 0
|
||||
#define FC_NET_TYPE_OUTER 1 //extranet IP
|
||||
#define FC_NET_TYPE_INNER 2 //intranet IP
|
||||
|
||||
#define FC_SUB_NET_TYPE_INNER_10 (FC_NET_TYPE_INNER | 4)
|
||||
#define FC_SUB_NET_TYPE_INNER_172 (FC_NET_TYPE_INNER | 8)
|
||||
#define FC_SUB_NET_TYPE_INNER_192 (FC_NET_TYPE_INNER | 16)
|
||||
|
||||
#define FAST_WRITE_BUFF_SIZE (256 * 1024)
|
||||
|
||||
typedef struct fast_if_config {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
|
||||
[group-inner]
|
||||
port = 5108
|
||||
|
||||
# outer: extranet IP, such as 202.102.100.1
|
||||
# inner: intranet IP such as 172.16.1.5 or 192.168.3.17
|
||||
# inner-10: 10 leading network, such as 10.32.1.100
|
||||
# inner-172: 172 leading network, such as 172.17.0.4
|
||||
# inner-192: 192 leading network, such as 192.168.0.1
|
||||
net_type = inner-172
|
||||
ip_prefix = 172.
|
||||
|
||||
[group-outer]
|
||||
port = 5109
|
||||
net_type = outer
|
||||
ip_prefix =
|
||||
|
||||
# config a server
|
||||
# section format: [server-$id]
|
||||
# server id is a 32 bits natural number (1, 2, 3 etc.),
|
||||
[server-1]
|
||||
|
||||
# format: host[:port]
|
||||
# host can be an IP or a hostname
|
||||
# can occur more than once
|
||||
host = 172.17.7.215
|
||||
host = 39.100.8.166
|
||||
|
||||
|
||||
[server-2]
|
||||
inner-port = 5106
|
||||
outer-port = 5107
|
||||
host = 172.17.7.215
|
||||
host = 39.100.8.166
|
||||
Loading…
Reference in New Issue