aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2011-06-22 12:20:33 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2011-06-22 12:20:33 +0000
commit2b14bddb1076b5902c1f3dac24ba3f231a957dd7 (patch)
tree40d25150f7bf7ca23319e2f48e5053d19019277f /src/util
parent83965c602cb557f08b094f1c160faf7b8101bcf3 (diff)
downloadgnunet-2b14bddb1076b5902c1f3dac24ba3f231a957dd7.tar.gz
gnunet-2b14bddb1076b5902c1f3dac24ba3f231a957dd7.zip
patch for time out bug
Diffstat (limited to 'src/util')
-rw-r--r--src/util/server.c86
1 files changed, 81 insertions, 5 deletions
diff --git a/src/util/server.c b/src/util/server.c
index 103ca24e7..ee5684dbb 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -185,6 +185,22 @@ struct GNUNET_SERVER_Client
185 struct GNUNET_TIME_Absolute last_activity; 185 struct GNUNET_TIME_Absolute last_activity;
186 186
187 /** 187 /**
188 *
189 */
190 GNUNET_CONNECTION_TransmitReadyNotify callback;
191
192 /**
193 * callback
194 */
195 void *callback_cls;
196
197 /**
198 * After how long should an idle connection time
199 * out (on write).
200 */
201 struct GNUNET_TIME_Relative idle_timeout;
202
203 /**
188 * Number of external entities with a reference to 204 * Number of external entities with a reference to
189 * this client object. 205 * this client object.
190 */ 206 */
@@ -765,11 +781,11 @@ process_mst (struct GNUNET_SERVER_Client *client,
765 client->receive_pending = GNUNET_YES; 781 client->receive_pending = GNUNET_YES;
766#if DEBUG_SERVER 782#if DEBUG_SERVER
767 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 783 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
768 "Server re-enters receive loop.\n"); 784 "Server re-enters receive loop, timeout: %llu.\n", client->server->idle_timeout.rel_value);
769#endif 785#endif
770 GNUNET_CONNECTION_receive (client->connection, 786 GNUNET_CONNECTION_receive (client->connection,
771 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, 787 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
772 client->server->idle_timeout, 788 client->idle_timeout,
773 &process_incoming, client); 789 &process_incoming, client);
774 break; 790 break;
775 } 791 }
@@ -821,10 +837,29 @@ process_incoming (void *cls,
821{ 837{
822 struct GNUNET_SERVER_Client *client = cls; 838 struct GNUNET_SERVER_Client *client = cls;
823 struct GNUNET_SERVER_Handle *server = client->server; 839 struct GNUNET_SERVER_Handle *server = client->server;
840 struct GNUNET_TIME_Absolute start;
824 int ret; 841 int ret;
825 842
826 GNUNET_assert (client->receive_pending == GNUNET_YES); 843 GNUNET_assert (client->receive_pending == GNUNET_YES);
827 client->receive_pending = GNUNET_NO; 844 client->receive_pending = GNUNET_NO;
845 start = GNUNET_TIME_absolute_subtract(GNUNET_TIME_absolute_get(),client->idle_timeout);
846
847
848 if ((buf == NULL) && (available == 0) && (addr == NULL) && (errCode == 0) &&
849 (client->last_activity.abs_value == GNUNET_TIME_absolute_max(start, client->last_activity).abs_value))
850 {
851 // wait longer...
852#if DEBUG_SERVER
853 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
854 "Receive time out, but no disconnect due to sending (%p)\n",
855 GNUNET_a2s (addr, addrlen));
856#endif
857 GNUNET_SERVER_client_keep (client);
858 client->last_activity = GNUNET_TIME_absolute_get ();
859 process_mst (client, ret);
860 return;
861 }
862
828 if ((buf == NULL) || 863 if ((buf == NULL) ||
829 (available == 0) || 864 (available == 0) ||
830 (errCode != 0) || 865 (errCode != 0) ||
@@ -879,7 +914,8 @@ restart_processing (void *cls,
879 client->receive_pending = GNUNET_YES; 914 client->receive_pending = GNUNET_YES;
880 GNUNET_CONNECTION_receive (client->connection, 915 GNUNET_CONNECTION_receive (client->connection,
881 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, 916 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
882 client->server->idle_timeout, &process_incoming, client); 917 client->idle_timeout, &process_incoming, client);
918
883 return; 919 return;
884 } 920 }
885#if DEBUG_SERVER 921#if DEBUG_SERVER
@@ -950,16 +986,35 @@ GNUNET_SERVER_connect_socket (struct
950 client->server = server; 986 client->server = server;
951 client->last_activity = GNUNET_TIME_absolute_get (); 987 client->last_activity = GNUNET_TIME_absolute_get ();
952 client->next = server->clients; 988 client->next = server->clients;
989 client->idle_timeout = server->idle_timeout;
953 server->clients = client; 990 server->clients = client;
954 client->receive_pending = GNUNET_YES; 991 client->receive_pending = GNUNET_YES;
992 client->callback = NULL;
993 client->callback_cls = NULL;
955 GNUNET_CONNECTION_receive (client->connection, 994 GNUNET_CONNECTION_receive (client->connection,
956 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, 995 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
957 server->idle_timeout, &process_incoming, client); 996 client->idle_timeout, &process_incoming, client);
958 return client; 997 return client;
959} 998}
960 999
961 1000
962/** 1001/**
1002 * Change the timeout for a particular client. Decreasing the timeout
1003 * may not go into effect immediately (only after the previous timeout
1004 * times out or activity happens on the socket).
1005 *
1006 * @param client the client to update
1007 * @param timeout new timeout for activities on the socket
1008 */
1009void
1010GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client,
1011 struct GNUNET_TIME_Relative timeout)
1012{
1013 client->idle_timeout = timeout;
1014}
1015
1016
1017/**
963 * Notify the server that the given client handle should 1018 * Notify the server that the given client handle should
964 * be kept (keeps the connection up if possible, increments 1019 * be kept (keeps the connection up if possible, increments
965 * the internal reference counter). 1020 * the internal reference counter).
@@ -1183,6 +1238,20 @@ GNUNET_SERVER_client_disable_corking (struct GNUNET_SERVER_Client *client)
1183 return GNUNET_CONNECTION_disable_corking (client->connection); 1238 return GNUNET_CONNECTION_disable_corking (client->connection);
1184} 1239}
1185 1240
1241size_t transmit_ready_callback_wrapper (void *cls, size_t size, void *buf)
1242{
1243 int ret;
1244 struct GNUNET_SERVER_Client *client = cls;
1245
1246 GNUNET_CONNECTION_TransmitReadyNotify callback = client->callback;
1247 void * callback_cls = client->callback_cls;
1248
1249 client->last_activity = GNUNET_TIME_absolute_get();
1250 client->callback = NULL;
1251 client->callback_cls = NULL;
1252
1253 return callback (callback_cls, size, buf);
1254}
1186 1255
1187/** 1256/**
1188 * Notify us when the server has enough space to transmit 1257 * Notify us when the server has enough space to transmit
@@ -1206,11 +1275,18 @@ GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
1206 GNUNET_CONNECTION_TransmitReadyNotify 1275 GNUNET_CONNECTION_TransmitReadyNotify
1207 callback, void *callback_cls) 1276 callback, void *callback_cls)
1208{ 1277{
1278 GNUNET_assert (client->callback == NULL);
1279
1280 client->callback_cls = callback_cls;
1281 client->callback = callback;
1282
1209 return GNUNET_CONNECTION_notify_transmit_ready (client->connection, 1283 return GNUNET_CONNECTION_notify_transmit_ready (client->connection,
1210 size, 1284 size,
1211 timeout, callback, callback_cls); 1285 timeout, transmit_ready_callback_wrapper, client);
1212} 1286}
1213 1287
1288
1289
1214/** 1290/**
1215 * Set the persistent flag on this client, used to setup client connection 1291 * Set the persistent flag on this client, used to setup client connection
1216 * to only be killed when the service it's connected to is actually dead. 1292 * to only be killed when the service it's connected to is actually dead.