Merged changes from github.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
This commit is contained in:
commit
f6af8cf389
@ -1,3 +1,12 @@
|
|||||||
|
0.2.6:
|
||||||
|
- Better "!uptime" command formatting.
|
||||||
|
- Better "!stats"; can display peak and current bandwidth usage.
|
||||||
|
- Added "+myip" command.
|
||||||
|
- Ensure super users and hub owners also have the operator flag set.
|
||||||
|
- Bug #1: Better dynamic send queue handling for large hubs at the cost of more memory use.
|
||||||
|
- Bug #5: Always provide IP-address to all users, not just for active clients.
|
||||||
|
|
||||||
|
|
||||||
0.2.5-3487:
|
0.2.5-3487:
|
||||||
- Fixed out of memory situations, used when uhub operates on a limited heap.
|
- Fixed out of memory situations, used when uhub operates on a limited heap.
|
||||||
- Code cleanups, reduced heap memory footprint.
|
- Code cleanups, reduced heap memory footprint.
|
||||||
|
@ -134,8 +134,8 @@ typedef uint32_t fourcc_t;
|
|||||||
#define ADC_CLIENT_TYPE_BOT "1"
|
#define ADC_CLIENT_TYPE_BOT "1"
|
||||||
#define ADC_CLIENT_TYPE_REGISTERED_USER "2"
|
#define ADC_CLIENT_TYPE_REGISTERED_USER "2"
|
||||||
#define ADC_CLIENT_TYPE_OPERATOR "4"
|
#define ADC_CLIENT_TYPE_OPERATOR "4"
|
||||||
#define ADC_CLIENT_TYPE_SUPER_USER "8"
|
#define ADC_CLIENT_TYPE_SUPER_USER "12" /* 8 + 4 */
|
||||||
#define ADC_CLIENT_TYPE_ADMIN "16" /* hub owner */
|
#define ADC_CLIENT_TYPE_ADMIN "20" /* 16 + 4 = hub owner */
|
||||||
#define ADC_CLIENT_TYPE_HUB "32" /* the hub itself */
|
#define ADC_CLIENT_TYPE_HUB "32" /* the hub itself */
|
||||||
|
|
||||||
|
|
||||||
|
12
src/auth.c
12
src/auth.c
@ -53,7 +53,7 @@ static int check_cmd_bool(const char* cmd, struct linked_list* list, char* line,
|
|||||||
data++;
|
data++;
|
||||||
|
|
||||||
data = strip_white_space(data);
|
data = strip_white_space(data);
|
||||||
if (!strlen(data))
|
if (!*data)
|
||||||
{
|
{
|
||||||
hub_log(log_fatal, "ACL parse error on line %d", line_count);
|
hub_log(log_fatal, "ACL parse error on line %d", line_count);
|
||||||
return -1;
|
return -1;
|
||||||
@ -80,7 +80,7 @@ static int check_cmd_user(const char* cmd, int status, struct linked_list* list,
|
|||||||
data++;
|
data++;
|
||||||
|
|
||||||
data = strip_white_space(data);
|
data = strip_white_space(data);
|
||||||
if (!strlen(data))
|
if (!*data)
|
||||||
{
|
{
|
||||||
hub_log(log_fatal, "ACL parse error on line %d", line_count);
|
hub_log(log_fatal, "ACL parse error on line %d", line_count);
|
||||||
return -1;
|
return -1;
|
||||||
@ -192,7 +192,7 @@ static int check_cmd_addr(const char* cmd, struct linked_list* list, char* line,
|
|||||||
data1++;
|
data1++;
|
||||||
|
|
||||||
data1 = strip_white_space(data1);
|
data1 = strip_white_space(data1);
|
||||||
if (!strlen(data1))
|
if (!*data1)
|
||||||
{
|
{
|
||||||
hub_log(log_fatal, "ACL parse error on line %d", line_count);
|
hub_log(log_fatal, "ACL parse error on line %d", line_count);
|
||||||
return -1;
|
return -1;
|
||||||
@ -266,7 +266,7 @@ static int acl_parse_line(char* line, int line_count, void* ptr_data)
|
|||||||
pos[0] = 0;
|
pos[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen(line) == 0)
|
if (!*line)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#ifdef ACL_DEBUG
|
#ifdef ACL_DEBUG
|
||||||
@ -274,7 +274,7 @@ static int acl_parse_line(char* line, int line_count, void* ptr_data)
|
|||||||
#endif
|
#endif
|
||||||
line = strip_white_space(line);
|
line = strip_white_space(line);
|
||||||
|
|
||||||
if (!strlen(line))
|
if (!*line)
|
||||||
{
|
{
|
||||||
hub_log(log_fatal, "ACL parse error on line %d", line_count);
|
hub_log(log_fatal, "ACL parse error on line %d", line_count);
|
||||||
return -1;
|
return -1;
|
||||||
@ -328,7 +328,7 @@ int acl_initialize(struct hub_config* config, struct acl_handle* handle)
|
|||||||
|
|
||||||
if (config)
|
if (config)
|
||||||
{
|
{
|
||||||
if (strlen(config->file_acl) == 0) return 0;
|
if (!*config->file_acl) return 0;
|
||||||
|
|
||||||
ret = file_read_lines(config->file_acl, handle, &acl_parse_line);
|
ret = file_read_lines(config->file_acl, handle, &acl_parse_line);
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
|
@ -39,8 +39,16 @@ static int command_stats(struct user* user, const char* message)
|
|||||||
if (user->credentials < cred_super)
|
if (user->credentials < cred_super)
|
||||||
return command_access_denied(user);
|
return command_access_denied(user);
|
||||||
|
|
||||||
char temp[64];
|
char temp[128];
|
||||||
snprintf(temp, 64, "*** Stats: %u users, peak %u", (unsigned int) user->hub->users->count, (unsigned int) user->hub->users->count_peak);
|
|
||||||
|
snprintf(temp, 128, "*** Stats: %zu users, peak: %zu. Network (up/down): %d/%d KB/s, peak: %d/%d KB/s",
|
||||||
|
user->hub->users->count,
|
||||||
|
user->hub->users->count_peak,
|
||||||
|
(int) user->hub->stats.net_tx / 1024,
|
||||||
|
(int) user->hub->stats.net_rx / 1024,
|
||||||
|
(int) user->hub->stats.net_tx_peak / 1024,
|
||||||
|
(int) user->hub->stats.net_rx_peak / 1024);
|
||||||
|
|
||||||
char* buffer = adc_msg_escape(temp);
|
char* buffer = adc_msg_escape(temp);
|
||||||
command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
|
command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
|
||||||
adc_msg_add_argument(command, buffer);
|
adc_msg_add_argument(command, buffer);
|
||||||
@ -54,7 +62,7 @@ static int command_stats(struct user* user, const char* message)
|
|||||||
static int command_help(struct user* user, const char* message)
|
static int command_help(struct user* user, const char* message)
|
||||||
{
|
{
|
||||||
struct adc_message* command;
|
struct adc_message* command;
|
||||||
char* buffer = adc_msg_escape(
|
char* buffer = adc_msg_escape("\n"
|
||||||
"*** Available commands:\n"
|
"*** Available commands:\n"
|
||||||
"!help - Show this help message\n"
|
"!help - Show this help message\n"
|
||||||
"!stats - Show hub stats (super)\n"
|
"!stats - Show hub stats (super)\n"
|
||||||
@ -74,9 +82,36 @@ static int command_help(struct user* user, const char* message)
|
|||||||
static int command_uptime(struct user* user, const char* message)
|
static int command_uptime(struct user* user, const char* message)
|
||||||
{
|
{
|
||||||
struct adc_message* command;
|
struct adc_message* command;
|
||||||
char temp[64];
|
char tmp[128];
|
||||||
snprintf(temp, 64, "*** Uptime: %s seconds", uhub_itoa((int) difftime(time(0), user->hub->tm_started)));
|
size_t d;
|
||||||
char* buffer = adc_msg_escape(temp);
|
size_t h;
|
||||||
|
size_t m;
|
||||||
|
size_t D = (size_t) difftime(time(0), user->hub->tm_started);
|
||||||
|
|
||||||
|
d = D / (24 * 3600);
|
||||||
|
D = D % (24 * 3600);
|
||||||
|
h = D / 3600;
|
||||||
|
D = D % 3600;
|
||||||
|
m = D / 60;
|
||||||
|
|
||||||
|
tmp[0] = 0;
|
||||||
|
strcat(tmp, "*** Uptime: ");
|
||||||
|
|
||||||
|
if (d)
|
||||||
|
{
|
||||||
|
strcat(tmp, uhub_itoa((int) d));
|
||||||
|
strcat(tmp, " day");
|
||||||
|
if (d != 1) strcat(tmp, "s");
|
||||||
|
strcat(tmp, ", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h < 10) strcat(tmp, "0");
|
||||||
|
strcat(tmp, uhub_itoa((int) h));
|
||||||
|
strcat(tmp, ":");
|
||||||
|
if (m < 10) strcat(tmp, "0");
|
||||||
|
strcat(tmp, uhub_itoa((int) m));
|
||||||
|
|
||||||
|
char* buffer = adc_msg_escape(tmp);
|
||||||
command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
|
command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
|
||||||
adc_msg_add_argument(command, buffer);
|
adc_msg_add_argument(command, buffer);
|
||||||
route_to_user(user, command);
|
route_to_user(user, command);
|
||||||
@ -113,6 +148,26 @@ static int command_version(struct user* user, const char* message)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int command_myip(struct user* user, const char* message)
|
||||||
|
{
|
||||||
|
struct adc_message* command;
|
||||||
|
char tmp[128];
|
||||||
|
char* buffer;
|
||||||
|
|
||||||
|
tmp[0] = 0;
|
||||||
|
strcat(tmp, "*** Your IP: ");
|
||||||
|
strcat(tmp, ip_convert_to_string(&user->ipaddr));
|
||||||
|
|
||||||
|
buffer = adc_msg_escape(tmp);
|
||||||
|
command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
|
||||||
|
adc_msg_add_argument(command, buffer);
|
||||||
|
route_to_user(user, command);
|
||||||
|
adc_msg_free(command);
|
||||||
|
hub_free(buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int command_dipatcher(struct user* user, const char* message)
|
int command_dipatcher(struct user* user, const char* message)
|
||||||
{
|
{
|
||||||
if (!strncmp(message, "!stats", 6)) command_stats(user, message);
|
if (!strncmp(message, "!stats", 6)) command_stats(user, message);
|
||||||
@ -120,6 +175,7 @@ int command_dipatcher(struct user* user, const char* message)
|
|||||||
else if (!strncmp(message, "!kick", 5)) command_kick(user, message);
|
else if (!strncmp(message, "!kick", 5)) command_kick(user, message);
|
||||||
else if (!strncmp(message, "!version", 8)) command_version(user, message);
|
else if (!strncmp(message, "!version", 8)) command_version(user, message);
|
||||||
else if (!strncmp(message, "!uptime", 7)) command_uptime(user, message);
|
else if (!strncmp(message, "!uptime", 7)) command_uptime(user, message);
|
||||||
|
else if (!strncmp(message, "+myip", 5)) command_myip(user, message);
|
||||||
else
|
else
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -64,7 +64,7 @@
|
|||||||
int val; \
|
int val; \
|
||||||
errno = 0; \
|
errno = 0; \
|
||||||
val = strtol(data, &endptr, 10); \
|
val = strtol(data, &endptr, 10); \
|
||||||
if (((errno == ERANGE && (val == INT_MAX || val == INT_MIN)) || (errno != 0 && val == 0)) || endptr == data /*|| endptr != &data[strlen(data)-1]*/) { \
|
if (((errno == ERANGE && (val == INT_MAX || val == INT_MIN)) || (errno != 0 && val == 0)) || endptr == data) { \
|
||||||
hub_log(log_fatal, "Configuration error on line %d: '%s' must be a number", line_count, key); \
|
hub_log(log_fatal, "Configuration error on line %d: '%s' must be a number", line_count, key); \
|
||||||
return -1; \
|
return -1; \
|
||||||
} \
|
} \
|
||||||
@ -458,7 +458,7 @@ static int config_parse_line(char* line, int line_count, void* ptr_data)
|
|||||||
pos[0] = 0;
|
pos[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen(line) == 0) return 0;
|
if (!*line) return 0;
|
||||||
|
|
||||||
#ifdef CONFIG_DUMP
|
#ifdef CONFIG_DUMP
|
||||||
hub_log(log_trace, "config_parse_line(): '%s'", line);
|
hub_log(log_trace, "config_parse_line(): '%s'", line);
|
||||||
@ -479,7 +479,7 @@ static int config_parse_line(char* line, int line_count, void* ptr_data)
|
|||||||
key = strip_white_space(key);
|
key = strip_white_space(key);
|
||||||
data = strip_white_space(data);
|
data = strip_white_space(data);
|
||||||
|
|
||||||
if (!strlen(key) || !strlen(data))
|
if (!*key || !*data)
|
||||||
{
|
{
|
||||||
hub_log(log_fatal, "Configuration parse error on line %d", line_count);
|
hub_log(log_fatal, "Configuration parse error on line %d", line_count);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -35,8 +35,8 @@ struct hub_config
|
|||||||
char* hub_name; /**<<< "Name of hub (default: 'My uhub hub')" */
|
char* hub_name; /**<<< "Name of hub (default: 'My uhub hub')" */
|
||||||
char* hub_description; /**<<< "Name of hub (default: 'no description')" */
|
char* hub_description; /**<<< "Name of hub (default: 'no description')" */
|
||||||
int max_recv_buffer; /**<<< "Max read buffer before parse, per user (default: 4096)" */
|
int max_recv_buffer; /**<<< "Max read buffer before parse, per user (default: 4096)" */
|
||||||
int max_send_buffer; /**<<< "Max send buffer before disconnect, per user (default: 16384)" */
|
int max_send_buffer; /**<<< "Max send buffer before disconnect, per user (default: 128K)" */
|
||||||
int max_send_buffer_soft; /**<<< "Max send buffer before message drops, per user (default: 8192)" */
|
int max_send_buffer_soft; /**<<< "Max send buffer before message drops, per user (default: 96K)" */
|
||||||
int low_bandwidth_mode; /**<<< "If this is enabled, the hub will strip off elements from each user's info message to reduce bandwidth usage" */
|
int low_bandwidth_mode; /**<<< "If this is enabled, the hub will strip off elements from each user's info message to reduce bandwidth usage" */
|
||||||
|
|
||||||
/* Limits enforced on users */
|
/* Limits enforced on users */
|
||||||
|
@ -189,7 +189,7 @@ int hub_handle_chat_message(struct user* u, struct adc_message* cmd)
|
|||||||
int relay = 1;
|
int relay = 1;
|
||||||
|
|
||||||
/* TODO: Check for hub-commands here. Set relay to 0 and the message will not be sent to other users. */
|
/* TODO: Check for hub-commands here. Set relay to 0 and the message will not be sent to other users. */
|
||||||
if (message[0] == '!')
|
if (message[0] == '!' || message[0] == '+')
|
||||||
{
|
{
|
||||||
relay = command_dipatcher(u, message);
|
relay = command_dipatcher(u, message);
|
||||||
}
|
}
|
||||||
|
14
src/hub.h
14
src/hub.h
@ -66,6 +66,19 @@ enum hub_state
|
|||||||
hub_status_disabled = 5, /**<<<"Hub is disabled (Running, but not accepting users) */
|
hub_status_disabled = 5, /**<<<"Hub is disabled (Running, but not accepting users) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Always updated each minute.
|
||||||
|
*/
|
||||||
|
struct hub_stats
|
||||||
|
{
|
||||||
|
size_t net_tx;
|
||||||
|
size_t net_rx;
|
||||||
|
size_t net_tx_peak;
|
||||||
|
size_t net_rx_peak;
|
||||||
|
size_t net_tx_total;
|
||||||
|
size_t net_rx_total;
|
||||||
|
};
|
||||||
|
|
||||||
struct hub_info
|
struct hub_info
|
||||||
{
|
{
|
||||||
int fd_tcp;
|
int fd_tcp;
|
||||||
@ -77,6 +90,7 @@ struct hub_info
|
|||||||
#ifdef ADC_UDP_OPERATION
|
#ifdef ADC_UDP_OPERATION
|
||||||
struct event ev_datagram;
|
struct event ev_datagram;
|
||||||
#endif
|
#endif
|
||||||
|
struct hub_stats stats;
|
||||||
struct event_queue* queue;
|
struct event_queue* queue;
|
||||||
struct hub_config* config;
|
struct hub_config* config;
|
||||||
struct user_manager* users;
|
struct user_manager* users;
|
||||||
|
62
src/inf.c
62
src/inf.c
@ -58,7 +58,7 @@ static int set_feature_cast_supports(struct user* u, struct adc_message* cmd)
|
|||||||
it = &it[5];
|
it = &it[5];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen(it) > 0)
|
if (*it)
|
||||||
{
|
{
|
||||||
user_set_feature_cast_support(u, it);
|
user_set_feature_cast_support(u, it);
|
||||||
}
|
}
|
||||||
@ -188,65 +188,37 @@ static int check_required_login_flags(struct user* user, struct adc_message* cmd
|
|||||||
*/
|
*/
|
||||||
int check_network(struct user* user, struct adc_message* cmd)
|
int check_network(struct user* user, struct adc_message* cmd)
|
||||||
{
|
{
|
||||||
int want_ipv4 = 0;
|
const char* address = ip_convert_to_string(&user->ipaddr);
|
||||||
int want_ipv6 = 0;
|
|
||||||
int nat_override = 0;
|
|
||||||
const char* address = 0;
|
|
||||||
|
|
||||||
if (adc_msg_has_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR))
|
/* Check for NAT override address */
|
||||||
{
|
if (acl_is_ip_nat_override(user->hub->acl, address))
|
||||||
want_ipv6 = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (adc_msg_has_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR))
|
|
||||||
{
|
|
||||||
want_ipv4 = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!want_ipv4 && !want_ipv6)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Add correct/verified IP addresses instead (if requested/stripped) */
|
|
||||||
address = (char*) net_get_peer_address(user->sd);
|
|
||||||
if (address)
|
|
||||||
{
|
|
||||||
if (want_ipv4 && strchr(address, '.'))
|
|
||||||
{
|
|
||||||
want_ipv6 = 0;
|
|
||||||
}
|
|
||||||
else if (want_ipv6)
|
|
||||||
{
|
|
||||||
want_ipv4 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check if user can do nat override */
|
|
||||||
if (want_ipv4 && acl_is_ip_nat_override(user->hub->acl, address))
|
|
||||||
{
|
{
|
||||||
char* client_given_ip = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
|
char* client_given_ip = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
|
||||||
if (strcmp(client_given_ip, "0.0.0.0") != 0)
|
if (strcmp(client_given_ip, "0.0.0.0") != 0)
|
||||||
{
|
{
|
||||||
user_set_nat_override(user);
|
user_set_nat_override(user);
|
||||||
nat_override = 1;
|
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR);
|
||||||
|
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_UDP_PORT);
|
||||||
|
hub_free(client_given_ip);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
hub_free(client_given_ip);
|
hub_free(client_given_ip);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!nat_override)
|
if (strchr(address, '.'))
|
||||||
|
{
|
||||||
|
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR);
|
||||||
|
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_UDP_PORT);
|
||||||
|
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
|
||||||
|
adc_msg_add_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR, address);
|
||||||
|
}
|
||||||
|
else if (strchr(address, ':'))
|
||||||
{
|
{
|
||||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
|
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
|
||||||
if (!want_ipv4)
|
|
||||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_UDP_PORT);
|
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_UDP_PORT);
|
||||||
else
|
|
||||||
adc_msg_add_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR, address);
|
|
||||||
|
|
||||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR);
|
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR);
|
||||||
if (!want_ipv6)
|
|
||||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_UDP_PORT);
|
|
||||||
else
|
|
||||||
adc_msg_add_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR, address);
|
adc_msg_add_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,7 +331,7 @@ static int check_logged_in(struct user* user, struct adc_message* cmd)
|
|||||||
{
|
{
|
||||||
if (lookup1 == lookup2)
|
if (lookup1 == lookup2)
|
||||||
{
|
{
|
||||||
hub_log(log_debug, "check_logged_in: exact same user is logged in: %s", user->id.nick);
|
hub_log(log_error, "check_logged_in: exact same user is logged in: %s", user->id.nick);
|
||||||
user_disconnect(lookup1, quit_timeout);
|
user_disconnect(lookup1, quit_timeout);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ int ip_convert_to_binary(const char* taddr, struct ip_addr_encap* raw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char* ip_convert_to_string(struct ip_addr_encap* raw)
|
const char* ip_convert_to_string(struct ip_addr_encap* raw)
|
||||||
{
|
{
|
||||||
static char address[INET6_ADDRSTRLEN+1];
|
static char address[INET6_ADDRSTRLEN+1];
|
||||||
memset(address, 0, INET6_ADDRSTRLEN);
|
memset(address, 0, INET6_ADDRSTRLEN);
|
||||||
|
@ -36,7 +36,7 @@ struct ip_addr_encap {
|
|||||||
|
|
||||||
extern int ip_convert_to_binary(const char* text_addr, struct ip_addr_encap* raw);
|
extern int ip_convert_to_binary(const char* text_addr, struct ip_addr_encap* raw);
|
||||||
|
|
||||||
extern char* ip_convert_to_string(struct ip_addr_encap* raw);
|
extern const char* ip_convert_to_string(struct ip_addr_encap* raw);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -70,7 +70,7 @@ void hub_handle_signal(int fd, short events, void* arg)
|
|||||||
case SIGUSR2:
|
case SIGUSR2:
|
||||||
hub_log(log_trace, "hub_handle_signal(): caught SIGUSR2");
|
hub_log(log_trace, "hub_handle_signal(): caught SIGUSR2");
|
||||||
{
|
{
|
||||||
user_manager_stats(hub);
|
user_manager_print_stats(hub);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -688,7 +688,7 @@ char* adc_msg_get_argument(struct adc_message* cmd, int offset)
|
|||||||
argument[strlen(argument)-1] = 0;
|
argument[strlen(argument)-1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen(argument))
|
if (*argument)
|
||||||
{
|
{
|
||||||
adc_msg_terminate(cmd);
|
adc_msg_terminate(cmd);
|
||||||
return argument;
|
return argument;
|
||||||
|
@ -38,8 +38,8 @@ char* strip_white_space(char* string)
|
|||||||
|
|
||||||
while (string[0] && is_white_space(string[0])) string++;
|
while (string[0] && is_white_space(string[0])) string++;
|
||||||
|
|
||||||
if (!strlen(string))
|
if (!*string)
|
||||||
return string;
|
return 0;
|
||||||
|
|
||||||
/* Strip appending whitespace */
|
/* Strip appending whitespace */
|
||||||
pos = &string[strlen(string)-1];
|
pos = &string[strlen(string)-1];
|
||||||
@ -187,7 +187,7 @@ int file_read_lines(const char* file, void* data, file_line_handler_t handler)
|
|||||||
while ((pos = strchr(start, '\n')))
|
while ((pos = strchr(start, '\n')))
|
||||||
{
|
{
|
||||||
pos[0] = '\0';
|
pos[0] = '\0';
|
||||||
if (strlen(start) > 0)
|
if (*start)
|
||||||
{
|
{
|
||||||
hub_log(log_dump, "Line: %s", start);
|
hub_log(log_dump, "Line: %s", start);
|
||||||
if (handler(start, line_count+1, data) < 0)
|
if (handler(start, line_count+1, data) < 0)
|
||||||
@ -197,7 +197,7 @@ int file_read_lines(const char* file, void* data, file_line_handler_t handler)
|
|||||||
line_count++;
|
line_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen(start) > 0)
|
if (*start)
|
||||||
{
|
{
|
||||||
buf[strlen(start)] = 0;
|
buf[strlen(start)] = 0;
|
||||||
hub_log(log_dump, "Line: %s", start);
|
hub_log(log_dump, "Line: %s", start);
|
||||||
|
@ -79,7 +79,7 @@ void net_on_read(int fd, short ev, void *arg)
|
|||||||
while ((pos = strchr(start, '\n')))
|
while ((pos = strchr(start, '\n')))
|
||||||
{
|
{
|
||||||
pos[0] = '\0';
|
pos[0] = '\0';
|
||||||
if (strlen(start) > 0 && strlen(start) < user->hub->config->max_recv_buffer)
|
if (*start && strlen(start) < user->hub->config->max_recv_buffer)
|
||||||
{
|
{
|
||||||
if (hub_handle_message(user, start, &pos[0]-&start[0]) == -1)
|
if (hub_handle_message(user, start, &pos[0]-&start[0]) == -1)
|
||||||
{
|
{
|
||||||
@ -176,6 +176,10 @@ void net_on_write(int fd, short ev, void *arg)
|
|||||||
{
|
{
|
||||||
user->send_queue_size -= ret;
|
user->send_queue_size -= ret;
|
||||||
user->send_queue_offset = 0;
|
user->send_queue_offset = 0;
|
||||||
|
|
||||||
|
assert(user->send_queue_size >= 0);
|
||||||
|
assert(user->send_queue_offset >= 0);
|
||||||
|
|
||||||
list_remove(user->send_queue, msg);
|
list_remove(user->send_queue, msg);
|
||||||
|
|
||||||
if (user_flag_get(user, flag_user_list) && (msg == user->info || user->send_queue_size == 0))
|
if (user_flag_get(user, flag_user_list) && (msg == user->info || user->send_queue_size == 0))
|
||||||
@ -193,6 +197,9 @@ void net_on_write(int fd, short ev, void *arg)
|
|||||||
{
|
{
|
||||||
user->send_queue_size -= ret;
|
user->send_queue_size -= ret;
|
||||||
user->send_queue_offset += ret;
|
user->send_queue_offset += ret;
|
||||||
|
|
||||||
|
assert(user->send_queue_size >= 0);
|
||||||
|
assert(user->send_queue_offset >= 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -591,19 +591,6 @@ void net_stats_get(struct net_statistics** intermediate, struct net_statistics**
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void net_stats_report()
|
|
||||||
{
|
|
||||||
int factor = (time(NULL) - stats.timestamp);
|
|
||||||
if (!factor) factor++;
|
|
||||||
|
|
||||||
hub_log(log_info, "Statistics NET: tx=%d KB/s, rx=%d KB/s, (acc=%d/cls=%d/err=%d)",
|
|
||||||
(int) ((stats.tx / factor) / 1024),
|
|
||||||
(int) ((stats.rx / factor) / 1024),
|
|
||||||
(int) stats.accept,
|
|
||||||
(int) stats.closed,
|
|
||||||
(int) stats.errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
void net_stats_reset()
|
void net_stats_reset()
|
||||||
{
|
{
|
||||||
stats_total.tx += stats.tx;
|
stats_total.tx += stats.tx;
|
||||||
@ -619,8 +606,7 @@ void net_stats_reset()
|
|||||||
|
|
||||||
int net_stats_timeout()
|
int net_stats_timeout()
|
||||||
{
|
{
|
||||||
/* FIXME: Configurable time for dumping network statistics */
|
return (difftime(time(NULL), stats.timestamp) > TIMEOUT_STATS) ? 1 : 0;
|
||||||
return (time(NULL) - stats.timestamp > 60) ? 1 : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
37
src/route.c
37
src/route.c
@ -80,6 +80,26 @@ static void queue_command(struct user* user, struct adc_message* msg__, int offs
|
|||||||
}
|
}
|
||||||
|
|
||||||
// #define ALWAYS_QUEUE_MESSAGES
|
// #define ALWAYS_QUEUE_MESSAGES
|
||||||
|
static size_t get_max_send_queue(struct hub_info* hub)
|
||||||
|
{
|
||||||
|
return MAX(hub->config->max_send_buffer, (hub->config->max_recv_buffer * hub_get_user_count(hub)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @return 1 if send queue is OK.
|
||||||
|
* -1 if send queue is overflowed
|
||||||
|
* 0 if soft send queue is overflowed (not implemented at the moment)
|
||||||
|
*/
|
||||||
|
static int check_send_queue(struct user* user, struct adc_message* msg)
|
||||||
|
{
|
||||||
|
if (user_flag_get(user, flag_user_list))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if ((user->send_queue_size + msg->length) > get_max_send_queue(user->hub))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int route_to_user(struct user* user, struct adc_message* msg)
|
int route_to_user(struct user* user, struct adc_message* msg)
|
||||||
{
|
{
|
||||||
@ -118,24 +138,23 @@ int route_to_user(struct user* user, struct adc_message* msg)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (!user_flag_get(user, flag_user_list) && user->send_queue_size + msg->length > user->hub->config->max_send_buffer && msg->priority >= 0)
|
ret = check_send_queue(user, msg);
|
||||||
|
if (ret == -1)
|
||||||
{
|
{
|
||||||
/* User is not able to swallow the data, let's cut our losses and disconnect. */
|
/* User is not able to swallow the data, let's cut our losses and disconnect. */
|
||||||
user_disconnect(user, quit_send_queue);
|
user_disconnect(user, quit_send_queue);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
else
|
else if (ret == 1)
|
||||||
{
|
|
||||||
if (user->send_queue_size + msg->length > user->hub->config->max_send_buffer_soft && msg->priority >= 0)
|
|
||||||
{
|
|
||||||
/* Don't queue this message if it is low priority! */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
/* queue command */
|
||||||
queue_command(user, msg, 0);
|
queue_command(user, msg, 0);
|
||||||
if (user->ev_write)
|
if (user->ev_write)
|
||||||
event_add(user->ev_write, NULL);
|
event_add(user->ev_write, NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* do not queue command as our soft-limits are exceeded */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@
|
|||||||
#define TIMEOUT_HANDSHAKE 30
|
#define TIMEOUT_HANDSHAKE 30
|
||||||
#define TIMEOUT_SENDQ 120
|
#define TIMEOUT_SENDQ 120
|
||||||
#define TIMEOUT_IDLE 7200
|
#define TIMEOUT_IDLE 7200
|
||||||
#define TIMEOUT_STATS 3600
|
#define TIMEOUT_STATS 60
|
||||||
|
|
||||||
#define MAX_CLIENTS 512
|
#define MAX_CLIENTS 512
|
||||||
#define MAX_CID_LEN 39
|
#define MAX_CID_LEN 39
|
||||||
|
@ -39,30 +39,40 @@ static void clear_user_list_callback(void* ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void user_manager_stats(struct hub_info* hub)
|
void user_manager_update_stats(struct hub_info* hub)
|
||||||
{
|
{
|
||||||
int factor = 0;
|
const int factor = TIMEOUT_STATS;
|
||||||
struct net_statistics* total;
|
struct net_statistics* total;
|
||||||
struct net_statistics* intermediate;
|
struct net_statistics* intermediate;
|
||||||
net_stats_get(&intermediate, &total);
|
net_stats_get(&intermediate, &total);
|
||||||
|
|
||||||
factor = (time(NULL) - intermediate->timestamp);
|
hub->stats.net_tx = (intermediate->tx / factor);
|
||||||
if (!factor) factor++;
|
hub->stats.net_rx = (intermediate->rx / factor);
|
||||||
|
hub->stats.net_tx_peak = MAX(hub->stats.net_tx, hub->stats.net_tx_peak);
|
||||||
hub_log(log_info, "Statistics users=%zu, net_tx=%d KB/s, net_rx=%d KB/s",
|
hub->stats.net_rx_peak = MAX(hub->stats.net_rx, hub->stats.net_rx_peak);
|
||||||
hub->users->count,
|
hub->stats.net_tx_total = total->tx;
|
||||||
(int) ((intermediate->tx / factor) / 1024),
|
hub->stats.net_rx_total = total->rx;
|
||||||
(int) ((intermediate->rx / factor) / 1024));
|
|
||||||
|
|
||||||
net_stats_reset();
|
net_stats_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void user_manager_print_stats(struct hub_info* hub)
|
||||||
|
{
|
||||||
|
hub_log(log_info, "Statistics users=%zu (peak_users=%zu), net_tx=%d KB/s, net_rx=%d KB/s (peak_tx=%d KB/s, peak_rx=%d KB/s)",
|
||||||
|
hub->users->count,
|
||||||
|
hub->users->count_peak,
|
||||||
|
(int) hub->stats.net_tx / 1024,
|
||||||
|
(int) hub->stats.net_rx / 1024,
|
||||||
|
(int) hub->stats.net_tx_peak / 1024,
|
||||||
|
(int) hub->stats.net_rx_peak / 1024);
|
||||||
|
}
|
||||||
|
|
||||||
static void timer_statistics(int fd, short ev, void *arg)
|
static void timer_statistics(int fd, short ev, void *arg)
|
||||||
{
|
{
|
||||||
struct hub_info* hub = (struct hub_info*) arg;
|
struct hub_info* hub = (struct hub_info*) arg;
|
||||||
struct timeval timeout = { TIMEOUT_STATS, 0 };
|
struct timeval timeout = { TIMEOUT_STATS, 0 };
|
||||||
user_manager_stats(hub);
|
user_manager_update_stats(hub);
|
||||||
evtimer_set(&hub->ev_timer, timer_statistics, hub);
|
evtimer_set(&hub->ev_timer, timer_statistics, hub);
|
||||||
evtimer_add(&hub->ev_timer, &timeout);
|
evtimer_add(&hub->ev_timer, &timeout);
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,8 @@ extern void user_manager_shutdown(struct hub_info* hub);
|
|||||||
/**
|
/**
|
||||||
* Generate statistics for logfiles.
|
* Generate statistics for logfiles.
|
||||||
*/
|
*/
|
||||||
extern void user_manager_stats(struct hub_info* hub);
|
extern void user_manager_update_stats(struct hub_info* hub);
|
||||||
|
extern void user_manager_print_stats(struct hub_info* hub);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new user to the user manager.
|
* Add a new user to the user manager.
|
||||||
|
Loading…
Reference in New Issue
Block a user