aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNathan S. Evans <evans@in.tum.de>2010-01-28 12:01:04 +0000
committerNathan S. Evans <evans@in.tum.de>2010-01-28 12:01:04 +0000
commit1c051694d229c10ee0c5ed4a60b4f7b46e972b3e (patch)
tree070e09634187d54d6fbaf78dc74487ee9120d1ed /src
parentf206220e03ccf5cfdb8e8d51d253fed17db4d4ee (diff)
downloadgnunet-1c051694d229c10ee0c5ed4a60b4f7b46e972b3e.tar.gz
gnunet-1c051694d229c10ee0c5ed4a60b4f7b46e972b3e.zip
udp test_transport_api test now working, tcp not... but a good omen
Diffstat (limited to 'src')
-rw-r--r--src/transport/gnunet-service-transport.c930
-rw-r--r--src/transport/plugin_transport_udp.c129
-rw-r--r--src/transport/test_transport_api.c7
-rw-r--r--src/transport/transport.h2
-rw-r--r--src/transport/transport_api.c15
5 files changed, 575 insertions, 508 deletions
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index 28fd38126..b8672e99d 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -97,6 +97,98 @@
97 97
98 98
99/** 99/**
100 * List of addresses of other peers
101 */
102struct PeerAddressList
103{
104 /**
105 * This is a linked list.
106 */
107 struct PeerAddressList *next;
108
109 /*
110 * Pointer to the validation associated with this
111 * address. May be NULL if already validated!
112 */
113 struct ValidationAddress *validation;
114
115 /**
116 * Which of our transport plugins does this entry
117 * belong to?
118 */
119 struct TransportPlugin *plugin;
120
121 /**
122 * Neighbor this entry belongs to.
123 */
124 struct NeighborList *neighbor;
125
126 /*
127 * Ready list (transport) that this peer belongs to
128 */
129 struct ReadyList *ready_list;
130 /**
131 * How long until we auto-expire this address (unless it is
132 * re-confirmed by the transport)?
133 */
134 struct GNUNET_TIME_Absolute expires;
135
136 /**
137 * Length of addr.
138 */
139 size_t addrlen;
140
141 /**
142 * The address
143 */
144 char *addr;
145
146 /**
147 * Is this plugin ready to transmit to the specific target?
148 * GNUNET_NO if not. Initially, all plugins are marked ready. If a
149 * transmission is in progress, "transmit_ready" is set to
150 * GNUNET_NO.
151 */
152 int transmit_ready;
153
154 /**
155 * What was the last latency observed for this plugin
156 * and peer? Invalid if connected is GNUNET_NO.
157 */
158 struct GNUNET_TIME_Relative latency;
159
160 /**
161 * If we did not successfully transmit a message to the given peer
162 * via this connection during the specified time, we should consider
163 * the connection to be dead. This is used in the case that a TCP
164 * transport simply stalls writing to the stream but does not
165 * formerly get a signal that the other peer died.
166 */
167 struct GNUNET_TIME_Absolute timeout;
168
169 /**
170 * Is this plugin currently connected? The first time
171 * we transmit or send data to a peer via a particular
172 * plugin, we set this to GNUNET_YES. If we later get
173 * an error (disconnect notification or transmission
174 * failure), we set it back to GNUNET_NO. Each time the
175 * value is set to GNUNET_YES, we increment the
176 * "connect_attempts" counter. If that one reaches a
177 * particular threshold, we consider the plugin to not
178 * be working properly at this time for the given peer
179 * and remove it from the eligible list.
180 */
181 int connected;
182
183 /**
184 * How often have we tried to connect using this plugin?
185 */
186 unsigned int connect_attempts;
187
188};
189
190
191/**
100 * Entry in linked list of network addresses. 192 * Entry in linked list of network addresses.
101 */ 193 */
102struct AddressList 194struct AddressList
@@ -195,13 +287,19 @@ struct MessageQueue
195 struct MessageQueue *next; 287 struct MessageQueue *next;
196 288
197 /** 289 /**
198 * The message we want to transmit. 290 * The message(s) we want to transmit, GNUNET_MessageHeader(s)
291 * stuck together in memory.
292 */
293 char *message_buf;
294
295 /*
296 * Size of the message buf
199 */ 297 */
200 struct GNUNET_MessageHeader *message; 298 size_t message_buf_size;
201 299
202 /** 300 /**
203 * Client responsible for queueing the message; 301 * Client responsible for queueing the message;
204 * used to check that a client has not two messages 302 * used to check that a client has no two messages
205 * pending for the same target. Can be NULL. 303 * pending for the same target. Can be NULL.
206 */ 304 */
207 struct TransportClient *client; 305 struct TransportClient *client;
@@ -231,6 +329,11 @@ struct MessageQueue
231 */ 329 */
232 unsigned int priority; 330 unsigned int priority;
233 331
332 /*
333 * Using which specific address should we send this message?
334 */
335 struct PeerAddressList *specific_peer;
336
234}; 337};
235 338
236 339
@@ -240,7 +343,6 @@ struct MessageQueue
240 */ 343 */
241struct ReadyList 344struct ReadyList
242{ 345{
243
244 /** 346 /**
245 * This is a linked list. 347 * This is a linked list.
246 */ 348 */
@@ -257,39 +359,11 @@ struct ReadyList
257 */ 359 */
258 struct NeighborList *neighbor; 360 struct NeighborList *neighbor;
259 361
260 /** 362 /*
261 * What was the last latency observed for this plugin 363 * Transport addresses, latency, and readiness for
262 * and peer? Invalid if connected is GNUNET_NO. 364 * this particular plugin.
263 */
264 struct GNUNET_TIME_Relative latency;
265
266 /**
267 * If we did not successfully transmit a message to the given peer
268 * via this connection during the specified time, we should consider
269 * the connection to be dead. This is used in the case that a TCP
270 * transport simply stalls writing to the stream but does not
271 * formerly get a signal that the other peer died.
272 */
273 struct GNUNET_TIME_Absolute timeout;
274
275 /**
276 * Is this plugin currently connected? The first time
277 * we transmit or send data to a peer via a particular
278 * plugin, we set this to GNUNET_YES. If we later get
279 * an error (disconnect notification or transmission
280 * failure), we set it back to GNUNET_NO. Each time the
281 * value is set to GNUNET_YES, we increment the
282 * "connect_attempts" counter. If that one reaches a
283 * particular threshold, we consider the plugin to not
284 * be working properly at this time for the given peer
285 * and remove it from the eligible list.
286 */
287 int connected;
288
289 /**
290 * How often have we tried to connect using this plugin?
291 */ 365 */
292 unsigned int connect_attempts; 366 struct PeerAddressList *addresses;
293 367
294 /** 368 /**
295 * Is this plugin ready to transmit to the specific target? 369 * Is this plugin ready to transmit to the specific target?
@@ -297,8 +371,12 @@ struct ReadyList
297 * transmission is in progress, "transmit_ready" is set to 371 * transmission is in progress, "transmit_ready" is set to
298 * GNUNET_NO. 372 * GNUNET_NO.
299 */ 373 */
300 int transmit_ready; 374 int plugin_transmit_ready;
301 375
376 /*
377 * Are any of our PeerAddressList addresses still connected?
378 */
379 int connected; /* FIXME: dynamically check PeerAddressList addresses when asked to! */
302}; 380};
303 381
304 382
@@ -330,16 +408,6 @@ struct NeighborList
330 */ 408 */
331 struct GNUNET_PeerIdentity id; 409 struct GNUNET_PeerIdentity id;
332 410
333 /*
334 * Opaque addr of this peer, only known to the plugin
335 */
336 char *addr;
337
338 /*
339 * Size of addr
340 */
341 size_t addr_len;
342
343 /** 411 /**
344 * ID of task scheduled to run when this peer is about to 412 * ID of task scheduled to run when this peer is about to
345 * time out (will free resources associated with the peer). 413 * time out (will free resources associated with the peer).
@@ -388,7 +456,7 @@ struct NeighborList
388 * (used to make up a fake ACK for clients connecting after 456 * (used to make up a fake ACK for clients connecting after
389 * the neighbor connected to us). 457 * the neighbor connected to us).
390 */ 458 */
391 int saw_ack; 459 int received_pong;
392 460
393 /* The latency we have seen for this particular address for 461 /* The latency we have seen for this particular address for
394 * this particular peer. This latency may have been calculated 462 * this particular peer. This latency may have been calculated
@@ -472,6 +540,11 @@ struct TransportPongMessage
472 */ 540 */
473 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded signer; 541 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded signer;
474 542
543 /*
544 * Size of address appended to this message
545 */
546 size_t addrlen;
547
475}; 548};
476 549
477/** 550/**
@@ -543,6 +616,11 @@ struct ValidationAddress
543 */ 616 */
544 struct ValidationAddress *next; 617 struct ValidationAddress *next;
545 618
619 /*
620 * What peer_address does this validation belong to?
621 */
622 struct PeerAddressList *peer_address;
623
546 /** 624 /**
547 * Name of the transport. 625 * Name of the transport.
548 */ 626 */
@@ -553,10 +631,10 @@ struct ValidationAddress
553 */ 631 */
554 struct GNUNET_TIME_Absolute expiration; 632 struct GNUNET_TIME_Absolute expiration;
555 633
556 /** 634 /*
557 * Length of the address we are validating. 635 * At what time did we send this validation?
558 */ 636 */
559 size_t addr_len; 637 struct GNUNET_TIME_Absolute send_time;
560 638
561 /** 639 /**
562 * Challenge number we used. 640 * Challenge number we used.
@@ -603,6 +681,33 @@ struct ValidationList
603}; 681};
604 682
605 683
684struct CheckHelloValidatedContext
685{
686 /**
687 * Plugin for which we are validating.
688 */
689 struct TransportPlugin *plugin;
690
691 /**
692 * Hello that we are validating.
693 */
694 struct GNUNET_HELLO_Message *hello;
695
696 /**
697 * Validation list being built.
698 */
699 struct ValidationList *e;
700
701 /**
702 * Context for peerinfo iteration.
703 * NULL after we are done processing peerinfo's information.
704 */
705 struct GNUNET_PEERINFO_IteratorContext *piter;
706
707};
708
709
710
606/** 711/**
607 * HELLOs awaiting validation. 712 * HELLOs awaiting validation.
608 */ 713 */
@@ -670,6 +775,31 @@ static struct NeighborList *neighbors;
670 */ 775 */
671static uint32_t max_connect_per_transport; 776static uint32_t max_connect_per_transport;
672 777
778/**
779 * The peer specified by the given neighbor has timed-out or a plugin
780 * has disconnected. We may either need to do nothing (other plugins
781 * still up), or trigger a full disconnect and clean up. This
782 * function updates our state and do the necessary notifications.
783 * Also notifies our clients that the neighbor is now officially
784 * gone.
785 *
786 * @param n the neighbor list entry for the peer
787 * @param check should we just check if all plugins
788 * disconnected or must we ask all plugins to
789 * disconnect?
790 */
791static void disconnect_neighbor (struct NeighborList *n, int check);
792
793
794/**
795 * Check the ready list for the given neighbor and
796 * if a plugin is ready for transmission (and if we
797 * have a message), do so!
798 *
799 * @param neighbor target peer for which to check the plugins
800 */
801static ssize_t try_transmission_to_peer (struct NeighborList *neighbor);
802
673 803
674/** 804/**
675 * Find an entry in the neighbor list for a particular peer. 805 * Find an entry in the neighbor list for a particular peer.
@@ -680,24 +810,14 @@ static uint32_t max_connect_per_transport;
680 * @return NULL if not found. 810 * @return NULL if not found.
681 */ 811 */
682static struct NeighborList * 812static struct NeighborList *
683find_neighbor (const struct GNUNET_PeerIdentity *key, const char *sender_address, 813find_neighbor (const struct GNUNET_PeerIdentity *key)
684 size_t sender_address_len)
685{ 814{
686 struct NeighborList *head = neighbors; 815 struct NeighborList *head = neighbors;
687 if (sender_address == NULL) 816
688 { 817 while ((head != NULL) &&
689 while ((head != NULL) && 818 (0 != memcmp (key, &head->id, sizeof (struct GNUNET_PeerIdentity))))
690 (0 != memcmp (key, &head->id, sizeof (struct GNUNET_PeerIdentity)))) 819 head = head->next;
691 head = head->next; 820
692 }
693 else
694 {
695 while ((head != NULL) &&
696 (0 != memcmp (key, &head->id, sizeof (struct GNUNET_PeerIdentity))) &&
697 (sender_address_len != head->addr_len) &&
698 (0 != memcmp (sender_address, &head->addr, head->addr_len)))
699 head = head->next;
700 }
701 return head; 821 return head;
702} 822}
703 823
@@ -904,43 +1024,18 @@ try_alternative_plugins (struct NeighborList *neighbor)
904 = GNUNET_TIME_relative_to_absolute (PLUGIN_RETRY_FREQUENCY); 1024 = GNUNET_TIME_relative_to_absolute (PLUGIN_RETRY_FREQUENCY);
905 1025
906 rl = neighbor->plugins; 1026 rl = neighbor->plugins;
1027#if WTF /* FIXME: What is this supposed to do? */
907 while (rl != NULL) 1028 while (rl != NULL)
908 { 1029 {
909 if (rl->connect_attempts > 0) 1030 if (rl->connect_attempts > 0)
910 rl->connect_attempts--; /* amnesty */ 1031 rl->connect_attempts--; /* amnesty */
911 rl = rl->next; 1032 rl = rl->next;
912 } 1033 }
913 1034#endif
914} 1035}
915 1036
916 1037
917/** 1038/**
918 * The peer specified by the given neighbor has timed-out or a plugin
919 * has disconnected. We may either need to do nothing (other plugins
920 * still up), or trigger a full disconnect and clean up. This
921 * function updates our state and do the necessary notifications.
922 * Also notifies our clients that the neighbor is now officially
923 * gone.
924 *
925 * @param n the neighbor list entry for the peer
926 * @param check should we just check if all plugins
927 * disconnected or must we ask all plugins to
928 * disconnect?
929 */
930static void disconnect_neighbor (struct NeighborList *n, int check);
931
932
933/**
934 * Check the ready list for the given neighbor and
935 * if a plugin is ready for transmission (and if we
936 * have a message), do so!
937 *
938 * @param neighbor target peer for which to check the plugins
939 */
940static void try_transmission_to_peer (struct NeighborList *neighbor);
941
942
943/**
944 * Function called by the GNUNET_TRANSPORT_TransmitFunction 1039 * Function called by the GNUNET_TRANSPORT_TransmitFunction
945 * upon "completion" of a send request. This tells the API 1040 * upon "completion" of a send request. This tells the API
946 * that it is now legal to send another message to the given 1041 * that it is now legal to send another message to the given
@@ -976,7 +1071,7 @@ transmit_send_continuation (void *cls,
976 GNUNET_assert (rl != NULL); 1071 GNUNET_assert (rl != NULL);
977 if (result == GNUNET_OK) 1072 if (result == GNUNET_OK)
978 { 1073 {
979 rl->timeout = 1074 mq->specific_peer->timeout =
980 GNUNET_TIME_relative_to_absolute 1075 GNUNET_TIME_relative_to_absolute
981 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); 1076 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
982 } 1077 }
@@ -985,19 +1080,21 @@ transmit_send_continuation (void *cls,
985 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1080 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
986 "Transmission to peer `%s' failed, marking connection as down.\n", 1081 "Transmission to peer `%s' failed, marking connection as down.\n",
987 GNUNET_i2s (target)); 1082 GNUNET_i2s (target));
988 rl->connected = GNUNET_NO; 1083 mq->specific_peer->connected = GNUNET_NO;
989 } 1084 }
990 if (!mq->internal_msg) 1085 if (!mq->internal_msg)
991 { 1086 {
1087#if DEBUG_TRANSPORT
992 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1088 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
993 "Setting transmit_ready on transport!\n"); 1089 "Setting transmit_ready on transport!\n");
994 rl->transmit_ready = GNUNET_YES; 1090#endif
1091 mq->specific_peer->transmit_ready = GNUNET_YES;
995 } 1092 }
996 1093
997 if (mq->client != NULL) 1094 if (mq->client != NULL)
998 { 1095 {
999 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1096 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1000 "Notifying client %p about failed transission to peer `%4s'.\n", 1097 "Notifying client %p about transmission to peer `%4s'.\n",
1001 mq->client, GNUNET_i2s (target)); 1098 mq->client, GNUNET_i2s (target));
1002 send_ok_msg.header.size = htons (sizeof (send_ok_msg)); 1099 send_ok_msg.header.size = htons (sizeof (send_ok_msg));
1003 send_ok_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK); 1100 send_ok_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK);
@@ -1005,7 +1102,7 @@ transmit_send_continuation (void *cls,
1005 send_ok_msg.peer = n->id; 1102 send_ok_msg.peer = n->id;
1006 transmit_to_client (mq->client, &send_ok_msg.header, GNUNET_NO); 1103 transmit_to_client (mq->client, &send_ok_msg.header, GNUNET_NO);
1007 } 1104 }
1008 GNUNET_free (mq->message); 1105 GNUNET_free (mq->message_buf);
1009 GNUNET_free (mq); 1106 GNUNET_free (mq);
1010 /* one plugin just became ready again, try transmitting 1107 /* one plugin just became ready again, try transmitting
1011 another message (if available) */ 1108 another message (if available) */
@@ -1016,38 +1113,39 @@ transmit_send_continuation (void *cls,
1016} 1113}
1017 1114
1018 1115
1019/** 1116
1020 * Check the ready list for the given neighbor and 1117
1021 * if a plugin is ready for transmission (and if we 1118struct PeerAddressList *
1022 * have a message), do so! 1119find_ready_address(struct NeighborList *neighbor)
1023 */
1024static void
1025try_transmission_to_peer (struct NeighborList *neighbor)
1026{ 1120{
1027 struct ReadyList *pos; 1121 struct ReadyList *head = neighbor->plugins;
1028 struct GNUNET_TIME_Relative min_latency; 1122 struct PeerAddressList *addresses;
1029 struct ReadyList *rl; 1123 while (head != NULL)
1030 struct MessageQueue *mq; 1124 {
1031 struct GNUNET_TIME_Absolute now; 1125 addresses = head->addresses;
1126 while ((addresses != NULL) &&
1127 ((addresses->connected != GNUNET_YES) ||
1128 (addresses->transmit_ready != GNUNET_YES)))
1129 {
1130 addresses = addresses->next;
1131 }
1032 1132
1033 if (neighbor->addr != NULL) 1133 if (addresses != NULL)
1034 { 1134 {
1035 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1135#if DEBUG_TRANSPORT
1036 _("try_transmission_to_peer entry: at this point neighbor->addr is NOT NULL\n")); 1136 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1037 } 1137 "Found ready address, connected is %d\n",
1038 else 1138 addresses->connected);
1039 { 1139#endif
1040 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("try_transmission_to_peer entry: at this point neighbor->addr is NULL\n")); 1140 return addresses;
1141 }
1142
1143
1144 head = head->next;
1041 } 1145 }
1146 return NULL;
1042 1147
1043 if (neighbor->messages == NULL) 1148#if 0 /* Do some checks to keep everything sane, return lowest latency connection */
1044 return; /* nothing to do */
1045 try_alternative_plugins (neighbor);
1046 min_latency = GNUNET_TIME_UNIT_FOREVER_REL;
1047 rl = NULL;
1048 mq = neighbor->messages;
1049 now = GNUNET_TIME_absolute_get ();
1050 pos = neighbor->plugins;
1051 while (pos != NULL) 1149 while (pos != NULL)
1052 { 1150 {
1053 /* set plugins that are inactive for a long time back to disconnected */ 1151 /* set plugins that are inactive for a long time back to disconnected */
@@ -1077,50 +1175,65 @@ try_transmission_to_peer (struct NeighborList *neighbor)
1077 } 1175 }
1078 pos = pos->next; 1176 pos = pos->next;
1079 } 1177 }
1080 if (rl == NULL)
1081 {
1082#if DEBUG_TRANSPORT
1083 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1084 "No plugin ready to transmit message\n");
1085#endif 1178#endif
1086 return; /* nobody ready */ 1179}
1087 } 1180
1088 if (GNUNET_NO == rl->connected) 1181/**
1182 * Check the ready list for the given neighbor and
1183 * if a plugin is ready for transmission (and if we
1184 * have a message), do so!
1185 */
1186static ssize_t
1187try_transmission_to_peer (struct NeighborList *neighbor)
1188{
1189 struct GNUNET_TIME_Relative min_latency;
1190 struct ReadyList *rl;
1191 struct MessageQueue *mq;
1192 struct GNUNET_TIME_Absolute now;
1193
1194 if (neighbor->messages == NULL)
1195 return 0; /* nothing to do */
1196 try_alternative_plugins (neighbor);
1197 min_latency = GNUNET_TIME_UNIT_FOREVER_REL;
1198 rl = NULL;
1199 mq = neighbor->messages;
1200 now = GNUNET_TIME_absolute_get ();
1201
1202 if (mq->specific_peer == NULL)
1203 mq->specific_peer = find_ready_address(neighbor); /* Find first available (or best!) address to transmit to */
1204
1205 if (mq->specific_peer == NULL)
1089 { 1206 {
1090 rl->connect_attempts++;
1091 rl->connected = GNUNET_YES;
1092#if DEBUG_TRANSPORT 1207#if DEBUG_TRANSPORT
1093 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1208 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1094 "Establishing fresh connection with `%4s' via plugin `%s'\n", 1209 "No plugin ready to transmit message\n");
1095 GNUNET_i2s (&neighbor->id), rl->plugin->short_name);
1096#endif 1210#endif
1211 return 0; /* nobody ready */
1097 } 1212 }
1213
1214 rl = mq->specific_peer->ready_list;
1098 neighbor->messages = mq->next; 1215 neighbor->messages = mq->next;
1099 mq->plugin = rl->plugin; 1216 mq->plugin = rl->plugin;
1100 if (!mq->internal_msg) 1217 if (!mq->internal_msg)
1101 rl->transmit_ready = GNUNET_NO; 1218 mq->specific_peer->transmit_ready = GNUNET_NO;
1102#if DEBUG_TRANSPORT 1219#if DEBUG_TRANSPORT
1103 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1220 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1104 "Giving message of type `%u' for `%4s' to plugin `%s'\n", 1221 "Giving message of size `%u' for `%4s' to plugin `%s'\n",
1105 ntohs (mq->message->type), 1222 mq->message_buf_size,
1106 GNUNET_i2s (&neighbor->id), rl->plugin->short_name); 1223 GNUNET_i2s (&neighbor->id), rl->plugin->short_name);
1107#endif 1224#endif
1108 1225
1109 if (rl->neighbor->addr != NULL) 1226 return rl->plugin->api->send (rl->plugin->api->cls,
1110 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("try_transmission_to_peer pre-send: at this point rl->neighbor->addr is NOT NULL, addrlen is %d\n"), rl->neighbor->addr_len);
1111 else
1112 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("try_transmission_to_peer pre-send: at this point rl->neighbor->addr is NULL\n"));
1113 /* FIXME: Change MessageQueue to hold message buffer and size? */
1114 rl->plugin->api->send (rl->plugin->api->cls,
1115 &neighbor->id, 1227 &neighbor->id,
1116 (char *)mq->message, 1228 mq->message_buf,
1117 ntohs(mq->message->size), 1229 mq->message_buf_size,
1118 mq->priority, 1230 mq->priority,
1119 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 1231 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1120 rl->neighbor->addr, 1232 mq->specific_peer->addr,
1121 rl->neighbor->addr_len, 1233 mq->specific_peer->addrlen,
1122 GNUNET_NO, 1234 GNUNET_NO,
1123 &transmit_send_continuation, mq); 1235 &transmit_send_continuation, mq);
1236
1124} 1237}
1125 1238
1126 1239
@@ -1128,28 +1241,25 @@ try_transmission_to_peer (struct NeighborList *neighbor)
1128 * Send the specified message to the specified peer. 1241 * Send the specified message to the specified peer.
1129 * 1242 *
1130 * @param client source of the transmission request (can be NULL) 1243 * @param client source of the transmission request (can be NULL)
1244 * @param peer_address PeerAddressList where we should send this message
1131 * @param priority how important is the message 1245 * @param priority how important is the message
1132 * @param msg message to send 1246 * @param message_buf message(s) to send GNUNET_MessageHeader(s)
1247 * @param message_buf_size total size of all messages in message_buf
1133 * @param is_internal is this an internal message 1248 * @param is_internal is this an internal message
1134 * @param neighbor handle to the neighbor for transmission 1249 * @param neighbor handle to the neighbor for transmission
1135 */ 1250 */
1136static void 1251static ssize_t
1137transmit_to_peer (struct TransportClient *client, 1252transmit_to_peer (struct TransportClient *client,
1253 struct PeerAddressList *peer_address,
1138 unsigned int priority, 1254 unsigned int priority,
1139 const struct GNUNET_MessageHeader *msg, 1255 const char *message_buf,
1256 size_t message_buf_size,
1140 int is_internal, struct NeighborList *neighbor) 1257 int is_internal, struct NeighborList *neighbor)
1141{ 1258{
1142 struct MessageQueue *mq; 1259 struct MessageQueue *mq;
1143 struct MessageQueue *mqe; 1260 struct MessageQueue *mqe;
1144 struct GNUNET_MessageHeader *m; 1261 char *m;
1145 1262
1146#if DEBUG_TRANSPORT
1147 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1148 _("Sending message of type %u to peer `%4s'\n"),
1149 ntohs (msg->type), GNUNET_i2s (&neighbor->id));
1150 if (neighbor->addr != NULL)
1151 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("transmit_to_peer: at this point neighbor->addr is NOT NULL\n"));
1152#endif
1153 if (client != NULL) 1263 if (client != NULL)
1154 { 1264 {
1155 /* check for duplicate submission */ 1265 /* check for duplicate submission */
@@ -1161,16 +1271,18 @@ transmit_to_peer (struct TransportClient *client,
1161 /* client transmitted to same peer twice 1271 /* client transmitted to same peer twice
1162 before getting SendOk! */ 1272 before getting SendOk! */
1163 GNUNET_break (0); 1273 GNUNET_break (0);
1164 return; 1274 return 0;
1165 } 1275 }
1166 mq = mq->next; 1276 mq = mq->next;
1167 } 1277 }
1168 } 1278 }
1169 mq = GNUNET_malloc (sizeof (struct MessageQueue)); 1279 mq = GNUNET_malloc (sizeof (struct MessageQueue));
1280 mq->specific_peer = peer_address;
1170 mq->client = client; 1281 mq->client = client;
1171 m = GNUNET_malloc (ntohs (msg->size)); 1282 m = GNUNET_malloc (message_buf_size);
1172 memcpy (m, msg, ntohs (msg->size)); 1283 memcpy (m, message_buf, message_buf_size);
1173 mq->message = m; 1284 mq->message_buf = m;
1285 mq->message_buf_size = message_buf_size;
1174 mq->neighbor = neighbor; 1286 mq->neighbor = neighbor;
1175 mq->internal_msg = is_internal; 1287 mq->internal_msg = is_internal;
1176 mq->priority = priority; 1288 mq->priority = priority;
@@ -1190,7 +1302,7 @@ transmit_to_peer (struct TransportClient *client,
1190 /* append */ 1302 /* append */
1191 mqe->next = mq; 1303 mqe->next = mq;
1192 } 1304 }
1193 try_transmission_to_peer (neighbor); 1305 return try_transmission_to_peer (neighbor);
1194} 1306}
1195 1307
1196 1308
@@ -1221,16 +1333,9 @@ address_generator (void *cls, size_t max, void *buf)
1221 } 1333 }
1222 if (NULL == gc->plug_pos) 1334 if (NULL == gc->plug_pos)
1223 { 1335 {
1224#if DEBUG_TRANSPORT 1336
1225 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1226 "In address_generator, gc->plug_pos is NULL!\n");
1227#endif
1228 return 0; 1337 return 0;
1229 } 1338 }
1230#if DEBUG_TRANSPORT
1231 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1232 "Should be adding an address...\n");
1233#endif
1234 ret = GNUNET_HELLO_add_address (gc->plug_pos->short_name, 1339 ret = GNUNET_HELLO_add_address (gc->plug_pos->short_name,
1235 gc->expiration, 1340 gc->expiration,
1236 gc->addr_pos->addr, 1341 gc->addr_pos->addr,
@@ -1252,10 +1357,6 @@ refresh_hello ()
1252 struct NeighborList *npos; 1357 struct NeighborList *npos;
1253 struct GeneratorContext gc; 1358 struct GeneratorContext gc;
1254 1359
1255#if DEBUG_TRANSPORT
1256 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
1257 "Refreshing my `%s'\n", "HELLO");
1258#endif
1259 gc.plug_pos = plugins; 1360 gc.plug_pos = plugins;
1260 gc.addr_pos = plugins != NULL ? plugins->addresses : NULL; 1361 gc.addr_pos = plugins != NULL ? plugins->addresses : NULL;
1261 gc.expiration = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION); 1362 gc.expiration = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION);
@@ -1284,10 +1385,10 @@ refresh_hello ()
1284 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 1385 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
1285 "Transmitting updated `%s' to neighbor `%4s'\n", 1386 "Transmitting updated `%s' to neighbor `%4s'\n",
1286 "HELLO", GNUNET_i2s (&npos->id)); 1387 "HELLO", GNUNET_i2s (&npos->id));
1287#endif 1388#endif // FIXME: just testing
1288 transmit_to_peer (NULL, 0, 1389 //transmit_to_peer (NULL, NULL, 0,
1289 (const struct GNUNET_MessageHeader *) our_hello, 1390 // (const char *) our_hello, GNUNET_HELLO_size(our_hello),
1290 GNUNET_YES, npos); 1391 // GNUNET_YES, npos);
1291 npos = npos->next; 1392 npos = npos->next;
1292 } 1393 }
1293} 1394}
@@ -1417,11 +1518,7 @@ plugin_env_notify_address (void *cls,
1417 } 1518 }
1418 al = al->next; 1519 al = al->next;
1419 } 1520 }
1420#if DEBUG_TRANSPORT 1521
1421 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1422 "Plugin `%s' informs us about a new address `%s'\n", name,
1423 GNUNET_a2s (addr, addrlen));
1424#endif
1425 al = GNUNET_malloc (sizeof (struct AddressList) + addrlen); 1522 al = GNUNET_malloc (sizeof (struct AddressList) + addrlen);
1426 al->addr = &al[1]; 1523 al->addr = &al[1];
1427 al->next = p->addresses; 1524 al->next = p->addresses;
@@ -1443,11 +1540,6 @@ notify_clients_connect (const struct GNUNET_PeerIdentity *peer,
1443 struct ConnectInfoMessage cim; 1540 struct ConnectInfoMessage cim;
1444 struct TransportClient *cpos; 1541 struct TransportClient *cpos;
1445 1542
1446#if DEBUG_TRANSPORT
1447 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1448 "Informing clients about peer `%4s' connecting to us\n",
1449 GNUNET_i2s (peer));
1450#endif
1451 cim.header.size = htons (sizeof (struct ConnectInfoMessage)); 1543 cim.header.size = htons (sizeof (struct ConnectInfoMessage));
1452 cim.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT); 1544 cim.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
1453 cim.quota_out = htonl (GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT / (60 * 1000)); 1545 cim.quota_out = htonl (GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT / (60 * 1000));
@@ -1471,11 +1563,6 @@ notify_clients_disconnect (const struct GNUNET_PeerIdentity *peer)
1471 struct DisconnectInfoMessage dim; 1563 struct DisconnectInfoMessage dim;
1472 struct TransportClient *cpos; 1564 struct TransportClient *cpos;
1473 1565
1474#if DEBUG_TRANSPORT
1475 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1476 "Informing clients about peer `%4s' disconnecting\n",
1477 GNUNET_i2s (peer));
1478#endif
1479 dim.header.size = htons (sizeof (struct DisconnectInfoMessage)); 1566 dim.header.size = htons (sizeof (struct DisconnectInfoMessage));
1480 dim.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT); 1567 dim.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT);
1481 dim.reserved = htonl (0); 1568 dim.reserved = htonl (0);
@@ -1507,7 +1594,7 @@ list_validated_addresses (void *cls, size_t max, void *buf)
1507 return 0; 1594 return 0;
1508 ret = GNUNET_HELLO_add_address ((*va)->transport_name, 1595 ret = GNUNET_HELLO_add_address ((*va)->transport_name,
1509 (*va)->expiration, 1596 (*va)->expiration,
1510 &(*va)[1], (*va)->addr_len, buf, max); 1597 (*va)->peer_address->addr, (*va)->peer_address->addrlen, buf, max);
1511 *va = (*va)->next; 1598 *va = (*va)->next;
1512 return ret; 1599 return ret;
1513} 1600}
@@ -1528,10 +1615,6 @@ cleanup_validation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1528 struct GNUNET_PeerIdentity pid; 1615 struct GNUNET_PeerIdentity pid;
1529 struct NeighborList *n; 1616 struct NeighborList *n;
1530 1617
1531#if DEBUG_TRANSPORT
1532 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
1533 "HELLO validation cleanup background task running...\n");
1534#endif
1535 now = GNUNET_TIME_absolute_get (); 1618 now = GNUNET_TIME_absolute_get ();
1536 prev = NULL; 1619 prev = NULL;
1537 pos = pending_validations; 1620 pos = pending_validations;
@@ -1556,7 +1639,7 @@ cleanup_validation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1556 "HELLO", GNUNET_i2s (&pid)); 1639 "HELLO", GNUNET_i2s (&pid));
1557#endif 1640#endif
1558 GNUNET_PEERINFO_add_peer (cfg, sched, &pid, hello); 1641 GNUNET_PEERINFO_add_peer (cfg, sched, &pid, hello);
1559 n = find_neighbor (&pid, NULL, 0); 1642 n = find_neighbor (&pid);
1560 if (NULL != n) 1643 if (NULL != n)
1561 { 1644 {
1562 try_transmission_to_peer (n); 1645 try_transmission_to_peer (n);
@@ -1663,13 +1746,18 @@ handle_pong (void *cls, const struct GNUNET_MessageHeader *message,
1663#endif 1746#endif
1664 GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK, 1747 GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK,
1665 _ 1748 _
1666 ("Another peer saw us using the address `%s' via `FIXME'. If this is not plausible, this address should be listed in the configuration as implausible to avoid MiM attacks.\n"), 1749 ("Another peer saw us using the address `%s' via `%s'. If this is not plausible, this address should be listed in the configuration as implausible to avoid MiM attacks.\n"),
1667 GNUNET_a2s ((const struct sockaddr *) &va[1], 1750 GNUNET_a2s ((const struct sockaddr *) &pong[1],
1668 va->addr_len)); 1751 ntohs(pong->addrlen)), va->transport_name);
1669 va->ok = GNUNET_YES; 1752 va->ok = GNUNET_YES;
1670 va->expiration = 1753 va->expiration =
1671 GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION); 1754 GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION);
1672 matched = GNUNET_YES; 1755 matched = GNUNET_YES;
1756 va->peer_address->connected = GNUNET_YES;
1757 va->peer_address->latency = GNUNET_TIME_absolute_get_difference(GNUNET_TIME_absolute_get(), va->send_time);
1758 va->peer_address->transmit_ready = GNUNET_YES;
1759 va->peer_address->expires = GNUNET_TIME_relative_to_absolute
1760 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1673 } 1761 }
1674 if (va->ok != GNUNET_YES) 1762 if (va->ok != GNUNET_YES)
1675 not_done++; 1763 not_done++;
@@ -1695,42 +1783,143 @@ handle_pong (void *cls, const struct GNUNET_MessageHeader *message,
1695 GNUNET_SCHEDULER_PRIORITY_IDLE, 1783 GNUNET_SCHEDULER_PRIORITY_IDLE,
1696 &cleanup_validation, NULL); 1784 &cleanup_validation, NULL);
1697 } 1785 }
1698 else 1786
1787}
1788
1789/**
1790 * Add an entry for each of our transport plugins
1791 * (that are able to send) to the list of plugins
1792 * for this neighbor.
1793 *
1794 * @param neighbor to initialize
1795 */
1796static void
1797add_plugins (struct NeighborList *neighbor)
1798{
1799 struct TransportPlugin *tp;
1800 struct ReadyList *rl;
1801
1802 neighbor->retry_plugins_time
1803 = GNUNET_TIME_relative_to_absolute (PLUGIN_RETRY_FREQUENCY);
1804 tp = plugins;
1805 while (tp != NULL)
1699 { 1806 {
1700#if DEBUG_TRANSPORT 1807 if (tp->api->send != NULL)
1701 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1808 {
1702 "Still waiting for %u additional `%s' messages before constructing `%s' for `%4s'.\n", 1809 rl = GNUNET_malloc (sizeof (struct ReadyList));
1703 not_done, "PONG", "HELLO", GNUNET_i2s (peer)); 1810 rl->next = neighbor->plugins;
1704#endif 1811 neighbor->plugins = rl;
1812 rl->plugin = tp;
1813 rl->neighbor = neighbor;
1814 rl->addresses = NULL;
1815 }
1816 tp = tp->next;
1705 } 1817 }
1706} 1818}
1707 1819
1708 1820static void
1709struct CheckHelloValidatedContext 1821neighbor_timeout_task (void *cls,
1822 const struct GNUNET_SCHEDULER_TaskContext *tc)
1710{ 1823{
1711 /** 1824 struct NeighborList *n = cls;
1712 * Plugin for which we are validating.
1713 */
1714 struct TransportPlugin *plugin;
1715 1825
1716 /** 1826#if DEBUG_TRANSPORT
1717 * Hello that we are validating. 1827 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
1718 */ 1828 "Neighbor `%4s' has timed out!\n", GNUNET_i2s (&n->id));
1719 struct GNUNET_HELLO_Message *hello; 1829#endif
1830 n->timeout_task = GNUNET_SCHEDULER_NO_TASK;
1831 disconnect_neighbor (n, GNUNET_NO);
1832}
1720 1833
1721 /** 1834/**
1722 * Validation list being build. 1835 * Create a fresh entry in our neighbor list for the given peer.
1723 */ 1836 * Will try to transmit our current HELLO to the new neighbor. Also
1724 struct ValidationList *e; 1837 * notifies our clients about the new "connection".
1838 *
1839 * @param peer the peer for which we create the entry
1840 * @return the new neighbor list entry
1841 */
1842static struct NeighborList *
1843setup_new_neighbor (const struct GNUNET_PeerIdentity *peer)
1844{
1845 struct NeighborList *n;
1725 1846
1726 /** 1847 GNUNET_assert (our_hello != NULL);
1727 * Context for peerinfo iteration. 1848 n = GNUNET_malloc (sizeof (struct NeighborList));
1728 * NULL after we are done processing peerinfo's information. 1849 n->next = neighbors;
1729 */ 1850 neighbors = n;
1730 struct GNUNET_PEERINFO_IteratorContext *piter; 1851 n->id = *peer;
1852 n->last_quota_update = GNUNET_TIME_absolute_get ();
1853 n->peer_timeout =
1854 GNUNET_TIME_relative_to_absolute
1855 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1856 n->quota_in = (GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT + 59999) / (60 * 1000);
1857 add_plugins (n);
1858 n->timeout_task = GNUNET_SCHEDULER_add_delayed (sched,
1859 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1860 &neighbor_timeout_task, n);
1861 transmit_to_peer (NULL, NULL, 0,
1862 (const char *) our_hello, GNUNET_HELLO_size(our_hello),
1863 GNUNET_YES, n);
1864 notify_clients_connect (peer, GNUNET_TIME_UNIT_FOREVER_REL);
1865 return n;
1866}
1731 1867
1732}; 1868static struct PeerAddressList *
1869add_peer_address(struct NeighborList *neighbor, const char *addr, size_t addrlen)
1870{
1871 /* FIXME: should return a list of PeerAddressLists, support for multiple transports! */
1872 struct ReadyList *head = neighbor->plugins;
1873 struct PeerAddressList * new_address;
1874
1875 GNUNET_assert(addr != NULL);
1876
1877 while (head != NULL)
1878 {
1879 new_address = GNUNET_malloc(sizeof(struct PeerAddressList));
1880 new_address->addr = GNUNET_malloc(addrlen);
1881 memcpy(new_address->addr, addr, addrlen);
1882 new_address->addrlen = addrlen;
1883 new_address->connect_attempts = 0;
1884 new_address->connected = GNUNET_YES; /* Set connected to GNUNET_YES, assuming that we're good */
1885 new_address->expires = GNUNET_TIME_relative_to_absolute
1886 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1887 new_address->latency = GNUNET_TIME_relative_get_forever();
1888 new_address->neighbor = neighbor;
1889 new_address->plugin = head->plugin;
1890 new_address->transmit_ready = GNUNET_YES;
1891 new_address->timeout = GNUNET_TIME_relative_to_absolute
1892 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); /* FIXME: Do we need this? */
1893 new_address->ready_list = head;
1894 new_address->next = head->addresses;
1895 head->addresses = new_address;
1896 head = head->next;
1897 }
1898
1899 return new_address;
1900}
1733 1901
1902static struct PeerAddressList *
1903find_peer_address(struct NeighborList *neighbor, const char *addr, size_t addrlen)
1904{
1905 struct ReadyList *head = neighbor->plugins;
1906 struct PeerAddressList *address_head;
1907 while (head != NULL)
1908 {
1909 address_head = head->addresses;
1910 while ((address_head != NULL) &&
1911 (address_head->addrlen != addrlen) &&
1912 (memcmp(address_head->addr, addr, addrlen) != 0))
1913 {
1914 address_head = address_head->next;
1915 }
1916 if (address_head != NULL)
1917 return address_head;
1918
1919 head = head->next;
1920 }
1921 return NULL;
1922}
1734 1923
1735/** 1924/**
1736 * Append the given address to the list of entries 1925 * Append the given address to the list of entries
@@ -1746,6 +1935,8 @@ run_validation (void *cls,
1746 struct TransportPlugin *tp; 1935 struct TransportPlugin *tp;
1747 struct ValidationAddress *va; 1936 struct ValidationAddress *va;
1748 struct GNUNET_PeerIdentity id; 1937 struct GNUNET_PeerIdentity id;
1938 struct NeighborList *neighbor;
1939 struct PeerAddressList *peer_address;
1749 int sent; 1940 int sent;
1750 struct TransportPingMessage *ping; 1941 struct TransportPingMessage *ping;
1751 char * message_buf; 1942 char * message_buf;
@@ -1766,18 +1957,34 @@ run_validation (void *cls,
1766 sizeof (struct 1957 sizeof (struct
1767 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), 1958 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
1768 &id.hashPubKey); 1959 &id.hashPubKey);
1960#if DEBUG_TRANSPORT
1769 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1961 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1770 "Scheduling validation of address `%s' via `%s' for `%4s'\n", 1962 "Scheduling validation of address `%s' via `%s' for `%4s'\n",
1771 GNUNET_a2s (addr, addrlen), tname, GNUNET_i2s (&id)); 1963 GNUNET_a2s (addr, addrlen), tname, GNUNET_i2s (&id));
1772 1964#endif
1773 va = GNUNET_malloc (sizeof (struct ValidationAddress) + addrlen); 1965 va = GNUNET_malloc (sizeof (struct ValidationAddress));
1774 va->next = e->addresses; 1966 va->next = e->addresses;
1775 e->addresses = va; 1967 e->addresses = va;
1776 va->transport_name = GNUNET_strdup (tname); 1968 va->transport_name = GNUNET_strdup (tname);
1777 va->addr_len = addrlen;
1778 va->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1969 va->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
1779 (unsigned int) -1); 1970 (unsigned int) -1);
1780 memcpy (&va[1], addr, addrlen); 1971 va->send_time = GNUNET_TIME_absolute_get();
1972
1973 neighbor = find_neighbor(&id);
1974
1975 if (neighbor == NULL)
1976 neighbor = setup_new_neighbor(&id);
1977
1978 peer_address = find_peer_address(neighbor, addr, addrlen);
1979 if (peer_address == NULL)
1980 {
1981 peer_address = add_peer_address(neighbor, addr, addrlen);
1982 }
1983
1984 GNUNET_assert(peer_address != NULL);
1985
1986 va->peer_address = peer_address; /* Back pointer FIXME: remove this nonsense! */
1987 peer_address->validation = va;
1781 1988
1782 hello_size = GNUNET_HELLO_size(our_hello); 1989 hello_size = GNUNET_HELLO_size(our_hello);
1783 tsize = sizeof(struct TransportPingMessage) + hello_size; 1990 tsize = sizeof(struct TransportPingMessage) + hello_size;
@@ -1790,27 +1997,29 @@ run_validation (void *cls,
1790 ping->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_PING); 1997 ping->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_PING);
1791 memcpy(&ping->target, &id, sizeof(struct GNUNET_PeerIdentity)); 1998 memcpy(&ping->target, &id, sizeof(struct GNUNET_PeerIdentity));
1792 1999
2000#if DEBUG_TRANSPORT
1793 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "hello size is %d, ping size is %d, total size is %d", hello_size, sizeof(struct TransportPingMessage), tsize); 2001 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "hello size is %d, ping size is %d, total size is %d", hello_size, sizeof(struct TransportPingMessage), tsize);
1794 2002#endif
1795 memcpy(message_buf, our_hello, hello_size); 2003 memcpy(message_buf, our_hello, hello_size);
1796 memcpy(&message_buf[hello_size], ping, sizeof(struct TransportPingMessage)); 2004 memcpy(&message_buf[hello_size], ping, sizeof(struct TransportPingMessage));
1797 2005
2006#if DEBUG_TRANSPORT
2007 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ping message of size %d to address `%s' via `%s' for `%4s'\n",
2008 tsize, GNUNET_a2s (addr, addrlen), tname, GNUNET_i2s (&id));
2009#endif
2010 sent = transmit_to_peer(NULL, peer_address, GNUNET_SCHEDULER_PRIORITY_DEFAULT,
2011 message_buf, tsize, GNUNET_NO, neighbor);
1798 2012
1799 2013#if DEBUG_TRANSPORT
1800 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ping message to address `%s' via `%s' for `%4s'\n",
1801 GNUNET_a2s (addr, addrlen), tname, GNUNET_i2s (&id));
1802
1803
1804 sent = tp->api->send(tp->api->cls, &id, message_buf, tsize, GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1805 TRANSPORT_DEFAULT_TIMEOUT, addr, addrlen, GNUNET_YES, NULL, NULL);
1806
1807 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transport returned %d from send!\n", sent); 2014 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transport returned %d from send!\n", sent);
2015#endif
1808 2016
1809 GNUNET_free(ping); 2017 GNUNET_free(ping);
1810 GNUNET_free(message_buf); 2018 GNUNET_free(message_buf);
1811 return GNUNET_OK; 2019 return GNUNET_OK;
1812} 2020}
1813 2021
2022#if WHY
1814/* 2023/*
1815 * @param cls handle to the plugin (for sending) 2024 * @param cls handle to the plugin (for sending)
1816 * @param target the peer identity of the peer we are sending to 2025 * @param target the peer identity of the peer we are sending to
@@ -1838,7 +2047,7 @@ validate_address (void *cls, struct ValidationAddress *va,
1838 2047
1839 return; 2048 return;
1840} 2049}
1841 2050#endif
1842 2051
1843/** 2052/**
1844 * Check if addresses in validated hello "h" overlap with 2053 * Check if addresses in validated hello "h" overlap with
@@ -1872,9 +2081,9 @@ check_hello_validated (void *cls,
1872 pending_validations = chvc->e; 2081 pending_validations = chvc->e;
1873 } 2082 }
1874 /* no existing HELLO, all addresses are new */ 2083 /* no existing HELLO, all addresses are new */
1875 GNUNET_HELLO_iterate_addresses (chvc->hello, 2084/* GNUNET_HELLO_iterate_addresses (chvc->hello,
1876 GNUNET_NO, &run_validation, chvc->e); 2085 GNUNET_NO, &run_validation, chvc->e);*/
1877#if 0 2086
1878 if (h != NULL) 2087 if (h != NULL)
1879 { 2088 {
1880 GNUNET_HELLO_iterate_new_addresses (chvc->hello, 2089 GNUNET_HELLO_iterate_new_addresses (chvc->hello,
@@ -1888,16 +2097,12 @@ check_hello_validated (void *cls,
1888 GNUNET_HELLO_iterate_addresses (chvc->hello, 2097 GNUNET_HELLO_iterate_addresses (chvc->hello,
1889 GNUNET_NO, &run_validation, chvc->e); 2098 GNUNET_NO, &run_validation, chvc->e);
1890 } 2099 }
1891#endif 2100
1892 if (h != NULL) 2101 if (h != NULL)
1893 return; /* wait for next call */ 2102 return; /* wait for next call */
1894 /* finally, transmit validation attempts */ 2103 /* finally, transmit validation attempts */
1895 GNUNET_assert (GNUNET_OK == GNUNET_HELLO_get_id (chvc->hello, &apeer)); 2104 GNUNET_assert (GNUNET_OK == GNUNET_HELLO_get_id (chvc->hello, &apeer));
1896#if DEBUG_TRANSPORT 2105
1897 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1898 "Ready to validate addresses from `%s' message for peer `%4s'\n",
1899 "HELLO", GNUNET_i2s (&apeer));
1900#endif
1901 va = chvc->e->addresses; 2106 va = chvc->e->addresses;
1902 count = 0; 2107 count = 0;
1903 while (va != NULL) 2108 while (va != NULL)
@@ -1907,24 +2112,17 @@ check_hello_validated (void *cls,
1907 "Establishing `%s' connection to validate `%s' address `%s' of `%4s'\n", 2112 "Establishing `%s' connection to validate `%s' address `%s' of `%4s'\n",
1908 va->transport_name, 2113 va->transport_name,
1909 "HELLO", 2114 "HELLO",
1910 GNUNET_a2s ((const struct sockaddr *) &va[1], 2115 GNUNET_a2s ((const struct sockaddr *) va->peer_address->addr,
1911 va->addr_len), GNUNET_i2s (&apeer)); 2116 va->peer_address->addrlen), GNUNET_i2s (&apeer));
1912#endif 2117#endif
1913 tp = find_transport (va->transport_name); 2118 tp = find_transport (va->transport_name);
1914 GNUNET_assert (tp != NULL); 2119 GNUNET_assert (tp != NULL);
1915 /* This validation should happen inside the transport, not from the plugin! */ 2120 /* This validation should happen inside the transport, not from the plugin! */
1916 validate_address (tp->api->cls, va, &apeer, 2121 va->ok = GNUNET_SYSERR;
1917 HELLO_VERIFICATION_TIMEOUT,
1918 &va[1], va->addr_len);
1919 /* va->ok = GNUNET_SYSERR; will be set by validate_address! */
1920 va = va->next; 2122 va = va->next;
1921 count++; 2123 count++;
1922 } 2124 }
1923 2125
1924#if DEBUG_TRANSPORT
1925 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1926 "Found %d addresses in hello of size %d\n", count, GNUNET_HELLO_size(chvc->hello));
1927#endif
1928 GNUNET_SCHEDULER_add_delayed (sched, 2126 GNUNET_SCHEDULER_add_delayed (sched,
1929 GNUNET_TIME_absolute_get_remaining (chvc-> 2127 GNUNET_TIME_absolute_get_remaining (chvc->
1930 e->timeout), 2128 e->timeout),
@@ -2000,6 +2198,7 @@ process_hello (struct TransportPlugin *plugin,
2000 chvc = GNUNET_malloc (sizeof (struct CheckHelloValidatedContext) + hsize); 2198 chvc = GNUNET_malloc (sizeof (struct CheckHelloValidatedContext) + hsize);
2001 chvc->plugin = plugin; 2199 chvc->plugin = plugin;
2002 chvc->hello = (struct GNUNET_HELLO_Message *) &chvc[1]; 2200 chvc->hello = (struct GNUNET_HELLO_Message *) &chvc[1];
2201 chvc->e = NULL;
2003 memcpy (chvc->hello, hello, hsize); 2202 memcpy (chvc->hello, hello, hsize);
2004 /* finally, check if HELLO was previously validated 2203 /* finally, check if HELLO was previously validated
2005 (continuation will then schedule actual validation) */ 2204 (continuation will then schedule actual validation) */
@@ -2090,92 +2289,6 @@ disconnect_neighbor (struct NeighborList *n, int check)
2090} 2289}
2091 2290
2092 2291
2093/**
2094 * Add an entry for each of our transport plugins
2095 * (that are able to send) to the list of plugins
2096 * for this neighbor.
2097 *
2098 * @param neighbor to initialize
2099 */
2100static void
2101add_plugins (struct NeighborList *neighbor)
2102{
2103 struct TransportPlugin *tp;
2104 struct ReadyList *rl;
2105
2106 neighbor->retry_plugins_time
2107 = GNUNET_TIME_relative_to_absolute (PLUGIN_RETRY_FREQUENCY);
2108 tp = plugins;
2109 while (tp != NULL)
2110 {
2111 if (tp->api->send != NULL)
2112 {
2113 rl = GNUNET_malloc (sizeof (struct ReadyList));
2114 rl->next = neighbor->plugins;
2115 neighbor->plugins = rl;
2116 rl->plugin = tp;
2117 rl->neighbor = neighbor;
2118 rl->transmit_ready = GNUNET_YES;
2119 }
2120 tp = tp->next;
2121 }
2122}
2123
2124
2125static void
2126neighbor_timeout_task (void *cls,
2127 const struct GNUNET_SCHEDULER_TaskContext *tc)
2128{
2129 struct NeighborList *n = cls;
2130
2131#if DEBUG_TRANSPORT
2132 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
2133 "Neighbor `%4s' has timed out!\n", GNUNET_i2s (&n->id));
2134#endif
2135 n->timeout_task = GNUNET_SCHEDULER_NO_TASK;
2136 disconnect_neighbor (n, GNUNET_NO);
2137}
2138
2139
2140/**
2141 * Create a fresh entry in our neighbor list for the given peer.
2142 * Will try to transmit our current HELLO to the new neighbor. Also
2143 * notifies our clients about the new "connection".
2144 *
2145 * @param peer the peer for which we create the entry
2146 * @return the new neighbor list entry
2147 */
2148static struct NeighborList *
2149setup_new_neighbor (const struct GNUNET_PeerIdentity *peer, const char *addr, size_t sender_address_len)
2150{
2151 struct NeighborList *n;
2152
2153#if DEBUG_TRANSPORT
2154 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
2155 "Setting up new neighbor `%4s', sending our HELLO to introduce ourselves\n",
2156 GNUNET_i2s (peer));
2157#endif
2158 GNUNET_assert (our_hello != NULL);
2159 n = GNUNET_malloc (sizeof (struct NeighborList));
2160 n->next = neighbors;
2161 neighbors = n;
2162 n->id = *peer;
2163 n->last_quota_update = GNUNET_TIME_absolute_get ();
2164 n->peer_timeout =
2165 GNUNET_TIME_relative_to_absolute
2166 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
2167 n->quota_in = (GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT + 59999) / (60 * 1000);
2168 add_plugins (n);
2169 n->timeout_task = GNUNET_SCHEDULER_add_delayed (sched,
2170 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
2171 &neighbor_timeout_task, n);
2172 transmit_to_peer (NULL, 0,
2173 (const struct GNUNET_MessageHeader *) our_hello,
2174 GNUNET_YES, n);
2175 notify_clients_connect (peer, GNUNET_TIME_UNIT_FOREVER_REL);
2176 return n;
2177}
2178
2179/* 2292/*
2180 * We have received a PING message from someone. Need to send a PONG message 2293 * We have received a PING message from someone. Need to send a PONG message
2181 * in response to the peer by any means necessary. Of course, with something 2294 * in response to the peer by any means necessary. Of course, with something
@@ -2190,6 +2303,7 @@ static int handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
2190 struct TransportPlugin *plugin = cls; 2303 struct TransportPlugin *plugin = cls;
2191 struct TransportPingMessage *ping; 2304 struct TransportPingMessage *ping;
2192 struct TransportPongMessage *pong; 2305 struct TransportPongMessage *pong;
2306 struct PeerAddressList *peer_address;
2193 uint16_t msize; 2307 uint16_t msize;
2194 struct NeighborList *n; 2308 struct NeighborList *n;
2195 pong = GNUNET_malloc(sizeof(struct TransportPongMessage)); 2309 pong = GNUNET_malloc(sizeof(struct TransportPongMessage));
@@ -2217,21 +2331,7 @@ static int handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
2217 } 2331 }
2218 2332
2219 msize -= sizeof (struct TransportPingMessage); 2333 msize -= sizeof (struct TransportPingMessage);
2220/*
2221 * if (GNUNET_OK != tcp_plugin_address_suggested (plugin, &vcm[1], msize))
2222 {
2223 GNUNET_break_op (0);
2224 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2225 return;
2226 }
2227 2334
2228 if (GNUNET_OK != GNUNET_SERVER_client_get_address (client, &addr, &addrlen))
2229 {
2230 GNUNET_break (0);
2231 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2232 return;
2233 }
2234*/
2235 pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + sender_address_len); 2335 pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + sender_address_len);
2236 pong->header.size = htons (sizeof (struct TransportPongMessage) + sender_address_len); 2336 pong->header.size = htons (sizeof (struct TransportPongMessage) + sender_address_len);
2237 pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG); 2337 pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG);
@@ -2241,42 +2341,23 @@ static int handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
2241 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + sender_address_len); 2341 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + sender_address_len);
2242 pong->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_TCP_PING); 2342 pong->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_TCP_PING);
2243 pong->challenge = ping->challenge; 2343 pong->challenge = ping->challenge;
2344 pong->addrlen = htons(sender_address_len);
2244 2345
2245 memcpy(&pong->signer, &my_public_key, sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); 2346 memcpy(&pong->signer, &my_public_key, sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
2246 memcpy (&pong[1], sender_address, sender_address_len); 2347 memcpy (&pong[1], sender_address, sender_address_len);
2247 GNUNET_assert (GNUNET_OK == 2348 GNUNET_assert (GNUNET_OK ==
2248 GNUNET_CRYPTO_rsa_sign (my_private_key, 2349 GNUNET_CRYPTO_rsa_sign (my_private_key,
2249 &pong->purpose, &pong->signature)); 2350 &pong->purpose, &pong->signature));
2250 /* Will this nonsense work, even for UDP? 2351
2251 * The idea is that we need an address to send to for UDP, but we may not know 2352 n = find_neighbor(peer);
2252 * this peer yet. So in that case, we need to create a new neighbor with the
2253 * current address, but is this address going to be correct, or will it have a
2254 * random high port or something? Another question is, why didn't we get a WELCOME
2255 * from this peer with its advertised addresses already? We don't want to
2256 * differentiate based on transport... */
2257 n = find_neighbor(peer, NULL, 0);
2258 if (n == NULL) 2353 if (n == NULL)
2259 { 2354 n = setup_new_neighbor(peer);
2260#if DEBUG_TRANSPORT
2261 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2262 "Didn't find peer in list, adding...\n");
2263#endif
2264 setup_new_neighbor(peer, sender_address, sender_address_len);
2265 n = find_neighbor(peer, sender_address, sender_address_len);
2266 GNUNET_assert(n != NULL);
2267 }
2268 else if (n->addr == NULL)
2269 {
2270#if DEBUG_TRANSPORT
2271 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2272 "Found peer in list, but without address, adding!\n");
2273#endif
2274 n->addr = GNUNET_malloc(sender_address_len);
2275 memcpy(n->addr, sender_address, sender_address_len);
2276 n->addr_len = sender_address_len;
2277 }
2278 2355
2279 transmit_to_peer(NULL, TRANSPORT_DEFAULT_PRIORITY, &pong->header, GNUNET_NO, n); 2356 peer_address = find_peer_address(n, sender_address, sender_address_len);
2357 if (peer_address == NULL)
2358 peer_address = add_peer_address(n, sender_address, sender_address_len);
2359
2360 transmit_to_peer(NULL, NULL, TRANSPORT_DEFAULT_PRIORITY, (char *)pong, ntohs(pong->header.size), GNUNET_NO, n);
2280 2361
2281 GNUNET_free(pong); 2362 GNUNET_free(pong);
2282 return GNUNET_OK; 2363 return GNUNET_OK;
@@ -2306,24 +2387,27 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
2306 unsigned int distance, const char *sender_address, 2387 unsigned int distance, const char *sender_address,
2307 size_t sender_address_len) 2388 size_t sender_address_len)
2308{ 2389{
2309 const struct GNUNET_MessageHeader ack = {
2310 htons (sizeof (struct GNUNET_MessageHeader)),
2311 htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ACK)
2312 };
2313 struct ReadyList *service_context; 2390 struct ReadyList *service_context;
2314 struct TransportPlugin *plugin = cls; 2391 struct TransportPlugin *plugin = cls;
2315 struct TransportClient *cpos; 2392 struct TransportClient *cpos;
2316 struct InboundMessage *im; 2393 struct InboundMessage *im;
2394 struct PeerAddressList *peer_address;
2317 uint16_t msize; 2395 uint16_t msize;
2318 struct NeighborList *n; 2396 struct NeighborList *n;
2319 2397
2320 n = find_neighbor (peer, sender_address, sender_address_len); 2398 n = find_neighbor (peer);
2321 if (n == NULL) 2399 if (n == NULL)
2322 { 2400 {
2323 if (message == NULL) 2401 if (message == NULL)
2324 return; /* disconnect of peer already marked down */ 2402 return; /* disconnect of peer already marked down */
2325 n = setup_new_neighbor (peer, sender_address, sender_address_len); 2403 n = setup_new_neighbor (peer);
2404
2326 } 2405 }
2406
2407 peer_address = find_peer_address(n, sender_address, sender_address_len);
2408 if (peer_address == NULL)
2409 peer_address = add_peer_address(n, sender_address, sender_address_len);
2410
2327 service_context = n->plugins; 2411 service_context = n->plugins;
2328 while ((service_context != NULL) && (plugin != service_context->plugin)) 2412 while ((service_context != NULL) && (plugin != service_context->plugin))
2329 service_context = service_context->next; 2413 service_context = service_context->next;
@@ -2350,15 +2434,17 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
2350 { 2434 {
2351 if (service_context->connected == GNUNET_NO) 2435 if (service_context->connected == GNUNET_NO)
2352 { 2436 {
2353 service_context->connected = GNUNET_YES; 2437 /*service_context->connected = GNUNET_YES;*/
2354 service_context->transmit_ready = GNUNET_YES; 2438 /* FIXME: What to do here? Should we use these as well, to specify some Address
2355 service_context->connect_attempts++; 2439 * in the AddressList should be available?
2440 */
2441 peer_address->transmit_ready = GNUNET_YES;
2442 peer_address->connect_attempts++;
2356 } 2443 }
2357 service_context->timeout 2444 peer_address->timeout
2358 = 2445 =
2359 GNUNET_TIME_relative_to_absolute 2446 GNUNET_TIME_relative_to_absolute
2360 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); 2447 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
2361 /* service_context->latency = latency; */ /* This value should be set by us! */
2362 } 2448 }
2363 /* update traffic received amount ... */ 2449 /* update traffic received amount ... */
2364 msize = ntohs (message->size); 2450 msize = ntohs (message->size);
@@ -2393,12 +2479,6 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
2393 GNUNET_i2s (peer)); 2479 GNUNET_i2s (peer));
2394#endif 2480#endif
2395 process_hello (plugin, message); 2481 process_hello (plugin, message);
2396#if DEBUG_TRANSPORT
2397 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2398 "Sending `%s' message to connecting peer `%4s'.\n", "ACK",
2399 GNUNET_i2s (peer));
2400#endif
2401 transmit_to_peer (NULL, 0, &ack, GNUNET_YES, n);
2402 break; 2482 break;
2403 case GNUNET_MESSAGE_TYPE_TRANSPORT_PING: 2483 case GNUNET_MESSAGE_TYPE_TRANSPORT_PING:
2404 handle_ping(plugin, message, peer, sender_address, sender_address_len); 2484 handle_ping(plugin, message, peer, sender_address, sender_address_len);
@@ -2406,14 +2486,10 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
2406 case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG: 2486 case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG:
2407 handle_pong(plugin, message, peer, sender_address, sender_address_len); 2487 handle_pong(plugin, message, peer, sender_address, sender_address_len);
2408 break; 2488 break;
2409 //plugin_env_notify_validation();
2410 case GNUNET_MESSAGE_TYPE_TRANSPORT_ACK:
2411 n->saw_ack = GNUNET_YES;
2412 /* intentional fall-through! */
2413 default: 2489 default:
2414#if DEBUG_TRANSPORT 2490#if DEBUG_TRANSPORT
2415 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2491 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2416 "Received message of type %u from `%4s', sending to all clients.\n", 2492 "Received \n\nREAL MESSAGE\n\ntype %u from `%4s', sending to all clients.\n",
2417 ntohs (message->type), GNUNET_i2s (peer)); 2493 ntohs (message->type), GNUNET_i2s (peer));
2418#endif 2494#endif
2419 /* transmit message to all clients */ 2495 /* transmit message to all clients */
@@ -2504,7 +2580,7 @@ handle_start (void *cls,
2504 { 2580 {
2505 cim.id = n->id; 2581 cim.id = n->id;
2506 transmit_to_client (c, &cim.header, GNUNET_NO); 2582 transmit_to_client (c, &cim.header, GNUNET_NO);
2507 if (n->saw_ack) 2583 if (n->received_pong)
2508 { 2584 {
2509 im->peer = n->id; 2585 im->peer = n->id;
2510 transmit_to_client (c, &im->header, GNUNET_NO); 2586 transmit_to_client (c, &im->header, GNUNET_NO);
@@ -2584,9 +2660,9 @@ handle_send (void *cls,
2584 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 2660 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2585 return; 2661 return;
2586 } 2662 }
2587 n = find_neighbor (&obm->peer, NULL, 0); 2663 n = find_neighbor (&obm->peer);
2588 if (n == NULL) 2664 if (n == NULL)
2589 n = setup_new_neighbor (&obm->peer, NULL, 0); 2665 n = setup_new_neighbor (&obm->peer); /* But won't ever add address, we have none! */
2590 tc = clients; 2666 tc = clients;
2591 while ((tc != NULL) && (tc->client != client)) 2667 while ((tc != NULL) && (tc->client != client))
2592 tc = tc->next; 2668 tc = tc->next;
@@ -2597,7 +2673,7 @@ handle_send (void *cls,
2597 ntohs (obmm->size), 2673 ntohs (obmm->size),
2598 ntohs (obmm->type), GNUNET_i2s (&obm->peer)); 2674 ntohs (obmm->type), GNUNET_i2s (&obm->peer));
2599#endif 2675#endif
2600 transmit_to_peer (tc, ntohl (obm->priority), obmm, GNUNET_NO, n); 2676 transmit_to_peer (tc, NULL, ntohl (obm->priority), (char *)obmm, ntohs (obmm->size), GNUNET_NO, n);
2601 GNUNET_SERVER_receive_done (client, GNUNET_OK); 2677 GNUNET_SERVER_receive_done (client, GNUNET_OK);
2602} 2678}
2603 2679
@@ -2625,7 +2701,7 @@ handle_set_quota (void *cls,
2625 "Received `%s' request from client for peer `%4s'\n", 2701 "Received `%s' request from client for peer `%4s'\n",
2626 "SET_QUOTA", GNUNET_i2s (&qsm->peer)); 2702 "SET_QUOTA", GNUNET_i2s (&qsm->peer));
2627#endif 2703#endif
2628 n = find_neighbor (&qsm->peer, NULL, 0); 2704 n = find_neighbor (&qsm->peer);
2629 if (n == NULL) 2705 if (n == NULL)
2630 { 2706 {
2631 GNUNET_SERVER_receive_done (client, GNUNET_OK); 2707 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -2667,14 +2743,8 @@ handle_try_connect (void *cls,
2667 "Received `%s' request from client %p asking to connect to `%4s'\n", 2743 "Received `%s' request from client %p asking to connect to `%4s'\n",
2668 "TRY_CONNECT", client, GNUNET_i2s (&tcm->peer)); 2744 "TRY_CONNECT", client, GNUNET_i2s (&tcm->peer));
2669#endif 2745#endif
2670 if (NULL == find_neighbor (&tcm->peer, NULL, 0)) 2746 if (NULL == find_neighbor (&tcm->peer))
2671 setup_new_neighbor (&tcm->peer, NULL, 0); /* Can we set up a truly _new_ neighbor without 2747 setup_new_neighbor (&tcm->peer);
2672 knowing its address? Should we ask the plugin
2673 for more information about this peer? I don't
2674 think we can... Or set up new peer should only
2675 happen when transport notifies us of an address,
2676 and this setup should check for an address in
2677 the existing list only */
2678#if DEBUG_TRANSPORT 2748#if DEBUG_TRANSPORT
2679 else 2749 else
2680 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2750 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c
index 3df492a91..5a3e92e1e 100644
--- a/src/transport/plugin_transport_udp.c
+++ b/src/transport/plugin_transport_udp.c
@@ -345,8 +345,6 @@ static void
345udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 345udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
346{ 346{
347 struct Plugin *plugin = cls; 347 struct Plugin *plugin = cls;
348 struct GNUNET_TIME_Relative timeout =
349 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 500);
350 char *buf; 348 char *buf;
351 struct UDPMessage *msg; 349 struct UDPMessage *msg;
352 const struct GNUNET_MessageHeader *hdr; 350 const struct GNUNET_MessageHeader *hdr;
@@ -361,8 +359,11 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
361 char *msgbuf; 359 char *msgbuf;
362 const struct GNUNET_MessageHeader *currhdr; 360 const struct GNUNET_MessageHeader *currhdr;
363 361
364 do 362#if DEBUG_UDP
365 { 363 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _
364 ("entered select...\n"));
365#endif
366
366 buflen = GNUNET_NETWORK_socket_recvfrom_amount (udp_sock); 367 buflen = GNUNET_NETWORK_socket_recvfrom_amount (udp_sock);
367 368
368#if DEBUG_UDP 369#if DEBUG_UDP
@@ -370,82 +371,80 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
370 ("we expect to read %u bytes\n"), buflen); 371 ("we expect to read %u bytes\n"), buflen);
371#endif 372#endif
372 373
373 if (buflen == GNUNET_NO) 374 if (buflen == GNUNET_NO)
374 return; 375 return;
375 376
376 buf = GNUNET_malloc (buflen); 377 buf = GNUNET_malloc (buflen);
377 fromlen = sizeof (addr); 378 fromlen = sizeof (addr);
378 379
379 memset (&addr, 0, fromlen); 380 memset (&addr, 0, fromlen);
380 ret = 381 ret =
381 GNUNET_NETWORK_socket_recvfrom (udp_sock, buf, buflen, 382 GNUNET_NETWORK_socket_recvfrom (udp_sock, buf, buflen,
382 (struct sockaddr *) &addr, &fromlen); 383 (struct sockaddr *) &addr, &fromlen);
383 384
384#if DEBUG_UDP 385#if DEBUG_UDP
385 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _ 386 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _
386 ("socket_recv returned %u, src_addr_len is %u\n"), ret, 387 ("socket_recv returned %u, src_addr_len is %u\n"), ret,
387 fromlen); 388 fromlen);
388#endif 389#endif
389 390
390 if (ret <= 0) 391 if (ret <= 0)
391 { 392 {
392 GNUNET_free (buf); 393 GNUNET_free (buf);
393 return; 394 return;
394 } 395 }
395 msg = (struct UDPMessage *) buf; 396 msg = (struct UDPMessage *) buf;
396 397
397#if DEBUG_UDP 398#if DEBUG_UDP
398 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _ 399 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _
399 ("header reports message size of %d\n"), 400 ("header reports message size of %d\n"),
400 ntohs (msg->header.size)); 401 ntohs (msg->header.size));
401 402
402 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _ 403 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _
403 ("header reports message type of %d\n"), 404 ("header reports message type of %d\n"),
404 ntohs (msg->header.type)); 405 ntohs (msg->header.type));
405#endif 406#endif
406 if (ntohs (msg->header.size) < sizeof (struct UDPMessage)) 407 if (ntohs (msg->header.size) < sizeof (struct UDPMessage))
407 { 408 {
408 GNUNET_free (buf); 409 GNUNET_free (buf);
409 GNUNET_NETWORK_fdset_zero (plugin->rs); 410 GNUNET_NETWORK_fdset_zero (plugin->rs);
410 GNUNET_NETWORK_fdset_set (plugin->rs, udp_sock); 411 GNUNET_NETWORK_fdset_set (plugin->rs, udp_sock);
411 break; 412 return;
412 } 413 }
413 hdr = (const struct GNUNET_MessageHeader *) &msg[1]; 414 hdr = (const struct GNUNET_MessageHeader *) &msg[1];
414 msgbuf = (char *)&msg[1]; 415 msgbuf = (char *)&msg[1];
415 sender = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 416 sender = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
416 memcpy (sender, &msg->sender, sizeof (struct GNUNET_PeerIdentity)); 417 memcpy (sender, &msg->sender, sizeof (struct GNUNET_PeerIdentity));
417 418
418 offset = 0; 419 offset = 0;
419 count = 0; 420 count = 0;
420 tsize = ntohs (msg->header.size) - sizeof(struct UDPMessage); 421 tsize = ntohs (msg->header.size) - sizeof(struct UDPMessage);
421 while (offset < tsize)
422 {
423 currhdr = (struct GNUNET_MessageHeader *)&msgbuf[offset];
424#if DEBUG_UDP 422#if DEBUG_UDP
425 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _ 423 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "UDP", _
426 ("processing msg %d: type %d, size %d at offset %d\n"), 424 ("offset is %d, tsize is %d (UDPMessage size is %d)\n"),
427 count, ntohs(currhdr->type), ntohs(currhdr->size), offset); 425 offset, tsize, sizeof(struct UDPMessage));
428#endif 426#endif
429 plugin->env->receive (plugin->env->cls, 427 while (offset < tsize)
430 sender, currhdr, UDP_DIRECT_DISTANCE, (char *)&addr, fromlen); 428 {
431 offset += ntohs(currhdr->size); 429 currhdr = (struct GNUNET_MessageHeader *)&msgbuf[offset];
432#if DEBUG_UDP 430#if DEBUG_UDP
433 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _ 431 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _
434 ("offset now %d, tsize %d\n"), 432 ("processing msg %d: type %d, size %d at offset %d\n"),
435 offset, tsize); 433 count, ntohs(currhdr->type), ntohs(currhdr->size), offset);
436#endif 434#endif
437 count++; 435 plugin->env->receive (plugin->env->cls,
438 } 436 sender, currhdr, UDP_DIRECT_DISTANCE, (char *)&addr, fromlen);
439 437 offset += ntohs(currhdr->size);
440 GNUNET_free (sender); 438#if DEBUG_UDP
441 GNUNET_free (buf); 439 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _
440 ("offset now %d, tsize %d\n"),
441 offset, tsize);
442#endif
443 count++;
444 }
442 445
443 } 446 GNUNET_free (sender);
444 while (GNUNET_NETWORK_socket_select (plugin->rs, 447 GNUNET_free (buf);
445 NULL,
446 NULL,
447 timeout) > 0
448 && GNUNET_NETWORK_fdset_isset (plugin->rs, udp_sock));
449 448
450 plugin->select_task = 449 plugin->select_task =
451 GNUNET_SCHEDULER_add_select (plugin->env->sched, 450 GNUNET_SCHEDULER_add_select (plugin->env->sched,
diff --git a/src/transport/test_transport_api.c b/src/transport/test_transport_api.c
index 536ccc29a..b48fb0dfb 100644
--- a/src/transport/test_transport_api.c
+++ b/src/transport/test_transport_api.c
@@ -31,7 +31,7 @@
31#include "gnunet_transport_service.h" 31#include "gnunet_transport_service.h"
32#include "transport.h" 32#include "transport.h"
33 33
34#define VERBOSE GNUNET_NO 34#define VERBOSE GNUNET_YES
35 35
36#define VERBOSE_ARM GNUNET_NO 36#define VERBOSE_ARM GNUNET_NO
37 37
@@ -82,8 +82,13 @@ end ()
82{ 82{
83 /* do work here */ 83 /* do work here */
84 GNUNET_assert (ok == 8); 84 GNUNET_assert (ok == 8);
85 GNUNET_SCHEDULER_cancel (sched, die_task);
86 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transports!\n");
85 GNUNET_TRANSPORT_disconnect (p1.th); 87 GNUNET_TRANSPORT_disconnect (p1.th);
86 GNUNET_TRANSPORT_disconnect (p2.th); 88 GNUNET_TRANSPORT_disconnect (p2.th);
89
90 die_task = GNUNET_SCHEDULER_NO_TASK;
91 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transports disconnected, returning success!\n");
87 ok = 0; 92 ok = 0;
88} 93}
89 94
diff --git a/src/transport/transport.h b/src/transport/transport.h
index 603f1bbc1..89f004ab8 100644
--- a/src/transport/transport.h
+++ b/src/transport/transport.h
@@ -30,7 +30,7 @@
30#include "gnunet_time_lib.h" 30#include "gnunet_time_lib.h"
31#include "gnunet_transport_service.h" 31#include "gnunet_transport_service.h"
32 32
33#define DEBUG_TRANSPORT GNUNET_YES 33#define DEBUG_TRANSPORT GNUNET_NO
34 34
35/** 35/**
36 * For how long do we allow unused bandwidth 36 * For how long do we allow unused bandwidth
diff --git a/src/transport/transport_api.c b/src/transport/transport_api.c
index 227976981..d0df90b48 100644
--- a/src/transport/transport_api.c
+++ b/src/transport/transport_api.c
@@ -1357,8 +1357,8 @@ add_neighbour (struct GNUNET_TRANSPORT_Handle *h,
1357 h->connect_wait_head = next; 1357 h->connect_wait_head = next;
1358 else 1358 else
1359 prev->next = next; 1359 prev->next = next;
1360 if (GNUNET_YES == n->received_ack) 1360// if (GNUNET_YES == n->received_ack)
1361 { 1361// {
1362#if DEBUG_TRANSPORT 1362#if DEBUG_TRANSPORT
1363 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1363 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1364 "Found pending request for `%4s' will trigger it now.\n", 1364 "Found pending request for `%4s' will trigger it now.\n",
@@ -1370,15 +1370,8 @@ add_neighbour (struct GNUNET_TRANSPORT_Handle *h,
1370 pos->notify_delay_task = GNUNET_SCHEDULER_NO_TASK; 1370 pos->notify_delay_task = GNUNET_SCHEDULER_NO_TASK;
1371 } 1371 }
1372 schedule_request (pos); 1372 schedule_request (pos);
1373 } 1373// }
1374 else 1374
1375 {
1376#if DEBUG_TRANSPORT
1377 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1378 "Found pending request for `%4s' but still need `%s' before proceeding.\n",
1379 GNUNET_i2s (&pos->target), "ACK");
1380#endif
1381 }
1382 break; 1375 break;
1383 } 1376 }
1384 prev = pos; 1377 prev = pos;