aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ats/ats_api_scheduling.c51
-rw-r--r--src/include/gnunet_ats_service.h30
-rw-r--r--src/transport/Makefile.am14
-rw-r--r--src/transport/gnunet-service-transport.c468
-rw-r--r--src/transport/gnunet-service-transport.h43
-rw-r--r--src/transport/gnunet-service-transport_ats.c441
-rw-r--r--src/transport/gnunet-service-transport_ats.h119
-rw-r--r--src/transport/gnunet-service-transport_blacklist.h25
-rw-r--r--src/transport/gnunet-service-transport_hello.h19
-rw-r--r--src/transport/gnunet-service-transport_manipulation.c52
-rw-r--r--src/transport/gnunet-service-transport_manipulation.h18
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c371
-rw-r--r--src/transport/gnunet-service-transport_neighbours.h82
-rw-r--r--src/transport/gnunet-service-transport_validation.c56
14 files changed, 1153 insertions, 636 deletions
diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c
index c7c79d289..1c30f2e66 100644
--- a/src/ats/ats_api_scheduling.c
+++ b/src/ats/ats_api_scheduling.c
@@ -48,6 +48,12 @@
48 */ 48 */
49struct GNUNET_ATS_AddressRecord 49struct GNUNET_ATS_AddressRecord
50{ 50{
51
52 /**
53 * Scheduling handle this address record belongs to.
54 */
55 struct GNUNET_ATS_SchedulingHandle *sh;
56
51 /** 57 /**
52 * Address data. 58 * Address data.
53 */ 59 */
@@ -331,7 +337,7 @@ find_empty_session_slot (struct GNUNET_ATS_SchedulingHandle *sh)
331 off++; 337 off++;
332 i++; 338 i++;
333 } 339 }
334 if ( (NOT_FOUND != off) && 340 if ( (NOT_FOUND != off % sh->session_array_size) &&
335 (NULL == sh->session_array[off % sh->session_array_size]) ) 341 (NULL == sh->session_array[off % sh->session_array_size]) )
336 return off; 342 return off;
337 i = sh->session_array_size; 343 i = sh->session_array_size;
@@ -1191,9 +1197,10 @@ GNUNET_ATS_session_known (struct GNUNET_ATS_SchedulingHandle *sh,
1191 * @param session session handle, can be NULL 1197 * @param session session handle, can be NULL
1192 * @param ats performance data for the address 1198 * @param ats performance data for the address
1193 * @param ats_count number of performance records in @a ats 1199 * @param ats_count number of performance records in @a ats
1194 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 1200 * @return handle to the address representation inside ATS, NULL
1201 * on error (i.e. ATS knows this exact address already)
1195 */ 1202 */
1196int 1203struct GNUNET_ATS_AddressRecord *
1197GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, 1204GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
1198 const struct GNUNET_HELLO_Address *address, 1205 const struct GNUNET_HELLO_Address *address,
1199 struct Session *session, 1206 struct Session *session,
@@ -1209,7 +1216,7 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
1209 { 1216 {
1210 /* we need a valid address */ 1217 /* we need a valid address */
1211 GNUNET_break (0); 1218 GNUNET_break (0);
1212 return GNUNET_SYSERR; 1219 return NULL;
1213 } 1220 }
1214 namelen = (NULL == address->transport_name) 1221 namelen = (NULL == address->transport_name)
1215 ? 0 1222 ? 0
@@ -1224,17 +1231,18 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
1224 { 1231 {
1225 /* address too large for us, this should not happen */ 1232 /* address too large for us, this should not happen */
1226 GNUNET_break (0); 1233 GNUNET_break (0);
1227 return GNUNET_SYSERR; 1234 return NULL;
1228 } 1235 }
1229 1236
1230 if (NOT_FOUND != find_session_id (sh, session, address)) 1237 if (NOT_FOUND != find_session_id (sh, session, address))
1231 { 1238 {
1232 /* Already existing, nothing todo, but this should not happen */ 1239 /* Already existing, nothing todo, but this should not happen */
1233 GNUNET_break (0); 1240 GNUNET_break (0);
1234 return GNUNET_SYSERR; 1241 return NULL;
1235 } 1242 }
1236 s = find_empty_session_slot (sh); 1243 s = find_empty_session_slot (sh);
1237 ar = GNUNET_new (struct GNUNET_ATS_AddressRecord); 1244 ar = GNUNET_new (struct GNUNET_ATS_AddressRecord);
1245 ar->sh = sh;
1238 ar->slot = s; 1246 ar->slot = s;
1239 ar->session = session; 1247 ar->session = session;
1240 ar->address = GNUNET_HELLO_address_copy (address); 1248 ar->address = GNUNET_HELLO_address_copy (address);
@@ -1244,7 +1252,7 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
1244 memcpy (ar->ats, ats, ats_count * sizeof (struct GNUNET_ATS_Information)); 1252 memcpy (ar->ats, ats, ats_count * sizeof (struct GNUNET_ATS_Information));
1245 sh->session_array[s] = ar; 1253 sh->session_array[s] = ar;
1246 send_add_address_message (sh, ar, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD); 1254 send_add_address_message (sh, ar, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD);
1247 return GNUNET_OK; 1255 return ar;
1248} 1256}
1249 1257
1250 1258
@@ -1256,33 +1264,17 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
1256 * which case the call may be ignored or the information may be stored 1264 * which case the call may be ignored or the information may be stored
1257 * for later use). Update bandwidth assignments. 1265 * for later use). Update bandwidth assignments.
1258 * 1266 *
1259 * FIXME: change API so we do not have to do the linear search! 1267 * @param ar address record to update information for
1260 *
1261 * @param sh handle
1262 * @param address the address
1263 * @param session session handle, can be NULL 1268 * @param session session handle, can be NULL
1264 * @param ats performance data for the address 1269 * @param ats performance data for the address
1265 * @param ats_count number of performance records in @a ats 1270 * @param ats_count number of performance records in @a ats
1266 * @return #GNUNET_YES on success, #GNUNET_NO if address or session are unknown,
1267 * #GNUNET_SYSERR on hard failure
1268 */ 1271 */
1269int 1272void
1270GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh, 1273GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar,
1271 const struct GNUNET_HELLO_Address *address,
1272 struct Session *session, 1274 struct Session *session,
1273 const struct GNUNET_ATS_Information *ats, 1275 const struct GNUNET_ATS_Information *ats,
1274 uint32_t ats_count) 1276 uint32_t ats_count)
1275{ 1277{
1276 uint32_t s;
1277 struct GNUNET_ATS_AddressRecord *ar;
1278
1279 s = find_session_id (sh, session, address);
1280 if (NOT_FOUND == s)
1281 {
1282 GNUNET_break (0);
1283 return GNUNET_NO;
1284 }
1285 ar = sh->session_array[s];
1286 GNUNET_array_grow (ar->ats, 1278 GNUNET_array_grow (ar->ats,
1287 ar->ats_count, 1279 ar->ats_count,
1288 ats_count); 1280 ats_count);
@@ -1290,8 +1282,9 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh,
1290 ats, 1282 ats,
1291 ats_count * sizeof (struct GNUNET_ATS_Information)); 1283 ats_count * sizeof (struct GNUNET_ATS_Information));
1292 ar->session = session; 1284 ar->session = session;
1293 send_add_address_message (sh, ar, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE); 1285 send_add_address_message (ar->sh,
1294 return GNUNET_YES; 1286 ar,
1287 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE);
1295} 1288}
1296 1289
1297 1290
@@ -1384,7 +1377,7 @@ GNUNET_ATS_address_destroyed (struct GNUNET_ATS_SchedulingHandle *sh,
1384 s = find_session_id (sh, session, address); 1377 s = find_session_id (sh, session, address);
1385 if (NOT_FOUND == s) 1378 if (NOT_FOUND == s)
1386 { 1379 {
1387 GNUNET_break (0); 1380 GNUNET_assert (0);
1388 return; 1381 return;
1389 } 1382 }
1390 ar = sh->session_array[s]; 1383 ar = sh->session_array[s];
diff --git a/src/include/gnunet_ats_service.h b/src/include/gnunet_ats_service.h
index b0ffc1271..271d6009e 100644
--- a/src/include/gnunet_ats_service.h
+++ b/src/include/gnunet_ats_service.h
@@ -421,7 +421,7 @@ GNUNET_ATS_print_network_type (enum GNUNET_ATS_Network_Type net);
421 421
422 422
423/** 423/**
424 * Returns where the address is located: LAN or WAN or ... 424 * Returns where the address is located: loopback, LAN or WAN.
425 * 425 *
426 * @param sh the `struct GNUNET_ATS_SchedulingHandle` handle 426 * @param sh the `struct GNUNET_ATS_SchedulingHandle` handle
427 * @param addr address 427 * @param addr address
@@ -449,6 +449,12 @@ GNUNET_ATS_session_known (struct GNUNET_ATS_SchedulingHandle *sh,
449 449
450 450
451/** 451/**
452 * Handle used within ATS to track an address.
453 */
454struct GNUNET_ATS_AddressRecord;
455
456
457/**
452 * We have a new address ATS should know. Addresses have to be added with this 458 * We have a new address ATS should know. Addresses have to be added with this
453 * function before they can be: updated, set in use and destroyed 459 * function before they can be: updated, set in use and destroyed
454 * 460 *
@@ -457,8 +463,11 @@ GNUNET_ATS_session_known (struct GNUNET_ATS_SchedulingHandle *sh,
457 * @param session session handle (if available) 463 * @param session session handle (if available)
458 * @param ats performance data for the address 464 * @param ats performance data for the address
459 * @param ats_count number of performance records in @a ats 465 * @param ats_count number of performance records in @a ats
466 * @return handle to the address representation inside ATS, NULL
467 * on error (i.e. ATS knows this exact address already, or
468 * address is invalid)
460 */ 469 */
461int 470struct GNUNET_ATS_AddressRecord *
462GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, 471GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
463 const struct GNUNET_HELLO_Address *address, 472 const struct GNUNET_HELLO_Address *address,
464 struct Session *session, 473 struct Session *session,
@@ -470,20 +479,19 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
470 * We have updated performance statistics for a given address. Note 479 * We have updated performance statistics for a given address. Note
471 * that this function can be called for addresses that are currently 480 * that this function can be called for addresses that are currently
472 * in use as well as addresses that are valid but not actively in use. 481 * in use as well as addresses that are valid but not actively in use.
473 * Furthermore, the peer may not even be connected to us right now (in 482 * Furthermore, the peer may not even be connected to us right now (@a
474 * which case the call may be ignored or the information may be stored 483 * session value of NULL used to signal disconnect, or somehow we
475 * for later use). Update bandwidth assignments. 484 * otherwise got updated on @a ats information). Based on the
485 * information provided, ATS may update bandwidth assignments and
486 * suggest to switch addresses.
476 * 487 *
477 * @param sh handle 488 * @param ar address record to update information for
478 * @param address updated address
479 * @param session session handle (if available) 489 * @param session session handle (if available)
480 * @param ats performance data for the address 490 * @param ats performance data for the address
481 * @param ats_count number of performance records in @a ats 491 * @param ats_count number of performance records in @a ats
482 * @return #GNUNET_OK or #GNUNET_SYSERR
483 */ 492 */
484int 493void
485GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh, 494GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar,
486 const struct GNUNET_HELLO_Address *address,
487 struct Session *session, 495 struct Session *session,
488 const struct GNUNET_ATS_Information *ats, 496 const struct GNUNET_ATS_Information *ats,
489 uint32_t ats_count); 497 uint32_t ats_count);
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index d2dcd4236..749550657 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -240,6 +240,7 @@ gnunet_transport_LDADD = \
240 240
241gnunet_service_transport_SOURCES = \ 241gnunet_service_transport_SOURCES = \
242 gnunet-service-transport.c gnunet-service-transport.h \ 242 gnunet-service-transport.c gnunet-service-transport.h \
243 gnunet-service-transport_ats.h gnunet-service-transport_ats.c \
243 gnunet-service-transport_blacklist.h gnunet-service-transport_blacklist.c \ 244 gnunet-service-transport_blacklist.h gnunet-service-transport_blacklist.c \
244 gnunet-service-transport_clients.h gnunet-service-transport_clients.c \ 245 gnunet-service-transport_clients.h gnunet-service-transport_clients.c \
245 gnunet-service-transport_hello.h gnunet-service-transport_hello.c \ 246 gnunet-service-transport_hello.h gnunet-service-transport_hello.c \
@@ -980,6 +981,7 @@ test_quota_compliance_http_SOURCES = \
980test_quota_compliance_http_LDADD = \ 981test_quota_compliance_http_LDADD = \
981 libgnunettransport.la \ 982 libgnunettransport.la \
982 $(top_builddir)/src/hello/libgnunethello.la \ 983 $(top_builddir)/src/hello/libgnunethello.la \
984 $(top_builddir)/src/ats/libgnunetats.la \
983 $(top_builddir)/src/util/libgnunetutil.la \ 985 $(top_builddir)/src/util/libgnunetutil.la \
984 libgnunettransporttesting.la 986 libgnunettransporttesting.la
985 987
@@ -988,6 +990,7 @@ test_quota_compliance_http_asymmetric_SOURCES = \
988test_quota_compliance_http_asymmetric_LDADD = \ 990test_quota_compliance_http_asymmetric_LDADD = \
989 libgnunettransport.la \ 991 libgnunettransport.la \
990 $(top_builddir)/src/hello/libgnunethello.la \ 992 $(top_builddir)/src/hello/libgnunethello.la \
993 $(top_builddir)/src/ats/libgnunetats.la \
991 $(top_builddir)/src/util/libgnunetutil.la \ 994 $(top_builddir)/src/util/libgnunetutil.la \
992 libgnunettransporttesting.la 995 libgnunettransporttesting.la
993 996
@@ -996,6 +999,7 @@ test_quota_compliance_https_SOURCES = \
996test_quota_compliance_https_LDADD = \ 999test_quota_compliance_https_LDADD = \
997 libgnunettransport.la \ 1000 libgnunettransport.la \
998 $(top_builddir)/src/hello/libgnunethello.la \ 1001 $(top_builddir)/src/hello/libgnunethello.la \
1002 $(top_builddir)/src/ats/libgnunetats.la \
999 $(top_builddir)/src/util/libgnunetutil.la \ 1003 $(top_builddir)/src/util/libgnunetutil.la \
1000 libgnunettransporttesting.la 1004 libgnunettransporttesting.la
1001 1005
@@ -1004,6 +1008,7 @@ test_quota_compliance_https_asymmetric_SOURCES = \
1004test_quota_compliance_https_asymmetric_LDADD = \ 1008test_quota_compliance_https_asymmetric_LDADD = \
1005 libgnunettransport.la \ 1009 libgnunettransport.la \
1006 $(top_builddir)/src/hello/libgnunethello.la \ 1010 $(top_builddir)/src/hello/libgnunethello.la \
1011 $(top_builddir)/src/ats/libgnunetats.la \
1007 $(top_builddir)/src/util/libgnunetutil.la \ 1012 $(top_builddir)/src/util/libgnunetutil.la \
1008 libgnunettransporttesting.la 1013 libgnunettransporttesting.la
1009 1014
@@ -1121,6 +1126,7 @@ test_quota_compliance_tcp_SOURCES = \
1121test_quota_compliance_tcp_LDADD = \ 1126test_quota_compliance_tcp_LDADD = \
1122 libgnunettransport.la \ 1127 libgnunettransport.la \
1123 $(top_builddir)/src/hello/libgnunethello.la \ 1128 $(top_builddir)/src/hello/libgnunethello.la \
1129 $(top_builddir)/src/ats/libgnunetats.la \
1124 $(top_builddir)/src/util/libgnunetutil.la \ 1130 $(top_builddir)/src/util/libgnunetutil.la \
1125 libgnunettransporttesting.la 1131 libgnunettransporttesting.la
1126 1132
@@ -1129,6 +1135,7 @@ test_quota_compliance_tcp_asymmetric_SOURCES = \
1129test_quota_compliance_tcp_asymmetric_LDADD = \ 1135test_quota_compliance_tcp_asymmetric_LDADD = \
1130 libgnunettransport.la \ 1136 libgnunettransport.la \
1131 $(top_builddir)/src/hello/libgnunethello.la \ 1137 $(top_builddir)/src/hello/libgnunethello.la \
1138 $(top_builddir)/src/ats/libgnunetats.la \
1132 $(top_builddir)/src/util/libgnunetutil.la \ 1139 $(top_builddir)/src/util/libgnunetutil.la \
1133 libgnunettransporttesting.la 1140 libgnunettransporttesting.la
1134 1141
@@ -1137,6 +1144,7 @@ test_quota_compliance_udp_SOURCES = \
1137test_quota_compliance_udp_LDADD = \ 1144test_quota_compliance_udp_LDADD = \
1138 libgnunettransport.la \ 1145 libgnunettransport.la \
1139 $(top_builddir)/src/hello/libgnunethello.la \ 1146 $(top_builddir)/src/hello/libgnunethello.la \
1147 $(top_builddir)/src/ats/libgnunetats.la \
1140 $(top_builddir)/src/util/libgnunetutil.la \ 1148 $(top_builddir)/src/util/libgnunetutil.la \
1141 libgnunettransporttesting.la 1149 libgnunettransporttesting.la
1142 1150
@@ -1145,6 +1153,7 @@ test_quota_compliance_unix_SOURCES = \
1145test_quota_compliance_unix_LDADD = \ 1153test_quota_compliance_unix_LDADD = \
1146 libgnunettransport.la \ 1154 libgnunettransport.la \
1147 $(top_builddir)/src/hello/libgnunethello.la \ 1155 $(top_builddir)/src/hello/libgnunethello.la \
1156 $(top_builddir)/src/ats/libgnunetats.la \
1148 $(top_builddir)/src/util/libgnunetutil.la \ 1157 $(top_builddir)/src/util/libgnunetutil.la \
1149 libgnunettransporttesting.la 1158 libgnunettransporttesting.la
1150 1159
@@ -1153,6 +1162,7 @@ test_quota_compliance_unix_asymmetric_SOURCES = \
1153test_quota_compliance_unix_asymmetric_LDADD = \ 1162test_quota_compliance_unix_asymmetric_LDADD = \
1154 libgnunettransport.la \ 1163 libgnunettransport.la \
1155 $(top_builddir)/src/hello/libgnunethello.la \ 1164 $(top_builddir)/src/hello/libgnunethello.la \
1165 $(top_builddir)/src/ats/libgnunetats.la \
1156 $(top_builddir)/src/util/libgnunetutil.la \ 1166 $(top_builddir)/src/util/libgnunetutil.la \
1157 libgnunettransporttesting.la 1167 libgnunettransporttesting.la
1158 1168
@@ -1161,6 +1171,7 @@ test_quota_compliance_wlan_SOURCES = \
1161test_quota_compliance_wlan_LDADD = \ 1171test_quota_compliance_wlan_LDADD = \
1162 libgnunettransport.la \ 1172 libgnunettransport.la \
1163 $(top_builddir)/src/hello/libgnunethello.la \ 1173 $(top_builddir)/src/hello/libgnunethello.la \
1174 $(top_builddir)/src/ats/libgnunetats.la \
1164 $(top_builddir)/src/util/libgnunetutil.la \ 1175 $(top_builddir)/src/util/libgnunetutil.la \
1165 libgnunettransporttesting.la 1176 libgnunettransporttesting.la
1166 1177
@@ -1169,6 +1180,7 @@ test_quota_compliance_wlan_asymmetric_SOURCES = \
1169test_quota_compliance_wlan_asymmetric_LDADD = \ 1180test_quota_compliance_wlan_asymmetric_LDADD = \
1170 libgnunettransport.la \ 1181 libgnunettransport.la \
1171 $(top_builddir)/src/hello/libgnunethello.la \ 1182 $(top_builddir)/src/hello/libgnunethello.la \
1183 $(top_builddir)/src/ats/libgnunetats.la \
1172 $(top_builddir)/src/util/libgnunetutil.la \ 1184 $(top_builddir)/src/util/libgnunetutil.la \
1173 libgnunettransporttesting.la 1185 libgnunettransporttesting.la
1174 1186
@@ -1178,6 +1190,7 @@ test_quota_compliance_bluetooth_LDADD = \
1178 $(top_builddir)/src/nat/libgnunetnat.la \ 1190 $(top_builddir)/src/nat/libgnunetnat.la \
1179 libgnunettransport.la \ 1191 libgnunettransport.la \
1180 $(top_builddir)/src/hello/libgnunethello.la \ 1192 $(top_builddir)/src/hello/libgnunethello.la \
1193 $(top_builddir)/src/ats/libgnunetats.la \
1181 $(top_builddir)/src/util/libgnunetutil.la \ 1194 $(top_builddir)/src/util/libgnunetutil.la \
1182 libgnunettransporttesting.la 1195 libgnunettransporttesting.la
1183 1196
@@ -1186,6 +1199,7 @@ test_quota_compliance_bluetooth_asymmetric_SOURCES = \
1186test_quota_compliance_bluetooth_asymmetric_LDADD = \ 1199test_quota_compliance_bluetooth_asymmetric_LDADD = \
1187 libgnunettransport.la \ 1200 libgnunettransport.la \
1188 $(top_builddir)/src/hello/libgnunethello.la \ 1201 $(top_builddir)/src/hello/libgnunethello.la \
1202 $(top_builddir)/src/ats/libgnunetats.la \
1189 $(top_builddir)/src/util/libgnunetutil.la \ 1203 $(top_builddir)/src/util/libgnunetutil.la \
1190 libgnunettransporttesting.la 1204 libgnunettransporttesting.la
1191 1205
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index 01ca2fc67..5126dad96 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -20,7 +20,7 @@
20 20
21/** 21/**
22 * @file transport/gnunet-service-transport.c 22 * @file transport/gnunet-service-transport.c
23 * @brief 23 * @brief main for gnunet-service-transport
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
@@ -31,6 +31,7 @@
31#include "gnunet_peerinfo_service.h" 31#include "gnunet_peerinfo_service.h"
32#include "gnunet_ats_service.h" 32#include "gnunet_ats_service.h"
33#include "gnunet-service-transport.h" 33#include "gnunet-service-transport.h"
34#include "gnunet-service-transport_ats.h"
34#include "gnunet-service-transport_blacklist.h" 35#include "gnunet-service-transport_blacklist.h"
35#include "gnunet-service-transport_clients.h" 36#include "gnunet-service-transport_clients.h"
36#include "gnunet-service-transport_hello.h" 37#include "gnunet-service-transport_hello.h"
@@ -71,19 +72,21 @@ struct SessionKiller
71 struct GNUNET_SCHEDULER_Task * task; 72 struct GNUNET_SCHEDULER_Task * task;
72}; 73};
73 74
75
74struct BlacklistCheckContext 76struct BlacklistCheckContext
75{ 77{
76 struct BlacklistCheckContext *prev; 78 struct BlacklistCheckContext *prev;
77 struct BlacklistCheckContext *next;
78 79
80 struct BlacklistCheckContext *next;
79 81
80 struct GST_BlacklistCheck *blc; 82 struct GST_BlacklistCheck *blc;
81 83
82 struct GNUNET_HELLO_Address *address; 84 struct GNUNET_HELLO_Address *address;
85
83 struct Session *session; 86 struct Session *session;
87
84 struct GNUNET_MessageHeader *msg; 88 struct GNUNET_MessageHeader *msg;
85 struct GNUNET_ATS_Information *ats; 89
86 uint32_t ats_count;
87}; 90};
88 91
89/* globals */ 92/* globals */
@@ -143,7 +146,14 @@ static struct SessionKiller *sk_head;
143 */ 146 */
144static struct SessionKiller *sk_tail; 147static struct SessionKiller *sk_tail;
145 148
149/**
150 * FIXME
151 */
146struct BlacklistCheckContext *bc_head; 152struct BlacklistCheckContext *bc_head;
153
154/**
155 * FIXME
156 */
147struct BlacklistCheckContext *bc_tail; 157struct BlacklistCheckContext *bc_tail;
148 158
149 159
@@ -172,7 +182,7 @@ transmit_our_hello (void *cls, const struct GNUNET_PeerIdentity *target,
172 return; 182 return;
173 183
174 GST_neighbours_send (target, hello, ntohs (hello->size), hello_expiration, 184 GST_neighbours_send (target, hello, ntohs (hello->size), hello_expiration,
175 NULL, NULL ); 185 NULL, NULL);
176} 186}
177 187
178/** 188/**
@@ -193,15 +203,18 @@ process_hello_update (void *cls, const struct GNUNET_MessageHeader *hello)
193 * We received some payload. Prepare to pass it on to our clients. 203 * We received some payload. Prepare to pass it on to our clients.
194 * 204 *
195 * @param peer (claimed) identity of the other peer 205 * @param peer (claimed) identity of the other peer
196 * @param address the address 206 * @param address address and (claimed) identity of the other peer
197 * @param session session used 207 * @param session identifier used for this session (NULL for plugins
208 * that do not offer bi-directional communication to the sender
209 * using the same "connection")
198 * @param message the message to process 210 * @param message the message to process
199 * @return how long the plugin should wait until receiving more data 211 * @return how long the plugin should wait until receiving more data
200 */ 212 */
201static struct GNUNET_TIME_Relative 213static struct GNUNET_TIME_Relative
202process_payload (const struct GNUNET_PeerIdentity *peer, 214process_payload (const struct GNUNET_PeerIdentity *peer,
203 const struct GNUNET_HELLO_Address *address, struct Session *session, 215 const struct GNUNET_HELLO_Address *address,
204 const struct GNUNET_MessageHeader *message) 216 struct Session *session,
217 const struct GNUNET_MessageHeader *message)
205{ 218{
206 struct GNUNET_TIME_Relative ret; 219 struct GNUNET_TIME_Relative ret;
207 int do_forward; 220 int do_forward;
@@ -214,18 +227,18 @@ process_payload (const struct GNUNET_PeerIdentity *peer,
214 ret = GST_neighbours_calculate_receive_delay (peer, msg_size, &do_forward); 227 ret = GST_neighbours_calculate_receive_delay (peer, msg_size, &do_forward);
215 if (! GST_neighbours_test_connected (peer)) 228 if (! GST_neighbours_test_connected (peer))
216 { 229 {
217 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 230 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
218 "Discarded %u bytes type %u payload from peer `%s'\n", msg_size, 231 "Discarded %u bytes type %u payload from peer `%s'\n",
219 ntohs (message->type), GNUNET_i2s (peer)); 232 msg_size,
233 ntohs (message->type),
234 GNUNET_i2s (peer));
220 GNUNET_STATISTICS_update (GST_stats, gettext_noop 235 GNUNET_STATISTICS_update (GST_stats, gettext_noop
221 ("# bytes payload discarded due to not connected peer"), msg_size, 236 ("# bytes payload discarded due to not connected peer"),
222 GNUNET_NO); 237 msg_size,
238 GNUNET_NO);
223 return ret; 239 return ret;
224 } 240 }
225 241
226 // FIXME: why is this call here?
227 GST_ats_add_address (address, session, NULL, 0);
228
229 if (GNUNET_YES != do_forward) 242 if (GNUNET_YES != do_forward)
230 return ret; 243 return ret;
231 im = (struct InboundMessage *) buf; 244 im = (struct InboundMessage *) buf;
@@ -237,6 +250,7 @@ process_payload (const struct GNUNET_PeerIdentity *peer,
237 return ret; 250 return ret;
238} 251}
239 252
253
240/** 254/**
241 * Task to asynchronously terminate a session. 255 * Task to asynchronously terminate a session.
242 * 256 *
@@ -254,16 +268,25 @@ kill_session_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
254 GNUNET_free(sk); 268 GNUNET_free(sk);
255} 269}
256 270
271
272/**
273 * FIXME. Also, consider moving the "bc_*" logic into
274 * blacklist.h?
275 */
257static void 276static void
258cancel_pending_blacklist_checks (const struct GNUNET_HELLO_Address *address, struct Session *session) 277cancel_pending_blacklist_checks (const struct GNUNET_HELLO_Address *address,
278 struct Session *session)
259{ 279{
260 struct BlacklistCheckContext *blctx; 280 struct BlacklistCheckContext *blctx;
261 struct BlacklistCheckContext *next; 281 struct BlacklistCheckContext *next;
282
262 next = bc_head; 283 next = bc_head;
263 for (blctx = next; NULL != blctx; blctx = next) 284 for (blctx = next; NULL != blctx; blctx = next)
264 { 285 {
265 next = blctx->next; 286 next = blctx->next;
266 if ((NULL != blctx->address) && (0 == GNUNET_HELLO_address_cmp(blctx->address, address)) && (blctx->session == session)) 287 if ( (NULL != blctx->address) &&
288 (0 == GNUNET_HELLO_address_cmp(blctx->address, address)) &&
289 (blctx->session == session))
267 { 290 {
268 GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, blctx); 291 GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, blctx);
269 if (NULL != blctx->blc) 292 if (NULL != blctx->blc)
@@ -273,12 +296,12 @@ cancel_pending_blacklist_checks (const struct GNUNET_HELLO_Address *address, str
273 } 296 }
274 GNUNET_HELLO_address_free (blctx->address); 297 GNUNET_HELLO_address_free (blctx->address);
275 GNUNET_free_non_null (blctx->msg); 298 GNUNET_free_non_null (blctx->msg);
276 GNUNET_free_non_null (blctx->ats);
277 GNUNET_free (blctx); 299 GNUNET_free (blctx);
278 } 300 }
279 } 301 }
280} 302}
281 303
304
282/** 305/**
283 * Force plugin to terminate session due to communication 306 * Force plugin to terminate session due to communication
284 * issue. 307 * issue.
@@ -287,7 +310,8 @@ cancel_pending_blacklist_checks (const struct GNUNET_HELLO_Address *address, str
287 * @param session session to termiante 310 * @param session session to termiante
288 */ 311 */
289static void 312static void
290kill_session (const char *plugin_name, struct Session *session) 313kill_session (const char *plugin_name,
314 struct Session *session)
291{ 315{
292 struct GNUNET_TRANSPORT_PluginFunctions *plugin; 316 struct GNUNET_TRANSPORT_PluginFunctions *plugin;
293 struct SessionKiller *sk; 317 struct SessionKiller *sk;
@@ -306,14 +330,15 @@ kill_session (const char *plugin_name, struct Session *session)
306 sk->session = session; 330 sk->session = session;
307 sk->plugin = plugin; 331 sk->plugin = plugin;
308 sk->task = GNUNET_SCHEDULER_add_now (&kill_session_task, sk); 332 sk->task = GNUNET_SCHEDULER_add_now (&kill_session_task, sk);
309 GNUNET_CONTAINER_DLL_insert(sk_head, sk_tail, sk); 333 GNUNET_CONTAINER_DLL_insert (sk_head,
334 sk_tail,
335 sk);
310} 336}
311 337
312 338
313
314/** 339/**
315 * Black list check result for try_connect call 340 * Black list check result for try_connect call
316 * If connection to the peer is allowed request adddress and 341 * If connection to the peer is allowed request adddress and ???
317 * 342 *
318 * @param cls blc_ctx bl context 343 * @param cls blc_ctx bl context
319 * @param peer the peer 344 * @param peer the peer
@@ -321,7 +346,8 @@ kill_session (const char *plugin_name, struct Session *session)
321 */ 346 */
322static void 347static void
323connect_bl_check_cont (void *cls, 348connect_bl_check_cont (void *cls,
324 const struct GNUNET_PeerIdentity *peer, int result) 349 const struct GNUNET_PeerIdentity *peer,
350 int result)
325{ 351{
326 struct BlacklistCheckContext *blctx = cls; 352 struct BlacklistCheckContext *blctx = cls;
327 353
@@ -335,8 +361,9 @@ connect_bl_check_cont (void *cls,
335 "Received SYN message from peer `%s' with `%s' %p\n", 361 "Received SYN message from peer `%s' with `%s' %p\n",
336 GNUNET_i2s (peer), GST_plugins_a2s (blctx->address), blctx->session); 362 GNUNET_i2s (peer), GST_plugins_a2s (blctx->address), blctx->session);
337 363
338 if (GNUNET_OK != GST_neighbours_handle_session_syn (blctx->msg, 364 if (GNUNET_OK !=
339 &blctx->address->peer)) 365 GST_neighbours_handle_session_syn (blctx->msg,
366 &blctx->address->peer))
340 { 367 {
341 cancel_pending_blacklist_checks (blctx->address, blctx->session); 368 cancel_pending_blacklist_checks (blctx->address, blctx->session);
342 kill_session (blctx->address->transport_name, blctx->session); 369 kill_session (blctx->address->transport_name, blctx->session);
@@ -361,38 +388,6 @@ connect_bl_check_cont (void *cls,
361 388
362 389
363/** 390/**
364 * Black list check result for try_connect call
365 * If connection to the peer is allowed request adddress and
366 *
367 * @param cls blc_ctx bl context
368 * @param peer the peer
369 * @param result the result
370 */
371static void
372connect_transport_bl_check_cont (void *cls,
373 const struct GNUNET_PeerIdentity *peer, int result)
374{
375 struct BlacklistCheckContext *blctx = cls;
376
377 GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, blctx);
378 blctx->blc = NULL;
379
380 if (GNUNET_OK == result)
381 {
382 /* Blacklist allows to speak to this transport */
383 GST_ats_add_address (blctx->address,
384 blctx->session,
385 blctx->ats, blctx->ats_count);
386 }
387
388 if (NULL != blctx->address)
389 GNUNET_HELLO_address_free (blctx->address);
390 GNUNET_free (blctx->msg);
391 GNUNET_free (blctx);
392}
393
394
395/**
396 * Function called by the transport for each received message. 391 * Function called by the transport for each received message.
397 * 392 *
398 * @param cls closure, const char* with the name of the plugin we received the message from 393 * @param cls closure, const char* with the name of the plugin we received the message from
@@ -426,7 +421,9 @@ GST_receive_callback (void *cls,
426 GNUNET_i2s (&address->peer)); 421 GNUNET_i2s (&address->peer));
427 422
428 GNUNET_STATISTICS_update (GST_stats, gettext_noop 423 GNUNET_STATISTICS_update (GST_stats, gettext_noop
429 ("# bytes total received"), ntohs (message->size), GNUNET_NO); 424 ("# bytes total received"),
425 ntohs (message->size),
426 GNUNET_NO);
430 GST_neighbours_notify_data_recv (&address->peer, address, session, message); 427 GST_neighbours_notify_data_recv (&address->peer, address, session, message);
431 428
432 switch (type) 429 switch (type)
@@ -442,19 +439,23 @@ GST_receive_callback (void *cls,
442 } 439 }
443 return ret; 440 return ret;
444 case GNUNET_MESSAGE_TYPE_TRANSPORT_PING: 441 case GNUNET_MESSAGE_TYPE_TRANSPORT_PING:
445 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 442 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
446 "Processing `%s' from `%s'\n", "PING", GST_plugins_a2s (address)); 443 "Processing `%s' from `%s'\n", "PING",
447 if (GNUNET_OK 444 GST_plugins_a2s (address));
448 != GST_validation_handle_ping (&address->peer, message, address, session)) 445 if (GNUNET_OK !=
446 GST_validation_handle_ping (&address->peer,
447 message,
448 address,
449 session))
449 { 450 {
450 cancel_pending_blacklist_checks (address, session); 451 cancel_pending_blacklist_checks (address, session);
451 kill_session (plugin_name, session); 452 kill_session (plugin_name, session);
452 } 453 }
453 break; 454 break;
454 case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG: 455 case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG:
455 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 456 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
456 "Processing `%s' from `%s'\n", "PONG", 457 "Processing `%s' from `%s'\n", "PONG",
457 GST_plugins_a2s (address)); 458 GST_plugins_a2s (address));
458 if (GNUNET_OK != GST_validation_handle_pong (&address->peer, message)) 459 if (GNUNET_OK != GST_validation_handle_pong (&address->peer, message))
459 { 460 {
460 GNUNET_break_op(0); 461 GNUNET_break_op(0);
@@ -475,18 +476,6 @@ GST_receive_callback (void *cls,
475 { 476 {
476 blctx->blc = blc; 477 blctx->blc = blc;
477 } 478 }
478
479 blctx = GNUNET_new (struct BlacklistCheckContext);
480 blctx->address = GNUNET_HELLO_address_copy (address);
481 blctx->session = session;
482 blctx->msg = GNUNET_malloc (ntohs(message->size));
483 memcpy (blctx->msg, message, ntohs(message->size));
484 GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, blctx);
485 if (NULL != (blc = GST_blacklist_test_allowed (&address->peer,
486 address->transport_name, &connect_transport_bl_check_cont, blctx)))
487 {
488 blctx->blc = blc;
489 }
490 break; 479 break;
491 case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN_ACK: 480 case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN_ACK:
492 if (GNUNET_OK != GST_neighbours_handle_session_syn_ack (message, 481 if (GNUNET_OK != GST_neighbours_handle_session_syn_ack (message,
@@ -529,6 +518,7 @@ GST_receive_callback (void *cls,
529 return ret; 518 return ret;
530} 519}
531 520
521
532/** 522/**
533 * Function that will be called for each address the transport 523 * Function that will be called for each address the transport
534 * is aware that it might be reachable under. Update our HELLO. 524 * is aware that it might be reachable under. Update our HELLO.
@@ -539,8 +529,9 @@ GST_receive_callback (void *cls,
539 * @param address the address to add or remove 529 * @param address the address to add or remove
540 */ 530 */
541static void 531static void
542plugin_env_address_change_notification (void *cls, int add_remove, 532plugin_env_address_change_notification (void *cls,
543 const struct GNUNET_HELLO_Address *address) 533 int add_remove,
534 const struct GNUNET_HELLO_Address *address)
544{ 535{
545 static int addresses = 0; 536 static int addresses = 0;
546 struct GNUNET_STATISTICS_Handle *cfg = GST_stats; 537 struct GNUNET_STATISTICS_Handle *cfg = GST_stats;
@@ -562,11 +553,12 @@ plugin_env_address_change_notification (void *cls, int add_remove,
562 } 553 }
563 554
564 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 555 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
565 "Transport now has %u addresses to communicate\n", addresses); 556 "Transport now has %u addresses to communicate\n",
566 557 addresses);
567 GST_hello_modify_addresses (add_remove, address); 558 GST_hello_modify_addresses (add_remove, address);
568} 559}
569 560
561
570/** 562/**
571 * Function that will be called whenever the plugin internally 563 * Function that will be called whenever the plugin internally
572 * cleans up a session pointer and hence the service needs to 564 * cleans up a session pointer and hence the service needs to
@@ -581,8 +573,9 @@ plugin_env_address_change_notification (void *cls, int add_remove,
581 * @param session which session is being destoyed 573 * @param session which session is being destoyed
582 */ 574 */
583static void 575static void
584plugin_env_session_end (void *cls, const struct GNUNET_HELLO_Address *address, 576plugin_env_session_end (void *cls,
585 struct Session *session) 577 const struct GNUNET_HELLO_Address *address,
578 struct Session *session)
586{ 579{
587 struct SessionKiller *sk; 580 struct SessionKiller *sk;
588 581
@@ -591,40 +584,30 @@ plugin_env_session_end (void *cls, const struct GNUNET_HELLO_Address *address,
591 GNUNET_break (0); 584 GNUNET_break (0);
592 return; 585 return;
593 } 586 }
594
595 if (NULL == session) 587 if (NULL == session)
596 { 588 {
597 GNUNET_break (0); 589 GNUNET_break (0);
598 return; 590 return;
599 } 591 }
592 GNUNET_assert (strlen (address->transport_name) > 0);
600 593
601 GNUNET_assert(strlen (address->transport_name) > 0); 594 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
602 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Session %p to peer `%s' ended \n", 595 "Notification from plugin `%s' about terminated %s session %p from peer `%s' address `%s'\n",
603 session, GNUNET_i2s (&address->peer)); 596 address->transport_name,
604 597 GNUNET_HELLO_address_check_option (address,
605 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 598 GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound", session,
606 "Notification from plugin `%s' about terminated %s session %p from peer `%s' address `%s'\n", 599 GNUNET_i2s (&address->peer),
607 address->transport_name, 600 GST_plugins_a2s (address));
608 GNUNET_HELLO_address_check_option (address,
609 GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound", session,
610 GNUNET_i2s (&address->peer), GST_plugins_a2s (address));
611 601
612 GST_neighbours_session_terminated (&address->peer, session); 602 GST_neighbours_session_terminated (&address->peer, session);
613 603 GST_ats_del_session (address, session);
614 GNUNET_log_from(GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
615 "transport-ats", "Telling ATS to destroy session %p from peer %s\n",
616 session, GNUNET_i2s (&address->peer));
617
618 /* Tell ATS that session has ended */
619 GNUNET_ATS_address_destroyed (GST_ats, address, session);
620
621 cancel_pending_blacklist_checks (address, session); 604 cancel_pending_blacklist_checks (address, session);
622 605
623 for (sk = sk_head; NULL != sk; sk = sk->next) 606 for (sk = sk_head; NULL != sk; sk = sk->next)
624 { 607 {
625 if (sk->session == session) 608 if (sk->session == session)
626 { 609 {
627 GNUNET_CONTAINER_DLL_remove(sk_head, sk_tail, sk); 610 GNUNET_CONTAINER_DLL_remove (sk_head, sk_tail, sk);
628 GNUNET_SCHEDULER_cancel (sk->task); 611 GNUNET_SCHEDULER_cancel (sk->task);
629 GNUNET_free(sk); 612 GNUNET_free(sk);
630 break; 613 break;
@@ -632,6 +615,7 @@ plugin_env_session_end (void *cls, const struct GNUNET_HELLO_Address *address,
632 } 615 }
633} 616}
634 617
618
635/** 619/**
636 * Function that will be called to figure if an address is an loopback, 620 * Function that will be called to figure if an address is an loopback,
637 * LAN, WAN etc. address 621 * LAN, WAN etc. address
@@ -651,14 +635,6 @@ plugin_env_address_to_type (void *cls,
651 GNUNET_break(0); 635 GNUNET_break(0);
652 return GNUNET_ATS_NET_UNSPECIFIED; 636 return GNUNET_ATS_NET_UNSPECIFIED;
653 } 637 }
654 if (((addr->sa_family != AF_INET) && (addrlen != sizeof(struct sockaddr_in)))
655 && ((addr->sa_family != AF_INET6)
656 && (addrlen != sizeof(struct sockaddr_in6)))
657 && (addr->sa_family != AF_UNIX))
658 {
659 GNUNET_break(0);
660 return GNUNET_ATS_NET_UNSPECIFIED;
661 }
662 return GNUNET_ATS_address_get_type (GST_ats, 638 return GNUNET_ATS_address_get_type (GST_ats,
663 addr, 639 addr,
664 addrlen); 640 addrlen);
@@ -666,110 +642,6 @@ plugin_env_address_to_type (void *cls,
666 642
667 643
668/** 644/**
669 * Notify ATS about the new address including the network this address is
670 * located in.
671 *
672 * @param address the address
673 * @param session the session
674 * @param ats ats information
675 * @param ats_count number of @a ats information
676 */
677void
678GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
679 struct Session *session,
680 const struct GNUNET_ATS_Information *ats,
681 uint32_t ats_count)
682{
683 struct GNUNET_TRANSPORT_PluginFunctions *papi;
684 struct GNUNET_ATS_Information ats2[ats_count + 1];
685 uint32_t net;
686
687 /* valid new address, let ATS know! */
688 if (NULL == address->transport_name)
689 {
690 GNUNET_break(0);
691 return;
692 }
693 if (NULL == (papi = GST_plugins_find (address->transport_name)))
694 {
695 /* we don't have the plugin for this address */
696 GNUNET_break(0);
697 return;
698 }
699
700 if (GNUNET_YES == GNUNET_ATS_session_known (GST_ats, address, session))
701 {
702 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
703 "ATS already knows the address, not passing it on again\n");
704 return;
705 }
706
707 net = papi->get_network (papi->cls, session);
708 if (GNUNET_ATS_NET_UNSPECIFIED == net)
709 {
710 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
711 _("Could not obtain a valid network for `%s' %s (%s)\n"),
712 GNUNET_i2s (&address->peer), GST_plugins_a2s (address),
713 address->transport_name);
714 return;
715 }
716 ats2[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
717 ats2[0].value = htonl (net);
718 memcpy (&ats2[1], ats, sizeof(struct GNUNET_ATS_Information) * ats_count);
719 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
720 "Notifying ATS about peer `%s''s new address `%s' session %p in network %s\n",
721 GNUNET_i2s (&address->peer),
722 (0 == address->address_length)
723 ? "<inbound>"
724 : GST_plugins_a2s (address),
725 session,
726 GNUNET_ATS_print_network_type (net));
727 GNUNET_ATS_address_add (GST_ats, address, session,
728 ats2, ats_count + 1);
729}
730
731
732/**
733 * Notify ATS about property changes to an address
734 *
735 * @param peer the peer
736 * @param address the address
737 * @param session the session
738 * @param ats performance information
739 * @param ats_count number of elements in @a ats
740 */
741void
742GST_ats_update_metrics (const struct GNUNET_PeerIdentity *peer,
743 const struct GNUNET_HELLO_Address *address,
744 struct Session *session,
745 const struct GNUNET_ATS_Information *ats,
746 uint32_t ats_count)
747{
748 struct GNUNET_ATS_Information *ats_new;
749
750 if (GNUNET_NO == GNUNET_ATS_session_known (GST_ats, address, session))
751 return;
752
753 /* Call to manipulation to manipulate ATS information */
754 ats_new = GST_manipulation_manipulate_metrics (peer, address, session, ats,
755 ats_count);
756 if (NULL == ats_new)
757 {
758 GNUNET_break(0);
759 return;
760 }
761 if (GNUNET_NO == GNUNET_ATS_address_update (GST_ats, address, session,
762 ats_new, ats_count))
763 {
764 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
765 _("Address or session unknown: failed to update properties for peer `%s' plugin `%s' address `%s' session %p\n"),
766 GNUNET_i2s (peer), address->transport_name, GST_plugins_a2s (address),
767 session);
768 }
769 GNUNET_free(ats_new);
770}
771
772/**
773 * Function that will be called to update metrics for an address 645 * Function that will be called to update metrics for an address
774 * 646 *
775 * @param cls closure 647 * @param cls closure
@@ -785,25 +657,16 @@ plugin_env_update_metrics (void *cls,
785 const struct GNUNET_ATS_Information *ats, 657 const struct GNUNET_ATS_Information *ats,
786 uint32_t ats_count) 658 uint32_t ats_count)
787{ 659{
788 if ((NULL == ats) || (0 == ats_count)) 660 GST_ats_update_metrics (address,
789 return;
790 GNUNET_assert(NULL != GST_ats);
791
792 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
793 "Updating metrics for peer `%s' address %s session %p\n",
794 GNUNET_i2s (&address->peer),
795 GST_plugins_a2s (address),
796 session);
797 GST_ats_update_metrics (&address->peer,
798 address,
799 session, 661 session,
800 ats, ats_count); 662 ats, ats_count);
801} 663}
802 664
803 665
804/** 666/**
805 * Black list check result for try_connect call 667 * Black list check result from blacklist check triggered when a
806 * If connection to the peer is allowed request adddress and 668 * plugin gave us a new session in #plugin_env_session_start(). If
669 * connection to the peer is disallowed, kill the session.
807 * 670 *
808 * @param cls blc_ctx bl context 671 * @param cls blc_ctx bl context
809 * @param peer the peer 672 * @param peer the peer
@@ -811,26 +674,23 @@ plugin_env_update_metrics (void *cls,
811 */ 674 */
812static void 675static void
813plugin_env_session_start_bl_check_cont (void *cls, 676plugin_env_session_start_bl_check_cont (void *cls,
814 const struct GNUNET_PeerIdentity *peer, int result) 677 const struct GNUNET_PeerIdentity *peer,
678 int result)
815{ 679{
816 struct BlacklistCheckContext *blctx = cls; 680 struct BlacklistCheckContext *blctx = cls;
817 681
818 GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, blctx); 682 GNUNET_CONTAINER_DLL_remove (bc_head,
683 bc_tail,
684 blctx);
819 blctx->blc = NULL; 685 blctx->blc = NULL;
820 686 if (GNUNET_OK != result)
821 if (GNUNET_OK == result)
822 {
823 GST_ats_add_address (blctx->address, blctx->session,
824 blctx->ats, blctx->ats_count);
825 }
826 else
827 { 687 {
828 cancel_pending_blacklist_checks (blctx->address, blctx->session); 688 cancel_pending_blacklist_checks (blctx->address,
829 kill_session (blctx->address->transport_name, blctx->session); 689 blctx->session);
690 kill_session (blctx->address->transport_name,
691 blctx->session);
830 } 692 }
831
832 GNUNET_HELLO_address_free (blctx->address); 693 GNUNET_HELLO_address_free (blctx->address);
833 GNUNET_free_non_null (blctx->ats);
834 GNUNET_free (blctx); 694 GNUNET_free (blctx);
835} 695}
836 696
@@ -846,14 +706,13 @@ plugin_env_session_start_bl_check_cont (void *cls,
846 */ 706 */
847static void 707static void
848plugin_env_session_start (void *cls, 708plugin_env_session_start (void *cls,
849 struct GNUNET_HELLO_Address *address, 709 const struct GNUNET_HELLO_Address *address,
850 struct Session *session, 710 struct Session *session,
851 const struct GNUNET_ATS_Information *ats, 711 const struct GNUNET_ATS_Information *ats,
852 uint32_t ats_count) 712 uint32_t ats_count)
853{ 713{
854 struct BlacklistCheckContext *blctx; 714 struct BlacklistCheckContext *blctx;
855 struct GST_BlacklistCheck *blc; 715 struct GST_BlacklistCheck *blc;
856 int c;
857 716
858 if (NULL == address) 717 if (NULL == address)
859 { 718 {
@@ -865,30 +724,46 @@ plugin_env_session_start (void *cls,
865 GNUNET_break(0); 724 GNUNET_break(0);
866 return; 725 return;
867 } 726 }
868 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 727 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
869 "Notification from plugin `%s' about new %s session %p from peer `%s' address `%s'\n", 728 "Notification from plugin `%s' about new %s session %p from peer `%s' address `%s'\n",
870 address->transport_name, 729 address->transport_name,
730 GNUNET_HELLO_address_check_option (address,
731 GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound",
732 session,
733 GNUNET_i2s (&address->peer),
734 GST_plugins_a2s (address));
735 if (GNUNET_YES ==
871 GNUNET_HELLO_address_check_option (address, 736 GNUNET_HELLO_address_check_option (address,
872 GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound", 737 GNUNET_HELLO_ADDRESS_INFO_INBOUND))
873 session, GNUNET_i2s (&address->peer), GST_plugins_a2s (address)); 738 {
874 739 /* inbound is always new */
740 GST_ats_add_address (address,
741 session,
742 ats,
743 ats_count);
744 }
745 else
746 {
747 /* outbound should already be known */
748 GST_ats_new_session (address,
749 session);
750 GST_ats_update_metrics (address,
751 session,
752 ats,
753 ats_count);
754 }
875 /* Do blacklist check if communication with this peer is allowed */ 755 /* Do blacklist check if communication with this peer is allowed */
876 blctx = GNUNET_new (struct BlacklistCheckContext); 756 blctx = GNUNET_new (struct BlacklistCheckContext);
877 blctx->address = GNUNET_HELLO_address_copy (address); 757 blctx->address = GNUNET_HELLO_address_copy (address);
878 blctx->session = session; 758 blctx->session = session;
879 if (ats_count > 0) 759 GNUNET_CONTAINER_DLL_insert (bc_head,
880 { 760 bc_tail,
881 blctx->ats = GNUNET_malloc (ats_count * sizeof (struct GNUNET_ATS_Information)); 761 blctx);
882 for (c = 0; c < ats_count; c++) 762 if (NULL !=
883 { 763 (blc = GST_blacklist_test_allowed (&address->peer,
884 blctx->ats[c].type = ats[c].type; 764 address->transport_name,
885 blctx->ats[c].value = ats[c].value; 765 &plugin_env_session_start_bl_check_cont,
886 } 766 blctx)))
887 }
888
889 GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, blctx);
890 if (NULL != (blc = GST_blacklist_test_allowed (&address->peer, address->transport_name,
891 &plugin_env_session_start_bl_check_cont, blctx)))
892 { 767 {
893 blctx->blc = blc; 768 blctx->blc = blc;
894 } 769 }
@@ -927,9 +802,9 @@ ats_request_address_change (void *cls,
927 /* ATS tells me to disconnect from peer */ 802 /* ATS tells me to disconnect from peer */
928 if ((0 == bw_in) && (0 == bw_out)) 803 if ((0 == bw_in) && (0 == bw_out))
929 { 804 {
930 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 805 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
931 "ATS tells me to disconnect from peer `%s'\n", 806 "ATS tells me to disconnect from peer `%s'\n",
932 GNUNET_i2s (&address->peer)); 807 GNUNET_i2s (&address->peer));
933 GST_neighbours_force_disconnect (&address->peer); 808 GST_neighbours_force_disconnect (&address->peer);
934 return; 809 return;
935 } 810 }
@@ -952,9 +827,9 @@ ats_request_address_change (void *cls,
952 */ 827 */
953static void 828static void
954neighbours_connect_notification (void *cls, 829neighbours_connect_notification (void *cls,
955 const struct GNUNET_PeerIdentity *peer, 830 const struct GNUNET_PeerIdentity *peer,
956 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, 831 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
957 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) 832 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out)
958{ 833{
959 size_t len = sizeof(struct ConnectInfoMessage); 834 size_t len = sizeof(struct ConnectInfoMessage);
960 char buf[len] GNUNET_ALIGN; 835 char buf[len] GNUNET_ALIGN;
@@ -962,8 +837,9 @@ neighbours_connect_notification (void *cls,
962 837
963 connections++; 838 connections++;
964 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 839 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
965 "We are now connected to peer `%s' and %u peers in total\n", 840 "We are now connected to peer `%s' and %u peers in total\n",
966 GNUNET_i2s (peer), connections); 841 GNUNET_i2s (peer),
842 connections);
967 connect_msg->header.size = htons (sizeof(buf)); 843 connect_msg->header.size = htons (sizeof(buf));
968 connect_msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT); 844 connect_msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
969 connect_msg->id = *peer; 845 connect_msg->id = *peer;
@@ -988,8 +864,8 @@ neighbours_disconnect_notification (void *cls,
988 864
989 connections--; 865 connections--;
990 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 866 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
991 "Peer `%s' disconnected and we are connected to %u peers\n", 867 "Peer `%s' disconnected and we are connected to %u peers\n",
992 GNUNET_i2s (peer), connections); 868 GNUNET_i2s (peer), connections);
993 869
994 GST_manipulation_peer_disconnect (peer); 870 GST_manipulation_peer_disconnect (peer);
995 disconnect_msg.header.size = htons (sizeof(struct DisconnectInfoMessage)); 871 disconnect_msg.header.size = htons (sizeof(struct DisconnectInfoMessage));
@@ -1021,12 +897,12 @@ neighbours_changed_notification (void *cls,
1021 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, 897 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
1022 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) 898 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out)
1023{ 899{
1024 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 900 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1025 "Notifying about change for peer `%s' with address `%s' in state `%s' timing out at %s\n", 901 "Notifying about change for peer `%s' with address `%s' in state `%s' timing out at %s\n",
1026 GNUNET_i2s (peer), 902 GNUNET_i2s (peer),
1027 (NULL != address) ? GST_plugins_a2s (address) : "<none>", 903 (NULL != address) ? GST_plugins_a2s (address) : "<none>",
1028 GNUNET_TRANSPORT_ps2s (state), 904 GNUNET_TRANSPORT_ps2s (state),
1029 GNUNET_STRINGS_absolute_time_to_string (state_timeout)); 905 GNUNET_STRINGS_absolute_time_to_string (state_timeout));
1030 906
1031 GST_clients_broadcast_peer_notification (peer, 907 GST_clients_broadcast_peer_notification (peer,
1032 address, 908 address,
@@ -1043,12 +919,13 @@ neighbours_changed_notification (void *cls,
1043 * @param tc task context (unused) 919 * @param tc task context (unused)
1044 */ 920 */
1045static void 921static void
1046shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 922shutdown_task (void *cls,
923 const struct GNUNET_SCHEDULER_TaskContext *tc)
1047{ 924{
1048 GST_neighbours_stop (); 925 GST_neighbours_stop ();
1049 GST_validation_stop (); 926 GST_validation_stop ();
1050 GST_plugins_unload (); 927 GST_plugins_unload ();
1051 928 GST_ats_done ();
1052 GNUNET_ATS_scheduling_done (GST_ats); 929 GNUNET_ATS_scheduling_done (GST_ats);
1053 GST_ats = NULL; 930 GST_ats = NULL;
1054 GST_clients_stop (); 931 GST_clients_stop ();
@@ -1083,8 +960,9 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1083 * @param c configuration to use 960 * @param c configuration to use
1084 */ 961 */
1085static void 962static void
1086run (void *cls, struct GNUNET_SERVER_Handle *server, 963run (void *cls,
1087 const struct GNUNET_CONFIGURATION_Handle *c) 964 struct GNUNET_SERVER_Handle *server,
965 const struct GNUNET_CONFIGURATION_Handle *c)
1088{ 966{
1089 char *keyfile; 967 char *keyfile;
1090 struct GNUNET_CRYPTO_EddsaPrivateKey *pk; 968 struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
@@ -1121,15 +999,16 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
1121 GST_stats = GNUNET_STATISTICS_create ("transport", GST_cfg); 999 GST_stats = GNUNET_STATISTICS_create ("transport", GST_cfg);
1122 GST_peerinfo = GNUNET_PEERINFO_connect (GST_cfg); 1000 GST_peerinfo = GNUNET_PEERINFO_connect (GST_cfg);
1123 GNUNET_CRYPTO_eddsa_key_get_public (GST_my_private_key, 1001 GNUNET_CRYPTO_eddsa_key_get_public (GST_my_private_key,
1124 &GST_my_identity.public_key); 1002 &GST_my_identity.public_key);
1125 GNUNET_assert(NULL != GST_my_private_key); 1003 GNUNET_assert(NULL != GST_my_private_key);
1126 1004
1127 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 1005 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1128 "My identity is `%4s'\n", 1006 "My identity is `%4s'\n",
1129 GNUNET_i2s_full (&GST_my_identity)); 1007 GNUNET_i2s_full (&GST_my_identity));
1130 1008
1131 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, 1009 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
1132 NULL ); 1010 &shutdown_task,
1011 NULL);
1133 if (NULL == GST_peerinfo) 1012 if (NULL == GST_peerinfo)
1134 { 1013 {
1135 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 1014 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
@@ -1152,8 +1031,10 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
1152 } 1031 }
1153 max_fd_rlimit = (9 * max_fd_rlimit) / 10; /* Keep 10% for rest of transport */ 1032 max_fd_rlimit = (9 * max_fd_rlimit) / 10; /* Keep 10% for rest of transport */
1154#endif 1033#endif
1155 GNUNET_CONFIGURATION_get_value_number (GST_cfg, "transport", "MAX_FD", 1034 GNUNET_CONFIGURATION_get_value_number (GST_cfg,
1156 &max_fd_cfg); 1035 "transport",
1036 "MAX_FD",
1037 &max_fd_cfg);
1157 1038
1158 if (max_fd_cfg > max_fd_rlimit) 1039 if (max_fd_cfg > max_fd_rlimit)
1159 max_fd = max_fd_cfg; 1040 max_fd = max_fd_cfg;
@@ -1162,9 +1043,9 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
1162 if (max_fd < DEFAULT_MAX_FDS) 1043 if (max_fd < DEFAULT_MAX_FDS)
1163 max_fd = DEFAULT_MAX_FDS; 1044 max_fd = DEFAULT_MAX_FDS;
1164 1045
1165 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1046 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1166 "Limiting number of sockets to %u: validation %u, neighbors: %u\n", 1047 "Limiting number of sockets to %u: validation %u, neighbors: %u\n",
1167 max_fd, (max_fd / 3), (max_fd / 3) * 2); 1048 max_fd, (max_fd / 3), (max_fd / 3) * 2);
1168 1049
1169 friend_only = GNUNET_CONFIGURATION_get_value_yesno (GST_cfg, "topology", 1050 friend_only = GNUNET_CONFIGURATION_get_value_yesno (GST_cfg, "topology",
1170 "FRIENDS-ONLY"); 1051 "FRIENDS-ONLY");
@@ -1176,7 +1057,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
1176 GST_blacklist_start (GST_server, GST_cfg, &GST_my_identity); 1057 GST_blacklist_start (GST_server, GST_cfg, &GST_my_identity);
1177 GST_ats = GNUNET_ATS_scheduling_init (GST_cfg, 1058 GST_ats = GNUNET_ATS_scheduling_init (GST_cfg,
1178 &ats_request_address_change, 1059 &ats_request_address_change,
1179 NULL ); 1060 NULL);
1061 GST_ats_init ();
1180 GST_manipulation_init (GST_cfg); 1062 GST_manipulation_init (GST_cfg);
1181 GST_plugins_load (&GST_manipulation_recv, 1063 GST_plugins_load (&GST_manipulation_recv,
1182 &GST_neighbours_register_quota_notification, 1064 &GST_neighbours_register_quota_notification,
diff --git a/src/transport/gnunet-service-transport.h b/src/transport/gnunet-service-transport.h
index 67456bd46..34b0083a2 100644
--- a/src/transport/gnunet-service-transport.h
+++ b/src/transport/gnunet-service-transport.h
@@ -28,6 +28,7 @@
28 28
29#include "gnunet_util_lib.h" 29#include "gnunet_util_lib.h"
30#include "gnunet_statistics_service.h" 30#include "gnunet_statistics_service.h"
31#include "gnunet_ats_service.h"
31#include "gnunet_transport_service.h" 32#include "gnunet_transport_service.h"
32 33
33#define VERBOSE_VALIDATION GNUNET_YES 34#define VERBOSE_VALIDATION GNUNET_YES
@@ -85,52 +86,20 @@ typedef void
85 * 86 *
86 * @param cls closure, const char* with the name of the plugin we received the message from 87 * @param cls closure, const char* with the name of the plugin we received the message from
87 * @param address address and (claimed) identity of the other peer 88 * @param address address and (claimed) identity of the other peer
88 * @param message the message, NULL if we only care about
89 * learning about the delay until we should receive again
90 * @param session identifier used for this session (NULL for plugins 89 * @param session identifier used for this session (NULL for plugins
91 * that do not offer bi-directional communication to the sender 90 * that do not offer bi-directional communication to the sender
92 * using the same "connection") 91 * using the same "connection")
92 * @param message the message, NULL if we only care about
93 * learning about the delay until we should receive again
93 * @return how long the plugin should wait until receiving more data 94 * @return how long the plugin should wait until receiving more data
94 * (plugins that do not support this, can ignore the return value) 95 * (plugins that do not support this, can ignore the return value)
95 */ 96 */
96struct GNUNET_TIME_Relative 97struct GNUNET_TIME_Relative
97GST_receive_callback (void *cls, 98GST_receive_callback (void *cls,
98 const struct GNUNET_HELLO_Address *address, 99 const struct GNUNET_HELLO_Address *address,
99 struct Session *session, 100 struct Session *session,
100 const struct GNUNET_MessageHeader *message); 101 const struct GNUNET_MessageHeader *message);
101
102
103/**
104 * Notify ATS about the new address including the network this address is
105 * located in.
106 *
107 * @param address the address
108 * @param session the session
109 * @param ats ats information
110 * @param ats_count number of @a ats information
111 */
112void
113GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
114 struct Session *session,
115 const struct GNUNET_ATS_Information *ats,
116 uint32_t ats_count);
117
118 102
119/**
120 * Notify ATS about property changes to an address
121 *
122 * @param peer the peer
123 * @param address the address
124 * @param session the session
125 * @param ats performance information
126 * @param ats_count number of elements in @a ats
127 */
128void
129GST_ats_update_metrics (const struct GNUNET_PeerIdentity *peer,
130 const struct GNUNET_HELLO_Address *address,
131 struct Session *session,
132 const struct GNUNET_ATS_Information *ats,
133 uint32_t ats_count);
134 103
135#endif 104#endif
136/* end of file gnunet-service-transport_plugins.h */ 105/* end of file gnunet-service-transport_plugins.h */
diff --git a/src/transport/gnunet-service-transport_ats.c b/src/transport/gnunet-service-transport_ats.c
new file mode 100644
index 000000000..c6975e526
--- /dev/null
+++ b/src/transport/gnunet-service-transport_ats.c
@@ -0,0 +1,441 @@
1/*
2 This file is part of GNUnet.
3 (C) 2015 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 * @file transport/gnunet-service-transport_ats.h
22 * @brief interfacing between transport and ATS service
23 * @author Christian Grothoff
24 */
25#include "platform.h"
26#include "gnunet-service-transport.h"
27#include "gnunet-service-transport_ats.h"
28#include "gnunet-service-transport_manipulation.h"
29#include "gnunet-service-transport_plugins.h"
30#include "gnunet_ats_service.h"
31
32
33/**
34 * Information we track for each address known to ATS.
35 */
36struct AddressInfo
37{
38
39 /**
40 * The address (with peer identity).
41 */
42 struct GNUNET_HELLO_Address *address;
43
44 /**
45 * Session (can be NULL)
46 */
47 struct Session *session;
48
49 /**
50 * Record with ATS API for the address.
51 */
52 struct GNUNET_ATS_AddressRecord *ar;
53};
54
55
56/**
57 * Map from peer identities to one or more `struct AddressInfo` values
58 * for the peer.
59 */
60static struct GNUNET_CONTAINER_MultiPeerMap *p2a;
61
62
63/**
64 * Closure for #find_ai().
65 */
66struct FindClosure
67{
68
69 /**
70 * Session to look for (only used if the address is inbound).
71 */
72 struct Session *session;
73
74 /**
75 * Address to look for.
76 */
77 const struct GNUNET_HELLO_Address *address;
78
79 /**
80 * Where to store the result.
81 */
82 struct AddressInfo *ret;
83
84};
85
86
87/**
88 * Find matching address info.
89 *
90 * @param cls the `struct FindClosure`
91 * @param key which peer is this about
92 * @param value the `struct AddressInfo`
93 * @return #GNUNET_YES to continue to iterate, #GNUNET_NO if we found the value
94 */
95static int
96find_ai_cb (void *cls,
97 const struct GNUNET_PeerIdentity *key,
98 void *value)
99{
100 struct FindClosure *fc = cls;
101 struct AddressInfo *ai = value;
102
103 if ( (0 ==
104 GNUNET_HELLO_address_cmp (fc->address,
105 ai->address) ) &&
106 (fc->session == ai->session) )
107 {
108 fc->ret = ai;
109 return GNUNET_NO;
110 }
111 return GNUNET_YES;
112}
113
114
115/**
116 * Find the address information struct for the
117 * given address and session.
118 *
119 * @param address address to look for
120 * @param session session to match for inbound connections
121 * @return NULL if this combination is unknown
122 */
123static struct AddressInfo *
124find_ai (const struct GNUNET_HELLO_Address *address,
125 struct Session *session)
126{
127 struct FindClosure fc;
128
129 fc.address = address;
130 fc.session = session;
131 fc.ret = NULL;
132 GNUNET_CONTAINER_multipeermap_get_multiple (p2a,
133 &address->peer,
134 &find_ai_cb,
135 &fc);
136 return fc.ret;
137}
138
139
140/**
141 * Notify ATS about the new address including the network this address is
142 * located in.
143 *
144 * @param address the address
145 * @param session the session
146 * @param ats ats information
147 * @param ats_count number of @a ats information
148 */
149void
150GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
151 struct Session *session,
152 const struct GNUNET_ATS_Information *ats,
153 uint32_t ats_count)
154{
155 struct GNUNET_TRANSPORT_PluginFunctions *papi;
156 struct GNUNET_ATS_Information ats2[ats_count + 1];
157 struct GNUNET_ATS_AddressRecord *ar;
158 struct AddressInfo *ai;
159 uint32_t net;
160
161 /* valid new address, let ATS know! */
162 if (NULL == address->transport_name)
163 {
164 GNUNET_break(0);
165 return;
166 }
167 if (GNUNET_YES ==
168 GNUNET_HELLO_address_check_option (address,
169 GNUNET_HELLO_ADDRESS_INFO_INBOUND))
170 {
171 GNUNET_break (NULL != session);
172 }
173 else
174 {
175 GNUNET_break (NULL == session);
176 }
177 ai = find_ai (address, session);
178 if (NULL != ai)
179 {
180 GNUNET_break (0);
181 return;
182 }
183 if (NULL == (papi = GST_plugins_find (address->transport_name)))
184 {
185 /* we don't have the plugin for this address */
186 GNUNET_break(0);
187 return;
188 }
189 if (NULL != session)
190 {
191 net = papi->get_network (papi->cls, session);
192 if (GNUNET_ATS_NET_UNSPECIFIED == net)
193 {
194 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
195 _ ("Could not obtain a valid network for `%s' %s (%s)\n"),
196 GNUNET_i2s (&address->peer),
197 GST_plugins_a2s (address),
198 address->transport_name);
199 return;
200 }
201 ats2[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
202 ats2[0].value = htonl (net);
203 memcpy (&ats2[1],
204 ats,
205 sizeof(struct GNUNET_ATS_Information) * ats_count);
206 }
207 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
208 "Notifying ATS about peer `%s''s new address `%s' session %p in network %s\n",
209 GNUNET_i2s (&address->peer),
210 (0 == address->address_length)
211 ? "<inbound>"
212 : GST_plugins_a2s (address),
213 session,
214 GNUNET_ATS_print_network_type (net));
215 ar = GNUNET_ATS_address_add (GST_ats,
216 address,
217 session,
218 (NULL != session) ? ats2 : ats,
219 (NULL != session) ? ats_count + 1 : ats_count);
220 ai = GNUNET_new (struct AddressInfo);
221 ai->address = GNUNET_HELLO_address_copy (address);
222 ai->session = session;
223 ai->ar = ar;
224 (void) GNUNET_CONTAINER_multipeermap_put (p2a,
225 &ai->address->peer,
226 ai,
227 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
228}
229
230
231/**
232 * Notify ATS about a new session now existing for the given
233 * address.
234 *
235 * @param address the address
236 * @param session the session
237 */
238void
239GST_ats_new_session (const struct GNUNET_HELLO_Address *address,
240 struct Session *session)
241{
242 struct AddressInfo *ai;
243
244 ai = find_ai (address, NULL);
245 if (NULL == ai)
246 {
247 GNUNET_break (NULL != (find_ai (address, session)));
248 return;
249 }
250 GNUNET_break (NULL == ai->session);
251 ai->session = session;
252 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
253 "transport-ats",
254 "Telling ATS about new session %p for peer %s\n",
255 session,
256 GNUNET_i2s (&address->peer));
257 // FIXME: tell ATS API, but not using this call:
258 GNUNET_ATS_address_update (ai->ar,
259 session,
260 NULL, 0);
261
262}
263
264
265/**
266 * Notify ATS that the session (but not the address) of
267 * a given address is no longer relevant.
268 *
269 * @param address the address
270 * @param session the session
271 */
272void
273GST_ats_del_session (const struct GNUNET_HELLO_Address *address,
274 struct Session *session)
275{
276 struct AddressInfo *ai;
277
278 if (NULL == session)
279 {
280 GNUNET_break (0);
281 return;
282 }
283 ai = find_ai (address, session);
284 if (NULL == ai)
285 {
286 /* We sometimes create sessions just for sending a PING,
287 and if those are destroyed they were never known to
288 ATS which means we end up here (however, in this
289 case, the address must be an outbound address). */
290 GNUNET_break (GNUNET_YES !=
291 GNUNET_HELLO_address_check_option (address,
292 GNUNET_HELLO_ADDRESS_INFO_INBOUND));
293
294 return;
295 }
296 GNUNET_assert (session == ai->session);
297 ai->session = NULL;
298 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
299 "transport-ats",
300 "Telling ATS to destroy session %p from peer %s\n",
301 session,
302 GNUNET_i2s (&address->peer));
303 /* FIXME: if this was an *inbound* address, destroy it
304 FULLY here well; but use different API, as looking up
305 inbound address without session is not great... */
306 GNUNET_ATS_address_destroyed (GST_ats, address, session);
307 if (GNUNET_YES ==
308 GNUNET_HELLO_address_check_option (address,
309 GNUNET_HELLO_ADDRESS_INFO_INBOUND))
310 GST_ats_expire_address (address);
311}
312
313
314/**
315 * Notify ATS about property changes to an address.
316 *
317 * @param address our information about the address
318 * @param session the session
319 * @param ats performance information
320 * @param ats_count number of elements in @a ats
321 */
322void
323GST_ats_update_metrics (const struct GNUNET_HELLO_Address *address,
324 struct Session *session,
325 const struct GNUNET_ATS_Information *ats,
326 uint32_t ats_count)
327{
328 struct GNUNET_ATS_Information *ats_new;
329 struct AddressInfo *ai;
330
331 ai = find_ai (address, session);
332 if (NULL == ai)
333 {
334 /* We sometimes create sessions just for sending a PING,
335 and if we get metrics for those, they were never known to
336 ATS which means we end up here (however, in this
337 case, the address must be an outbound address). */
338 GNUNET_break (GNUNET_YES !=
339 GNUNET_HELLO_address_check_option (address,
340 GNUNET_HELLO_ADDRESS_INFO_INBOUND));
341
342 return;
343 }
344 /* Call to manipulation to manipulate ATS information */
345 GNUNET_assert (NULL != GST_ats);
346 if ((NULL == ats) || (0 == ats_count))
347 return;
348 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
349 "Updating metrics for peer `%s' address %s session %p\n",
350 GNUNET_i2s (&address->peer),
351 GST_plugins_a2s (address),
352 session);
353 ats_new = GST_manipulation_manipulate_metrics (address,
354 session,
355 ats,
356 ats_count);
357 GNUNET_ATS_address_update (ai->ar,
358 session,
359 ats_new, ats_count);
360 GNUNET_free_non_null (ats_new);
361}
362
363
364/**
365 * Notify ATS that the address has expired and thus cannot
366 * be used any longer. This function must only be called
367 * if the corresponding session is already gone.
368 *
369 * @param address the address
370 */
371void
372GST_ats_expire_address (const struct GNUNET_HELLO_Address *address)
373{
374 struct AddressInfo *ai;
375
376 ai = find_ai (address, NULL);
377 if (NULL == ai)
378 {
379 GNUNET_break (0);
380 return;
381 }
382 GNUNET_assert (GNUNET_YES ==
383 GNUNET_CONTAINER_multipeermap_remove (p2a,
384 &address->peer,
385 ai));
386 GNUNET_break (NULL == ai->session);
387 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
388 "transport-ats",
389 "Telling ATS to destroy address from peer %s\n",
390 GNUNET_i2s (&address->peer));
391 GNUNET_ATS_address_destroyed (GST_ats, address, NULL);
392 GNUNET_HELLO_address_free (ai->address);
393 GNUNET_free (ai);
394}
395
396
397/**
398 * Initialize ATS subsystem.
399 */
400void
401GST_ats_init ()
402{
403 p2a = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_YES);
404}
405
406
407/**
408 * Release memory used by the given address data.
409 *
410 * @param cls NULL
411 * @param key which peer is this about
412 * @param value the `struct AddressInfo`
413 * @return #GNUNET_OK (continue to iterate)
414 */
415static int
416destroy_ai (void *cls,
417 const struct GNUNET_PeerIdentity *key,
418 void *value)
419{
420 struct AddressInfo *ai = value;
421
422 GNUNET_HELLO_address_free (ai->address);
423 GNUNET_free (ai);
424 return GNUNET_OK;
425}
426
427
428/**
429 * Shutdown ATS subsystem.
430 */
431void
432GST_ats_done ()
433{
434 GNUNET_CONTAINER_multipeermap_iterate (p2a,
435 &destroy_ai,
436 NULL);
437 GNUNET_CONTAINER_multipeermap_destroy (p2a);
438 p2a = NULL;
439}
440
441/* end of gnunet-service-transport_ats.c */
diff --git a/src/transport/gnunet-service-transport_ats.h b/src/transport/gnunet-service-transport_ats.h
new file mode 100644
index 000000000..c7b826484
--- /dev/null
+++ b/src/transport/gnunet-service-transport_ats.h
@@ -0,0 +1,119 @@
1/*
2 This file is part of GNUnet.
3 (C) 2015 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 * @file transport/gnunet-service-transport_ats.h
22 * @brief interfacing between transport and ATS service
23 * @author Christian Grothoff
24 *
25 * FIXME:
26 * - add API to give ATS feedback about an address that was
27 * suggested but did not work out (without fully 'deleting'
28 * it forever)
29 * - improve ATS API to take advantage of this new subsystem
30 * when calling ATS functions, make ATS API match this API
31 * more closely
32 * - combine with API to tell ATS about address "use"
33 */
34#ifndef GNUNET_SERVICE_TRANSPORT_ATS_H
35#define GNUNET_SERVICE_TRANSPORT_ATS_H
36
37#include "gnunet_ats_service.h"
38
39/**
40 * Initialize ATS subsystem.
41 */
42void
43GST_ats_init (void);
44
45
46/**
47 * Shutdown ATS subsystem.
48 */
49void
50GST_ats_done (void);
51
52
53/**
54 * Notify ATS about the new address including the network this address is
55 * located in.
56 *
57 * @param address the address
58 * @param session the session
59 * @param ats ats information
60 * @param ats_count number of @a ats information
61 */
62void
63GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
64 struct Session *session,
65 const struct GNUNET_ATS_Information *ats,
66 uint32_t ats_count);
67
68
69/**
70 * Notify ATS about a new session now existing for the given
71 * address.
72 *
73 * @param address the address
74 * @param session the session
75 */
76void
77GST_ats_new_session (const struct GNUNET_HELLO_Address *address,
78 struct Session *session);
79
80
81/**
82 * Notify ATS about property changes to an address
83 *
84 * @param address the address
85 * @param session the session
86 * @param ats performance information
87 * @param ats_count number of elements in @a ats
88 */
89void
90GST_ats_update_metrics (const struct GNUNET_HELLO_Address *address,
91 struct Session *session,
92 const struct GNUNET_ATS_Information *ats,
93 uint32_t ats_count);
94
95
96/**
97 * Notify ATS that the session (but not the address) of
98 * a given address is no longer relevant.
99 *
100 * @param address the address
101 * @param session the session
102 */
103void
104GST_ats_del_session (const struct GNUNET_HELLO_Address *address,
105 struct Session *session);
106
107
108/**
109 * Notify ATS that the address has expired and thus cannot
110 * be used any longer. This function must only be called
111 * if the corresponding session is already gone.
112 *
113 * @param address the address
114 */
115void
116GST_ats_expire_address (const struct GNUNET_HELLO_Address *address);
117
118
119#endif
diff --git a/src/transport/gnunet-service-transport_blacklist.h b/src/transport/gnunet-service-transport_blacklist.h
index a0ae5a959..c635566be 100644
--- a/src/transport/gnunet-service-transport_blacklist.h
+++ b/src/transport/gnunet-service-transport_blacklist.h
@@ -38,8 +38,8 @@
38 */ 38 */
39void 39void
40GST_blacklist_start (struct GNUNET_SERVER_Handle *server, 40GST_blacklist_start (struct GNUNET_SERVER_Handle *server,
41 const struct GNUNET_CONFIGURATION_Handle *cfg, 41 const struct GNUNET_CONFIGURATION_Handle *cfg,
42 const struct GNUNET_PeerIdentity *my_id); 42 const struct GNUNET_PeerIdentity *my_id);
43 43
44 44
45/** 45/**
@@ -59,7 +59,8 @@ GST_blacklist_stop (void);
59 * @param message the blacklist-init message that was sent 59 * @param message the blacklist-init message that was sent
60 */ 60 */
61void 61void
62GST_blacklist_handle_init (void *cls, struct GNUNET_SERVER_Client *client, 62GST_blacklist_handle_init (void *cls,
63 struct GNUNET_SERVER_Client *client,
63 const struct GNUNET_MessageHeader *message); 64 const struct GNUNET_MessageHeader *message);
64 65
65 66
@@ -71,7 +72,8 @@ GST_blacklist_handle_init (void *cls, struct GNUNET_SERVER_Client *client,
71 * @param message the blacklist-init message that was sent 72 * @param message the blacklist-init message that was sent
72 */ 73 */
73void 74void
74GST_blacklist_handle_reply (void *cls, struct GNUNET_SERVER_Client *client, 75GST_blacklist_handle_reply (void *cls,
76 struct GNUNET_SERVER_Client *client,
75 const struct GNUNET_MessageHeader *message); 77 const struct GNUNET_MessageHeader *message);
76 78
77 79
@@ -97,12 +99,13 @@ struct GST_BlacklistCheck;
97 * 99 *
98 * @param cls closure 100 * @param cls closure
99 * @param peer identity of peer that was tested 101 * @param peer identity of peer that was tested
100 * @param result GNUNET_OK if the connection is allowed, 102 * @param result #GNUNET_OK if the connection is allowed,
101 * GNUNET_NO if not 103 * #GNUNET_NO if not
102 */ 104 */
103typedef void (*GST_BlacklistTestContinuation) (void *cls, 105typedef void
104 const struct GNUNET_PeerIdentity 106(*GST_BlacklistTestContinuation) (void *cls,
105 * peer, int result); 107 const struct GNUNET_PeerIdentity *peer,
108 int result);
106 109
107 110
108/** 111/**
@@ -111,9 +114,9 @@ typedef void (*GST_BlacklistTestContinuation) (void *cls,
111 * @param peer the identity of the peer to test 114 * @param peer the identity of the peer to test
112 * @param transport_name name of the transport to test, never NULL 115 * @param transport_name name of the transport to test, never NULL
113 * @param cont function to call with result 116 * @param cont function to call with result
114 * @param cont_cls closure for 'cont' 117 * @param cont_cls closure for @a cont
115 * @return handle to the blacklist check, NULL if the decision 118 * @return handle to the blacklist check, NULL if the decision
116 * was made instantly and 'cont' was already called 119 * was made instantly and @a cont was already called
117 */ 120 */
118struct GST_BlacklistCheck * 121struct GST_BlacklistCheck *
119GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer, 122GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer,
diff --git a/src/transport/gnunet-service-transport_hello.h b/src/transport/gnunet-service-transport_hello.h
index 0c67cef4d..725a6167e 100644
--- a/src/transport/gnunet-service-transport_hello.h
+++ b/src/transport/gnunet-service-transport_hello.h
@@ -17,7 +17,6 @@
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20
21/** 20/**
22 * @file transport/gnunet-service-transport_hello.h 21 * @file transport/gnunet-service-transport_hello.h
23 * @brief hello API 22 * @brief hello API
@@ -32,15 +31,15 @@
32#include "gnunet_hello_lib.h" 31#include "gnunet_hello_lib.h"
33 32
34 33
35
36/** 34/**
37 * Signature of a function to call whenever our hello changes. 35 * Signature of a function to call whenever our hello changes.
38 * 36 *
39 * @param cls closure 37 * @param cls closure
40 * @param hello updated HELLO 38 * @param hello updated HELLO
41 */ 39 */
42typedef void (*GST_HelloCallback) (void *cls, 40typedef void
43 const struct GNUNET_MessageHeader * hello); 41(*GST_HelloCallback) (void *cls,
42 const struct GNUNET_MessageHeader *hello);
44 43
45 44
46/** 45/**
@@ -48,10 +47,12 @@ typedef void (*GST_HelloCallback) (void *cls,
48 * 47 *
49 * @param friend_only use a friend only hello 48 * @param friend_only use a friend only hello
50 * @param cb function to call whenever our HELLO changes 49 * @param cb function to call whenever our HELLO changes
51 * @param cb_cls closure for cb 50 * @param cb_cls closure for @a cb
52 */ 51 */
53void 52void
54GST_hello_start (int friend_only, GST_HelloCallback cb, void *cb_cls); 53GST_hello_start (int friend_only,
54 GST_HelloCallback cb,
55 void *cb_cls);
55 56
56 57
57/** 58/**
@@ -73,7 +74,7 @@ GST_hello_get (void);
73/** 74/**
74 * Add or remove an address from this peer's HELLO message. 75 * Add or remove an address from this peer's HELLO message.
75 * 76 *
76 * @param addremove GNUNET_YES to add, GNUNET_NO to remove 77 * @param addremove #GNUNET_YES to add, #GNUNET_NO to remove
77 * @param address address to add or remove 78 * @param address address to add or remove
78 */ 79 */
79void 80void
@@ -88,8 +89,8 @@ GST_hello_modify_addresses (int addremove,
88 * @param sig location where to cache PONG signatures for this address [set] 89 * @param sig location where to cache PONG signatures for this address [set]
89 * @param sig_expiration how long until the current 'sig' expires? 90 * @param sig_expiration how long until the current 'sig' expires?
90 * (ZERO if sig was never created) [set] 91 * (ZERO if sig was never created) [set]
91 * @return GNUNET_YES if this is one of our addresses, 92 * @return #GNUNET_YES if this is one of our addresses,
92 * GNUNET_NO if not 93 * #GNUNET_NO if not
93 */ 94 */
94int 95int
95GST_hello_test_address (const struct GNUNET_HELLO_Address *address, 96GST_hello_test_address (const struct GNUNET_HELLO_Address *address,
diff --git a/src/transport/gnunet-service-transport_manipulation.c b/src/transport/gnunet-service-transport_manipulation.c
index 0d0249bc2..3d4701188 100644
--- a/src/transport/gnunet-service-transport_manipulation.c
+++ b/src/transport/gnunet-service-transport_manipulation.c
@@ -39,6 +39,7 @@ enum TRAFFIC_METRIC_DIRECTION
39 TM_SEND = 0, TM_RECEIVE = 1, TM_BOTH = 2 39 TM_SEND = 0, TM_RECEIVE = 1, TM_BOTH = 2
40}; 40};
41 41
42
42/** 43/**
43 * Struct containing information about manipulations to a specific peer 44 * Struct containing information about manipulations to a specific peer
44 */ 45 */
@@ -105,6 +106,7 @@ struct TM_Peer
105 struct DelayQueueEntry *send_tail; 106 struct DelayQueueEntry *send_tail;
106}; 107};
107 108
109
108struct GST_ManipulationHandle 110struct GST_ManipulationHandle
109{ 111{
110 /** 112 /**
@@ -487,35 +489,39 @@ GST_manipulation_send(const struct GNUNET_PeerIdentity *target, const void *msg,
487 * @param ats_count the number of ats information 489 * @param ats_count the number of ats information
488 */ 490 */
489struct GNUNET_ATS_Information * 491struct GNUNET_ATS_Information *
490GST_manipulation_manipulate_metrics(const struct GNUNET_PeerIdentity *peer, 492GST_manipulation_manipulate_metrics(const struct GNUNET_HELLO_Address *address,
491 const struct GNUNET_HELLO_Address *address, struct Session *session, 493 struct Session *session,
492 const struct GNUNET_ATS_Information *ats, uint32_t ats_count) 494 const struct GNUNET_ATS_Information *ats,
495 uint32_t ats_count)
493{ 496{
494 struct GNUNET_ATS_Information *ats_new = 497 const struct GNUNET_PeerIdentity *peer = &address->peer;
495 GNUNET_malloc (sizeof (struct GNUNET_ATS_Information) *ats_count); 498 struct GNUNET_ATS_Information *ats_new;
496 struct TM_Peer *tmp; 499 struct TM_Peer *tmp;
497 uint32_t m_tmp; 500 uint32_t m_tmp;
498 uint32_t g_tmp; 501 uint32_t g_tmp;
499 int d; 502 uint32_t d;
500 tmp = GNUNET_CONTAINER_multipeermap_get(man_handle.peers, peer);
501 503
504 if (0 == ats_count)
505 return NULL;
506 ats_new = GNUNET_malloc (sizeof (struct GNUNET_ATS_Information) * ats_count);
507 tmp = GNUNET_CONTAINER_multipeermap_get (man_handle.peers, peer);
502 for (d = 0; d < ats_count; d++) 508 for (d = 0; d < ats_count; d++)
503 { 509 {
504 ats_new[d] = ats[d]; 510 ats_new[d] = ats[d];
505 m_tmp = UINT32_MAX; 511 m_tmp = UINT32_MAX;
506 if (NULL != tmp) 512 if (NULL != tmp)
507 m_tmp = find_metric(tmp, ntohl(ats[d].type), TM_RECEIVE); 513 m_tmp = find_metric(tmp, ntohl(ats[d].type), TM_RECEIVE);
508 g_tmp = find_metric(&man_handle.general, ntohl(ats[d].type), TM_RECEIVE); 514 g_tmp = find_metric(&man_handle.general, ntohl(ats[d].type), TM_RECEIVE);
509 515
510 if (UINT32_MAX != g_tmp) 516 if (UINT32_MAX != g_tmp)
511 ats_new[d].value = htonl(g_tmp); 517 ats_new[d].value = htonl(g_tmp);
512 if (UINT32_MAX != m_tmp) 518 if (UINT32_MAX != m_tmp)
513 ats_new[d].value = htonl(m_tmp); 519 ats_new[d].value = htonl(m_tmp);
514 } 520 }
515
516 return ats_new; 521 return ats_new;
517} 522}
518 523
524
519/** 525/**
520 * Adapter function between transport plugins and transport receive function 526 * Adapter function between transport plugins and transport receive function
521 * manipulation delays for next send. 527 * manipulation delays for next send.
@@ -528,9 +534,9 @@ GST_manipulation_manipulate_metrics(const struct GNUNET_PeerIdentity *peer,
528 */ 534 */
529struct GNUNET_TIME_Relative 535struct GNUNET_TIME_Relative
530GST_manipulation_recv (void *cls, 536GST_manipulation_recv (void *cls,
531 const struct GNUNET_HELLO_Address *address, 537 const struct GNUNET_HELLO_Address *address,
532 struct Session *session, 538 struct Session *session,
533 const struct GNUNET_MessageHeader *message) 539 const struct GNUNET_MessageHeader *message)
534{ 540{
535 struct TM_Peer *tmp; 541 struct TM_Peer *tmp;
536 uint32_t p_recv_delay; 542 uint32_t p_recv_delay;
diff --git a/src/transport/gnunet-service-transport_manipulation.h b/src/transport/gnunet-service-transport_manipulation.h
index 668e91716..e020c3396 100644
--- a/src/transport/gnunet-service-transport_manipulation.h
+++ b/src/transport/gnunet-service-transport_manipulation.h
@@ -77,9 +77,10 @@ GST_manipulation_send (const struct GNUNET_PeerIdentity *target,
77 */ 77 */
78struct GNUNET_TIME_Relative 78struct GNUNET_TIME_Relative
79GST_manipulation_recv (void *cls, 79GST_manipulation_recv (void *cls,
80 const struct GNUNET_HELLO_Address *address, 80 const struct GNUNET_HELLO_Address *address,
81 struct Session *session, 81 struct Session *session,
82 const struct GNUNET_MessageHeader *message); 82 const struct GNUNET_MessageHeader *message);
83
83 84
84/** 85/**
85 * Function that will be called to manipulate ATS information according to 86 * Function that will be called to manipulate ATS information according to
@@ -90,13 +91,14 @@ GST_manipulation_recv (void *cls,
90 * @param session the session 91 * @param session the session
91 * @param ats the ats information 92 * @param ats the ats information
92 * @param ats_count the number of ats information 93 * @param ats_count the number of ats information
94 * @return modified @a ats information
93 */ 95 */
94struct GNUNET_ATS_Information * 96struct GNUNET_ATS_Information *
95GST_manipulation_manipulate_metrics (const struct GNUNET_PeerIdentity *peer, 97GST_manipulation_manipulate_metrics (const struct GNUNET_HELLO_Address *address,
96 const struct GNUNET_HELLO_Address *address, 98 struct Session *session,
97 struct Session *session, 99 const struct GNUNET_ATS_Information *ats,
98 const struct GNUNET_ATS_Information *ats, 100 uint32_t ats_count);
99 uint32_t ats_count); 101
100 102
101/** 103/**
102 * Notify manipulation about disconnect so it can discard queued messages 104 * Notify manipulation about disconnect so it can discard queued messages
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c
index 1bf1fd754..40bad6d75 100644
--- a/src/transport/gnunet-service-transport_neighbours.c
+++ b/src/transport/gnunet-service-transport_neighbours.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2010-2013 Christian Grothoff (and other contributing authors) 3 (C) 2010-2015 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,13 +25,14 @@
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_ats_service.h" 27#include "gnunet_ats_service.h"
28#include "gnunet-service-transport_ats.h"
29#include "gnunet-service-transport_blacklist.h"
30#include "gnunet-service-transport_clients.h"
28#include "gnunet-service-transport_neighbours.h" 31#include "gnunet-service-transport_neighbours.h"
29#include "gnunet-service-transport_plugins.h" 32#include "gnunet-service-transport_plugins.h"
30#include "gnunet-service-transport_validation.h" 33#include "gnunet-service-transport_validation.h"
31#include "gnunet-service-transport_clients.h"
32#include "gnunet-service-transport.h" 34#include "gnunet-service-transport.h"
33#include "gnunet_peerinfo_service.h" 35#include "gnunet_peerinfo_service.h"
34#include "gnunet-service-transport_blacklist.h"
35#include "gnunet_constants.h" 36#include "gnunet_constants.h"
36#include "transport.h" 37#include "transport.h"
37 38
@@ -255,8 +256,6 @@ struct MessageQueue
255}; 256};
256 257
257 258
258
259
260/** 259/**
261 * A possible address we could use to communicate with a neighbour. 260 * A possible address we could use to communicate with a neighbour.
262 */ 261 */
@@ -301,6 +300,7 @@ struct NeighbourAddress
301 uint32_t keep_alive_nonce; 300 uint32_t keep_alive_nonce;
302}; 301};
303 302
303
304/** 304/**
305 * Entry in neighbours. 305 * Entry in neighbours.
306 */ 306 */
@@ -344,12 +344,12 @@ struct NeighbourMapEntry
344 * Main task that drives this peer (timeouts, keepalives, etc.). 344 * Main task that drives this peer (timeouts, keepalives, etc.).
345 * Always runs the 'master_task'. 345 * Always runs the 'master_task'.
346 */ 346 */
347 struct GNUNET_SCHEDULER_Task * task; 347 struct GNUNET_SCHEDULER_Task *task;
348 348
349 /** 349 /**
350 * Task to disconnect neighbour after we received a DISCONNECT message 350 * Task to disconnect neighbour after we received a DISCONNECT message
351 */ 351 */
352 struct GNUNET_SCHEDULER_Task * delayed_disconnect_task; 352 struct GNUNET_SCHEDULER_Task *delayed_disconnect_task;
353 353
354 /** 354 /**
355 * At what time should we sent the next keep-alive message? 355 * At what time should we sent the next keep-alive message?
@@ -480,7 +480,7 @@ struct BlackListCheckContext
480 480
481 481
482/** 482/**
483 * Hash map from peer identities to the respective 'struct NeighbourMapEntry'. 483 * Hash map from peer identities to the respective `struct NeighbourMapEntry`.
484 */ 484 */
485static struct GNUNET_CONTAINER_MultiPeerMap *neighbours; 485static struct GNUNET_CONTAINER_MultiPeerMap *neighbours;
486 486
@@ -541,9 +541,15 @@ static unsigned long long bytes_in_send_queue;
541 */ 541 */
542static struct GNUNET_SCHEDULER_Task * util_transmission_tk; 542static struct GNUNET_SCHEDULER_Task * util_transmission_tk;
543 543
544 544/**
545 * FIXME
546 */
545static struct GNUNET_CONTAINER_MultiPeerMap *registered_quota_notifications; 547static struct GNUNET_CONTAINER_MultiPeerMap *registered_quota_notifications;
546 548
549
550/**
551 * FIXME
552 */
547static char * 553static char *
548print_ack_state (enum GST_ACK_State s) 554print_ack_state (enum GST_ACK_State s)
549{ 555{
@@ -589,6 +595,7 @@ test_connected (struct NeighbourMapEntry *n)
589 return GNUNET_TRANSPORT_is_connected (n->state); 595 return GNUNET_TRANSPORT_is_connected (n->state);
590} 596}
591 597
598
592/** 599/**
593 * Send information about a new outbound quota to our clients. 600 * Send information about a new outbound quota to our clients.
594 * 601 *
@@ -701,9 +708,10 @@ set_timeout (struct NeighbourMapEntry *n,
701 struct GNUNET_TIME_Absolute timeout) 708 struct GNUNET_TIME_Absolute timeout)
702{ 709{
703 n->timeout = timeout; 710 n->timeout = timeout;
704 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Neighbour `%s' changed timeout %s\n", 711 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
705 GNUNET_i2s (&n->id), 712 "Neighbour `%s' changed timeout %s\n",
706 GNUNET_STRINGS_absolute_time_to_string (timeout)); 713 GNUNET_i2s (&n->id),
714 GNUNET_STRINGS_absolute_time_to_string (timeout));
707 neighbour_change_cb (callback_cls, 715 neighbour_change_cb (callback_cls,
708 &n->id, 716 &n->id,
709 n->primary_address.address, 717 n->primary_address.address,
@@ -732,6 +740,7 @@ set_alternative_address (struct NeighbourMapEntry *n,
732 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) 740 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out)
733{ 741{
734 struct GNUNET_TRANSPORT_PluginFunctions *papi; 742 struct GNUNET_TRANSPORT_PluginFunctions *papi;
743
735 if (NULL == (papi = GST_plugins_find (address->transport_name))) 744 if (NULL == (papi = GST_plugins_find (address->transport_name)))
736 { 745 {
737 GNUNET_break (0); 746 GNUNET_break (0);
@@ -750,14 +759,19 @@ set_alternative_address (struct NeighbourMapEntry *n,
750 { 759 {
751 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 760 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
752 "Failed to obtain new session for peer `%s' and address '%s'\n", 761 "Failed to obtain new session for peer `%s' and address '%s'\n",
753 GNUNET_i2s (&address->peer), GST_plugins_a2s (address)); 762 GNUNET_i2s (&address->peer),
754 GNUNET_ATS_address_destroyed (GST_ats, address, NULL); 763 GST_plugins_a2s (address));
764 GNUNET_STATISTICS_update (GST_stats,
765 gettext_noop ("# session creation failed"),
766 1,
767 GNUNET_NO);
755 return; 768 return;
756 } 769 }
757 770 GST_ats_new_session (address, session);
758 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Neighbour `%s' configured alternative address %s\n", 771 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
759 GNUNET_i2s (&n->id), 772 "Neighbour `%s' configured alternative address %s\n",
760 GST_plugins_a2s(address)); 773 GNUNET_i2s (&n->id),
774 GST_plugins_a2s(address));
761 775
762 n->alternative_address.address = GNUNET_HELLO_address_copy (address); 776 n->alternative_address.address = GNUNET_HELLO_address_copy (address);
763 n->alternative_address.bandwidth_in = bandwidth_in; 777 n->alternative_address.bandwidth_in = bandwidth_in;
@@ -802,8 +816,13 @@ set_primary_address (struct NeighbourMapEntry *n,
802 if (is_active != n->primary_address.ats_active) 816 if (is_active != n->primary_address.ats_active)
803 { 817 {
804 n->primary_address.ats_active = is_active; 818 n->primary_address.ats_active = is_active;
805 GNUNET_ATS_address_in_use (GST_ats, n->primary_address.address, n->primary_address.session, is_active); 819 GNUNET_ATS_address_in_use (GST_ats,
806 GST_validation_set_address_use (n->primary_address.address, n->primary_address.session, is_active); 820 n->primary_address.address,
821 n->primary_address.session,
822 is_active);
823 GST_validation_set_address_use (n->primary_address.address,
824 n->primary_address.session,
825 is_active);
807 } 826 }
808 if (GNUNET_YES == is_active) 827 if (GNUNET_YES == is_active)
809 { 828 {
@@ -820,10 +839,13 @@ set_primary_address (struct NeighbourMapEntry *n,
820 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 839 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
821 "Failed to obtain new session for peer `%s' and address '%s'\n", 840 "Failed to obtain new session for peer `%s' and address '%s'\n",
822 GNUNET_i2s (&address->peer), GST_plugins_a2s (address)); 841 GNUNET_i2s (&address->peer), GST_plugins_a2s (address));
823 GNUNET_ATS_address_destroyed (GST_ats, address, NULL); 842 GNUNET_STATISTICS_update (GST_stats,
843 gettext_noop ("# session creation failed"),
844 1,
845 GNUNET_NO);
824 return; 846 return;
825 } 847 }
826 848 GST_ats_new_session (address, session);
827 n->primary_address.address = GNUNET_HELLO_address_copy (address); 849 n->primary_address.address = GNUNET_HELLO_address_copy (address);
828 n->primary_address.bandwidth_in = bandwidth_in; 850 n->primary_address.bandwidth_in = bandwidth_in;
829 n->primary_address.bandwidth_out = bandwidth_out; 851 n->primary_address.bandwidth_out = bandwidth_out;
@@ -833,24 +855,31 @@ set_primary_address (struct NeighbourMapEntry *n,
833 if (GNUNET_YES == is_active) 855 if (GNUNET_YES == is_active)
834 { 856 {
835 /* Telling ATS about new session */ 857 /* Telling ATS about new session */
836 GNUNET_ATS_address_in_use (GST_ats, n->primary_address.address, n->primary_address.session, GNUNET_YES); 858 GNUNET_ATS_address_in_use (GST_ats,
837 GST_validation_set_address_use (n->primary_address.address, n->primary_address.session, GNUNET_YES); 859 n->primary_address.address,
860 n->primary_address.session,
861 GNUNET_YES);
862 GST_validation_set_address_use (n->primary_address.address,
863 n->primary_address.session,
864 GNUNET_YES);
838 GST_neighbours_set_incoming_quota (&address->peer, bandwidth_in); 865 GST_neighbours_set_incoming_quota (&address->peer, bandwidth_in);
839 send_outbound_quota (&address->peer, bandwidth_out); 866 send_outbound_quota (&address->peer, bandwidth_out);
840 } 867 }
841 868
842 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Neighbour `%s' switched to address `%s'\n", 869 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
843 GNUNET_i2s (&n->id), 870 "Neighbour `%s' switched to address `%s'\n",
844 GST_plugins_a2s(address)); 871 GNUNET_i2s (&n->id),
872 GST_plugins_a2s(address));
845 873
846 neighbour_change_cb (callback_cls, 874 neighbour_change_cb (callback_cls,
847 &n->id, 875 &n->id,
848 n->primary_address.address, 876 n->primary_address.address,
849 n->state, n->timeout, 877 n->state, n->timeout,
850 n->primary_address.bandwidth_in, 878 n->primary_address.bandwidth_in,
851 n->primary_address.bandwidth_out); 879 n->primary_address.bandwidth_out);
852} 880}
853 881
882
854/** 883/**
855 * Clear the primary address of a neighbour since this address is not 884 * Clear the primary address of a neighbour since this address is not
856 * valid anymore and notify monitoring about it 885 * valid anymore and notify monitoring about it
@@ -865,13 +894,14 @@ unset_primary_address (struct NeighbourMapEntry *n)
865 894
866 /* Notify monitoring about it */ 895 /* Notify monitoring about it */
867 neighbour_change_cb (callback_cls, 896 neighbour_change_cb (callback_cls,
868 &n->id, 897 &n->id,
869 NULL, 898 NULL,
870 n->state, n->timeout, 899 n->state, n->timeout,
871 n->primary_address.bandwidth_in, 900 n->primary_address.bandwidth_in,
872 n->primary_address.bandwidth_out); 901 n->primary_address.bandwidth_out);
873} 902}
874 903
904
875/** 905/**
876 * Clear the alternative address of a neighbour since this address is not 906 * Clear the alternative address of a neighbour since this address is not
877 * valid anymore 907 * valid anymore
@@ -885,6 +915,7 @@ unset_alternative_address (struct NeighbourMapEntry *n)
885 free_address (&n->alternative_address); 915 free_address (&n->alternative_address);
886} 916}
887 917
918
888/** 919/**
889 * Free a neighbour map entry. 920 * Free a neighbour map entry.
890 * 921 *
@@ -937,6 +968,8 @@ free_neighbour (struct NeighbourMapEntry *n,
937 free_address (&n->alternative_address); 968 free_address (&n->alternative_address);
938 969
939 /* cut all transport-level connection for this peer */ 970 /* cut all transport-level connection for this peer */
971 // FIXME: might want to revisit this; maybe just
972 // shorten session timeout on plugin level?
940 if ((GNUNET_NO == keep_sessions) && 973 if ((GNUNET_NO == keep_sessions) &&
941 (NULL != backup_primary) && 974 (NULL != backup_primary) &&
942 (NULL != (papi = GST_plugins_find (backup_primary->transport_name)))) 975 (NULL != (papi = GST_plugins_find (backup_primary->transport_name))))
@@ -1369,7 +1402,7 @@ send_keepalive (struct NeighbourMapEntry *n)
1369 */ 1402 */
1370void 1403void
1371GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour, 1404GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour,
1372 const struct GNUNET_MessageHeader *m) 1405 const struct GNUNET_MessageHeader *m)
1373{ 1406{
1374 struct NeighbourMapEntry *n; 1407 struct NeighbourMapEntry *n;
1375 const struct SessionKeepAliveMessage *msg_in; 1408 const struct SessionKeepAliveMessage *msg_in;
@@ -1422,7 +1455,7 @@ GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour,
1422 */ 1455 */
1423void 1456void
1424GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour, 1457GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour,
1425 const struct GNUNET_MessageHeader *m) 1458 const struct GNUNET_MessageHeader *m)
1426{ 1459{
1427 struct NeighbourMapEntry *n; 1460 struct NeighbourMapEntry *n;
1428 const struct SessionKeepAliveMessage *msg; 1461 const struct SessionKeepAliveMessage *msg;
@@ -1505,8 +1538,9 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour,
1505 else 1538 else
1506 latency = n->latency.rel_value_us; 1539 latency = n->latency.rel_value_us;
1507 ats.value = htonl (latency); 1540 ats.value = htonl (latency);
1508 GST_ats_update_metrics (&n->id, n->primary_address.address, 1541 GST_ats_update_metrics (n->primary_address.address,
1509 n->primary_address.session, &ats, 1); 1542 n->primary_address.session,
1543 &ats, 1);
1510} 1544}
1511 1545
1512 1546
@@ -1655,12 +1689,13 @@ GST_neighbours_send (const struct GNUNET_PeerIdentity *target, const void *msg,
1655 n->task = GNUNET_SCHEDULER_add_now (&master_task, n); 1689 n->task = GNUNET_SCHEDULER_add_now (&master_task, n);
1656} 1690}
1657 1691
1692
1658static void 1693static void
1659send_session_connect_cont (void *cls, 1694send_session_connect_cont (void *cls,
1660 const struct GNUNET_PeerIdentity *target, 1695 const struct GNUNET_PeerIdentity *target,
1661 int result, 1696 int result,
1662 size_t size_payload, 1697 size_t size_payload,
1663 size_t size_on_wire) 1698 size_t size_on_wire)
1664{ 1699{
1665 struct NeighbourMapEntry *n; 1700 struct NeighbourMapEntry *n;
1666 1701
@@ -1686,26 +1721,20 @@ send_session_connect_cont (void *cls,
1686 return; 1721 return;
1687 1722
1688 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1723 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1689 _("Failed to send SYN message to peer `%s' using address `%s' session %p\n"), 1724 _("Failed to send SYN message to peer `%s' using address `%s' session %p\n"),
1690 GNUNET_i2s (target), 1725 GNUNET_i2s (target),
1691 GST_plugins_a2s (n->primary_address.address), 1726 GST_plugins_a2s (n->primary_address.address),
1692 n->primary_address.session); 1727 n->primary_address.session);
1693 1728
1694 switch (n->state) { 1729 switch (n->state) {
1695 case GNUNET_TRANSPORT_PS_SYN_SENT: 1730 case GNUNET_TRANSPORT_PS_SYN_SENT:
1696 /* Remove address and request and additional one */ 1731 /* Remove address and request and additional one */
1697 GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address,
1698 n->primary_address.session);
1699 GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL );
1700 unset_primary_address (n); 1732 unset_primary_address (n);
1701 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS, 1733 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS,
1702 GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT)); 1734 GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT));
1703 break; 1735 break;
1704 case GNUNET_TRANSPORT_PS_RECONNECT_SENT: 1736 case GNUNET_TRANSPORT_PS_RECONNECT_SENT:
1705 /* Remove address and request and additional one */ 1737 /* Remove address and request and additional one */
1706 GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address,
1707 n->primary_address.session);
1708 GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL );
1709 unset_primary_address (n); 1738 unset_primary_address (n);
1710 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_ATS, 1739 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_ATS,
1711 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); 1740 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
@@ -1714,10 +1743,6 @@ send_session_connect_cont (void *cls,
1714 /* Remove address and request and go back to primary address */ 1743 /* Remove address and request and go back to primary address */
1715 GNUNET_STATISTICS_update (GST_stats, gettext_noop 1744 GNUNET_STATISTICS_update (GST_stats, gettext_noop
1716 ("# Failed attempts to switch addresses (failed to send SYN CONT)"), 1, GNUNET_NO); 1745 ("# Failed attempts to switch addresses (failed to send SYN CONT)"), 1, GNUNET_NO);
1717 GNUNET_ATS_address_destroyed (GST_ats, n->alternative_address.address,
1718 n->alternative_address.session);
1719 GNUNET_ATS_address_destroyed (GST_ats, n->alternative_address.address,
1720 NULL );
1721 unset_alternative_address (n); 1746 unset_alternative_address (n);
1722 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED, 1747 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED,
1723 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); 1748 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
@@ -1756,6 +1781,8 @@ send_syn (struct NeighbourAddress *na)
1756 GNUNET_break (0); 1781 GNUNET_break (0);
1757 return; 1782 return;
1758 } 1783 }
1784 GST_ats_new_session (na->address,
1785 na->session);
1759 GNUNET_STATISTICS_update (GST_stats, 1786 GNUNET_STATISTICS_update (GST_stats,
1760 gettext_noop 1787 gettext_noop
1761 ("# SYN messages sent"), 1788 ("# SYN messages sent"),
@@ -1811,8 +1838,6 @@ send_syn (struct NeighbourAddress *na)
1811 disconnect_neighbour (n); 1838 disconnect_neighbour (n);
1812 break; 1839 break;
1813 } 1840 }
1814 GNUNET_ATS_address_destroyed (GST_ats, na->address, na->session);
1815 GNUNET_ATS_address_destroyed (GST_ats, na->address, NULL);
1816 } 1841 }
1817 GST_neighbours_notify_data_sent (&na->address->peer, 1842 GST_neighbours_notify_data_sent (&na->address->peer,
1818 na->address, 1843 na->address,
@@ -1855,12 +1880,6 @@ send_session_connect_ack_cont (void *cls,
1855 GST_plugins_a2s (n->primary_address.address), 1880 GST_plugins_a2s (n->primary_address.address),
1856 n->primary_address.session); 1881 n->primary_address.session);
1857 1882
1858 /* Failed to send SYN_ACK message with this address */
1859 GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address,
1860 n->primary_address.session);
1861 GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address,
1862 NULL);
1863
1864 /* Remove address and request and additional one */ 1883 /* Remove address and request and additional one */
1865 unset_primary_address (n); 1884 unset_primary_address (n);
1866 n->ack_state = ACK_SEND_SYN_ACK; 1885 n->ack_state = ACK_SEND_SYN_ACK;
@@ -1903,6 +1922,7 @@ send_connect_ack_message (const struct GNUNET_HELLO_Address *address,
1903 GNUNET_break (0); 1922 GNUNET_break (0);
1904 return; 1923 return;
1905 } 1924 }
1925 GST_ats_new_session (address, session);
1906 GNUNET_STATISTICS_update (GST_stats, 1926 GNUNET_STATISTICS_update (GST_stats,
1907 gettext_noop 1927 gettext_noop
1908 ("# SYN_ACK messages sent"), 1928 ("# SYN_ACK messages sent"),
@@ -1929,17 +1949,6 @@ send_connect_ack_message (const struct GNUNET_HELLO_Address *address,
1929 GNUNET_break (0); 1949 GNUNET_break (0);
1930 return; 1950 return;
1931 } 1951 }
1932 /* Hard failure to send the SYN_ACK message with this address:
1933 Destroy session (and address) */
1934 if (GNUNET_YES == GNUNET_HELLO_address_check_option(address,
1935 GNUNET_HELLO_ADDRESS_INFO_INBOUND))
1936 {
1937 GNUNET_ATS_address_destroyed (GST_ats, address, session);
1938 GNUNET_ATS_address_destroyed (GST_ats, address, NULL);
1939 }
1940 else
1941 GNUNET_ATS_address_destroyed (GST_ats, address, session);
1942
1943 /* Remove address and request and additional one */ 1952 /* Remove address and request and additional one */
1944 unset_primary_address (n); 1953 unset_primary_address (n);
1945 n->ack_state = ACK_SEND_SYN_ACK; 1954 n->ack_state = ACK_SEND_SYN_ACK;
@@ -1973,7 +1982,9 @@ find_notification_request (void *cls, const struct GNUNET_PeerIdentity *key, voi
1973 struct QuotaNotificationRequest *qnr = value; 1982 struct QuotaNotificationRequest *qnr = value;
1974 1983
1975 if ((qnr->session == qnr_ctx->session) && 1984 if ((qnr->session == qnr_ctx->session) &&
1976 (0 == memcmp (&qnr->peer, &qnr_ctx->peer, sizeof (struct GNUNET_PeerIdentity))) && 1985 (0 == memcmp (&qnr->peer,
1986 &qnr_ctx->peer,
1987 sizeof (struct GNUNET_PeerIdentity))) &&
1977 (0 == strcmp(qnr_ctx->plugin, qnr->plugin))) 1988 (0 == strcmp(qnr_ctx->plugin, qnr->plugin)))
1978 { 1989 {
1979 qnr_ctx->res = value; 1990 qnr_ctx->res = value;
@@ -1982,10 +1993,12 @@ find_notification_request (void *cls, const struct GNUNET_PeerIdentity *key, voi
1982 return GNUNET_YES; 1993 return GNUNET_YES;
1983} 1994}
1984 1995
1996
1985void 1997void
1986GST_neighbours_register_quota_notification(void *cls, 1998GST_neighbours_register_quota_notification (void *cls,
1987 const struct GNUNET_PeerIdentity *peer, const char *plugin, 1999 const struct GNUNET_PeerIdentity *peer,
1988 struct Session *session) 2000 const char *plugin,
2001 struct Session *session)
1989{ 2002{
1990 struct QuotaNotificationRequest *qnr; 2003 struct QuotaNotificationRequest *qnr;
1991 struct QNR_LookContext qnr_ctx; 2004 struct QNR_LookContext qnr_ctx;
@@ -2024,7 +2037,9 @@ GST_neighbours_register_quota_notification(void *cls,
2024 2037
2025void 2038void
2026GST_neighbours_unregister_quota_notification(void *cls, 2039GST_neighbours_unregister_quota_notification(void *cls,
2027 const struct GNUNET_PeerIdentity *peer, const char *plugin, struct Session *session) 2040 const struct GNUNET_PeerIdentity *peer,
2041 const char *plugin,
2042 struct Session *session)
2028{ 2043{
2029 struct QNR_LookContext qnr_ctx; 2044 struct QNR_LookContext qnr_ctx;
2030 2045
@@ -2056,8 +2071,11 @@ GST_neighbours_unregister_quota_notification(void *cls,
2056 GNUNET_free (qnr_ctx.res); 2071 GNUNET_free (qnr_ctx.res);
2057} 2072}
2058 2073
2074
2059static int 2075static int
2060notification_cb(void *cls, const struct GNUNET_PeerIdentity *key, void *value) 2076notification_cb (void *cls,
2077 const struct GNUNET_PeerIdentity *key,
2078 void *value)
2061{ 2079{
2062 /* struct NeighbourMapEntry *n = cls; */ 2080 /* struct NeighbourMapEntry *n = cls; */
2063 struct QuotaNotificationRequest *qnr = value; 2081 struct QuotaNotificationRequest *qnr = value;
@@ -2082,9 +2100,11 @@ notification_cb(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
2082 return GNUNET_OK; 2100 return GNUNET_OK;
2083} 2101}
2084 2102
2103
2085static int 2104static int
2086free_notification_cb(void *cls, const struct GNUNET_PeerIdentity *key, 2105free_notification_cb (void *cls,
2087 void *value) 2106 const struct GNUNET_PeerIdentity *key,
2107 void *value)
2088{ 2108{
2089 /* struct NeighbourMapEntry *n = cls; */ 2109 /* struct NeighbourMapEntry *n = cls; */
2090 struct QuotaNotificationRequest *qnr = value; 2110 struct QuotaNotificationRequest *qnr = value;
@@ -2097,8 +2117,9 @@ free_notification_cb(void *cls, const struct GNUNET_PeerIdentity *key,
2097 return GNUNET_OK; 2117 return GNUNET_OK;
2098} 2118}
2099 2119
2120
2100static void 2121static void
2101inbound_bw_tracker_update(void *cls) 2122inbound_bw_tracker_update (void *cls)
2102{ 2123{
2103 struct NeighbourMapEntry *n = cls; 2124 struct NeighbourMapEntry *n = cls;
2104 2125
@@ -2144,18 +2165,44 @@ setup_neighbour (const struct GNUNET_PeerIdentity *peer)
2144} 2165}
2145 2166
2146 2167
2168/**
2169 * FIXME
2170 */
2147struct BlacklistCheckSwitchContext 2171struct BlacklistCheckSwitchContext
2148{ 2172{
2173 /**
2174 * FIXME
2175 */
2149 struct BlacklistCheckSwitchContext *prev; 2176 struct BlacklistCheckSwitchContext *prev;
2150 struct BlacklistCheckSwitchContext *next;
2151 2177
2178 /**
2179 * FIXME
2180 */
2181 struct BlacklistCheckSwitchContext *next;
2152 2182
2183 /**
2184 * FIXME
2185 */
2153 struct GST_BlacklistCheck *blc; 2186 struct GST_BlacklistCheck *blc;
2154 2187
2188 /**
2189 * FIXME
2190 */
2155 struct GNUNET_HELLO_Address *address; 2191 struct GNUNET_HELLO_Address *address;
2192
2193 /**
2194 * FIXME
2195 */
2156 struct Session *session; 2196 struct Session *session;
2157 2197
2198 /**
2199 * FIXME
2200 */
2158 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in; 2201 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in;
2202
2203 /**
2204 * FIXME
2205 */
2159 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out; 2206 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out;
2160}; 2207};
2161 2208
@@ -2465,18 +2512,13 @@ switch_address_bl_check_cont (void *cls,
2465 GNUNET_i2s (&blc_ctx->address->peer)); 2512 GNUNET_i2s (&blc_ctx->address->peer));
2466 } 2513 }
2467 2514
2468 /* This address is blacklisted, delete address and session (if existing) in ATS */ 2515 /* This address is blacklisted, delete session */
2469 GNUNET_ATS_address_destroyed (GST_ats, blc_ctx->address, blc_ctx->session); 2516 /* FIXME: tell plugin to force killing session here and now! */
2470
2471 if ( (GNUNET_YES == (GNUNET_HELLO_address_check_option (blc_ctx->address,
2472 GNUNET_HELLO_ADDRESS_INFO_INBOUND))) && (NULL != blc_ctx->session))
2473 {
2474 /* This is an inbound address, destroy full address */
2475 GNUNET_ATS_address_destroyed (GST_ats, blc_ctx->address, NULL );
2476 }
2477 2517
2478 /* Remove blacklist check and clean up */ 2518 /* Remove blacklist check and clean up */
2479 GNUNET_CONTAINER_DLL_remove (pending_bc_head, pending_bc_tail, blc_ctx); 2519 GNUNET_CONTAINER_DLL_remove (pending_bc_head,
2520 pending_bc_tail,
2521 blc_ctx);
2480 GNUNET_HELLO_address_free (blc_ctx->address); 2522 GNUNET_HELLO_address_free (blc_ctx->address);
2481 GNUNET_free (blc_ctx); 2523 GNUNET_free (blc_ctx);
2482 return; 2524 return;
@@ -2484,10 +2526,17 @@ switch_address_bl_check_cont (void *cls,
2484 2526
2485 if (NULL == blc_ctx->session) 2527 if (NULL == blc_ctx->session)
2486 { 2528 {
2487 blc_ctx->session = papi->get_session (papi->cls, blc_ctx->address); 2529 blc_ctx->session = papi->get_session (papi->cls,
2530 blc_ctx->address);
2488 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2531 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2489 "Obtained new session for peer `%s' and address '%s': %p\n", 2532 "Obtained new session for peer `%s' and address '%s': %p\n",
2490 GNUNET_i2s (&blc_ctx->address->peer), GST_plugins_a2s (blc_ctx->address), blc_ctx->session); 2533 GNUNET_i2s (&blc_ctx->address->peer),
2534 GST_plugins_a2s (blc_ctx->address),
2535 blc_ctx->session);
2536 if (NULL != blc_ctx->session)
2537 GST_ats_new_session (blc_ctx->address,
2538 blc_ctx->session);
2539
2491 } 2540 }
2492 if (NULL == blc_ctx->session) 2541 if (NULL == blc_ctx->session)
2493 { 2542 {
@@ -2497,9 +2546,9 @@ switch_address_bl_check_cont (void *cls,
2497 GNUNET_i2s (&blc_ctx->address->peer), 2546 GNUNET_i2s (&blc_ctx->address->peer),
2498 GST_plugins_a2s (blc_ctx->address)); 2547 GST_plugins_a2s (blc_ctx->address));
2499 /* Delete address in ATS */ 2548 /* Delete address in ATS */
2500 GNUNET_ATS_address_destroyed (GST_ats, blc_ctx->address, NULL); 2549 GNUNET_CONTAINER_DLL_remove (pending_bc_head,
2501 2550 pending_bc_tail,
2502 GNUNET_CONTAINER_DLL_remove (pending_bc_head, pending_bc_tail, blc_ctx); 2551 blc_ctx);
2503 GNUNET_HELLO_address_free (blc_ctx->address); 2552 GNUNET_HELLO_address_free (blc_ctx->address);
2504 GNUNET_free (blc_ctx); 2553 GNUNET_free (blc_ctx);
2505 return; 2554 return;
@@ -2721,21 +2770,15 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
2721 if (NULL == (GST_plugins_find (address->transport_name))) 2770 if (NULL == (GST_plugins_find (address->transport_name)))
2722 { 2771 {
2723 /* we don't have the plugin for this address */ 2772 /* we don't have the plugin for this address */
2724 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2773 GNUNET_break (0);
2725 "Plugin `%s' is unknown, suggestion for peer %s ignored\n",
2726 address->transport_name,
2727 GNUNET_i2s (peer));
2728 GNUNET_ATS_address_destroyed (GST_ats, address, NULL);
2729 return; 2774 return;
2730 } 2775 }
2731 if ((NULL == session) && 2776 if ((NULL == session) &&
2732 (GNUNET_HELLO_address_check_option (address, GNUNET_HELLO_ADDRESS_INFO_INBOUND))) 2777 (GNUNET_HELLO_address_check_option (address,
2778 GNUNET_HELLO_ADDRESS_INFO_INBOUND)))
2733 { 2779 {
2734 /* This is a inbound address and we do not have a session to use! */ 2780 /* This is a inbound address and we do not have a session to use! */
2735 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2781 GNUNET_break (0);
2736 "Inbound address without session `%s'! Destroying address...\n",
2737 GST_plugins_a2s (address));
2738 GNUNET_ATS_address_destroyed (GST_ats, address, NULL);
2739 return; 2782 return;
2740 } 2783 }
2741 2784
@@ -2766,6 +2809,15 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
2766} 2809}
2767 2810
2768 2811
2812/**
2813 * Function called to send network utilization data to ATS for
2814 * each active connection.
2815 *
2816 * @param cls NULL
2817 * @param key peer we send utilization data for
2818 * @param value the `struct NeighbourMapEntry *` with data to send
2819 * @return #GNUNET_OK (continue to iterate)
2820 */
2769static int 2821static int
2770send_utilization_data (void *cls, 2822send_utilization_data (void *cls,
2771 const struct GNUNET_PeerIdentity *key, 2823 const struct GNUNET_PeerIdentity *key,
@@ -2779,6 +2831,8 @@ send_utilization_data (void *cls,
2779 uint32_t bps_out; 2831 uint32_t bps_out;
2780 struct GNUNET_TIME_Relative delta; 2832 struct GNUNET_TIME_Relative delta;
2781 2833
2834 if (GNUNET_TRANSPORT_PS_CONNECTED != n->state)
2835 return GNUNET_OK;
2782 delta = GNUNET_TIME_absolute_get_difference (n->last_util_transmission, 2836 delta = GNUNET_TIME_absolute_get_difference (n->last_util_transmission,
2783 GNUNET_TIME_absolute_get ()); 2837 GNUNET_TIME_absolute_get ());
2784 2838
@@ -2817,8 +2871,9 @@ send_utilization_data (void *cls,
2817 atsi[3].type = htonl (GNUNET_ATS_UTILIZATION_PAYLOAD_IN); 2871 atsi[3].type = htonl (GNUNET_ATS_UTILIZATION_PAYLOAD_IN);
2818 atsi[3].value = htonl (bps_pl_in); 2872 atsi[3].value = htonl (bps_pl_in);
2819 2873
2820 GST_ats_update_metrics (key, n->primary_address.address, 2874 GST_ats_update_metrics (n->primary_address.address,
2821 n->primary_address.session, atsi, 4); 2875 n->primary_address.session,
2876 atsi, 4);
2822 n->util_payload_bytes_recv = 0; 2877 n->util_payload_bytes_recv = 0;
2823 n->util_payload_bytes_sent = 0; 2878 n->util_payload_bytes_sent = 0;
2824 n->util_total_bytes_recv = 0; 2879 n->util_total_bytes_recv = 0;
@@ -2952,12 +3007,6 @@ master_task (void *cls,
2952 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 3007 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2953 "Connection to `%s' timed out waiting for other peer to send SYN_ACK\n", 3008 "Connection to `%s' timed out waiting for other peer to send SYN_ACK\n",
2954 GNUNET_i2s (&n->id)); 3009 GNUNET_i2s (&n->id));
2955 /* We could not send to this address, delete address and session */
2956 if (NULL != n->primary_address.session)
2957 GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address,
2958 n->primary_address.session);
2959 GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL);
2960
2961 /* Remove address and request and additional one */ 3010 /* Remove address and request and additional one */
2962 unset_primary_address (n); 3011 unset_primary_address (n);
2963 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS, 3012 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS,
@@ -3023,8 +3072,10 @@ master_task (void *cls,
3023 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 3072 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3024 "Connection to `%s' timed out, missing KEEPALIVE_RESPONSEs (after trying to SYN on alternative address)\n", 3073 "Connection to `%s' timed out, missing KEEPALIVE_RESPONSEs (after trying to SYN on alternative address)\n",
3025 GNUNET_i2s (&n->id)); 3074 GNUNET_i2s (&n->id));
3026 GNUNET_STATISTICS_update (GST_stats, gettext_noop 3075 GNUNET_STATISTICS_update (GST_stats,
3027 ("# Failed attempts to switch addresses (no response)"), 1, GNUNET_NO); 3076 gettext_noop ("# Failed attempts to switch addresses (no response)"),
3077 1,
3078 GNUNET_NO);
3028 disconnect_neighbour (n); 3079 disconnect_neighbour (n);
3029 return; 3080 return;
3030 } 3081 }
@@ -3161,17 +3212,12 @@ GST_neighbours_handle_session_syn_ack (const struct GNUNET_MessageHeader *messag
3161 n->primary_address.bandwidth_in, 3212 n->primary_address.bandwidth_in,
3162 n->primary_address.bandwidth_out); 3213 n->primary_address.bandwidth_out);
3163 /* Tell ATS that the outbound session we created to send SYN was successful */ 3214 /* Tell ATS that the outbound session we created to send SYN was successful */
3164 // FIXME: shouldn't ATS already know about *outbound* sessions
3165 // in particular?
3166 GST_ats_add_address (n->primary_address.address,
3167 n->primary_address.session,
3168 NULL, 0);
3169 set_primary_address (n, 3215 set_primary_address (n,
3170 n->primary_address.address, 3216 n->primary_address.address,
3171 n->primary_address.session, 3217 n->primary_address.session,
3172 n->primary_address.bandwidth_in, 3218 n->primary_address.bandwidth_in,
3173 n->primary_address.bandwidth_out, 3219 n->primary_address.bandwidth_out,
3174 GNUNET_YES); 3220 GNUNET_YES);
3175 send_session_ack_message (n); 3221 send_session_ack_message (n);
3176 break; 3222 break;
3177 case GNUNET_TRANSPORT_PS_SYN_RECV_ATS: 3223 case GNUNET_TRANSPORT_PS_SYN_RECV_ATS:
@@ -3202,13 +3248,9 @@ GST_neighbours_handle_session_syn_ack (const struct GNUNET_MessageHeader *messag
3202 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT: 3248 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT:
3203 /* new address worked; adopt it and go back to connected! */ 3249 /* new address worked; adopt it and go back to connected! */
3204 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED, 3250 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED,
3205 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT)); 3251 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
3206 GNUNET_break (GNUNET_NO == n->alternative_address.ats_active); 3252 GNUNET_break (GNUNET_NO == n->alternative_address.ats_active);
3207 3253
3208 /* Notify about session... perhaps we obtained it */
3209 // FIXME: why is this needed?
3210 GST_ats_add_address (n->alternative_address.address,
3211 n->alternative_address.session, NULL, 0);
3212 /* Set primary addresses */ 3254 /* Set primary addresses */
3213 set_primary_address (n, n->alternative_address.address, 3255 set_primary_address (n, n->alternative_address.address,
3214 n->alternative_address.session, n->alternative_address.bandwidth_in, 3256 n->alternative_address.session, n->alternative_address.bandwidth_in,
@@ -3309,7 +3351,6 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
3309 GNUNET_i2s (peer)); 3351 GNUNET_i2s (peer));
3310 3352
3311 /* Destroy the address since it cannot be used */ 3353 /* Destroy the address since it cannot be used */
3312 GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL);
3313 unset_primary_address (n); 3354 unset_primary_address (n);
3314 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS, 3355 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS,
3315 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); 3356 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
@@ -3337,9 +3378,7 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
3337 GST_plugins_a2s (n->primary_address.address), 3378 GST_plugins_a2s (n->primary_address.address),
3338 n->primary_address.session, 3379 n->primary_address.session,
3339 GNUNET_i2s (peer)); 3380 GNUNET_i2s (peer));
3340
3341 /* Destroy the address since it cannot be used */ 3381 /* Destroy the address since it cannot be used */
3342 GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL);
3343 unset_primary_address (n); 3382 unset_primary_address (n);
3344 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_ATS, 3383 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_ATS,
3345 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); 3384 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
@@ -3358,13 +3397,7 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
3358 n->alternative_address.session); 3397 n->alternative_address.session);
3359 3398
3360 /* Destroy the inbound address since it cannot be used */ 3399 /* Destroy the inbound address since it cannot be used */
3361 if (GNUNET_YES
3362 == GNUNET_HELLO_address_check_option (n->primary_address.address,
3363 GNUNET_HELLO_ADDRESS_INFO_INBOUND))
3364 GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL);
3365 free_address (&n->primary_address); 3400 free_address (&n->primary_address);
3366
3367
3368 n->primary_address = n->alternative_address; 3401 n->primary_address = n->alternative_address;
3369 memset (&n->alternative_address, 0, sizeof (struct NeighbourAddress)); 3402 memset (&n->alternative_address, 0, sizeof (struct NeighbourAddress));
3370 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_SENT, 3403 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_SENT,
@@ -3487,20 +3520,13 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message,
3487 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED, 3520 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED,
3488 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT)); 3521 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
3489 3522
3490 /* Add session to ATS since no session was given (NULL) and we may have
3491 * obtained a new session */
3492 // FIXME: likely not the best place to do this...
3493 GST_ats_add_address (n->primary_address.address,
3494 n->primary_address.session,
3495 NULL, 0);
3496
3497 /* Set primary address to used */ 3523 /* Set primary address to used */
3498 set_primary_address (n, 3524 set_primary_address (n,
3499 n->primary_address.address, 3525 n->primary_address.address,
3500 n->primary_address.session, 3526 n->primary_address.session,
3501 n->primary_address.bandwidth_in, 3527 n->primary_address.bandwidth_in,
3502 n->primary_address.bandwidth_out, 3528 n->primary_address.bandwidth_out,
3503 GNUNET_YES); 3529 GNUNET_YES);
3504 return GNUNET_OK; 3530 return GNUNET_OK;
3505} 3531}
3506 3532
@@ -3554,8 +3580,10 @@ GST_neighbours_set_incoming_quota (const struct GNUNET_PeerIdentity *neighbour,
3554 disconnect_neighbour (n); 3580 disconnect_neighbour (n);
3555} 3581}
3556 3582
3557void delayed_disconnect (void *cls, 3583
3558 const struct GNUNET_SCHEDULER_TaskContext* tc) 3584static void
3585delayed_disconnect (void *cls,
3586 const struct GNUNET_SCHEDULER_TaskContext* tc)
3559{ 3587{
3560 struct NeighbourMapEntry *n = cls; 3588 struct NeighbourMapEntry *n = cls;
3561 3589
@@ -3563,11 +3591,6 @@ void delayed_disconnect (void *cls,
3563 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 3591 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3564 "Disconnecting by request from peer %s\n", 3592 "Disconnecting by request from peer %s\n",
3565 GNUNET_i2s (&n->id)); 3593 GNUNET_i2s (&n->id));
3566
3567 if (NULL != n->primary_address.address)
3568 GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address,
3569 n->primary_address.session);
3570
3571 free_neighbour (n, GNUNET_NO); 3594 free_neighbour (n, GNUNET_NO);
3572} 3595}
3573 3596
@@ -3871,16 +3894,18 @@ GST_neighbours_stop ()
3871 GNUNET_SCHEDULER_cancel (util_transmission_tk); 3894 GNUNET_SCHEDULER_cancel (util_transmission_tk);
3872 util_transmission_tk = NULL; 3895 util_transmission_tk = NULL;
3873 } 3896 }
3874 3897 GNUNET_CONTAINER_multipeermap_iterate (neighbours,
3875 GNUNET_CONTAINER_multipeermap_iterate (neighbours, &disconnect_all_neighbours, 3898 &disconnect_all_neighbours,
3876 NULL ); 3899 NULL);
3877 GNUNET_CONTAINER_multipeermap_destroy (neighbours); 3900 GNUNET_CONTAINER_multipeermap_destroy (neighbours);
3878 3901
3879 next = pending_bc_head; 3902 next = pending_bc_head;
3880 for (cur = next; NULL != cur; cur = next ) 3903 for (cur = next; NULL != cur; cur = next)
3881 { 3904 {
3882 next = cur->next; 3905 next = cur->next;
3883 GNUNET_CONTAINER_DLL_remove (pending_bc_head, pending_bc_tail, cur); 3906 GNUNET_CONTAINER_DLL_remove (pending_bc_head,
3907 pending_bc_tail,
3908 cur);
3884 3909
3885 if (NULL != cur->blc) 3910 if (NULL != cur->blc)
3886 { 3911 {
@@ -3893,7 +3918,7 @@ GST_neighbours_stop ()
3893 } 3918 }
3894 3919
3895 GNUNET_CONTAINER_multipeermap_iterate (registered_quota_notifications, 3920 GNUNET_CONTAINER_multipeermap_iterate (registered_quota_notifications,
3896 &free_notification_cb, NULL); 3921 &free_notification_cb, NULL);
3897 GNUNET_CONTAINER_multipeermap_destroy (registered_quota_notifications); 3922 GNUNET_CONTAINER_multipeermap_destroy (registered_quota_notifications);
3898 registered_quota_notifications = NULL; 3923 registered_quota_notifications = NULL;
3899 3924
diff --git a/src/transport/gnunet-service-transport_neighbours.h b/src/transport/gnunet-service-transport_neighbours.h
index 49a54e9dd..744a3b913 100644
--- a/src/transport/gnunet-service-transport_neighbours.h
+++ b/src/transport/gnunet-service-transport_neighbours.h
@@ -86,10 +86,14 @@ GST_neighbours_test_connected (const struct GNUNET_PeerIdentity *target);
86 * 86 *
87 * @param cls closure 87 * @param cls closure
88 * @param success #GNUNET_OK on success, #GNUNET_NO on failure, #GNUNET_SYSERR if we're not connected 88 * @param success #GNUNET_OK on success, #GNUNET_NO on failure, #GNUNET_SYSERR if we're not connected
89 * @param bytes_payload how much payload was transmitted
90 * @param bytes_on_wire how many bytes were used on the wire
89 */ 91 */
90typedef void (*GST_NeighbourSendContinuation) (void *cls, int success, 92typedef void
91 size_t bytes_payload, 93(*GST_NeighbourSendContinuation) (void *cls,
92 size_t bytes_on_wire); 94 int success,
95 size_t bytes_payload,
96 size_t bytes_on_wire);
93 97
94 98
95/** 99/**
@@ -103,19 +107,33 @@ typedef void (*GST_NeighbourSendContinuation) (void *cls, int success,
103 * @param cont_cls closure for @a cont 107 * @param cont_cls closure for @a cont
104 */ 108 */
105void 109void
106GST_neighbours_send (const struct GNUNET_PeerIdentity *target, const void *msg, 110GST_neighbours_send (const struct GNUNET_PeerIdentity *target,
107 size_t msg_size, struct GNUNET_TIME_Relative timeout, 111 const void *msg,
112 size_t msg_size,
113 struct GNUNET_TIME_Relative timeout,
108 GST_NeighbourSendContinuation cont, void *cont_cls); 114 GST_NeighbourSendContinuation cont, void *cont_cls);
109 115
116
117
118/**
119 * FIXME
120 */
110void 121void
111GST_neighbours_register_quota_notification (void *cls, 122GST_neighbours_register_quota_notification (void *cls,
112 const struct GNUNET_PeerIdentity *peer, 123 const struct GNUNET_PeerIdentity *peer,
113 const char *plugin, 124 const char *plugin,
114 struct Session *session); 125 struct Session *session);
115 126
127
128/**
129 * FIXME
130 */
116void 131void
117GST_neighbours_unregister_quota_notification(void *cls, 132GST_neighbours_unregister_quota_notification (void *cls,
118 const struct GNUNET_PeerIdentity *peer, const char *plugin, struct Session *session); 133 const struct GNUNET_PeerIdentity *peer,
134 const char *plugin,
135 struct Session *session);
136
119 137
120/** 138/**
121 * We have received a message from the given sender. 139 * We have received a message from the given sender.
@@ -129,8 +147,9 @@ GST_neighbours_unregister_quota_notification(void *cls,
129 * @return how long to wait before reading more from this sender 147 * @return how long to wait before reading more from this sender
130 */ 148 */
131struct GNUNET_TIME_Relative 149struct GNUNET_TIME_Relative
132GST_neighbours_calculate_receive_delay (const struct GNUNET_PeerIdentity 150GST_neighbours_calculate_receive_delay (const struct GNUNET_PeerIdentity *sender,
133 *sender, ssize_t size, int *do_forward); 151 ssize_t size,
152 int *do_forward);
134 153
135 154
136/** 155/**
@@ -155,7 +174,7 @@ GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour,
155 */ 174 */
156void 175void
157GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour, 176GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour,
158 const struct GNUNET_MessageHeader *m); 177 const struct GNUNET_MessageHeader *m);
159 178
160 179
161/** 180/**
@@ -189,13 +208,14 @@ GST_neighbours_force_disconnect (const struct GNUNET_PeerIdentity *target);
189 * @param bandwidth_in inbound quota in NBO 208 * @param bandwidth_in inbound quota in NBO
190 * @param bandwidth_out outbound quota in NBO 209 * @param bandwidth_out outbound quota in NBO
191 */ 210 */
192typedef void (*GST_NeighbourIterator) (void *cls, 211typedef void
193 const struct GNUNET_PeerIdentity *neighbour, 212(*GST_NeighbourIterator) (void *cls,
194 const struct GNUNET_HELLO_Address *address, 213 const struct GNUNET_PeerIdentity *neighbour,
195 enum GNUNET_TRANSPORT_PeerState state, 214 const struct GNUNET_HELLO_Address *address,
196 struct GNUNET_TIME_Absolute state_timeout, 215 enum GNUNET_TRANSPORT_PeerState state,
197 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, 216 struct GNUNET_TIME_Absolute state_timeout,
198 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out); 217 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
218 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out);
199 219
200 220
201/** 221/**
@@ -221,6 +241,9 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
221 struct Session *session); 241 struct Session *session);
222 242
223 243
244/**
245 * FIXME
246 */
224void 247void
225GST_neighbours_notify_data_recv (const struct GNUNET_PeerIdentity *peer, 248GST_neighbours_notify_data_recv (const struct GNUNET_PeerIdentity *peer,
226 const struct GNUNET_HELLO_Address *address, 249 const struct GNUNET_HELLO_Address *address,
@@ -228,6 +251,9 @@ GST_neighbours_notify_data_recv (const struct GNUNET_PeerIdentity *peer,
228 const struct GNUNET_MessageHeader *message); 251 const struct GNUNET_MessageHeader *message);
229 252
230 253
254/**
255 * FIXME
256 */
231void 257void
232GST_neighbours_notify_payload_recv (const struct GNUNET_PeerIdentity *peer, 258GST_neighbours_notify_payload_recv (const struct GNUNET_PeerIdentity *peer,
233 const struct GNUNET_HELLO_Address *address, 259 const struct GNUNET_HELLO_Address *address,
@@ -235,11 +261,17 @@ GST_neighbours_notify_payload_recv (const struct GNUNET_PeerIdentity *peer,
235 const struct GNUNET_MessageHeader *message); 261 const struct GNUNET_MessageHeader *message);
236 262
237 263
264/**
265 * FIXME
266 */
238void 267void
239GST_neighbours_notify_payload_sent (const struct GNUNET_PeerIdentity *peer, 268GST_neighbours_notify_payload_sent (const struct GNUNET_PeerIdentity *peer,
240 size_t size); 269 size_t size);
241 270
242 271
272/**
273 * FIXME
274 */
243void 275void
244GST_neighbours_notify_data_sent (const struct GNUNET_PeerIdentity *peer, 276GST_neighbours_notify_data_sent (const struct GNUNET_PeerIdentity *peer,
245 const struct GNUNET_HELLO_Address *address, 277 const struct GNUNET_HELLO_Address *address,
@@ -276,14 +308,14 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
276 */ 308 */
277int 309int
278GST_neighbours_handle_session_syn (const struct GNUNET_MessageHeader *message, 310GST_neighbours_handle_session_syn (const struct GNUNET_MessageHeader *message,
279 const struct GNUNET_PeerIdentity *peer); 311 const struct GNUNET_PeerIdentity *peer);
280 312
281 313
282/** 314/**
283 * We received a 'SESSION_CONNECT_ACK' message from the other peer. 315 * We received a 'SESSION_CONNECT_ACK' message from the other peer.
284 * Consider switching to it. 316 * Consider switching to it.
285 * 317 *
286 * @param message possibly a 'struct SessionConnectMessage' (check format) 318 * @param message possibly a `struct SessionConnectMessage` (check format)
287 * @param peer identity of the peer to switch the address for 319 * @param peer identity of the peer to switch the address for
288 * @param address address of the other peer, NULL if other peer 320 * @param address address of the other peer, NULL if other peer
289 * connected to us 321 * connected to us
@@ -292,9 +324,9 @@ GST_neighbours_handle_session_syn (const struct GNUNET_MessageHeader *message,
292 */ 324 */
293int 325int
294GST_neighbours_handle_session_syn_ack (const struct GNUNET_MessageHeader *message, 326GST_neighbours_handle_session_syn_ack (const struct GNUNET_MessageHeader *message,
295 const struct GNUNET_PeerIdentity *peer, 327 const struct GNUNET_PeerIdentity *peer,
296 const struct GNUNET_HELLO_Address *address, 328 const struct GNUNET_HELLO_Address *address,
297 struct Session *session); 329 struct Session *session);
298 330
299 331
300/** 332/**
@@ -345,10 +377,8 @@ GST_neighbour_get_current_address (const struct GNUNET_PeerIdentity *peer);
345 * @param msg the disconnect message 377 * @param msg the disconnect message
346 */ 378 */
347void 379void
348GST_neighbours_handle_disconnect_message (const struct GNUNET_PeerIdentity 380GST_neighbours_handle_disconnect_message (const struct GNUNET_PeerIdentity *peer,
349 *peer, 381 const struct GNUNET_MessageHeader *msg);
350 const struct GNUNET_MessageHeader
351 *msg);
352 382
353 383
354#endif 384#endif
diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c
index b02c90009..03b125dc5 100644
--- a/src/transport/gnunet-service-transport_validation.c
+++ b/src/transport/gnunet-service-transport_validation.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2010-2014 Christian Grothoff (and other contributing authors) 3 (C) 2010-2015 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
@@ -24,12 +24,13 @@
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
27#include "gnunet-service-transport_ats.h"
28#include "gnunet-service-transport_blacklist.h"
27#include "gnunet-service-transport_clients.h" 29#include "gnunet-service-transport_clients.h"
28#include "gnunet-service-transport_validation.h"
29#include "gnunet-service-transport_plugins.h"
30#include "gnunet-service-transport_hello.h" 30#include "gnunet-service-transport_hello.h"
31#include "gnunet-service-transport_blacklist.h"
32#include "gnunet-service-transport_neighbours.h" 31#include "gnunet-service-transport_neighbours.h"
32#include "gnunet-service-transport_plugins.h"
33#include "gnunet-service-transport_validation.h"
33#include "gnunet-service-transport.h" 34#include "gnunet-service-transport.h"
34#include "gnunet_hello_lib.h" 35#include "gnunet_hello_lib.h"
35#include "gnunet_ats_service.h" 36#include "gnunet_ats_service.h"
@@ -253,6 +254,7 @@ struct ValidationEntry
253 * Current state of this validation entry 254 * Current state of this validation entry
254 */ 255 */
255 enum GNUNET_TRANSPORT_ValidationState state; 256 enum GNUNET_TRANSPORT_ValidationState state;
257
256 /** 258 /**
257 * Challenge number we used. 259 * Challenge number we used.
258 */ 260 */
@@ -275,6 +277,11 @@ struct ValidationEntry
275 int expecting_pong; 277 int expecting_pong;
276 278
277 /** 279 /**
280 * Is this address known to ATS as valid right now?
281 */
282 int known_to_ats;
283
284 /**
278 * Which network type does our address belong to? 285 * Which network type does our address belong to?
279 */ 286 */
280 enum GNUNET_ATS_Network_Type network; 287 enum GNUNET_ATS_Network_Type network;
@@ -445,6 +452,11 @@ cleanup_validation_entry (void *cls,
445 GNUNET_break (GNUNET_OK == 452 GNUNET_break (GNUNET_OK ==
446 GNUNET_CONTAINER_multipeermap_remove (validation_map, 453 GNUNET_CONTAINER_multipeermap_remove (validation_map,
447 &ve->pid, ve)); 454 &ve->pid, ve));
455 if (GNUNET_YES == ve->known_to_ats)
456 {
457 GST_ats_expire_address (ve->address);
458 ve->known_to_ats = GNUNET_NO;
459 }
448 GNUNET_HELLO_address_free (ve->address); 460 GNUNET_HELLO_address_free (ve->address);
449 if (NULL != ve->timeout_task) 461 if (NULL != ve->timeout_task)
450 { 462 {
@@ -593,7 +605,8 @@ transmit_ping_if_allowed (void *cls,
593 { 605 {
594 GNUNET_assert (NULL != papi->send); 606 GNUNET_assert (NULL != papi->send);
595 GNUNET_assert (NULL != papi->get_session); 607 GNUNET_assert (NULL != papi->get_session);
596 struct Session * session = papi->get_session(papi->cls, ve->address); 608 struct Session *session = papi->get_session (papi->cls,
609 ve->address);
597 610
598 if (NULL != session) 611 if (NULL != session)
599 { 612 {
@@ -847,8 +860,11 @@ add_valid_address (void *cls,
847 860
848 ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); 861 ats.type = htonl (GNUNET_ATS_NETWORK_TYPE);
849 ats.value = htonl (ve->network); 862 ats.value = htonl (ve->network);
850 GNUNET_ATS_address_add (GST_ats, address, NULL, &ats, 1); 863 if (GNUNET_YES != ve->known_to_ats)
851 864 {
865 ve->known_to_ats = GNUNET_YES;
866 GST_ats_add_address (address, NULL, &ats, 1);
867 }
852 return GNUNET_OK; 868 return GNUNET_OK;
853} 869}
854 870
@@ -975,6 +991,7 @@ multicast_pong (void *cls,
975 GNUNET_break (0); 991 GNUNET_break (0);
976 return; 992 return;
977 } 993 }
994 GST_ats_new_session (address, session);
978 papi->send (papi->cls, session, 995 papi->send (papi->cls, session,
979 (const char *) pong, 996 (const char *) pong,
980 ntohs (pong->header.size), 997 ntohs (pong->header.size),
@@ -1190,18 +1207,19 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender,
1190 1207
1191 /* first see if the session we got this PING from can be used to transmit 1208 /* first see if the session we got this PING from can be used to transmit
1192 * a response reliably */ 1209 * a response reliably */
1193 if (papi == NULL) 1210 if (NULL == papi)
1211 {
1194 ret = -1; 1212 ret = -1;
1213 }
1195 else 1214 else
1196 { 1215 {
1197 GNUNET_assert (papi->send != NULL); 1216 GNUNET_assert (NULL != papi->send);
1198 GNUNET_assert (papi->get_session != NULL); 1217 GNUNET_assert (NULL != papi->get_session);
1199 1218 if (NULL == session)
1200 if (session == NULL)
1201 { 1219 {
1202 session = papi->get_session (papi->cls, sender_address); 1220 session = papi->get_session (papi->cls, sender_address);
1203 } 1221 }
1204 if (session == NULL) 1222 if (NULL == session)
1205 { 1223 {
1206 GNUNET_break (0); 1224 GNUNET_break (0);
1207 ret = -1; 1225 ret = -1;
@@ -1491,8 +1509,15 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender,
1491 ats[0].value = htonl ((uint32_t) ve->latency.rel_value_us); 1509 ats[0].value = htonl ((uint32_t) ve->latency.rel_value_us);
1492 ats[1].type = htonl (GNUNET_ATS_NETWORK_TYPE); 1510 ats[1].type = htonl (GNUNET_ATS_NETWORK_TYPE);
1493 ats[1].value = htonl ((uint32_t) ve->network); 1511 ats[1].value = htonl ((uint32_t) ve->network);
1494 // FIXME: add vs. update! 1512 if (GNUNET_YES == ve->known_to_ats)
1495 GNUNET_ATS_address_add (GST_ats, ve->address, NULL, ats, 2); 1513 {
1514 GST_ats_update_metrics (ve->address, NULL, ats, 2);
1515 }
1516 else
1517 {
1518 ve->known_to_ats = GNUNET_YES;
1519 GST_ats_add_address (ve->address, NULL, ats, 2);
1520 }
1496 } 1521 }
1497 if (validations_running > 0) 1522 if (validations_running > 0)
1498 { 1523 {
@@ -1668,7 +1693,6 @@ GST_validation_set_address_use (const struct GNUNET_HELLO_Address *address,
1668 } 1693 }
1669 if (ve->in_use == in_use) 1694 if (ve->in_use == in_use)
1670 { 1695 {
1671
1672 if (GNUNET_YES == in_use) 1696 if (GNUNET_YES == in_use)
1673 { 1697 {
1674 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1698 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,