mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-18 20:57:56 +00:00
Enable a more graceful shutdown of the server in most cases
This commit is contained in:
parent
dfe108d287
commit
0382e7990e
@ -139,8 +139,11 @@ int directory_registration(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void interface_change(struct overlay_interface *UNUSED(interface)){
|
||||
directory_registration();
|
||||
static void interface_change(struct overlay_interface *UNUSED(interface), unsigned count){
|
||||
if (count)
|
||||
directory_registration();
|
||||
else
|
||||
unschedule(&directory_alarm);
|
||||
}
|
||||
|
||||
DEFINE_TRIGGER(iupdown, interface_change);
|
||||
|
11
dna_helper.c
11
dna_helper.c
@ -60,6 +60,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "strbuf_helpers.h"
|
||||
#include "dataformats.h"
|
||||
#include "overlay_address.h"
|
||||
#include "server.h"
|
||||
|
||||
static void dna_helper_shutdown();
|
||||
|
||||
/*
|
||||
The challenge with making an interface for calling an external program to
|
||||
@ -324,19 +327,19 @@ dna_helper_harvest(int blocking)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dna_helper_shutdown()
|
||||
static void dna_helper_shutdown()
|
||||
{
|
||||
DEBUG(dnahelper, "DNAHELPER shutting down");
|
||||
dna_helper_close_pipes();
|
||||
switch (dna_helper_kill()) {
|
||||
case -1:
|
||||
return -1;
|
||||
case 0:
|
||||
return 0;
|
||||
return;
|
||||
default:
|
||||
return dna_helper_harvest(1);
|
||||
dna_helper_harvest(1);
|
||||
}
|
||||
}
|
||||
DEFINE_TRIGGER(shutdown, dna_helper_shutdown);
|
||||
|
||||
static void monitor_requests(struct sched_ent *alarm)
|
||||
{
|
||||
|
41
fdqueue.c
41
fdqueue.c
@ -67,27 +67,38 @@ struct profile_total poll_stats={NULL,0,"Idle (in poll)",0,0,0,0};
|
||||
|
||||
#define alloca_alarm_name(alarm) ((alarm)->stats ? alloca_str_toprint((alarm)->stats->name) : "Unnamed")
|
||||
|
||||
void list_alarms()
|
||||
int list_alarms(int log_level)
|
||||
{
|
||||
int count=0;
|
||||
time_ms_t now = gettime_ms();
|
||||
struct sched_ent *alarm;
|
||||
|
||||
_DEBUG("Run now;");
|
||||
for (alarm = run_now; alarm; alarm=alarm->_next_run)
|
||||
_DEBUGF("%p %s deadline in %"PRId64"ms", alarm->function, alloca_alarm_name(alarm), alarm->run_before - now);
|
||||
LOGF(log_level, "Run now;");
|
||||
for (alarm = run_now; alarm; alarm=alarm->_next_run){
|
||||
count ++;
|
||||
LOGF(log_level, "%p %s deadline in %"PRId64"ms", alarm->function, alloca_alarm_name(alarm), alarm->run_before - now);
|
||||
}
|
||||
|
||||
_DEBUG("Run soon;");
|
||||
for (alarm = run_soon; alarm; alarm=alarm->_next_run)
|
||||
_DEBUGF("%p %s run in %"PRId64"ms", alarm->function, alloca_alarm_name(alarm), alarm->run_after - now);
|
||||
|
||||
_DEBUG("Wake at;");
|
||||
for (alarm = wake_list; alarm; alarm = alarm->_next_wake)
|
||||
_DEBUGF("%p %s wake in %"PRId64"ms", alarm->function, alloca_alarm_name(alarm), alarm->wake_at - now);
|
||||
|
||||
_DEBUG("File handles;");
|
||||
LOGF(log_level, "Run soon;");
|
||||
for (alarm = run_soon; alarm; alarm=alarm->_next_run){
|
||||
count ++;
|
||||
LOGF(log_level, "%p %s run in %"PRId64"ms", alarm->function, alloca_alarm_name(alarm), alarm->run_after - now);
|
||||
}
|
||||
|
||||
LOGF(log_level, "Wake at;");
|
||||
for (alarm = wake_list; alarm; alarm = alarm->_next_wake){
|
||||
count ++;
|
||||
LOGF(log_level, "%p %s wake in %"PRId64"ms", alarm->function, alloca_alarm_name(alarm), alarm->wake_at - now);
|
||||
}
|
||||
|
||||
LOGF(log_level, "File handles;");
|
||||
int i;
|
||||
for (i = 0; i < fdcount; ++i)
|
||||
_DEBUGF("%s watching #%d for %x", alloca_alarm_name(fd_callbacks[i]), fds[i].fd, fds[i].events);
|
||||
for (i = 0; i < fdcount; ++i){
|
||||
count ++;
|
||||
LOGF(log_level, "%s watching #%d for %x", alloca_alarm_name(fd_callbacks[i]), fds[i].fd, fds[i].events);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static void insert_run_now(struct sched_ent *alarm)
|
||||
|
@ -173,6 +173,6 @@ unsigned fd_depth();
|
||||
#define RETURNVOID do { OUT(); return; } while (0)
|
||||
|
||||
DECLARE_ALARM(fd_periodicstats);
|
||||
void list_alarms();
|
||||
int list_alarms(int log_level);
|
||||
|
||||
#endif // __SERVAL_DNA__FDQUEUE_H
|
||||
|
26
httpd.c
26
httpd.c
@ -23,9 +23,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "net.h"
|
||||
#include "conf.h"
|
||||
#include "str.h"
|
||||
#include "server.h"
|
||||
|
||||
#define RHIZOME_SERVER_MAX_LIVE_REQUESTS 32
|
||||
|
||||
static int httpd_dispatch(struct http_request *);
|
||||
static unsigned int http_request_uuid_counter = 0;
|
||||
static httpd_request * current_httpd_requests = NULL;
|
||||
unsigned int current_httpd_request_count = 0;
|
||||
|
||||
static int httpd_dispatch(struct http_request *hr)
|
||||
{
|
||||
httpd_request *r = (httpd_request *) hr;
|
||||
@ -101,6 +107,20 @@ int is_httpd_server_running()
|
||||
return httpd_server_socket != -1;
|
||||
}
|
||||
|
||||
static void httpd_server_shutdown()
|
||||
{
|
||||
if (httpd_server_socket==-1)
|
||||
return;
|
||||
unwatch(&server_alarm);
|
||||
close(httpd_server_socket);
|
||||
httpd_server_socket=-1;
|
||||
|
||||
// forcefully close all requests immediately
|
||||
while(current_httpd_requests)
|
||||
http_request_finalise(¤t_httpd_requests->http);
|
||||
}
|
||||
DEFINE_TRIGGER(shutdown, httpd_server_shutdown);
|
||||
|
||||
/* Start the Rhizome HTTP server by creating a socket, binding it to an available port, and
|
||||
marking it as passive. If called repeatedly and frequently, this function will only try to start
|
||||
the server after a certain time has elapsed since the last attempt.
|
||||
@ -193,12 +213,6 @@ success:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int httpd_dispatch(struct http_request *);
|
||||
|
||||
static unsigned int http_request_uuid_counter = 0;
|
||||
static httpd_request * current_httpd_requests = NULL;
|
||||
unsigned int current_httpd_request_count = 0;
|
||||
|
||||
static void httpd_server_finalise_http_request(struct http_request *hr)
|
||||
{
|
||||
httpd_request *r = (httpd_request *) hr;
|
||||
|
@ -37,8 +37,8 @@ static time_ms_t waiting(time_ms_t now, time_ms_t next_run, time_ms_t next_wakeu
|
||||
jlong r = (*server_env)->CallLongMethod(server_env, JniCallback, aboutToWait, (jlong)now, (jlong)next_run, (jlong)next_wakeup);
|
||||
// stop the server if there are any issues
|
||||
if ((*server_env)->ExceptionCheck(server_env)){
|
||||
serverMode=SERVER_CLOSING;
|
||||
INFO("Stopping server due to exception");
|
||||
server_close();
|
||||
return now;
|
||||
}
|
||||
return r;
|
||||
@ -53,7 +53,7 @@ static void wokeup()
|
||||
// stop the server if there are any issues
|
||||
if ((*server_env)->ExceptionCheck(server_env)){
|
||||
INFO("Stopping server due to exception");
|
||||
serverMode=SERVER_CLOSING;
|
||||
server_close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
27
monitor.c
27
monitor.c
@ -178,7 +178,7 @@ static void monitor_close(struct monitor_context *c){
|
||||
|
||||
if (serverMode && (c->flags & MONITOR_QUIT_ON_DISCONNECT)){
|
||||
INFOF("Stopping server due to client disconnecting");
|
||||
serverMode=SERVER_CLOSING;
|
||||
server_close();
|
||||
}
|
||||
unwatch(&c->alarm);
|
||||
close(c->alarm.poll.fd);
|
||||
@ -187,6 +187,20 @@ static void monitor_close(struct monitor_context *c){
|
||||
c->flags=0;
|
||||
}
|
||||
|
||||
static void monitor_shutdown()
|
||||
{
|
||||
if (named_socket.poll.fd == -1)
|
||||
return;
|
||||
unwatch(&named_socket);
|
||||
close(named_socket.poll.fd);
|
||||
named_socket.poll.fd=-1;
|
||||
|
||||
int i;
|
||||
for(i=monitor_socket_count -1;i>=0;i--)
|
||||
monitor_close(&monitor_sockets[i]);
|
||||
}
|
||||
DEFINE_TRIGGER(shutdown, monitor_shutdown);
|
||||
|
||||
void monitor_client_poll(struct sched_ent *alarm)
|
||||
{
|
||||
/* Read available data from a monitor socket */
|
||||
@ -652,7 +666,7 @@ int monitor_client_interested(int mask){
|
||||
|
||||
int monitor_tell_clients(char *msg, int msglen, int mask)
|
||||
{
|
||||
int i;
|
||||
int i, count=0;
|
||||
IN();
|
||||
for(i=monitor_socket_count -1;i>=0;i--) {
|
||||
if (monitor_sockets[i].flags & mask) {
|
||||
@ -660,10 +674,12 @@ int monitor_tell_clients(char *msg, int msglen, int mask)
|
||||
if ( write_all_nonblock(monitor_sockets[i].alarm.poll.fd, msg, msglen) == -1) {
|
||||
INFOF("Tear down monitor client #%d due to write error", i);
|
||||
monitor_close(&monitor_sockets[i]);
|
||||
}else{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
RETURN(0);
|
||||
RETURN(count);
|
||||
}
|
||||
|
||||
int monitor_tell_formatted(int mask, char *fmt, ...){
|
||||
@ -674,11 +690,10 @@ int monitor_tell_formatted(int mask, char *fmt, ...){
|
||||
va_start(ap, fmt);
|
||||
n=vsnprintf(msg, sizeof(msg), fmt, ap);
|
||||
va_end(ap);
|
||||
monitor_tell_clients(msg, n, mask);
|
||||
return 0;
|
||||
return monitor_tell_clients(msg, n, mask);
|
||||
}
|
||||
|
||||
static void monitor_interface_change(struct overlay_interface *interface){
|
||||
static void monitor_interface_change(struct overlay_interface *interface, unsigned UNUSED(count)){
|
||||
unsigned i = interface - overlay_interfaces;
|
||||
if (interface->state==INTERFACE_STATE_UP)
|
||||
monitor_tell_formatted(MONITOR_INTERFACE, "\nINTERFACE:%u:%s:UP\n", i, interface->name);
|
||||
|
@ -97,11 +97,16 @@ void overlay_interface_close(overlay_interface *interface)
|
||||
|
||||
INFOF("Interface %s addr %s is down",
|
||||
interface->name, alloca_socket_address(&interface->address));
|
||||
CALL_TRIGGER(iupdown, interface);
|
||||
|
||||
|
||||
unsigned i, count=0;
|
||||
for (i=0;i<OVERLAY_MAX_INTERFACES;i++){
|
||||
if (overlay_interfaces[i].state == INTERFACE_STATE_UP)
|
||||
count++;
|
||||
}
|
||||
CALL_TRIGGER(iupdown, interface, count);
|
||||
}
|
||||
|
||||
void overlay_interface_close_all()
|
||||
static void overlay_interface_close_all()
|
||||
{
|
||||
unsigned i;
|
||||
for (i=0;i<OVERLAY_MAX_INTERFACES;i++){
|
||||
@ -109,6 +114,7 @@ void overlay_interface_close_all()
|
||||
overlay_interface_close(&overlay_interfaces[i]);
|
||||
}
|
||||
}
|
||||
DEFINE_TRIGGER(shutdown, overlay_interface_close_all);
|
||||
|
||||
void overlay_interface_monitor_up()
|
||||
{
|
||||
@ -647,7 +653,12 @@ overlay_interface_init(const char *name,
|
||||
interface->destination->transfer_limit.burst_size,
|
||||
interface->destination->transfer_limit.burst_length);
|
||||
|
||||
CALL_TRIGGER(iupdown, interface);
|
||||
unsigned count=0;
|
||||
for (i=0;i<OVERLAY_MAX_INTERFACES;i++){
|
||||
if (overlay_interfaces[i].state == INTERFACE_STATE_UP)
|
||||
count++;
|
||||
}
|
||||
CALL_TRIGGER(iupdown, interface, count);
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
@ -1320,6 +1331,18 @@ static int netlink_init()
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void netlink_shutdown()
|
||||
{
|
||||
struct sched_ent *alarm=&ALARM_STRUCT(netlink_poll);
|
||||
if (alarm->poll.fd != -1){
|
||||
unwatch(alarm);
|
||||
close(alarm->poll.fd);
|
||||
DEBUGF(overlayinterfaces, "close(%d)", alarm->poll.fd);
|
||||
alarm->poll.fd = -1;
|
||||
}
|
||||
}
|
||||
DEFINE_TRIGGER(shutdown, netlink_shutdown);
|
||||
|
||||
#else
|
||||
|
||||
// poll the OS's network interfaces
|
||||
|
@ -126,7 +126,6 @@ int overlay_interface_register(const char *name,
|
||||
struct socket_address *addr,
|
||||
const struct socket_address *netmask,
|
||||
struct socket_address *broadcast);
|
||||
void overlay_interface_close_all();
|
||||
overlay_interface * overlay_interface_get_default();
|
||||
overlay_interface * overlay_interface_find(struct in_addr addr, int return_default);
|
||||
overlay_interface * overlay_interface_find_name_addr(const char *name, struct socket_address *addr);
|
||||
@ -135,6 +134,6 @@ int overlay_broadcast_ensemble(struct network_destination *destination, struct o
|
||||
void interface_state_html(struct strbuf *b, struct overlay_interface *interface);
|
||||
void overlay_interface_monitor_up();
|
||||
|
||||
DECLARE_TRIGGER(iupdown, struct overlay_interface *);
|
||||
DECLARE_TRIGGER(iupdown, struct overlay_interface *, unsigned count);
|
||||
|
||||
#endif // __SERVAL_DNA__OVERLAY_INTERFACE_H
|
||||
|
@ -224,6 +224,27 @@ static int mdp_bind_socket(const char *name)
|
||||
return sock;
|
||||
}
|
||||
|
||||
static void overlay_mdp_shutdown()
|
||||
{
|
||||
if (mdp_sock.poll.fd != -1) {
|
||||
unwatch(&mdp_sock);
|
||||
close(mdp_sock.poll.fd);
|
||||
mdp_sock.poll.fd=-1;
|
||||
}
|
||||
if (mdp_sock2.poll.fd != -1) {
|
||||
unwatch(&mdp_sock2);
|
||||
close(mdp_sock2.poll.fd);
|
||||
mdp_sock2.poll.fd=-1;
|
||||
}
|
||||
if (mdp_sock2_inet.poll.fd != -1) {
|
||||
unwatch(&mdp_sock2_inet);
|
||||
close(mdp_sock2_inet.poll.fd);
|
||||
mdp_sock2_inet.poll.fd=-1;
|
||||
}
|
||||
overlay_mdp_clean_socket_files();
|
||||
}
|
||||
DEFINE_TRIGGER(shutdown, overlay_mdp_shutdown);
|
||||
|
||||
int overlay_mdp_setup_sockets()
|
||||
{
|
||||
/* Delete stale socket files from instance directory. */
|
||||
@ -1130,7 +1151,7 @@ static void send_route_changed(struct subscriber *subscriber, int UNUSED(prior_r
|
||||
}
|
||||
DEFINE_TRIGGER(link_change, send_route_changed);
|
||||
|
||||
static void send_interface_change(struct overlay_interface *interface)
|
||||
static void send_interface_change(struct overlay_interface *interface, unsigned UNUSED(count))
|
||||
{
|
||||
struct mdp_header header;
|
||||
bzero(&header, sizeof(header));
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "str.h"
|
||||
#include "strbuf.h"
|
||||
#include "route_link.h"
|
||||
#include "server.h"
|
||||
|
||||
typedef struct overlay_txqueue {
|
||||
struct overlay_frame *first;
|
||||
@ -103,13 +104,14 @@ overlay_queue_remove(overlay_txqueue *queue, struct overlay_frame *frame){
|
||||
return next;
|
||||
}
|
||||
|
||||
void overlay_queue_release(){
|
||||
static void overlay_queue_release(){
|
||||
unsigned i;
|
||||
for(i=0;i<OQ_MAX;i++) {
|
||||
while(overlay_tx[i].first)
|
||||
overlay_queue_remove(&overlay_tx[i], overlay_tx[i].first);
|
||||
}
|
||||
}
|
||||
DEFINE_TRIGGER(shutdown, overlay_queue_release);
|
||||
|
||||
#if 0 // unused
|
||||
static int
|
||||
|
@ -111,6 +111,35 @@ static void _clear_transfer(struct __sourceloc __whence, struct transfers *ptr)
|
||||
}
|
||||
#define clear_transfer(P) _clear_transfer(__WHENCE__,P)
|
||||
|
||||
static void sync_free_transfers(struct rhizome_sync_keys *sync_state){
|
||||
// drop all transfer records
|
||||
while(sync_state->queue){
|
||||
struct transfers *msg = sync_state->queue;
|
||||
sync_state->queue = msg->next;
|
||||
clear_transfer(msg);
|
||||
free(msg);
|
||||
}
|
||||
}
|
||||
|
||||
static void free_peer_sync_state(struct subscriber *peer){
|
||||
if (sync_tree)
|
||||
sync_free_peer_state(sync_tree, peer);
|
||||
|
||||
if (!peer->sync_keys_state)
|
||||
return;
|
||||
|
||||
if (peer->sync_keys_state->connection){
|
||||
msp_stop_stream(peer->sync_keys_state->connection);
|
||||
time_ms_t now = gettime_ms();
|
||||
RESCHEDULE(&ALARM_STRUCT(sync_send), now, now, now);
|
||||
return;
|
||||
}
|
||||
|
||||
sync_free_transfers(peer->sync_keys_state);
|
||||
free(peer->sync_keys_state);
|
||||
peer->sync_keys_state = NULL;
|
||||
}
|
||||
|
||||
static struct transfers **find_and_update_transfer(struct subscriber *peer, struct rhizome_sync_keys *keys_state, const sync_key_t *key, uint8_t state, int rank)
|
||||
{
|
||||
if (rank>0xFF)
|
||||
@ -499,17 +528,12 @@ void sync_send(struct sched_ent *alarm)
|
||||
|
||||
DEBUGF(rhizome_sync_keys, "Connection closed %s", alloca_tohex_sid_t(peer->sid));
|
||||
|
||||
// drop all transfer records
|
||||
while(sync_state->queue){
|
||||
struct transfers *msg = sync_state->queue;
|
||||
sync_state->queue = msg->next;
|
||||
clear_transfer(msg);
|
||||
free(msg);
|
||||
}
|
||||
|
||||
sync_free_transfers(sync_state);
|
||||
|
||||
sync_state->connection = NULL;
|
||||
// eg connection timeout; drop all sync state
|
||||
if (msp_get_connection_state(connection)& (MSP_STATE_ERROR|MSP_STATE_STOPPED))
|
||||
|
||||
// connection timeout? drop all sync state
|
||||
if (sync_tree && msp_get_connection_state(connection) & (MSP_STATE_ERROR|MSP_STATE_STOPPED))
|
||||
sync_free_peer_state(sync_tree, peer);
|
||||
}
|
||||
|
||||
@ -992,8 +1016,9 @@ static int sync_keys_recv(struct internal_mdp_header *header, struct overlay_buf
|
||||
static void sync_neighbour_changed(struct subscriber *neighbour, uint8_t found, unsigned count)
|
||||
{
|
||||
struct sched_ent *alarm = &ALARM_STRUCT(sync_send_keys);
|
||||
|
||||
if (count>0 && is_rhizome_advertise_enabled()){
|
||||
int enabled = is_rhizome_advertise_enabled();
|
||||
|
||||
if (count>0 && enabled){
|
||||
time_ms_t now = gettime_ms();
|
||||
if (alarm->alarm == TIME_MS_NEVER_WILL){
|
||||
DEBUG(rhizome_sync_keys,"Queueing next message now");
|
||||
@ -1001,18 +1026,29 @@ static void sync_neighbour_changed(struct subscriber *neighbour, uint8_t found,
|
||||
}
|
||||
}else{
|
||||
DEBUG(rhizome_sync_keys,"Stop queueing messages");
|
||||
RESCHEDULE(alarm, TIME_MS_NEVER_WILL, TIME_MS_NEVER_WILL, TIME_MS_NEVER_WILL);
|
||||
unschedule(alarm);
|
||||
unschedule(&ALARM_STRUCT(sync_keys_status));
|
||||
}
|
||||
|
||||
if (!found){
|
||||
struct rhizome_sync_keys *sync_state = get_peer_sync_state(neighbour);
|
||||
// if there's no connection, there shouldn't be any items in the transfer queue
|
||||
if (sync_state->connection)
|
||||
msp_stop_stream(sync_state->connection);
|
||||
}
|
||||
if (!found || !enabled)
|
||||
free_peer_sync_state(neighbour);
|
||||
}
|
||||
DEFINE_TRIGGER(nbr_change, sync_neighbour_changed);
|
||||
|
||||
static void sync_config_changed(){
|
||||
if (!is_rhizome_advertise_enabled()){
|
||||
DEBUG(rhizome_sync_keys,"Stop queueing messages");
|
||||
unschedule(&ALARM_STRUCT(sync_send_keys));
|
||||
unschedule(&ALARM_STRUCT(sync_keys_status));
|
||||
|
||||
if (sync_tree){
|
||||
sync_free_state(sync_tree);
|
||||
sync_tree = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
DEFINE_TRIGGER(conf_change, sync_config_changed);
|
||||
|
||||
static void sync_bundle_add(rhizome_manifest *m)
|
||||
{
|
||||
if (!sync_tree){
|
||||
|
@ -649,8 +649,7 @@ static void clean_neighbours(time_ms_t now)
|
||||
if (neighbour_count==0){
|
||||
// clean up the routing table
|
||||
enum_subscribers(NULL, free_subscriber_link_state, NULL);
|
||||
RESCHEDULE(&ALARM_STRUCT(link_send),
|
||||
TIME_MS_NEVER_WILL, TIME_MS_NEVER_WILL, TIME_MS_NEVER_WILL);
|
||||
unschedule(&ALARM_STRUCT(link_send));
|
||||
}
|
||||
}else{
|
||||
n_ptr = &n->_next;
|
||||
@ -1003,6 +1002,8 @@ static void update_alarm(struct __sourceloc __whence, time_ms_t limit)
|
||||
{
|
||||
if (limit == 0)
|
||||
FATALF("limit == 0");
|
||||
if (!neighbours)
|
||||
return;
|
||||
if (ALARM_STRUCT(link_send).alarm>limit){
|
||||
RESCHEDULE(&ALARM_STRUCT(link_send), limit, limit, limit+20);
|
||||
}
|
||||
@ -1587,7 +1588,7 @@ void link_explained(struct subscriber *subscriber)
|
||||
update_alarm(__WHENCE__, now + 5);
|
||||
}
|
||||
|
||||
static void link_interface_change(struct overlay_interface *UNUSED(interface))
|
||||
static void link_interface_change(struct overlay_interface *UNUSED(interface), unsigned UNUSED(count))
|
||||
{
|
||||
clean_neighbours(gettime_ms());
|
||||
}
|
||||
|
2
serval.h
2
serval.h
@ -248,7 +248,6 @@ int lsif();
|
||||
int doifaddrs();
|
||||
|
||||
int dna_helper_start();
|
||||
int dna_helper_shutdown();
|
||||
int dna_helper_enqueue(struct subscriber *source, mdp_port_t source_port, const char *did);
|
||||
int parseDnaReply(const char *buf, size_t len, char *token, char *did, char *name, char *uri, const char **bufp);
|
||||
|
||||
@ -261,7 +260,6 @@ int overlay_send_stun_request(struct subscriber *server, struct subscriber *requ
|
||||
void rhizome_check_connections(struct sched_ent *alarm);
|
||||
|
||||
int overlay_queue_init();
|
||||
void overlay_queue_release();
|
||||
|
||||
void monitor_client_poll(struct sched_ent *alarm);
|
||||
void monitor_poll(struct sched_ent *alarm);
|
||||
|
77
server.c
77
server.c
@ -77,6 +77,7 @@ static const char *_server_pidfile_path(struct __sourceloc __whence);
|
||||
|
||||
static int server_write_proc_state(const char *path, const char *fmt, ...);
|
||||
static int server_get_proc_state(const char *path, char *buff, size_t buff_len);
|
||||
static void server_stop_alarms();
|
||||
|
||||
// Define our own gettid() and tgkill() if <unistd.h> doesn't provide them (eg, it does on Android).
|
||||
|
||||
@ -303,16 +304,18 @@ int server_bind()
|
||||
|
||||
void server_loop(time_ms_t (*waiting)(time_ms_t, time_ms_t, time_ms_t), void (*wokeup)())
|
||||
{
|
||||
// possible race condition... Shutting down before we even started
|
||||
CALL_TRIGGER(conf_change);
|
||||
|
||||
|
||||
// This log message is used by tests to wait for the server to start.
|
||||
INFOF("Server initialised, entering main loop");
|
||||
|
||||
|
||||
/* Check for activitiy and respond to it */
|
||||
while ((serverMode == SERVER_RUNNING) && fd_poll2(waiting, wokeup))
|
||||
while (fd_poll2(waiting, wokeup))
|
||||
;
|
||||
|
||||
INFOF("Server finished, exiting main loop");
|
||||
fd_showstats();
|
||||
serverCleanUp();
|
||||
|
||||
if (server_pidfd!=-1){
|
||||
@ -497,6 +500,11 @@ static int server_get_proc_state(const char *path, char *buff, size_t buff_len)
|
||||
DEFINE_ALARM(server_config_reload);
|
||||
void server_config_reload(struct sched_ent *alarm)
|
||||
{
|
||||
if (serverMode == SERVER_CLOSING){
|
||||
CALL_TRIGGER(shutdown);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (cf_reload_strict()) {
|
||||
case -1:
|
||||
WARN("server continuing with prior config");
|
||||
@ -577,13 +585,13 @@ void server_watchdog(struct sched_ent *alarm)
|
||||
WHY_perror("fork");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (alarm) {
|
||||
time_ms_t now = gettime_ms();
|
||||
RESCHEDULE(alarm,
|
||||
now+config.server.watchdog.interval_ms,
|
||||
now+config.server.watchdog.interval_ms,
|
||||
now+100);
|
||||
if (alarm) {
|
||||
time_ms_t now = gettime_ms();
|
||||
RESCHEDULE(alarm,
|
||||
now+config.server.watchdog.interval_ms,
|
||||
now+config.server.watchdog.interval_ms,
|
||||
now+100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -599,17 +607,14 @@ void rhizome_clean_db(struct sched_ent *alarm)
|
||||
RESCHEDULE(alarm, now + 30*60*1000, TIME_MS_NEVER_WILL, TIME_MS_NEVER_WILL);
|
||||
}
|
||||
|
||||
static void server_on_config_change();
|
||||
|
||||
DEFINE_TRIGGER(conf_change, server_on_config_change);
|
||||
|
||||
static void server_on_config_change()
|
||||
{
|
||||
if (!serverMode)
|
||||
return;
|
||||
|
||||
time_ms_t now = gettime_ms();
|
||||
|
||||
|
||||
// TODO move to their own trigger
|
||||
dna_helper_start();
|
||||
directory_service_init();
|
||||
|
||||
@ -643,6 +648,7 @@ static void server_on_config_change()
|
||||
rhizome_close_db();
|
||||
}
|
||||
}
|
||||
DEFINE_TRIGGER(conf_change, server_on_config_change);
|
||||
|
||||
static void clean_proc()
|
||||
{
|
||||
@ -667,16 +673,44 @@ static void clean_proc()
|
||||
}
|
||||
}
|
||||
|
||||
void server_close(){
|
||||
if (serverMode != SERVER_RUNNING)
|
||||
return;
|
||||
|
||||
DEBUGF(server,"Graceful shutdown");
|
||||
|
||||
serverMode = SERVER_CLOSING;
|
||||
|
||||
// trigger an alarm to finish cleanup
|
||||
time_ms_t now = gettime_ms();
|
||||
RESCHEDULE(&ALARM_STRUCT(server_config_reload),
|
||||
now,
|
||||
now,
|
||||
TIME_MS_NEVER_WILL);
|
||||
}
|
||||
|
||||
static void server_stop_alarms()
|
||||
{
|
||||
DEBUGF(server,"Stopping alarms");
|
||||
unschedule(&ALARM_STRUCT(fd_periodicstats));
|
||||
unschedule(&ALARM_STRUCT(server_watchdog));
|
||||
unschedule(&ALARM_STRUCT(server_config_reload));
|
||||
unschedule(&ALARM_STRUCT(rhizome_clean_db));
|
||||
unschedule(&ALARM_STRUCT(rhizome_fetch_status));
|
||||
}
|
||||
DEFINE_TRIGGER(shutdown, server_stop_alarms);
|
||||
|
||||
static void serverCleanUp()
|
||||
{
|
||||
assert(serverMode != SERVER_NOT_RUNNING);
|
||||
INFOF("Server cleaning up");
|
||||
overlay_queue_release();
|
||||
|
||||
// release alarms, in case we aborted without attempting a graceful close
|
||||
server_stop_alarms();
|
||||
|
||||
rhizome_close_db();
|
||||
dna_helper_shutdown();
|
||||
overlay_interface_close_all();
|
||||
overlay_mdp_clean_socket_files();
|
||||
release_my_subscriber();
|
||||
|
||||
serverMode = SERVER_NOT_RUNNING;
|
||||
clean_proc();
|
||||
}
|
||||
@ -693,7 +727,7 @@ static void signal_handler(int signum)
|
||||
case SERVER_RUNNING:
|
||||
// Trigger the server to close gracefully after any current alarm has completed.
|
||||
INFOF("Caught signal %s -- attempting clean shutdown", alloca_signal_name(signum));
|
||||
serverMode = SERVER_CLOSING;
|
||||
server_close();
|
||||
return;
|
||||
case SERVER_CLOSING:
|
||||
// If a second signal is received before the server has gracefully shut down, then forcibly
|
||||
@ -701,7 +735,8 @@ static void signal_handler(int signum)
|
||||
// serverCleanUp() if the signal was received by the same thread that is running the server,
|
||||
// because serverMode is thread-local. The zero exit status indicates a clean shutdown. So
|
||||
// the "stop" command must send SIGHUP to the correct thread.
|
||||
WARNF("Caught signal %s -- forced shutdown", alloca_signal_name(signum));
|
||||
WHYF("Caught signal %s -- forced shutdown", alloca_signal_name(signum));
|
||||
list_alarms(LOG_LEVEL_ERROR);
|
||||
serverCleanUp();
|
||||
exit(0);
|
||||
case SERVER_NOT_RUNNING:
|
||||
|
5
server.h
5
server.h
@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#include "fdqueue.h"
|
||||
#include "os.h" // for time_ms_t
|
||||
#include "trigger.h"
|
||||
|
||||
enum server_mode {
|
||||
SERVER_NOT_RUNNING = 0,
|
||||
@ -44,8 +45,12 @@ int server_pid();
|
||||
|
||||
int server_bind();
|
||||
|
||||
void server_close();
|
||||
|
||||
void server_loop(time_ms_t (*waiting)(time_ms_t, time_ms_t, time_ms_t), void (*wokeup)());
|
||||
|
||||
void server_rhizome_add_bundle(uint64_t rowid);
|
||||
|
||||
DECLARE_TRIGGER(shutdown);
|
||||
|
||||
#endif // __SERVAL_DNA__SERVER_H
|
||||
|
34
vomp.c
34
vomp.c
@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "overlay_address.h"
|
||||
#include "overlay_buffer.h"
|
||||
#include "overlay_packet.h"
|
||||
#include "server.h"
|
||||
|
||||
/*
|
||||
Typical call state lifecycle between 2 parties.
|
||||
@ -572,9 +573,8 @@ static int monitor_call_status(struct vomp_call_state *call)
|
||||
alloca_tohex_sid_t(call->local.subscriber->sid),
|
||||
alloca_tohex_sid_t(call->remote.subscriber->sid),
|
||||
call->local.did,call->remote.did);
|
||||
|
||||
monitor_tell_clients(msg, n, MONITOR_VOMP);
|
||||
return 0;
|
||||
|
||||
return monitor_tell_clients(msg, n, MONITOR_VOMP);
|
||||
}
|
||||
|
||||
static int monitor_send_audio(struct vomp_call_state *call, int audio_codec, int time, int sequence,
|
||||
@ -600,8 +600,7 @@ static int monitor_send_audio(struct vomp_call_state *call, int audio_codec, int
|
||||
bcopy(audio, &msg[msglen], audio_length);
|
||||
msglen+=audio_length;
|
||||
msg[msglen++]='\n';
|
||||
monitor_tell_clients(msg, msglen, MONITOR_VOMP);
|
||||
return 0;
|
||||
return monitor_tell_clients(msg, msglen, MONITOR_VOMP);
|
||||
}
|
||||
|
||||
// update local state and notify interested clients with the correct message
|
||||
@ -776,6 +775,13 @@ static int vomp_call_destroy(struct vomp_call_state *call)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vomp_shutdown(){
|
||||
int i=0;
|
||||
for(i=vomp_call_count -1; i>=0; i--)
|
||||
vomp_call_destroy(&vomp_call_states[i]);
|
||||
}
|
||||
DEFINE_TRIGGER(shutdown, vomp_shutdown);
|
||||
|
||||
int vomp_dial(struct subscriber *local, struct subscriber *remote, const char *local_did, const char *remote_did)
|
||||
{
|
||||
/* TODO use local_did and remote_did start putting the call together.
|
||||
@ -1083,11 +1089,17 @@ static void vomp_process_tick(struct sched_ent *alarm)
|
||||
struct vomp_call_state *call = (struct vomp_call_state *)alarm;
|
||||
|
||||
/* See if any calls need to be expired.
|
||||
if all monitor clients have disconnected
|
||||
Allow vomp.dial_timeout_ms for the other party to ring / request ringing
|
||||
Allow vomp.ring_timeout_ms for the ringing party to answer
|
||||
Allow vomp.network_timeout_ms between received packets
|
||||
*/
|
||||
|
||||
|
||||
if (!monitor_client_interested(MONITOR_VOMP)){
|
||||
call->rejection_reason=VOMP_REJECT_NOPHONE;
|
||||
vomp_hangup(call);
|
||||
}
|
||||
|
||||
if ((call->remote.state < VOMP_STATE_RINGINGOUT && call->create_time + config.vomp.dial_timeout_ms < now) ||
|
||||
(call->local.state < VOMP_STATE_INCALL && call->create_time + config.vomp.ring_timeout_ms < now) ||
|
||||
(call->last_activity+config.vomp.network_timeout_ms<now) ){
|
||||
@ -1096,9 +1108,11 @@ static void vomp_process_tick(struct sched_ent *alarm)
|
||||
call->rejection_reason=VOMP_REJECT_TIMEOUT;
|
||||
vomp_update_local_state(call, VOMP_STATE_CALLENDED);
|
||||
vomp_update_remote_state(call, VOMP_STATE_CALLENDED);
|
||||
vomp_update(call);
|
||||
}
|
||||
|
||||
/* update everyone if the state has changed */
|
||||
vomp_update(call);
|
||||
|
||||
/*
|
||||
If we are calling ourselves, mdp packets are processed as soon as they are sent.
|
||||
So we can't risk moving call entries around at that time as that will change pointers that are still on the stack.
|
||||
@ -1110,15 +1124,13 @@ static void vomp_process_tick(struct sched_ent *alarm)
|
||||
return;
|
||||
}
|
||||
|
||||
/* update everyone if the state has changed */
|
||||
vomp_update(call);
|
||||
/* force a packet to the other party. We are still here */
|
||||
vomp_send_status_remote(call);
|
||||
|
||||
|
||||
/* tell local monitor clients the call is still alive */
|
||||
len = snprintf(msg,sizeof(msg) -1,"\nKEEPALIVE:%06x\n", call->local.session);
|
||||
monitor_tell_clients(msg, len, MONITOR_VOMP);
|
||||
|
||||
|
||||
alarm->alarm = gettime_ms() + VOMP_CALL_STATUS_INTERVAL;
|
||||
alarm->deadline = alarm->alarm + VOMP_CALL_STATUS_INTERVAL/2;
|
||||
schedule(alarm);
|
||||
|
Loading…
Reference in New Issue
Block a user