diff options
-rw-r--r-- | src/dv/Makefile.am | 66 | ||||
-rw-r--r-- | src/dv/dv.h | 165 | ||||
-rw-r--r-- | src/dv/dv_api.c | 392 | ||||
-rw-r--r-- | src/dv/gnunet-service-dv.c | 278 | ||||
-rw-r--r-- | src/dv/plugin_transport_dv.c | 400 |
5 files changed, 1301 insertions, 0 deletions
diff --git a/src/dv/Makefile.am b/src/dv/Makefile.am new file mode 100644 index 000000000..755f89d59 --- /dev/null +++ b/src/dv/Makefile.am | |||
@@ -0,0 +1,66 @@ | |||
1 | INCLUDES = -I$(top_srcdir)/src/include | ||
2 | |||
3 | if MINGW | ||
4 | WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols | ||
5 | endif | ||
6 | |||
7 | if USE_COVERAGE | ||
8 | AM_CFLAGS = --coverage -O0 | ||
9 | XLIB = -lgcov | ||
10 | endif | ||
11 | |||
12 | plugindir = $(libdir)/gnunet | ||
13 | |||
14 | lib_LTLIBRARIES = libgnunetdv.la | ||
15 | |||
16 | plugin_LTLIBRARIES = libgnunet_plugin_transport_dv.la | ||
17 | |||
18 | libgnunetdv_la_SOURCES = \ | ||
19 | dv_api.c dv.h | ||
20 | libgnunetdv_la_LIBADD = \ | ||
21 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
22 | $(top_builddir)/src/core/libgnunetcore.la \ | ||
23 | $(GN_LIBINTL) $(XLIB) | ||
24 | libgnunetdv_la_LDFLAGS = \ | ||
25 | $(GN_LIB_LDFLAGS) $(WINFLAGS) \ | ||
26 | -version-info 0:0:0 | ||
27 | |||
28 | |||
29 | bin_PROGRAMS = \ | ||
30 | gnunet-service-dv | ||
31 | |||
32 | gnunet_service_dv_SOURCES = \ | ||
33 | gnunet-service-dv.c | ||
34 | gnunet_service_dv_LDADD = \ | ||
35 | $(top_builddir)/src/dv/libgnunetdv.la \ | ||
36 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
37 | $(GN_LIBINTL) | ||
38 | |||
39 | libgnunet_plugin_transport_dv_la_SOURCES = \ | ||
40 | plugin_transport_dv.c | ||
41 | libgnunet_plugin_transport_dv_la_LIBADD = \ | ||
42 | $(top_builddir)/src/hello/libgnunethello.la \ | ||
43 | $(top_builddir)/src/dv/libgnunetdv.la \ | ||
44 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ | ||
45 | $(top_builddir)/src/util/libgnunetutil.la | ||
46 | libgnunet_plugin_transport_dv_la_LDFLAGS = \ | ||
47 | $(GN_PLUGIN_LDFLAGS) | ||
48 | |||
49 | |||
50 | #check_PROGRAMS = \ | ||
51 | # test_statistics_api | ||
52 | |||
53 | TESTS = $(check_PROGRAMS) $(check_SCRIPTS) | ||
54 | |||
55 | #test_statistics_api_SOURCES = \ | ||
56 | # test_statistics_api.c | ||
57 | #test_statistics_api_LDADD = \ | ||
58 | # $(top_builddir)/src/statistics/libgnunetstatistics.la \ | ||
59 | # $(top_builddir)/src/util/libgnunetutil.la | ||
60 | |||
61 | #EXTRA_DIST = \ | ||
62 | # test_statistics_api_data.conf | ||
63 | |||
64 | #check_SCRIPTS = \ | ||
65 | # test_gnunet_statistics.sh | ||
66 | |||
diff --git a/src/dv/dv.h b/src/dv/dv.h new file mode 100644 index 000000000..3063bc917 --- /dev/null +++ b/src/dv/dv.h | |||
@@ -0,0 +1,165 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2001, 2002, 2003, 2004, 2009 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 2, 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 | * @author NOT Nathan Evans | ||
24 | * @file dv/dv.h | ||
25 | */ | ||
26 | #ifndef DV_H | ||
27 | #define DV_H | ||
28 | |||
29 | #include "gnunet_common.h" | ||
30 | |||
31 | #define DEBUG_DV GNUNET_YES | ||
32 | #define DEBUG_DV_API GNUNET_YES | ||
33 | |||
34 | typedef void (*GNUNET_DV_MessageReceivedHandler) (void *cls, | ||
35 | struct GNUNET_PeerIdentity *sender, | ||
36 | struct GNUNET_MessageHeader *msg, | ||
37 | unsigned int distance, | ||
38 | char *sender_address, | ||
39 | size_t sender_address_len); | ||
40 | |||
41 | /** | ||
42 | * DV Message, contains a message that was received | ||
43 | * via DV for this peer! | ||
44 | * | ||
45 | * Sender address is copied to the end of this struct. | ||
46 | */ | ||
47 | struct GNUNET_DV_MessageReceived | ||
48 | { | ||
49 | /** | ||
50 | * Type: GNUNET_MESSAGE_TYPE_TRANSPORT_DV_MESSAGE | ||
51 | */ | ||
52 | struct GNUNET_MessageHeader header; | ||
53 | |||
54 | /** | ||
55 | * The sender of the message | ||
56 | */ | ||
57 | struct GNUNET_PeerIdentity *sender; | ||
58 | |||
59 | /** | ||
60 | * The message that was sent | ||
61 | */ | ||
62 | struct GNUNET_MessageHeader *msg; | ||
63 | |||
64 | /** | ||
65 | * The distance to the peer that we received the message from | ||
66 | */ | ||
67 | size_t distance; | ||
68 | |||
69 | /** | ||
70 | * Length of the sender address, appended to end of this message | ||
71 | */ | ||
72 | size_t sender_address_len; | ||
73 | |||
74 | }; | ||
75 | |||
76 | |||
77 | /** | ||
78 | * DV Message, indicates that we have learned of a new DV level peer. | ||
79 | * | ||
80 | * Sender address is copied to the end of this struct. | ||
81 | */ | ||
82 | struct GNUNET_DV_ConnectMessage | ||
83 | { | ||
84 | /** | ||
85 | * Type: GNUNET_MESSAGE_TYPE_TRANSPORT_DV_MESSAGE | ||
86 | */ | ||
87 | struct GNUNET_MessageHeader header; | ||
88 | |||
89 | /** | ||
90 | * The sender of the message | ||
91 | */ | ||
92 | struct GNUNET_PeerIdentity *sender; | ||
93 | |||
94 | /** | ||
95 | * The message that was sent | ||
96 | */ | ||
97 | struct GNUNET_MessageHeader *msg; | ||
98 | |||
99 | /** | ||
100 | * The distance to the peer that we received the message from | ||
101 | */ | ||
102 | size_t distance; | ||
103 | |||
104 | /** | ||
105 | * Length of the sender address, appended to end of this message | ||
106 | */ | ||
107 | size_t sender_address_len; | ||
108 | |||
109 | }; | ||
110 | |||
111 | |||
112 | /** | ||
113 | * Message to send a message over DV via a specific peer | ||
114 | */ | ||
115 | struct GNUNET_DV_SendMessage | ||
116 | { | ||
117 | /** | ||
118 | * Type: GNUNET_MESSAGE_TYPE_DV_SEND | ||
119 | */ | ||
120 | struct GNUNET_MessageHeader header; | ||
121 | |||
122 | /** | ||
123 | * Intended final recipient of this message | ||
124 | */ | ||
125 | struct GNUNET_PeerIdentity target; | ||
126 | |||
127 | /** | ||
128 | * The message(s) to be sent. | ||
129 | */ | ||
130 | char *msgbuf; | ||
131 | |||
132 | /** | ||
133 | * The size of the msgbuf | ||
134 | */ | ||
135 | size_t msgbuf_size; | ||
136 | |||
137 | /** | ||
138 | * Message priority | ||
139 | */ | ||
140 | size_t priority; | ||
141 | |||
142 | /** | ||
143 | * How long can we delay sending? | ||
144 | */ | ||
145 | struct GNUNET_TIME_Relative timeout; | ||
146 | |||
147 | /** | ||
148 | * Size of the address (appended to end of struct) | ||
149 | */ | ||
150 | size_t addrlen; | ||
151 | |||
152 | /* | ||
153 | * Sender, appended to end of struct tells via whom | ||
154 | * to send this message. | ||
155 | */ | ||
156 | |||
157 | }; | ||
158 | |||
159 | struct GNUNET_DV_Handle * | ||
160 | GNUNET_DV_connect (struct GNUNET_SCHEDULER_Handle *sched, | ||
161 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
162 | GNUNET_DV_MessageReceivedHandler receive_handler, | ||
163 | void *receive_handler_cls); | ||
164 | |||
165 | #endif | ||
diff --git a/src/dv/dv_api.c b/src/dv/dv_api.c new file mode 100644 index 000000000..8c536b207 --- /dev/null +++ b/src/dv/dv_api.c | |||
@@ -0,0 +1,392 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2009, 2010 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 2, 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 | * @file transport/dv_api.c | ||
23 | * @brief library to access the DV service | ||
24 | * @author Christian Grothoff | ||
25 | * @author Not Nathan Evans | ||
26 | */ | ||
27 | #include "platform.h" | ||
28 | #include "gnunet_bandwidth_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" | ||
38 | #include "dv.h" | ||
39 | |||
40 | |||
41 | struct PendingMessages | ||
42 | { | ||
43 | /** | ||
44 | * Linked list of pending messages | ||
45 | */ | ||
46 | struct PendingMessages *next; | ||
47 | |||
48 | /** | ||
49 | * Message that is pending | ||
50 | */ | ||
51 | struct GNUNET_DV_SendMessage *msg; | ||
52 | |||
53 | /** | ||
54 | * Timeout for this message | ||
55 | */ | ||
56 | struct GNUNET_TIME_Absolute timeout; | ||
57 | |||
58 | }; | ||
59 | |||
60 | /** | ||
61 | * Handle for the service. | ||
62 | */ | ||
63 | struct GNUNET_DV_Handle | ||
64 | { | ||
65 | /** | ||
66 | * Our scheduler. | ||
67 | */ | ||
68 | struct GNUNET_SCHEDULER_Handle *sched; | ||
69 | |||
70 | /** | ||
71 | * Configuration to use. | ||
72 | */ | ||
73 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
74 | |||
75 | /** | ||
76 | * Socket (if available). | ||
77 | */ | ||
78 | struct GNUNET_CLIENT_Connection *client; | ||
79 | |||
80 | /** | ||
81 | * Currently pending transmission request. | ||
82 | */ | ||
83 | struct GNUNET_CLIENT_TransmitHandle *th; | ||
84 | |||
85 | /** | ||
86 | * List of the currently pending messages for the DV service. | ||
87 | */ | ||
88 | struct PendingMessages *pending_list; | ||
89 | |||
90 | /** | ||
91 | * Message we are currently sending. | ||
92 | */ | ||
93 | struct PendingMessages *current; | ||
94 | |||
95 | /** | ||
96 | * Kill off the connection and any pending messages. | ||
97 | */ | ||
98 | int do_destroy; | ||
99 | |||
100 | /** | ||
101 | * Handler for messages we receive from the DV service | ||
102 | */ | ||
103 | GNUNET_DV_MessageReceivedHandler receive_handler; | ||
104 | |||
105 | /** | ||
106 | * Closure for the receive handler | ||
107 | */ | ||
108 | void *receive_cls; | ||
109 | |||
110 | }; | ||
111 | |||
112 | |||
113 | /** | ||
114 | * Try to (re)connect to the dv service. | ||
115 | * | ||
116 | * @return GNUNET_YES on success, GNUNET_NO on failure. | ||
117 | */ | ||
118 | static int | ||
119 | try_connect (struct GNUNET_DV_Handle *ret) | ||
120 | { | ||
121 | if (ret->client != NULL) | ||
122 | return GNUNET_OK; | ||
123 | ret->client = GNUNET_CLIENT_connect (ret->sched, "dv", ret->cfg); | ||
124 | if (ret->client != NULL) | ||
125 | return GNUNET_YES; | ||
126 | #if DEBUG_STATISTICS | ||
127 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
128 | _("Failed to connect to the dv service!\n")); | ||
129 | #endif | ||
130 | return GNUNET_NO; | ||
131 | } | ||
132 | |||
133 | static void process_pending_message(struct GNUNET_DV_Handle *handle); | ||
134 | |||
135 | /** | ||
136 | * Send complete, schedule next | ||
137 | */ | ||
138 | static void | ||
139 | finish (struct GNUNET_DV_Handle *handle, int code) | ||
140 | { | ||
141 | struct PendingMessages *pos = handle->current; | ||
142 | handle->current = NULL; | ||
143 | process_pending_message (handle); | ||
144 | |||
145 | GNUNET_free (pos); | ||
146 | } | ||
147 | |||
148 | |||
149 | static size_t | ||
150 | transmit_pending (void *cls, size_t size, void *buf) | ||
151 | { | ||
152 | struct GNUNET_DV_Handle *handle = cls; | ||
153 | size_t ret; | ||
154 | |||
155 | if (buf == NULL) | ||
156 | { | ||
157 | finish(handle, GNUNET_SYSERR); | ||
158 | return 0; | ||
159 | } | ||
160 | handle->th = NULL; | ||
161 | |||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | /** | ||
166 | * Try to send messages from list of messages to send | ||
167 | */ | ||
168 | static void process_pending_message(struct GNUNET_DV_Handle *handle) | ||
169 | { | ||
170 | struct GNUNET_TIME_Relative timeout; | ||
171 | |||
172 | if (handle->current != NULL) | ||
173 | return; /* action already pending */ | ||
174 | if (GNUNET_YES != try_connect (handle)) | ||
175 | { | ||
176 | finish (handle, GNUNET_SYSERR); | ||
177 | return; | ||
178 | } | ||
179 | |||
180 | /* schedule next action */ | ||
181 | handle->current = handle->pending_list; | ||
182 | if (NULL == handle->current) | ||
183 | { | ||
184 | if (handle->do_destroy) | ||
185 | { | ||
186 | handle->do_destroy = GNUNET_NO; | ||
187 | //GNUNET_DV_disconnect (handle); /* FIXME: replace with proper disconnect stuffs */ | ||
188 | } | ||
189 | return; | ||
190 | } | ||
191 | handle->pending_list = handle->pending_list->next; | ||
192 | handle->current->next = NULL; | ||
193 | |||
194 | timeout = GNUNET_TIME_absolute_get_remaining (handle->current->timeout); | ||
195 | if (NULL == | ||
196 | (handle->th = GNUNET_CLIENT_notify_transmit_ready (handle->client, | ||
197 | ntohs(handle->current->msg->msgbuf_size), | ||
198 | timeout, | ||
199 | GNUNET_YES, | ||
200 | &transmit_pending, handle))) | ||
201 | { | ||
202 | #if DEBUG_STATISTICS | ||
203 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
204 | "Failed to transmit request to dv service.\n"); | ||
205 | #endif | ||
206 | finish (handle, GNUNET_SYSERR); | ||
207 | } | ||
208 | } | ||
209 | |||
210 | /** | ||
211 | * Add a pending message to the linked list | ||
212 | * | ||
213 | * @param handle handle to the specified DV api | ||
214 | * @param msg the message to add to the list | ||
215 | */ | ||
216 | static void add_pending(struct GNUNET_DV_Handle *handle, struct GNUNET_DV_SendMessage *msg) | ||
217 | { | ||
218 | struct PendingMessages *new_message; | ||
219 | struct PendingMessages *pos; | ||
220 | struct PendingMessages *last; | ||
221 | |||
222 | new_message = GNUNET_malloc(sizeof(struct PendingMessages)); | ||
223 | new_message->msg = msg; | ||
224 | |||
225 | if (handle->pending_list != NULL) | ||
226 | { | ||
227 | pos = handle->pending_list; | ||
228 | while(pos != NULL) | ||
229 | { | ||
230 | last = pos; | ||
231 | pos = pos->next; | ||
232 | } | ||
233 | new_message->next = last->next; /* Should always be null */ | ||
234 | last->next = new_message; | ||
235 | } | ||
236 | else | ||
237 | { | ||
238 | new_message->next = handle->pending_list; /* Will always be null */ | ||
239 | handle->pending_list = new_message; | ||
240 | } | ||
241 | |||
242 | process_pending_message(handle); | ||
243 | } | ||
244 | |||
245 | |||
246 | |||
247 | |||
248 | void handle_message_receipt (void *cls, | ||
249 | const struct GNUNET_MessageHeader * msg) | ||
250 | { | ||
251 | struct GNUNET_DV_Handle *handle = cls; | ||
252 | struct GNUNET_DV_MessageReceived *received_msg; | ||
253 | char *sender_address; | ||
254 | |||
255 | GNUNET_assert(ntohs(msg->type) == GNUNET_MESSAGE_TYPE_TRANSPORT_DV_RECEIVE); | ||
256 | |||
257 | if (ntohs(msg->size) < sizeof(struct GNUNET_DV_MessageReceived)) | ||
258 | return; | ||
259 | |||
260 | received_msg = (struct GNUNET_DV_MessageReceived *)msg; | ||
261 | GNUNET_assert(ntohs(msg->size) == (sizeof(struct GNUNET_DV_MessageReceived) + ntohs(received_msg->msg->size) + ntohs(received_msg->sender_address_len))); | ||
262 | |||
263 | sender_address = GNUNET_malloc(ntohs(received_msg->sender_address_len)); | ||
264 | sender_address = memcpy(sender_address, &received_msg[1], ntohs(received_msg->sender_address_len)); | ||
265 | |||
266 | handle->receive_handler(handle->receive_cls, | ||
267 | received_msg->sender, | ||
268 | received_msg->msg, | ||
269 | ntohl(received_msg->distance), | ||
270 | sender_address, | ||
271 | ntohs(received_msg->sender_address_len)); | ||
272 | |||
273 | GNUNET_free(sender_address); | ||
274 | |||
275 | GNUNET_CLIENT_receive (handle->client, | ||
276 | &handle_message_receipt, | ||
277 | handle, GNUNET_TIME_UNIT_FOREVER_REL); | ||
278 | } | ||
279 | |||
280 | /** | ||
281 | * Send a message from the plugin to the DV service indicating that | ||
282 | * a message should be sent via DV to some peer. | ||
283 | * | ||
284 | * @target the final target of the message | ||
285 | * @msgbuf the msg(s) to send | ||
286 | * @msgbuf_size the size of msgbuf | ||
287 | * @priority priority to pass on to core when sending the message | ||
288 | * @timeout how long can this message be delayed (pass through to core) | ||
289 | * @addr the address of this peer (internally known to DV) | ||
290 | * @addrlen the length of the peer address | ||
291 | * | ||
292 | */ | ||
293 | int GNUNET_DV_send (struct GNUNET_DV_Handle *dv_handle, | ||
294 | const struct GNUNET_PeerIdentity *target, | ||
295 | const char *msgbuf, | ||
296 | size_t msgbuf_size, | ||
297 | unsigned int priority, | ||
298 | struct GNUNET_TIME_Relative timeout, | ||
299 | const void *addr, | ||
300 | size_t addrlen) | ||
301 | { | ||
302 | struct GNUNET_DV_SendMessage *msg; | ||
303 | |||
304 | msg = GNUNET_malloc(sizeof(struct GNUNET_DV_SendMessage) + msgbuf_size + addrlen); | ||
305 | msg->header.size = htons(sizeof(struct GNUNET_DV_SendMessage) + msgbuf_size + addrlen); | ||
306 | msg->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND); | ||
307 | memcpy(&msg->target, target, sizeof(struct GNUNET_PeerIdentity)); | ||
308 | msg->msgbuf = GNUNET_malloc(msgbuf_size); | ||
309 | memcpy(msg->msgbuf, msgbuf, msgbuf_size); | ||
310 | msg->msgbuf_size = htons(msgbuf_size); | ||
311 | msg->priority = htonl(priority); | ||
312 | msg->timeout = timeout; | ||
313 | msg->addrlen = htons(addrlen); | ||
314 | memcpy(&msg[1], addr, addrlen); | ||
315 | |||
316 | add_pending(dv_handle, msg); | ||
317 | process_pending_message(dv_handle); | ||
318 | |||
319 | return GNUNET_OK; | ||
320 | } | ||
321 | |||
322 | /** | ||
323 | * Connect to the DV service | ||
324 | * | ||
325 | * @param sched the scheduler to use | ||
326 | * @param cfg the configuration to use | ||
327 | * | ||
328 | * @return handle to the DV service | ||
329 | */ | ||
330 | struct GNUNET_DV_Handle * | ||
331 | GNUNET_DV_connect (struct GNUNET_SCHEDULER_Handle *sched, | ||
332 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
333 | GNUNET_DV_MessageReceivedHandler receive_handler, | ||
334 | void *receive_handler_cls) | ||
335 | { | ||
336 | struct GNUNET_DV_Handle *handle; | ||
337 | |||
338 | handle = GNUNET_malloc(sizeof(struct GNUNET_DV_Handle)); | ||
339 | |||
340 | handle->cfg = cfg; | ||
341 | handle->sched = sched; | ||
342 | handle->pending_list = NULL; | ||
343 | handle->current = NULL; | ||
344 | handle->do_destroy = GNUNET_NO; | ||
345 | handle->th = NULL; | ||
346 | handle->client = GNUNET_CLIENT_connect(sched, "dv", cfg); | ||
347 | handle->receive_handler = receive_handler; | ||
348 | handle->receive_cls = receive_handler_cls; | ||
349 | |||
350 | if (handle->client == NULL) | ||
351 | return NULL; | ||
352 | |||
353 | GNUNET_CLIENT_receive (handle->client, | ||
354 | &handle_message_receipt, | ||
355 | handle, GNUNET_TIME_UNIT_FOREVER_REL); | ||
356 | |||
357 | return handle; | ||
358 | } | ||
359 | |||
360 | /** | ||
361 | * Disconnect from the DV service | ||
362 | * | ||
363 | * @param handle the current handle to the service to disconnect | ||
364 | */ | ||
365 | void GNUNET_DV_disconnect(struct GNUNET_DV_Handle *handle) | ||
366 | { | ||
367 | struct PendingMessages *pos; | ||
368 | |||
369 | GNUNET_assert(handle != NULL); | ||
370 | |||
371 | if (handle->th != NULL) /* We have a live transmit request in the Aether */ | ||
372 | { | ||
373 | GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th); | ||
374 | handle->th = NULL; | ||
375 | } | ||
376 | if (handle->current != NULL) /* We are trying to send something now, clean it up */ | ||
377 | GNUNET_free(handle->current); | ||
378 | while (NULL != (pos = handle->pending_list)) /* Remove all pending sends from the list */ | ||
379 | { | ||
380 | handle->pending_list = pos->next; | ||
381 | GNUNET_free(pos); | ||
382 | } | ||
383 | if (handle->client != NULL) /* Finally, disconnect from the service */ | ||
384 | { | ||
385 | GNUNET_CLIENT_disconnect (handle->client); | ||
386 | handle->client = NULL; | ||
387 | } | ||
388 | |||
389 | GNUNET_free (handle); | ||
390 | } | ||
391 | |||
392 | /* end of dv_api.c */ | ||
diff --git a/src/dv/gnunet-service-dv.c b/src/dv/gnunet-service-dv.c new file mode 100644 index 000000000..92f5c96aa --- /dev/null +++ b/src/dv/gnunet-service-dv.c | |||
@@ -0,0 +1,278 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2009 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 2, 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 | * @file dv/gnunet-service-dv.c | ||
23 | * @brief the distance vector service, primarily handles gossip of nearby | ||
24 | * peers and sending/receiving DV messages from core and decapsulating | ||
25 | * them | ||
26 | * | ||
27 | * @author Christian Grothoff | ||
28 | * @author Nathan Evans | ||
29 | * | ||
30 | */ | ||
31 | #include "platform.h" | ||
32 | #include "gnunet_client_lib.h" | ||
33 | #include "gnunet_getopt_lib.h" | ||
34 | #include "gnunet_os_lib.h" | ||
35 | #include "gnunet_protocols.h" | ||
36 | #include "gnunet_service_lib.h" | ||
37 | #include "gnunet_core_service.h" | ||
38 | #include "gnunet_signal_lib.h" | ||
39 | #include "dv.h" | ||
40 | |||
41 | /** | ||
42 | * DV Service Context stuff goes here... | ||
43 | */ | ||
44 | static struct GNUNET_CORE_Handle *coreAPI; | ||
45 | |||
46 | static struct GNUNET_PeerIdentity *my_identity; | ||
47 | |||
48 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
49 | |||
50 | struct GNUNET_SCHEDULER_Handle *sched; | ||
51 | |||
52 | GNUNET_SCHEDULER_TaskIdentifier cleanup_task; | ||
53 | |||
54 | /** | ||
55 | * Core handler for dv data messages. Whatever this message | ||
56 | * contains all we really have to do is rip it out of its | ||
57 | * DV layering and give it to our pal the DV plugin to report | ||
58 | * in with. | ||
59 | * | ||
60 | * @param cls closure | ||
61 | * @param client identification of the client | ||
62 | * @param message the actual message | ||
63 | */ | ||
64 | void handle_dv_data_message (void *cls, | ||
65 | struct GNUNET_SERVER_Client * | ||
66 | client, | ||
67 | const struct | ||
68 | GNUNET_MessageHeader * | ||
69 | message) | ||
70 | { | ||
71 | #if DEBUG_DV | ||
72 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
73 | "%s: Receives %s message!\n", "dv", "DV DATA"); | ||
74 | #endif | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * Core handler for dv gossip messages. These will be used | ||
79 | * by us to create a HELLO message for the newly peer containing | ||
80 | * which direct peer we can connect through, and what the cost | ||
81 | * is. This HELLO will then be scheduled for validation by the | ||
82 | * transport service so that it can be used by all others. | ||
83 | * | ||
84 | * @param cls closure | ||
85 | * @param client identification of the client | ||
86 | * @param message the actual message | ||
87 | */ | ||
88 | void handle_dv_gossip_message (void *cls, | ||
89 | struct GNUNET_SERVER_Client * | ||
90 | client, | ||
91 | const struct GNUNET_MessageHeader * | ||
92 | message) | ||
93 | { | ||
94 | #if DEBUG_DV | ||
95 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
96 | "%s: Receives %s message!\n", "dv", "DV GOSSIP"); | ||
97 | #endif | ||
98 | } | ||
99 | |||
100 | |||
101 | /** | ||
102 | * Service server's handler for message send requests (which come | ||
103 | * bubbling up to us through the DV plugin). | ||
104 | * | ||
105 | * @param cls closure | ||
106 | * @param client identification of the client | ||
107 | * @param message the actual message | ||
108 | */ | ||
109 | void send_dv_message (void *cls, | ||
110 | struct GNUNET_SERVER_Client * client, | ||
111 | const struct GNUNET_MessageHeader * message) | ||
112 | { | ||
113 | #if DEBUG_DV | ||
114 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
115 | "%s: Receives %s message!\n", "dv", "SEND"); | ||
116 | #endif | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * List of handlers for the messages understood by this | ||
121 | * service. | ||
122 | * | ||
123 | * Hmm... will we need to register some handlers with core and | ||
124 | * some handlers with our server here? Because core should be | ||
125 | * getting the incoming DV messages (from whichever lower level | ||
126 | * transport) and then our server should be getting messages | ||
127 | * from the dv_plugin, right? | ||
128 | */ | ||
129 | static struct GNUNET_SERVER_MessageHandler core_handlers[] = { | ||
130 | {&handle_dv_data_message, NULL, GNUNET_MESSAGE_TYPE_DV_DATA, 0}, | ||
131 | {&handle_dv_gossip_message, NULL, GNUNET_MESSAGE_TYPE_DV_GOSSIP, 0}, | ||
132 | {NULL, NULL, 0, 0} | ||
133 | }; | ||
134 | |||
135 | static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = { | ||
136 | {&send_dv_message, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND, 0}, | ||
137 | {NULL, NULL, 0, 0} | ||
138 | }; | ||
139 | |||
140 | |||
141 | /** | ||
142 | * Task run during shutdown. | ||
143 | * | ||
144 | * @param cls unused | ||
145 | * @param tc unused | ||
146 | */ | ||
147 | static void | ||
148 | shutdown_task (void *cls, | ||
149 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
150 | { | ||
151 | |||
152 | GNUNET_CORE_disconnect (coreAPI); | ||
153 | } | ||
154 | |||
155 | /** | ||
156 | * To be called on core init/fail. | ||
157 | */ | ||
158 | void core_init (void *cls, | ||
159 | struct GNUNET_CORE_Handle * server, | ||
160 | const struct GNUNET_PeerIdentity *my_identity, | ||
161 | const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded * publicKey) | ||
162 | { | ||
163 | |||
164 | if (server == NULL) | ||
165 | { | ||
166 | GNUNET_SCHEDULER_cancel(sched, cleanup_task); | ||
167 | GNUNET_SCHEDULER_add_now(sched, &shutdown_task, NULL); | ||
168 | } | ||
169 | #if DEBUG_DV | ||
170 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
171 | "%s: Core initialized, I am peer: %s\n", "dv", GNUNET_i2s(my_identity)); | ||
172 | #endif | ||
173 | coreAPI = server; | ||
174 | } | ||
175 | |||
176 | /** | ||
177 | * Method called whenever a given peer either connects. | ||
178 | * | ||
179 | * @param cls closure | ||
180 | * @param peer peer identity this notification is about | ||
181 | * @param latency reported latency of the connection with 'other' | ||
182 | * @param distance reported distance (DV) to 'other' | ||
183 | */ | ||
184 | void handle_core_connect (void *cls, | ||
185 | const struct GNUNET_PeerIdentity * peer, | ||
186 | struct GNUNET_TIME_Relative latency, | ||
187 | uint32_t distance) | ||
188 | { | ||
189 | |||
190 | #if DEBUG_DV | ||
191 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
192 | "%s: Receives core connect message!\n", "dv"); | ||
193 | #endif | ||
194 | } | ||
195 | |||
196 | /** | ||
197 | * Method called whenever a given peer either connects. | ||
198 | * | ||
199 | * @param cls closure | ||
200 | * @param peer peer identity this notification is about | ||
201 | * @param latency reported latency of the connection with 'other' | ||
202 | * @param distance reported distance (DV) to 'other' | ||
203 | */ | ||
204 | void handle_core_disconnect (void *cls, | ||
205 | const struct GNUNET_PeerIdentity * peer, | ||
206 | struct GNUNET_TIME_Relative latency, | ||
207 | uint32_t distance) | ||
208 | { | ||
209 | #if DEBUG_DV | ||
210 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
211 | "%s: Receives core disconnect message!\n", "dv"); | ||
212 | #endif | ||
213 | } | ||
214 | |||
215 | |||
216 | /** | ||
217 | * Process dv requests. | ||
218 | * | ||
219 | * @param cls closure | ||
220 | * @param sched scheduler to use | ||
221 | * @param server the initialized server | ||
222 | * @param c configuration to use | ||
223 | */ | ||
224 | static void | ||
225 | run (void *cls, | ||
226 | struct GNUNET_SCHEDULER_Handle *scheduler, | ||
227 | struct GNUNET_SERVER_Handle *server, | ||
228 | const struct GNUNET_CONFIGURATION_Handle *c) | ||
229 | { | ||
230 | struct GNUNET_TIME_Relative timeout; | ||
231 | sched = scheduler; | ||
232 | cfg = c; | ||
233 | GNUNET_SERVER_add_handlers (server, plugin_handlers); | ||
234 | coreAPI = | ||
235 | GNUNET_CORE_connect (sched, | ||
236 | cfg, | ||
237 | timeout, | ||
238 | NULL, /* FIXME: anything we want to pass around? */ | ||
239 | &core_init, | ||
240 | NULL, /* Don't care about pre-connects */ | ||
241 | &handle_core_connect, | ||
242 | &handle_core_disconnect, | ||
243 | NULL, | ||
244 | NULL, | ||
245 | NULL, | ||
246 | NULL, | ||
247 | core_handlers); | ||
248 | |||
249 | if (coreAPI == NULL) | ||
250 | return; | ||
251 | /* load (server); Huh? */ | ||
252 | |||
253 | /* Scheduled the task to clean up when shutdown is called */ | ||
254 | |||
255 | cleanup_task = GNUNET_SCHEDULER_add_delayed (sched, | ||
256 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
257 | &shutdown_task, | ||
258 | NULL); | ||
259 | } | ||
260 | |||
261 | |||
262 | /** | ||
263 | * The main function for the dv service. | ||
264 | * | ||
265 | * @param argc number of arguments from the command line | ||
266 | * @param argv command line arguments | ||
267 | * @return 0 ok, 1 on error | ||
268 | */ | ||
269 | int | ||
270 | main (int argc, char *const *argv) | ||
271 | { | ||
272 | return (GNUNET_OK == | ||
273 | GNUNET_SERVICE_run (argc, | ||
274 | argv, | ||
275 | "dv", | ||
276 | GNUNET_SERVICE_OPTION_NONE, | ||
277 | &run, NULL)) ? 0 : 1; | ||
278 | } | ||
diff --git a/src/dv/plugin_transport_dv.c b/src/dv/plugin_transport_dv.c new file mode 100644 index 000000000..aa25c97e6 --- /dev/null +++ b/src/dv/plugin_transport_dv.c | |||
@@ -0,0 +1,400 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 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 2, 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 | * @file transport/plugin_transport_dv.c | ||
23 | * @brief DV transport service, takes incoming DV requests and deals with | ||
24 | * the DV service | ||
25 | * @author Christian Grothoff | ||
26 | */ | ||
27 | |||
28 | /** | ||
29 | * TODO: | ||
30 | * | ||
31 | * As a start, the dv plugin needs to listen for information from the dv | ||
32 | * service. The plugin (?) will be notified by core (?) when a tcp/udp/whatever | ||
33 | * message comes in that should be for dv. The plugin will then hand off the message | ||
34 | * to the dv service which will decrypt/validate the message (?) and then send the | ||
35 | * result back to us (the transport) which will then send the message to the transport | ||
36 | * service (yikes). | ||
37 | * | ||
38 | * Or, core will notify the dv service directly which will validate, | ||
39 | * etc. and then just send a message to us. | ||
40 | * | ||
41 | * For starters, this plugin needs to have a client which will listen for messages from | ||
42 | * the dv service that need to be sent up to the gnunet-transport-service. | ||
43 | * | ||
44 | * Messages sent from the dv transport get passed to the dv service which deals | ||
45 | * with the actual sending (how much state does this transport need? should it know | ||
46 | * which peers it is currently connected to and their distances, or just assume that | ||
47 | * anything should be passed along to the dv service?). | ||
48 | */ | ||
49 | #include "platform.h" | ||
50 | #include "gnunet_protocols.h" | ||
51 | #include "gnunet_connection_lib.h" | ||
52 | #include "gnunet_server_lib.h" | ||
53 | #include "gnunet_service_lib.h" | ||
54 | #include "gnunet_statistics_service.h" | ||
55 | #include "gnunet_dv_service.h" | ||
56 | #include "gnunet_transport_service.h" | ||
57 | #include "../transport/plugin_transport.h" | ||
58 | #include "dv.h" | ||
59 | |||
60 | #define DEBUG_TEMPLATE GNUNET_NO | ||
61 | |||
62 | /** | ||
63 | * Encapsulation of all of the state of the plugin. | ||
64 | */ | ||
65 | struct Plugin; | ||
66 | |||
67 | |||
68 | /** | ||
69 | * Session handle for connections. | ||
70 | */ | ||
71 | struct Session | ||
72 | { | ||
73 | |||
74 | /** | ||
75 | * Stored in a linked list. | ||
76 | */ | ||
77 | struct Session *next; | ||
78 | |||
79 | /** | ||
80 | * Pointer to the global plugin struct. | ||
81 | */ | ||
82 | struct Plugin *plugin; | ||
83 | |||
84 | /** | ||
85 | * The client (used to identify this connection) | ||
86 | */ | ||
87 | /* void *client; */ | ||
88 | |||
89 | /** | ||
90 | * Continuation function to call once the transmission buffer | ||
91 | * has again space available. NULL if there is no | ||
92 | * continuation to call. | ||
93 | */ | ||
94 | GNUNET_TRANSPORT_TransmitContinuation transmit_cont; | ||
95 | |||
96 | /** | ||
97 | * Closure for transmit_cont. | ||
98 | */ | ||
99 | void *transmit_cont_cls; | ||
100 | |||
101 | /** | ||
102 | * To whom are we talking to (set to our identity | ||
103 | * if we are still waiting for the welcome message) | ||
104 | */ | ||
105 | struct GNUNET_PeerIdentity sender; | ||
106 | |||
107 | /** | ||
108 | * At what time did we reset last_received last? | ||
109 | */ | ||
110 | struct GNUNET_TIME_Absolute last_quota_update; | ||
111 | |||
112 | /** | ||
113 | * How many bytes have we received since the "last_quota_update" | ||
114 | * timestamp? | ||
115 | */ | ||
116 | uint64_t last_received; | ||
117 | |||
118 | /** | ||
119 | * Number of bytes per ms that this peer is allowed | ||
120 | * to send to us. | ||
121 | */ | ||
122 | uint32_t quota; | ||
123 | |||
124 | }; | ||
125 | |||
126 | /** | ||
127 | * Encapsulation of all of the state of the plugin. | ||
128 | */ | ||
129 | struct Plugin | ||
130 | { | ||
131 | /** | ||
132 | * Our environment. | ||
133 | */ | ||
134 | struct GNUNET_TRANSPORT_PluginEnvironment *env; | ||
135 | |||
136 | /** | ||
137 | * List of open sessions. | ||
138 | */ | ||
139 | struct Session *sessions; | ||
140 | |||
141 | /** | ||
142 | * Handle for the statistics service. | ||
143 | */ | ||
144 | struct GNUNET_STATISTICS_Handle *statistics; | ||
145 | |||
146 | /** | ||
147 | * Our server. | ||
148 | */ | ||
149 | struct GNUNET_SERVER_Handle *server; | ||
150 | |||
151 | /* | ||
152 | * Handle to the running service. | ||
153 | */ | ||
154 | struct GNUNET_SERVICE_Context *service; | ||
155 | |||
156 | /** | ||
157 | * Copy of the handler array where the closures are | ||
158 | * set to this struct's instance. | ||
159 | */ | ||
160 | struct GNUNET_SERVER_MessageHandler *handlers; | ||
161 | |||
162 | /** | ||
163 | * Handle to the DV service | ||
164 | */ | ||
165 | struct GNUNET_DV_Handle *dv_handle; | ||
166 | |||
167 | }; | ||
168 | |||
169 | |||
170 | void handle_dv_message_received (void *cls, | ||
171 | struct GNUNET_PeerIdentity *sender, | ||
172 | struct GNUNET_MessageHeader *msg, | ||
173 | unsigned int distance, | ||
174 | char *sender_address, | ||
175 | size_t sender_address_len) | ||
176 | { | ||
177 | struct Plugin *plugin = cls; | ||
178 | |||
179 | plugin->env->receive(plugin, | ||
180 | sender, | ||
181 | msg, | ||
182 | distance, | ||
183 | sender_address, | ||
184 | sender_address_len); | ||
185 | |||
186 | } | ||
187 | |||
188 | |||
189 | /* Question: how does the transport service learn of a newly connected (gossipped about) | ||
190 | * DV peer? Should the plugin (here) create a HELLO for that peer and send it along, | ||
191 | * or should the DV service create a HELLO and send it to us via the other part? | ||
192 | */ | ||
193 | |||
194 | /** | ||
195 | * Function that can be used by the transport service to transmit | ||
196 | * a message using the plugin. | ||
197 | * | ||
198 | * @param cls closure | ||
199 | * @param target who should receive this message | ||
200 | * @param priority how important is the message | ||
201 | * @param msgbuf the message to transmit | ||
202 | * @param msgbuf_size number of bytes in 'msgbuf' | ||
203 | * @param timeout when should we time out | ||
204 | * @param addr the address to use (can be NULL if the plugin | ||
205 | * is "on its own" (i.e. re-use existing TCP connection)) | ||
206 | * @param addrlen length of the address in bytes | ||
207 | * @param force_address GNUNET_YES if the plugin MUST use the given address, | ||
208 | * otherwise the plugin may use other addresses or | ||
209 | * existing connections (if available) | ||
210 | * @param cont continuation to call once the message has | ||
211 | * been transmitted (or if the transport is ready | ||
212 | * for the next transmission call; or if the | ||
213 | * peer disconnected...) | ||
214 | * @param cont_cls closure for cont | ||
215 | * @return number of bytes used (on the physical network, with overheads); | ||
216 | * -1 on hard errors (i.e. address invalid); 0 is a legal value | ||
217 | * and does NOT mean that the message was not transmitted (DV) | ||
218 | */ | ||
219 | static ssize_t | ||
220 | dv_plugin_send (void *cls, | ||
221 | const struct GNUNET_PeerIdentity *target, | ||
222 | const char *msgbuf, | ||
223 | size_t msgbuf_size, | ||
224 | unsigned int priority, | ||
225 | struct GNUNET_TIME_Relative timeout, | ||
226 | const void *addr, | ||
227 | size_t addrlen, | ||
228 | int force_address, | ||
229 | GNUNET_TRANSPORT_TransmitContinuation | ||
230 | cont, void *cont_cls) | ||
231 | { | ||
232 | int ret = 0; | ||
233 | struct Plugin *plugin = cls; | ||
234 | |||
235 | /* FIXME: do we want the dv plugin to remember sent messages to call continuation once message actually goes out? | ||
236 | * Or do we just call the continuation once we've notified the plugin? | ||
237 | */ | ||
238 | ret = GNUNET_DV_send(plugin->dv_handle, | ||
239 | target, | ||
240 | msgbuf, | ||
241 | msgbuf_size, | ||
242 | priority, | ||
243 | timeout, | ||
244 | addr, | ||
245 | addrlen); | ||
246 | /*, cont, cont_cls);*/ | ||
247 | |||
248 | if (ret == 0) | ||
249 | cont(cls, target, GNUNET_OK); | ||
250 | else | ||
251 | cont(cls, target, GNUNET_SYSERR); | ||
252 | |||
253 | return ret; | ||
254 | } | ||
255 | |||
256 | |||
257 | |||
258 | /** | ||
259 | * Function that can be used to force the plugin to disconnect | ||
260 | * from the given peer and cancel all previous transmissions | ||
261 | * (and their continuations). | ||
262 | * | ||
263 | * @param cls closure | ||
264 | * @param target peer from which to disconnect | ||
265 | */ | ||
266 | static void | ||
267 | dv_plugin_disconnect (void *cls, | ||
268 | const struct GNUNET_PeerIdentity *target) | ||
269 | { | ||
270 | // struct Plugin *plugin = cls; | ||
271 | // FIXME | ||
272 | } | ||
273 | |||
274 | |||
275 | /** | ||
276 | * Convert the transports address to a nice, human-readable | ||
277 | * format. | ||
278 | * | ||
279 | * @param cls closure | ||
280 | * @param type name of the transport that generated the address | ||
281 | * @param addr one of the addresses of the host, NULL for the last address | ||
282 | * the specific address format depends on the transport | ||
283 | * @param addrlen length of the address | ||
284 | * @param numeric should (IP) addresses be displayed in numeric form? | ||
285 | * @param timeout after how long should we give up? | ||
286 | * @param asc function to call on each string | ||
287 | * @param asc_cls closure for asc | ||
288 | */ | ||
289 | static void | ||
290 | dv_plugin_address_pretty_printer (void *cls, | ||
291 | const char *type, | ||
292 | const void *addr, | ||
293 | size_t addrlen, | ||
294 | int numeric, | ||
295 | struct GNUNET_TIME_Relative timeout, | ||
296 | GNUNET_TRANSPORT_AddressStringCallback | ||
297 | asc, void *asc_cls) | ||
298 | { | ||
299 | asc (asc_cls, NULL); | ||
300 | } | ||
301 | |||
302 | |||
303 | |||
304 | /** | ||
305 | * Another peer has suggested an address for this | ||
306 | * peer and transport plugin. Check that this could be a valid | ||
307 | * address. If so, consider adding it to the list | ||
308 | * of addresses. | ||
309 | * | ||
310 | * @param cls closure | ||
311 | * @param addr pointer to the address | ||
312 | * @param addrlen length of addr | ||
313 | * @return GNUNET_OK if this is a plausible address for this peer | ||
314 | * and transport | ||
315 | * | ||
316 | * FIXME: does this mean anything for the DV plugin? | ||
317 | */ | ||
318 | static int | ||
319 | dv_plugin_address_suggested (void *cls, | ||
320 | void *addr, size_t addrlen) | ||
321 | { | ||
322 | /* struct Plugin *plugin = cls; */ | ||
323 | |||
324 | /* check if the address is plausible; if so, | ||
325 | add it to our list! */ | ||
326 | return GNUNET_OK; | ||
327 | } | ||
328 | |||
329 | |||
330 | /** | ||
331 | * Entry point for the plugin. | ||
332 | */ | ||
333 | void * | ||
334 | gnunet_plugin_transport_dv_init (void *cls) | ||
335 | { | ||
336 | struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; | ||
337 | struct GNUNET_TRANSPORT_PluginFunctions *api; | ||
338 | struct Plugin *plugin; | ||
339 | unsigned long long port; | ||
340 | struct GNUNET_SERVICE_Context *service; | ||
341 | |||
342 | service = GNUNET_SERVICE_start ("transport-dv", env->sched, env->cfg); | ||
343 | if (service == NULL) | ||
344 | { | ||
345 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | ||
346 | "dv", | ||
347 | _ | ||
348 | ("Failed to start service for `%s' transport plugin.\n"), | ||
349 | "dv"); | ||
350 | return NULL; | ||
351 | } | ||
352 | |||
353 | if ((GNUNET_OK != | ||
354 | GNUNET_CONFIGURATION_get_value_number (env->cfg, | ||
355 | "transport-dv", | ||
356 | "PORT", | ||
357 | &port))) | ||
358 | { | ||
359 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
360 | "dv", | ||
361 | _ | ||
362 | ("Require valid port number for service `%s' in configuration!\n"), | ||
363 | "transport-dv"); | ||
364 | GNUNET_SERVICE_stop (service); | ||
365 | return NULL; | ||
366 | } | ||
367 | |||
368 | plugin = GNUNET_malloc (sizeof (struct Plugin)); | ||
369 | plugin->env = env; | ||
370 | plugin->statistics = NULL; | ||
371 | plugin->service = service; | ||
372 | plugin->server = GNUNET_SERVICE_get_server (service); | ||
373 | |||
374 | plugin->dv_handle = GNUNET_DV_connect(env->sched, env->cfg, &handle_dv_message_received, plugin); | ||
375 | |||
376 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | ||
377 | api->cls = plugin; | ||
378 | api->send = &dv_plugin_send; | ||
379 | api->disconnect = &dv_plugin_disconnect; | ||
380 | api->address_pretty_printer = &dv_plugin_address_pretty_printer; | ||
381 | api->check_address = &dv_plugin_address_suggested; | ||
382 | return api; | ||
383 | } | ||
384 | |||
385 | |||
386 | /** | ||
387 | * Exit point from the plugin. | ||
388 | */ | ||
389 | void * | ||
390 | gnunet_plugin_transport_dv_done (void *cls) | ||
391 | { | ||
392 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | ||
393 | struct Plugin *plugin = api->cls; | ||
394 | |||
395 | GNUNET_free (plugin); | ||
396 | GNUNET_free (api); | ||
397 | return NULL; | ||
398 | } | ||
399 | |||
400 | /* end of plugin_transport_template.c */ | ||