aboutsummaryrefslogtreecommitdiff
path: root/src/dv
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-03-12 12:56:19 +0000
committerChristian Grothoff <christian@grothoff.org>2013-03-12 12:56:19 +0000
commit00f89992860b261ba6f938b77392a433f3dec91b (patch)
tree11e912177df58875c68d8129265c00f49fb7c7cb /src/dv
parent6e8793e115782b277ed97e6072a3fd87c75d4707 (diff)
downloadgnunet-00f89992860b261ba6f938b77392a433f3dec91b.tar.gz
gnunet-00f89992860b261ba6f938b77392a433f3dec91b.zip
-hacking on dv
Diffstat (limited to 'src/dv')
-rw-r--r--src/dv/Makefile.am17
-rw-r--r--src/dv/dv.h215
-rw-r--r--src/dv/dv_api.c148
-rw-r--r--src/dv/gnunet-service-dv.c2212
-rw-r--r--src/dv/gnunet_dv_service.h143
-rw-r--r--src/dv/plugin_transport_dv.c170
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
23plugin_LTLIBRARIES = libgnunet_plugin_transport_dv.la 23plugin_LTLIBRARIES = libgnunet_plugin_transport_dv.la
24 24
25libgnunetdv_la_SOURCES = \ 25libgnunetdv_la_SOURCES = \
26 dv_api.c dv.h 26 dv_api.c dv.h gnunet_dv_service.h
27libgnunetdv_la_LIBADD = \ 27libgnunetdv_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)
31libgnunetdv_la_LDFLAGS = \ 30libgnunetdv_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
39gnunet_service_dv_SOURCES = \ 38gnunet_service_dv_SOURCES = \
40 gnunet-service-dv.c 39 gnunet-service-dv.c dv.h
41gnunet_service_dv_LDADD = \ 40gnunet_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)
49gnunet_service_dv_DEPENDENCIES = \
50 libgnunetdv.la
51 45
52libgnunet_plugin_transport_dv_la_SOURCES = \ 46libgnunet_plugin_transport_dv_la_SOURCES = \
53 plugin_transport_dv.c 47 plugin_transport_dv.c
54libgnunet_plugin_transport_dv_la_LIBADD = \ 48libgnunet_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
59libgnunet_plugin_transport_dv_la_LDFLAGS = \ 51libgnunet_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
79EXTRA_DIST = \ 71EXTRA_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
39typedef 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
47GNUNET_NETWORK_STRUCT_BEGIN 31GNUNET_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 */
56struct GNUNET_DV_MessageReceived 37struct 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 */
87struct GNUNET_DV_ConnectMessage 64struct 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 */
120struct GNUNET_DV_SendResultMessage 91struct 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 */
143struct GNUNET_DV_SendMessage 116struct 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 */
190typedef 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 */
220typedef struct 140struct 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 */
250typedef 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};
260GNUNET_NETWORK_STRUCT_END 158GNUNET_NETWORK_STRUCT_END
261 159
262struct GNUNET_DV_Handle *
263GNUNET_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 */
272void
273GNUNET_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 */
40struct 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 */
62struct 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 */
94struct GNUNET_DV_ServiceHandle *
95GNUNET_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 */
111void
112GNUNET_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 */
129struct GNUNET_DV_TransmitHandle *
130GNUNET_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 */
148void
149GNUNET_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/** 57GNUNET_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 */
121struct PendingMessage 64struct 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
165struct 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 */
187struct NeighborSendContext 84struct 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
106GNUNET_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 */
219struct NeighborUpdateInfo 112struct 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 */
252struct UnknownSenderMessage 146struct 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 */
285struct DirectNeighbor 176struct 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 */
332struct DistantNeighbor 203struct 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
403struct 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 */
426struct HelloContext 248struct 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
445struct 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 */ 270static 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
491struct FindDestinationContext
492{
493 unsigned int tid;
494 struct DistantNeighbor *dest;
495};
496
497struct FindIDContext
498{
499 unsigned int tid;
500 struct GNUNET_PeerIdentity *dest;
501 const struct GNUNET_PeerIdentity *via;
502};
503
504struct 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
517struct 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 */
276static 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}; 282static 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 */
539struct FindLeastCostContext 288static 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 */
548static struct GNUNET_CORE_Handle *coreAPI; 294static 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 */
553static struct GNUNET_SERVER_MessageStreamTokenizer *coreMST; 299static 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 */
563static const struct GNUNET_CONFIGURATION_Handle *cfg; 309static 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;
571static struct GNUNET_SERVER_Client *client_handle; 316static struct GNUNET_SERVER_Client *client_handle;
572 317
573/** 318/**
574 * Task to run when we shut down, cleaning up all our trash
575 */
576static GNUNET_SCHEDULER_TaskIdentifier cleanup_task;
577
578static size_t default_dv_priority = 0;
579
580static char *my_short_id;
581
582/**
583 * Transmit handle to the plugin. 319 * Transmit handle to the plugin.
584 */ 320 */
585static struct GNUNET_SERVER_TransmitHandle *plugin_transmit_handle; 321static struct GNUNET_SERVER_TransmitHandle *plugin_transmit_handle;
@@ -595,53 +331,6 @@ static struct PendingMessage *plugin_pending_head;
595static struct PendingMessage *plugin_pending_tail; 331static struct PendingMessage *plugin_pending_tail;
596 332
597/** 333/**
598 * Handle to the peerinfo service
599 */
600static struct GNUNET_PEERINFO_Handle *peerinfo_handle;
601
602/**
603 * Transmit handle to core service.
604 */
605static struct GNUNET_CORE_TransmitHandle *core_transmit_handle;
606
607/**
608 * Head of DLL for core messages
609 */
610static struct PendingMessage *core_pending_head;
611
612/**
613 * Tail of DLL for core messages
614 */
615static struct PendingMessage *core_pending_tail;
616
617/**
618 * Map of PeerIdentifiers to 'struct GNUNET_dv_neighbor*'s for all
619 * directly connected peers.
620 */
621static 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 */
629static 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 */
635static 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 */
642static struct GNUNET_CONTAINER_Heap *neighbor_max_heap;
643
644/**
645 * Handle for the statistics service. 334 * Handle for the statistics service.
646 */ 335 */
647struct GNUNET_STATISTICS_Handle *stats; 336struct GNUNET_STATISTICS_Handle *stats;
@@ -651,71 +340,27 @@ struct GNUNET_STATISTICS_Handle *stats;
651 */ 340 */
652static unsigned long long fisheye_depth; 341static unsigned long long fisheye_depth;
653 342
654/**
655 * How many peers to store at most.
656 */
657static 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 */
664static int
665find_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 */
683static int 351static uint32_t
684find_specific_id (void *cls, const struct GNUNET_HashCode * key, void *value) 352get_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 */
706static int
707find_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 */
731size_t 376static size_t
732transmit_to_plugin (void *cls, size_t size, void *buf) 377transmit_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 */
782void 417static void
783send_to_plugin (const struct GNUNET_PeerIdentity *sender, 418send_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 */
861size_t
862core_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 */
867static void 469static void
868try_core_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 470send_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 */
899size_t 516static size_t
900core_transmit_notify (void *cls, size_t size, void *buf) 517core_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 */
1351static uint32_t
1352get_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 */
1398static int
1399handle_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 */
1823static void
1824handle_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 */
1874void
1875handle_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 **/
2076static int 1146static 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 */
2100static 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
2107static 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 */
2224static int
2225free_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 */
2242static int
2243free_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 */
2258static void
2259shutdown_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 */
2289void
2290core_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 */
2786static int
2787handle_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 */
2877static int
2878gossip_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 */
2901static void
2902gossip_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 */
2987static void
2988process_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 */
1882static int
1883handle_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 */
1901static void
1902handle_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 */
1920static int
1921cull_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 */
1946static int
1947cull_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 */
3176void 1968static void
3177handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) 1969handle_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 */
2023static int
2024free_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 */
2041static int
2042free_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 */
2061static int
2062free_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 */
2078static void
2079shutdown_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 */
2117static void
2118handle_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 */
2140static void
2141core_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
3257run (void *cls, struct GNUNET_SERVER_Handle *server, 2159run (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 */
36typedef 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 */
45typedef 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 */
58typedef 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 */
71typedef void (*GNUNET_DV_MessageSentCallback)(void *cls,
72 int ok);
73
74
75/**
76 * Handle to the DV service.
77 */
78struct 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 */
91struct GNUNET_DV_ServiceHandle *
92GNUNET_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 */
104void
105GNUNET_DV_service_disconnect (struct GNUNET_DV_ServiceHandle *sh);
106
107
108/**
109 * Handle for a send operation.
110 */
111struct 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 */
124struct GNUNET_DV_TransmitHandle *
125GNUNET_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 */
139void
140GNUNET_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 */
147void 143static void
148handle_dv_message_received (void *cls, struct GNUNET_PeerIdentity *sender, 144handle_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,
308static const char * 250static const char *
309address_to_string (void *cls, const void *addr, size_t addrlen) 251address_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)
355static int 273static int
356dv_plugin_check_address (void *cls, const void *addr, size_t addrlen) 274dv_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;