diff options
author | ambrop7 <ambrop7@1a93d707-3861-5ebc-ad3b-9740d49b5140> | 2011-07-14 03:16:05 +0400 |
---|---|---|
committer | ambrop7 <ambrop7@1a93d707-3861-5ebc-ad3b-9740d49b5140> | 2011-07-14 03:16:05 +0400 |
commit | 66918c13c0abdfbad88a51dba74cd486176f63eb (patch) | |
tree | d9cdd037bcd0386728159086f4a9d5be2c24461c /server | |
parent | 83d1e9514b20c0aa2e89c280020bd3fcee2babfc (diff) |
server: always reset after some time
Diffstat (limited to 'server')
-rw-r--r-- | server/server.c | 95 | ||||
-rw-r--r-- | server/server.h | 5 |
2 files changed, 65 insertions, 35 deletions
diff --git a/server/server.c b/server/server.c index c23137d..2cee0b1 100644 --- a/server/server.c +++ b/server/server.c @@ -239,6 +239,12 @@ static void peer_flow_end_packet (struct peer_flow *flow, uint8_t type); // handler called by the queue when a peer flow can be freed after its source has gone away static void peer_flow_handler_canremove (struct peer_flow *flow); +// schedules resetting of clients knowledge +static void peer_flow_schedule_reset (struct peer_flow *flow); + +// resets clients knowledge after the timer expires +static void peer_flow_reset_timer_handler (struct peer_flow *flow); + // generates a client ID to be used for a newly connected client static peerid_t new_client_id (void); @@ -287,8 +293,6 @@ static void know_uninform_job_handler (struct peer_know *k); static int create_know_pair (struct peer_flow *flow_to); -static void reset_clients (struct peer_flow *flow_to); - int main (int argc, char *argv[]) { if (argc <= 0) { @@ -1517,7 +1521,8 @@ void process_packet_outmsg (struct client_data *client, uint8_t *data, int data_ uint8_t x; BRandom_randomize(&x, sizeof(x)); if (x < SIMULATE_OUT_OF_FLOW_BUFFER) { - reset_clients(flow); + client_log(client, BLOG_WARNING, "simulating error; scheduling reset to %d", (int)flow->dest_client->id); + peer_flow_schedule_reset(flow); return; } #endif @@ -1526,7 +1531,8 @@ void process_packet_outmsg (struct client_data *client, uint8_t *data, int data_ struct sc_server_inmsg *pack; if (!peer_flow_start_packet(flow, (void **)&pack, sizeof(struct sc_server_inmsg) + payload_size)) { // out of buffer, reset these two clients - reset_clients(flow); + client_log(client, BLOG_WARNING, "out of buffer; scheduling reset to %d", (int)flow->dest_client->id); + peer_flow_schedule_reset(flow); return; } pack->clientid = htol16(client->id); @@ -1559,8 +1565,10 @@ void process_packet_resetpeer (struct client_data *client, uint8_t *data, int da } struct peer_flow *flow = UPPER_OBJECT(node, struct peer_flow, src_tree_node); + client_log(client, BLOG_WARNING, "resetpeer: scheduling reset to %d", (int)flow->dest_client->id); + // reset clients - reset_clients(flow); + peer_flow_schedule_reset(flow); } struct peer_flow * peer_flow_create (struct client_data *src_client, struct client_data *dest_client) @@ -1601,6 +1609,9 @@ struct peer_flow * peer_flow_create (struct client_data *src_client, struct clie flow->input = PacketProtoFlow_GetInput(&flow->oflow); flow->packet_len = -1; + // init reset timer + BTimer_Init(&flow->reset_timer, CLIENT_RESET_TIME, (BTimer_handler)peer_flow_reset_timer_handler, flow); + return flow; fail1: @@ -1617,6 +1628,9 @@ void peer_flow_dealloc (struct peer_flow *flow) { PacketPassFairQueueFlow_AssertFree(&flow->qflow); + // free reset timer + BReactor_RemoveTimer(&ss, &flow->reset_timer); + // free I/O PacketProtoFlow_Free(&flow->oflow); PacketPassFairQueueFlow_Free(&flow->qflow); @@ -1659,7 +1673,6 @@ int peer_flow_start_packet (struct peer_flow *flow, void **data, int len) // obtain location for writing the packet if (!BufferWriter_StartPacket(flow->input, &flow->packet)) { - client_log(flow->src_client, BLOG_INFO, "out of flow buffer for message to %d", (int)flow->dest_client->id); return 0; } @@ -1699,6 +1712,47 @@ void peer_flow_handler_canremove (struct peer_flow *flow) return; } +void peer_flow_schedule_reset (struct peer_flow *flow) +{ + ASSERT(flow->src_client->initstatus == INITSTATUS_COMPLETE) + ASSERT(!flow->src_client->dying) + ASSERT(flow->dest_client->initstatus == INITSTATUS_COMPLETE) + ASSERT(!flow->dest_client->dying) + + // set reset timer + BReactor_SetTimer(&ss, &flow->reset_timer); +} + +void peer_flow_reset_timer_handler (struct peer_flow *flow) +{ + ASSERT(flow->src_client->initstatus == INITSTATUS_COMPLETE) + ASSERT(!flow->src_client->dying) + ASSERT(flow->dest_client->initstatus == INITSTATUS_COMPLETE) + ASSERT(!flow->dest_client->dying) + + client_log(flow->src_client, BLOG_WARNING, "resetting to %d", (int)flow->dest_client->id); + + // stop opposite reset timer + BReactor_RemoveTimer(&ss, &flow->opposite->reset_timer); + + struct peer_know *know = flow->know; + struct peer_know *know_opposite = flow->opposite->know; + + // create new knows + if (!create_know_pair(flow)) { + goto fail; + } + + // remove old knows + uninform_know(know); + uninform_know(know_opposite); + + return; + +fail: + client_remove(flow->src_client); +} + peerid_t new_client_id (void) { ASSERT(clients_num < MAX_CLIENTS) @@ -1984,32 +2038,3 @@ int create_know_pair (struct peer_flow *flow_to) fail: return 0; } - -void reset_clients (struct peer_flow *flow_to) -{ - struct client_data *client = flow_to->src_client; - struct client_data *client2 = flow_to->dest_client; - ASSERT(client->initstatus == INITSTATUS_COMPLETE) - ASSERT(!client->dying) - ASSERT(client2->initstatus == INITSTATUS_COMPLETE) - ASSERT(!client2->dying) - - client_log(client, BLOG_ERROR, "resetting link to client %d", (int)client2->id); - - struct peer_know *know_to = flow_to->know; - struct peer_know *know_from = flow_to->opposite->know; - - // create new knows - if (!create_know_pair(flow_to)) { - goto fail; - } - - // remove old knows - uninform_know(know_to); - uninform_know(know_from); - - return; - -fail: - client_remove(client); -} diff --git a/server/server.h b/server/server.h index 68b7c75..368e001 100644 --- a/server/server.h +++ b/server/server.h @@ -30,6 +30,7 @@ #include <flow/PacketPassPriorityQueue.h> #include <flow/PacketPassFairQueue.h> #include <flow/PacketProtoFlow.h> +#include <system/BReactor.h> #include <system/BConnection.h> #include <nspr_support/BSSLConnection.h> @@ -48,6 +49,8 @@ #define CLIENT_NO_DATA_TIME_LIMIT 30000 // SO_SNDBFUF socket option for clients #define CLIENT_DEFAULT_SOCKET_SNDBUF 16384 +// reset time when a buffer runs out or when we get the resetpeer message +#define CLIENT_RESET_TIME 30000 // maxiumum listen addresses #define MAX_LISTEN_ADDRS 16 @@ -86,6 +89,8 @@ struct peer_flow { BufferWriter *input; int packet_len; uint8_t *packet; + // reset timer + BTimer reset_timer; // opposite flow struct peer_flow *opposite; // corresponding know |