Author: tjansen Date: Mon Oct 19 17:37:26 2009 New Revision: 1235 Log: Heartbeat is a per connection task now in the client. Before, we had a single task looping over all connections, now we have one task for each connection. Modified: trunk/include/conmgr.h trunk/libpisa/conmgr.c trunk/pisacd/cdderegister.c trunk/pisacd/cdheartbeat.c trunk/pisacd/cdmain.c trunk/pisacd/cdregister.c trunk/pisacd/cdtun.c Modified: trunk/include/conmgr.h ============================================================================== --- trunk/include/conmgr.h Mon Oct 19 16:51:24 2009 (r1234) +++ trunk/include/conmgr.h Mon Oct 19 17:37:26 2009 (r1235) @@ -67,6 +67,16 @@ time_t timeout_heartbeat; /** + * 0 if no data was received since last check, 1 otherwise. + */ + int heartbeat_flag; + + /** + * Current task for the heartbeat + */ + pisa_sched_task *heartbeat_task; + + /** * 0 if no data was transfered since last check, 1 otherwise. */ int timeout_flag; Modified: trunk/libpisa/conmgr.c ============================================================================== --- trunk/libpisa/conmgr.c Mon Oct 19 16:51:24 2009 (r1234) +++ trunk/libpisa/conmgr.c Mon Oct 19 17:37:26 2009 (r1235) @@ -150,6 +150,8 @@ time(&entry->timeout_heartbeat); entry->timeout_flag = 0; entry->timeout_task = NULL; + entry->heartbeat_flag = 0; + entry->heartbeat_task = NULL; entry->status = PISA_CON_DISCONNECTED; HASH_ADD_KEYPTR(hh, conlist->hash_ipv6, &entry->hit, Modified: trunk/pisacd/cdderegister.c ============================================================================== --- trunk/pisacd/cdderegister.c Mon Oct 19 16:51:24 2009 (r1234) +++ trunk/pisacd/cdderegister.c Mon Oct 19 17:37:26 2009 (r1235) @@ -32,6 +32,10 @@ if (entry->timeout_task) pisa_sched_remove(&cd_ctx.scheduler, entry->timeout_task); entry->timeout_task = NULL; + + if (entry->heartbeat_task) + pisa_sched_remove(&cd_ctx.scheduler, entry->heartbeat_task); + entry->heartbeat_task = NULL; } /** Modified: trunk/pisacd/cdheartbeat.c ============================================================================== --- trunk/pisacd/cdheartbeat.c Mon Oct 19 16:51:24 2009 (r1234) +++ trunk/pisacd/cdheartbeat.c Mon Oct 19 17:37:26 2009 (r1235) @@ -13,6 +13,7 @@ #include "cdctx.h" #include "cdderegister.h" +#include "cdheartbeat.h" #include "cdpending.h" #include "scheduler.h" @@ -31,7 +32,6 @@ if (entry == NULL) return; - time(&entry->timeout_heartbeat); pend = pisa_pending_find(entry, PISA_PKTTYPE_TUN_HEARTBEAT); if (pend) pisa_pending_remove(pend); @@ -75,41 +75,26 @@ } /** - * Check if a connection was idle long enough to send a heartbeat. Current - * time is passed to avoid multiple time() calls in a row. - * @param data pointer to the current time in time_t format. - * @param entry conmgr entry for the server + * Check a connection for its last received time to see if we need to + * send a heartbeat. */ -static void pisa_client_send_heartbeat(void *data, pisa_conmgr_entry *entry) +void pisa_task_heartbeat(void *data) { - pisa_pending *pend; - time_t *t = (time_t *)data; - char buffer[INET6_ADDRSTRLEN]={0}; + struct timeval delay = {PISA_HEARTBEAT_DELAY, 0}; + pisa_conmgr_entry *e = (pisa_conmgr_entry *)data; + + e->heartbeat_task = NULL; - inet_ntop(AF_INET6, &entry->hit, buffer, sizeof(buffer)); - if (entry->timeout_heartbeat + 15 < *t) { - pend = pisa_pending_add(entry, PISA_PKTTYPE_TUN_HEARTBEAT); + /* If we did not receive data in the last window, send a heartbeat to + * the server. */ + if (e->heartbeat_flag == 0) { + pisa_pending *pend; + pend = pisa_pending_add(e, PISA_PKTTYPE_TUN_HEARTBEAT); pend->func = pisa_send_heartbeat_pend; pend->fail = pisa_send_heartbeat_fail; pisa_pending_reschedule(pend, 0); - entry->timeout_heartbeat = *t; } -} - -/* TODO: Start a separate heartbeat task for each connection - * Get rid of entry->timeout_heartbeat */ - -/** - * Check all connections for their last received time to see if we need to - * send a heartbeat. - */ -void pisa_task_heartbeat(void *data) -{ - time_t t; - struct timeval delay = {2, 0}; - - time(&t); - pisa_conmgr_iterate_connected(cd_ctx.conlist, pisa_client_send_heartbeat, &t); - pisa_sched_add(&cd_ctx.scheduler, pisa_task_heartbeat, &delay, NULL); + e->heartbeat_flag = 0; + e->heartbeat_task = pisa_sched_add(&cd_ctx.scheduler, pisa_task_heartbeat, &delay, e); } Modified: trunk/pisacd/cdmain.c ============================================================================== --- trunk/pisacd/cdmain.c Mon Oct 19 16:51:24 2009 (r1234) +++ trunk/pisacd/cdmain.c Mon Oct 19 17:37:26 2009 (r1235) @@ -152,6 +152,8 @@ pisa_pending_remove_by_entry(entry); if (entry->timeout_task) pisa_sched_remove(&cd_ctx.scheduler, entry->timeout_task); + if (entry->heartbeat_task) + pisa_sched_remove(&cd_ctx.scheduler, entry->heartbeat_task); } /** @@ -279,7 +281,6 @@ /* Initialize the scheduler and start some maintenance tasks */ pisa_sched_init(&cd_ctx.scheduler); - pisa_sched_add_now(&cd_ctx.scheduler, pisa_task_heartbeat, NULL); pisa_sched_add_now(&cd_ctx.scheduler, pisa_task_pending, NULL); } Modified: trunk/pisacd/cdregister.c ============================================================================== --- trunk/pisacd/cdregister.c Mon Oct 19 16:51:24 2009 (r1234) +++ trunk/pisacd/cdregister.c Mon Oct 19 17:37:26 2009 (r1235) @@ -14,6 +14,7 @@ #include "tunnel.h" #include "cdctx.h" #include "cdconf.h" +#include "cdheartbeat.h" #include "cdpending.h" #include "cdtimeout.h" @@ -162,6 +163,12 @@ delay.tv_usec = 0; entry->timeout_task = pisa_sched_add(&cd_ctx.scheduler, pisa_task_timeout, &delay, entry); + /* Start the heartbeat task. */ + entry->heartbeat_flag = 0; + delay.tv_sec = PISA_HEARTBEAT_DELAY; + delay.tv_usec = 0; + entry->heartbeat_task = pisa_sched_add(&cd_ctx.scheduler, pisa_task_heartbeat, &delay, entry); + inet_ntop(AF_INET6, &addr->sin6_addr, buffer, sizeof(buffer)); PISA_DEBUG(PL_REGISTER, "Connected to PISA server %s\n", buffer); Modified: trunk/pisacd/cdtun.c ============================================================================== --- trunk/pisacd/cdtun.c Mon Oct 19 16:51:24 2009 (r1234) +++ trunk/pisacd/cdtun.c Mon Oct 19 17:37:26 2009 (r1235) @@ -73,11 +73,9 @@ if (write(cd_ctx.tunnel, buffer + 6, len - 6) == -1) { PISA_ERROR("remote -> local: write failed: %s\n", strerror(errno)); } else { - /* Set this variable to the current time, we don't - * have to send a heartbeat until our heartbeat - * timeout ran out from THIS point in time - the - * server takes incoming data as heartbeat */ - time(&entry->timeout_heartbeat); + /* Sending a heartbeat at the next scheduled time is + * unnecessary, we already sent some payload. */ + entry->heartbeat_flag = 1; /* Keep track of the last time this connection was * used. Disconnect after a timeout to save