diff options
Diffstat (limited to 'src/util/server.c')
-rw-r--r-- | src/util/server.c | 86 |
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 | */ | ||
1009 | void | ||
1010 | GNUNET_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 | ||
1241 | size_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. |