aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-02-15 21:23:35 +0000
committerChristian Grothoff <christian@grothoff.org>2010-02-15 21:23:35 +0000
commit1bdc9fdda72046693bb63a56011b10ca3bf9bbf1 (patch)
tree37b88557409e3dcb84fbb434760c833e40ab563a /src
parentc85876510b686d59afded1fa65879eb81ae916dd (diff)
downloadgnunet-1bdc9fdda72046693bb63a56011b10ca3bf9bbf1.tar.gz
gnunet-1bdc9fdda72046693bb63a56011b10ca3bf9bbf1.zip
code cleanup
Diffstat (limited to 'src')
-rw-r--r--src/transport/plugin_transport_tcp.c200
1 files changed, 92 insertions, 108 deletions
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c
index 725a3bde4..50bfa70f4 100644
--- a/src/transport/plugin_transport_tcp.c
+++ b/src/transport/plugin_transport_tcp.c
@@ -27,6 +27,7 @@
27#include "platform.h" 27#include "platform.h"
28#include "gnunet_hello_lib.h" 28#include "gnunet_hello_lib.h"
29#include "gnunet_connection_lib.h" 29#include "gnunet_connection_lib.h"
30#include "gnunet_container_lib.h"
30#include "gnunet_os_lib.h" 31#include "gnunet_os_lib.h"
31#include "gnunet_protocols.h" 32#include "gnunet_protocols.h"
32#include "gnunet_resolver_service.h" 33#include "gnunet_resolver_service.h"
@@ -43,11 +44,6 @@
43/** 44/**
44 * How long until we give up on transmitting the welcome message? 45 * How long until we give up on transmitting the welcome message?
45 */ 46 */
46#define WELCOME_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
47
48/**
49 * How long until we give up on transmitting the welcome message?
50 */
51#define HOSTNAME_RESOLVE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) 47#define HOSTNAME_RESOLVE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
52 48
53 49
@@ -83,21 +79,19 @@ struct PendingMessage
83{ 79{
84 80
85 /** 81 /**
86 * This is a linked list. 82 * This is a doubly-linked list.
87 */ 83 */
88 struct PendingMessage *next; 84 struct PendingMessage *next;
89 85
90 /** 86 /**
91 * The pending message 87 * This is a doubly-linked list.
92 */ 88 */
93 const char *msg; 89 struct PendingMessage *prev;
94 90
95 /** 91 /**
96 * So that the gnunet-service-transport can group messages together, 92 * The pending message
97 * these pending messages need to accept a message buffer and size
98 * instead of just a GNUNET_MessageHeader.
99 */ 93 */
100 size_t message_size; 94 const char *msg;
101 95
102 /** 96 /**
103 * Continuation function to call once the message 97 * Continuation function to call once the message
@@ -116,6 +110,13 @@ struct PendingMessage
116 */ 110 */
117 struct GNUNET_TIME_Absolute timeout; 111 struct GNUNET_TIME_Absolute timeout;
118 112
113 /**
114 * So that the gnunet-service-transport can group messages together,
115 * these pending messages need to accept a message buffer and size
116 * instead of just a GNUNET_MessageHeader.
117 */
118 size_t message_size;
119
119}; 120};
120 121
121 122
@@ -144,7 +145,13 @@ struct Session
144 * Messages currently pending for transmission 145 * Messages currently pending for transmission
145 * to this peer, if any. 146 * to this peer, if any.
146 */ 147 */
147 struct PendingMessage *pending_messages; 148 struct PendingMessage *pending_messages_head;
149
150 /**
151 * Messages currently pending for transmission
152 * to this peer, if any.
153 */
154 struct PendingMessage *pending_messages_tail;
148 155
149 /** 156 /**
150 * Handle for pending transmission request. 157 * Handle for pending transmission request.
@@ -261,7 +268,10 @@ struct Plugin
261 268
262 269
263/** 270/**
264 * Find the session handle for the given peer. 271 * Find a session handle for the given peer.
272 * FIXME: using a hash map we could do this in O(1).
273 *
274 * @return NULL if no matching session exists
265 */ 275 */
266static struct Session * 276static struct Session *
267find_session_by_target (struct Plugin *plugin, 277find_session_by_target (struct Plugin *plugin,
@@ -280,7 +290,9 @@ find_session_by_target (struct Plugin *plugin,
280 290
281 291
282/** 292/**
283 * Find the session handle for the given peer. 293 * Find the session handle for the given client.
294 *
295 * @return NULL if no matching session exists
284 */ 296 */
285static struct Session * 297static struct Session *
286find_session_by_client (struct Plugin *plugin, 298find_session_by_client (struct Plugin *plugin,
@@ -296,28 +308,7 @@ find_session_by_client (struct Plugin *plugin,
296 308
297 309
298/** 310/**
299 * Create a welcome message. 311 * Create a new session. Also queues a welcome message.
300 */
301static struct PendingMessage *
302create_welcome (struct Plugin *plugin)
303{
304 struct PendingMessage *pm;
305 struct WelcomeMessage welcome;
306
307 pm = GNUNET_malloc (sizeof (struct PendingMessage) + sizeof (struct WelcomeMessage));
308 pm->msg = (const char*) &pm[1];
309 pm->message_size = sizeof (struct WelcomeMessage);
310 welcome.header.size = htons (sizeof (struct WelcomeMessage));
311 welcome.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME);
312 welcome.clientIdentity = *plugin->env->my_identity;
313 memcpy (&pm[1], &welcome, sizeof (welcome));
314 pm->timeout = GNUNET_TIME_relative_to_absolute (WELCOME_TIMEOUT);
315 return pm;
316}
317
318
319/**
320 * Create a new session.
321 * 312 *
322 * @param plugin us 313 * @param plugin us
323 * @param target peer to connect to 314 * @param target peer to connect to
@@ -330,6 +321,8 @@ create_session (struct Plugin *plugin,
330 struct GNUNET_SERVER_Client *client) 321 struct GNUNET_SERVER_Client *client)
331{ 322{
332 struct Session *ret; 323 struct Session *ret;
324 struct PendingMessage *pm;
325 struct WelcomeMessage welcome;
333 326
334 ret = GNUNET_malloc (sizeof (struct Session)); 327 ret = GNUNET_malloc (sizeof (struct Session));
335 ret->plugin = plugin; 328 ret->plugin = plugin;
@@ -340,7 +333,17 @@ create_session (struct Plugin *plugin,
340 ret->last_quota_update = GNUNET_TIME_absolute_get (); 333 ret->last_quota_update = GNUNET_TIME_absolute_get ();
341 ret->quota_in = plugin->env->default_quota_in; 334 ret->quota_in = plugin->env->default_quota_in;
342 ret->expecting_welcome = GNUNET_YES; 335 ret->expecting_welcome = GNUNET_YES;
343 ret->pending_messages = create_welcome (plugin); 336 pm = GNUNET_malloc (sizeof (struct PendingMessage) + sizeof (struct WelcomeMessage));
337 pm->msg = (const char*) &pm[1];
338 pm->message_size = sizeof (struct WelcomeMessage);
339 welcome.header.size = htons (sizeof (struct WelcomeMessage));
340 welcome.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME);
341 welcome.clientIdentity = *plugin->env->my_identity;
342 memcpy (&pm[1], &welcome, sizeof (welcome));
343 pm->timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
344 GNUNET_CONTAINER_DLL_insert (ret->pending_messages_head,
345 ret->pending_messages_tail,
346 pm);
344 return ret; 347 return ret;
345} 348}
346 349
@@ -384,13 +387,16 @@ do_transmit (void *cls, size_t size, void *buf)
384 GNUNET_i2s (&session->target)); 387 GNUNET_i2s (&session->target));
385#endif 388#endif
386 /* timeout */ 389 /* timeout */
387 while (NULL != (pm = session->pending_messages)) 390 while (NULL != (pm = session->pending_messages_head))
388 { 391 {
389 session->pending_messages = pm->next; 392 GNUNET_CONTAINER_DLL_remove (session->pending_messages_head,
393 session->pending_messages_tail,
394 pm);
390#if DEBUG_TCP 395#if DEBUG_TCP
391 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 396 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
392 "tcp", 397 "tcp",
393 "Failed to transmit message of to `%4s'.\n", 398 "Failed to transmit %u byte message to `%4s'.\n",
399 pm->message_size,
394 GNUNET_i2s (&session->target)); 400 GNUNET_i2s (&session->target));
395#endif 401#endif
396 if (pm->transmit_cont != NULL) 402 if (pm->transmit_cont != NULL)
@@ -402,7 +408,7 @@ do_transmit (void *cls, size_t size, void *buf)
402 } 408 }
403 ret = 0; 409 ret = 0;
404 cbuf = buf; 410 cbuf = buf;
405 while (NULL != (pm = session->pending_messages)) 411 while (NULL != (pm = session->pending_messages_head))
406 { 412 {
407 if (size < pm->message_size) 413 if (size < pm->message_size)
408 break; 414 break;
@@ -410,7 +416,9 @@ do_transmit (void *cls, size_t size, void *buf)
410 cbuf += pm->message_size; 416 cbuf += pm->message_size;
411 ret += pm->message_size; 417 ret += pm->message_size;
412 size -= pm->message_size; 418 size -= pm->message_size;
413 session->pending_messages = pm->next; 419 GNUNET_CONTAINER_DLL_remove (session->pending_messages_head,
420 session->pending_messages_tail,
421 pm);
414 if (pm->transmit_cont != NULL) 422 if (pm->transmit_cont != NULL)
415 pm->transmit_cont (pm->transmit_cont_cls, 423 pm->transmit_cont (pm->transmit_cont_cls,
416 &session->target, GNUNET_OK); 424 &session->target, GNUNET_OK);
@@ -439,7 +447,7 @@ process_pending_messages (struct Session *session)
439 GNUNET_assert (session->client != NULL); 447 GNUNET_assert (session->client != NULL);
440 if (session->transmit_handle != NULL) 448 if (session->transmit_handle != NULL)
441 return; 449 return;
442 if (NULL == (pm = session->pending_messages)) 450 if (NULL == (pm = session->pending_messages_head))
443 return; 451 return;
444 session->transmit_handle 452 session->transmit_handle
445 = GNUNET_SERVER_notify_transmit_ready (session->client, 453 = GNUNET_SERVER_notify_transmit_ready (session->client,
@@ -492,7 +500,7 @@ disconnect_session (struct Session *session)
492 (session->transmit_handle); 500 (session->transmit_handle);
493 session->transmit_handle = NULL; 501 session->transmit_handle = NULL;
494 } 502 }
495 while (NULL != (pm = session->pending_messages)) 503 while (NULL != (pm = session->pending_messages_head))
496 { 504 {
497#if DEBUG_TCP 505#if DEBUG_TCP
498 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 506 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
@@ -503,7 +511,9 @@ disconnect_session (struct Session *session)
503 "Could not deliver message to `%4s', notifying.\n", 511 "Could not deliver message to `%4s', notifying.\n",
504 GNUNET_i2s (&session->target)); 512 GNUNET_i2s (&session->target));
505#endif 513#endif
506 session->pending_messages = pm->next; 514 GNUNET_CONTAINER_DLL_remove (session->pending_messages_head,
515 session->pending_messages_tail,
516 pm);
507 if (NULL != pm->transmit_cont) 517 if (NULL != pm->transmit_cont)
508 pm->transmit_cont (pm->transmit_cont_cls, 518 pm->transmit_cont (pm->transmit_cont_cls,
509 &session->target, GNUNET_SYSERR); 519 &session->target, GNUNET_SYSERR);
@@ -517,10 +527,11 @@ disconnect_session (struct Session *session)
517 "Notifying transport service about loss of data connection with `%4s'.\n", 527 "Notifying transport service about loss of data connection with `%4s'.\n",
518 GNUNET_i2s (&session->target)); 528 GNUNET_i2s (&session->target));
519#endif 529#endif
520 /* Data session that actually went past the 530 /* Data session that actually went past the initial handshake;
521 initial handshake; transport service may 531 transport service may know about this one, so we need to
522 know about this one, so we need to
523 notify transport service about disconnect */ 532 notify transport service about disconnect */
533 // FIXME: we should have a very clear connect-disconnect
534 // protocol with gnunet-service-transport!
524 session->plugin->env->receive (session->plugin->env->cls, 535 session->plugin->env->receive (session->plugin->env->cls,
525 &session->target, NULL, 536 &session->target, NULL,
526 1, 537 1,
@@ -584,7 +595,6 @@ tcp_plugin_send (void *cls,
584 struct Plugin *plugin = cls; 595 struct Plugin *plugin = cls;
585 struct Session *session; 596 struct Session *session;
586 struct PendingMessage *pm; 597 struct PendingMessage *pm;
587 struct PendingMessage *pme;
588 struct GNUNET_CONNECTION_Handle *sa; 598 struct GNUNET_CONNECTION_Handle *sa;
589 int af; 599 int af;
590 600
@@ -668,19 +678,10 @@ tcp_plugin_send (void *cls,
668 pm->transmit_cont_cls = cont_cls; 678 pm->transmit_cont_cls = cont_cls;
669 679
670 /* append pm to pending_messages list */ 680 /* append pm to pending_messages list */
671 pme = session->pending_messages; 681 GNUNET_CONTAINER_DLL_insert_after (session->pending_messages_head,
672 if (pme == NULL) 682 session->pending_messages_tail,
673 { 683 session->pending_messages_tail,
674 session->pending_messages = pm; 684 pm);
675 }
676 else
677 {
678 /* FIXME: this could be done faster by keeping
679 track of the tail of the list... */
680 while (NULL != pme->next)
681 pme = pme->next;
682 pme->next = pm;
683 }
684#if DEBUG_TCP 685#if DEBUG_TCP
685 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 686 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
686 "tcp", 687 "tcp",
@@ -729,7 +730,7 @@ tcp_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
729 &session->target, 730 &session->target,
730 sizeof (struct GNUNET_PeerIdentity))) 731 sizeof (struct GNUNET_PeerIdentity)))
731 { 732 {
732 pm = session->pending_messages; 733 pm = session->pending_messages_head;
733 while (pm != NULL) 734 while (pm != NULL)
734 { 735 {
735 pm->transmit_cont = NULL; 736 pm->transmit_cont = NULL;
@@ -1008,10 +1009,11 @@ handle_tcp_welcome (void *cls,
1008 GNUNET_SERVER_client_get_address (client, &vaddr, &alen)) 1009 GNUNET_SERVER_client_get_address (client, &vaddr, &alen))
1009 { 1010 {
1010#if DEBUG_TCP 1011#if DEBUG_TCP
1011 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1012 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1012 "tcp", 1013 "tcp",
1013 "Found address for incoming `%s' message\n", 1014 "Found address `%s' for incoming connection %p\n",
1014 "WELCOME"); 1015 GNUNET_a2s (vaddr, alen),
1016 client);
1015#endif 1017#endif
1016 session->connect_addr = vaddr; 1018 session->connect_addr = vaddr;
1017 session->connect_alen = alen; 1019 session->connect_alen = alen;
@@ -1019,17 +1021,16 @@ handle_tcp_welcome (void *cls,
1019 else 1021 else
1020 { 1022 {
1021#if DEBUG_TCP 1023#if DEBUG_TCP
1022 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1024 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1023 "tcp", 1025 "tcp",
1024 "Didn't find address for incoming `%s' message\n", 1026 "Did not obtain TCP socket address for incoming connection\n");
1025 "WELCOME");
1026#endif 1027#endif
1027 } 1028 }
1028#if DEBUG_TCP 1029#if DEBUG_TCP
1029 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1030 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1030 "tcp", 1031 "tcp",
1031 "Creating new session %p for incoming `%s' message.\n", 1032 "Creating new session %p for connection %p\n",
1032 session, "WELCOME"); 1033 session, client);
1033#endif 1034#endif
1034 process_pending_messages (session); 1035 process_pending_messages (session);
1035 } 1036 }
@@ -1113,17 +1114,10 @@ handle_tcp_data (void *cls,
1113 1114
1114 if (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME == ntohs(message->type)) 1115 if (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME == ntohs(message->type))
1115 { 1116 {
1116#if DEBUG_TCP 1117 /* We don't want to propagate WELCOME messages up! */
1117 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1118 "tcp", "Received a welcome, NOT sending to clients!\n");
1119#endif
1120 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1118 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1121 return; /* We don't want to propagate WELCOME messages up! */ 1119 return;
1122 } 1120 }
1123#if DEBUG_TCP
1124 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1125 "tcp", "Received DATA message, checking session!\n");
1126#endif
1127 if ( (NULL == session) || (GNUNET_NO != session->expecting_welcome)) 1121 if ( (NULL == session) || (GNUNET_NO != session->expecting_welcome))
1128 { 1122 {
1129 GNUNET_break_op (0); 1123 GNUNET_break_op (0);
@@ -1132,15 +1126,11 @@ handle_tcp_data (void *cls,
1132 } 1126 }
1133#if DEBUG_TCP 1127#if DEBUG_TCP
1134 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1128 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1135 "tcp", "Receiving %u bytes from `%4s'.\n", 1129 "tcp",
1136 msize, GNUNET_i2s (&session->target)); 1130 "Passing %u bytes of type %u from `%4s' to transport service.\n",
1137#endif 1131 (unsigned int) msize,
1138#if DEBUG_TCP 1132 (unsigned int) ntohs (message->type),
1139 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1133 GNUNET_i2s (&session->target));
1140 "tcp",
1141 "Forwarding %u bytes of data of type %u to transport service.\n",
1142 (unsigned int) msize,
1143 (unsigned int) ntohs (message->type));
1144#endif 1134#endif
1145 plugin->env->receive (plugin->env->cls, &session->target, message, 1, 1135 plugin->env->receive (plugin->env->cls, &session->target, message, 1,
1146 session->connect_addr, 1136 session->connect_addr,
@@ -1168,21 +1158,6 @@ static struct GNUNET_SERVER_MessageHandler my_handlers[] = {
1168}; 1158};
1169 1159
1170 1160
1171static void
1172create_tcp_handlers (struct Plugin *plugin)
1173{
1174 unsigned int i;
1175 plugin->handlers = GNUNET_malloc (sizeof (my_handlers));
1176 memcpy (plugin->handlers, my_handlers, sizeof (my_handlers));
1177 for (i = 0;
1178 i <
1179 sizeof (my_handlers) / sizeof (struct GNUNET_SERVER_MessageHandler);
1180 i++)
1181 plugin->handlers[i].callback_cls = plugin;
1182 GNUNET_SERVER_add_handlers (plugin->server, plugin->handlers);
1183}
1184
1185
1186/** 1161/**
1187 * Functions with this signature are called whenever a peer 1162 * Functions with this signature are called whenever a peer
1188 * is disconnected on the network level. 1163 * is disconnected on the network level.
@@ -1288,6 +1263,7 @@ libgnunet_plugin_transport_tcp_init (void *cls)
1288 struct GNUNET_SERVICE_Context *service; 1263 struct GNUNET_SERVICE_Context *service;
1289 unsigned long long aport; 1264 unsigned long long aport;
1290 unsigned long long bport; 1265 unsigned long long bport;
1266 unsigned int i;
1291 1267
1292 service = GNUNET_SERVICE_start ("transport-tcp", env->sched, env->cfg); 1268 service = GNUNET_SERVICE_start ("transport-tcp", env->sched, env->cfg);
1293 if (service == NULL) 1269 if (service == NULL)
@@ -1337,7 +1313,15 @@ libgnunet_plugin_transport_tcp_init (void *cls)
1337 api->check_address = &tcp_plugin_check_address; 1313 api->check_address = &tcp_plugin_check_address;
1338 plugin->service = service; 1314 plugin->service = service;
1339 plugin->server = GNUNET_SERVICE_get_server (service); 1315 plugin->server = GNUNET_SERVICE_get_server (service);
1340 create_tcp_handlers (plugin); 1316 plugin->handlers = GNUNET_malloc (sizeof (my_handlers));
1317 memcpy (plugin->handlers, my_handlers, sizeof (my_handlers));
1318 for (i = 0;
1319 i <
1320 sizeof (my_handlers) / sizeof (struct GNUNET_SERVER_MessageHandler);
1321 i++)
1322 plugin->handlers[i].callback_cls = plugin;
1323 GNUNET_SERVER_add_handlers (plugin->server, plugin->handlers);
1324
1341 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, 1325 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO,
1342 "tcp", _("TCP transport listening on port %llu\n"), bport); 1326 "tcp", _("TCP transport listening on port %llu\n"), bport);
1343 if (aport != bport) 1327 if (aport != bport)