Author: tjansen Date: Thu Oct 15 13:46:14 2009 New Revision: 1158 Log: Fixed timeout handling on the client side. The only way for the client to notice a broken connection is a failed heartbeat. The client used to reset the timeout for a heartbeat every time it sent out a packet to the server. As PISA doesn't guarantee successful delivery, we may not assume that this packet reached the server and causes the server to reset its timeout. Receiving a data packet from the server implies that the server still considers the client to be connected. We therefore may reset our heartbeat timeout if we receive such a data packet. The way the connection idle timeout is handled has also been updated. A connection is now considered idle if no data has been sent in either direction for a while. Previously, we considered a connection to be idle if _we_ did not send for a while. Data sent by the server was not taken into account. Modified: trunk/pisacd/cdtun.c Modified: trunk/pisacd/cdtun.c ============================================================================== --- trunk/pisacd/cdtun.c Thu Oct 15 13:17:37 2009 (r1157) +++ trunk/pisacd/cdtun.c Thu Oct 15 13:46:14 2009 (r1158) @@ -70,10 +70,22 @@ pisa_nat_apply(hdr, srcaddr, &map->local_private); /* Send the packet out to the tunnel device */ - if (write(cd_ctx.tunnel, buffer + 6, len - 6) == -1) + if (write(cd_ctx.tunnel, buffer + 6, len - 6) == -1) { PISA_ERROR("remote -> local: write failed: %s\n", strerror(errno)); - else + } 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); + + /* Keep track of the last time this connection was + * used. Disconnect after a timeout to save + * resources. */ + time(&entry->timeout_client); + PISA_DEBUG(PL_DATA, "remote -> local: %i bytes\n", len - 6); + } } else { inet_ntop(AF_INET6, &(from.sin6_addr), buffer, sizeof(buffer)); PISA_DEBUG(PL_DATA, "remote -> local: from unknown server %s\n", buffer); @@ -151,14 +163,8 @@ if (sendto(cd_ctx.tund, buffer, len + 6, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in6)) == -1) { PISA_ERROR("local -> remote: sendto 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); - - /* Keep track of the last time we actively used this - * connection. Disconnect after a timeout to save + /* Keep track of the last time this connection was + * used. Disconnect after a timeout to save * resources. */ time(&entry->timeout_client);