diff options
-rw-r--r-- | src/dv/Makefile.am | 17 | ||||
-rw-r--r-- | src/dv/dv.h | 215 | ||||
-rw-r--r-- | src/dv/dv_api.c | 148 | ||||
-rw-r--r-- | src/dv/gnunet-service-dv.c | 2212 | ||||
-rw-r--r-- | src/dv/gnunet_dv_service.h | 143 | ||||
-rw-r--r-- | src/dv/plugin_transport_dv.c | 170 |
6 files changed, 910 insertions, 1995 deletions
diff --git a/src/dv/Makefile.am b/src/dv/Makefile.am index 0fa26a90d..e9e2bba3f 100644 --- a/src/dv/Makefile.am +++ b/src/dv/Makefile.am | |||
@@ -23,10 +23,9 @@ lib_LTLIBRARIES = libgnunetdv.la | |||
23 | plugin_LTLIBRARIES = libgnunet_plugin_transport_dv.la | 23 | plugin_LTLIBRARIES = libgnunet_plugin_transport_dv.la |
24 | 24 | ||
25 | libgnunetdv_la_SOURCES = \ | 25 | libgnunetdv_la_SOURCES = \ |
26 | dv_api.c dv.h | 26 | dv_api.c dv.h gnunet_dv_service.h |
27 | libgnunetdv_la_LIBADD = \ | 27 | libgnunetdv_la_LIBADD = \ |
28 | $(top_builddir)/src/util/libgnunetutil.la \ | 28 | $(top_builddir)/src/util/libgnunetutil.la \ |
29 | $(top_builddir)/src/core/libgnunetcore.la \ | ||
30 | $(GN_LIBINTL) $(XLIB) | 29 | $(GN_LIBINTL) $(XLIB) |
31 | libgnunetdv_la_LDFLAGS = \ | 30 | libgnunetdv_la_LDFLAGS = \ |
32 | $(GN_LIB_LDFLAGS) $(WINFLAGS) \ | 31 | $(GN_LIB_LDFLAGS) $(WINFLAGS) \ |
@@ -37,24 +36,17 @@ libexec_PROGRAMS = \ | |||
37 | gnunet-service-dv | 36 | gnunet-service-dv |
38 | 37 | ||
39 | gnunet_service_dv_SOURCES = \ | 38 | gnunet_service_dv_SOURCES = \ |
40 | gnunet-service-dv.c | 39 | gnunet-service-dv.c dv.h |
41 | gnunet_service_dv_LDADD = \ | 40 | gnunet_service_dv_LDADD = \ |
42 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 41 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
43 | $(top_builddir)/src/dv/libgnunetdv.la \ | ||
44 | $(top_builddir)/src/core/libgnunetcore.la \ | 42 | $(top_builddir)/src/core/libgnunetcore.la \ |
45 | $(top_builddir)/src/hello/libgnunethello.la \ | ||
46 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ | ||
47 | $(top_builddir)/src/util/libgnunetutil.la \ | 43 | $(top_builddir)/src/util/libgnunetutil.la \ |
48 | $(GN_LIBINTL) | 44 | $(GN_LIBINTL) |
49 | gnunet_service_dv_DEPENDENCIES = \ | ||
50 | libgnunetdv.la | ||
51 | 45 | ||
52 | libgnunet_plugin_transport_dv_la_SOURCES = \ | 46 | libgnunet_plugin_transport_dv_la_SOURCES = \ |
53 | plugin_transport_dv.c | 47 | plugin_transport_dv.c |
54 | libgnunet_plugin_transport_dv_la_LIBADD = \ | 48 | libgnunet_plugin_transport_dv_la_LIBADD = \ |
55 | $(top_builddir)/src/hello/libgnunethello.la \ | 49 | libgnunetdv.la \ |
56 | $(top_builddir)/src/dv/libgnunetdv.la \ | ||
57 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ | ||
58 | $(top_builddir)/src/util/libgnunetutil.la | 50 | $(top_builddir)/src/util/libgnunetutil.la |
59 | libgnunet_plugin_transport_dv_la_LDFLAGS = \ | 51 | libgnunet_plugin_transport_dv_la_LDFLAGS = \ |
60 | $(GN_PLUGIN_LDFLAGS) | 52 | $(GN_PLUGIN_LDFLAGS) |
@@ -77,4 +69,5 @@ endif | |||
77 | # $(top_builddir)/src/util/libgnunetutil.la | 69 | # $(top_builddir)/src/util/libgnunetutil.la |
78 | 70 | ||
79 | EXTRA_DIST = \ | 71 | EXTRA_DIST = \ |
80 | test_transport_dv_data.conf | 72 | test_transport_dv_data.conf |
73 | |||
diff --git a/src/dv/dv.h b/src/dv/dv.h index 948845bf7..cfa09409e 100644 --- a/src/dv/dv.h +++ b/src/dv/dv.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2001, 2002, 2003, 2004, 2009 Christian Grothoff (and other contributing authors) | 3 | (C) 2013 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -20,125 +20,98 @@ | |||
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @author Christian Grothoff | 22 | * @author Christian Grothoff |
23 | * @author NOT Nathan Evans | ||
24 | * @file dv/dv.h | 23 | * @file dv/dv.h |
24 | * @brief IPC messages between DV service and DV plugin | ||
25 | */ | 25 | */ |
26 | #ifndef DV_H | 26 | #ifndef DV_H |
27 | #define DV_H | 27 | #define DV_H |
28 | 28 | ||
29 | #include "gnunet_common.h" | 29 | #include "gnunet_common.h" |
30 | 30 | ||
31 | #define DEBUG_DV_GOSSIP GNUNET_EXTRA_LOGGING | ||
32 | #define DEBUG_DV_GOSSIP_SEND GNUNET_EXTRA_LOGGING | ||
33 | #define DEBUG_DV_GOSSIP_RECEIPT GNUNET_EXTRA_LOGGING | ||
34 | #define DEBUG_DV_MESSAGES GNUNET_EXTRA_LOGGING | ||
35 | #define DEBUG_DV GNUNET_EXTRA_LOGGING | ||
36 | #define DEBUG_DV_PEER_NUMBERS GNUNET_EXTRA_LOGGING | ||
37 | #define DEBUG_MESSAGE_DROP GNUNET_EXTRA_LOGGING | ||
38 | |||
39 | typedef void (*GNUNET_DV_MessageReceivedHandler) (void *cls, | ||
40 | struct GNUNET_PeerIdentity * | ||
41 | sender, char *msg, | ||
42 | size_t msg_len, | ||
43 | uint32_t distance, | ||
44 | char *sender_address, | ||
45 | size_t sender_address_len); | ||
46 | |||
47 | GNUNET_NETWORK_STRUCT_BEGIN | 31 | GNUNET_NETWORK_STRUCT_BEGIN |
48 | 32 | ||
49 | /** | 33 | /** |
50 | * DV Message, contains a message that was received | 34 | * DV service tells plugin about a DV-connection being |
51 | * via DV for this peer! Internal. | 35 | * now available. |
52 | * | ||
53 | * Sender address is copied to the end of this struct, | ||
54 | * followed by the actual message received. | ||
55 | */ | 36 | */ |
56 | struct GNUNET_DV_MessageReceived | 37 | struct GNUNET_DV_ConnectMessage |
57 | { | 38 | { |
58 | /** | 39 | /** |
59 | * Type: GNUNET_MESSAGE_TYPE_TRANSPORT_DV_MESSAGE | 40 | * Type: GNUNET_MESSAGE_TYPE_TRANSPORT_DV_CONNECT |
60 | */ | 41 | */ |
61 | struct GNUNET_MessageHeader header; | 42 | struct GNUNET_MessageHeader header; |
62 | 43 | ||
63 | /** | 44 | /** |
64 | * The sender of the message | 45 | * The distance to the peer that we are now connected to |
65 | */ | 46 | */ |
66 | struct GNUNET_PeerIdentity sender; | 47 | uint32_t distance GNUNET_PACKED; |
67 | 48 | ||
68 | /** | 49 | /** |
69 | * The length of the message that was sent (appended to this end of struct) | 50 | * The other peer (at the given distance). |
70 | */ | ||
71 | uint32_t msg_len; | ||
72 | |||
73 | /** | ||
74 | * The distance to the peer that we received the message from | ||
75 | */ | 51 | */ |
76 | uint32_t distance; | 52 | struct GNUNET_PeerIdentity peer; |
77 | 53 | ||
78 | }; | 54 | }; |
79 | 55 | ||
80 | 56 | ||
81 | /** | 57 | /** |
82 | * DV Message, indicates that we have learned of a new DV level peer. | 58 | * DV service tells plugin about a DV-connection being |
83 | * Internal. | 59 | * no longer available. |
84 | * | 60 | * |
85 | * Sender address is copied to the end of this struct. | 61 | * Sender address is copied to the end of this struct, |
62 | * followed by the actual message received. | ||
86 | */ | 63 | */ |
87 | struct GNUNET_DV_ConnectMessage | 64 | struct GNUNET_DV_DisconnectMessage |
88 | { | 65 | { |
89 | /** | 66 | /** |
90 | * Type: GNUNET_MESSAGE_TYPE_TRANSPORT_DV_MESSAGE | 67 | * Type: GNUNET_MESSAGE_TYPE_TRANSPORT_DV_DISCONNECT |
91 | */ | 68 | */ |
92 | struct GNUNET_MessageHeader header; | 69 | struct GNUNET_MessageHeader header; |
93 | 70 | ||
94 | /** | 71 | /** |
95 | * The sender of the message | 72 | * The distance to the peer that we used to have |
96 | */ | ||
97 | struct GNUNET_PeerIdentity *sender; | ||
98 | |||
99 | /** | ||
100 | * The message that was sent | ||
101 | */ | ||
102 | struct GNUNET_MessageHeader *msg; | ||
103 | |||
104 | /** | ||
105 | * The distance to the peer that we received the message from | ||
106 | */ | 73 | */ |
107 | uint32_t distance; | 74 | uint32_t distance GNUNET_PACKED; |
108 | 75 | ||
109 | /** | 76 | /** |
110 | * Length of the sender address, appended to end of this message | 77 | * The peer that is no longer available. |
111 | */ | 78 | */ |
112 | uint32_t sender_address_len; | 79 | struct GNUNET_PeerIdentity peer; |
113 | 80 | ||
114 | }; | 81 | }; |
115 | 82 | ||
83 | |||
116 | /** | 84 | /** |
117 | * Message to return result from a send attempt. | 85 | * DV Message, contains a message that was received via DV for this |
118 | * Internal. | 86 | * peer. Send from the DV service to the DV plugin. |
87 | * | ||
88 | * Sender address is copied to the end of this struct, | ||
89 | * followed by the actual message received. | ||
119 | */ | 90 | */ |
120 | struct GNUNET_DV_SendResultMessage | 91 | struct GNUNET_DV_ReceivedMessage |
121 | { | 92 | { |
122 | /** | 93 | /** |
123 | * Type: GNUNET_MESSAGE_TYPE_DV_SEND_RESULT | 94 | * Type: GNUNET_MESSAGE_TYPE_TRANSPORT_DV_RECV |
124 | */ | 95 | */ |
125 | struct GNUNET_MessageHeader header; | 96 | struct GNUNET_MessageHeader header; |
126 | 97 | ||
127 | /** | 98 | /** |
128 | * Unique ID for attempted sent message. | 99 | * The distance to the peer that we received the message from |
129 | */ | 100 | */ |
130 | uint32_t uid; | 101 | uint32_t distance GNUNET_PACKED; |
131 | 102 | ||
132 | /** | 103 | /** |
133 | * Result of attempted send, 0 for send okay, | 104 | * The (actual) sender of the message |
134 | * 1 for failure of any reason. | ||
135 | */ | 105 | */ |
136 | uint32_t result; | 106 | struct GNUNET_PeerIdentity sender; |
107 | |||
108 | /* payload follows */ | ||
137 | }; | 109 | }; |
138 | 110 | ||
111 | |||
139 | /** | 112 | /** |
140 | * Message to send a message over DV via a specific peer. | 113 | * Message from plugin to DV service, requesting a |
141 | * Internal. | 114 | * message to be routed. |
142 | */ | 115 | */ |
143 | struct GNUNET_DV_SendMessage | 116 | struct GNUNET_DV_SendMessage |
144 | { | 117 | { |
@@ -148,128 +121,40 @@ struct GNUNET_DV_SendMessage | |||
148 | struct GNUNET_MessageHeader header; | 121 | struct GNUNET_MessageHeader header; |
149 | 122 | ||
150 | /** | 123 | /** |
151 | * Intended final recipient of this message | ||
152 | */ | ||
153 | struct GNUNET_PeerIdentity target; | ||
154 | |||
155 | /** | ||
156 | * Message priority | ||
157 | */ | ||
158 | uint32_t priority; | ||
159 | |||
160 | /** | ||
161 | * Unique ID for this message, for confirm callback. | 124 | * Unique ID for this message, for confirm callback. |
162 | */ | 125 | */ |
163 | uint32_t uid; | 126 | uint32_t uid GNUNET_PACKED; |
164 | |||
165 | /** | ||
166 | * How long can we delay sending? | ||
167 | */ | ||
168 | struct GNUNET_TIME_Relative timeout; | ||
169 | |||
170 | /** | ||
171 | * Size of the address (appended to end of struct) | ||
172 | */ | ||
173 | uint32_t addrlen; | ||
174 | 127 | ||
175 | /** | 128 | /** |
176 | * The message(s) to be sent. | 129 | * The (actual) target of the message |
177 | */ | ||
178 | char *msgbuf; | ||
179 | |||
180 | /* | ||
181 | * Sender, appended to end of struct tells via whom | ||
182 | * to send this message. | ||
183 | */ | 130 | */ |
131 | struct GNUNET_PeerIdentity target; | ||
184 | 132 | ||
185 | }; | 133 | }; |
186 | 134 | ||
187 | /** | ||
188 | * Message that gets sent between nodes updating dv infos | ||
189 | */ | ||
190 | typedef struct | ||
191 | { | ||
192 | /* Message Header */ | ||
193 | struct GNUNET_MessageHeader header; | ||
194 | |||
195 | /** | ||
196 | * Cost from received from node to neighbor node, takes distance into account | ||
197 | */ | ||
198 | uint32_t cost GNUNET_PACKED; | ||
199 | |||
200 | /** | ||
201 | * Identity of neighbor we learned information about | ||
202 | */ | ||
203 | struct GNUNET_PeerIdentity neighbor; | ||
204 | |||
205 | /** | ||
206 | * PublicKey of neighbor. | ||
207 | */ | ||
208 | struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded pkey; | ||
209 | |||
210 | /** | ||
211 | * Neighbor ID to use when sending to this peer | ||
212 | */ | ||
213 | uint32_t neighbor_id GNUNET_PACKED; | ||
214 | |||
215 | } p2p_dv_MESSAGE_NeighborInfo; | ||
216 | 135 | ||
217 | /** | 136 | /** |
218 | * Message that gets sent between nodes carrying information | 137 | * Message from service to DV plugin, saying that a |
138 | * SEND request was handled. | ||
219 | */ | 139 | */ |
220 | typedef struct | 140 | struct GNUNET_DV_AckMessage |
221 | { | 141 | { |
142 | /** | ||
143 | * Type: GNUNET_MESSAGE_TYPE_DV_SEND_ACK | ||
144 | */ | ||
222 | struct GNUNET_MessageHeader header; | 145 | struct GNUNET_MessageHeader header; |
223 | 146 | ||
224 | /** | 147 | /** |
225 | * Unique ID for this message. Will be zero unless | 148 | * Which message is being acknowledged? |
226 | * message tracking is desired. | ||
227 | */ | 149 | */ |
228 | uint32_t uid GNUNET_PACKED; | 150 | uint32_t uid GNUNET_PACKED; |
229 | 151 | ||
230 | /** | 152 | /** |
231 | * Identity of peer that ultimately sent the message. | 153 | * The (actual) target of the message |
232 | * Should be looked up in the set of 'neighbor_id's of | ||
233 | * the referring peer. | ||
234 | */ | ||
235 | uint32_t sender GNUNET_PACKED; | ||
236 | |||
237 | /** | ||
238 | * Identity of neighbor this message is going to. Should | ||
239 | * be looked up in the set of our own identifiers for | ||
240 | * neighbors! | ||
241 | */ | ||
242 | uint32_t recipient GNUNET_PACKED; | ||
243 | |||
244 | } p2p_dv_MESSAGE_Data; | ||
245 | |||
246 | /** | ||
247 | * Message that gets sent between nodes indicating a peer | ||
248 | * was disconnected. | ||
249 | */ | ||
250 | typedef struct | ||
251 | { | ||
252 | struct GNUNET_MessageHeader header; | ||
253 | |||
254 | /** | ||
255 | * Identity of neighbor that was disconnected. | ||
256 | */ | 154 | */ |
257 | uint32_t peer_id GNUNET_PACKED; | 155 | struct GNUNET_PeerIdentity target; |
258 | 156 | ||
259 | } p2p_dv_MESSAGE_Disconnect; | 157 | }; |
260 | GNUNET_NETWORK_STRUCT_END | 158 | GNUNET_NETWORK_STRUCT_END |
261 | 159 | ||
262 | struct GNUNET_DV_Handle * | ||
263 | GNUNET_DV_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
264 | GNUNET_DV_MessageReceivedHandler receive_handler, | ||
265 | void *receive_handler_cls); | ||
266 | |||
267 | /** | ||
268 | * Disconnect from the DV service | ||
269 | * | ||
270 | * @param handle the current handle to the service to disconnect | ||
271 | */ | ||
272 | void | ||
273 | GNUNET_DV_disconnect (struct GNUNET_DV_Handle *handle); | ||
274 | |||
275 | #endif | 160 | #endif |
diff --git a/src/dv/dv_api.c b/src/dv/dv_api.c index d3cdb0fb7..ca4334f2f 100644 --- a/src/dv/dv_api.c +++ b/src/dv/dv_api.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2009, 2010 Christian Grothoff (and other contributing authors) | 3 | (C) 2009--2013 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -25,21 +25,147 @@ | |||
25 | * @author Nathan Evans | 25 | * @author Nathan Evans |
26 | */ | 26 | */ |
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet_bandwidth_lib.h" | 28 | #include "gnunet_util_lib.h" |
29 | #include "gnunet_client_lib.h" | ||
30 | #include "gnunet_constants.h" | ||
31 | #include "gnunet_container_lib.h" | ||
32 | #include "gnunet_arm_service.h" | ||
33 | #include "gnunet_hello_lib.h" | ||
34 | #include "gnunet_protocols.h" | ||
35 | #include "gnunet_server_lib.h" | ||
36 | #include "gnunet_time_lib.h" | ||
37 | #include "gnunet_dv_service.h" | 29 | #include "gnunet_dv_service.h" |
30 | #include "gnunet_protocols.h" | ||
38 | #include "dv.h" | 31 | #include "dv.h" |
39 | #include "gnunet_transport_plugin.h" | 32 | #include "gnunet_transport_plugin.h" |
40 | 33 | ||
41 | #define LOG(kind,...) GNUNET_log_from (kind, "dv-api",__VA_ARGS__) | 34 | #define LOG(kind,...) GNUNET_log_from (kind, "dv-api",__VA_ARGS__) |
42 | 35 | ||
36 | |||
37 | /** | ||
38 | * Handle for a send operation. | ||
39 | */ | ||
40 | struct GNUNET_DV_TransmitHandle | ||
41 | { | ||
42 | struct GNUNET_DV_TransmitHandle *next; | ||
43 | |||
44 | struct GNUNET_DV_TransmitHandle *prev; | ||
45 | |||
46 | struct GNUNET_DV_ServiceHandle *sh; | ||
47 | |||
48 | GNUNET_DV_MessageSentCallback cb; | ||
49 | |||
50 | void *cb_cls; | ||
51 | |||
52 | const struct GNUNET_MessageHeader *msg; | ||
53 | |||
54 | struct GNUNET_PeerIdentity target; | ||
55 | |||
56 | }; | ||
57 | |||
58 | |||
59 | /** | ||
60 | * Handle to the DV service. | ||
61 | */ | ||
62 | struct GNUNET_DV_ServiceHandle | ||
63 | { | ||
64 | |||
65 | struct GNUNET_ClientHandle *client; | ||
66 | |||
67 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
68 | |||
69 | void *cls; | ||
70 | |||
71 | GNUNET_DV_ConnectCallback connect_cb; | ||
72 | |||
73 | GNUNET_DV_DisconnectCallback disconnect_cb; | ||
74 | |||
75 | GNUNET_DV_MessageReceivedCallback message_cb; | ||
76 | |||
77 | struct GNUNET_DV_TransmitHandle *th_head; | ||
78 | |||
79 | struct GNUNET_DV_TransmitHandle *th_tail; | ||
80 | |||
81 | }; | ||
82 | |||
83 | |||
84 | /** | ||
85 | * Connect to the DV service. | ||
86 | * | ||
87 | * @param cfg configuration | ||
88 | * @param cls closure for callbacks | ||
89 | * @param connect_cb function to call on connects | ||
90 | * @param disconnect_cb function to call on disconnects | ||
91 | * @param message_cb function to call if we receive messages | ||
92 | * @return handle to access the service | ||
93 | */ | ||
94 | struct GNUNET_DV_ServiceHandle * | ||
95 | GNUNET_DV_service_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
96 | void *cls, | ||
97 | GNUNET_DV_ConnectCallback connect_cb, | ||
98 | GNUNET_DV_DisconnectCallback disconnect_cb, | ||
99 | GNUNET_DV_MessageReceivedCallback message_cb) | ||
100 | { | ||
101 | GNUNET_break (0); | ||
102 | return NULL; | ||
103 | } | ||
104 | |||
105 | |||
106 | /** | ||
107 | * Disconnect from DV service. | ||
108 | * | ||
109 | * @param sh service handle | ||
110 | */ | ||
111 | void | ||
112 | GNUNET_DV_service_disconnect (struct GNUNET_DV_ServiceHandle *sh) | ||
113 | { | ||
114 | GNUNET_break (0); | ||
115 | } | ||
116 | |||
117 | |||
118 | |||
119 | /** | ||
120 | * Send a message via DV service. | ||
121 | * | ||
122 | * @param sh service handle | ||
123 | * @param target intended recpient | ||
124 | * @param msg message payload | ||
125 | * @param cb function to invoke when done | ||
126 | * @param cb_cls closure for 'cb' | ||
127 | * @return handle to cancel the operation | ||
128 | */ | ||
129 | struct GNUNET_DV_TransmitHandle * | ||
130 | GNUNET_DV_send (struct GNUNET_DV_ServiceHandle *sh, | ||
131 | const struct GNUNET_PeerIdentity *target, | ||
132 | const struct GNUNET_MessageHeader *msg, | ||
133 | GNUNET_DV_MessageSentCallback cb, | ||
134 | void *cb_cls) | ||
135 | { | ||
136 | GNUNET_break (0); | ||
137 | return NULL; | ||
138 | } | ||
139 | |||
140 | |||
141 | /** | ||
142 | * Abort send operation (naturally, the message may have | ||
143 | * already been transmitted; this only stops the 'cb' | ||
144 | * from being called again). | ||
145 | * | ||
146 | * @param th send operation to cancel | ||
147 | */ | ||
148 | void | ||
149 | GNUNET_DV_send_cancel (struct GNUNET_DV_TransmitHandle *th) | ||
150 | { | ||
151 | GNUNET_break (0); | ||
152 | } | ||
153 | |||
154 | |||
155 | |||
156 | #if 0 | ||
157 | |||
158 | |||
159 | |||
160 | |||
161 | |||
162 | |||
163 | |||
164 | |||
165 | |||
166 | |||
167 | |||
168 | |||
43 | /** | 169 | /** |
44 | * Store ready to send messages | 170 | * Store ready to send messages |
45 | */ | 171 | */ |
@@ -639,4 +765,6 @@ GNUNET_DV_disconnect (struct GNUNET_DV_Handle *handle) | |||
639 | GNUNET_free (handle); | 765 | GNUNET_free (handle); |
640 | } | 766 | } |
641 | 767 | ||
768 | #endif | ||
769 | |||
642 | /* end of dv_api.c */ | 770 | /* end of dv_api.c */ |
diff --git a/src/dv/gnunet-service-dv.c b/src/dv/gnunet-service-dv.c index 9efd3cde6..451a438f9 100644 --- a/src/dv/gnunet-service-dv.c +++ b/src/dv/gnunet-service-dv.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2009 Christian Grothoff (and other contributing authors) | 3 | (C) 2013 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -29,528 +29,274 @@ | |||
29 | * | 29 | * |
30 | */ | 30 | */ |
31 | #include "platform.h" | 31 | #include "platform.h" |
32 | #include "gnunet_client_lib.h" | 32 | #include "gnunet_util_lib.h" |
33 | #include "gnunet_getopt_lib.h" | ||
34 | #include "gnunet_os_lib.h" | ||
35 | #include "gnunet_protocols.h" | 33 | #include "gnunet_protocols.h" |
36 | #include "gnunet_service_lib.h" | ||
37 | #include "gnunet_core_service.h" | 34 | #include "gnunet_core_service.h" |
38 | #include "gnunet_signal_lib.h" | ||
39 | #include "gnunet_util_lib.h" | ||
40 | #include "gnunet_hello_lib.h" | 35 | #include "gnunet_hello_lib.h" |
41 | #include "gnunet_peerinfo_service.h" | 36 | #include "gnunet_peerinfo_service.h" |
42 | #include "gnunet_crypto_lib.h" | ||
43 | #include "gnunet_statistics_service.h" | 37 | #include "gnunet_statistics_service.h" |
38 | #include "gnunet_consensus_service.h" | ||
44 | #include "dv.h" | 39 | #include "dv.h" |
45 | 40 | ||
46 | /** | 41 | /** |
47 | * For testing mostly, remember only the | 42 | * How often do we establish the consensu? |
48 | * shortest path to a distant neighbor. | ||
49 | */ | ||
50 | #define AT_MOST_ONE GNUNET_NO | ||
51 | |||
52 | #define USE_PEER_ID GNUNET_YES | ||
53 | |||
54 | /** | ||
55 | * How many outstanding messages (unknown sender) will we allow per peer? | ||
56 | */ | ||
57 | #define MAX_OUTSTANDING_MESSAGES 5 | ||
58 | |||
59 | /** | ||
60 | * How often do we check about sending out more peer information (if | ||
61 | * we are connected to no peers previously). | ||
62 | */ | ||
63 | #define GNUNET_DV_DEFAULT_SEND_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 500000) | ||
64 | |||
65 | /** | ||
66 | * How long do we wait at most between sending out information? | ||
67 | */ | ||
68 | #define GNUNET_DV_MAX_SEND_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 500000) | ||
69 | |||
70 | /** | ||
71 | * How long can we have not heard from a peer and | ||
72 | * still have it in our tables? | ||
73 | */ | ||
74 | #define GNUNET_DV_PEER_EXPIRATION_TIME GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1000)) | ||
75 | |||
76 | /** | ||
77 | * Priority for gossip. | ||
78 | */ | ||
79 | #define GNUNET_DV_DHT_GOSSIP_PRIORITY (GNUNET_EXTREME_PRIORITY / 10) | ||
80 | |||
81 | /** | ||
82 | * How often should we check if expiration time has elapsed for | ||
83 | * some peer? | ||
84 | */ | ||
85 | #define GNUNET_DV_MAINTAIN_FREQUENCY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5)) | ||
86 | |||
87 | /** | ||
88 | * How long to allow a message to be delayed? | ||
89 | */ | 43 | */ |
90 | #define DV_DELAY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5)) | 44 | #define GNUNET_DV_CONSENSUS_FREQUENCY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5)) |
91 | 45 | ||
92 | /** | 46 | /** |
93 | * Priority to use for DV data messages. | 47 | * The default fisheye depth, from how many hops away will |
48 | * we keep peers? | ||
94 | */ | 49 | */ |
95 | #define DV_PRIORITY 0 | 50 | #define DEFAULT_FISHEYE_DEPTH 3 |
96 | 51 | ||
97 | /** | 52 | /** |
98 | * The cost to a direct neighbor. We used to use 0, but 1 makes more sense. | 53 | * How many hops is a direct neighbor away? |
99 | */ | 54 | */ |
100 | #define DIRECT_NEIGHBOR_COST 1 | 55 | #define DIRECT_NEIGHBOR_COST 1 |
101 | 56 | ||
102 | /** | 57 | GNUNET_NETWORK_STRUCT_BEGIN |
103 | * The default number of direct connections to store in DV (max) | ||
104 | */ | ||
105 | #define DEFAULT_DIRECT_CONNECTIONS 50 | ||
106 | |||
107 | /** | ||
108 | * The default size of direct + extended peers in DV (max) | ||
109 | */ | ||
110 | #define DEFAULT_DV_SIZE 100 | ||
111 | |||
112 | /** | ||
113 | * The default fisheye depth, from how many hops away will | ||
114 | * we keep peers? | ||
115 | */ | ||
116 | #define DEFAULT_FISHEYE_DEPTH 4 | ||
117 | 58 | ||
118 | /** | 59 | /** |
119 | * Linked list of messages to send to clients. | 60 | * Information about a peer DV can route to. These entries are what |
61 | * we use as the binary format to establish consensus to create our | ||
62 | * routing table and as the address format in the HELLOs. | ||
120 | */ | 63 | */ |
121 | struct PendingMessage | 64 | struct Target |
122 | { | 65 | { |
123 | /** | ||
124 | * Pointer to next item in the list | ||
125 | */ | ||
126 | struct PendingMessage *next; | ||
127 | |||
128 | /** | ||
129 | * Pointer to previous item in the list | ||
130 | */ | ||
131 | struct PendingMessage *prev; | ||
132 | |||
133 | /** | ||
134 | * The PeerIdentity to send to | ||
135 | */ | ||
136 | struct GNUNET_PeerIdentity recipient; | ||
137 | |||
138 | /** | ||
139 | * The result of message sending. | ||
140 | */ | ||
141 | struct GNUNET_DV_SendResultMessage *send_result; | ||
142 | |||
143 | /** | ||
144 | * Message importance level. | ||
145 | */ | ||
146 | unsigned int importance; | ||
147 | 66 | ||
148 | /** | 67 | /** |
149 | * Size of message. | 68 | * Identity of the peer we can reach. |
150 | */ | 69 | */ |
151 | unsigned int msg_size; | 70 | struct GNUNET_PeerIdentity peer; |
152 | |||
153 | /** | ||
154 | * How long to wait before sending message. | ||
155 | */ | ||
156 | struct GNUNET_TIME_Relative timeout; | ||
157 | 71 | ||
158 | /** | 72 | /** |
159 | * Actual message to be sent; // avoid allocation | 73 | * How many hops (1-3) is this peer away? |
160 | */ | 74 | */ |
161 | const struct GNUNET_MessageHeader *msg; // msg = (cast) &pm[1]; // memcpy (&pm[1], data, len); | 75 | uint32_t distance GNUNET_PACKED; |
162 | 76 | ||
163 | }; | 77 | }; |
164 | 78 | ||
165 | struct FastGossipNeighborList | ||
166 | { | ||
167 | /** | ||
168 | * Next element of DLL | ||
169 | */ | ||
170 | struct FastGossipNeighborList *next; | ||
171 | |||
172 | /** | ||
173 | * Prev element of DLL | ||
174 | */ | ||
175 | struct FastGossipNeighborList *prev; | ||
176 | |||
177 | /** | ||
178 | * The neighbor to gossip about | ||
179 | */ | ||
180 | struct DistantNeighbor *about; | ||
181 | }; | ||
182 | 79 | ||
183 | /** | 80 | /** |
184 | * Context created whenever a direct peer connects to us, | 81 | * Message exchanged between DV services (via core), requesting a |
185 | * used to gossip other peers to it. | 82 | * message to be routed. |
186 | */ | 83 | */ |
187 | struct NeighborSendContext | 84 | struct RouteMessage |
188 | { | 85 | { |
189 | /** | 86 | /** |
190 | * The peer we will gossip to. | 87 | * Type: GNUNET_MESSAGE_TYPE_DV_ROUTE |
191 | */ | ||
192 | struct DirectNeighbor *toNeighbor; | ||
193 | |||
194 | /** | ||
195 | * The task associated with this context. | ||
196 | */ | 88 | */ |
197 | GNUNET_SCHEDULER_TaskIdentifier task; | 89 | struct GNUNET_MessageHeader header; |
198 | 90 | ||
199 | /** | 91 | /** |
200 | * Head of DLL of peers to gossip about | 92 | * Expected (remaining) distance. Must be always smaller than |
201 | * as fast as possible to this peer, for initial | 93 | * DEFAULT_FISHEYE_DEPTH, should be zero at the target. Must |
202 | * set up. | 94 | * be decremented by one at each hop. Peers must not forward |
95 | * these messages further once the counter has reached zero. | ||
203 | */ | 96 | */ |
204 | struct FastGossipNeighborList *fast_gossip_list_head; | 97 | uint32_t distance GNUNET_PACKED; |
205 | 98 | ||
206 | /** | 99 | /** |
207 | * Tail of DLL of peers to gossip about | 100 | * The (actual) target of the message (this peer, if distance is zero). |
208 | * as fast as possible to this peer, for initial | ||
209 | * set up. | ||
210 | */ | 101 | */ |
211 | struct FastGossipNeighborList *fast_gossip_list_tail; | 102 | struct GNUNET_PeerIdentity target; |
212 | 103 | ||
213 | }; | 104 | }; |
214 | 105 | ||
106 | GNUNET_NETWORK_STRUCT_END | ||
107 | |||
215 | 108 | ||
216 | /** | 109 | /** |
217 | * Struct to hold information for updating existing neighbors | 110 | * Linked list of messages to send to clients. |
218 | */ | 111 | */ |
219 | struct NeighborUpdateInfo | 112 | struct PendingMessage |
220 | { | 113 | { |
221 | /** | 114 | /** |
222 | * Cost | 115 | * Pointer to next item in the list |
223 | */ | 116 | */ |
224 | unsigned int cost; | 117 | struct PendingMessage *next; |
225 | 118 | ||
226 | /** | 119 | /** |
227 | * The existing neighbor | 120 | * Pointer to previous item in the list |
228 | */ | 121 | */ |
229 | struct DistantNeighbor *neighbor; | 122 | struct PendingMessage *prev; |
230 | 123 | ||
231 | /** | 124 | /** |
232 | * The referrer of the possibly existing peer | 125 | * Actual message to be sent, allocated after this struct. |
233 | */ | 126 | */ |
234 | struct DirectNeighbor *referrer; | 127 | const struct GNUNET_MessageHeader *msg; |
235 | 128 | ||
236 | /** | 129 | /** |
237 | * The time we heard about this peer | 130 | * Ultimate target for the message. |
238 | */ | 131 | */ |
239 | struct GNUNET_TIME_Absolute now; | 132 | struct GNUNET_PeerIdentity ultimate_target; |
240 | 133 | ||
241 | /** | 134 | /** |
242 | * Peer id this peer uses to refer to neighbor. | 135 | * Unique ID of the message. |
243 | */ | 136 | */ |
244 | unsigned int referrer_peer_id; | 137 | uint32_t uid; |
245 | 138 | ||
246 | }; | 139 | }; |
247 | 140 | ||
141 | |||
248 | /** | 142 | /** |
249 | * Struct to store a single message received with | 143 | * Information about a direct neighbor (core-level, excluding |
250 | * an unknown sender. | 144 | * DV-links, only DV-enabled peers). |
251 | */ | 145 | */ |
252 | struct UnknownSenderMessage | 146 | struct DirectNeighbor |
253 | { | 147 | { |
254 | /** | ||
255 | * Message sender (immediate) | ||
256 | */ | ||
257 | struct GNUNET_PeerIdentity sender; | ||
258 | 148 | ||
259 | /** | 149 | /** |
260 | * The actual message received | 150 | * Identity of the peer. |
261 | */ | 151 | */ |
262 | struct GNUNET_MessageHeader *message; | 152 | struct GNUNET_PeerIdentity peer; |
263 | 153 | ||
264 | /** | 154 | /** |
265 | * Latency of connection | 155 | * Head of linked list of messages to send to this peer. |
266 | */ | 156 | */ |
267 | struct GNUNET_TIME_Relative latency; | 157 | struct PendingMessage *pm_head; |
268 | 158 | ||
269 | /** | 159 | /** |
270 | * Distance to destination | 160 | * Tail of linked list of messages to send to this peer. |
271 | */ | 161 | */ |
272 | uint32_t distance; | 162 | struct PendingMessage *pm_tail; |
273 | 163 | ||
274 | /** | 164 | /** |
275 | * Unknown sender id | 165 | * Transmit handle to core service. |
276 | */ | 166 | */ |
277 | uint32_t sender_id; | 167 | struct GNUNET_CORE_TransmitHandle *cth; |
278 | }; | 168 | }; |
279 | 169 | ||
170 | |||
280 | /** | 171 | /** |
281 | * Struct where actual neighbor information is stored, | 172 | * A route includes information about the next hop, |
282 | * referenced by min_heap and max_heap. Freeing dealt | 173 | * the target, and the ultimate distance to the |
283 | * with when items removed from hashmap. | 174 | * target. |
284 | */ | 175 | */ |
285 | struct DirectNeighbor | 176 | struct Route |
286 | { | 177 | { |
287 | /** | ||
288 | * Identity of neighbor. | ||
289 | */ | ||
290 | struct GNUNET_PeerIdentity identity; | ||
291 | |||
292 | /** | ||
293 | * PublicKey of neighbor. | ||
294 | */ | ||
295 | struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded pkey; | ||
296 | |||
297 | /** | ||
298 | * Head of DLL of nodes that this direct neighbor referred to us. | ||
299 | */ | ||
300 | struct DistantNeighbor *referee_head; | ||
301 | 178 | ||
302 | /** | 179 | /** |
303 | * Tail of DLL of nodes that this direct neighbor referred to us. | 180 | * Which peer do we need to forward the message to? |
304 | */ | 181 | */ |
305 | struct DistantNeighbor *referee_tail; | 182 | struct DirectNeighbor *next_hop; |
306 | 183 | ||
307 | /** | 184 | /** |
308 | * The sending context for gossiping peers to this neighbor. | 185 | * What would be the target, and how far is it away? |
309 | */ | 186 | */ |
310 | struct NeighborSendContext *send_context; | 187 | struct Target target; |
311 | 188 | ||
312 | /** | 189 | /** |
313 | * Is this one of the direct neighbors that we are "hiding" | 190 | * Offset of this target in the respective consensus set. |
314 | * from DV? | ||
315 | */ | 191 | */ |
316 | int hidden; | 192 | unsigned int set_offset; |
317 | 193 | ||
318 | /** | ||
319 | * Save messages immediately from this direct neighbor from a | ||
320 | * distan peer we don't know on the chance that it will be | ||
321 | * gossiped about and we can deliver the message. | ||
322 | */ | ||
323 | struct UnknownSenderMessage pending_messages[MAX_OUTSTANDING_MESSAGES]; | ||
324 | }; | 194 | }; |
325 | 195 | ||
326 | 196 | ||
327 | /** | 197 | /** |
328 | * Struct where actual neighbor information is stored, | 198 | * Routing neighbors are neighbors that we exchange |
329 | * referenced by min_heap and max_heap. Freeing dealt | 199 | * routing information with; that is, their distance |
330 | * with when items removed from hashmap. | 200 | * must be strictly less than the DEFAULT_FISHEYE_DEPTH; |
201 | * they can also be direct neighbors. | ||
331 | */ | 202 | */ |
332 | struct DistantNeighbor | 203 | struct RoutingNeighbor |
333 | { | 204 | { |
334 | /** | ||
335 | * We keep distant neighbor's of the same referrer in a DLL. | ||
336 | */ | ||
337 | struct DistantNeighbor *next; | ||
338 | 205 | ||
339 | /** | 206 | /** |
340 | * We keep distant neighbor's of the same referrer in a DLL. | 207 | * Which peer is this, and how do we talk to it? |
341 | */ | 208 | */ |
342 | struct DistantNeighbor *prev; | 209 | struct Route route; |
343 | 210 | ||
344 | /** | 211 | /** |
345 | * Node in min heap | 212 | * Routing table of the neighbor, NULL if not yet established. |
346 | */ | 213 | */ |
347 | struct GNUNET_CONTAINER_HeapNode *min_loc; | 214 | struct GNUNET_CONTAINER_MultiHashMap *neighbor_table; |
348 | 215 | ||
349 | /** | 216 | /** |
350 | * Node in max heap | 217 | * Updated routing table of the neighbor, under construction, |
351 | */ | 218 | * NULL if we are not currently building it. |
352 | struct GNUNET_CONTAINER_HeapNode *max_loc; | 219 | */ |
220 | struct GNUNET_CONTAINER_MultiHashMap *neighbor_table_consensus; | ||
353 | 221 | ||
354 | /** | 222 | /** |
355 | * Identity of referrer (next hop towards 'neighbor'). | 223 | * Active consensus, if we are currently synchronizing the |
224 | * routing tables. | ||
356 | */ | 225 | */ |
357 | struct DirectNeighbor *referrer; | 226 | struct GNUNET_CONSENSUS_Handle *consensus; |
358 | 227 | ||
359 | /** | 228 | /** |
360 | * Identity of neighbor. | 229 | * At what offset are we, with respect to inserting our own routes |
230 | * into the consensus? | ||
361 | */ | 231 | */ |
362 | struct GNUNET_PeerIdentity identity; | 232 | unsigned int consensus_insertion_offset; |
363 | 233 | ||
364 | /** | 234 | /** |
365 | * PublicKey of neighbor. | 235 | * At what distance are we, with respect to inserting our own routes |
236 | * into the consensus? | ||
366 | */ | 237 | */ |
367 | struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded *pkey; | 238 | unsigned int consensus_insertion_distance; |
368 | |||
369 | /** | ||
370 | * Last time we received routing information from this peer | ||
371 | */ | ||
372 | struct GNUNET_TIME_Absolute last_activity; | ||
373 | |||
374 | /** | ||
375 | * Last time we sent routing information about this peer | ||
376 | */ | ||
377 | struct GNUNET_TIME_Absolute last_gossip; | ||
378 | |||
379 | /** | ||
380 | * Cost to neighbor, used for actual distance vector computations | ||
381 | */ | ||
382 | unsigned int cost; | ||
383 | |||
384 | /** | ||
385 | * Random identifier *we* use for this peer, to be used as shortcut | ||
386 | * instead of sending full peer id for each message | ||
387 | */ | ||
388 | unsigned int our_id; | ||
389 | |||
390 | /** | ||
391 | * Random identifier the *referrer* uses for this peer. | ||
392 | */ | ||
393 | unsigned int referrer_id; | ||
394 | |||
395 | /** | ||
396 | * Is this one of the direct neighbors that we are "hiding" | ||
397 | * from DV? | ||
398 | */ | ||
399 | int hidden; | ||
400 | 239 | ||
401 | }; | 240 | }; |
402 | 241 | ||
403 | struct PeerIteratorContext | ||
404 | { | ||
405 | /** | ||
406 | * The actual context, to be freed later. | ||
407 | */ | ||
408 | struct GNUNET_PEERINFO_IteratorContext *ic; | ||
409 | |||
410 | /** | ||
411 | * The neighbor about which we are concerned. | ||
412 | */ | ||
413 | struct DirectNeighbor *neighbor; | ||
414 | |||
415 | /** | ||
416 | * The distant neighbor entry for this direct neighbor. | ||
417 | */ | ||
418 | struct DistantNeighbor *distant; | ||
419 | |||
420 | }; | ||
421 | 242 | ||
422 | /** | 243 | /** |
423 | * Context used for creating hello messages when | 244 | * Set of targets we bring to a consensus; all targets in a set have a |
424 | * gossips are received. | 245 | * distance equal to the sets distance (which is implied by the array |
246 | * index of the set). | ||
425 | */ | 247 | */ |
426 | struct HelloContext | 248 | struct ConsensusSet |
427 | { | 249 | { |
428 | /** | ||
429 | * Identity of distant neighbor. | ||
430 | */ | ||
431 | struct GNUNET_PeerIdentity distant_peer; | ||
432 | 250 | ||
433 | /** | 251 | /** |
434 | * Identity of direct neighbor, via which we send this message. | 252 | * Array of targets in the set, may include NULL |
253 | * entries if a neighbor has disconnected; the | ||
254 | * targets are allocated with the respective | ||
255 | * 'struct Route', not here. | ||
435 | */ | 256 | */ |
436 | const struct GNUNET_PeerIdentity *direct_peer; | 257 | struct Target **targets; |
437 | 258 | ||
438 | /** | 259 | /** |
439 | * How many addresses do we need to add (always starts at 1, then set to 0) | 260 | * Size of the 'targets' array. |
440 | */ | 261 | */ |
441 | int addresses_to_add; | 262 | unsigned int array_length; |
442 | 263 | ||
443 | }; | 264 | }; |
444 | 265 | ||
445 | struct DV_SendContext | ||
446 | { | ||
447 | /** | ||
448 | * The distant peer (should always match) | ||
449 | */ | ||
450 | struct GNUNET_PeerIdentity *distant_peer; | ||
451 | |||
452 | /** | ||
453 | * The direct peer, we need to verify the referrer of. | ||
454 | */ | ||
455 | struct GNUNET_PeerIdentity *direct_peer; | ||
456 | |||
457 | /** | ||
458 | * The message to be sent | ||
459 | */ | ||
460 | struct GNUNET_MessageHeader *message; | ||
461 | 266 | ||
462 | /** | 267 | /** |
463 | * The pre-built send result message. Simply needs to be queued | 268 | * Hashmap of all of our direct neighbors (no DV routing). |
464 | * and freed once send has been called! | 269 | */ |
465 | */ | 270 | static struct GNUNET_CONTAINER_MultiHashMap *direct_neighbors; |
466 | struct GNUNET_DV_SendResultMessage *send_result; | ||
467 | |||
468 | /** | ||
469 | * The size of the message being sent, may be larger | ||
470 | * than message->header.size because it's multiple | ||
471 | * messages packed into one! | ||
472 | */ | ||
473 | size_t message_size; | ||
474 | |||
475 | /** | ||
476 | * How important is this message? | ||
477 | */ | ||
478 | unsigned int importance; | ||
479 | |||
480 | /** | ||
481 | * Timeout for this message | ||
482 | */ | ||
483 | struct GNUNET_TIME_Relative timeout; | ||
484 | |||
485 | /** | ||
486 | * Unique ID for DV message | ||
487 | */ | ||
488 | unsigned int uid; | ||
489 | }; | ||
490 | |||
491 | struct FindDestinationContext | ||
492 | { | ||
493 | unsigned int tid; | ||
494 | struct DistantNeighbor *dest; | ||
495 | }; | ||
496 | |||
497 | struct FindIDContext | ||
498 | { | ||
499 | unsigned int tid; | ||
500 | struct GNUNET_PeerIdentity *dest; | ||
501 | const struct GNUNET_PeerIdentity *via; | ||
502 | }; | ||
503 | |||
504 | struct DisconnectContext | ||
505 | { | ||
506 | /** | ||
507 | * Distant neighbor to get pid from. | ||
508 | */ | ||
509 | struct DistantNeighbor *distant; | ||
510 | |||
511 | /** | ||
512 | * Direct neighbor that disconnected. | ||
513 | */ | ||
514 | struct DirectNeighbor *direct; | ||
515 | }; | ||
516 | |||
517 | struct TokenizedMessageContext | ||
518 | { | ||
519 | /** | ||
520 | * Immediate sender of this message | ||
521 | */ | ||
522 | const struct GNUNET_PeerIdentity *peer; | ||
523 | 271 | ||
524 | /** | 272 | /** |
525 | * Distant sender of the message | 273 | * Hashmap of all of the neighbors we exchange routing information |
526 | */ | 274 | * with (peers up to DEFAULT_FISHEYE_DEPTH - 1 distance from us). |
527 | struct DistantNeighbor *distant; | 275 | */ |
276 | static struct GNUNET_CONTAINER_MultiHashMap *routing_neighbors; | ||
528 | 277 | ||
529 | /** | 278 | /** |
530 | * Uid for this set of messages | 279 | * Hashmap with all routes that we currently support; contains |
531 | */ | 280 | * routing information for all peers up to distance DEFAULT_FISHEYE_DEPTH. |
532 | uint32_t uid; | 281 | */ |
533 | }; | 282 | static struct GNUNET_CONTAINER_MultiHashMap *all_routes; |
534 | 283 | ||
535 | /** | 284 | /** |
536 | * Context for finding the least cost peer to send to. | 285 | * Array of consensus sets we expose to the outside world. Sets |
537 | * Transport selection can only go so far. | 286 | * are structured by the distance to the target. |
538 | */ | 287 | */ |
539 | struct FindLeastCostContext | 288 | static struct ConsensusSet consensi[DEFAULT_FISHEYE_DEPTH - 1]; |
540 | { | ||
541 | struct DistantNeighbor *target; | ||
542 | unsigned int least_cost; | ||
543 | }; | ||
544 | 289 | ||
545 | /** | 290 | /** |
546 | * Handle to the core service api. | 291 | * ID of the task we use to (periodically) update our consensus |
292 | * with other peers. | ||
547 | */ | 293 | */ |
548 | static struct GNUNET_CORE_Handle *coreAPI; | 294 | static GNUNET_SCHEDULER_Task consensus_task; |
549 | 295 | ||
550 | /** | 296 | /** |
551 | * Stream tokenizer to handle messages coming in from core. | 297 | * Handle to the core service api. |
552 | */ | 298 | */ |
553 | static struct GNUNET_SERVER_MessageStreamTokenizer *coreMST; | 299 | static struct GNUNET_CORE_Handle *core_api; |
554 | 300 | ||
555 | /** | 301 | /** |
556 | * The identity of our peer. | 302 | * The identity of our peer. |
@@ -562,7 +308,6 @@ static struct GNUNET_PeerIdentity my_identity; | |||
562 | */ | 308 | */ |
563 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 309 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
564 | 310 | ||
565 | |||
566 | /** | 311 | /** |
567 | * The client, the DV plugin connected to us. Hopefully | 312 | * The client, the DV plugin connected to us. Hopefully |
568 | * this client will never change, although if the plugin dies | 313 | * this client will never change, although if the plugin dies |
@@ -571,15 +316,6 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg; | |||
571 | static struct GNUNET_SERVER_Client *client_handle; | 316 | static struct GNUNET_SERVER_Client *client_handle; |
572 | 317 | ||
573 | /** | 318 | /** |
574 | * Task to run when we shut down, cleaning up all our trash | ||
575 | */ | ||
576 | static GNUNET_SCHEDULER_TaskIdentifier cleanup_task; | ||
577 | |||
578 | static size_t default_dv_priority = 0; | ||
579 | |||
580 | static char *my_short_id; | ||
581 | |||
582 | /** | ||
583 | * Transmit handle to the plugin. | 319 | * Transmit handle to the plugin. |
584 | */ | 320 | */ |
585 | static struct GNUNET_SERVER_TransmitHandle *plugin_transmit_handle; | 321 | static struct GNUNET_SERVER_TransmitHandle *plugin_transmit_handle; |
@@ -595,53 +331,6 @@ static struct PendingMessage *plugin_pending_head; | |||
595 | static struct PendingMessage *plugin_pending_tail; | 331 | static struct PendingMessage *plugin_pending_tail; |
596 | 332 | ||
597 | /** | 333 | /** |
598 | * Handle to the peerinfo service | ||
599 | */ | ||
600 | static struct GNUNET_PEERINFO_Handle *peerinfo_handle; | ||
601 | |||
602 | /** | ||
603 | * Transmit handle to core service. | ||
604 | */ | ||
605 | static struct GNUNET_CORE_TransmitHandle *core_transmit_handle; | ||
606 | |||
607 | /** | ||
608 | * Head of DLL for core messages | ||
609 | */ | ||
610 | static struct PendingMessage *core_pending_head; | ||
611 | |||
612 | /** | ||
613 | * Tail of DLL for core messages | ||
614 | */ | ||
615 | static struct PendingMessage *core_pending_tail; | ||
616 | |||
617 | /** | ||
618 | * Map of PeerIdentifiers to 'struct GNUNET_dv_neighbor*'s for all | ||
619 | * directly connected peers. | ||
620 | */ | ||
621 | static struct GNUNET_CONTAINER_MultiHashMap *direct_neighbors; | ||
622 | |||
623 | /** | ||
624 | * Map of PeerIdentifiers to 'struct GNUNET_dv_neighbor*'s for | ||
625 | * peers connected via DV (extended neighborhood). Does ALSO | ||
626 | * include any peers that are in 'direct_neighbors'; for those | ||
627 | * peers, the cost will be zero and the referrer all zeros. | ||
628 | */ | ||
629 | static struct GNUNET_CONTAINER_MultiHashMap *extended_neighbors; | ||
630 | |||
631 | /** | ||
632 | * We use the min heap (min refers to cost) to prefer | ||
633 | * gossipping about peers with small costs. | ||
634 | */ | ||
635 | static struct GNUNET_CONTAINER_Heap *neighbor_min_heap; | ||
636 | |||
637 | /** | ||
638 | * We use the max heap (max refers to cost) for general | ||
639 | * iterations over all peers and to remove the most costly | ||
640 | * connection if we have too many. | ||
641 | */ | ||
642 | static struct GNUNET_CONTAINER_Heap *neighbor_max_heap; | ||
643 | |||
644 | /** | ||
645 | * Handle for the statistics service. | 334 | * Handle for the statistics service. |
646 | */ | 335 | */ |
647 | struct GNUNET_STATISTICS_Handle *stats; | 336 | struct GNUNET_STATISTICS_Handle *stats; |
@@ -651,71 +340,27 @@ struct GNUNET_STATISTICS_Handle *stats; | |||
651 | */ | 340 | */ |
652 | static unsigned long long fisheye_depth; | 341 | static unsigned long long fisheye_depth; |
653 | 342 | ||
654 | /** | ||
655 | * How many peers to store at most. | ||
656 | */ | ||
657 | static unsigned long long max_table_size; | ||
658 | |||
659 | /** | ||
660 | * We've been given a target ID based on the random numbers that | ||
661 | * we assigned to our DV-neighborhood. Find the entry for the | ||
662 | * respective neighbor. | ||
663 | */ | ||
664 | static int | ||
665 | find_destination (void *cls, struct GNUNET_CONTAINER_HeapNode *node, | ||
666 | void *element, GNUNET_CONTAINER_HeapCostType cost) | ||
667 | { | ||
668 | struct FindDestinationContext *fdc = cls; | ||
669 | struct DistantNeighbor *dn = element; | ||
670 | |||
671 | if (fdc->tid != dn->our_id) | ||
672 | return GNUNET_YES; | ||
673 | fdc->dest = dn; | ||
674 | return GNUNET_NO; | ||
675 | } | ||
676 | |||
677 | 343 | ||
678 | /** | 344 | /** |
679 | * We've been given a target ID based on the random numbers that | 345 | * Get distance information from 'atsi'. |
680 | * we assigned to our DV-neighborhood. Find the entry for the | 346 | * |
681 | * respective neighbor. | 347 | * @param atsi performance data |
348 | * @param atsi_count number of entries in atsi | ||
349 | * @return connected transport distance | ||
682 | */ | 350 | */ |
683 | static int | 351 | static uint32_t |
684 | find_specific_id (void *cls, const struct GNUNET_HashCode * key, void *value) | 352 | get_atsi_distance (const struct GNUNET_ATS_Information *atsi, |
353 | unsigned int atsi_count) | ||
685 | { | 354 | { |
686 | struct FindIDContext *fdc = cls; | 355 | unsigned int i; |
687 | struct DistantNeighbor *dn = value; | ||
688 | 356 | ||
689 | if (memcmp | 357 | for (i = 0; i < atsi_count; i++) |
690 | (&dn->referrer->identity, fdc->via, | 358 | if (ntohl (atsi[i].type) == GNUNET_ATS_QUALITY_NET_DISTANCE) |
691 | sizeof (struct GNUNET_PeerIdentity)) == 0) | 359 | return ntohl (atsi->value); |
692 | { | 360 | /* FIXME: we do not have distance data? Assume direct neighbor. */ |
693 | fdc->tid = dn->referrer_id; | 361 | return DIRECT_NEIGHBOR_COST; |
694 | return GNUNET_NO; | ||
695 | } | ||
696 | return GNUNET_YES; | ||
697 | } | 362 | } |
698 | 363 | ||
699 | /** | ||
700 | * Find a distant peer whose referrer_id matches what we're | ||
701 | * looking for. For looking up a peer we've gossipped about | ||
702 | * but is now disconnected. Need to do this because we don't | ||
703 | * want to remove those that may be accessible via a different | ||
704 | * route. | ||
705 | */ | ||
706 | static int | ||
707 | find_distant_peer (void *cls, const struct GNUNET_HashCode * key, void *value) | ||
708 | { | ||
709 | struct FindDestinationContext *fdc = cls; | ||
710 | struct DistantNeighbor *distant = value; | ||
711 | |||
712 | if (fdc->tid == distant->referrer_id) | ||
713 | { | ||
714 | fdc->dest = distant; | ||
715 | return GNUNET_NO; | ||
716 | } | ||
717 | return GNUNET_YES; | ||
718 | } | ||
719 | 364 | ||
720 | /** | 365 | /** |
721 | * Function called to notify a client about the socket | 366 | * Function called to notify a client about the socket |
@@ -728,7 +373,7 @@ find_distant_peer (void *cls, const struct GNUNET_HashCode * key, void *value) | |||
728 | * @param buf where the callee should write the message | 373 | * @param buf where the callee should write the message |
729 | * @return number of bytes written to buf | 374 | * @return number of bytes written to buf |
730 | */ | 375 | */ |
731 | size_t | 376 | static size_t |
732 | transmit_to_plugin (void *cls, size_t size, void *buf) | 377 | transmit_to_plugin (void *cls, size_t size, void *buf) |
733 | { | 378 | { |
734 | char *cbuf = buf; | 379 | char *cbuf = buf; |
@@ -736,20 +381,15 @@ transmit_to_plugin (void *cls, size_t size, void *buf) | |||
736 | size_t off; | 381 | size_t off; |
737 | size_t msize; | 382 | size_t msize; |
738 | 383 | ||
739 | if (buf == NULL) | 384 | plugin_transmit_handle = NULL; |
385 | if (NULL == buf) | ||
740 | { | 386 | { |
741 | /* client disconnected */ | 387 | /* client disconnected */ |
742 | #if DEBUG_DV_MESSAGES | ||
743 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
744 | "%s: %s buffer was NULL (client disconnect?)\n", my_short_id, | ||
745 | "transmit_to_plugin"); | ||
746 | #endif | ||
747 | return 0; | 388 | return 0; |
748 | } | 389 | } |
749 | plugin_transmit_handle = NULL; | ||
750 | off = 0; | 390 | off = 0; |
751 | while ((NULL != (reply = plugin_pending_head)) && | 391 | while ( (NULL != (reply = plugin_pending_head)) && |
752 | (size >= off + (msize = ntohs (reply->msg->size)))) | 392 | (size >= off + (msize = ntohs (reply->msg->size)))) |
753 | { | 393 | { |
754 | GNUNET_CONTAINER_DLL_remove (plugin_pending_head, plugin_pending_tail, | 394 | GNUNET_CONTAINER_DLL_remove (plugin_pending_head, plugin_pending_tail, |
755 | reply); | 395 | reply); |
@@ -757,219 +397,169 @@ transmit_to_plugin (void *cls, size_t size, void *buf) | |||
757 | GNUNET_free (reply); | 397 | GNUNET_free (reply); |
758 | off += msize; | 398 | off += msize; |
759 | } | 399 | } |
760 | 400 | if (NULL != plugin_pending_head) | |
761 | if (plugin_pending_head != NULL) | ||
762 | plugin_transmit_handle = | 401 | plugin_transmit_handle = |
763 | GNUNET_SERVER_notify_transmit_ready (client_handle, | 402 | GNUNET_SERVER_notify_transmit_ready (client_handle, |
764 | ntohs (plugin_pending_head->msg-> | 403 | msize, |
765 | size), | 404 | GNUNET_TIME_UNIT_FOREVER_REL, |
766 | GNUNET_TIME_UNIT_FOREVER_REL, | 405 | &transmit_to_plugin, NULL); |
767 | &transmit_to_plugin, NULL); | ||
768 | |||
769 | return off; | 406 | return off; |
770 | } | 407 | } |
771 | 408 | ||
409 | |||
772 | /** | 410 | /** |
773 | * Send a message to the dv plugin. | 411 | * Forward a message from another peer to the plugin. |
774 | * | 412 | * |
775 | * @param sender the direct sender of the message | ||
776 | * @param message the message to send to the plugin | 413 | * @param message the message to send to the plugin |
777 | * (may be an encapsulated type) | ||
778 | * @param message_size the size of the message to be sent | ||
779 | * @param distant_neighbor the original sender of the message | 414 | * @param distant_neighbor the original sender of the message |
780 | * @param cost the cost to the original sender of the message | 415 | * @param distnace distance to the original sender of the message |
781 | */ | 416 | */ |
782 | void | 417 | static void |
783 | send_to_plugin (const struct GNUNET_PeerIdentity *sender, | 418 | send_data_to_plugin (const struct GNUNET_MessageHeader *message, |
784 | const struct GNUNET_MessageHeader *message, size_t message_size, | 419 | struct GNUNET_PeerIdentity *distant_neighbor, |
785 | struct GNUNET_PeerIdentity *distant_neighbor, size_t cost) | 420 | uint32_t distance) |
786 | { | 421 | { |
787 | struct GNUNET_DV_MessageReceived *received_msg; | 422 | struct GNUNET_DV_ReceivedMessage *received_msg; |
788 | struct PendingMessage *pending_message; | 423 | struct PendingMessage *pending_message; |
789 | char *sender_address; | 424 | size_t size; |
790 | size_t sender_address_len; | ||
791 | char *packed_msg_start; | ||
792 | int size; | ||
793 | |||
794 | #if DEBUG_DV | ||
795 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
796 | "send_to_plugin called with peer %s as sender\n", | ||
797 | GNUNET_i2s (distant_neighbor)); | ||
798 | #endif | ||
799 | 425 | ||
800 | if (memcmp (sender, distant_neighbor, sizeof (struct GNUNET_PeerIdentity)) != | 426 | if (NULL == client_handle) |
801 | 0) | ||
802 | { | 427 | { |
803 | sender_address_len = sizeof (struct GNUNET_PeerIdentity) * 2; | 428 | GNUNET_STATISTICS_update (stats, |
804 | sender_address = GNUNET_malloc (sender_address_len); | 429 | "# messages discarded (no plugin)", |
805 | memcpy (sender_address, distant_neighbor, | 430 | 1, GNUNET_NO); |
806 | sizeof (struct GNUNET_PeerIdentity)); | 431 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
807 | memcpy (&sender_address[sizeof (struct GNUNET_PeerIdentity)], sender, | 432 | _("Refusing to queue messages, DV plugin not active.\n")); |
808 | sizeof (struct GNUNET_PeerIdentity)); | 433 | return; |
809 | } | 434 | } |
810 | else | 435 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
811 | { | 436 | "Delivering message from peer `%s'\n", |
812 | sender_address_len = sizeof (struct GNUNET_PeerIdentity); | 437 | GNUNET_i2s (distant_neighbor)); |
813 | sender_address = GNUNET_malloc (sender_address_len); | 438 | size = sizeof (struct GNUNET_DV_ReceivedMessage) + |
814 | memcpy (sender_address, sender, sizeof (struct GNUNET_PeerIdentity)); | 439 | ntohs (message->size); |
440 | if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
441 | { | ||
442 | GNUNET_break (0); /* too big */ | ||
443 | return; | ||
815 | } | 444 | } |
816 | |||
817 | size = | ||
818 | sizeof (struct GNUNET_DV_MessageReceived) + sender_address_len + | ||
819 | message_size; | ||
820 | received_msg = GNUNET_malloc (size); | ||
821 | received_msg->header.size = htons (size); | ||
822 | received_msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_RECEIVE); | ||
823 | received_msg->distance = htonl (cost); | ||
824 | received_msg->msg_len = htonl (message_size); | ||
825 | /* Set the sender in this message to be the original sender! */ | ||
826 | memcpy (&received_msg->sender, distant_neighbor, | ||
827 | sizeof (struct GNUNET_PeerIdentity)); | ||
828 | /* Copy the intermediate sender to the end of the message, this is how the transport identifies this peer */ | ||
829 | memcpy (&received_msg[1], sender_address, sender_address_len); | ||
830 | GNUNET_free (sender_address); | ||
831 | /* Copy the actual message after the sender */ | ||
832 | packed_msg_start = (char *) &received_msg[1]; | ||
833 | packed_msg_start = &packed_msg_start[sender_address_len]; | ||
834 | memcpy (packed_msg_start, message, message_size); | ||
835 | pending_message = GNUNET_malloc (sizeof (struct PendingMessage) + size); | 445 | pending_message = GNUNET_malloc (sizeof (struct PendingMessage) + size); |
836 | pending_message->msg = (struct GNUNET_MessageHeader *) &pending_message[1]; | 446 | received_msg = (struct GNUNET_DV_ReceivedMessage *) &pending_message[1]; |
837 | memcpy (&pending_message[1], received_msg, size); | 447 | received_msg->header.size = htons (size); |
838 | GNUNET_free (received_msg); | 448 | received_msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_RECV); |
839 | 449 | received_msg->distance = htonl (distance); | |
840 | GNUNET_CONTAINER_DLL_insert_after (plugin_pending_head, plugin_pending_tail, | 450 | received_msg->sender = *distant_neighbor; |
841 | plugin_pending_tail, pending_message); | 451 | memcpy (&received_msg[1], message, ntohs (message->size)); |
842 | 452 | GNUNET_CONTAINER_DLL_insert_tail (plugin_pending_head, | |
843 | if (client_handle != NULL) | 453 | plugin_pending_tail, |
844 | { | 454 | pending_message); |
845 | if (plugin_transmit_handle == NULL) | 455 | if (NULL == plugin_transmit_handle) |
846 | { | 456 | plugin_transmit_handle = |
847 | plugin_transmit_handle = | 457 | GNUNET_SERVER_notify_transmit_ready (client_handle, size, |
848 | GNUNET_SERVER_notify_transmit_ready (client_handle, size, | 458 | GNUNET_TIME_UNIT_FOREVER_REL, |
849 | GNUNET_TIME_UNIT_FOREVER_REL, | 459 | &transmit_to_plugin, NULL); |
850 | &transmit_to_plugin, NULL); | ||
851 | } | ||
852 | } | ||
853 | else | ||
854 | { | ||
855 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
856 | "Failed to queue message for plugin, client_handle not yet set (how?)!\n"); | ||
857 | } | ||
858 | } | 460 | } |
859 | 461 | ||
860 | /* Declare here so retry_core_send is aware of it */ | ||
861 | size_t | ||
862 | core_transmit_notify (void *cls, size_t size, void *buf); | ||
863 | 462 | ||
864 | /** | 463 | /** |
865 | * Try to send another message from our core sending list | 464 | * Give an ACK message to the plugin, we transmitted a message for it. |
465 | * | ||
466 | * @param target peer that received the message | ||
467 | * @param uid plugin-chosen UID for the message | ||
866 | */ | 468 | */ |
867 | static void | 469 | static void |
868 | try_core_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 470 | send_ack_to_plugin (struct GNUNET_PeerIdentity *target, |
471 | uint32_t uid) | ||
869 | { | 472 | { |
870 | struct PendingMessage *pending; | 473 | struct GNUNET_DV_AckMessage *ack_msg; |
871 | 474 | struct PendingMessage *pending_message; | |
872 | pending = core_pending_head; | 475 | size_t size; |
873 | |||
874 | if (core_transmit_handle != NULL) | ||
875 | return; /* Message send already in progress */ | ||
876 | 476 | ||
877 | if ((pending != NULL) && (coreAPI != NULL)) | 477 | if (NULL == client_handle) |
878 | core_transmit_handle = | 478 | { |
879 | GNUNET_CORE_notify_transmit_ready (coreAPI, GNUNET_YES, | 479 | GNUNET_STATISTICS_update (stats, |
880 | pending->importance, | 480 | "# acks discarded (no plugin)", |
881 | pending->timeout, | 481 | 1, GNUNET_NO); |
882 | &pending->recipient, | 482 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
883 | pending->msg_size, | 483 | _("Refusing to queue messages, DV plugin not active.\n")); |
884 | &core_transmit_notify, NULL); | 484 | return; |
485 | } | ||
486 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
487 | "Delivering ACK for message to peer `%s'\n", | ||
488 | GNUNET_i2s (target)); | ||
489 | size = sizeof (struct GNUNET_DV_AckMessage); | ||
490 | pending_message = GNUNET_malloc (sizeof (struct PendingMessage) + size); | ||
491 | ack_msg = (struct GNUNET_DV_AckMessage *) &pending_message[1]; | ||
492 | ack_msg->header.size = htons (size); | ||
493 | ack_msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND_ACK); | ||
494 | ack_msg->uid = htonl (uid); | ||
495 | ack_msg->target = *target; | ||
496 | GNUNET_CONTAINER_DLL_insert_tail (plugin_pending_head, | ||
497 | plugin_pending_tail, | ||
498 | pending_message); | ||
499 | if (NULL == plugin_transmit_handle) | ||
500 | plugin_transmit_handle = | ||
501 | GNUNET_SERVER_notify_transmit_ready (client_handle, size, | ||
502 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
503 | &transmit_to_plugin, NULL); | ||
885 | } | 504 | } |
886 | 505 | ||
887 | 506 | ||
888 | /** | 507 | /** |
889 | * Function called to notify a client about the socket | 508 | * Function called to transfer a message to another peer |
890 | * being ready to queue more data. "buf" will be | 509 | * via core. |
891 | * NULL and "size" zero if the socket was closed for | ||
892 | * writing in the meantime. | ||
893 | * | 510 | * |
894 | * @param cls closure (NULL) | 511 | * @param cls closure with the direct neighbor |
895 | * @param size number of bytes available in buf | 512 | * @param size number of bytes available in buf |
896 | * @param buf where the callee should write the message | 513 | * @param buf where the callee should write the message |
897 | * @return number of bytes written to buf | 514 | * @return number of bytes written to buf |
898 | */ | 515 | */ |
899 | size_t | 516 | static size_t |
900 | core_transmit_notify (void *cls, size_t size, void *buf) | 517 | core_transmit_notify (void *cls, size_t size, void *buf) |
901 | { | 518 | { |
519 | struct DirectNeighbor *dn = cls; | ||
902 | char *cbuf = buf; | 520 | char *cbuf = buf; |
903 | struct PendingMessage *pending; | 521 | struct PendingMessage *pending; |
904 | struct PendingMessage *client_reply; | ||
905 | size_t off; | 522 | size_t off; |
906 | size_t msize; | 523 | size_t msize; |
907 | 524 | ||
908 | if (buf == NULL) | 525 | dn->cth = NULL; |
526 | if (NULL == buf) | ||
909 | { | 527 | { |
910 | /* client disconnected */ | 528 | /* peer disconnected */ |
911 | #if DEBUG_DV | ||
912 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s': buffer was NULL\n", "DHT"); | ||
913 | #endif | ||
914 | return 0; | 529 | return 0; |
915 | } | 530 | } |
916 | |||
917 | core_transmit_handle = NULL; | ||
918 | off = 0; | 531 | off = 0; |
919 | pending = core_pending_head; | 532 | pending = dn->pm_head; |
920 | if ((pending != NULL) && (size >= (msize = ntohs (pending->msg->size)))) | 533 | off = 0; |
534 | while ( (NULL != (pending = dn->pm_head)) && | ||
535 | (size >= off + (msize = ntohs (pending->msg->size)))) | ||
921 | { | 536 | { |
922 | #if DEBUG_DV | 537 | GNUNET_CONTAINER_DLL_remove (dn->pm_head, |
923 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 538 | dn->pm_tail, |
924 | "`%s' : transmit_notify (core) called with size %d\n", | 539 | pending); |
925 | "dv service", msize); | ||
926 | #endif | ||
927 | GNUNET_CONTAINER_DLL_remove (core_pending_head, core_pending_tail, pending); | ||
928 | if (pending->send_result != NULL) /* Will only be non-null if a real client asked for this send */ | ||
929 | { | ||
930 | client_reply = | ||
931 | GNUNET_malloc (sizeof (struct PendingMessage) + | ||
932 | sizeof (struct GNUNET_DV_SendResultMessage)); | ||
933 | client_reply->msg = (struct GNUNET_MessageHeader *) &client_reply[1]; | ||
934 | memcpy (&client_reply[1], pending->send_result, | ||
935 | sizeof (struct GNUNET_DV_SendResultMessage)); | ||
936 | GNUNET_free (pending->send_result); | ||
937 | |||
938 | GNUNET_CONTAINER_DLL_insert_after (plugin_pending_head, | ||
939 | plugin_pending_tail, | ||
940 | plugin_pending_tail, client_reply); | ||
941 | if (client_handle != NULL) | ||
942 | { | ||
943 | if (plugin_transmit_handle == NULL) | ||
944 | { | ||
945 | plugin_transmit_handle = | ||
946 | GNUNET_SERVER_notify_transmit_ready (client_handle, | ||
947 | sizeof (struct | ||
948 | GNUNET_DV_SendResultMessage), | ||
949 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
950 | &transmit_to_plugin, NULL); | ||
951 | } | ||
952 | else | ||
953 | { | ||
954 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
955 | "Failed to queue message for plugin, must be one in progress already!!\n"); | ||
956 | } | ||
957 | } | ||
958 | } | ||
959 | memcpy (&cbuf[off], pending->msg, msize); | 540 | memcpy (&cbuf[off], pending->msg, msize); |
541 | send_ack_to_plugin (&pending->ultimate_target, | ||
542 | pending->uid); | ||
960 | GNUNET_free (pending); | 543 | GNUNET_free (pending); |
961 | off += msize; | 544 | off += msize; |
962 | } | 545 | } |
963 | /*reply = core_pending_head; */ | 546 | if (NULL != dn->pm_head) |
964 | 547 | dn->cth = | |
965 | GNUNET_SCHEDULER_add_now (&try_core_send, NULL); | 548 | GNUNET_CORE_notify_transmit_ready (core_api, |
966 | /*if (reply != NULL) | 549 | GNUNET_YES /* cork */, |
967 | * core_transmit_handle = GNUNET_CORE_notify_transmit_ready(coreAPI, GNUNET_YES, reply->importance, reply->timeout, &reply->recipient, reply->msg_size, &core_transmit_notify, NULL); */ | 550 | 0 /* priority */, |
968 | 551 | GNUNET_TIME_UNIT_FOREVER_REL, | |
552 | &dn->peer, | ||
553 | msize, | ||
554 | &core_transmit_notify, dn); | ||
969 | return off; | 555 | return off; |
970 | } | 556 | } |
971 | 557 | ||
972 | 558 | ||
559 | #if 0 | ||
560 | // //////////////////////////////////////////////////////////////////////// | ||
561 | |||
562 | |||
973 | /** | 563 | /** |
974 | * Send a DV data message via DV. | 564 | * Send a DV data message via DV. |
975 | * | 565 | * |
@@ -990,10 +580,6 @@ send_message_via (const struct GNUNET_PeerIdentity *sender, | |||
990 | struct PendingMessage *pending_message; | 580 | struct PendingMessage *pending_message; |
991 | struct FindIDContext find_context; | 581 | struct FindIDContext find_context; |
992 | 582 | ||
993 | #if DEBUG_DV | ||
994 | char shortname[5]; | ||
995 | #endif | ||
996 | |||
997 | msg_size = send_context->message_size + sizeof (p2p_dv_MESSAGE_Data); | 583 | msg_size = send_context->message_size + sizeof (p2p_dv_MESSAGE_Data); |
998 | 584 | ||
999 | find_context.dest = send_context->distant_peer; | 585 | find_context.dest = send_context->distant_peer; |
@@ -1342,26 +928,6 @@ send_message_delayed (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1342 | #endif | 928 | #endif |
1343 | 929 | ||
1344 | /** | 930 | /** |
1345 | * Get distance information from 'atsi'. | ||
1346 | * | ||
1347 | * @param atsi performance data | ||
1348 | * @param atsi_count number of entries in atsi | ||
1349 | * @return connected transport distance | ||
1350 | */ | ||
1351 | static uint32_t | ||
1352 | get_atsi_distance (const struct GNUNET_ATS_Information *atsi, | ||
1353 | unsigned int atsi_count) | ||
1354 | { | ||
1355 | unsigned int i; | ||
1356 | |||
1357 | for (i = 0; i < atsi_count; i++) | ||
1358 | if (ntohl (atsi[i].type) == GNUNET_ATS_QUALITY_NET_DISTANCE) | ||
1359 | return ntohl (atsi->value); | ||
1360 | /* FIXME: we do not have distance data? Assume direct neighbor. */ | ||
1361 | return DIRECT_NEIGHBOR_COST; | ||
1362 | } | ||
1363 | |||
1364 | /** | ||
1365 | * Find latency information in 'atsi'. | 931 | * Find latency information in 'atsi'. |
1366 | * | 932 | * |
1367 | * @param atsi performance data | 933 | * @param atsi performance data |
@@ -1383,271 +949,6 @@ get_atsi_latency (const struct GNUNET_ATS_Information *atsi, | |||
1383 | return GNUNET_TIME_UNIT_SECONDS; | 949 | return GNUNET_TIME_UNIT_SECONDS; |
1384 | } | 950 | } |
1385 | 951 | ||
1386 | /** | ||
1387 | * Core handler for dv data messages. Whatever this message | ||
1388 | * contains all we really have to do is rip it out of its | ||
1389 | * DV layering and give it to our pal the DV plugin to report | ||
1390 | * in with. | ||
1391 | * | ||
1392 | * @param cls closure | ||
1393 | * @param peer peer which sent the message (immediate sender) | ||
1394 | * @param message the message | ||
1395 | * @param atsi transport ATS information (latency, distance, etc.) | ||
1396 | * @param atsi_count number of entries in atsi | ||
1397 | */ | ||
1398 | static int | ||
1399 | handle_dv_data_message (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
1400 | const struct GNUNET_MessageHeader *message, | ||
1401 | const struct GNUNET_ATS_Information *atsi, | ||
1402 | unsigned int atsi_count) | ||
1403 | { | ||
1404 | const p2p_dv_MESSAGE_Data *incoming = (const p2p_dv_MESSAGE_Data *) message; | ||
1405 | const struct GNUNET_MessageHeader *packed_message; | ||
1406 | struct DirectNeighbor *dn; | ||
1407 | struct DistantNeighbor *pos; | ||
1408 | unsigned int sid; /* Sender id */ | ||
1409 | unsigned int tid; /* Target id */ | ||
1410 | struct GNUNET_PeerIdentity *original_sender; | ||
1411 | struct GNUNET_PeerIdentity *destination; | ||
1412 | struct FindDestinationContext fdc; | ||
1413 | struct TokenizedMessageContext tkm_ctx; | ||
1414 | int i; | ||
1415 | int found_pos; | ||
1416 | |||
1417 | #if DELAY_FORWARDS | ||
1418 | struct DelayedMessageContext *delayed_context; | ||
1419 | #endif | ||
1420 | #if USE_PEER_ID | ||
1421 | struct CheckPeerContext checkPeerCtx; | ||
1422 | #endif | ||
1423 | #if DEBUG_DV_MESSAGES | ||
1424 | char *sender_id; | ||
1425 | #endif | ||
1426 | int ret; | ||
1427 | size_t packed_message_size; | ||
1428 | char *cbuf; | ||
1429 | uint32_t distance; /* Distance information */ | ||
1430 | struct GNUNET_TIME_Relative latency; /* Latency information */ | ||
1431 | |||
1432 | packed_message_size = | ||
1433 | ntohs (incoming->header.size) - sizeof (p2p_dv_MESSAGE_Data); | ||
1434 | #if DEBUG_DV | ||
1435 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1436 | "%s: Receives DATA message from %s size %d, packed size %d!\n", | ||
1437 | my_short_id, GNUNET_i2s (peer), ntohs (incoming->header.size), | ||
1438 | packed_message_size); | ||
1439 | #endif | ||
1440 | |||
1441 | if (ntohs (incoming->header.size) < | ||
1442 | sizeof (p2p_dv_MESSAGE_Data) + sizeof (struct GNUNET_MessageHeader)) | ||
1443 | { | ||
1444 | #if DEBUG_DV | ||
1445 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1446 | "`%s': Message sizes don't add up, total size %u, expected at least %u!\n", | ||
1447 | "dv service", ntohs (incoming->header.size), | ||
1448 | sizeof (p2p_dv_MESSAGE_Data) + | ||
1449 | sizeof (struct GNUNET_MessageHeader)); | ||
1450 | #endif | ||
1451 | return GNUNET_SYSERR; | ||
1452 | } | ||
1453 | |||
1454 | /* Iterate over ATS_Information to get distance and latency */ | ||
1455 | latency = get_atsi_latency (atsi, atsi_count); | ||
1456 | distance = get_atsi_distance (atsi, atsi_count); | ||
1457 | dn = GNUNET_CONTAINER_multihashmap_get (direct_neighbors, &peer->hashPubKey); | ||
1458 | if (dn == NULL) | ||
1459 | return GNUNET_OK; | ||
1460 | |||
1461 | sid = ntohl (incoming->sender); | ||
1462 | #if USE_PEER_ID | ||
1463 | if (sid != 0) | ||
1464 | { | ||
1465 | checkPeerCtx.sender_id = sid; | ||
1466 | checkPeerCtx.peer = NULL; | ||
1467 | GNUNET_CONTAINER_multihashmap_iterate (extended_neighbors, &checkPeerID, | ||
1468 | &checkPeerCtx); | ||
1469 | pos = checkPeerCtx.peer; | ||
1470 | } | ||
1471 | else | ||
1472 | { | ||
1473 | pos = | ||
1474 | GNUNET_CONTAINER_multihashmap_get (extended_neighbors, | ||
1475 | &peer->hashPubKey); | ||
1476 | } | ||
1477 | #else | ||
1478 | pos = dn->referee_head; | ||
1479 | while ((NULL != pos) && (pos->referrer_id != sid)) | ||
1480 | pos = pos->next; | ||
1481 | #endif | ||
1482 | |||
1483 | if (pos == NULL) | ||
1484 | { | ||
1485 | #if DEBUG_DV_MESSAGES | ||
1486 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1487 | "%s: unknown sender (%u), Message uid %u from %s!\n", | ||
1488 | my_short_id, ntohl (incoming->sender), ntohl (incoming->uid), | ||
1489 | GNUNET_i2s (&dn->identity)); | ||
1490 | pos = dn->referee_head; | ||
1491 | while ((NULL != pos) && (pos->referrer_id != sid)) | ||
1492 | { | ||
1493 | sender_id = GNUNET_strdup (GNUNET_i2s (&pos->identity)); | ||
1494 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "I know sender %u %s\n", | ||
1495 | pos->referrer_id, sender_id); | ||
1496 | GNUNET_free (sender_id); | ||
1497 | pos = pos->next; | ||
1498 | } | ||
1499 | #endif | ||
1500 | |||
1501 | found_pos = -1; | ||
1502 | for (i = 0; i < MAX_OUTSTANDING_MESSAGES; i++) | ||
1503 | { | ||
1504 | if (dn->pending_messages[i].sender_id == 0) | ||
1505 | { | ||
1506 | found_pos = i; | ||
1507 | break; | ||
1508 | } | ||
1509 | } | ||
1510 | |||
1511 | if (found_pos == -1) | ||
1512 | { | ||
1513 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1514 | "%s: Too many unknown senders (%u), ignoring message! Message uid %llu from %s!\n", | ||
1515 | my_short_id, ntohl (incoming->sender), ntohl (incoming->uid), | ||
1516 | GNUNET_i2s (&dn->identity)); | ||
1517 | } | ||
1518 | else | ||
1519 | { | ||
1520 | dn->pending_messages[found_pos].message = | ||
1521 | GNUNET_malloc (ntohs (message->size)); | ||
1522 | memcpy (dn->pending_messages[found_pos].message, message, | ||
1523 | ntohs (message->size)); | ||
1524 | dn->pending_messages[found_pos].distance = distance; | ||
1525 | dn->pending_messages[found_pos].latency = latency; | ||
1526 | memcpy (&dn->pending_messages[found_pos].sender, peer, | ||
1527 | sizeof (struct GNUNET_PeerIdentity)); | ||
1528 | dn->pending_messages[found_pos].sender_id = sid; | ||
1529 | } | ||
1530 | /* unknown sender */ | ||
1531 | return GNUNET_OK; | ||
1532 | } | ||
1533 | original_sender = &pos->identity; | ||
1534 | tid = ntohl (incoming->recipient); | ||
1535 | if (tid == 0) | ||
1536 | { | ||
1537 | /* 0 == us */ | ||
1538 | cbuf = (char *) &incoming[1]; | ||
1539 | |||
1540 | tkm_ctx.peer = peer; | ||
1541 | tkm_ctx.distant = pos; | ||
1542 | tkm_ctx.uid = ntohl (incoming->uid); | ||
1543 | if (GNUNET_OK != | ||
1544 | GNUNET_SERVER_mst_receive (coreMST, &tkm_ctx, cbuf, packed_message_size, | ||
1545 | GNUNET_NO, GNUNET_NO)) | ||
1546 | { | ||
1547 | GNUNET_break_op (0); | ||
1548 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1549 | "%s: %s Received corrupt data, discarding!", my_short_id, | ||
1550 | "DV SERVICE"); | ||
1551 | } | ||
1552 | return GNUNET_OK; | ||
1553 | } | ||
1554 | else | ||
1555 | { | ||
1556 | packed_message = (struct GNUNET_MessageHeader *) &incoming[1]; | ||
1557 | } | ||
1558 | |||
1559 | /* FIXME: this is the *only* per-request operation we have in DV | ||
1560 | * that is O(n) in relation to the number of connected peers; a | ||
1561 | * hash-table lookup could easily solve this (minor performance | ||
1562 | * issue) */ | ||
1563 | fdc.tid = tid; | ||
1564 | fdc.dest = NULL; | ||
1565 | GNUNET_CONTAINER_heap_iterate (neighbor_max_heap, &find_destination, &fdc); | ||
1566 | |||
1567 | #if DEBUG_DV | ||
1568 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1569 | "%s: Receives %s message for someone else!\n", "dv", "DV DATA"); | ||
1570 | #endif | ||
1571 | |||
1572 | if (fdc.dest == NULL) | ||
1573 | { | ||
1574 | #if DEBUG_DV_MESSAGES | ||
1575 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1576 | "%s: Receives %s message uid %u for someone we don't know (id %u)!\n", | ||
1577 | my_short_id, "DV DATA", ntohl (incoming->uid), tid); | ||
1578 | #endif | ||
1579 | return GNUNET_OK; | ||
1580 | } | ||
1581 | destination = &fdc.dest->identity; | ||
1582 | |||
1583 | if (0 == memcmp (destination, peer, sizeof (struct GNUNET_PeerIdentity))) | ||
1584 | { | ||
1585 | /* FIXME: create stat: routing loop-discard! */ | ||
1586 | |||
1587 | #if DEBUG_DV_MESSAGES | ||
1588 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1589 | "%s: DROPPING MESSAGE uid %u type %d, routing loop! Message immediately from %s!\n", | ||
1590 | my_short_id, ntohl (incoming->uid), | ||
1591 | ntohs (packed_message->type), GNUNET_i2s (&dn->identity)); | ||
1592 | #endif | ||
1593 | return GNUNET_OK; | ||
1594 | } | ||
1595 | |||
1596 | /* At this point we have a message, and we need to forward it on to the | ||
1597 | * next DV hop. | ||
1598 | */ | ||
1599 | #if DEBUG_DV_MESSAGES | ||
1600 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1601 | "%s: FORWARD %s message for %s, uid %u, size %d type %d, cost %u!\n", | ||
1602 | my_short_id, "DV DATA", GNUNET_i2s (destination), | ||
1603 | ntohl (incoming->uid), ntohs (packed_message->size), | ||
1604 | ntohs (packed_message->type), pos->cost); | ||
1605 | #endif | ||
1606 | |||
1607 | #if DELAY_FORWARDS | ||
1608 | if (GNUNET_TIME_absolute_get_duration (pos->last_gossip).abs_value < | ||
1609 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2).abs_value) | ||
1610 | { | ||
1611 | delayed_context = GNUNET_malloc (sizeof (struct DelayedMessageContext)); | ||
1612 | memcpy (&delayed_context->dest, destination, | ||
1613 | sizeof (struct GNUNET_PeerIdentity)); | ||
1614 | memcpy (&delayed_context->sender, original_sender, | ||
1615 | sizeof (struct GNUNET_PeerIdentity)); | ||
1616 | delayed_context->message = GNUNET_malloc (packed_message_size); | ||
1617 | memcpy (delayed_context->message, packed_message, packed_message_size); | ||
1618 | delayed_context->message_size = packed_message_size; | ||
1619 | delayed_context->uid = ntohl (incoming->uid); | ||
1620 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | ||
1621 | (GNUNET_TIME_UNIT_MILLISECONDS, 2500), | ||
1622 | &send_message_delayed, delayed_context); | ||
1623 | return GNUNET_OK; | ||
1624 | } | ||
1625 | else | ||
1626 | #endif | ||
1627 | { | ||
1628 | ret = | ||
1629 | send_message (destination, original_sender, NULL, packed_message, | ||
1630 | packed_message_size, default_dv_priority, | ||
1631 | ntohl (incoming->uid), | ||
1632 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
1633 | } | ||
1634 | if (ret != GNUNET_SYSERR) | ||
1635 | return GNUNET_OK; | ||
1636 | else | ||
1637 | { | ||
1638 | #if DEBUG_MESSAGE_DROP | ||
1639 | char *direct_id = GNUNET_strdup (GNUNET_i2s (&dn->identity)); | ||
1640 | |||
1641 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1642 | "%s: DROPPING MESSAGE type %d, forwarding failed! Message immediately from %s!\n", | ||
1643 | GNUNET_i2s (&my_identity), | ||
1644 | ntohs (((struct GNUNET_MessageHeader *) &incoming[1])->type), | ||
1645 | direct_id); | ||
1646 | GNUNET_free (direct_id); | ||
1647 | #endif | ||
1648 | return GNUNET_SYSERR; | ||
1649 | } | ||
1650 | } | ||
1651 | 952 | ||
1652 | #if DEBUG_DV | 953 | #if DEBUG_DV |
1653 | /** | 954 | /** |
@@ -1812,29 +1113,6 @@ neighbor_send_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1812 | } | 1113 | } |
1813 | 1114 | ||
1814 | 1115 | ||
1815 | /** | ||
1816 | * Handle START-message. This is the first message sent to us | ||
1817 | * by the client (can only be one!). | ||
1818 | * | ||
1819 | * @param cls closure (always NULL) | ||
1820 | * @param client identification of the client | ||
1821 | * @param message the actual message | ||
1822 | */ | ||
1823 | static void | ||
1824 | handle_start (void *cls, struct GNUNET_SERVER_Client *client, | ||
1825 | const struct GNUNET_MessageHeader *message) | ||
1826 | { | ||
1827 | |||
1828 | #if DEBUG_DV | ||
1829 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' request from client\n", | ||
1830 | "START"); | ||
1831 | #endif | ||
1832 | |||
1833 | client_handle = client; | ||
1834 | |||
1835 | GNUNET_SERVER_client_keep (client_handle); | ||
1836 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
1837 | } | ||
1838 | 1116 | ||
1839 | #if UNSIMPLER | 1117 | #if UNSIMPLER |
1840 | /** | 1118 | /** |
@@ -1863,214 +1141,6 @@ send_iterator (void *cls, const struct GNUNET_HashCode * key, void *abs_value) | |||
1863 | } | 1141 | } |
1864 | #endif | 1142 | #endif |
1865 | 1143 | ||
1866 | /** | ||
1867 | * Service server's handler for message send requests (which come | ||
1868 | * bubbling up to us through the DV plugin). | ||
1869 | * | ||
1870 | * @param cls closure | ||
1871 | * @param client identification of the client | ||
1872 | * @param message the actual message | ||
1873 | */ | ||
1874 | void | ||
1875 | handle_dv_send_message (void *cls, struct GNUNET_SERVER_Client *client, | ||
1876 | const struct GNUNET_MessageHeader *message) | ||
1877 | { | ||
1878 | struct GNUNET_DV_SendMessage *send_msg; | ||
1879 | struct GNUNET_DV_SendResultMessage *send_result_msg; | ||
1880 | struct PendingMessage *pending_message; | ||
1881 | size_t address_len; | ||
1882 | size_t message_size; | ||
1883 | struct GNUNET_PeerIdentity *destination; | ||
1884 | struct GNUNET_PeerIdentity *direct; | ||
1885 | struct GNUNET_MessageHeader *message_buf; | ||
1886 | char *temp_pos; | ||
1887 | int offset; | ||
1888 | static struct GNUNET_CRYPTO_HashAsciiEncoded dest_hash; | ||
1889 | struct DV_SendContext *send_context; | ||
1890 | |||
1891 | #if DEBUG_DV_MESSAGES | ||
1892 | char *cbuf; | ||
1893 | struct GNUNET_MessageHeader *packed_message; | ||
1894 | #endif | ||
1895 | |||
1896 | if (client_handle == NULL) | ||
1897 | { | ||
1898 | client_handle = client; | ||
1899 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1900 | "%s: Setting initial client handle, never received `%s' message?\n", | ||
1901 | "dv", "START"); | ||
1902 | } | ||
1903 | else if (client_handle != client) | ||
1904 | { | ||
1905 | client_handle = client; | ||
1906 | /* What should we do in this case, assert fail or just log the warning? */ | ||
1907 | #if DEBUG_DV | ||
1908 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1909 | "%s: Setting client handle (was a different client!)!\n", "dv"); | ||
1910 | #endif | ||
1911 | } | ||
1912 | |||
1913 | GNUNET_assert (ntohs (message->size) > sizeof (struct GNUNET_DV_SendMessage)); | ||
1914 | send_msg = (struct GNUNET_DV_SendMessage *) message; | ||
1915 | |||
1916 | address_len = ntohl (send_msg->addrlen); | ||
1917 | GNUNET_assert (address_len == sizeof (struct GNUNET_PeerIdentity) * 2); | ||
1918 | message_size = | ||
1919 | ntohs (message->size) - sizeof (struct GNUNET_DV_SendMessage) - | ||
1920 | address_len; | ||
1921 | destination = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); | ||
1922 | direct = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); | ||
1923 | message_buf = GNUNET_malloc (message_size); | ||
1924 | |||
1925 | temp_pos = (char *) &send_msg[1]; /* Set pointer to end of message */ | ||
1926 | offset = 0; /* Offset starts at zero */ | ||
1927 | |||
1928 | memcpy (destination, &temp_pos[offset], sizeof (struct GNUNET_PeerIdentity)); | ||
1929 | offset += sizeof (struct GNUNET_PeerIdentity); | ||
1930 | |||
1931 | memcpy (direct, &temp_pos[offset], sizeof (struct GNUNET_PeerIdentity)); | ||
1932 | offset += sizeof (struct GNUNET_PeerIdentity); | ||
1933 | |||
1934 | |||
1935 | memcpy (message_buf, &temp_pos[offset], message_size); | ||
1936 | if (memcmp | ||
1937 | (&send_msg->target, destination, | ||
1938 | sizeof (struct GNUNET_PeerIdentity)) != 0) | ||
1939 | { | ||
1940 | GNUNET_CRYPTO_hash_to_enc (&destination->hashPubKey, &dest_hash); /* GNUNET_i2s won't properly work, need to hash one ourselves */ | ||
1941 | dest_hash.encoding[4] = '\0'; | ||
1942 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1943 | "%s: asked to send message to `%s', but address is for `%s'!", | ||
1944 | "DV SERVICE", GNUNET_i2s (&send_msg->target), | ||
1945 | (const char *) &dest_hash.encoding); | ||
1946 | } | ||
1947 | |||
1948 | #if DEBUG_DV_MESSAGES | ||
1949 | cbuf = (char *) message_buf; | ||
1950 | offset = 0; | ||
1951 | while (offset < message_size) | ||
1952 | { | ||
1953 | packed_message = (struct GNUNET_MessageHeader *) &cbuf[offset]; | ||
1954 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1955 | "%s: DV PLUGIN SEND uid %u type %d to %s\n", my_short_id, | ||
1956 | ntohl (send_msg->uid), ntohs (packed_message->type), | ||
1957 | GNUNET_i2s (destination)); | ||
1958 | offset += ntohs (packed_message->size); | ||
1959 | } | ||
1960 | /*GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s: DV PLUGIN SEND uid %u type %d to %s\n", my_short_id, ntohl(send_msg->uid), ntohs(message_buf->type), GNUNET_i2s(destination)); */ | ||
1961 | #endif | ||
1962 | GNUNET_CRYPTO_hash_to_enc (&destination->hashPubKey, &dest_hash); /* GNUNET_i2s won't properly work, need to hash one ourselves */ | ||
1963 | dest_hash.encoding[4] = '\0'; | ||
1964 | send_context = GNUNET_malloc (sizeof (struct DV_SendContext)); | ||
1965 | |||
1966 | send_result_msg = GNUNET_malloc (sizeof (struct GNUNET_DV_SendResultMessage)); | ||
1967 | send_result_msg->header.size = | ||
1968 | htons (sizeof (struct GNUNET_DV_SendResultMessage)); | ||
1969 | send_result_msg->header.type = | ||
1970 | htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND_RESULT); | ||
1971 | send_result_msg->uid = send_msg->uid; /* No need to ntohl->htonl this */ | ||
1972 | |||
1973 | send_context->importance = ntohl (send_msg->priority); | ||
1974 | send_context->timeout = send_msg->timeout; | ||
1975 | send_context->direct_peer = direct; | ||
1976 | send_context->distant_peer = destination; | ||
1977 | send_context->message = message_buf; | ||
1978 | send_context->message_size = message_size; | ||
1979 | send_context->send_result = send_result_msg; | ||
1980 | #if DEBUG_DV_MESSAGES | ||
1981 | send_context->uid = send_msg->uid; | ||
1982 | #endif | ||
1983 | |||
1984 | if (send_message_via (&my_identity, direct, send_context) != GNUNET_YES) | ||
1985 | { | ||
1986 | send_result_msg->result = htons (1); | ||
1987 | pending_message = | ||
1988 | GNUNET_malloc (sizeof (struct PendingMessage) + | ||
1989 | sizeof (struct GNUNET_DV_SendResultMessage)); | ||
1990 | pending_message->msg = (struct GNUNET_MessageHeader *) &pending_message[1]; | ||
1991 | memcpy (&pending_message[1], send_result_msg, | ||
1992 | sizeof (struct GNUNET_DV_SendResultMessage)); | ||
1993 | GNUNET_free (send_result_msg); | ||
1994 | |||
1995 | GNUNET_CONTAINER_DLL_insert_after (plugin_pending_head, plugin_pending_tail, | ||
1996 | plugin_pending_tail, pending_message); | ||
1997 | |||
1998 | if (client_handle != NULL) | ||
1999 | { | ||
2000 | if (plugin_transmit_handle == NULL) | ||
2001 | { | ||
2002 | plugin_transmit_handle = | ||
2003 | GNUNET_SERVER_notify_transmit_ready (client_handle, | ||
2004 | sizeof (struct | ||
2005 | GNUNET_DV_SendResultMessage), | ||
2006 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
2007 | &transmit_to_plugin, NULL); | ||
2008 | } | ||
2009 | else | ||
2010 | { | ||
2011 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2012 | "Failed to queue message for plugin, must be one in progress already!!\n"); | ||
2013 | } | ||
2014 | } | ||
2015 | GNUNET_CRYPTO_hash_to_enc (&destination->hashPubKey, &dest_hash); /* GNUNET_i2s won't properly work, need to hash one ourselves */ | ||
2016 | dest_hash.encoding[4] = '\0'; | ||
2017 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2018 | "%s DV SEND failed to send message to destination `%s' via `%s'\n", | ||
2019 | my_short_id, (const char *) &dest_hash.encoding, | ||
2020 | GNUNET_i2s (direct)); | ||
2021 | } | ||
2022 | |||
2023 | /* In bizarro world GNUNET_SYSERR indicates that we succeeded */ | ||
2024 | #if UNSIMPLER | ||
2025 | if (GNUNET_SYSERR != | ||
2026 | GNUNET_CONTAINER_multihashmap_get_multiple (extended_neighbors, | ||
2027 | &destination->hashPubKey, | ||
2028 | &send_iterator, send_context)) | ||
2029 | { | ||
2030 | send_result_msg->result = htons (1); | ||
2031 | pending_message = | ||
2032 | GNUNET_malloc (sizeof (struct PendingMessage) + | ||
2033 | sizeof (struct GNUNET_DV_SendResultMessage)); | ||
2034 | pending_message->msg = (struct GNUNET_MessageHeader *) &pending_message[1]; | ||
2035 | memcpy (&pending_message[1], send_result_msg, | ||
2036 | sizeof (struct GNUNET_DV_SendResultMessage)); | ||
2037 | GNUNET_free (send_result_msg); | ||
2038 | |||
2039 | GNUNET_CONTAINER_DLL_insert_after (plugin_pending_head, plugin_pending_tail, | ||
2040 | plugin_pending_tail, pending_message); | ||
2041 | |||
2042 | if (client_handle != NULL) | ||
2043 | { | ||
2044 | if (plugin_transmit_handle == NULL) | ||
2045 | { | ||
2046 | plugin_transmit_handle = | ||
2047 | GNUNET_SERVER_notify_transmit_ready (client_handle, | ||
2048 | sizeof (struct | ||
2049 | GNUNET_DV_SendResultMessage), | ||
2050 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
2051 | &transmit_to_plugin, NULL); | ||
2052 | } | ||
2053 | else | ||
2054 | { | ||
2055 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2056 | "Failed to queue message for plugin, must be one in progress already!!\n"); | ||
2057 | } | ||
2058 | } | ||
2059 | GNUNET_CRYPTO_hash_to_enc (&destination->hashPubKey, &dest_hash); /* GNUNET_i2s won't properly work, need to hash one ourselves */ | ||
2060 | dest_hash.encoding[4] = '\0'; | ||
2061 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2062 | "%s DV SEND failed to send message to destination `%s' via `%s'\n", | ||
2063 | my_short_id, (const char *) &dest_hash.encoding, | ||
2064 | GNUNET_i2s (direct)); | ||
2065 | } | ||
2066 | #endif | ||
2067 | GNUNET_free (message_buf); | ||
2068 | GNUNET_free (send_context); | ||
2069 | GNUNET_free (direct); | ||
2070 | GNUNET_free (destination); | ||
2071 | |||
2072 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
2073 | } | ||
2074 | 1144 | ||
2075 | /** Forward declarations **/ | 1145 | /** Forward declarations **/ |
2076 | static int | 1146 | static int |
@@ -2088,29 +1158,6 @@ handle_dv_disconnect_message (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2088 | 1158 | ||
2089 | 1159 | ||
2090 | /** | 1160 | /** |
2091 | * List of handlers for the messages understood by this | ||
2092 | * service. | ||
2093 | * | ||
2094 | * Hmm... will we need to register some handlers with core and | ||
2095 | * some handlers with our server here? Because core should be | ||
2096 | * getting the incoming DV messages (from whichever lower level | ||
2097 | * transport) and then our server should be getting messages | ||
2098 | * from the dv_plugin, right? | ||
2099 | */ | ||
2100 | static struct GNUNET_CORE_MessageHandler core_handlers[] = { | ||
2101 | {&handle_dv_data_message, GNUNET_MESSAGE_TYPE_DV_DATA, 0}, | ||
2102 | {&handle_dv_gossip_message, GNUNET_MESSAGE_TYPE_DV_GOSSIP, 0}, | ||
2103 | {&handle_dv_disconnect_message, GNUNET_MESSAGE_TYPE_DV_DISCONNECT, 0}, | ||
2104 | {NULL, 0, 0} | ||
2105 | }; | ||
2106 | |||
2107 | static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = { | ||
2108 | {&handle_dv_send_message, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND, 0}, | ||
2109 | {&handle_start, NULL, GNUNET_MESSAGE_TYPE_DV_START, 0}, | ||
2110 | {NULL, NULL, 0, 0} | ||
2111 | }; | ||
2112 | |||
2113 | /** | ||
2114 | * Free a DistantNeighbor node, including removing it | 1161 | * Free a DistantNeighbor node, including removing it |
2115 | * from the referer's list. | 1162 | * from the referer's list. |
2116 | */ | 1163 | */ |
@@ -2212,101 +1259,6 @@ schedule_disconnect_messages (void *cls, const struct GNUNET_HashCode * key, | |||
2212 | return GNUNET_YES; | 1259 | return GNUNET_YES; |
2213 | } | 1260 | } |
2214 | 1261 | ||
2215 | /** | ||
2216 | * Multihashmap iterator for freeing extended neighbors. | ||
2217 | * | ||
2218 | * @param cls NULL | ||
2219 | * @param key key value stored under | ||
2220 | * @param value the distant neighbor to be freed | ||
2221 | * | ||
2222 | * @return GNUNET_YES to continue iteration, GNUNET_NO to stop | ||
2223 | */ | ||
2224 | static int | ||
2225 | free_extended_neighbors (void *cls, const struct GNUNET_HashCode * key, void *value) | ||
2226 | { | ||
2227 | struct DistantNeighbor *distant = value; | ||
2228 | |||
2229 | distant_neighbor_free (distant); | ||
2230 | return GNUNET_YES; | ||
2231 | } | ||
2232 | |||
2233 | /** | ||
2234 | * Multihashmap iterator for freeing direct neighbors. | ||
2235 | * | ||
2236 | * @param cls NULL | ||
2237 | * @param key key value stored under | ||
2238 | * @param value the direct neighbor to be freed | ||
2239 | * | ||
2240 | * @return GNUNET_YES to continue iteration, GNUNET_NO to stop | ||
2241 | */ | ||
2242 | static int | ||
2243 | free_direct_neighbors (void *cls, const struct GNUNET_HashCode * key, void *value) | ||
2244 | { | ||
2245 | struct DirectNeighbor *direct = value; | ||
2246 | |||
2247 | direct_neighbor_free (direct); | ||
2248 | return GNUNET_YES; | ||
2249 | } | ||
2250 | |||
2251 | |||
2252 | /** | ||
2253 | * Task run during shutdown. | ||
2254 | * | ||
2255 | * @param cls unused | ||
2256 | * @param tc unused | ||
2257 | */ | ||
2258 | static void | ||
2259 | shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
2260 | { | ||
2261 | #if DEBUG_DV | ||
2262 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "calling CORE_DISCONNECT\n"); | ||
2263 | GNUNET_CONTAINER_multihashmap_iterate (extended_neighbors, &print_neighbors, | ||
2264 | NULL); | ||
2265 | #endif | ||
2266 | GNUNET_CONTAINER_multihashmap_iterate (extended_neighbors, | ||
2267 | &free_extended_neighbors, NULL); | ||
2268 | GNUNET_CONTAINER_multihashmap_destroy (extended_neighbors); | ||
2269 | GNUNET_CONTAINER_multihashmap_iterate (direct_neighbors, | ||
2270 | &free_direct_neighbors, NULL); | ||
2271 | GNUNET_CONTAINER_multihashmap_destroy (direct_neighbors); | ||
2272 | |||
2273 | GNUNET_CONTAINER_heap_destroy (neighbor_max_heap); | ||
2274 | GNUNET_CONTAINER_heap_destroy (neighbor_min_heap); | ||
2275 | |||
2276 | GNUNET_CORE_disconnect (coreAPI); | ||
2277 | coreAPI = NULL; | ||
2278 | GNUNET_PEERINFO_disconnect (peerinfo_handle); | ||
2279 | GNUNET_SERVER_mst_destroy (coreMST); | ||
2280 | GNUNET_free_non_null (my_short_id); | ||
2281 | #if DEBUG_DV | ||
2282 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CORE_DISCONNECT completed\n"); | ||
2283 | #endif | ||
2284 | } | ||
2285 | |||
2286 | /** | ||
2287 | * To be called on core init/fail. | ||
2288 | */ | ||
2289 | void | ||
2290 | core_init (void *cls, struct GNUNET_CORE_Handle *server, | ||
2291 | const struct GNUNET_PeerIdentity *identity) | ||
2292 | { | ||
2293 | |||
2294 | if (server == NULL) | ||
2295 | { | ||
2296 | GNUNET_SCHEDULER_cancel (cleanup_task); | ||
2297 | GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); | ||
2298 | return; | ||
2299 | } | ||
2300 | #if DEBUG_DV | ||
2301 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2302 | "%s: Core connection initialized, I am peer: %s\n", "dv", | ||
2303 | GNUNET_i2s (identity)); | ||
2304 | #endif | ||
2305 | memcpy (&my_identity, identity, sizeof (struct GNUNET_PeerIdentity)); | ||
2306 | my_short_id = GNUNET_strdup (GNUNET_i2s (&my_identity)); | ||
2307 | coreAPI = server; | ||
2308 | } | ||
2309 | |||
2310 | 1262 | ||
2311 | #if PKEY_NO_NEIGHBOR_ON_ADD | 1263 | #if PKEY_NO_NEIGHBOR_ON_ADD |
2312 | /** | 1264 | /** |
@@ -2771,61 +1723,6 @@ handle_dv_disconnect_message (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2771 | 1723 | ||
2772 | 1724 | ||
2773 | /** | 1725 | /** |
2774 | * Core handler for dv gossip messages. These will be used | ||
2775 | * by us to create a HELLO message for the newly peer containing | ||
2776 | * which direct peer we can connect through, and what the cost | ||
2777 | * is. This HELLO will then be scheduled for validation by the | ||
2778 | * transport service so that it can be used by all others. | ||
2779 | * | ||
2780 | * @param cls closure | ||
2781 | * @param peer peer which sent the message (immediate sender) | ||
2782 | * @param message the message | ||
2783 | * @param atsi performance data | ||
2784 | * @param atsi_count number of entries in atsi | ||
2785 | */ | ||
2786 | static int | ||
2787 | handle_dv_gossip_message (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
2788 | const struct GNUNET_MessageHeader *message, | ||
2789 | const struct GNUNET_ATS_Information *atsi, | ||
2790 | unsigned int atsi_count) | ||
2791 | { | ||
2792 | struct DirectNeighbor *referrer; | ||
2793 | p2p_dv_MESSAGE_NeighborInfo *enc_message = | ||
2794 | (p2p_dv_MESSAGE_NeighborInfo *) message; | ||
2795 | |||
2796 | if (ntohs (message->size) < sizeof (p2p_dv_MESSAGE_NeighborInfo)) | ||
2797 | { | ||
2798 | return GNUNET_SYSERR; /* invalid message */ | ||
2799 | } | ||
2800 | |||
2801 | #if DEBUG_DV_GOSSIP_RECEIPT | ||
2802 | char *encPeerAbout; | ||
2803 | char *encPeerFrom; | ||
2804 | |||
2805 | encPeerAbout = GNUNET_strdup (GNUNET_i2s (&enc_message->neighbor)); | ||
2806 | encPeerFrom = GNUNET_strdup (GNUNET_i2s (peer)); | ||
2807 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2808 | "%s: Received %s message from peer %s about peer %s id %u distance %d!\n", | ||
2809 | GNUNET_i2s (&my_identity), "DV GOSSIP", encPeerFrom, encPeerAbout, | ||
2810 | ntohl (enc_message->neighbor_id), ntohl (enc_message->cost) + 1); | ||
2811 | GNUNET_free (encPeerAbout); | ||
2812 | GNUNET_free (encPeerFrom); | ||
2813 | #endif | ||
2814 | |||
2815 | referrer = | ||
2816 | GNUNET_CONTAINER_multihashmap_get (direct_neighbors, &peer->hashPubKey); | ||
2817 | if (referrer == NULL) | ||
2818 | return GNUNET_OK; | ||
2819 | |||
2820 | addUpdateNeighbor (&enc_message->neighbor, &enc_message->pkey, | ||
2821 | ntohl (enc_message->neighbor_id), referrer, | ||
2822 | ntohl (enc_message->cost) + 1); | ||
2823 | |||
2824 | return GNUNET_OK; | ||
2825 | } | ||
2826 | |||
2827 | |||
2828 | /** | ||
2829 | * Iterate over all currently known peers, add them to the | 1726 | * Iterate over all currently known peers, add them to the |
2830 | * fast gossip list for this peer so we get DV routing information | 1727 | * fast gossip list for this peer so we get DV routing information |
2831 | * out as fast as possible! | 1728 | * out as fast as possible! |
@@ -2863,54 +1760,8 @@ add_all_extended_peers (void *cls, const struct GNUNET_HashCode * key, void *val | |||
2863 | return GNUNET_YES; | 1760 | return GNUNET_YES; |
2864 | } | 1761 | } |
2865 | 1762 | ||
2866 | #if INSANE_GOSSIP | ||
2867 | /** | ||
2868 | * Iterator over hash map entries. | ||
2869 | * | ||
2870 | * @param cls closure | ||
2871 | * @param key current key code | ||
2872 | * @param value value in the hash map | ||
2873 | * @return GNUNET_YES if we should continue to | ||
2874 | * iterate, | ||
2875 | * GNUNET_NO if not. | ||
2876 | */ | ||
2877 | static int | ||
2878 | gossip_all_to_all_iterator (void *cls, const struct GNUNET_HashCode * key, | ||
2879 | void *abs_value) | ||
2880 | { | ||
2881 | struct DirectNeighbor *direct = abs_value; | ||
2882 | |||
2883 | GNUNET_CONTAINER_multihashmap_iterate (extended_neighbors, | ||
2884 | &add_all_extended_peers, | ||
2885 | direct->send_context); | ||
2886 | |||
2887 | if (direct->send_context->task != GNUNET_SCHEDULER_NO_TASK) | ||
2888 | GNUNET_SCHEDULER_cancel (direct->send_context->task); | ||
2889 | |||
2890 | direct->send_context->task = | ||
2891 | GNUNET_SCHEDULER_add_now (&neighbor_send_task, direct->send_context); | ||
2892 | return GNUNET_YES; | ||
2893 | } | ||
2894 | 1763 | ||
2895 | /** | 1764 | /** |
2896 | * Task run during shutdown. | ||
2897 | * | ||
2898 | * @param cls unused | ||
2899 | * @param tc unused | ||
2900 | */ | ||
2901 | static void | ||
2902 | gossip_all_to_all (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
2903 | { | ||
2904 | GNUNET_CONTAINER_multihashmap_iterate (direct_neighbors, | ||
2905 | &gossip_all_to_all_iterator, NULL); | ||
2906 | |||
2907 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | ||
2908 | (GNUNET_TIME_UNIT_SECONDS, 5), | ||
2909 | &gossip_all_to_all, NULL); | ||
2910 | |||
2911 | } | ||
2912 | #endif | ||
2913 | /** | ||
2914 | * Iterate over all current direct peers, add newly connected peer | 1765 | * Iterate over all current direct peers, add newly connected peer |
2915 | * to the fast gossip list for that peer so we get DV routing | 1766 | * to the fast gossip list for that peer so we get DV routing |
2916 | * information out as fast as possible! | 1767 | * information out as fast as possible! |
@@ -2975,108 +1826,10 @@ add_all_direct_neighbors (void *cls, const struct GNUNET_HashCode * key, void *v | |||
2975 | return GNUNET_YES; | 1826 | return GNUNET_YES; |
2976 | } | 1827 | } |
2977 | 1828 | ||
2978 | /** | ||
2979 | * Type of an iterator over the hosts. Note that each | ||
2980 | * host will be called with each available protocol. | ||
2981 | * | ||
2982 | * @param cls closure | ||
2983 | * @param peer id of the peer, NULL for last call | ||
2984 | * @param hello hello message for the peer (can be NULL) | ||
2985 | * @param err_msg NULL if successful, otherwise contains error message | ||
2986 | */ | ||
2987 | static void | ||
2988 | process_peerinfo (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
2989 | const struct GNUNET_HELLO_Message *hello, const char *err_msg) | ||
2990 | { | ||
2991 | struct PeerIteratorContext *peerinfo_iterator = cls; | ||
2992 | struct DirectNeighbor *neighbor = peerinfo_iterator->neighbor; | ||
2993 | struct DistantNeighbor *distant = peerinfo_iterator->distant; | ||
2994 | |||
2995 | #if DEBUG_DV_PEER_NUMBERS | ||
2996 | char *neighbor_pid; | ||
2997 | #endif | ||
2998 | int sent; | ||
2999 | 1829 | ||
3000 | if (err_msg != NULL) | 1830 | //////////////////////////////////////////////////////////////////////// |
3001 | { | ||
3002 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3003 | _("Error in communication with PEERINFO service\n")); | ||
3004 | /* return; */ | ||
3005 | } | ||
3006 | if (peer == NULL) | ||
3007 | { | ||
3008 | if (distant->pkey == NULL) | ||
3009 | { | ||
3010 | #if DEBUG_DV | ||
3011 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
3012 | "Failed to get peerinfo information for this peer, retrying!\n"); | ||
3013 | #endif | 1831 | #endif |
3014 | peerinfo_iterator->ic = | ||
3015 | GNUNET_PEERINFO_iterate (peerinfo_handle, | ||
3016 | &peerinfo_iterator->neighbor->identity, | ||
3017 | GNUNET_TIME_relative_multiply | ||
3018 | (GNUNET_TIME_UNIT_SECONDS, 3), | ||
3019 | &process_peerinfo, peerinfo_iterator); | ||
3020 | } | ||
3021 | else | ||
3022 | { | ||
3023 | GNUNET_free (peerinfo_iterator); | ||
3024 | } | ||
3025 | return; | ||
3026 | } | ||
3027 | |||
3028 | if (memcmp | ||
3029 | (&neighbor->identity, peer, sizeof (struct GNUNET_PeerIdentity) != 0)) | ||
3030 | return; | ||
3031 | |||
3032 | if ((hello != NULL) && | ||
3033 | (GNUNET_HELLO_get_key (hello, &neighbor->pkey) == GNUNET_OK)) | ||
3034 | { | ||
3035 | if (distant->pkey == NULL) | ||
3036 | { | ||
3037 | distant->pkey = | ||
3038 | GNUNET_malloc (sizeof | ||
3039 | (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded)); | ||
3040 | memcpy (distant->pkey, &neighbor->pkey, | ||
3041 | sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded)); | ||
3042 | } | ||
3043 | 1832 | ||
3044 | sent = | ||
3045 | GNUNET_CONTAINER_multihashmap_iterate (extended_neighbors, | ||
3046 | &add_all_extended_peers, | ||
3047 | neighbor->send_context); | ||
3048 | if (stats != NULL) | ||
3049 | { | ||
3050 | GNUNET_STATISTICS_update (stats, | ||
3051 | "# distant peers gossiped to direct neighbors", | ||
3052 | sent, GNUNET_NO); | ||
3053 | } | ||
3054 | #if DEBUG_DV_PEER_NUMBERS | ||
3055 | neighbor_pid = GNUNET_strdup (GNUNET_i2s (&neighbor->identity)); | ||
3056 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3057 | "%s: Gossipped %d extended peers to %s\n", | ||
3058 | GNUNET_i2s (&my_identity), sent, neighbor_pid); | ||
3059 | #endif | ||
3060 | sent = | ||
3061 | GNUNET_CONTAINER_multihashmap_iterate (direct_neighbors, | ||
3062 | &add_all_direct_neighbors, | ||
3063 | neighbor); | ||
3064 | if (stats != NULL) | ||
3065 | { | ||
3066 | GNUNET_STATISTICS_update (stats, | ||
3067 | "# direct peers gossiped to direct neighbors", | ||
3068 | sent, GNUNET_NO); | ||
3069 | } | ||
3070 | #if DEBUG_DV_PEER_NUMBERS | ||
3071 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3072 | "%s: Gossipped about %s to %d direct peers\n", | ||
3073 | GNUNET_i2s (&my_identity), neighbor_pid, sent); | ||
3074 | GNUNET_free (neighbor_pid); | ||
3075 | #endif | ||
3076 | neighbor->send_context->task = | ||
3077 | GNUNET_SCHEDULER_add_now (&neighbor_send_task, neighbor->send_context); | ||
3078 | } | ||
3079 | } | ||
3080 | 1833 | ||
3081 | 1834 | ||
3082 | /** | 1835 | /** |
@@ -3093,156 +1846,305 @@ handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
3093 | unsigned int atsi_count) | 1846 | unsigned int atsi_count) |
3094 | { | 1847 | { |
3095 | struct DirectNeighbor *neighbor; | 1848 | struct DirectNeighbor *neighbor; |
3096 | struct DistantNeighbor *about; | ||
3097 | struct PeerIteratorContext *peerinfo_iterator; | ||
3098 | int sent; | ||
3099 | |||
3100 | uint32_t distance; | 1849 | uint32_t distance; |
3101 | 1850 | ||
3102 | /* Check for connect to self message */ | 1851 | /* Check for connect to self message */ |
3103 | if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity))) | 1852 | if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity))) |
3104 | return; | 1853 | return; |
3105 | |||
3106 | distance = get_atsi_distance (atsi, atsi_count); | 1854 | distance = get_atsi_distance (atsi, atsi_count); |
3107 | if ((distance == DIRECT_NEIGHBOR_COST) && | 1855 | neighbor = GNUNET_CONTAINER_multihashmap_get (direct_neighbors, |
3108 | (GNUNET_CONTAINER_multihashmap_get (direct_neighbors, &peer->hashPubKey) | 1856 | &peer->hashPubKey); |
3109 | == NULL)) | 1857 | if (NULL != neighbor) |
3110 | { | ||
3111 | peerinfo_iterator = GNUNET_malloc (sizeof (struct PeerIteratorContext)); | ||
3112 | neighbor = GNUNET_malloc (sizeof (struct DirectNeighbor)); | ||
3113 | neighbor->send_context = | ||
3114 | GNUNET_malloc (sizeof (struct NeighborSendContext)); | ||
3115 | neighbor->send_context->toNeighbor = neighbor; | ||
3116 | memcpy (&neighbor->identity, peer, sizeof (struct GNUNET_PeerIdentity)); | ||
3117 | |||
3118 | GNUNET_assert (GNUNET_SYSERR != | ||
3119 | GNUNET_CONTAINER_multihashmap_put (direct_neighbors, | ||
3120 | &peer->hashPubKey, | ||
3121 | neighbor, | ||
3122 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
3123 | about = addUpdateNeighbor (peer, NULL, 0, neighbor, DIRECT_NEIGHBOR_COST); | ||
3124 | peerinfo_iterator->distant = about; | ||
3125 | peerinfo_iterator->neighbor = neighbor; | ||
3126 | peerinfo_iterator->ic = | ||
3127 | GNUNET_PEERINFO_iterate (peerinfo_handle, peer, | ||
3128 | GNUNET_TIME_relative_multiply | ||
3129 | (GNUNET_TIME_UNIT_SECONDS, 3), | ||
3130 | &process_peerinfo, peerinfo_iterator); | ||
3131 | |||
3132 | if ((about != NULL) && (about->pkey == NULL)) | ||
3133 | { | ||
3134 | #if DEBUG_DV | ||
3135 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3136 | "Newly added peer %s has NULL pkey!\n", GNUNET_i2s (peer)); | ||
3137 | #endif | ||
3138 | } | ||
3139 | else if (about != NULL) | ||
3140 | { | ||
3141 | GNUNET_free (peerinfo_iterator); | ||
3142 | } | ||
3143 | } | ||
3144 | else | ||
3145 | { | 1858 | { |
3146 | about = | 1859 | GNUNET_break (0); |
3147 | GNUNET_CONTAINER_multihashmap_get (extended_neighbors, | ||
3148 | &peer->hashPubKey); | ||
3149 | if ((GNUNET_CONTAINER_multihashmap_get (direct_neighbors, &peer->hashPubKey) | ||
3150 | == NULL) && (about != NULL)) | ||
3151 | { | ||
3152 | sent = | ||
3153 | GNUNET_CONTAINER_multihashmap_iterate (direct_neighbors, | ||
3154 | &add_distant_all_direct_neighbors, | ||
3155 | about); | ||
3156 | if (stats != NULL) | ||
3157 | GNUNET_STATISTICS_update (stats, | ||
3158 | "# direct peers gossiped to new direct neighbors", | ||
3159 | sent, GNUNET_NO); | ||
3160 | } | ||
3161 | #if DEBUG_DV | ||
3162 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3163 | "%s: Distance (%d) greater than %d or already know about peer (%s), not re-adding!\n", | ||
3164 | "dv", distance, DIRECT_NEIGHBOR_COST, GNUNET_i2s (peer)); | ||
3165 | #endif | ||
3166 | return; | 1860 | return; |
3167 | } | 1861 | } |
1862 | if (DIRECT_NEIGHBOR_COST != distance) | ||
1863 | return; /* is a DV-neighbor */ | ||
1864 | |||
1865 | GNUNET_break (0); // FIXME... | ||
3168 | } | 1866 | } |
3169 | 1867 | ||
1868 | |||
1869 | |||
1870 | /** | ||
1871 | * Core handler for dv data messages. Whatever this message | ||
1872 | * contains all we really have to do is rip it out of its | ||
1873 | * DV layering and give it to our pal the DV plugin to report | ||
1874 | * in with. | ||
1875 | * | ||
1876 | * @param cls closure | ||
1877 | * @param peer peer which sent the message (immediate sender) | ||
1878 | * @param message the message | ||
1879 | * @param atsi transport ATS information (latency, distance, etc.) | ||
1880 | * @param atsi_count number of entries in atsi | ||
1881 | */ | ||
1882 | static int | ||
1883 | handle_dv_route_message (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
1884 | const struct GNUNET_MessageHeader *message, | ||
1885 | const struct GNUNET_ATS_Information *atsi, | ||
1886 | unsigned int atsi_count) | ||
1887 | { | ||
1888 | GNUNET_break (0); // FIXME | ||
1889 | return GNUNET_OK; | ||
1890 | } | ||
1891 | |||
1892 | |||
1893 | /** | ||
1894 | * Service server's handler for message send requests (which come | ||
1895 | * bubbling up to us through the DV plugin). | ||
1896 | * | ||
1897 | * @param cls closure | ||
1898 | * @param client identification of the client | ||
1899 | * @param message the actual message | ||
1900 | */ | ||
1901 | static void | ||
1902 | handle_dv_send_message (void *cls, struct GNUNET_SERVER_Client *client, | ||
1903 | const struct GNUNET_MessageHeader *message) | ||
1904 | { | ||
1905 | GNUNET_break (0); // FIXME | ||
1906 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
1907 | } | ||
1908 | |||
1909 | |||
1910 | /** | ||
1911 | * Multihashmap iterator for freeing routes that go via a particular | ||
1912 | * neighbor that disconnected and is thus no longer available. | ||
1913 | * | ||
1914 | * @param cls the direct neighbor that is now unavailable | ||
1915 | * @param key key value stored under | ||
1916 | * @param value a 'struct Route' that may or may not go via neighbor | ||
1917 | * | ||
1918 | * @return GNUNET_YES to continue iteration, GNUNET_NO to stop | ||
1919 | */ | ||
1920 | static int | ||
1921 | cull_routes (void *cls, const struct GNUNET_HashCode * key, void *value) | ||
1922 | { | ||
1923 | struct DirectNeighbor *neighbor = cls; | ||
1924 | struct Route *route = value; | ||
1925 | |||
1926 | if (route->next_hop != neighbor) | ||
1927 | return GNUNET_YES; /* not affected */ | ||
1928 | |||
1929 | /* FIXME: destroy route! */ | ||
1930 | GNUNET_break (0); | ||
1931 | |||
1932 | return GNUNET_YES; | ||
1933 | } | ||
1934 | |||
1935 | |||
1936 | /** | ||
1937 | * Multihashmap iterator for freeing routes that go via a particular | ||
1938 | * neighbor that disconnected and is thus no longer available. | ||
1939 | * | ||
1940 | * @param cls the direct neighbor that is now unavailable | ||
1941 | * @param key key value stored under | ||
1942 | * @param value a 'struct Route' that may or may not go via neighbor | ||
1943 | * | ||
1944 | * @return GNUNET_YES to continue iteration, GNUNET_NO to stop | ||
1945 | */ | ||
1946 | static int | ||
1947 | cull_routing_neighbors (void *cls, const struct GNUNET_HashCode * key, void *value) | ||
1948 | { | ||
1949 | struct DirectNeighbor *neighbor = cls; | ||
1950 | struct RoutingNeighbor *rn = value; | ||
1951 | |||
1952 | if (rn->route.next_hop != neighbor) | ||
1953 | return GNUNET_YES; /* not affected */ | ||
1954 | |||
1955 | /* FIXME: destroy routing neighbor! */ | ||
1956 | GNUNET_break (0); | ||
1957 | |||
1958 | return GNUNET_YES; | ||
1959 | } | ||
1960 | |||
1961 | |||
3170 | /** | 1962 | /** |
3171 | * Method called whenever a given peer disconnects. | 1963 | * Method called whenever a given peer disconnects. |
3172 | * | 1964 | * |
3173 | * @param cls closure | 1965 | * @param cls closure |
3174 | * @param peer peer identity this notification is about | 1966 | * @param peer peer identity this notification is about |
3175 | */ | 1967 | */ |
3176 | void | 1968 | static void |
3177 | handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) | 1969 | handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) |
3178 | { | 1970 | { |
3179 | struct DirectNeighbor *neighbor; | 1971 | struct DirectNeighbor *neighbor; |
3180 | struct DistantNeighbor *referee; | 1972 | struct PendingMessage *pending; |
3181 | struct FindDestinationContext fdc; | ||
3182 | struct DisconnectContext disconnect_context; | ||
3183 | struct PendingMessage *pending_pos; | ||
3184 | 1973 | ||
3185 | #if DEBUG_DV | ||
3186 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1974 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3187 | "%s: Receives core peer disconnect message!\n", "dv"); | 1975 | "Received core peer disconnect message for peer `%s'!\n", |
3188 | #endif | 1976 | GNUNET_i2s (peer)); |
3189 | |||
3190 | /* Check for disconnect from self message */ | 1977 | /* Check for disconnect from self message */ |
3191 | if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity))) | 1978 | if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity))) |
3192 | return; | 1979 | return; |
3193 | |||
3194 | neighbor = | 1980 | neighbor = |
3195 | GNUNET_CONTAINER_multihashmap_get (direct_neighbors, &peer->hashPubKey); | 1981 | GNUNET_CONTAINER_multihashmap_get (direct_neighbors, &peer->hashPubKey); |
3196 | 1982 | if (NULL == neighbor) | |
3197 | if (neighbor == NULL) | ||
3198 | { | 1983 | { |
1984 | /* must have been a DV-neighbor, ignore */ | ||
3199 | return; | 1985 | return; |
3200 | } | 1986 | } |
3201 | 1987 | while (NULL != (pending = neighbor->pm_head)) | |
3202 | pending_pos = core_pending_head; | ||
3203 | while (NULL != pending_pos) | ||
3204 | { | 1988 | { |
3205 | if (0 == | 1989 | GNUNET_CONTAINER_DLL_remove (neighbor->pm_head, |
3206 | memcmp (&pending_pos->recipient, &neighbor->identity, | 1990 | neighbor->pm_tail, |
3207 | sizeof (struct GNUNET_PeerIdentity))) | 1991 | pending); |
3208 | { | 1992 | GNUNET_free (pending); |
3209 | GNUNET_CONTAINER_DLL_remove (core_pending_head, core_pending_tail, | ||
3210 | pending_pos); | ||
3211 | pending_pos = core_pending_head; | ||
3212 | } | ||
3213 | else | ||
3214 | pending_pos = pending_pos->next; | ||
3215 | } | 1993 | } |
1994 | GNUNET_CONTAINER_multihashmap_iterate (all_routes, | ||
1995 | &cull_routes, | ||
1996 | neighbor); | ||
1997 | GNUNET_CONTAINER_multihashmap_iterate (routing_neighbors, | ||
1998 | &cull_routing_neighbors, | ||
1999 | neighbor); | ||
2000 | if (NULL != neighbor->cth) | ||
2001 | { | ||
2002 | GNUNET_CORE_notify_transmit_ready_cancel (neighbor->cth); | ||
2003 | neighbor->cth = NULL; | ||
2004 | } | ||
2005 | GNUNET_assert (GNUNET_YES == | ||
2006 | GNUNET_CONTAINER_multihashmap_remove (direct_neighbors, | ||
2007 | &peer->hashPubKey, | ||
2008 | neighbor)); | ||
2009 | GNUNET_free (neighbor); | ||
2010 | } | ||
3216 | 2011 | ||
3217 | while (NULL != (referee = neighbor->referee_head)) | ||
3218 | distant_neighbor_free (referee); | ||
3219 | 2012 | ||
3220 | fdc.dest = NULL; | ||
3221 | fdc.tid = 0; | ||
3222 | 2013 | ||
3223 | GNUNET_CONTAINER_multihashmap_iterate (extended_neighbors, &find_distant_peer, | 2014 | /** |
3224 | &fdc); | 2015 | * Multihashmap iterator for freeing routes. Should never be called. |
2016 | * | ||
2017 | * @param cls NULL | ||
2018 | * @param key key value stored under | ||
2019 | * @param value the route to be freed | ||
2020 | * | ||
2021 | * @return GNUNET_YES to continue iteration, GNUNET_NO to stop | ||
2022 | */ | ||
2023 | static int | ||
2024 | free_route (void *cls, const struct GNUNET_HashCode * key, void *value) | ||
2025 | { | ||
2026 | GNUNET_break (0); | ||
2027 | // FIXME: notify client about disconnect | ||
2028 | return GNUNET_YES; | ||
2029 | } | ||
2030 | |||
3225 | 2031 | ||
3226 | if (fdc.dest != NULL) | 2032 | /** |
3227 | { | 2033 | * Multihashmap iterator for freeing routing neighbors. Should never be called. |
3228 | disconnect_context.direct = neighbor; | 2034 | * |
3229 | disconnect_context.distant = fdc.dest; | 2035 | * @param cls NULL |
3230 | GNUNET_CONTAINER_multihashmap_iterate (direct_neighbors, | 2036 | * @param key key value stored under |
3231 | &schedule_disconnect_messages, | 2037 | * @param value the distant neighbor to be freed |
3232 | &disconnect_context); | 2038 | * |
2039 | * @return GNUNET_YES to continue iteration, GNUNET_NO to stop | ||
2040 | */ | ||
2041 | static int | ||
2042 | free_routing_neighbors (void *cls, const struct GNUNET_HashCode * key, void *value) | ||
2043 | { | ||
2044 | struct RoutingNeighbor *router = value; | ||
2045 | |||
2046 | GNUNET_break (0); | ||
2047 | // FIXME: release resources | ||
2048 | return GNUNET_YES; | ||
2049 | } | ||
2050 | |||
2051 | |||
2052 | /** | ||
2053 | * Multihashmap iterator for freeing direct neighbors. Should never be called. | ||
2054 | * | ||
2055 | * @param cls NULL | ||
2056 | * @param key key value stored under | ||
2057 | * @param value the direct neighbor to be freed | ||
2058 | * | ||
2059 | * @return GNUNET_YES to continue iteration, GNUNET_NO to stop | ||
2060 | */ | ||
2061 | static int | ||
2062 | free_direct_neighbors (void *cls, const struct GNUNET_HashCode * key, void *value) | ||
2063 | { | ||
2064 | struct DirectNeighbor *dn = value; | ||
2065 | |||
2066 | GNUNET_break (0); | ||
2067 | // FIXME: release resources, ... | ||
2068 | return GNUNET_YES; | ||
2069 | } | ||
2070 | |||
2071 | |||
2072 | /** | ||
2073 | * Task run during shutdown. | ||
2074 | * | ||
2075 | * @param cls unused | ||
2076 | * @param tc unused | ||
2077 | */ | ||
2078 | static void | ||
2079 | shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
2080 | { | ||
2081 | struct PendingMessage *pending; | ||
2082 | unsigned int i; | ||
2083 | |||
2084 | GNUNET_CONTAINER_multihashmap_iterate (direct_neighbors, | ||
2085 | &free_direct_neighbors, NULL); | ||
2086 | GNUNET_CONTAINER_multihashmap_destroy (direct_neighbors); | ||
2087 | GNUNET_CONTAINER_multihashmap_iterate (routing_neighbors, | ||
2088 | &free_routing_neighbors, NULL); | ||
2089 | GNUNET_CONTAINER_multihashmap_destroy (routing_neighbors); | ||
2090 | GNUNET_CONTAINER_multihashmap_iterate (all_routes, | ||
2091 | &free_route, NULL); | ||
2092 | GNUNET_CONTAINER_multihashmap_destroy (all_routes); | ||
2093 | GNUNET_CORE_disconnect (core_api); | ||
2094 | core_api = NULL; | ||
2095 | while (NULL != (pending = plugin_pending_head)) | ||
2096 | { | ||
2097 | GNUNET_CONTAINER_DLL_remove (plugin_pending_head, | ||
2098 | plugin_pending_tail, | ||
2099 | pending); | ||
2100 | GNUNET_free (pending); | ||
3233 | } | 2101 | } |
2102 | for (i=0;i<DEFAULT_FISHEYE_DEPTH - 1;i++) | ||
2103 | GNUNET_array_grow (consensi[i].targets, | ||
2104 | consensi[i].array_length, | ||
2105 | 0); | ||
2106 | } | ||
3234 | 2107 | ||
3235 | GNUNET_assert (neighbor->referee_tail == NULL); | 2108 | |
3236 | if (GNUNET_NO == | 2109 | /** |
3237 | GNUNET_CONTAINER_multihashmap_remove (direct_neighbors, &peer->hashPubKey, | 2110 | * Handle START-message. This is the first message sent to us |
3238 | neighbor)) | 2111 | * by the client (can only be one!). |
2112 | * | ||
2113 | * @param cls closure (always NULL) | ||
2114 | * @param client identification of the client | ||
2115 | * @param message the actual message | ||
2116 | */ | ||
2117 | static void | ||
2118 | handle_start (void *cls, struct GNUNET_SERVER_Client *client, | ||
2119 | const struct GNUNET_MessageHeader *message) | ||
2120 | { | ||
2121 | if (NULL != client_handle) | ||
3239 | { | 2122 | { |
3240 | GNUNET_break (0); | 2123 | /* forcefully drop old client */ |
2124 | GNUNET_SERVER_client_disconnect (client_handle); | ||
2125 | GNUNET_SERVER_client_drop (client_handle); | ||
3241 | } | 2126 | } |
3242 | if ((neighbor->send_context != NULL) && | 2127 | client_handle = client; |
3243 | (neighbor->send_context->task != GNUNET_SCHEDULER_NO_TASK)) | 2128 | GNUNET_SERVER_client_keep (client_handle); |
3244 | GNUNET_SCHEDULER_cancel (neighbor->send_context->task); | 2129 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
3245 | GNUNET_free (neighbor); | 2130 | } |
2131 | |||
2132 | |||
2133 | /** | ||
2134 | * Called on core init. | ||
2135 | * | ||
2136 | * @param cls unused | ||
2137 | * @param server legacy | ||
2138 | * @param identity this peer's identity | ||
2139 | */ | ||
2140 | static void | ||
2141 | core_init (void *cls, struct GNUNET_CORE_Handle *server, | ||
2142 | const struct GNUNET_PeerIdentity *identity) | ||
2143 | { | ||
2144 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2145 | "I am peer: %s\n", | ||
2146 | GNUNET_i2s (identity)); | ||
2147 | my_identity = *identity; | ||
3246 | } | 2148 | } |
3247 | 2149 | ||
3248 | 2150 | ||
@@ -3257,66 +2159,38 @@ static void | |||
3257 | run (void *cls, struct GNUNET_SERVER_Handle *server, | 2159 | run (void *cls, struct GNUNET_SERVER_Handle *server, |
3258 | const struct GNUNET_CONFIGURATION_Handle *c) | 2160 | const struct GNUNET_CONFIGURATION_Handle *c) |
3259 | { | 2161 | { |
3260 | unsigned long long max_hosts; | 2162 | static struct GNUNET_CORE_MessageHandler core_handlers[] = { |
2163 | {&handle_dv_route_message, GNUNET_MESSAGE_TYPE_DV_ROUTE, 0}, | ||
2164 | {NULL, 0, 0} | ||
2165 | }; | ||
2166 | static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = { | ||
2167 | {&handle_start, NULL, | ||
2168 | GNUNET_MESSAGE_TYPE_DV_START, | ||
2169 | sizeof (struct GNUNET_MessageHeader) }, | ||
2170 | { &handle_dv_send_message, NULL, | ||
2171 | GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND, | ||
2172 | 0}, | ||
2173 | {NULL, NULL, 0, 0} | ||
2174 | }; | ||
3261 | 2175 | ||
3262 | cfg = c; | 2176 | cfg = c; |
3263 | 2177 | direct_neighbors = GNUNET_CONTAINER_multihashmap_create (128, GNUNET_NO); | |
3264 | /* FIXME: Read from config, or calculate, or something other than this! */ | 2178 | routing_neighbors = GNUNET_CONTAINER_multihashmap_create (128 * 128, GNUNET_NO); |
3265 | max_hosts = DEFAULT_DIRECT_CONNECTIONS; | 2179 | all_routes = GNUNET_CONTAINER_multihashmap_create (65536, GNUNET_NO); |
3266 | max_table_size = DEFAULT_DV_SIZE; | 2180 | core_api = GNUNET_CORE_connect (cfg, NULL, |
3267 | fisheye_depth = DEFAULT_FISHEYE_DEPTH; | 2181 | &core_init, |
3268 | 2182 | &handle_core_connect, | |
3269 | if (GNUNET_CONFIGURATION_have_value (cfg, "dv", "max_direct_connections")) | 2183 | &handle_core_disconnect, |
3270 | GNUNET_assert (GNUNET_OK == | 2184 | NULL, GNUNET_NO, |
3271 | GNUNET_CONFIGURATION_get_value_number (cfg, "dv", | 2185 | NULL, GNUNET_NO, |
3272 | "max_direct_connections", | 2186 | core_handlers); |
3273 | &max_hosts)); | 2187 | |
3274 | 2188 | if (NULL == core_api) | |
3275 | if (GNUNET_CONFIGURATION_have_value (cfg, "dv", "max_total_connections")) | ||
3276 | GNUNET_assert (GNUNET_OK == | ||
3277 | GNUNET_CONFIGURATION_get_value_number (cfg, "dv", | ||
3278 | "max_total_connections", | ||
3279 | &max_table_size)); | ||
3280 | |||
3281 | |||
3282 | if (GNUNET_CONFIGURATION_have_value (cfg, "dv", "fisheye_depth")) | ||
3283 | GNUNET_assert (GNUNET_OK == | ||
3284 | GNUNET_CONFIGURATION_get_value_number (cfg, "dv", | ||
3285 | "fisheye_depth", | ||
3286 | &fisheye_depth)); | ||
3287 | |||
3288 | neighbor_min_heap = | ||
3289 | GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | ||
3290 | neighbor_max_heap = | ||
3291 | GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MAX); | ||
3292 | |||
3293 | direct_neighbors = GNUNET_CONTAINER_multihashmap_create (max_hosts, GNUNET_NO); | ||
3294 | extended_neighbors = | ||
3295 | GNUNET_CONTAINER_multihashmap_create (max_table_size * 3, GNUNET_NO); | ||
3296 | |||
3297 | GNUNET_SERVER_add_handlers (server, plugin_handlers); | ||
3298 | coreAPI = GNUNET_CORE_connect (cfg, NULL, /* FIXME: anything we want to pass around? */ | ||
3299 | &core_init, &handle_core_connect, | ||
3300 | &handle_core_disconnect, NULL, GNUNET_NO, NULL, | ||
3301 | GNUNET_NO, core_handlers); | ||
3302 | |||
3303 | if (coreAPI == NULL) | ||
3304 | return; | 2189 | return; |
3305 | 2190 | // FIXME: stats | |
3306 | coreMST = GNUNET_SERVER_mst_create (&tokenized_message_handler, NULL); | 2191 | GNUNET_SERVER_add_handlers (server, plugin_handlers); |
3307 | 2192 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, | |
3308 | peerinfo_handle = GNUNET_PEERINFO_connect (cfg); | 2193 | &shutdown_task, NULL); |
3309 | |||
3310 | if (peerinfo_handle == NULL) | ||
3311 | { | ||
3312 | GNUNET_CORE_disconnect (coreAPI); | ||
3313 | return; | ||
3314 | } | ||
3315 | |||
3316 | /* Scheduled the task to clean up when shutdown is called */ | ||
3317 | cleanup_task = | ||
3318 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, | ||
3319 | &shutdown_task, NULL); | ||
3320 | } | 2194 | } |
3321 | 2195 | ||
3322 | 2196 | ||
diff --git a/src/dv/gnunet_dv_service.h b/src/dv/gnunet_dv_service.h new file mode 100644 index 000000000..7bdb17858 --- /dev/null +++ b/src/dv/gnunet_dv_service.h | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2013 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @author Christian Grothoff | ||
23 | * @file dv/gnunet-service-dv.h | ||
24 | * @brief DV service API (should only be used by the DV plugin) | ||
25 | */ | ||
26 | #ifndef GNUNET_SERVICE_DV_H | ||
27 | #define GNUNET_SERVICE_DV_H | ||
28 | |||
29 | #include "gnunet_util_lib.h" | ||
30 | |||
31 | |||
32 | /** | ||
33 | * Signature of a function to be called if DV | ||
34 | * starts to be able to talk to a peer. | ||
35 | */ | ||
36 | typedef void (*GNUNET_DV_ConnectCallback)(void *cls, | ||
37 | const struct GNUNET_PeerIdentity *peer, | ||
38 | uint32_t distance); | ||
39 | |||
40 | |||
41 | /** | ||
42 | * Signature of a function to be called if DV | ||
43 | * is no longer able to talk to a peer. | ||
44 | */ | ||
45 | typedef void (*GNUNET_DV_DisconnectCallback)(void *cls, | ||
46 | const struct GNUNET_PeerIdentity *peer); | ||
47 | |||
48 | |||
49 | /** | ||
50 | * Signature of a function to be called if DV | ||
51 | * receives a message for this peer. | ||
52 | * | ||
53 | * @param cls closure | ||
54 | * @param sender sender of the message | ||
55 | * @param distance how far did the message travel | ||
56 | * @param msg actual message payload | ||
57 | */ | ||
58 | typedef void (*GNUNET_DV_MessageReceivedCallback)(void *cls, | ||
59 | const struct GNUNET_PeerIdentity *sender, | ||
60 | uint32_t distance, | ||
61 | const struct GNUNET_MessageHeader *msg); | ||
62 | |||
63 | |||
64 | /** | ||
65 | * Signature of a function called once the delivery of a | ||
66 | * message has been successful. | ||
67 | * | ||
68 | * @param cls closure | ||
69 | * @param ok GNUNET_OK on success, GNUNET_SYSERR on error | ||
70 | */ | ||
71 | typedef void (*GNUNET_DV_MessageSentCallback)(void *cls, | ||
72 | int ok); | ||
73 | |||
74 | |||
75 | /** | ||
76 | * Handle to the DV service. | ||
77 | */ | ||
78 | struct GNUNET_DV_ServiceHandle; | ||
79 | |||
80 | |||
81 | /** | ||
82 | * Connect to the DV service. | ||
83 | * | ||
84 | * @param cfg configuration | ||
85 | * @param cls closure for callbacks | ||
86 | * @param connect_cb function to call on connects | ||
87 | * @param disconnect_cb function to call on disconnects | ||
88 | * @param message_cb function to call if we receive messages | ||
89 | * @return handle to access the service | ||
90 | */ | ||
91 | struct GNUNET_DV_ServiceHandle * | ||
92 | GNUNET_DV_service_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
93 | void *cls, | ||
94 | GNUNET_DV_ConnectCallback connect_cb, | ||
95 | GNUNET_DV_DisconnectCallback disconnect_cb, | ||
96 | GNUNET_DV_MessageReceivedCallback message_cb); | ||
97 | |||
98 | |||
99 | /** | ||
100 | * Disconnect from DV service. | ||
101 | * | ||
102 | * @param sh service handle | ||
103 | */ | ||
104 | void | ||
105 | GNUNET_DV_service_disconnect (struct GNUNET_DV_ServiceHandle *sh); | ||
106 | |||
107 | |||
108 | /** | ||
109 | * Handle for a send operation. | ||
110 | */ | ||
111 | struct GNUNET_DV_TransmitHandle; | ||
112 | |||
113 | |||
114 | /** | ||
115 | * Send a message via DV service. | ||
116 | * | ||
117 | * @param sh service handle | ||
118 | * @param target intended recpient | ||
119 | * @param msg message payload | ||
120 | * @param cb function to invoke when done | ||
121 | * @param cb_cls closure for 'cb' | ||
122 | * @return handle to cancel the operation | ||
123 | */ | ||
124 | struct GNUNET_DV_TransmitHandle * | ||
125 | GNUNET_DV_send (struct GNUNET_DV_ServiceHandle *sh, | ||
126 | const struct GNUNET_PeerIdentity *target, | ||
127 | const struct GNUNET_MessageHeader *msg, | ||
128 | GNUNET_DV_MessageSentCallback cb, | ||
129 | void *cb_cls); | ||
130 | |||
131 | |||
132 | /** | ||
133 | * Abort send operation (naturally, the message may have | ||
134 | * already been transmitted; this only stops the 'cb' | ||
135 | * from being called again). | ||
136 | * | ||
137 | * @param th send operation to cancel | ||
138 | */ | ||
139 | void | ||
140 | GNUNET_DV_send_cancel (struct GNUNET_DV_TransmitHandle *th); | ||
141 | |||
142 | |||
143 | #endif | ||
diff --git a/src/dv/plugin_transport_dv.c b/src/dv/plugin_transport_dv.c index 3a8bafcef..ef8456b55 100644 --- a/src/dv/plugin_transport_dv.c +++ b/src/dv/plugin_transport_dv.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Christian Grothoff (and other contributing authors) | 3 | (C) 2002--2013 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -114,21 +114,11 @@ struct Plugin | |||
114 | struct GNUNET_TRANSPORT_PluginEnvironment *env; | 114 | struct GNUNET_TRANSPORT_PluginEnvironment *env; |
115 | 115 | ||
116 | /** | 116 | /** |
117 | * List of open sessions. | 117 | * List of open sessions. FIXME: use hash map! |
118 | */ | 118 | */ |
119 | struct Session *sessions; | 119 | struct Session *sessions; |
120 | 120 | ||
121 | /** | 121 | /** |
122 | * Our server. | ||
123 | */ | ||
124 | //struct GNUNET_SERVER_Handle *server; | ||
125 | |||
126 | /* | ||
127 | * Handle to the running service. | ||
128 | */ | ||
129 | //struct GNUNET_SERVICE_Context *service; | ||
130 | |||
131 | /** | ||
132 | * Copy of the handler array where the closures are | 122 | * Copy of the handler array where the closures are |
133 | * set to this struct's instance. | 123 | * set to this struct's instance. |
134 | */ | 124 | */ |
@@ -137,53 +127,35 @@ struct Plugin | |||
137 | /** | 127 | /** |
138 | * Handle to the DV service | 128 | * Handle to the DV service |
139 | */ | 129 | */ |
140 | struct GNUNET_DV_Handle *dv_handle; | 130 | struct GNUNET_DV_ServiceHandle *dvh; |
141 | 131 | ||
142 | }; | 132 | }; |
143 | 133 | ||
134 | |||
144 | /** | 135 | /** |
145 | * Handler for messages received from the DV service. | 136 | * Handler for messages received from the DV service. |
137 | * | ||
138 | * @param cls closure with the plugin | ||
139 | * @param sender sender of the message | ||
140 | * @param distance how far did the message travel | ||
141 | * @param msg actual message payload | ||
146 | */ | 142 | */ |
147 | void | 143 | static void |
148 | handle_dv_message_received (void *cls, struct GNUNET_PeerIdentity *sender, | 144 | handle_dv_message_received (void *cls, |
149 | char *msg, size_t msg_len, uint32_t distance, | 145 | const struct GNUNET_PeerIdentity *sender, |
150 | char *sender_address, size_t sender_address_len) | 146 | uint32_t distance, |
147 | const struct GNUNET_MessageHeader *msg) | ||
151 | { | 148 | { |
152 | struct Plugin *plugin = cls; | 149 | struct Plugin *plugin = cls; |
150 | struct GNUNET_ATS_Information ats; | ||
153 | 151 | ||
154 | #if DEBUG_DV_MESSAGES | 152 | ats.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); |
155 | char *my_id; | 153 | ats.value = htonl (distance); |
156 | |||
157 | my_id = GNUNET_strdup (GNUNET_i2s (plugin->env->my_identity)); | ||
158 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "plugin_transport_dv", | ||
159 | _("%s Received message from %s of type %d, distance %u!\n"), | ||
160 | my_id, GNUNET_i2s (sender), | ||
161 | ntohs (((struct GNUNET_MessageHeader *) msg)->type), | ||
162 | distance); | ||
163 | if (sender_address_len == (2 * sizeof (struct GNUNET_PeerIdentity))) | ||
164 | { | ||
165 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "plugin_transport_dv", | ||
166 | "Parsed sender address: %s:%s\n", | ||
167 | GNUNET_i2s ((struct GNUNET_PeerIdentity *) sender_address), | ||
168 | GNUNET_h2s (& | ||
169 | ((struct GNUNET_PeerIdentity *) | ||
170 | &sender_address[sizeof | ||
171 | (struct | ||
172 | GNUNET_PeerIdentity)])->hashPubKey)); | ||
173 | } | ||
174 | |||
175 | GNUNET_free_non_null (my_id); | ||
176 | #endif | ||
177 | struct GNUNET_ATS_Information ats[1]; | ||
178 | |||
179 | ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); | ||
180 | ats[0].value = htonl (distance); | ||
181 | 154 | ||
182 | plugin->env->receive (plugin->env->cls, sender, | 155 | plugin->env->receive (plugin->env->cls, sender, |
183 | (struct GNUNET_MessageHeader *) msg, | 156 | msg, |
184 | (const struct GNUNET_ATS_Information *) &ats, 1, NULL, | 157 | &ats, 1, |
185 | sender_address, sender_address_len); | 158 | NULL, NULL, 0); |
186 | |||
187 | } | 159 | } |
188 | 160 | ||
189 | 161 | ||
@@ -219,14 +191,7 @@ dv_plugin_send (void *cls, | |||
219 | GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) | 191 | GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) |
220 | { | 192 | { |
221 | int ret = -1; | 193 | int ret = -1; |
222 | #if 0 | ||
223 | struct Plugin *plugin = cls; | ||
224 | 194 | ||
225 | ret = | ||
226 | GNUNET_DV_send (plugin->dv_handle, &session->sender, | ||
227 | msgbuf, msgbuf_size, priority, | ||
228 | timeout, addr, addrlen, cont, cont_cls); | ||
229 | #endif | ||
230 | return ret; | 195 | return ret; |
231 | } | 196 | } |
232 | 197 | ||
@@ -269,33 +234,10 @@ dv_plugin_address_pretty_printer (void *cls, const char *type, const void *addr, | |||
269 | GNUNET_TRANSPORT_AddressStringCallback asc, | 234 | GNUNET_TRANSPORT_AddressStringCallback asc, |
270 | void *asc_cls) | 235 | void *asc_cls) |
271 | { | 236 | { |
272 | char *dest_peer; | 237 | asc (asc_cls, NULL); |
273 | char *via_peer; | ||
274 | char *print_string; | ||
275 | char *addr_buf = (char *) addr; | ||
276 | |||
277 | if (addrlen != sizeof (struct GNUNET_PeerIdentity) * 2) | ||
278 | { | ||
279 | asc (asc_cls, NULL); | ||
280 | } | ||
281 | else | ||
282 | { | ||
283 | dest_peer = | ||
284 | GNUNET_strdup (GNUNET_i2s ((struct GNUNET_PeerIdentity *) addr)); | ||
285 | via_peer = | ||
286 | GNUNET_strdup (GNUNET_i2s | ||
287 | ((struct GNUNET_PeerIdentity *) | ||
288 | &addr_buf[sizeof (struct GNUNET_PeerIdentity)])); | ||
289 | GNUNET_asprintf (&print_string, "DV Peer `%s' via peer`%s'", dest_peer, | ||
290 | via_peer); | ||
291 | asc (asc_cls, print_string); | ||
292 | asc (asc_cls, NULL); | ||
293 | GNUNET_free (via_peer); | ||
294 | GNUNET_free (dest_peer); | ||
295 | GNUNET_free (print_string); | ||
296 | } | ||
297 | } | 238 | } |
298 | 239 | ||
240 | |||
299 | /** | 241 | /** |
300 | * Convert the DV address to a pretty string. | 242 | * Convert the DV address to a pretty string. |
301 | * | 243 | * |
@@ -308,34 +250,10 @@ dv_plugin_address_pretty_printer (void *cls, const char *type, const void *addr, | |||
308 | static const char * | 250 | static const char * |
309 | address_to_string (void *cls, const void *addr, size_t addrlen) | 251 | address_to_string (void *cls, const void *addr, size_t addrlen) |
310 | { | 252 | { |
311 | static char return_buffer[2 * 4 + 2]; // Two four character peer identity prefixes a ':' and '\0' | 253 | return "<not implemented>"; |
312 | |||
313 | struct GNUNET_CRYPTO_HashAsciiEncoded peer_hash; | ||
314 | struct GNUNET_CRYPTO_HashAsciiEncoded via_hash; | ||
315 | struct GNUNET_PeerIdentity *peer; | ||
316 | struct GNUNET_PeerIdentity *via; | ||
317 | char *addr_buf = (char *) addr; | ||
318 | |||
319 | if (addrlen == (2 * sizeof (struct GNUNET_PeerIdentity))) | ||
320 | { | ||
321 | peer = (struct GNUNET_PeerIdentity *) addr_buf; | ||
322 | via = | ||
323 | (struct GNUNET_PeerIdentity *) | ||
324 | &addr_buf[sizeof (struct GNUNET_PeerIdentity)]; | ||
325 | |||
326 | GNUNET_CRYPTO_hash_to_enc (&peer->hashPubKey, &peer_hash); | ||
327 | peer_hash.encoding[4] = '\0'; | ||
328 | GNUNET_CRYPTO_hash_to_enc (&via->hashPubKey, &via_hash); | ||
329 | via_hash.encoding[4] = '\0'; | ||
330 | GNUNET_snprintf (return_buffer, sizeof (return_buffer), "%s:%s", &peer_hash, | ||
331 | &via_hash); | ||
332 | } | ||
333 | else | ||
334 | return NULL; | ||
335 | |||
336 | return return_buffer; | ||
337 | } | 254 | } |
338 | 255 | ||
256 | |||
339 | /** | 257 | /** |
340 | * Another peer has suggested an address for this peer and transport | 258 | * Another peer has suggested an address for this peer and transport |
341 | * plugin. Check that this could be a valid address. This function | 259 | * plugin. Check that this could be a valid address. This function |
@@ -355,26 +273,7 @@ address_to_string (void *cls, const void *addr, size_t addrlen) | |||
355 | static int | 273 | static int |
356 | dv_plugin_check_address (void *cls, const void *addr, size_t addrlen) | 274 | dv_plugin_check_address (void *cls, const void *addr, size_t addrlen) |
357 | { | 275 | { |
358 | struct Plugin *plugin = cls; | 276 | return GNUNET_SYSERR; |
359 | |||
360 | /* Verify that the first peer of this address matches our peer id! */ | ||
361 | if ((addrlen != (2 * sizeof (struct GNUNET_PeerIdentity))) || | ||
362 | (0 != | ||
363 | memcmp (addr, plugin->env->my_identity, | ||
364 | sizeof (struct GNUNET_PeerIdentity)))) | ||
365 | { | ||
366 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
367 | "%s: Address not correct size or identity doesn't match ours!\n", | ||
368 | GNUNET_i2s (plugin->env->my_identity)); | ||
369 | if (addrlen == (2 * sizeof (struct GNUNET_PeerIdentity))) | ||
370 | { | ||
371 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer in address is %s\n", | ||
372 | GNUNET_i2s (addr)); | ||
373 | } | ||
374 | return GNUNET_SYSERR; | ||
375 | } | ||
376 | |||
377 | return GNUNET_OK; | ||
378 | } | 277 | } |
379 | 278 | ||
380 | 279 | ||
@@ -408,16 +307,10 @@ libgnunet_plugin_transport_dv_init (void *cls) | |||
408 | 307 | ||
409 | plugin = GNUNET_malloc (sizeof (struct Plugin)); | 308 | plugin = GNUNET_malloc (sizeof (struct Plugin)); |
410 | plugin->env = env; | 309 | plugin->env = env; |
411 | 310 | plugin->dvh = GNUNET_DV_service_connect (env->cfg, | |
412 | plugin->dv_handle = | 311 | plugin, |
413 | GNUNET_DV_connect (env->cfg, &handle_dv_message_received, plugin); | 312 | NULL, NULL, /*FIXME! */ |
414 | 313 | &handle_dv_message_received); | |
415 | if (plugin->dv_handle == NULL) | ||
416 | { | ||
417 | GNUNET_free (plugin); | ||
418 | return NULL; | ||
419 | } | ||
420 | |||
421 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | 314 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); |
422 | api->cls = plugin; | 315 | api->cls = plugin; |
423 | api->send = &dv_plugin_send; | 316 | api->send = &dv_plugin_send; |
@@ -425,6 +318,7 @@ libgnunet_plugin_transport_dv_init (void *cls) | |||
425 | api->address_pretty_printer = &dv_plugin_address_pretty_printer; | 318 | api->address_pretty_printer = &dv_plugin_address_pretty_printer; |
426 | api->check_address = &dv_plugin_check_address; | 319 | api->check_address = &dv_plugin_check_address; |
427 | api->address_to_string = &address_to_string; | 320 | api->address_to_string = &address_to_string; |
321 | api->string_to_address = NULL; /* FIXME */ | ||
428 | api->get_session = dv_get_session; | 322 | api->get_session = dv_get_session; |
429 | return api; | 323 | return api; |
430 | } | 324 | } |
@@ -439,9 +333,7 @@ libgnunet_plugin_transport_dv_done (void *cls) | |||
439 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | 333 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; |
440 | struct Plugin *plugin = api->cls; | 334 | struct Plugin *plugin = api->cls; |
441 | 335 | ||
442 | if (plugin->dv_handle != NULL) | 336 | GNUNET_DV_service_disconnect (plugin->dvh); |
443 | GNUNET_DV_disconnect (plugin->dv_handle); | ||
444 | |||
445 | GNUNET_free (plugin); | 337 | GNUNET_free (plugin); |
446 | GNUNET_free (api); | 338 | GNUNET_free (api); |
447 | return NULL; | 339 | return NULL; |