diff options
Diffstat (limited to 'src/ats')
-rw-r--r-- | src/ats/gnunet-service-ats_addresses.c | 151 |
1 files changed, 85 insertions, 66 deletions
diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c index eda7093e7..b55703cae 100644 --- a/src/ats/gnunet-service-ats_addresses.c +++ b/src/ats/gnunet-service-ats_addresses.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet-service-ats_addresses.h" | 28 | #include "gnunet-service-ats_addresses.h" |
29 | #include "gnunet-service-ats_scheduling.h" | 29 | #include "gnunet-service-ats_scheduling.h" |
30 | #include "gnunet-service-ats_reservations.h" | ||
30 | 31 | ||
31 | struct ATS_Address | 32 | struct ATS_Address |
32 | { | 33 | { |
@@ -40,7 +41,7 @@ struct ATS_Address | |||
40 | 41 | ||
41 | uint32_t ats_count; | 42 | uint32_t ats_count; |
42 | 43 | ||
43 | void * addr; | 44 | const void * addr; |
44 | 45 | ||
45 | char * plugin; | 46 | char * plugin; |
46 | 47 | ||
@@ -49,16 +50,18 @@ struct ATS_Address | |||
49 | struct GNUNET_BANDWIDTH_Value32NBO bw_in; | 50 | struct GNUNET_BANDWIDTH_Value32NBO bw_in; |
50 | 51 | ||
51 | struct GNUNET_BANDWIDTH_Value32NBO bw_out; | 52 | struct GNUNET_BANDWIDTH_Value32NBO bw_out; |
53 | |||
52 | }; | 54 | }; |
53 | 55 | ||
54 | 56 | ||
55 | static struct GNUNET_CONTAINER_MultiHashMap * addresses; | 57 | static struct GNUNET_CONTAINER_MultiHashMap * addresses; |
56 | 58 | ||
57 | |||
58 | static unsigned long long total_quota_in; | 59 | static unsigned long long total_quota_in; |
59 | 60 | ||
60 | static unsigned long long total_quota_out; | 61 | static unsigned long long total_quota_out; |
61 | 62 | ||
63 | static unsigned int active_addr_count; | ||
64 | |||
62 | 65 | ||
63 | struct CompareAddressContext | 66 | struct CompareAddressContext |
64 | { | 67 | { |
@@ -66,14 +69,25 @@ struct CompareAddressContext | |||
66 | struct ATS_Address * result; | 69 | struct ATS_Address * result; |
67 | }; | 70 | }; |
68 | 71 | ||
72 | |||
69 | static void | 73 | static void |
70 | destroy_address (struct ATS_Address * addr) | 74 | destroy_address (struct ATS_Address *addr) |
71 | { | 75 | { |
76 | GNUNET_assert (GNUNET_YES == | ||
77 | GNUNET_CONTAINER_multihashmap_remove(addresses, | ||
78 | &addr->peer.hashPubKey, | ||
79 | addr)); | ||
80 | if (ntohl (addr->bw_in.value__) > 0) | ||
81 | { | ||
82 | active_addr_count--; | ||
83 | // FIXME: update address assignment for other peers... | ||
84 | } | ||
72 | GNUNET_free_non_null (addr->ats); | 85 | GNUNET_free_non_null (addr->ats); |
73 | GNUNET_free (addr->plugin); | 86 | GNUNET_free (addr->plugin); |
74 | GNUNET_free (addr); | 87 | GNUNET_free (addr); |
75 | } | 88 | } |
76 | 89 | ||
90 | |||
77 | static int | 91 | static int |
78 | compare_address_it (void *cls, | 92 | compare_address_it (void *cls, |
79 | const GNUNET_HashCode * key, | 93 | const GNUNET_HashCode * key, |
@@ -102,10 +116,10 @@ compare_address_it (void *cls, | |||
102 | cac->result = aa; | 116 | cac->result = aa; |
103 | return GNUNET_NO; | 117 | return GNUNET_NO; |
104 | } | 118 | } |
105 | |||
106 | return GNUNET_YES; | 119 | return GNUNET_YES; |
107 | } | 120 | } |
108 | 121 | ||
122 | |||
109 | struct ATS_Address * | 123 | struct ATS_Address * |
110 | find_address (const struct GNUNET_PeerIdentity *peer, | 124 | find_address (const struct GNUNET_PeerIdentity *peer, |
111 | struct ATS_Address * addr) | 125 | struct ATS_Address * addr) |
@@ -122,6 +136,7 @@ find_address (const struct GNUNET_PeerIdentity *peer, | |||
122 | return cac.result; | 136 | return cac.result; |
123 | } | 137 | } |
124 | 138 | ||
139 | |||
125 | void | 140 | void |
126 | GAS_address_update (const struct GNUNET_PeerIdentity *peer, | 141 | GAS_address_update (const struct GNUNET_PeerIdentity *peer, |
127 | const char *plugin_name, | 142 | const char *plugin_name, |
@@ -136,68 +151,61 @@ GAS_address_update (const struct GNUNET_PeerIdentity *peer, | |||
136 | 151 | ||
137 | aa = GNUNET_malloc (sizeof (struct ATS_Address) + plugin_addr_len); | 152 | aa = GNUNET_malloc (sizeof (struct ATS_Address) + plugin_addr_len); |
138 | aa->ats = GNUNET_malloc(atsi_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information)); | 153 | aa->ats = GNUNET_malloc(atsi_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information)); |
139 | |||
140 | aa->peer = *peer; | 154 | aa->peer = *peer; |
141 | aa->addr_len = plugin_addr_len; | 155 | aa->addr_len = plugin_addr_len; |
142 | aa->ats_count = atsi_count; | 156 | aa->ats_count = atsi_count; |
143 | memcpy (aa->ats, atsi, atsi_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information)); | 157 | memcpy (aa->ats, atsi, atsi_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information)); |
144 | aa->addr = &aa[1]; | 158 | aa->addr = &aa[1]; |
145 | memcpy (aa->addr, plugin_addr, plugin_addr_len); | 159 | memcpy (&aa[1], plugin_addr, plugin_addr_len); |
146 | aa->plugin = GNUNET_strdup (plugin_name); | 160 | aa->plugin = GNUNET_strdup (plugin_name); |
147 | aa->session_client = session_client; | 161 | aa->session_client = session_client; |
148 | aa->session_id = session_id; | 162 | aa->session_id = session_id; |
149 | |||
150 | old = find_address (peer, aa); | 163 | old = find_address (peer, aa); |
151 | if (old == NULL) | 164 | if (old == NULL) |
152 | { | 165 | { |
153 | GNUNET_assert (GNUNET_OK == | 166 | GNUNET_assert (GNUNET_OK == |
154 | GNUNET_CONTAINER_multihashmap_put(addresses, | 167 | GNUNET_CONTAINER_multihashmap_put (addresses, |
155 | &peer->hashPubKey, | 168 | &peer->hashPubKey, |
156 | aa, | 169 | aa, |
157 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); | 170 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); |
158 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
159 | "Added new address for peer `%s' %X\n", | ||
160 | GNUNET_i2s (peer), aa); | ||
161 | } | ||
162 | else | ||
163 | { | ||
164 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 171 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
165 | "Updated existing address for peer `%s' %X \n", | 172 | "Added new address for peer `%s' %X\n", |
166 | GNUNET_i2s (peer), old); | 173 | GNUNET_i2s (peer), aa); |
167 | GNUNET_free_non_null(old->ats); | 174 | return; |
168 | old->ats = NULL; | ||
169 | old->ats_count = 0; | ||
170 | old->ats = aa->ats; | ||
171 | old->ats_count = aa->ats_count; | ||
172 | GNUNET_free (aa->plugin); | ||
173 | GNUNET_free (aa); | ||
174 | } | 175 | } |
175 | 176 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | |
177 | "Updated existing address for peer `%s' %X \n", | ||
178 | GNUNET_i2s (peer), old); | ||
179 | GNUNET_free_non_null (old->ats); | ||
180 | old->ats = NULL; | ||
181 | old->ats_count = 0; | ||
182 | old->ats = aa->ats; | ||
183 | old->ats_count = aa->ats_count; | ||
184 | GNUNET_free (aa->plugin); | ||
185 | GNUNET_free (aa); | ||
176 | } | 186 | } |
177 | 187 | ||
188 | |||
178 | static int | 189 | static int |
179 | remove_client (void *cls, | 190 | remove_address_by_client (void *cls, |
180 | const GNUNET_HashCode * key, | 191 | const GNUNET_HashCode * key, |
181 | void *value) | 192 | void *value) |
182 | { | 193 | { |
183 | struct GNUNET_SERVER_Client *client = cls; | 194 | struct GNUNET_SERVER_Client *client = cls; |
184 | struct ATS_Address * aa = (struct ATS_Address * ) value; | 195 | struct ATS_Address * aa = value; |
185 | 196 | ||
186 | if (aa->session_client == client) | 197 | if (aa->session_client == client) |
187 | { | 198 | destroy_address (aa); |
188 | GNUNET_CONTAINER_multihashmap_remove(addresses, key, value); | ||
189 | destroy_address (aa); | ||
190 | } | ||
191 | return GNUNET_OK; | 199 | return GNUNET_OK; |
192 | } | 200 | } |
193 | 201 | ||
194 | 202 | ||
195 | |||
196 | void | 203 | void |
197 | GAS_address_client_disconnected (struct GNUNET_SERVER_Client *client) | 204 | GAS_address_client_disconnected (struct GNUNET_SERVER_Client *client) |
198 | { | 205 | { |
199 | if (addresses != NULL) | 206 | if (addresses != NULL) |
200 | GNUNET_CONTAINER_multihashmap_iterate(addresses, &remove_client, client); | 207 | GNUNET_CONTAINER_multihashmap_iterate(addresses, |
208 | &remove_address_by_client, client); | ||
201 | } | 209 | } |
202 | 210 | ||
203 | 211 | ||
@@ -209,49 +217,60 @@ GAS_address_destroyed (const struct GNUNET_PeerIdentity *peer, | |||
209 | uint32_t session_id) | 217 | uint32_t session_id) |
210 | { | 218 | { |
211 | 219 | ||
212 | struct ATS_Address *aa; | 220 | struct ATS_Address aa; |
213 | struct ATS_Address *res; | 221 | struct ATS_Address *res; |
214 | 222 | ||
215 | aa = GNUNET_malloc (sizeof (struct ATS_Address) + | 223 | aa.peer = *peer; |
216 | plugin_addr_len); | 224 | aa.addr_len = plugin_addr_len; |
217 | 225 | aa.addr = plugin_addr; | |
218 | aa->peer = *peer; | 226 | aa.plugin = (char*) plugin_name; |
219 | aa->addr_len = plugin_addr_len; | 227 | aa.session_client = session_client; |
220 | aa->addr = &aa[1]; | 228 | aa.session_id = session_id; |
221 | memcpy (aa->addr, plugin_addr, plugin_addr_len); | ||
222 | aa->plugin = GNUNET_strdup (plugin_name); | ||
223 | aa->session_client = session_client; | ||
224 | aa->session_id = session_id; | ||
225 | 229 | ||
226 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 230 | res = find_address (peer, &aa); |
227 | "Deleting address for peer `%s': `%s'\n", | 231 | if (res == NULL) |
228 | GNUNET_i2s (peer), plugin_name); | ||
229 | |||
230 | res = find_address (peer, aa); | ||
231 | if (res != NULL) | ||
232 | { | 232 | { |
233 | GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove(addresses, &peer->hashPubKey, res)); | 233 | /* we don't even know this one, can this happen? */ |
234 | destroy_address (aa); | 234 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
235 | destroy_address (res); | 235 | "Asked to delete unknown address for peer `%s'\n", |
236 | GNUNET_i2s (peer)); | ||
237 | return; | ||
236 | } | 238 | } |
239 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
240 | "Deleting address for peer `%s': `%s'\n", | ||
241 | GNUNET_i2s (peer), plugin_name); | ||
242 | destroy_address (res); | ||
237 | } | 243 | } |
238 | 244 | ||
239 | 245 | ||
240 | void | 246 | void |
241 | GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer) | 247 | GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer) |
242 | { | 248 | { |
243 | struct ATS_Address * aa = NULL; | 249 | struct ATS_Address * aa; |
250 | |||
244 | aa = GNUNET_CONTAINER_multihashmap_get (addresses, &peer->hashPubKey); | 251 | aa = GNUNET_CONTAINER_multihashmap_get (addresses, &peer->hashPubKey); |
245 | if (aa != NULL) | 252 | if (aa == NULL) |
246 | { | 253 | { |
247 | aa->bw_in.value__ = htonl (10000000); | ||
248 | aa->bw_out.value__ = htonl (10000000); | ||
249 | GAS_scheduling_transmit_address_suggestion (peer, aa->plugin, aa->addr, aa->addr_len, aa->session_client, aa->session_id, aa->ats, aa->ats_count, aa->bw_out, aa->bw_in); | ||
250 | } | ||
251 | else | ||
252 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 254 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
253 | "Cannot provide address for peer `%s'\n", | 255 | "Cannot suggest address for peer `%s'\n", |
254 | GNUNET_i2s (peer)); | 256 | GNUNET_i2s (peer)); |
257 | return; | ||
258 | } | ||
259 | /* FIXME: ensure that we don't do this multiple times per peer! */ | ||
260 | if (ntohl (aa->bw_in.value__) == 0) | ||
261 | { | ||
262 | active_addr_count++; | ||
263 | aa->bw_in.value__ = htonl (total_quota_in / active_addr_count); | ||
264 | aa->bw_out.value__ = htonl (total_quota_out / active_addr_count); | ||
265 | /* FIXME: update bw assignments for other addresses... */ | ||
266 | } | ||
267 | GAS_reservations_set_bandwidth (peer, | ||
268 | aa->bw_in); | ||
269 | GAS_scheduling_transmit_address_suggestion (peer, aa->plugin, | ||
270 | aa->addr, aa->addr_len, | ||
271 | aa->session_client, aa->session_id, | ||
272 | aa->ats, aa->ats_count, | ||
273 | aa->bw_out, aa->bw_in); | ||
255 | } | 274 | } |
256 | 275 | ||
257 | 276 | ||