diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2012-05-25 11:05:34 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2012-05-25 11:05:34 +0000 |
commit | d87b9a8065669e71342b8e6823b596b1db02f4d6 (patch) | |
tree | 44a50d05760c8b1514261230f2f6085dc046bb2a /src/transport | |
parent | 95a032ed3619880651eda8f0a5abc9d3520a6f8e (diff) | |
download | gnunet-d87b9a8065669e71342b8e6823b596b1db02f4d6.tar.gz gnunet-d87b9a8065669e71342b8e6823b596b1db02f4d6.zip |
- timeout for unix
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/plugin_transport_unix.c | 184 |
1 files changed, 177 insertions, 7 deletions
diff --git a/src/transport/plugin_transport_unix.c b/src/transport/plugin_transport_unix.c index 6862dd878..4562d08e5 100644 --- a/src/transport/plugin_transport_unix.c +++ b/src/transport/plugin_transport_unix.c | |||
@@ -85,6 +85,13 @@ struct Session | |||
85 | void *addr; | 85 | void *addr; |
86 | size_t addrlen; | 86 | size_t addrlen; |
87 | struct GNUNET_PeerIdentity target; | 87 | struct GNUNET_PeerIdentity target; |
88 | |||
89 | /** | ||
90 | * Session timeout task | ||
91 | */ | ||
92 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; | ||
93 | |||
94 | struct Plugin * plugin; | ||
88 | }; | 95 | }; |
89 | 96 | ||
90 | struct UNIXMessageWrapper | 97 | struct UNIXMessageWrapper |
@@ -241,6 +248,24 @@ struct Plugin | |||
241 | unsigned int bytes_discarded; | 248 | unsigned int bytes_discarded; |
242 | }; | 249 | }; |
243 | 250 | ||
251 | /** | ||
252 | * Start session timeout | ||
253 | */ | ||
254 | static void | ||
255 | start_session_timeout (struct Session *s); | ||
256 | |||
257 | /** | ||
258 | * Increment session timeout due to activity | ||
259 | */ | ||
260 | static void | ||
261 | reschedule_session_timeout (struct Session *s); | ||
262 | |||
263 | /** | ||
264 | * Cancel timeout | ||
265 | */ | ||
266 | static void | ||
267 | stop_session_timeout (struct Session *s); | ||
268 | |||
244 | 269 | ||
245 | static void | 270 | static void |
246 | unix_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | 271 | unix_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); |
@@ -278,18 +303,64 @@ reschedule_select (struct Plugin * plugin) | |||
278 | } | 303 | } |
279 | } | 304 | } |
280 | 305 | ||
306 | struct LookupCtx | ||
307 | { | ||
308 | struct Session *s; | ||
309 | const struct sockaddr_un *addr; | ||
310 | }; | ||
281 | 311 | ||
282 | static int | 312 | int lookup_session_it (void *cls, |
283 | get_session_delete_it (void *cls, const GNUNET_HashCode * key, void *value) | 313 | const GNUNET_HashCode * key, |
314 | void *value) | ||
315 | { | ||
316 | struct LookupCtx *lctx = cls; | ||
317 | struct Session *t = value; | ||
318 | |||
319 | if (0 == strcmp (t->addr, lctx->addr->sun_path)) | ||
320 | { | ||
321 | lctx->s = t; | ||
322 | return GNUNET_NO; | ||
323 | } | ||
324 | return GNUNET_YES; | ||
325 | } | ||
326 | |||
327 | |||
328 | static struct Session * | ||
329 | lookup_session (struct Plugin *plugin, struct GNUNET_PeerIdentity *sender, const struct sockaddr_un *addr) | ||
330 | { | ||
331 | struct LookupCtx lctx; | ||
332 | |||
333 | GNUNET_assert (NULL != plugin); | ||
334 | GNUNET_assert (NULL != sender); | ||
335 | GNUNET_assert (NULL != addr); | ||
336 | |||
337 | lctx.s = NULL; | ||
338 | lctx.addr = addr; | ||
339 | |||
340 | GNUNET_CONTAINER_multihashmap_get_multiple (plugin->session_map, &sender->hashPubKey, &lookup_session_it, &lctx); | ||
341 | |||
342 | return lctx.s; | ||
343 | } | ||
344 | |||
345 | /** | ||
346 | * Functions with this signature are called whenever we need | ||
347 | * to close a session due to a disconnect or failure to | ||
348 | * establish a connection. | ||
349 | * | ||
350 | * @param session session to close down | ||
351 | */ | ||
352 | static void | ||
353 | disconnect_session (struct Session *s) | ||
284 | { | 354 | { |
285 | struct Session *s = value; | ||
286 | struct UNIXMessageWrapper *msgw; | 355 | struct UNIXMessageWrapper *msgw; |
287 | struct UNIXMessageWrapper *next; | 356 | struct UNIXMessageWrapper *next; |
288 | struct Plugin *plugin = cls; | 357 | struct Plugin * plugin = s->plugin; |
289 | int removed; | 358 | int removed; |
290 | GNUNET_assert (plugin != NULL); | 359 | GNUNET_assert (plugin != NULL); |
360 | GNUNET_assert (s != NULL); | ||
291 | 361 | ||
292 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting session for peer `%s' `%s' \n", GNUNET_i2s (&s->target), s->addr); | 362 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting session for peer `%s' `%s' \n", GNUNET_i2s (&s->target), s->addr); |
363 | stop_session_timeout (s); | ||
293 | plugin->env->session_end (plugin->env->cls, &s->target, s); | 364 | plugin->env->session_end (plugin->env->cls, &s->target, s); |
294 | 365 | ||
295 | msgw = plugin->msg_head; | 366 | msgw = plugin->msg_head; |
@@ -312,7 +383,7 @@ get_session_delete_it (void *cls, const GNUNET_HashCode * key, void *value) | |||
312 | reschedule_select (plugin); | 383 | reschedule_select (plugin); |
313 | 384 | ||
314 | GNUNET_assert (GNUNET_YES == | 385 | GNUNET_assert (GNUNET_YES == |
315 | GNUNET_CONTAINER_multihashmap_remove(plugin->session_map, &s->target.hashPubKey, s)); | 386 | GNUNET_CONTAINER_multihashmap_remove(plugin->session_map, &s->target.hashPubKey, s)); |
316 | 387 | ||
317 | GNUNET_STATISTICS_set(plugin->env->stats, | 388 | GNUNET_STATISTICS_set(plugin->env->stats, |
318 | "# UNIX sessions active", | 389 | "# UNIX sessions active", |
@@ -320,6 +391,13 @@ get_session_delete_it (void *cls, const GNUNET_HashCode * key, void *value) | |||
320 | GNUNET_NO); | 391 | GNUNET_NO); |
321 | 392 | ||
322 | GNUNET_free (s); | 393 | GNUNET_free (s); |
394 | } | ||
395 | |||
396 | static int | ||
397 | get_session_delete_it (void *cls, const GNUNET_HashCode * key, void *value) | ||
398 | { | ||
399 | struct Session *s = value; | ||
400 | disconnect_session (s); | ||
323 | return GNUNET_YES; | 401 | return GNUNET_YES; |
324 | } | 402 | } |
325 | 403 | ||
@@ -603,9 +681,12 @@ unix_plugin_get_session (void *cls, | |||
603 | s = GNUNET_malloc (sizeof (struct Session) + address->address_length); | 681 | s = GNUNET_malloc (sizeof (struct Session) + address->address_length); |
604 | s->addr = &s[1]; | 682 | s->addr = &s[1]; |
605 | s->addrlen = address->address_length; | 683 | s->addrlen = address->address_length; |
684 | s->plugin = plugin; | ||
606 | memcpy(s->addr, address->address, s->addrlen); | 685 | memcpy(s->addr, address->address, s->addrlen); |
607 | memcpy(&s->target, &address->peer, sizeof (struct GNUNET_PeerIdentity)); | 686 | memcpy(&s->target, &address->peer, sizeof (struct GNUNET_PeerIdentity)); |
608 | 687 | ||
688 | start_session_timeout (s); | ||
689 | |||
609 | GNUNET_CONTAINER_multihashmap_put (plugin->session_map, | 690 | GNUNET_CONTAINER_multihashmap_put (plugin->session_map, |
610 | &address->peer.hashPubKey, s, | 691 | &address->peer.hashPubKey, s, |
611 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 692 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
@@ -688,6 +769,7 @@ unix_plugin_send (void *cls, | |||
688 | sizeof (struct GNUNET_PeerIdentity)); | 769 | sizeof (struct GNUNET_PeerIdentity)); |
689 | memcpy (&message[1], msgbuf, msgbuf_size); | 770 | memcpy (&message[1], msgbuf, msgbuf_size); |
690 | 771 | ||
772 | reschedule_session_timeout (session); | ||
691 | 773 | ||
692 | wrapper = GNUNET_malloc (sizeof (struct UNIXMessageWrapper)); | 774 | wrapper = GNUNET_malloc (sizeof (struct UNIXMessageWrapper)); |
693 | wrapper->msg = message; | 775 | wrapper->msg = message; |
@@ -729,6 +811,8 @@ unix_demultiplexer (struct Plugin *plugin, struct GNUNET_PeerIdentity *sender, | |||
729 | const struct sockaddr_un *un, size_t fromlen) | 811 | const struct sockaddr_un *un, size_t fromlen) |
730 | { | 812 | { |
731 | struct GNUNET_ATS_Information ats[2]; | 813 | struct GNUNET_ATS_Information ats[2]; |
814 | struct Session *s = NULL; | ||
815 | struct GNUNET_HELLO_Address * addr; | ||
732 | 816 | ||
733 | ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); | 817 | ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); |
734 | ats[0].value = htonl (UNIX_DIRECT_DISTANCE); | 818 | ats[0].value = htonl (UNIX_DIRECT_DISTANCE); |
@@ -744,9 +828,16 @@ unix_demultiplexer (struct Plugin *plugin, struct GNUNET_PeerIdentity *sender, | |||
744 | GNUNET_STATISTICS_set (plugin->env->stats,"# UNIX bytes received", | 828 | GNUNET_STATISTICS_set (plugin->env->stats,"# UNIX bytes received", |
745 | plugin->bytes_in_recv, GNUNET_NO); | 829 | plugin->bytes_in_recv, GNUNET_NO); |
746 | 830 | ||
831 | addr = GNUNET_HELLO_address_allocate(sender, "unix", un->sun_path, strlen (un->sun_path)); | ||
832 | s = lookup_session (plugin, sender, un); | ||
833 | if (NULL == s) | ||
834 | s = unix_plugin_get_session (plugin, addr); | ||
835 | reschedule_session_timeout (s); | ||
836 | |||
747 | plugin->env->receive (plugin->env->cls, sender, currhdr, | 837 | plugin->env->receive (plugin->env->cls, sender, currhdr, |
748 | (const struct GNUNET_ATS_Information *) &ats, 2, | 838 | (const struct GNUNET_ATS_Information *) &ats, 2, |
749 | NULL, un->sun_path, strlen (un->sun_path) + 1); | 839 | s, un->sun_path, strlen (un->sun_path) + 1); |
840 | GNUNET_free (addr); | ||
750 | } | 841 | } |
751 | 842 | ||
752 | 843 | ||
@@ -1132,6 +1223,85 @@ address_notification (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1132 | strlen (plugin->unix_socket_path) + 1); | 1223 | strlen (plugin->unix_socket_path) + 1); |
1133 | } | 1224 | } |
1134 | 1225 | ||
1226 | |||
1227 | /** | ||
1228 | * Session was idle, so disconnect it | ||
1229 | */ | ||
1230 | static void | ||
1231 | session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1232 | { | ||
1233 | GNUNET_assert (NULL != cls); | ||
1234 | struct Session *s = cls; | ||
1235 | |||
1236 | s->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
1237 | |||
1238 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Session %p was idle for %llu, disconnecting\n", | ||
1239 | s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); | ||
1240 | |||
1241 | /* call session destroy function */ | ||
1242 | disconnect_session(s); | ||
1243 | |||
1244 | } | ||
1245 | |||
1246 | /** | ||
1247 | * Start session timeout | ||
1248 | */ | ||
1249 | static void | ||
1250 | start_session_timeout (struct Session *s) | ||
1251 | { | ||
1252 | GNUNET_assert (NULL != s); | ||
1253 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == s->timeout_task); | ||
1254 | |||
1255 | s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
1256 | &session_timeout, | ||
1257 | s); | ||
1258 | |||
1259 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout for session %p set to %llu\n", | ||
1260 | s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); | ||
1261 | } | ||
1262 | |||
1263 | /** | ||
1264 | * Increment session timeout due to activity | ||
1265 | */ | ||
1266 | static void | ||
1267 | reschedule_session_timeout (struct Session *s) | ||
1268 | { | ||
1269 | GNUNET_assert (NULL != s); | ||
1270 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != s->timeout_task); | ||
1271 | |||
1272 | GNUNET_SCHEDULER_cancel (s->timeout_task); | ||
1273 | s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
1274 | &session_timeout, | ||
1275 | s); | ||
1276 | |||
1277 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout rescheduled for session %p set to %llu\n", | ||
1278 | s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); | ||
1279 | } | ||
1280 | |||
1281 | /** | ||
1282 | * Cancel timeout | ||
1283 | */ | ||
1284 | static void | ||
1285 | stop_session_timeout (struct Session *s) | ||
1286 | { | ||
1287 | GNUNET_assert (NULL != s); | ||
1288 | |||
1289 | if (GNUNET_SCHEDULER_NO_TASK != s->timeout_task) | ||
1290 | { | ||
1291 | GNUNET_SCHEDULER_cancel (s->timeout_task); | ||
1292 | s->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
1293 | |||
1294 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout rescheduled for session %p canceled\n", | ||
1295 | s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); | ||
1296 | } | ||
1297 | else | ||
1298 | { | ||
1299 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout for session %p was not active\n", | ||
1300 | s); | ||
1301 | } | ||
1302 | } | ||
1303 | |||
1304 | |||
1135 | /** | 1305 | /** |
1136 | * The exported method. Makes the core api available via a global and | 1306 | * The exported method. Makes the core api available via a global and |
1137 | * returns the unix transport API. | 1307 | * returns the unix transport API. |