Skip to content

Commit

Permalink
Added "no network" detection, tweaked housekeeping timers to cap the
Browse files Browse the repository at this point in the history
exponential fallback at different levels depending on that factor and
rejection status.

Also improved stability of frontend-choice in the face of local network
outages by only changing frontend choices if DNS is working.
  • Loading branch information
BjarniRunar committed Feb 24, 2015
1 parent 73b5246 commit fddd753
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 19 deletions.
6 changes: 3 additions & 3 deletions include/pagekite.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ Note: For alternate license terms, see the file COPYING.md.
#define _PAGEKITEC_DLL_H

#ifdef ANDROID
#define PK_VERSION "0.90.150209A"
#define PK_VERSION "0.90.150224A"
#else
#ifdef _MSC_VER
#define PK_VERSION "0.90.150209W"
#define PK_VERSION "0.90.150224W"
#else
#define PK_VERSION "0.90.150209C"
#define PK_VERSION "0.90.150224C"
#endif
#endif

Expand Down
35 changes: 23 additions & 12 deletions libpagekite/pkblocker.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ void pkb_choose_tunnels(struct pk_manager* pkm)
pk_log(PK_LOG_MANAGER_ERROR, "No front-end wanted! We are lame.");
}

void pkb_check_kites_dns(struct pk_manager* pkm)
int pkb_check_kites_dns(struct pk_manager* pkm)
{
int i, j, rv;
int in_dns = 0;
Expand All @@ -225,24 +225,27 @@ void pkb_check_kites_dns(struct pk_manager* pkm)
struct addrinfo hints;
struct addrinfo *result, *rp;
char buffer[128];
int cleared_flags = 0;

PK_TRACE_FUNCTION;

memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;

/* Clear DNS flag... */
for (j = 0, fe = pkm->tunnels; j < pkm->tunnel_max; j++, fe++) {
fe->conn.status &= ~FE_STATUS_IN_DNS;
}

/* Walk through kite list, look each up in DNS and update the
* tunnel flags as appropriate.
*/
for (i = 0, kite = pkm->kites; i < pkm->kite_max; i++, kite++) {
rv = getaddrinfo(kite->public_domain, NULL, &hints, &result);
if (rv == 0) {
if (!cleared_flags) {
/* Clear DNS flag everywhere, once we know DNS is responding. */
for (j = 0, fe = pkm->tunnels; j < pkm->tunnel_max; j++, fe++) {
fe->conn.status &= ~FE_STATUS_IN_DNS;
}
cleared_flags = 1;
}
for (rp = result; rp != NULL; rp = rp->ai_next) {
for (j = 0, fe = pkm->tunnels; j < pkm->tunnel_max; j++, fe++) {
if (fe->ai && fe->fe_hostname) {
Expand All @@ -262,6 +265,11 @@ void pkb_check_kites_dns(struct pk_manager* pkm)
}
}

/*
* If flags weren't cleared, then the network is probably down: bail out!
*/
if (!cleared_flags) return 1;

/* FIXME: We should really get this from the TTL of the DNS record itself,
* not from a hard coded magic number.
*/
Expand Down Expand Up @@ -295,6 +303,7 @@ void pkb_check_kites_dns(struct pk_manager* pkm)
}

PK_CHECK_MEMORY_CANARIES;
return 0;
}

void* pkb_tunnel_ping(void* void_fe) {
Expand Down Expand Up @@ -528,16 +537,15 @@ void pkb_check_world(struct pk_manager* pkm)
void pkb_check_tunnels(struct pk_manager* pkm)
{
int problems = 0;
int dns_is_down = 0;
PK_TRACE_FUNCTION;

if (pkm->status == PK_STATUS_NO_NETWORK) return;
pk_log(PK_LOG_MANAGER_DEBUG, "Checking tunnels...");
pk_log(PK_LOG_MANAGER_DEBUG, "Checking network & tunnels...");

pkb_check_kites_dns(pkm);
dns_is_down = (0 != pkb_check_kites_dns(pkm));
pkb_choose_tunnels(pkm);
pkb_log_fe_status(pkm);

problems += pkm_reconnect_all(pkm);
problems += pkm_reconnect_all(pkm, dns_is_down);

if (!problems) pkm_disconnect_unused(pkm);

Expand All @@ -551,7 +559,10 @@ void pkb_check_tunnels(struct pk_manager* pkm)
PKS_STATE(pkm->status = PK_STATUS_FLYING);
}
else if (pkm->status != PK_STATUS_REJECTED) {
PKS_STATE(pkm->status = PK_STATUS_PROBLEMS);
if (dns_is_down)
pk_log(PK_LOG_MANAGER_DEBUG, "Network appears to be down.");
PKS_STATE(pkm->status = (dns_is_down ? PK_STATUS_NO_NETWORK
: PK_STATUS_PROBLEMS));
}
}

Expand Down
21 changes: 18 additions & 3 deletions libpagekite/pkmanager.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ static void pkm_listener_cb(EV_P_ ev_io* w, int revents)
(void) revents;
}

int pkm_reconnect_all(struct pk_manager* pkm) {
int pkm_reconnect_all(struct pk_manager* pkm, int ignore_errors) {
struct pk_tunnel *fe;
struct pk_kite_request *kite_r;
unsigned int status;
Expand Down Expand Up @@ -742,7 +742,8 @@ int pkm_reconnect_all(struct pk_manager* pkm) {
/* FIXME: Is this the right behavior? */
pk_log(PK_LOG_MANAGER_INFO, "Connect failed: %d", fe->conn.sockfd);
fe->request_count = 0;
if (fe->error_count < 999)

if (!ignore_errors && fe->error_count < 999)
fe->error_count += 1;

status = fe->conn.status;
Expand Down Expand Up @@ -848,9 +849,23 @@ static void pkm_tick_cb(EV_P_ ev_async* w, int revents)
pk_log(PK_LOG_MANAGER_DEBUG, "Tick! [repeating=%s, next=%d]",
pkm->enable_timer ? "yes" : "no", pkm->next_tick);

/* We slow down exponentially by default, no matter what. */
/* We slow down exponentially by default... */
next_tick += increment;
max_tick = pkm->housekeeping_interval_max + pkm->interval_fudge_factor;

/* Fallback is tuned for normal operation: if the relay rejected
us that is not normal anymore and we'll happily go idle until it
is time to re-check the state of the world. */
if (pkm->status == PK_STATUS_REJECTED)
max_tick += pkm->check_world_interval;

/* Similarly, if there's no network AND we are relying on the built-in
timer and not external app logic, then retry more frequently. Power
constrained apps shouldn't be using the timer anyway! */
if (pkm->status == PK_STATUS_NO_NETWORK)
max_tick = (PK_HOUSEKEEPING_INTERVAL_MIN +
PK_HOUSEKEEPING_INTERVAL_MAX_MIN) / 2;

if (next_tick > max_tick)
next_tick = max_tick;
}
Expand Down
2 changes: 1 addition & 1 deletion libpagekite/pkmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ int pkm_run_in_thread (struct pk_manager*);
int pkm_wait_thread (struct pk_manager*);
int pkm_stop_thread (struct pk_manager*);

int pkm_reconnect_all (struct pk_manager*);
int pkm_reconnect_all (struct pk_manager*, int);
int pkm_disconnect_unused (struct pk_manager*);

int pkm_configure_lua (struct pk_manager*);
Expand Down

0 comments on commit fddd753

Please sign in to comment.