aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-service-transport.c')
-rw-r--r--src/transport/gnunet-service-transport.c5612
1 files changed, 2686 insertions, 2926 deletions
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index cf02d14b2..4f962d117 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -178,9 +178,9 @@ struct ForeignAddressList
178 */ 178 */
179 struct Session *session; 179 struct Session *session;
180 180
181 struct ATS_ressource_entry * ressources; 181 struct ATS_ressource_entry *ressources;
182 182
183 struct ATS_quality_entry * quality; 183 struct ATS_quality_entry *quality;
184 184
185 /** 185 /**
186 * What was the last latency observed for this address, plugin and peer? 186 * What was the last latency observed for this address, plugin and peer?
@@ -325,7 +325,7 @@ struct TransportPlugin
325 */ 325 */
326 int rebuild; 326 int rebuild;
327 327
328 struct ATS_plugin * rc; 328 struct ATS_plugin *rc;
329 329
330 /** 330 /**
331 * Hashmap of blacklisted peers for this particular transport. 331 * Hashmap of blacklisted peers for this particular transport.
@@ -735,7 +735,7 @@ struct CheckHelloValidatedContext;
735/** 735/**
736 * Entry in map of all HELLOs awaiting validation. 736 * Entry in map of all HELLOs awaiting validation.
737 */ 737 */
738struct ValidationEntry 738struct ValidationEntry
739{ 739{
740 740
741 /** 741 /**
@@ -929,10 +929,12 @@ static struct ATS_Handle *ats;
929 * Time of last ats execution 929 * Time of last ats execution
930 */ 930 */
931struct GNUNET_TIME_Absolute last_ats_execution; 931struct GNUNET_TIME_Absolute last_ats_execution;
932
932/** 933/**
933 * Minimum interval between two ATS executions 934 * Minimum interval between two ATS executions
934 */ 935 */
935struct GNUNET_TIME_Relative ats_minimum_interval; 936struct GNUNET_TIME_Relative ats_minimum_interval;
937
936/** 938/**
937 * Regular interval when ATS execution is triggered 939 * Regular interval when ATS execution is triggered
938 */ 940 */
@@ -961,8 +963,8 @@ static void disconnect_neighbour (struct NeighbourMapEntry *n, int check);
961 */ 963 */
962static void try_transmission_to_peer (struct NeighbourMapEntry *n); 964static void try_transmission_to_peer (struct NeighbourMapEntry *n);
963 965
964struct ForeignAddressList * get_preferred_ats_address ( 966struct ForeignAddressList *get_preferred_ats_address (struct NeighbourMapEntry
965 struct NeighbourMapEntry *n); 967 *n);
966 968
967/** 969/**
968 * Find an entry in the neighbour list for a particular peer. 970 * Find an entry in the neighbour list for a particular peer.
@@ -975,11 +977,14 @@ find_neighbour (const struct GNUNET_PeerIdentity *key)
975 return GNUNET_CONTAINER_multihashmap_get (neighbours, &key->hashPubKey); 977 return GNUNET_CONTAINER_multihashmap_get (neighbours, &key->hashPubKey);
976} 978}
977 979
978static int update_addr_value (struct ForeignAddressList *fal, uint32_t value , int ats_index) 980static int
981update_addr_value (struct ForeignAddressList *fal, uint32_t value,
982 int ats_index)
979{ 983{
980 int c; 984 int c;
981 int set = GNUNET_NO; 985 int set = GNUNET_NO;
982 for (c=0; c<available_quality_metrics; c++) 986
987 for (c = 0; c < available_quality_metrics; c++)
983 { 988 {
984 if (ats_index == qm[c].atis_index) 989 if (ats_index == qm[c].atis_index)
985 { 990 {
@@ -994,7 +999,7 @@ static int update_addr_value (struct ForeignAddressList *fal, uint32_t value , i
994 } 999 }
995 if (set == GNUNET_NO) 1000 if (set == GNUNET_NO)
996 { 1001 {
997 for (c=0; c<available_ressources; c++) 1002 for (c = 0; c < available_ressources; c++)
998 { 1003 {
999 if (ats_index == ressources[c].atis_index) 1004 if (ats_index == ressources[c].atis_index)
1000 { 1005 {
@@ -1010,16 +1015,19 @@ static int update_addr_value (struct ForeignAddressList *fal, uint32_t value , i
1010} 1015}
1011 1016
1012static int 1017static int
1013update_addr_ats (struct ForeignAddressList *fal, 1018update_addr_ats (struct ForeignAddressList *fal,
1014 const struct GNUNET_TRANSPORT_ATS_Information *ats_data, 1019 const struct GNUNET_TRANSPORT_ATS_Information *ats_data,
1015 int ats_count) 1020 int ats_count)
1016{ 1021{
1017 int c1, set; 1022 int c1, set;
1023
1018 set = GNUNET_NO; 1024 set = GNUNET_NO;
1019 for (c1=0; c1<ats_count; c1++) 1025 for (c1 = 0; c1 < ats_count; c1++)
1020 { 1026 {
1021 set = update_addr_value(fal, ntohl(ats_data[c1].value), ntohl(ats_data[c1].type)); 1027 set =
1022 } 1028 update_addr_value (fal, ntohl (ats_data[c1].value),
1029 ntohl (ats_data[c1].type));
1030 }
1023 return set; 1031 return set;
1024} 1032}
1025 1033
@@ -1032,6 +1040,7 @@ static struct TransportPlugin *
1032find_transport (const char *short_name) 1040find_transport (const char *short_name)
1033{ 1041{
1034 struct TransportPlugin *head = plugins; 1042 struct TransportPlugin *head = plugins;
1043
1035 while ((head != NULL) && (0 != strcmp (short_name, head->short_name))) 1044 while ((head != NULL) && (0 != strcmp (short_name, head->short_name)))
1036 head = head->next; 1045 head = head->next;
1037 return head; 1046 return head;
@@ -1046,49 +1055,51 @@ find_transport (const char *short_name)
1046 * @return GNUNET_YES if the peer is blacklisted, GNUNET_NO if not 1055 * @return GNUNET_YES if the peer is blacklisted, GNUNET_NO if not
1047 */ 1056 */
1048static int 1057static int
1049is_blacklisted (const struct GNUNET_PeerIdentity *peer, struct TransportPlugin *plugin) 1058is_blacklisted (const struct GNUNET_PeerIdentity *peer,
1059 struct TransportPlugin *plugin)
1050{ 1060{
1051 1061
1052 if (plugin->blacklist != NULL) 1062 if (plugin->blacklist != NULL)
1063 {
1064 if (GNUNET_CONTAINER_multihashmap_contains
1065 (plugin->blacklist, &peer->hashPubKey) == GNUNET_YES)
1053 { 1066 {
1054 if (GNUNET_CONTAINER_multihashmap_contains (plugin->blacklist, &peer->hashPubKey) == GNUNET_YES)
1055 {
1056#if DEBUG_BLACKLIST 1067#if DEBUG_BLACKLIST
1057 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1068 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1058 "Peer `%s:%s' is blacklisted!\n", 1069 "Peer `%s:%s' is blacklisted!\n",
1059 plugin->short_name, GNUNET_i2s (peer)); 1070 plugin->short_name, GNUNET_i2s (peer));
1060#endif 1071#endif
1061 if (stats != NULL) 1072 if (stats != NULL)
1062 GNUNET_STATISTICS_update (stats, "# blacklisted peers refused", 1, GNUNET_NO); 1073 GNUNET_STATISTICS_update (stats, "# blacklisted peers refused", 1,
1063 return GNUNET_YES; 1074 GNUNET_NO);
1064 } 1075 return GNUNET_YES;
1065 } 1076 }
1077 }
1066 1078
1067 return GNUNET_NO; 1079 return GNUNET_NO;
1068} 1080}
1069 1081
1070 1082
1071static void 1083static void
1072add_peer_to_blacklist (struct GNUNET_PeerIdentity *peer, 1084add_peer_to_blacklist (struct GNUNET_PeerIdentity *peer, char *transport_name)
1073 char *transport_name)
1074{ 1085{
1075 struct TransportPlugin *plugin; 1086 struct TransportPlugin *plugin;
1076 1087
1077 plugin = find_transport(transport_name); 1088 plugin = find_transport (transport_name);
1078 if (plugin == NULL) /* Nothing to do */ 1089 if (plugin == NULL) /* Nothing to do */
1079 return; 1090 return;
1080#if DEBUG_TRANSPORT 1091#if DEBUG_TRANSPORT
1081 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1092 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1082 "Adding peer `%s' with plugin `%s' to blacklist\n", 1093 "Adding peer `%s' with plugin `%s' to blacklist\n",
1083 GNUNET_i2s (peer), 1094 GNUNET_i2s (peer), transport_name);
1084 transport_name);
1085#endif 1095#endif
1086 if (plugin->blacklist == NULL) 1096 if (plugin->blacklist == NULL)
1087 plugin->blacklist = GNUNET_CONTAINER_multihashmap_create(TRANSPORT_BLACKLIST_HT_SIZE); 1097 plugin->blacklist =
1088 GNUNET_assert(plugin->blacklist != NULL); 1098 GNUNET_CONTAINER_multihashmap_create (TRANSPORT_BLACKLIST_HT_SIZE);
1089 GNUNET_CONTAINER_multihashmap_put(plugin->blacklist, &peer->hashPubKey, 1099 GNUNET_assert (plugin->blacklist != NULL);
1090 NULL, 1100 GNUNET_CONTAINER_multihashmap_put (plugin->blacklist, &peer->hashPubKey,
1091 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); 1101 NULL,
1102 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
1092} 1103}
1093 1104
1094 1105
@@ -1115,145 +1126,148 @@ read_blacklist_file (const struct GNUNET_CONFIGURATION_Handle *cfg)
1115 if (GNUNET_OK != 1126 if (GNUNET_OK !=
1116 GNUNET_CONFIGURATION_get_value_filename (cfg, 1127 GNUNET_CONFIGURATION_get_value_filename (cfg,
1117 "TRANSPORT", 1128 "TRANSPORT",
1118 "BLACKLIST_FILE", 1129 "BLACKLIST_FILE", &fn))
1119 &fn)) 1130 {
1120 {
1121#if DEBUG_TRANSPORT 1131#if DEBUG_TRANSPORT
1122 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1132 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1123 "Option `%s' in section `%s' not specified!\n", 1133 "Option `%s' in section `%s' not specified!\n",
1124 "BLACKLIST_FILE", 1134 "BLACKLIST_FILE", "TRANSPORT");
1125 "TRANSPORT");
1126#endif 1135#endif
1127 return; 1136 return;
1128 } 1137 }
1129 if (GNUNET_OK != GNUNET_DISK_file_test (fn)) 1138 if (GNUNET_OK != GNUNET_DISK_file_test (fn))
1130 GNUNET_DISK_fn_write (fn, NULL, 0, GNUNET_DISK_PERM_USER_READ 1139 GNUNET_DISK_fn_write (fn, NULL, 0, GNUNET_DISK_PERM_USER_READ
1131 | GNUNET_DISK_PERM_USER_WRITE); 1140 | GNUNET_DISK_PERM_USER_WRITE);
1132 if (0 != STAT (fn, &frstat)) 1141 if (0 != STAT (fn, &frstat))
1133 { 1142 {
1134 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1143 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1135 _("Could not read blacklist file `%s'\n"), fn); 1144 _("Could not read blacklist file `%s'\n"), fn);
1136 GNUNET_free (fn); 1145 GNUNET_free (fn);
1137 return; 1146 return;
1138 } 1147 }
1139 if (frstat.st_size == 0) 1148 if (frstat.st_size == 0)
1140 { 1149 {
1141#if DEBUG_TRANSPORT 1150#if DEBUG_TRANSPORT
1142 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1151 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1143 _("Blacklist file `%s' is empty.\n"), 1152 _("Blacklist file `%s' is empty.\n"), fn);
1144 fn);
1145#endif 1153#endif
1146 GNUNET_free (fn); 1154 GNUNET_free (fn);
1147 return; 1155 return;
1148 } 1156 }
1149 /* FIXME: use mmap */ 1157 /* FIXME: use mmap */
1150 data = GNUNET_malloc_large (frstat.st_size); 1158 data = GNUNET_malloc_large (frstat.st_size);
1151 GNUNET_assert(data != NULL); 1159 GNUNET_assert (data != NULL);
1152 if (frstat.st_size != 1160 if (frstat.st_size != GNUNET_DISK_fn_read (fn, data, frstat.st_size))
1153 GNUNET_DISK_fn_read (fn, data, frstat.st_size)) 1161 {
1154 { 1162 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1155 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1163 _("Failed to read blacklist from `%s'\n"), fn);
1156 _("Failed to read blacklist from `%s'\n"), fn); 1164 GNUNET_free (fn);
1157 GNUNET_free (fn); 1165 GNUNET_free (data);
1158 GNUNET_free (data); 1166 return;
1159 return; 1167 }
1160 }
1161 entries_found = 0; 1168 entries_found = 0;
1162 pos = 0; 1169 pos = 0;
1163 while ((pos < frstat.st_size) && isspace ( (unsigned char) data[pos])) 1170 while ((pos < frstat.st_size) && isspace ((unsigned char) data[pos]))
1164 pos++; 1171 pos++;
1165 while ((frstat.st_size >= sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) && 1172 while ((frstat.st_size >= sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) &&
1166 (pos <= frstat.st_size - sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded))) 1173 (pos <=
1167 { 1174 frstat.st_size - sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)))
1168 colon_pos = pos; 1175 {
1169 while ((colon_pos < frstat.st_size) && (data[colon_pos] != ':') && !isspace ( (unsigned char) data[colon_pos])) 1176 colon_pos = pos;
1170 colon_pos++; 1177 while ((colon_pos < frstat.st_size) && (data[colon_pos] != ':') &&
1178 !isspace ((unsigned char) data[colon_pos]))
1179 colon_pos++;
1171 1180
1172 if (colon_pos >= frstat.st_size) 1181 if (colon_pos >= frstat.st_size)
1173 { 1182 {
1174 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1183 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1175 _("Syntax error in blacklist file at offset %llu, giving up!\n"), 1184 _
1176 (unsigned long long) colon_pos); 1185 ("Syntax error in blacklist file at offset %llu, giving up!\n"),
1177 GNUNET_free (fn); 1186 (unsigned long long) colon_pos);
1178 GNUNET_free (data); 1187 GNUNET_free (fn);
1179 return; 1188 GNUNET_free (data);
1180 } 1189 return;
1190 }
1181 1191
1182 if (isspace( (unsigned char) data[colon_pos])) 1192 if (isspace ((unsigned char) data[colon_pos]))
1183 { 1193 {
1184 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1194 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1185 _("Syntax error in blacklist file at offset %llu, skipping bytes.\n"), 1195 _
1186 (unsigned long long) colon_pos); 1196 ("Syntax error in blacklist file at offset %llu, skipping bytes.\n"),
1187 pos = colon_pos; 1197 (unsigned long long) colon_pos);
1188 while ((pos < frstat.st_size) && isspace ( (unsigned char) data[pos])) 1198 pos = colon_pos;
1189 pos++; 1199 while ((pos < frstat.st_size) && isspace ((unsigned char) data[pos]))
1190 continue; 1200 pos++;
1191 } 1201 continue;
1192 tsize = colon_pos - pos; 1202 }
1193 if ((pos >= frstat.st_size) || (pos + tsize >= frstat.st_size) || (tsize == 0)) 1203 tsize = colon_pos - pos;
1194 { 1204 if ((pos >= frstat.st_size) || (pos + tsize >= frstat.st_size) ||
1195 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1205 (tsize == 0))
1196 _("Syntax error in blacklist file at offset %llu, giving up!\n"), 1206 {
1197 (unsigned long long) colon_pos); 1207 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1198 GNUNET_free (fn); 1208 _
1199 GNUNET_free (data); 1209 ("Syntax error in blacklist file at offset %llu, giving up!\n"),
1200 return; 1210 (unsigned long long) colon_pos);
1201 } 1211 GNUNET_free (fn);
1212 GNUNET_free (data);
1213 return;
1214 }
1202 1215
1203 if (tsize < 1) 1216 if (tsize < 1)
1204 continue; 1217 continue;
1205 1218
1206 transport_name = GNUNET_malloc(tsize + 1); 1219 transport_name = GNUNET_malloc (tsize + 1);
1207 memcpy(transport_name, &data[pos], tsize); 1220 memcpy (transport_name, &data[pos], tsize);
1208 pos = colon_pos + 1; 1221 pos = colon_pos + 1;
1209#if DEBUG_TRANSPORT 1222#if DEBUG_TRANSPORT
1210 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1223 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1211 "Read transport name %s in blacklist file.\n", 1224 "Read transport name %s in blacklist file.\n", transport_name);
1212 transport_name);
1213#endif 1225#endif
1214 memcpy (&enc, &data[pos], sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)); 1226 memcpy (&enc, &data[pos], sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded));
1215 if (!isspace ( (unsigned char) enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1])) 1227 if (!isspace
1216 { 1228 ((unsigned char)
1217 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1229 enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1]))
1218 _("Syntax error in blacklist file at offset %llu, skipping bytes.\n"), 1230 {
1219 (unsigned long long) pos); 1231 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1220 pos++; 1232 _
1221 while ((pos < frstat.st_size) && (!isspace ( (unsigned char) data[pos]))) 1233 ("Syntax error in blacklist file at offset %llu, skipping bytes.\n"),
1222 pos++; 1234 (unsigned long long) pos);
1223 GNUNET_free_non_null(transport_name); 1235 pos++;
1224 continue; 1236 while ((pos < frstat.st_size) && (!isspace ((unsigned char) data[pos])))
1225 }
1226 enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
1227 if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char *) &enc, &pid.hashPubKey))
1228 {
1229 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1230 _("Syntax error in blacklist file at offset %llu, skipping bytes `%s'.\n"),
1231 (unsigned long long) pos,
1232 &enc);
1233 }
1234 else
1235 {
1236 if (0 != memcmp (&pid,
1237 &my_identity,
1238 sizeof (struct GNUNET_PeerIdentity)))
1239 {
1240 entries_found++;
1241 add_peer_to_blacklist (&pid,
1242 transport_name);
1243 }
1244 else
1245 {
1246 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1247 _("Found myself `%s' in blacklist (useless, ignored)\n"),
1248 GNUNET_i2s (&pid));
1249 }
1250 }
1251 pos = pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded);
1252 GNUNET_free_non_null(transport_name);
1253 while ((pos < frstat.st_size) && isspace ( (unsigned char) data[pos]))
1254 pos++; 1237 pos++;
1238 GNUNET_free_non_null (transport_name);
1239 continue;
1240 }
1241 enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
1242 if (GNUNET_OK !=
1243 GNUNET_CRYPTO_hash_from_string ((char *) &enc, &pid.hashPubKey))
1244 {
1245 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1246 _
1247 ("Syntax error in blacklist file at offset %llu, skipping bytes `%s'.\n"),
1248 (unsigned long long) pos, &enc);
1255 } 1249 }
1256 GNUNET_STATISTICS_update (stats, "# Transport entries blacklisted", entries_found, GNUNET_NO); 1250 else
1251 {
1252 if (0 != memcmp (&pid, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
1253 {
1254 entries_found++;
1255 add_peer_to_blacklist (&pid, transport_name);
1256 }
1257 else
1258 {
1259 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1260 _("Found myself `%s' in blacklist (useless, ignored)\n"),
1261 GNUNET_i2s (&pid));
1262 }
1263 }
1264 pos = pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded);
1265 GNUNET_free_non_null (transport_name);
1266 while ((pos < frstat.st_size) && isspace ((unsigned char) data[pos]))
1267 pos++;
1268 }
1269 GNUNET_STATISTICS_update (stats, "# Transport entries blacklisted",
1270 entries_found, GNUNET_NO);
1257 GNUNET_free (data); 1271 GNUNET_free (data);
1258 GNUNET_free (fn); 1272 GNUNET_free (fn);
1259} 1273}
@@ -1281,57 +1295,56 @@ transmit_to_client_callback (void *cls, size_t size, void *buf)
1281 1295
1282 client->th = NULL; 1296 client->th = NULL;
1283 if (buf == NULL) 1297 if (buf == NULL)
1284 { 1298 {
1285#if DEBUG_TRANSPORT 1299#if DEBUG_TRANSPORT
1286 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1300 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1287 "Transmission to client failed, closing connection.\n"); 1301 "Transmission to client failed, closing connection.\n");
1288#endif 1302#endif
1289 /* fatal error with client, free message queue! */ 1303 /* fatal error with client, free message queue! */
1290 while (NULL != (q = client->message_queue_head)) 1304 while (NULL != (q = client->message_queue_head))
1291 { 1305 {
1292 GNUNET_STATISTICS_update (stats, 1306 GNUNET_STATISTICS_update (stats,
1293 gettext_noop ("# bytes discarded (could not transmit to client)"), 1307 gettext_noop
1294 ntohs (((const struct GNUNET_MessageHeader*)&q[1])->size), 1308 ("# bytes discarded (could not transmit to client)"),
1295 GNUNET_NO); 1309 ntohs (((const struct GNUNET_MessageHeader *)
1296 GNUNET_CONTAINER_DLL_remove (client->message_queue_head, 1310 &q[1])->size), GNUNET_NO);
1297 client->message_queue_tail, 1311 GNUNET_CONTAINER_DLL_remove (client->message_queue_head,
1298 q); 1312 client->message_queue_tail, q);
1299 GNUNET_free (q); 1313 GNUNET_free (q);
1300 }
1301 client->message_count = 0;
1302 return 0;
1303 } 1314 }
1315 client->message_count = 0;
1316 return 0;
1317 }
1304 cbuf = buf; 1318 cbuf = buf;
1305 tsize = 0; 1319 tsize = 0;
1306 while (NULL != (q = client->message_queue_head)) 1320 while (NULL != (q = client->message_queue_head))
1307 { 1321 {
1308 msg = (const struct GNUNET_MessageHeader *) &q[1]; 1322 msg = (const struct GNUNET_MessageHeader *) &q[1];
1309 msize = ntohs (msg->size); 1323 msize = ntohs (msg->size);
1310 if (msize + tsize > size) 1324 if (msize + tsize > size)
1311 break; 1325 break;
1312#if DEBUG_TRANSPORT 1326#if DEBUG_TRANSPORT
1313 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1327 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1314 "Transmitting message of type %u to client.\n", 1328 "Transmitting message of type %u to client.\n",
1315 ntohs (msg->type)); 1329 ntohs (msg->type));
1316#endif 1330#endif
1317 GNUNET_CONTAINER_DLL_remove (client->message_queue_head, 1331 GNUNET_CONTAINER_DLL_remove (client->message_queue_head,
1318 client->message_queue_tail, 1332 client->message_queue_tail, q);
1319 q); 1333 memcpy (&cbuf[tsize], msg, msize);
1320 memcpy (&cbuf[tsize], msg, msize); 1334 tsize += msize;
1321 tsize += msize; 1335 GNUNET_free (q);
1322 GNUNET_free (q); 1336 client->message_count--;
1323 client->message_count--; 1337 }
1324 }
1325 if (NULL != q) 1338 if (NULL != q)
1326 { 1339 {
1327 GNUNET_assert (msize >= sizeof (struct GNUNET_MessageHeader)); 1340 GNUNET_assert (msize >= sizeof (struct GNUNET_MessageHeader));
1328 client->th = GNUNET_SERVER_notify_transmit_ready (client->client, 1341 client->th = GNUNET_SERVER_notify_transmit_ready (client->client,
1329 msize, 1342 msize,
1330 GNUNET_TIME_UNIT_FOREVER_REL, 1343 GNUNET_TIME_UNIT_FOREVER_REL,
1331 &transmit_to_client_callback, 1344 &transmit_to_client_callback,
1332 client); 1345 client);
1333 GNUNET_assert (client->th != NULL); 1346 GNUNET_assert (client->th != NULL);
1334 } 1347 }
1335 return tsize; 1348 return tsize;
1336} 1349}
1337 1350
@@ -1344,10 +1357,8 @@ transmit_to_client_callback (void *cls, size_t size, void *buf)
1344 * @param addr_len number of bytes in addr 1357 * @param addr_len number of bytes in addr
1345 * @return NULL on error, otherwise address string 1358 * @return NULL on error, otherwise address string
1346 */ 1359 */
1347static const char* 1360static const char *
1348a2s (const char *plugin, 1361a2s (const char *plugin, const void *addr, uint16_t addr_len)
1349 const void *addr,
1350 uint16_t addr_len)
1351{ 1362{
1352 struct TransportPlugin *p; 1363 struct TransportPlugin *p;
1353 1364
@@ -1356,9 +1367,7 @@ a2s (const char *plugin,
1356 p = find_transport (plugin); 1367 p = find_transport (plugin);
1357 if ((p == NULL) || (addr_len == 0) || (addr == NULL)) 1368 if ((p == NULL) || (addr_len == 0) || (addr == NULL))
1358 return NULL; 1369 return NULL;
1359 return p->api->address_to_string (NULL, 1370 return p->api->address_to_string (NULL, addr, addr_len);
1360 addr,
1361 addr_len);
1362} 1371}
1363 1372
1364 1373
@@ -1373,9 +1382,7 @@ a2s (const char *plugin,
1373 * @return GNUNET_YES (always) 1382 * @return GNUNET_YES (always)
1374 */ 1383 */
1375static int 1384static int
1376abort_validation (void *cls, 1385abort_validation (void *cls, const GNUNET_HashCode * key, void *value)
1377 const GNUNET_HashCode * key,
1378 void *value)
1379{ 1386{
1380 struct ValidationEntry *va = value; 1387 struct ValidationEntry *va = value;
1381 1388
@@ -1383,17 +1390,15 @@ abort_validation (void *cls,
1383 GNUNET_SCHEDULER_cancel (va->timeout_task); 1390 GNUNET_SCHEDULER_cancel (va->timeout_task);
1384 GNUNET_free (va->transport_name); 1391 GNUNET_free (va->transport_name);
1385 if (va->chvc != NULL) 1392 if (va->chvc != NULL)
1393 {
1394 va->chvc->ve_count--;
1395 if (va->chvc->ve_count == 0)
1386 { 1396 {
1387 va->chvc->ve_count--; 1397 GNUNET_CONTAINER_DLL_remove (chvc_head, chvc_tail, va->chvc);
1388 if (va->chvc->ve_count == 0) 1398 GNUNET_free (va->chvc);
1389 {
1390 GNUNET_CONTAINER_DLL_remove (chvc_head,
1391 chvc_tail,
1392 va->chvc);
1393 GNUNET_free (va->chvc);
1394 }
1395 va->chvc = NULL;
1396 } 1399 }
1400 va->chvc = NULL;
1401 }
1397 GNUNET_free (va); 1402 GNUNET_free (va);
1398 return GNUNET_YES; 1403 return GNUNET_YES;
1399} 1404}
@@ -1406,24 +1411,23 @@ abort_validation (void *cls,
1406 * @param tc scheduler context (unused) 1411 * @param tc scheduler context (unused)
1407 */ 1412 */
1408static void 1413static void
1409timeout_hello_validation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 1414timeout_hello_validation (void *cls,
1415 const struct GNUNET_SCHEDULER_TaskContext *tc)
1410{ 1416{
1411 struct ValidationEntry *va = cls; 1417 struct ValidationEntry *va = cls;
1412 struct GNUNET_PeerIdentity pid; 1418 struct GNUNET_PeerIdentity pid;
1413 1419
1414 va->timeout_task = GNUNET_SCHEDULER_NO_TASK; 1420 va->timeout_task = GNUNET_SCHEDULER_NO_TASK;
1415 GNUNET_STATISTICS_update (stats, 1421 GNUNET_STATISTICS_update (stats,
1416 gettext_noop ("# address validation timeouts"), 1422 gettext_noop ("# address validation timeouts"),
1417 1, 1423 1, GNUNET_NO);
1418 GNUNET_NO);
1419 GNUNET_CRYPTO_hash (&va->publicKey, 1424 GNUNET_CRYPTO_hash (&va->publicKey,
1420 sizeof (struct 1425 sizeof (struct
1421 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), 1426 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
1422 &pid.hashPubKey); 1427 &pid.hashPubKey);
1423 GNUNET_break (GNUNET_OK == 1428 GNUNET_break (GNUNET_OK ==
1424 GNUNET_CONTAINER_multihashmap_remove (validation_map, 1429 GNUNET_CONTAINER_multihashmap_remove (validation_map,
1425 &pid.hashPubKey, 1430 &pid.hashPubKey, va));
1426 va));
1427 abort_validation (NULL, NULL, va); 1431 abort_validation (NULL, NULL, va);
1428} 1432}
1429 1433
@@ -1450,43 +1454,40 @@ transmit_to_client (struct TransportClient *client,
1450 * freed in client_disconnect_notification 1454 * freed in client_disconnect_notification
1451 */ 1455 */
1452 if (client->client == NULL) 1456 if (client->client == NULL)
1453 { 1457 {
1454 GNUNET_break (0); 1458 GNUNET_break (0);
1455 return; 1459 return;
1456 } 1460 }
1457 1461
1458 if ((client->message_count >= MAX_PENDING) && (GNUNET_YES == may_drop)) 1462 if ((client->message_count >= MAX_PENDING) && (GNUNET_YES == may_drop))
1459 { 1463 {
1460 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1464 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1461 _ 1465 _
1462 ("Dropping message of type %u and size %u, have %u messages pending (%u is the soft limit)\n"), 1466 ("Dropping message of type %u and size %u, have %u messages pending (%u is the soft limit)\n"),
1463 ntohs (msg->type), 1467 ntohs (msg->type),
1464 ntohs (msg->size), 1468 ntohs (msg->size), client->message_count, MAX_PENDING);
1465 client->message_count, 1469 GNUNET_STATISTICS_update (stats,
1466 MAX_PENDING); 1470 gettext_noop
1467 GNUNET_STATISTICS_update (stats, 1471 ("# messages dropped due to slow client"), 1,
1468 gettext_noop ("# messages dropped due to slow client"), 1472 GNUNET_NO);
1469 1, 1473 return;
1470 GNUNET_NO); 1474 }
1471 return;
1472 }
1473 msize = ntohs (msg->size); 1475 msize = ntohs (msg->size);
1474 GNUNET_assert (msize >= sizeof (struct GNUNET_MessageHeader)); 1476 GNUNET_assert (msize >= sizeof (struct GNUNET_MessageHeader));
1475 q = GNUNET_malloc (sizeof (struct ClientMessageQueueEntry) + msize); 1477 q = GNUNET_malloc (sizeof (struct ClientMessageQueueEntry) + msize);
1476 memcpy (&q[1], msg, msize); 1478 memcpy (&q[1], msg, msize);
1477 GNUNET_CONTAINER_DLL_insert_tail (client->message_queue_head, 1479 GNUNET_CONTAINER_DLL_insert_tail (client->message_queue_head,
1478 client->message_queue_tail, 1480 client->message_queue_tail, q);
1479 q);
1480 client->message_count++; 1481 client->message_count++;
1481 if (client->th == NULL) 1482 if (client->th == NULL)
1482 { 1483 {
1483 client->th = GNUNET_SERVER_notify_transmit_ready (client->client, 1484 client->th = GNUNET_SERVER_notify_transmit_ready (client->client,
1484 msize, 1485 msize,
1485 GNUNET_TIME_UNIT_FOREVER_REL, 1486 GNUNET_TIME_UNIT_FOREVER_REL,
1486 &transmit_to_client_callback, 1487 &transmit_to_client_callback,
1487 client); 1488 client);
1488 GNUNET_assert (client->th != NULL); 1489 GNUNET_assert (client->th != NULL);
1489 } 1490 }
1490} 1491}
1491 1492
1492 1493
@@ -1501,9 +1502,8 @@ transmit_to_client (struct TransportClient *client,
1501 */ 1502 */
1502static void 1503static void
1503transmit_send_ok (struct TransportClient *client, 1504transmit_send_ok (struct TransportClient *client,
1504 struct NeighbourMapEntry *n, 1505 struct NeighbourMapEntry *n,
1505 const struct GNUNET_PeerIdentity *target, 1506 const struct GNUNET_PeerIdentity *target, int result)
1506 int result)
1507{ 1507{
1508 struct SendOkMessage send_ok_msg; 1508 struct SendOkMessage send_ok_msg;
1509 1509
@@ -1513,7 +1513,8 @@ transmit_send_ok (struct TransportClient *client,
1513 if (n != NULL) 1513 if (n != NULL)
1514 send_ok_msg.latency = GNUNET_TIME_relative_hton (n->latency); 1514 send_ok_msg.latency = GNUNET_TIME_relative_hton (n->latency);
1515 else 1515 else
1516 send_ok_msg.latency = GNUNET_TIME_relative_hton (GNUNET_TIME_UNIT_FOREVER_REL); 1516 send_ok_msg.latency =
1517 GNUNET_TIME_relative_hton (GNUNET_TIME_UNIT_FOREVER_REL);
1517 send_ok_msg.peer = *target; 1518 send_ok_msg.peer = *target;
1518 transmit_to_client (client, &send_ok_msg.header, GNUNET_NO); 1519 transmit_to_client (client, &send_ok_msg.header, GNUNET_NO);
1519} 1520}
@@ -1526,8 +1527,7 @@ transmit_send_ok (struct TransportClient *client,
1526 * 1527 *
1527 * @param fal address to set to 'connected' 1528 * @param fal address to set to 'connected'
1528 */ 1529 */
1529static void 1530static void mark_address_connected (struct ForeignAddressList *fal);
1530mark_address_connected (struct ForeignAddressList *fal);
1531 1531
1532 1532
1533 1533
@@ -1537,7 +1537,7 @@ mark_address_connected (struct ForeignAddressList *fal);
1537 */ 1537 */
1538static void 1538static void
1539retry_transmission_task (void *cls, 1539retry_transmission_task (void *cls,
1540 const struct GNUNET_SCHEDULER_TaskContext *tc) 1540 const struct GNUNET_SCHEDULER_TaskContext *tc)
1541{ 1541{
1542 struct NeighbourMapEntry *n = cls; 1542 struct NeighbourMapEntry *n = cls;
1543 1543
@@ -1569,67 +1569,62 @@ transmit_send_continuation (void *cls,
1569 struct NeighbourMapEntry *n; 1569 struct NeighbourMapEntry *n;
1570 1570
1571 GNUNET_STATISTICS_update (stats, 1571 GNUNET_STATISTICS_update (stats,
1572 gettext_noop ("# bytes pending with plugins"), 1572 gettext_noop ("# bytes pending with plugins"),
1573 - (int64_t) mq->message_buf_size, 1573 -(int64_t) mq->message_buf_size, GNUNET_NO);
1574 GNUNET_NO);
1575 if (result == GNUNET_OK) 1574 if (result == GNUNET_OK)
1576 { 1575 {
1577 GNUNET_STATISTICS_update (stats, 1576 GNUNET_STATISTICS_update (stats,
1578 gettext_noop ("# bytes successfully transmitted by plugins"), 1577 gettext_noop
1579 mq->message_buf_size, 1578 ("# bytes successfully transmitted by plugins"),
1580 GNUNET_NO); 1579 mq->message_buf_size, GNUNET_NO);
1581 } 1580 }
1582 else 1581 else
1582 {
1583 GNUNET_STATISTICS_update (stats,
1584 gettext_noop
1585 ("# bytes with transmission failure by plugins"),
1586 mq->message_buf_size, GNUNET_NO);
1587 }
1588 if (mq->specific_address != NULL)
1589 {
1590 if (result == GNUNET_OK)
1583 { 1591 {
1584 GNUNET_STATISTICS_update (stats, 1592 mq->specific_address->timeout =
1585 gettext_noop ("# bytes with transmission failure by plugins"), 1593 GNUNET_TIME_relative_to_absolute
1586 mq->message_buf_size, 1594 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1587 GNUNET_NO); 1595 if (mq->specific_address->validated == GNUNET_YES)
1596 mark_address_connected (mq->specific_address);
1588 } 1597 }
1589 if (mq->specific_address != NULL) 1598 else
1590 { 1599 {
1591 if (result == GNUNET_OK) 1600 if (mq->specific_address->connected == GNUNET_YES)
1592 { 1601 {
1593 mq->specific_address->timeout =
1594 GNUNET_TIME_relative_to_absolute
1595 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1596 if (mq->specific_address->validated == GNUNET_YES)
1597 mark_address_connected (mq->specific_address);
1598 }
1599 else
1600 {
1601 if (mq->specific_address->connected == GNUNET_YES)
1602 {
1603#if DEBUG_TRANSPORT 1602#if DEBUG_TRANSPORT
1604 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1603 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1605 "Marking address `%s' as no longer connected (due to transmission problem)\n", 1604 "Marking address `%s' as no longer connected (due to transmission problem)\n",
1606 a2s (mq->specific_address->ready_list->plugin->short_name, 1605 a2s (mq->specific_address->ready_list->plugin->short_name,
1607 mq->specific_address->addr, 1606 mq->specific_address->addr,
1608 mq->specific_address->addrlen)); 1607 mq->specific_address->addrlen));
1609#endif 1608#endif
1610 GNUNET_STATISTICS_update (stats, 1609 GNUNET_STATISTICS_update (stats,
1611 gettext_noop ("# connected addresses"), 1610 gettext_noop ("# connected addresses"),
1612 -1, 1611 -1, GNUNET_NO);
1613 GNUNET_NO); 1612 mq->specific_address->connected = GNUNET_NO;
1614 mq->specific_address->connected = GNUNET_NO; 1613 }
1615 }
1616 }
1617 if (! mq->internal_msg)
1618 mq->specific_address->in_transmit = GNUNET_NO;
1619 } 1614 }
1615 if (!mq->internal_msg)
1616 mq->specific_address->in_transmit = GNUNET_NO;
1617 }
1620 n = find_neighbour (&mq->neighbour_id); 1618 n = find_neighbour (&mq->neighbour_id);
1621 if (mq->client != NULL) 1619 if (mq->client != NULL)
1622 transmit_send_ok (mq->client, n, target, result); 1620 transmit_send_ok (mq->client, n, target, result);
1623 GNUNET_assert (n != NULL); 1621 GNUNET_assert (n != NULL);
1624 GNUNET_CONTAINER_DLL_remove (n->cont_head, 1622 GNUNET_CONTAINER_DLL_remove (n->cont_head, n->cont_tail, mq);
1625 n->cont_tail,
1626 mq);
1627 GNUNET_free (mq); 1623 GNUNET_free (mq);
1628 if (result == GNUNET_OK) 1624 if (result == GNUNET_OK)
1629 try_transmission_to_peer (n); 1625 try_transmission_to_peer (n);
1630 else if (GNUNET_SCHEDULER_NO_TASK == n->retry_task) 1626 else if (GNUNET_SCHEDULER_NO_TASK == n->retry_task)
1631 n->retry_task = GNUNET_SCHEDULER_add_now (&retry_transmission_task, 1627 n->retry_task = GNUNET_SCHEDULER_add_now (&retry_transmission_task, n);
1632 n);
1633} 1628}
1634 1629
1635 1630
@@ -1649,81 +1644,73 @@ try_transmission_to_peer (struct NeighbourMapEntry *n)
1649 int force_address; 1644 int force_address;
1650 1645
1651 if (n->messages_head == NULL) 1646 if (n->messages_head == NULL)
1652 { 1647 {
1653#if DEBUG_TRANSPORT 1648#if DEBUG_TRANSPORT
1654 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1649 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1655 "Transmission queue for `%4s' is empty\n", 1650 "Transmission queue for `%4s' is empty\n", GNUNET_i2s (&n->id));
1656 GNUNET_i2s (&n->id));
1657#endif 1651#endif
1658 return; /* nothing to do */ 1652 return; /* nothing to do */
1659 } 1653 }
1660 rl = NULL; 1654 rl = NULL;
1661 mq = n->messages_head; 1655 mq = n->messages_head;
1662 force_address = GNUNET_YES; 1656 force_address = GNUNET_YES;
1663 if (mq->specific_address == NULL) 1657 if (mq->specific_address == NULL)
1664 { 1658 {
1665 /* TODO: ADD ATS */ 1659 /* TODO: ADD ATS */
1666 mq->specific_address = get_preferred_ats_address(n); 1660 mq->specific_address = get_preferred_ats_address (n);
1667 GNUNET_STATISTICS_update (stats, 1661 GNUNET_STATISTICS_update (stats,
1668 gettext_noop ("# transport selected peer address freely"), 1662 gettext_noop
1669 1, 1663 ("# transport selected peer address freely"), 1,
1670 GNUNET_NO); 1664 GNUNET_NO);
1671 force_address = GNUNET_NO; 1665 force_address = GNUNET_NO;
1672 } 1666 }
1673 if (mq->specific_address == NULL) 1667 if (mq->specific_address == NULL)
1668 {
1669 GNUNET_STATISTICS_update (stats,
1670 gettext_noop
1671 ("# transport failed to selected peer address"),
1672 1, GNUNET_NO);
1673 timeout = GNUNET_TIME_absolute_get_remaining (mq->timeout);
1674 if (timeout.rel_value == 0)
1674 { 1675 {
1675 GNUNET_STATISTICS_update (stats,
1676 gettext_noop ("# transport failed to selected peer address"),
1677 1,
1678 GNUNET_NO);
1679 timeout = GNUNET_TIME_absolute_get_remaining (mq->timeout);
1680 if (timeout.rel_value == 0)
1681 {
1682#if DEBUG_TRANSPORT 1676#if DEBUG_TRANSPORT
1683 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1677 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1684 "No destination address available to transmit message of size %u to peer `%4s'\n", 1678 "No destination address available to transmit message of size %u to peer `%4s'\n",
1685 mq->message_buf_size, 1679 mq->message_buf_size, GNUNET_i2s (&mq->neighbour_id));
1686 GNUNET_i2s (&mq->neighbour_id));
1687#endif 1680#endif
1688 GNUNET_STATISTICS_update (stats,
1689 gettext_noop ("# bytes in message queue for other peers"),
1690 - (int64_t) mq->message_buf_size,
1691 GNUNET_NO);
1692 GNUNET_STATISTICS_update (stats,
1693 gettext_noop ("# bytes discarded (no destination address available)"),
1694 mq->message_buf_size,
1695 GNUNET_NO);
1696 if (mq->client != NULL)
1697 transmit_send_ok (mq->client, n, &n->id, GNUNET_NO);
1698 GNUNET_CONTAINER_DLL_remove (n->messages_head,
1699 n->messages_tail,
1700 mq);
1701 GNUNET_free (mq);
1702 return; /* nobody ready */
1703 }
1704 GNUNET_STATISTICS_update (stats, 1681 GNUNET_STATISTICS_update (stats,
1705 gettext_noop ("# message delivery deferred (no address)"), 1682 gettext_noop
1706 1, 1683 ("# bytes in message queue for other peers"),
1707 GNUNET_NO); 1684 -(int64_t) mq->message_buf_size, GNUNET_NO);
1708 if (n->retry_task != GNUNET_SCHEDULER_NO_TASK) 1685 GNUNET_STATISTICS_update (stats,
1709 GNUNET_SCHEDULER_cancel (n->retry_task); 1686 gettext_noop
1710 n->retry_task = GNUNET_SCHEDULER_add_delayed (timeout, 1687 ("# bytes discarded (no destination address available)"),
1711 &retry_transmission_task, 1688 mq->message_buf_size, GNUNET_NO);
1712 n); 1689 if (mq->client != NULL)
1690 transmit_send_ok (mq->client, n, &n->id, GNUNET_NO);
1691 GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq);
1692 GNUNET_free (mq);
1693 return; /* nobody ready */
1694 }
1695 GNUNET_STATISTICS_update (stats,
1696 gettext_noop
1697 ("# message delivery deferred (no address)"), 1,
1698 GNUNET_NO);
1699 if (n->retry_task != GNUNET_SCHEDULER_NO_TASK)
1700 GNUNET_SCHEDULER_cancel (n->retry_task);
1701 n->retry_task = GNUNET_SCHEDULER_add_delayed (timeout,
1702 &retry_transmission_task, n);
1713#if DEBUG_TRANSPORT 1703#if DEBUG_TRANSPORT
1714 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1704 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1715 "No validated destination address available to transmit message of size %u to peer `%4s', will wait %llums to find an address.\n", 1705 "No validated destination address available to transmit message of size %u to peer `%4s', will wait %llums to find an address.\n",
1716 mq->message_buf_size, 1706 mq->message_buf_size,
1717 GNUNET_i2s (&mq->neighbour_id), 1707 GNUNET_i2s (&mq->neighbour_id), timeout.rel_value);
1718 timeout.rel_value);
1719#endif 1708#endif
1720 /* FIXME: might want to trigger peerinfo lookup here 1709 /* FIXME: might want to trigger peerinfo lookup here
1721 (unless that's already pending...) */ 1710 * (unless that's already pending...) */
1722 return; 1711 return;
1723 } 1712 }
1724 GNUNET_CONTAINER_DLL_remove (n->messages_head, 1713 GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq);
1725 n->messages_tail,
1726 mq);
1727 if (mq->specific_address->connected == GNUNET_NO) 1714 if (mq->specific_address->connected == GNUNET_NO)
1728 mq->specific_address->connect_attempts++; 1715 mq->specific_address->connect_attempts++;
1729 rl = mq->specific_address->ready_list; 1716 rl = mq->specific_address->ready_list;
@@ -1735,45 +1722,38 @@ try_transmission_to_peer (struct NeighbourMapEntry *n)
1735 "Sending message of size %u for `%4s' to `%s' via plugin `%s'\n", 1722 "Sending message of size %u for `%4s' to `%s' via plugin `%s'\n",
1736 mq->message_buf_size, 1723 mq->message_buf_size,
1737 GNUNET_i2s (&n->id), 1724 GNUNET_i2s (&n->id),
1738 (mq->specific_address->addr != NULL) 1725 (mq->specific_address->addr != NULL)
1739 ? a2s (mq->plugin->short_name, 1726 ? a2s (mq->plugin->short_name,
1740 mq->specific_address->addr, 1727 mq->specific_address->addr,
1741 mq->specific_address->addrlen) 1728 mq->specific_address->addrlen)
1742 : "<inbound>", 1729 : "<inbound>", rl->plugin->short_name);
1743 rl->plugin->short_name);
1744#endif 1730#endif
1745 GNUNET_STATISTICS_update (stats, 1731 GNUNET_STATISTICS_update (stats,
1746 gettext_noop ("# bytes in message queue for other peers"), 1732 gettext_noop
1747 - (int64_t) mq->message_buf_size, 1733 ("# bytes in message queue for other peers"),
1748 GNUNET_NO); 1734 -(int64_t) mq->message_buf_size, GNUNET_NO);
1749 GNUNET_STATISTICS_update (stats, 1735 GNUNET_STATISTICS_update (stats,
1750 gettext_noop ("# bytes pending with plugins"), 1736 gettext_noop ("# bytes pending with plugins"),
1751 mq->message_buf_size, 1737 mq->message_buf_size, GNUNET_NO);
1752 GNUNET_NO);
1753 1738
1754 GNUNET_CONTAINER_DLL_insert (n->cont_head, 1739 GNUNET_CONTAINER_DLL_insert (n->cont_head, n->cont_tail, mq);
1755 n->cont_tail,
1756 mq);
1757 1740
1758 ret = rl->plugin->api->send (rl->plugin->api->cls, 1741 ret = rl->plugin->api->send (rl->plugin->api->cls,
1759 &mq->neighbour_id, 1742 &mq->neighbour_id,
1760 mq->message_buf, 1743 mq->message_buf,
1761 mq->message_buf_size, 1744 mq->message_buf_size,
1762 mq->priority, 1745 mq->priority,
1763 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 1746 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1764 mq->specific_address->session, 1747 mq->specific_address->session,
1765 mq->specific_address->addr, 1748 mq->specific_address->addr,
1766 mq->specific_address->addrlen, 1749 mq->specific_address->addrlen,
1767 force_address, 1750 force_address, &transmit_send_continuation, mq);
1768 &transmit_send_continuation, mq);
1769 if (ret == -1) 1751 if (ret == -1)
1770 { 1752 {
1771 /* failure, but 'send' would not call continuation in this case, 1753 /* failure, but 'send' would not call continuation in this case,
1772 so we need to do it here! */ 1754 * so we need to do it here! */
1773 transmit_send_continuation (mq, 1755 transmit_send_continuation (mq, &mq->neighbour_id, GNUNET_SYSERR);
1774 &mq->neighbour_id, 1756 }
1775 GNUNET_SYSERR);
1776 }
1777} 1757}
1778 1758
1779 1759
@@ -1794,7 +1774,7 @@ static void
1794transmit_to_peer (struct TransportClient *client, 1774transmit_to_peer (struct TransportClient *client,
1795 struct ForeignAddressList *peer_address, 1775 struct ForeignAddressList *peer_address,
1796 unsigned int priority, 1776 unsigned int priority,
1797 struct GNUNET_TIME_Relative timeout, 1777 struct GNUNET_TIME_Relative timeout,
1798 const char *message_buf, 1778 const char *message_buf,
1799 size_t message_buf_size, 1779 size_t message_buf_size,
1800 int is_internal, struct NeighbourMapEntry *neighbour) 1780 int is_internal, struct NeighbourMapEntry *neighbour)
@@ -1803,46 +1783,45 @@ transmit_to_peer (struct TransportClient *client,
1803 1783
1804#if EXTRA_CHECKS 1784#if EXTRA_CHECKS
1805 if (client != NULL) 1785 if (client != NULL)
1786 {
1787 /* check for duplicate submission */
1788 mq = neighbour->messages_head;
1789 while (NULL != mq)
1806 { 1790 {
1807 /* check for duplicate submission */ 1791 if (mq->client == client)
1808 mq = neighbour->messages_head; 1792 {
1809 while (NULL != mq) 1793 /* client transmitted to same peer twice
1810 { 1794 * before getting SEND_OK! */
1811 if (mq->client == client) 1795 GNUNET_break (0);
1812 { 1796 return;
1813 /* client transmitted to same peer twice 1797 }
1814 before getting SEND_OK! */ 1798 mq = mq->next;
1815 GNUNET_break (0);
1816 return;
1817 }
1818 mq = mq->next;
1819 }
1820 } 1799 }
1800 }
1821#endif 1801#endif
1822 GNUNET_STATISTICS_update (stats, 1802 GNUNET_STATISTICS_update (stats,
1823 gettext_noop ("# bytes in message queue for other peers"), 1803 gettext_noop
1824 message_buf_size, 1804 ("# bytes in message queue for other peers"),
1825 GNUNET_NO); 1805 message_buf_size, GNUNET_NO);
1826 mq = GNUNET_malloc (sizeof (struct MessageQueue) + message_buf_size); 1806 mq = GNUNET_malloc (sizeof (struct MessageQueue) + message_buf_size);
1827 mq->specific_address = peer_address; 1807 mq->specific_address = peer_address;
1828 mq->client = client; 1808 mq->client = client;
1829 /* FIXME: this memcpy can be up to 7% of our total runtime! */ 1809 /* FIXME: this memcpy can be up to 7% of our total runtime! */
1830 memcpy (&mq[1], message_buf, message_buf_size); 1810 memcpy (&mq[1], message_buf, message_buf_size);
1831 mq->message_buf = (const char*) &mq[1]; 1811 mq->message_buf = (const char *) &mq[1];
1832 mq->message_buf_size = message_buf_size; 1812 mq->message_buf_size = message_buf_size;
1833 memcpy(&mq->neighbour_id, &neighbour->id, sizeof(struct GNUNET_PeerIdentity)); 1813 memcpy (&mq->neighbour_id, &neighbour->id,
1814 sizeof (struct GNUNET_PeerIdentity));
1834 mq->internal_msg = is_internal; 1815 mq->internal_msg = is_internal;
1835 mq->priority = priority; 1816 mq->priority = priority;
1836 mq->timeout = GNUNET_TIME_relative_to_absolute (timeout); 1817 mq->timeout = GNUNET_TIME_relative_to_absolute (timeout);
1837 if (is_internal) 1818 if (is_internal)
1838 GNUNET_CONTAINER_DLL_insert (neighbour->messages_head, 1819 GNUNET_CONTAINER_DLL_insert (neighbour->messages_head,
1839 neighbour->messages_tail, 1820 neighbour->messages_tail, mq);
1840 mq);
1841 else 1821 else
1842 GNUNET_CONTAINER_DLL_insert_after (neighbour->messages_head, 1822 GNUNET_CONTAINER_DLL_insert_after (neighbour->messages_head,
1843 neighbour->messages_tail, 1823 neighbour->messages_tail,
1844 neighbour->messages_tail, 1824 neighbour->messages_tail, mq);
1845 mq);
1846 try_transmission_to_peer (neighbour); 1825 try_transmission_to_peer (neighbour);
1847} 1826}
1848 1827
@@ -1863,62 +1842,56 @@ transmit_plain_ping (struct NeighbourMapEntry *n)
1863 struct TransportPlugin *plugin; 1842 struct TransportPlugin *plugin;
1864 struct ForeignAddressList *fal; 1843 struct ForeignAddressList *fal;
1865 1844
1866 if (! n->public_key_valid) 1845 if (!n->public_key_valid)
1867 { 1846 {
1868 /* This should not happen since the other peer 1847 /* This should not happen since the other peer
1869 should send us a HELLO prior to sending his 1848 * should send us a HELLO prior to sending his
1870 PING */ 1849 * PING */
1871 GNUNET_break_op (0); 1850 GNUNET_break_op (0);
1872 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1851 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1873 "Could not transmit plain PING to `%s': public key not known\n", 1852 "Could not transmit plain PING to `%s': public key not known\n",
1874 GNUNET_i2s (&n->id)); 1853 GNUNET_i2s (&n->id));
1875 return; 1854 return;
1876 } 1855 }
1877 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1856 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1878 "Looking for addresses to transmit plain PING to `%s'\n", 1857 "Looking for addresses to transmit plain PING to `%s'\n",
1879 GNUNET_i2s (&n->id)); 1858 GNUNET_i2s (&n->id));
1880 for (rl = n->plugins; rl != NULL; rl = rl->next) 1859 for (rl = n->plugins; rl != NULL; rl = rl->next)
1860 {
1861 plugin = rl->plugin;
1862 for (fal = rl->addresses; fal != NULL; fal = fal->next)
1881 { 1863 {
1882 plugin = rl->plugin; 1864 if (!fal->connected)
1883 for (fal = rl->addresses; fal != NULL; fal = fal->next) 1865 continue;
1884 { 1866 ve = GNUNET_malloc (sizeof (struct ValidationEntry));
1885 if (! fal->connected) 1867 ve->transport_name = GNUNET_strdup (plugin->short_name);
1886 continue; 1868 ve->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
1887 ve = GNUNET_malloc (sizeof (struct ValidationEntry)); 1869 UINT_MAX);
1888 ve->transport_name = GNUNET_strdup (plugin->short_name); 1870 ve->send_time = GNUNET_TIME_absolute_get ();
1889 ve->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, 1871 ve->session = fal->session;
1890 UINT_MAX); 1872 memcpy (&ve->publicKey,
1891 ve->send_time = GNUNET_TIME_absolute_get(); 1873 &n->publicKey,
1892 ve->session = fal->session; 1874 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
1893 memcpy(&ve->publicKey, 1875 ve->timeout_task =
1894 &n->publicKey, 1876 GNUNET_SCHEDULER_add_delayed (HELLO_VERIFICATION_TIMEOUT,
1895 sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); 1877 &timeout_hello_validation, ve);
1896 ve->timeout_task = GNUNET_SCHEDULER_add_delayed (HELLO_VERIFICATION_TIMEOUT, 1878 GNUNET_CONTAINER_multihashmap_put (validation_map, &n->id.hashPubKey, ve,
1897 &timeout_hello_validation, 1879 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1898 ve); 1880 ping.header.size = htons (sizeof (struct TransportPingMessage));
1899 GNUNET_CONTAINER_multihashmap_put (validation_map, 1881 ping.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PING);
1900 &n->id.hashPubKey, 1882 ping.challenge = htonl (ve->challenge);
1901 ve, 1883 memcpy (&ping.target, &n->id, sizeof (struct GNUNET_PeerIdentity));
1902 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1884 GNUNET_STATISTICS_update (stats,
1903 ping.header.size = htons(sizeof(struct TransportPingMessage)); 1885 gettext_noop
1904 ping.header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_PING); 1886 ("# PING without HELLO messages sent"), 1,
1905 ping.challenge = htonl(ve->challenge); 1887 GNUNET_NO);
1906 memcpy(&ping.target, &n->id, sizeof(struct GNUNET_PeerIdentity)); 1888 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting plain PING to `%s'\n",
1907 GNUNET_STATISTICS_update (stats, 1889 GNUNET_i2s (&n->id));
1908 gettext_noop ("# PING without HELLO messages sent"), 1890 transmit_to_peer (NULL, fal, GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1909 1, 1891 HELLO_VERIFICATION_TIMEOUT, (const char *) &ping,
1910 GNUNET_NO); 1892 sizeof (ping), GNUNET_YES, n);
1911 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1912 "Transmitting plain PING to `%s'\n",
1913 GNUNET_i2s (&n->id));
1914 transmit_to_peer (NULL,
1915 fal,
1916 GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1917 HELLO_VERIFICATION_TIMEOUT,
1918 (const char*) &ping, sizeof (ping),
1919 GNUNET_YES, n);
1920 }
1921 } 1893 }
1894 }
1922} 1895}
1923 1896
1924 1897
@@ -1930,7 +1903,7 @@ transmit_plain_ping (struct NeighbourMapEntry *n)
1930 * @param fal address to set to 'connected' 1903 * @param fal address to set to 'connected'
1931 */ 1904 */
1932static void 1905static void
1933mark_address_connected(struct ForeignAddressList *fal) 1906mark_address_connected (struct ForeignAddressList *fal)
1934{ 1907{
1935 struct ForeignAddressList *pos; 1908 struct ForeignAddressList *pos;
1936 struct ForeignAddressList *inbound; 1909 struct ForeignAddressList *inbound;
@@ -1938,92 +1911,102 @@ mark_address_connected(struct ForeignAddressList *fal)
1938 1911
1939 GNUNET_assert (GNUNET_YES == fal->validated); 1912 GNUNET_assert (GNUNET_YES == fal->validated);
1940 if (fal->connected == GNUNET_YES) 1913 if (fal->connected == GNUNET_YES)
1941 return; /* nothing to do */ 1914 return; /* nothing to do */
1942 inbound = NULL; 1915 inbound = NULL;
1943 outbound = NULL; 1916 outbound = NULL;
1944 1917
1945 pos = fal->ready_list->addresses; 1918 pos = fal->ready_list->addresses;
1946 while (pos != NULL) 1919 while (pos != NULL)
1947 { 1920 {
1948 /* Already have inbound address, and this is also an inbound address, don't switch!! */ 1921 /* Already have inbound address, and this is also an inbound address, don't switch!! */
1949 if ( (GNUNET_YES == pos->connected) && 1922 if ((GNUNET_YES == pos->connected) &&
1950 (0 == pos->addrlen) && 1923 (0 == pos->addrlen) && (0 == fal->addrlen))
1951 (0 == fal->addrlen) ) 1924 return;
1952 return; 1925 if ((0 == pos->addrlen) && (GNUNET_YES == pos->connected))
1953 if ( (0 == pos->addrlen) && 1926 inbound = pos;
1954 (GNUNET_YES == pos->connected) ) 1927 pos = pos->next;
1955 inbound = pos; 1928 }
1956 pos = pos->next;
1957 }
1958 1929
1959 pos = fal->ready_list->addresses; 1930 pos = fal->ready_list->addresses;
1960 while (pos != NULL) 1931 while (pos != NULL)
1961 { 1932 {
1962 /* Already have outbound address, and this is also an outbound address, don't switch!! */ 1933 /* Already have outbound address, and this is also an outbound address, don't switch!! */
1963 if ( (GNUNET_YES == pos->connected) && 1934 if ((GNUNET_YES == pos->connected) &&
1964 (0 < pos->addrlen) && 1935 (0 < pos->addrlen) && (0 < fal->addrlen))
1965 (0 < fal->addrlen) ) 1936 return;
1966 return; 1937 if ((0 < pos->addrlen) && (GNUNET_YES == pos->connected))
1967 if ( (0 < pos->addrlen) && (GNUNET_YES == pos->connected) ) 1938 outbound = pos;
1968 outbound = pos; 1939 pos = pos->next;
1969 pos = pos->next; 1940 }
1970 }
1971 1941
1972#if DEBUG_INBOUND 1942#if DEBUG_INBOUND
1973 if (inbound != NULL) 1943 if (inbound != NULL)
1974 fprintf(stderr, "Peer: %s, have inbound connection.\n", GNUNET_i2s(&my_identity)); 1944 fprintf (stderr, "Peer: %s, have inbound connection.\n",
1945 GNUNET_i2s (&my_identity));
1975 if (outbound != NULL) 1946 if (outbound != NULL)
1976 fprintf(stderr, "Peer: %s, have outbound connection.\n", GNUNET_i2s(&my_identity)); 1947 fprintf (stderr, "Peer: %s, have outbound connection.\n",
1948 GNUNET_i2s (&my_identity));
1977#endif 1949#endif
1978 1950
1979 /* Have an inbound connection to this peer which is valid; our id is lower, ignore outbound connection! */ 1951 /* Have an inbound connection to this peer which is valid; our id is lower, ignore outbound connection! */
1980 if ((inbound != NULL) && (0 != fal->addrlen) && (1 1952 if ((inbound != NULL) && (0 != fal->addrlen) && (1
1981 == GNUNET_CRYPTO_hash_xorcmp (&inbound->ready_list->neighbour->id.hashPubKey, 1953 ==
1982 &my_identity.hashPubKey, &null_hash))) 1954 GNUNET_CRYPTO_hash_xorcmp
1983 { 1955 (&inbound->
1956 ready_list->neighbour->id.
1957 hashPubKey,
1958 &my_identity.hashPubKey,
1959 &null_hash)))
1960 {
1984#if DEBUG_INBOUND 1961#if DEBUG_INBOUND
1985 fprintf(stderr, "Peer: %s, had inbound connection, ignoring outbound!\n", GNUNET_i2s(&my_identity)); 1962 fprintf (stderr, "Peer: %s, had inbound connection, ignoring outbound!\n",
1963 GNUNET_i2s (&my_identity));
1986#endif 1964#endif
1987 return; 1965 return;
1988 } 1966 }
1989 else if ((outbound != NULL) && (0 == fal->addrlen) && ((-1 1967 else if ((outbound != NULL) && (0 == fal->addrlen) && ((-1
1990 == GNUNET_CRYPTO_hash_xorcmp (&outbound->ready_list->neighbour->id.hashPubKey, 1968 ==
1991 &my_identity.hashPubKey, &null_hash)))) 1969 GNUNET_CRYPTO_hash_xorcmp
1992 { 1970 (&outbound->ready_list->neighbour->
1971 id.hashPubKey,
1972 &my_identity.hashPubKey,
1973 &null_hash))))
1974 {
1993#if DEBUG_INBOUND 1975#if DEBUG_INBOUND
1994 fprintf(stderr, "Peer: %s, have outbound connection, ignoring inbound!\n", GNUNET_i2s(&my_identity)); 1976 fprintf (stderr, "Peer: %s, have outbound connection, ignoring inbound!\n",
1977 GNUNET_i2s (&my_identity));
1995#endif 1978#endif
1996 return; 1979 return;
1997 } 1980 }
1998 1981
1999 pos = fal->ready_list->addresses; 1982 pos = fal->ready_list->addresses;
2000 while (pos != NULL) 1983 while (pos != NULL)
1984 {
1985 if ((GNUNET_YES == pos->connected) && (0 < pos->addrlen))
2001 { 1986 {
2002 if ((GNUNET_YES == pos->connected) && (0 < pos->addrlen))
2003 {
2004#if DEBUG_TRANSPORT 1987#if DEBUG_TRANSPORT
2005 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1988 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2006 "Marking address `%s' as no longer connected (due to connect on other address)\n", 1989 "Marking address `%s' as no longer connected (due to connect on other address)\n",
2007 a2s (pos->ready_list->plugin->short_name, pos->addr, 1990 a2s (pos->ready_list->plugin->short_name, pos->addr,
2008 pos->addrlen)); 1991 pos->addrlen));
2009#endif 1992#endif
2010#if DEBUG_INBOUND 1993#if DEBUG_INBOUND
2011 fprintf(stderr, 1994 fprintf (stderr,
2012 "Peer: %s, setting %s connection to disconnected.\n", 1995 "Peer: %s, setting %s connection to disconnected.\n",
2013 GNUNET_i2s(&my_identity), 1996 GNUNET_i2s (&my_identity),
2014 (0 == pos->addrlen) ? "INBOUND" : "OUTBOUND"); 1997 (0 == pos->addrlen) ? "INBOUND" : "OUTBOUND");
2015#endif 1998#endif
2016 pos->connected = GNUNET_NO; 1999 pos->connected = GNUNET_NO;
2017 GNUNET_STATISTICS_update (stats, 2000 GNUNET_STATISTICS_update (stats,
2018 gettext_noop ("# connected addresses"), -1, 2001 gettext_noop ("# connected addresses"), -1,
2019 GNUNET_NO); 2002 GNUNET_NO);
2020 }
2021 pos = pos->next;
2022 } 2003 }
2004 pos = pos->next;
2005 }
2023 GNUNET_assert (GNUNET_NO == fal->connected); 2006 GNUNET_assert (GNUNET_NO == fal->connected);
2024 fal->connected = GNUNET_YES; 2007 fal->connected = GNUNET_YES;
2025 GNUNET_STATISTICS_update (stats, gettext_noop ("# connected addresses"), 2008 GNUNET_STATISTICS_update (stats, gettext_noop ("# connected addresses"),
2026 1, GNUNET_NO); 2009 1, GNUNET_NO);
2027} 2010}
2028 2011
2029 2012
@@ -2037,7 +2020,7 @@ mark_address_connected(struct ForeignAddressList *fal)
2037 * @return selected address, NULL if we have none 2020 * @return selected address, NULL if we have none
2038 */ 2021 */
2039struct ForeignAddressList * 2022struct ForeignAddressList *
2040find_ready_address(struct NeighbourMapEntry *neighbour) 2023find_ready_address (struct NeighbourMapEntry *neighbour)
2041{ 2024{
2042 struct ReadyList *head = neighbour->plugins; 2025 struct ReadyList *head = neighbour->plugins;
2043 struct ForeignAddressList *addresses; 2026 struct ForeignAddressList *addresses;
@@ -2049,95 +2032,93 @@ find_ready_address(struct NeighbourMapEntry *neighbour)
2049 2032
2050 best_address = NULL; 2033 best_address = NULL;
2051 while (head != NULL) 2034 while (head != NULL)
2035 {
2036 addresses = head->addresses;
2037 while (addresses != NULL)
2052 { 2038 {
2053 addresses = head->addresses; 2039 if ((addresses->timeout.abs_value < now.abs_value) &&
2054 while (addresses != NULL) 2040 (addresses->connected == GNUNET_YES))
2055 { 2041 {
2056 if ( (addresses->timeout.abs_value < now.abs_value) &&
2057 (addresses->connected == GNUNET_YES) )
2058 {
2059#if DEBUG_TRANSPORT 2042#if DEBUG_TRANSPORT
2060 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2043 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2061 "Marking long-time inactive connection to `%4s' as down.\n", 2044 "Marking long-time inactive connection to `%4s' as down.\n",
2062 GNUNET_i2s (&neighbour->id)); 2045 GNUNET_i2s (&neighbour->id));
2063#endif 2046#endif
2064 GNUNET_STATISTICS_update (stats, 2047 GNUNET_STATISTICS_update (stats,
2065 gettext_noop ("# connected addresses"), 2048 gettext_noop ("# connected addresses"),
2066 -1, 2049 -1, GNUNET_NO);
2067 GNUNET_NO); 2050 addresses->connected = GNUNET_NO;
2068 addresses->connected = GNUNET_NO; 2051 }
2069 } 2052 addresses = addresses->next;
2070 addresses = addresses->next; 2053 }
2071 }
2072 2054
2073 addresses = head->addresses; 2055 addresses = head->addresses;
2074 while (addresses != NULL) 2056 while (addresses != NULL)
2075 { 2057 {
2076#if DEBUG_TRANSPORT 2058#if DEBUG_TRANSPORT
2077 if (addresses->addr != NULL) 2059 if (addresses->addr != NULL)
2078 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2060 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2079 "Have address `%s' for peer `%4s' (status: %d, %d, %d, %u, %llums, %u)\n", 2061 "Have address `%s' for peer `%4s' (status: %d, %d, %d, %u, %llums, %u)\n",
2080 a2s (head->plugin->short_name, 2062 a2s (head->plugin->short_name,
2081 addresses->addr, 2063 addresses->addr,
2082 addresses->addrlen), 2064 addresses->addrlen),
2083 GNUNET_i2s (&neighbour->id), 2065 GNUNET_i2s (&neighbour->id),
2084 addresses->connected, 2066 addresses->connected,
2085 addresses->in_transmit, 2067 addresses->in_transmit,
2086 addresses->validated, 2068 addresses->validated,
2087 addresses->connect_attempts, 2069 addresses->connect_attempts,
2088 (unsigned long long) addresses->timeout.abs_value, 2070 (unsigned long long) addresses->timeout.abs_value,
2089 (unsigned int) addresses->distance); 2071 (unsigned int) addresses->distance);
2090#endif 2072#endif
2091 if (0==strcmp(head->plugin->short_name,"unix")) 2073 if (0 == strcmp (head->plugin->short_name, "unix"))
2092 { 2074 {
2093 if ( (unix_address == NULL) || 2075 if ((unix_address == NULL) ||
2094 ( (unix_address != NULL) && 2076 ((unix_address != NULL) &&
2095 (addresses->latency.rel_value < unix_address->latency.rel_value) ) ) 2077 (addresses->latency.rel_value < unix_address->latency.rel_value)))
2096 unix_address = addresses; 2078 unix_address = addresses;
2097 } 2079 }
2098 if ( ( (best_address == NULL) || 2080 if (((best_address == NULL) ||
2099 (addresses->connected == GNUNET_YES) || 2081 (addresses->connected == GNUNET_YES) ||
2100 (best_address->connected == GNUNET_NO) ) && 2082 (best_address->connected == GNUNET_NO)) &&
2101 (addresses->in_transmit == GNUNET_NO) && 2083 (addresses->in_transmit == GNUNET_NO) &&
2102 ( (best_address == NULL) || 2084 ((best_address == NULL) ||
2103 (addresses->latency.rel_value < best_address->latency.rel_value)) ) 2085 (addresses->latency.rel_value < best_address->latency.rel_value)))
2104 best_address = addresses; 2086 best_address = addresses;
2105 /* FIXME: also give lower-latency addresses that are not 2087 /* FIXME: also give lower-latency addresses that are not
2106 connected a chance some times... */ 2088 * connected a chance some times... */
2107 addresses = addresses->next; 2089 addresses = addresses->next;
2108 } 2090 }
2109 if (unix_address != NULL) 2091 if (unix_address != NULL)
2110 break; 2092 break;
2111 head = head->next; 2093 head = head->next;
2112 } 2094 }
2113 if (unix_address != NULL) 2095 if (unix_address != NULL)
2114 { 2096 {
2115 best_address = unix_address; 2097 best_address = unix_address;
2116#if DEBUG_TRANSPORT 2098#if DEBUG_TRANSPORT
2117 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2099 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2118 "Found UNIX address, forced this address\n"); 2100 "Found UNIX address, forced this address\n");
2119#endif 2101#endif
2120 } 2102 }
2121 if (best_address != NULL) 2103 if (best_address != NULL)
2122 { 2104 {
2123#if DEBUG_TRANSPORT 2105#if DEBUG_TRANSPORT
2124 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2106 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2125 "Best address found (`%s') has latency of %llu ms.\n", 2107 "Best address found (`%s') has latency of %llu ms.\n",
2126 (best_address->addrlen > 0) 2108 (best_address->addrlen > 0)
2127 ? a2s (best_address->ready_list->plugin->short_name, 2109 ? a2s (best_address->ready_list->plugin->short_name,
2128 best_address->addr, 2110 best_address->addr,
2129 best_address->addrlen) 2111 best_address->addrlen)
2130 : "<inbound>", 2112 : "<inbound>", best_address->latency.rel_value);
2131 best_address->latency.rel_value);
2132#endif 2113#endif
2133 } 2114 }
2134 else 2115 else
2135 { 2116 {
2136 GNUNET_STATISTICS_update (stats, 2117 GNUNET_STATISTICS_update (stats,
2137 gettext_noop ("# transmission attempts failed (no address)"), 2118 gettext_noop
2138 1, 2119 ("# transmission attempts failed (no address)"),
2139 GNUNET_NO); 2120 1, GNUNET_NO);
2140 } 2121 }
2141 2122
2142 return best_address; 2123 return best_address;
2143} 2124}
@@ -2164,15 +2145,15 @@ address_generator (void *cls, size_t max, void *buf)
2164 size_t ret; 2145 size_t ret;
2165 2146
2166 while ((gc->addr_pos == NULL) && (gc->plug_pos != NULL)) 2147 while ((gc->addr_pos == NULL) && (gc->plug_pos != NULL))
2167 { 2148 {
2168 gc->plug_pos = gc->plug_pos->next; 2149 gc->plug_pos = gc->plug_pos->next;
2169 gc->addr_pos = (gc->plug_pos != NULL) ? gc->plug_pos->addresses : NULL; 2150 gc->addr_pos = (gc->plug_pos != NULL) ? gc->plug_pos->addresses : NULL;
2170 } 2151 }
2171 if (NULL == gc->plug_pos) 2152 if (NULL == gc->plug_pos)
2172 { 2153 {
2173 2154
2174 return 0; 2155 return 0;
2175 } 2156 }
2176 ret = GNUNET_HELLO_add_address (gc->plug_pos->short_name, 2157 ret = GNUNET_HELLO_add_address (gc->plug_pos->short_name,
2177 gc->expiration, 2158 gc->expiration,
2178 &gc->addr_pos[1], 2159 &gc->addr_pos[1],
@@ -2184,9 +2165,7 @@ address_generator (void *cls, size_t max, void *buf)
2184 2165
2185 2166
2186static int 2167static int
2187transmit_our_hello_if_pong (void *cls, 2168transmit_our_hello_if_pong (void *cls, const GNUNET_HashCode * key, void *value)
2188 const GNUNET_HashCode *key,
2189 void *value)
2190{ 2169{
2191 struct NeighbourMapEntry *npos = value; 2170 struct NeighbourMapEntry *npos = value;
2192 2171
@@ -2194,18 +2173,16 @@ transmit_our_hello_if_pong (void *cls,
2194 return GNUNET_OK; 2173 return GNUNET_OK;
2195#if DEBUG_TRANSPORT 2174#if DEBUG_TRANSPORT
2196 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 2175 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
2197 "Transmitting updated `%s' to neighbour `%4s'\n", 2176 "Transmitting updated `%s' to neighbour `%4s'\n",
2198 "HELLO", GNUNET_i2s (&npos->id)); 2177 "HELLO", GNUNET_i2s (&npos->id));
2199#endif 2178#endif
2200 GNUNET_STATISTICS_update (stats, 2179 GNUNET_STATISTICS_update (stats,
2201 gettext_noop ("# transmitted my HELLO to other peers"), 2180 gettext_noop
2202 1, 2181 ("# transmitted my HELLO to other peers"), 1,
2203 GNUNET_NO); 2182 GNUNET_NO);
2204 transmit_to_peer (NULL, NULL, 0, 2183 transmit_to_peer (NULL, NULL, 0, HELLO_ADDRESS_EXPIRATION,
2205 HELLO_ADDRESS_EXPIRATION, 2184 (const char *) our_hello, GNUNET_HELLO_size (our_hello),
2206 (const char *) our_hello, 2185 GNUNET_NO, npos);
2207 GNUNET_HELLO_size(our_hello),
2208 GNUNET_NO, npos);
2209 return GNUNET_OK; 2186 return GNUNET_OK;
2210} 2187}
2211 2188
@@ -2218,8 +2195,7 @@ transmit_our_hello_if_pong (void *cls,
2218 * @param tc scheduler context 2195 * @param tc scheduler context
2219 */ 2196 */
2220static void 2197static void
2221refresh_hello_task (void *cls, 2198refresh_hello_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2222 const struct GNUNET_SCHEDULER_TaskContext *tc)
2223{ 2199{
2224 struct GNUNET_HELLO_Message *hello; 2200 struct GNUNET_HELLO_Message *hello;
2225 struct TransportClient *cpos; 2201 struct TransportClient *cpos;
@@ -2232,29 +2208,26 @@ refresh_hello_task (void *cls,
2232 hello = GNUNET_HELLO_create (&my_public_key, &address_generator, &gc); 2208 hello = GNUNET_HELLO_create (&my_public_key, &address_generator, &gc);
2233#if DEBUG_TRANSPORT 2209#if DEBUG_TRANSPORT
2234 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 2210 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
2235 "Refreshed my `%s', new size is %d\n", "HELLO", GNUNET_HELLO_size(hello)); 2211 "Refreshed my `%s', new size is %d\n", "HELLO",
2212 GNUNET_HELLO_size (hello));
2236#endif 2213#endif
2237 GNUNET_STATISTICS_update (stats, 2214 GNUNET_STATISTICS_update (stats,
2238 gettext_noop ("# refreshed my HELLO"), 2215 gettext_noop ("# refreshed my HELLO"),
2239 1, 2216 1, GNUNET_NO);
2240 GNUNET_NO);
2241 cpos = clients; 2217 cpos = clients;
2242 while (cpos != NULL) 2218 while (cpos != NULL)
2243 { 2219 {
2244 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2220 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting my HELLO to client!\n");
2245 "Transmitting my HELLO to client!\n"); 2221 transmit_to_client (cpos,
2246 transmit_to_client (cpos, 2222 (const struct GNUNET_MessageHeader *) hello, GNUNET_NO);
2247 (const struct GNUNET_MessageHeader *) hello, 2223 cpos = cpos->next;
2248 GNUNET_NO); 2224 }
2249 cpos = cpos->next;
2250 }
2251 2225
2252 GNUNET_free_non_null (our_hello); 2226 GNUNET_free_non_null (our_hello);
2253 our_hello = hello; 2227 our_hello = hello;
2254 GNUNET_PEERINFO_add_peer (peerinfo, our_hello); 2228 GNUNET_PEERINFO_add_peer (peerinfo, our_hello);
2255 GNUNET_CONTAINER_multihashmap_iterate (neighbours, 2229 GNUNET_CONTAINER_multihashmap_iterate (neighbours,
2256 &transmit_our_hello_if_pong, 2230 &transmit_our_hello_if_pong, NULL);
2257 NULL);
2258} 2231}
2259 2232
2260 2233
@@ -2266,14 +2239,11 @@ static void
2266refresh_hello () 2239refresh_hello ()
2267{ 2240{
2268#if DEBUG_TRANSPORT_HELLO 2241#if DEBUG_TRANSPORT_HELLO
2269 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2242 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "refresh_hello() called!\n");
2270 "refresh_hello() called!\n");
2271#endif 2243#endif
2272 if (hello_task != GNUNET_SCHEDULER_NO_TASK) 2244 if (hello_task != GNUNET_SCHEDULER_NO_TASK)
2273 return; 2245 return;
2274 hello_task 2246 hello_task = GNUNET_SCHEDULER_add_now (&refresh_hello_task, NULL);
2275 = GNUNET_SCHEDULER_add_now (&refresh_hello_task,
2276 NULL);
2277} 2247}
2278 2248
2279 2249
@@ -2287,9 +2257,7 @@ refresh_hello ()
2287 * @return GNUNET_YES (we should continue to iterate) 2257 * @return GNUNET_YES (we should continue to iterate)
2288 */ 2258 */
2289static int 2259static int
2290remove_session_validations (void *cls, 2260remove_session_validations (void *cls, const GNUNET_HashCode * key, void *value)
2291 const GNUNET_HashCode * key,
2292 void *value)
2293{ 2261{
2294 struct Session *session = cls; 2262 struct Session *session = cls;
2295 struct ValidationEntry *ve = value; 2263 struct ValidationEntry *ve = value;
@@ -2313,34 +2281,32 @@ remove_session_validations (void *cls,
2313 * @param nl neighbour that was disconnected 2281 * @param nl neighbour that was disconnected
2314 */ 2282 */
2315static void 2283static void
2316try_fast_reconnect (struct TransportPlugin *p, 2284try_fast_reconnect (struct TransportPlugin *p, struct NeighbourMapEntry *nl)
2317 struct NeighbourMapEntry *nl)
2318{ 2285{
2319 /* FIXME-MW: fast reconnect / transport switching not implemented... */ 2286 /* FIXME-MW: fast reconnect / transport switching not implemented... */
2320 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 2287 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "try_fast_reconnect not implemented!\n");
2321 "try_fast_reconnect not implemented!\n");
2322 /* Note: the idea here is to hide problems with transports (or 2288 /* Note: the idea here is to hide problems with transports (or
2323 switching between plugins) from the core to eliminate the need to 2289 * switching between plugins) from the core to eliminate the need to
2324 re-negotiate session keys and the like; OTOH, we should tell core 2290 * re-negotiate session keys and the like; OTOH, we should tell core
2325 quickly (much faster than timeout) `if a connection was lost and 2291 * quickly (much faster than timeout) `if a connection was lost and
2326 could not be re-established (i.e. other peer went down or is 2292 * could not be re-established (i.e. other peer went down or is
2327 unable / refuses to communicate); 2293 * unable / refuses to communicate);
2328 2294 *
2329 So we should consider: 2295 * So we should consider:
2330 1) ideally: our own willingness / need to connect 2296 * 1) ideally: our own willingness / need to connect
2331 2) prior failures to connect to this peer (by plugin) 2297 * 2) prior failures to connect to this peer (by plugin)
2332 3) ideally: reasons why other peer terminated (as far as knowable) 2298 * 3) ideally: reasons why other peer terminated (as far as knowable)
2333 2299 *
2334 Most importantly, it must be POSSIBLE for another peer to terminate 2300 * Most importantly, it must be POSSIBLE for another peer to terminate
2335 a connection for a while (without us instantly re-establishing it). 2301 * a connection for a while (without us instantly re-establishing it).
2336 Similarly, if another peer is gone we should quickly notify CORE. 2302 * Similarly, if another peer is gone we should quickly notify CORE.
2337 OTOH, if there was a minor glitch (i.e. crash of gnunet-service-transport 2303 * OTOH, if there was a minor glitch (i.e. crash of gnunet-service-transport
2338 on the other end), we should reconnect in such a way that BOTH CORE 2304 * on the other end), we should reconnect in such a way that BOTH CORE
2339 services never even notice. 2305 * services never even notice.
2340 Furthermore, the same mechanism (or small variation) could be used 2306 * Furthermore, the same mechanism (or small variation) could be used
2341 to switch to a better-performing plugin (ATS). 2307 * to switch to a better-performing plugin (ATS).
2342 2308 *
2343 Finally, this needs to be tested throughly... */ 2309 * Finally, this needs to be tested throughly... */
2344 2310
2345 /* 2311 /*
2346 * GNUNET_NO in the call below makes transport disconnect the peer, 2312 * GNUNET_NO in the call below makes transport disconnect the peer,
@@ -2355,12 +2321,12 @@ try_fast_reconnect (struct TransportPlugin *p,
2355#if DEBUG_TRANSPORT 2321#if DEBUG_TRANSPORT
2356#endif 2322#endif
2357 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2323 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2358 "Disconnecting peer `%4s', %s\n", GNUNET_i2s(&nl->id), 2324 "Disconnecting peer `%4s', %s\n", GNUNET_i2s (&nl->id),
2359 "try_fast_reconnect"); 2325 "try_fast_reconnect");
2360 2326
2361 GNUNET_STATISTICS_update (stats, 2327 GNUNET_STATISTICS_update (stats,
2362 gettext_noop ("# disconnects due to try_fast_reconnect"), 2328 gettext_noop
2363 1, 2329 ("# disconnects due to try_fast_reconnect"), 1,
2364 GNUNET_NO); 2330 GNUNET_NO);
2365#if DISCONNECT || 1 2331#if DISCONNECT || 1
2366 disconnect_neighbour (nl, GNUNET_YES); 2332 disconnect_neighbour (nl, GNUNET_YES);
@@ -2380,9 +2346,9 @@ try_fast_reconnect (struct TransportPlugin *p,
2380 * @param session which session is being destoyed 2346 * @param session which session is being destoyed
2381 */ 2347 */
2382static void 2348static void
2383plugin_env_session_end (void *cls, 2349plugin_env_session_end (void *cls,
2384 const struct GNUNET_PeerIdentity *peer, 2350 const struct GNUNET_PeerIdentity *peer,
2385 struct Session *session) 2351 struct Session *session)
2386{ 2352{
2387 struct TransportPlugin *p = cls; 2353 struct TransportPlugin *p = cls;
2388 struct NeighbourMapEntry *nl; 2354 struct NeighbourMapEntry *nl;
@@ -2392,119 +2358,116 @@ plugin_env_session_end (void *cls,
2392 2358
2393#if DEBUG_TRANSPORT 2359#if DEBUG_TRANSPORT
2394 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2360 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2395 "Session ended with peer `%4s', %s\n", 2361 "Session ended with peer `%4s', %s\n",
2396 GNUNET_i2s(peer), 2362 GNUNET_i2s (peer), "plugin_env_session_end");
2397 "plugin_env_session_end");
2398#endif 2363#endif
2399 GNUNET_CONTAINER_multihashmap_iterate (validation_map, 2364 GNUNET_CONTAINER_multihashmap_iterate (validation_map,
2400 &remove_session_validations, 2365 &remove_session_validations, session);
2401 session);
2402 nl = find_neighbour (peer); 2366 nl = find_neighbour (peer);
2403 if (nl == NULL) 2367 if (nl == NULL)
2404 { 2368 {
2405#if DEBUG_TRANSPORT 2369#if DEBUG_TRANSPORT
2406 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2370 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2407 "No neighbour record found for peer `%4s'\n", 2371 "No neighbour record found for peer `%4s'\n",
2408 GNUNET_i2s(peer)); 2372 GNUNET_i2s (peer));
2409#endif 2373#endif
2410 return; /* was never marked as connected */ 2374 return; /* was never marked as connected */
2411 } 2375 }
2412 rl = nl->plugins; 2376 rl = nl->plugins;
2413 while (rl != NULL) 2377 while (rl != NULL)
2414 { 2378 {
2415 if (rl->plugin == p) 2379 if (rl->plugin == p)
2416 break; 2380 break;
2417 rl = rl->next; 2381 rl = rl->next;
2418 } 2382 }
2419 if (rl == NULL) 2383 if (rl == NULL)
2420 { 2384 {
2421#if DEBUG_TRANSPORT 2385#if DEBUG_TRANSPORT
2422 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2386 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2423 "Plugin was associated with peer `%4s'\n", 2387 "Plugin was associated with peer `%4s'\n", GNUNET_i2s (peer));
2424 GNUNET_i2s(peer));
2425#endif 2388#endif
2426 GNUNET_STATISTICS_update (stats, 2389 GNUNET_STATISTICS_update (stats,
2427 gettext_noop ("# disconnects due to session end"), 2390 gettext_noop ("# disconnects due to session end"),
2428 1, 2391 1, GNUNET_NO);
2429 GNUNET_NO); 2392 disconnect_neighbour (nl, GNUNET_YES);
2430 disconnect_neighbour (nl, GNUNET_YES); 2393 return;
2431 return; 2394 }
2432 }
2433 prev = NULL; 2395 prev = NULL;
2434 pos = rl->addresses; 2396 pos = rl->addresses;
2435 while ( (pos != NULL) && 2397 while ((pos != NULL) && (pos->session != session))
2436 (pos->session != session) ) 2398 {
2437 { 2399 prev = pos;
2438 prev = pos; 2400 pos = pos->next;
2439 pos = pos->next; 2401 }
2440 }
2441 if (pos == NULL) 2402 if (pos == NULL)
2442 { 2403 {
2443#if DEBUG_TRANSPORT 2404#if DEBUG_TRANSPORT
2444 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2405 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2445 "Session was never marked as ready for peer `%4s'\n", 2406 "Session was never marked as ready for peer `%4s'\n",
2446 GNUNET_i2s(peer)); 2407 GNUNET_i2s (peer));
2447#endif 2408#endif
2448 2409
2449 int validations_pending = GNUNET_CONTAINER_multihashmap_contains (validation_map, &peer->hashPubKey); 2410 int validations_pending =
2411 GNUNET_CONTAINER_multihashmap_contains (validation_map,
2412 &peer->hashPubKey);
2450 2413
2451 /* No session was marked as ready, but we have pending validations so do not disconnect from neighbour */ 2414 /* No session was marked as ready, but we have pending validations so do not disconnect from neighbour */
2452 if (validations_pending ==GNUNET_YES) 2415 if (validations_pending == GNUNET_YES)
2453 { 2416 {
2454#if DEBUG_TRANSPORT 2417#if DEBUG_TRANSPORT
2455 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2418 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2456 "Not disconnecting from peer `%4s due to pending address validations\n", GNUNET_i2s(peer)); 2419 "Not disconnecting from peer `%4s due to pending address validations\n",
2420 GNUNET_i2s (peer));
2457#endif 2421#endif
2458 return; 2422 return;
2459 } 2423 }
2460 2424
2461 //FIXME: This conflicts with inbound tcp connections and tcp nat ... debugging in progress 2425 //FIXME: This conflicts with inbound tcp connections and tcp nat ... debugging in progress
2462 GNUNET_STATISTICS_update (stats, 2426 GNUNET_STATISTICS_update (stats,
2463 gettext_noop ("# disconnects due to unready session"), 2427 gettext_noop
2464 1, 2428 ("# disconnects due to unready session"), 1,
2465 GNUNET_NO); 2429 GNUNET_NO);
2466 2430
2467 disconnect_neighbour (nl, GNUNET_YES); 2431 disconnect_neighbour (nl, GNUNET_YES);
2468 return; /* was never marked as connected */ 2432 return; /* was never marked as connected */
2469 } 2433 }
2470 pos->session = NULL; 2434 pos->session = NULL;
2471 if (GNUNET_YES == pos->connected) 2435 if (GNUNET_YES == pos->connected)
2472 { 2436 {
2473 pos->connected = GNUNET_NO; 2437 pos->connected = GNUNET_NO;
2474 GNUNET_STATISTICS_update (stats, 2438 GNUNET_STATISTICS_update (stats,
2475 gettext_noop ("# connected addresses"), 2439 gettext_noop ("# connected addresses"),
2476 -1, 2440 -1, GNUNET_NO);
2477 GNUNET_NO); 2441 }
2478 }
2479 if (GNUNET_SCHEDULER_NO_TASK != pos->revalidate_task) 2442 if (GNUNET_SCHEDULER_NO_TASK != pos->revalidate_task)
2480 { 2443 {
2481 GNUNET_SCHEDULER_cancel (pos->revalidate_task); 2444 GNUNET_SCHEDULER_cancel (pos->revalidate_task);
2482 pos->revalidate_task = GNUNET_SCHEDULER_NO_TASK; 2445 pos->revalidate_task = GNUNET_SCHEDULER_NO_TASK;
2483 } 2446 }
2484 2447
2485 if (pos->addrlen != 0) 2448 if (pos->addrlen != 0)
2449 {
2450 if (nl->received_pong != GNUNET_NO)
2486 { 2451 {
2487 if (nl->received_pong != GNUNET_NO) 2452 GNUNET_STATISTICS_update (stats,
2488 { 2453 gettext_noop
2489 GNUNET_STATISTICS_update (stats, 2454 ("# try_fast_reconnect thanks to plugin_env_session_end"),
2490 gettext_noop ("# try_fast_reconnect thanks to plugin_env_session_end"), 2455 1, GNUNET_NO);
2491 1, 2456 if (GNUNET_YES == pos->connected)
2492 GNUNET_NO); 2457 try_fast_reconnect (p, nl);
2493 if (GNUNET_YES == pos->connected)
2494 try_fast_reconnect (p, nl);
2495 }
2496 else
2497 {
2498 GNUNET_STATISTICS_update (stats,
2499 gettext_noop ("# disconnects due to missing pong"),
2500 1,
2501 GNUNET_NO);
2502 /* FIXME this is never true?! See: line 2416*/
2503 if (GNUNET_YES == pos->connected)
2504 disconnect_neighbour (nl, GNUNET_YES);
2505 }
2506 return;
2507 } 2458 }
2459 else
2460 {
2461 GNUNET_STATISTICS_update (stats,
2462 gettext_noop
2463 ("# disconnects due to missing pong"), 1,
2464 GNUNET_NO);
2465 /* FIXME this is never true?! See: line 2416 */
2466 if (GNUNET_YES == pos->connected)
2467 disconnect_neighbour (nl, GNUNET_YES);
2468 }
2469 return;
2470 }
2508 2471
2509 /* was inbound connection, free 'pos' */ 2472 /* was inbound connection, free 'pos' */
2510 if (prev == NULL) 2473 if (prev == NULL)
@@ -2512,59 +2475,56 @@ plugin_env_session_end (void *cls,
2512 else 2475 else
2513 prev->next = pos->next; 2476 prev->next = pos->next;
2514 if (GNUNET_SCHEDULER_NO_TASK != pos->revalidate_task) 2477 if (GNUNET_SCHEDULER_NO_TASK != pos->revalidate_task)
2515 { 2478 {
2516 GNUNET_SCHEDULER_cancel (pos->revalidate_task); 2479 GNUNET_SCHEDULER_cancel (pos->revalidate_task);
2517 pos->revalidate_task = GNUNET_SCHEDULER_NO_TASK; 2480 pos->revalidate_task = GNUNET_SCHEDULER_NO_TASK;
2518 } 2481 }
2519 GNUNET_free_non_null (pos->ressources); 2482 GNUNET_free_non_null (pos->ressources);
2520 GNUNET_free_non_null (pos->quality); 2483 GNUNET_free_non_null (pos->quality);
2521#if HAVE_LIBGLPK 2484#if HAVE_LIBGLPK
2522 ats_modify_problem_state (ats, ATS_MODIFIED); 2485 ats_modify_problem_state (ats, ATS_MODIFIED);
2523#endif 2486#endif
2524 if (GNUNET_YES != pos->connected) 2487 if (GNUNET_YES != pos->connected)
2525 { 2488 {
2526 /* nothing else to do, connection was never up... */ 2489 /* nothing else to do, connection was never up... */
2527 GNUNET_free (pos); 2490 GNUNET_free (pos);
2528 return; 2491 return;
2529 } 2492 }
2530 pos->connected = GNUNET_NO; 2493 pos->connected = GNUNET_NO;
2531 GNUNET_STATISTICS_update (stats, 2494 GNUNET_STATISTICS_update (stats,
2532 gettext_noop ("# connected addresses"), 2495 gettext_noop ("# connected addresses"),
2533 -1, 2496 -1, GNUNET_NO);
2534 GNUNET_NO);
2535 GNUNET_free (pos); 2497 GNUNET_free (pos);
2536 2498
2537 if (nl->received_pong == GNUNET_NO) 2499 if (nl->received_pong == GNUNET_NO)
2538 { 2500 {
2539 GNUNET_STATISTICS_update (stats, 2501 GNUNET_STATISTICS_update (stats,
2540 gettext_noop ("# disconnects due to NO pong"), 2502 gettext_noop ("# disconnects due to NO pong"),
2541 1, 2503 1, GNUNET_NO);
2542 GNUNET_NO); 2504 disconnect_neighbour (nl, GNUNET_YES);
2543 disconnect_neighbour (nl, GNUNET_YES); 2505 return; /* nothing to do, never connected... */
2544 return; /* nothing to do, never connected... */ 2506 }
2545 }
2546 /* check if we have any validated addresses left */ 2507 /* check if we have any validated addresses left */
2547 pos = rl->addresses; 2508 pos = rl->addresses;
2548 while (pos != NULL) 2509 while (pos != NULL)
2510 {
2511 if (GNUNET_YES == pos->validated)
2549 { 2512 {
2550 if (GNUNET_YES == pos->validated) 2513 GNUNET_STATISTICS_update (stats,
2551 { 2514 gettext_noop
2552 GNUNET_STATISTICS_update (stats, 2515 ("# try_fast_reconnect thanks to validated_address"),
2553 gettext_noop ("# try_fast_reconnect thanks to validated_address"), 2516 1, GNUNET_NO);
2554 1, 2517 try_fast_reconnect (p, nl);
2555 GNUNET_NO); 2518 return;
2556 try_fast_reconnect (p, nl);
2557 return;
2558 }
2559 pos = pos->next;
2560 } 2519 }
2520 pos = pos->next;
2521 }
2561 /* no valid addresses left, signal disconnect! */ 2522 /* no valid addresses left, signal disconnect! */
2562 2523
2563#if DEBUG_TRANSPORT 2524#if DEBUG_TRANSPORT
2564 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2525 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2565 "Disconnecting peer `%4s', %s\n", 2526 "Disconnecting peer `%4s', %s\n",
2566 GNUNET_i2s(peer), 2527 GNUNET_i2s (peer), "plugin_env_session_end");
2567 "plugin_env_session_end");
2568#endif 2528#endif
2569 /* FIXME: This doesn't mean there are no addresses left for this PEER, 2529 /* FIXME: This doesn't mean there are no addresses left for this PEER,
2570 * it means there aren't any left for this PLUGIN/PEER combination! So 2530 * it means there aren't any left for this PLUGIN/PEER combination! So
@@ -2574,8 +2534,8 @@ plugin_env_session_end (void *cls,
2574 * --NE 2534 * --NE
2575 */ 2535 */
2576 GNUNET_STATISTICS_update (stats, 2536 GNUNET_STATISTICS_update (stats,
2577 gettext_noop ("# disconnects due to plugin_env_session_end"), 2537 gettext_noop
2578 1, 2538 ("# disconnects due to plugin_env_session_end"), 1,
2579 GNUNET_NO); 2539 GNUNET_NO);
2580 disconnect_neighbour (nl, GNUNET_YES); 2540 disconnect_neighbour (nl, GNUNET_YES);
2581} 2541}
@@ -2594,9 +2554,7 @@ plugin_env_session_end (void *cls,
2594 */ 2554 */
2595static void 2555static void
2596plugin_env_notify_address (void *cls, 2556plugin_env_notify_address (void *cls,
2597 int add_remove, 2557 int add_remove, const void *addr, size_t addrlen)
2598 const void *addr,
2599 size_t addrlen)
2600{ 2558{
2601 struct TransportPlugin *p = cls; 2559 struct TransportPlugin *p = cls;
2602 struct OwnAddressList *al; 2560 struct OwnAddressList *al;
@@ -2605,37 +2563,34 @@ plugin_env_notify_address (void *cls,
2605 GNUNET_assert (p->api != NULL); 2563 GNUNET_assert (p->api != NULL);
2606#if DEBUG_TRANSPORT 2564#if DEBUG_TRANSPORT
2607 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2565 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2608 (add_remove == GNUNET_YES) 2566 (add_remove == GNUNET_YES)
2609 ? "Adding `%s':%s to the set of our addresses\n" 2567 ? "Adding `%s':%s to the set of our addresses\n"
2610 : "Removing `%s':%s from the set of our addresses\n", 2568 : "Removing `%s':%s from the set of our addresses\n",
2611 a2s (p->short_name, 2569 a2s (p->short_name, addr, addrlen), p->short_name);
2612 addr, addrlen),
2613 p->short_name);
2614#endif 2570#endif
2615 GNUNET_assert (addr != NULL); 2571 GNUNET_assert (addr != NULL);
2616 if (GNUNET_NO == add_remove) 2572 if (GNUNET_NO == add_remove)
2573 {
2574 prev = NULL;
2575 al = p->addresses;
2576 while (al != NULL)
2617 { 2577 {
2618 prev = NULL; 2578 if ((addrlen == al->addrlen) && (0 == memcmp (addr, &al[1], addrlen)))
2619 al = p->addresses; 2579 {
2620 while (al != NULL) 2580 if (prev == NULL)
2621 { 2581 p->addresses = al->next;
2622 if ( (addrlen == al->addrlen) && 2582 else
2623 (0 == memcmp (addr, &al[1], addrlen)) ) 2583 prev->next = al->next;
2624 { 2584 GNUNET_free (al);
2625 if (prev == NULL) 2585 refresh_hello ();
2626 p->addresses = al->next; 2586 return;
2627 else 2587 }
2628 prev->next = al->next; 2588 prev = al;
2629 GNUNET_free (al); 2589 al = al->next;
2630 refresh_hello ();
2631 return;
2632 }
2633 prev = al;
2634 al = al->next;
2635 }
2636 GNUNET_break (0);
2637 return;
2638 } 2590 }
2591 GNUNET_break (0);
2592 return;
2593 }
2639 al = GNUNET_malloc (sizeof (struct OwnAddressList) + addrlen); 2594 al = GNUNET_malloc (sizeof (struct OwnAddressList) + addrlen);
2640 al->next = p->addresses; 2595 al->next = p->addresses;
2641 p->addresses = al; 2596 p->addresses = al;
@@ -2650,38 +2605,35 @@ plugin_env_notify_address (void *cls,
2650 */ 2605 */
2651static void 2606static void
2652notify_clients_connect (const struct GNUNET_PeerIdentity *peer, 2607notify_clients_connect (const struct GNUNET_PeerIdentity *peer,
2653 struct GNUNET_TIME_Relative latency, 2608 struct GNUNET_TIME_Relative latency, uint32_t distance)
2654 uint32_t distance)
2655{ 2609{
2656 struct ConnectInfoMessage * cim; 2610 struct ConnectInfoMessage *cim;
2657 struct TransportClient *cpos; 2611 struct TransportClient *cpos;
2658 uint32_t ats_count; 2612 uint32_t ats_count;
2659 size_t size; 2613 size_t size;
2660 2614
2661 if (0 == memcmp (peer, 2615 if (0 == memcmp (peer, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
2662 &my_identity, 2616 {
2663 sizeof (struct GNUNET_PeerIdentity))) 2617 GNUNET_break (0);
2664 { 2618 return;
2665 GNUNET_break (0); 2619 }
2666 return;
2667 }
2668#if DEBUG_TRANSPORT 2620#if DEBUG_TRANSPORT
2669 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2621 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2670 "Notifying clients about connection with `%s'\n", 2622 "Notifying clients about connection with `%s'\n",
2671 GNUNET_i2s (peer)); 2623 GNUNET_i2s (peer));
2672#endif 2624#endif
2673 GNUNET_STATISTICS_update (stats, 2625 GNUNET_STATISTICS_update (stats,
2674 gettext_noop ("# peers connected"), 2626 gettext_noop ("# peers connected"), 1, GNUNET_NO);
2675 1,
2676 GNUNET_NO);
2677 2627
2678 ats_count = 2; 2628 ats_count = 2;
2679 size = sizeof (struct ConnectInfoMessage) + ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information); 2629 size =
2630 sizeof (struct ConnectInfoMessage) +
2631 ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
2680 GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE); 2632 GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE);
2681 cim = GNUNET_malloc (size); 2633 cim = GNUNET_malloc (size);
2682 cim->header.size = htons (size); 2634 cim->header.size = htons (size);
2683 cim->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT); 2635 cim->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
2684 cim->ats_count = htonl(2); 2636 cim->ats_count = htonl (2);
2685 (&cim->ats)[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE); 2637 (&cim->ats)[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
2686 (&cim->ats)[0].value = htonl (distance); 2638 (&cim->ats)[0].value = htonl (distance);
2687 (&cim->ats)[1].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY); 2639 (&cim->ats)[1].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY);
@@ -2692,18 +2644,18 @@ notify_clients_connect (const struct GNUNET_PeerIdentity *peer,
2692 2644
2693 /* notify ats about connecting peer */ 2645 /* notify ats about connecting peer */
2694 if ((ats != NULL) && (shutdown_in_progress == GNUNET_NO)) 2646 if ((ats != NULL) && (shutdown_in_progress == GNUNET_NO))
2695 { 2647 {
2696#if HAVE_LIBGLPK 2648#if HAVE_LIBGLPK
2697 ats_modify_problem_state(ats, ATS_MODIFIED); 2649 ats_modify_problem_state (ats, ATS_MODIFIED);
2698 ats_calculate_bandwidth_distribution (ats); 2650 ats_calculate_bandwidth_distribution (ats);
2699#endif 2651#endif
2700 } 2652 }
2701 cpos = clients; 2653 cpos = clients;
2702 while (cpos != NULL) 2654 while (cpos != NULL)
2703 { 2655 {
2704 transmit_to_client (cpos, &cim->header, GNUNET_NO); 2656 transmit_to_client (cpos, &cim->header, GNUNET_NO);
2705 cpos = cpos->next; 2657 cpos = cpos->next;
2706 } 2658 }
2707 GNUNET_free (cim); 2659 GNUNET_free (cim);
2708} 2660}
2709 2661
@@ -2717,22 +2669,18 @@ notify_clients_disconnect (const struct GNUNET_PeerIdentity *peer)
2717 struct DisconnectInfoMessage dim; 2669 struct DisconnectInfoMessage dim;
2718 struct TransportClient *cpos; 2670 struct TransportClient *cpos;
2719 2671
2720 if (0 == memcmp (peer, 2672 if (0 == memcmp (peer, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
2721 &my_identity, 2673 {
2722 sizeof (struct GNUNET_PeerIdentity))) 2674 GNUNET_break (0);
2723 { 2675 return;
2724 GNUNET_break (0); 2676 }
2725 return;
2726 }
2727#if DEBUG_TRANSPORT 2677#if DEBUG_TRANSPORT
2728 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2678 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2729 "Notifying clients about lost connection to `%s'\n", 2679 "Notifying clients about lost connection to `%s'\n",
2730 GNUNET_i2s (peer)); 2680 GNUNET_i2s (peer));
2731#endif 2681#endif
2732 GNUNET_STATISTICS_update (stats, 2682 GNUNET_STATISTICS_update (stats,
2733 gettext_noop ("# peers connected"), 2683 gettext_noop ("# peers connected"), -1, GNUNET_NO);
2734 -1,
2735 GNUNET_NO);
2736 dim.header.size = htons (sizeof (struct DisconnectInfoMessage)); 2684 dim.header.size = htons (sizeof (struct DisconnectInfoMessage));
2737 dim.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT); 2685 dim.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT);
2738 dim.reserved = htonl (0); 2686 dim.reserved = htonl (0);
@@ -2742,17 +2690,17 @@ notify_clients_disconnect (const struct GNUNET_PeerIdentity *peer)
2742 if ((ats != NULL) && (shutdown_in_progress == GNUNET_NO)) 2690 if ((ats != NULL) && (shutdown_in_progress == GNUNET_NO))
2743 { 2691 {
2744#if HAVE_LIBGLPK 2692#if HAVE_LIBGLPK
2745 ats_modify_problem_state(ats, ATS_MODIFIED); 2693 ats_modify_problem_state (ats, ATS_MODIFIED);
2746 ats_calculate_bandwidth_distribution (ats); 2694 ats_calculate_bandwidth_distribution (ats);
2747#endif 2695#endif
2748 } 2696 }
2749 2697
2750 cpos = clients; 2698 cpos = clients;
2751 while (cpos != NULL) 2699 while (cpos != NULL)
2752 { 2700 {
2753 transmit_to_client (cpos, &dim.header, GNUNET_NO); 2701 transmit_to_client (cpos, &dim.header, GNUNET_NO);
2754 cpos = cpos->next; 2702 cpos = cpos->next;
2755 } 2703 }
2756} 2704}
2757 2705
2758 2706
@@ -2770,36 +2718,33 @@ notify_clients_disconnect (const struct GNUNET_PeerIdentity *peer)
2770 * @return NULL if no such entry exists 2718 * @return NULL if no such entry exists
2771 */ 2719 */
2772static struct ForeignAddressList * 2720static struct ForeignAddressList *
2773find_peer_address(struct NeighbourMapEntry *neighbour, 2721find_peer_address (struct NeighbourMapEntry *neighbour,
2774 const char *tname, 2722 const char *tname,
2775 struct Session *session, 2723 struct Session *session, const char *addr, uint16_t addrlen)
2776 const char *addr,
2777 uint16_t addrlen)
2778{ 2724{
2779 struct ReadyList *head; 2725 struct ReadyList *head;
2780 struct ForeignAddressList *pos; 2726 struct ForeignAddressList *pos;
2781 2727
2782 head = neighbour->plugins; 2728 head = neighbour->plugins;
2783 while (head != NULL) 2729 while (head != NULL)
2784 { 2730 {
2785 if (0 == strcmp (tname, head->plugin->short_name)) 2731 if (0 == strcmp (tname, head->plugin->short_name))
2786 break; 2732 break;
2787 head = head->next; 2733 head = head->next;
2788 } 2734 }
2789 if (head == NULL) 2735 if (head == NULL)
2790 return NULL; 2736 return NULL;
2791 pos = head->addresses; 2737 pos = head->addresses;
2792 while ( (pos != NULL) && 2738 while ((pos != NULL) &&
2793 ( (pos->addrlen != addrlen) || 2739 ((pos->addrlen != addrlen) ||
2794 (memcmp(pos->addr, addr, addrlen) != 0) ) ) 2740 (memcmp (pos->addr, addr, addrlen) != 0)))
2795 { 2741 {
2796 if ( (session != NULL) && 2742 if ((session != NULL) && (pos->session == session))
2797 (pos->session == session) ) 2743 return pos;
2798 return pos; 2744 pos = pos->next;
2799 pos = pos->next; 2745 }
2800 } 2746 if ((session != NULL) && (pos != NULL))
2801 if ( (session != NULL) && (pos != NULL) ) 2747 pos->session = session; /* learn it! */
2802 pos->session = session; /* learn it! */
2803 return pos; 2748 return pos;
2804} 2749}
2805 2750
@@ -2817,10 +2762,8 @@ find_peer_address(struct NeighbourMapEntry *neighbour,
2817 */ 2762 */
2818static struct ForeignAddressList * 2763static struct ForeignAddressList *
2819add_peer_address (struct NeighbourMapEntry *neighbour, 2764add_peer_address (struct NeighbourMapEntry *neighbour,
2820 const char *tname, 2765 const char *tname,
2821 struct Session *session, 2766 struct Session *session, const char *addr, uint16_t addrlen)
2822 const char *addr,
2823 uint16_t addrlen)
2824{ 2767{
2825 struct ReadyList *head; 2768 struct ReadyList *head;
2826 struct ForeignAddressList *ret; 2769 struct ForeignAddressList *ret;
@@ -2832,73 +2775,78 @@ add_peer_address (struct NeighbourMapEntry *neighbour,
2832 head = neighbour->plugins; 2775 head = neighbour->plugins;
2833 2776
2834 while (head != NULL) 2777 while (head != NULL)
2835 { 2778 {
2836 if (0 == strcmp (tname, head->plugin->short_name)) 2779 if (0 == strcmp (tname, head->plugin->short_name))
2837 break; 2780 break;
2838 head = head->next; 2781 head = head->next;
2839 } 2782 }
2840 if (head == NULL) 2783 if (head == NULL)
2841 return NULL; 2784 return NULL;
2842 ret = GNUNET_malloc(sizeof(struct ForeignAddressList) + addrlen); 2785 ret = GNUNET_malloc (sizeof (struct ForeignAddressList) + addrlen);
2843 ret->session = session; 2786 ret->session = session;
2844 if ((addrlen > 0) && (addr != NULL)) 2787 if ((addrlen > 0) && (addr != NULL))
2788 {
2789 ret->addr = (const char *) &ret[1];
2790 memcpy (&ret[1], addr, addrlen);
2791 }
2792 else
2793 {
2794 ret->addr = NULL;
2795 }
2796
2797 ret->ressources =
2798 GNUNET_malloc (available_ressources *
2799 sizeof (struct ATS_ressource_entry));
2800 for (c = 0; c < available_ressources; c++)
2801 {
2802 struct ATS_ressource_entry *r = ret->ressources;
2803
2804 r[c].index = c;
2805 r[c].atis_index = ressources[c].atis_index;
2806 if (0 == strcmp (neighbour->plugins->plugin->short_name, "unix"))
2845 { 2807 {
2846 ret->addr = (const char*) &ret[1]; 2808 r[c].c = ressources[c].c_unix;
2847 memcpy (&ret[1], addr, addrlen);
2848 } 2809 }
2849 else 2810 else if (0 == strcmp (neighbour->plugins->plugin->short_name, "udp"))
2850 { 2811 {
2851 ret->addr = NULL; 2812 r[c].c = ressources[c].c_udp;
2852 } 2813 }
2853 2814 else if (0 == strcmp (neighbour->plugins->plugin->short_name, "tcp"))
2854 ret->ressources = GNUNET_malloc(available_ressources * sizeof (struct ATS_ressource_entry));
2855 for (c=0; c<available_ressources; c++)
2856 { 2815 {
2857 struct ATS_ressource_entry *r = ret->ressources; 2816 r[c].c = ressources[c].c_tcp;
2858 r[c].index = c; 2817 }
2859 r[c].atis_index = ressources[c].atis_index; 2818 else if (0 == strcmp (neighbour->plugins->plugin->short_name, "http"))
2860 if (0 == strcmp(neighbour->plugins->plugin->short_name,"unix")) 2819 {
2861 { 2820 r[c].c = ressources[c].c_http;
2862 r[c].c = ressources[c].c_unix; 2821 }
2863 } 2822 else if (0 == strcmp (neighbour->plugins->plugin->short_name, "https"))
2864 else if (0 == strcmp(neighbour->plugins->plugin->short_name,"udp")) 2823 {
2865 { 2824 r[c].c = ressources[c].c_https;
2866 r[c].c = ressources[c].c_udp;
2867 }
2868 else if (0 == strcmp(neighbour->plugins->plugin->short_name,"tcp"))
2869 {
2870 r[c].c = ressources[c].c_tcp;
2871 }
2872 else if (0 == strcmp(neighbour->plugins->plugin->short_name,"http"))
2873 {
2874 r[c].c = ressources[c].c_http;
2875 }
2876 else if (0 == strcmp(neighbour->plugins->plugin->short_name,"https"))
2877 {
2878 r[c].c = ressources[c].c_https;
2879 }
2880 else if (0 == strcmp(neighbour->plugins->plugin->short_name,"wlan"))
2881 {
2882 r[c].c = ressources[c].c_wlan;
2883 }
2884 else
2885 {
2886 r[c].c = ressources[c].c_default;
2887 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2888 "Assigning default cost to peer `%s' addr plugin `%s'! This should not happen!\n",
2889 GNUNET_i2s(&neighbour->id),
2890 neighbour->plugins->plugin->short_name);
2891 }
2892 } 2825 }
2826 else if (0 == strcmp (neighbour->plugins->plugin->short_name, "wlan"))
2827 {
2828 r[c].c = ressources[c].c_wlan;
2829 }
2830 else
2831 {
2832 r[c].c = ressources[c].c_default;
2833 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2834 "Assigning default cost to peer `%s' addr plugin `%s'! This should not happen!\n",
2835 GNUNET_i2s (&neighbour->id),
2836 neighbour->plugins->plugin->short_name);
2837 }
2838 }
2893 2839
2894 ret->quality = GNUNET_malloc (available_quality_metrics * sizeof (struct ATS_quality_entry)); 2840 ret->quality =
2841 GNUNET_malloc (available_quality_metrics *
2842 sizeof (struct ATS_quality_entry));
2895 ret->addrlen = addrlen; 2843 ret->addrlen = addrlen;
2896 ret->expires = GNUNET_TIME_relative_to_absolute 2844 ret->expires = GNUNET_TIME_relative_to_absolute
2897 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); 2845 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
2898 ret->latency = GNUNET_TIME_relative_get_forever(); 2846 ret->latency = GNUNET_TIME_relative_get_forever ();
2899 ret->distance = -1; 2847 ret->distance = -1;
2900 ret->timeout = GNUNET_TIME_relative_to_absolute 2848 ret->timeout = GNUNET_TIME_relative_to_absolute
2901 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); 2849 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
2902 ret->ready_list = head; 2850 ret->ready_list = head;
2903 ret->next = head->addresses; 2851 ret->next = head->addresses;
2904 head->addresses = ret; 2852 head->addresses = ret;
@@ -2936,8 +2884,7 @@ struct AddValidatedAddressContext
2936 * end of the iteration. 2884 * end of the iteration.
2937 */ 2885 */
2938static size_t 2886static size_t
2939add_validated_address (void *cls, 2887add_validated_address (void *cls, size_t max, void *buf)
2940 size_t max, void *buf)
2941{ 2888{
2942 struct AddValidatedAddressContext *avac = cls; 2889 struct AddValidatedAddressContext *avac = cls;
2943 const struct ValidationEntry *ve = avac->ve; 2890 const struct ValidationEntry *ve = avac->ve;
@@ -2946,11 +2893,9 @@ add_validated_address (void *cls,
2946 return 0; 2893 return 0;
2947 avac->done = GNUNET_YES; 2894 avac->done = GNUNET_YES;
2948 return GNUNET_HELLO_add_address (ve->transport_name, 2895 return GNUNET_HELLO_add_address (ve->transport_name,
2949 GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION), 2896 GNUNET_TIME_relative_to_absolute
2950 ve->addr, 2897 (HELLO_ADDRESS_EXPIRATION), ve->addr,
2951 ve->addrlen, 2898 ve->addrlen, buf, max);
2952 buf,
2953 max);
2954} 2899}
2955 2900
2956 2901
@@ -3000,36 +2945,31 @@ struct CheckAddressExistsClosure
3000 * iterate (mismatch), GNUNET_NO if not (entry matched) 2945 * iterate (mismatch), GNUNET_NO if not (entry matched)
3001 */ 2946 */
3002static int 2947static int
3003check_address_exists (void *cls, 2948check_address_exists (void *cls, const GNUNET_HashCode * key, void *value)
3004 const GNUNET_HashCode * key,
3005 void *value)
3006{ 2949{
3007 struct CheckAddressExistsClosure *caec = cls; 2950 struct CheckAddressExistsClosure *caec = cls;
3008 struct ValidationEntry *ve = value; 2951 struct ValidationEntry *ve = value;
3009 2952
3010 if ( (0 == strcmp (caec->tname, 2953 if ((0 == strcmp (caec->tname,
3011 ve->transport_name)) && 2954 ve->transport_name)) &&
3012 (caec->addrlen == ve->addrlen) && 2955 (caec->addrlen == ve->addrlen) &&
3013 (0 == memcmp (caec->addr, 2956 (0 == memcmp (caec->addr, ve->addr, caec->addrlen)))
3014 ve->addr, 2957 {
3015 caec->addrlen)) ) 2958 caec->exists = GNUNET_YES;
3016 { 2959 return GNUNET_NO;
3017 caec->exists = GNUNET_YES; 2960 }
3018 return GNUNET_NO; 2961 if ((ve->session != NULL) && (caec->session == ve->session))
3019 } 2962 {
3020 if ( (ve->session != NULL) && 2963 caec->exists = GNUNET_YES;
3021 (caec->session == ve->session) ) 2964 return GNUNET_NO;
3022 { 2965 }
3023 caec->exists = GNUNET_YES;
3024 return GNUNET_NO;
3025 }
3026 return GNUNET_YES; 2966 return GNUNET_YES;
3027} 2967}
3028 2968
3029 2969
3030static void 2970static void
3031neighbour_timeout_task (void *cls, 2971neighbour_timeout_task (void *cls,
3032 const struct GNUNET_SCHEDULER_TaskContext *tc) 2972 const struct GNUNET_SCHEDULER_TaskContext *tc)
3033{ 2973{
3034 struct NeighbourMapEntry *n = cls; 2974 struct NeighbourMapEntry *n = cls;
3035 2975
@@ -3038,9 +2978,8 @@ neighbour_timeout_task (void *cls,
3038 "Neighbour `%4s' has timed out!\n", GNUNET_i2s (&n->id)); 2978 "Neighbour `%4s' has timed out!\n", GNUNET_i2s (&n->id));
3039#endif 2979#endif
3040 GNUNET_STATISTICS_update (stats, 2980 GNUNET_STATISTICS_update (stats,
3041 gettext_noop ("# disconnects due to timeout"), 2981 gettext_noop ("# disconnects due to timeout"),
3042 1, 2982 1, GNUNET_NO);
3043 GNUNET_NO);
3044 n->timeout_task = GNUNET_SCHEDULER_NO_TASK; 2983 n->timeout_task = GNUNET_SCHEDULER_NO_TASK;
3045 disconnect_neighbour (n, GNUNET_NO); 2984 disconnect_neighbour (n, GNUNET_NO);
3046} 2985}
@@ -3052,8 +2991,7 @@ neighbour_timeout_task (void *cls,
3052 * 2991 *
3053 * @param fal address to PING 2992 * @param fal address to PING
3054 */ 2993 */
3055static void 2994static void schedule_next_ping (struct ForeignAddressList *fal);
3056schedule_next_ping (struct ForeignAddressList *fal);
3057 2995
3058 2996
3059/** 2997/**
@@ -3069,77 +3007,71 @@ schedule_next_ping (struct ForeignAddressList *fal);
3069 */ 3007 */
3070static int 3008static int
3071add_to_foreign_address_list (void *cls, 3009add_to_foreign_address_list (void *cls,
3072 const char *tname, 3010 const char *tname,
3073 struct GNUNET_TIME_Absolute expiration, 3011 struct GNUNET_TIME_Absolute expiration,
3074 const void *addr, 3012 const void *addr, uint16_t addrlen)
3075 uint16_t addrlen)
3076{ 3013{
3077 struct NeighbourMapEntry *n = cls; 3014 struct NeighbourMapEntry *n = cls;
3078 struct ForeignAddressList *fal; 3015 struct ForeignAddressList *fal;
3079 int try; 3016 int try;
3080 3017
3081 GNUNET_STATISTICS_update (stats, 3018 GNUNET_STATISTICS_update (stats,
3082 gettext_noop ("# valid peer addresses returned by PEERINFO"), 3019 gettext_noop
3083 1, 3020 ("# valid peer addresses returned by PEERINFO"), 1,
3084 GNUNET_NO); 3021 GNUNET_NO);
3085 try = GNUNET_NO; 3022 try = GNUNET_NO;
3086 fal = find_peer_address (n, tname, NULL, addr, addrlen); 3023 fal = find_peer_address (n, tname, NULL, addr, addrlen);
3087 if (fal == NULL) 3024 if (fal == NULL)
3088 { 3025 {
3089#if DEBUG_TRANSPORT_HELLO 3026#if DEBUG_TRANSPORT_HELLO
3090 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3027 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3091 "Adding address `%s' (%s) for peer `%4s' due to PEERINFO data for %llums.\n", 3028 "Adding address `%s' (%s) for peer `%4s' due to PEERINFO data for %llums.\n",
3092 a2s (tname, addr, addrlen), 3029 a2s (tname, addr, addrlen),
3093 tname, 3030 tname, GNUNET_i2s (&n->id), expiration.abs_value);
3094 GNUNET_i2s (&n->id),
3095 expiration.abs_value);
3096#endif 3031#endif
3097 fal = add_peer_address (n, tname, NULL, addr, addrlen); 3032 fal = add_peer_address (n, tname, NULL, addr, addrlen);
3098 if (fal == NULL) 3033 if (fal == NULL)
3099 { 3034 {
3100 GNUNET_STATISTICS_update (stats, 3035 GNUNET_STATISTICS_update (stats,
3101 gettext_noop ("# previously validated addresses lacking transport"), 3036 gettext_noop
3102 1, 3037 ("# previously validated addresses lacking transport"),
3103 GNUNET_NO); 3038 1, GNUNET_NO);
3104 }
3105 else
3106 {
3107 fal->expires = GNUNET_TIME_absolute_max (expiration,
3108 fal->expires);
3109 schedule_next_ping (fal);
3110 }
3111 try = GNUNET_YES;
3112 } 3039 }
3113 else 3040 else
3114 { 3041 {
3115 fal->expires = GNUNET_TIME_absolute_max (expiration, 3042 fal->expires = GNUNET_TIME_absolute_max (expiration, fal->expires);
3116 fal->expires); 3043 schedule_next_ping (fal);
3117 } 3044 }
3045 try = GNUNET_YES;
3046 }
3047 else
3048 {
3049 fal->expires = GNUNET_TIME_absolute_max (expiration, fal->expires);
3050 }
3118 if (fal == NULL) 3051 if (fal == NULL)
3119 { 3052 {
3120#if DEBUG_TRANSPORT 3053#if DEBUG_TRANSPORT
3121 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3054 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3122 "Failed to add new address for `%4s'\n", 3055 "Failed to add new address for `%4s'\n", GNUNET_i2s (&n->id));
3123 GNUNET_i2s (&n->id));
3124#endif 3056#endif
3125 return GNUNET_OK; 3057 return GNUNET_OK;
3126 } 3058 }
3127 if (fal->validated == GNUNET_NO) 3059 if (fal->validated == GNUNET_NO)
3128 { 3060 {
3129 fal->validated = GNUNET_YES; 3061 fal->validated = GNUNET_YES;
3130 GNUNET_STATISTICS_update (stats, 3062 GNUNET_STATISTICS_update (stats,
3131 gettext_noop ("# peer addresses considered valid"), 3063 gettext_noop
3132 1, 3064 ("# peer addresses considered valid"), 1,
3133 GNUNET_NO); 3065 GNUNET_NO);
3134 } 3066 }
3135 if (try == GNUNET_YES) 3067 if (try == GNUNET_YES)
3136 { 3068 {
3137#if DEBUG_TRANSPORT 3069#if DEBUG_TRANSPORT
3138 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3070 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3139 "Have new addresses, will try to trigger transmissions.\n"); 3071 "Have new addresses, will try to trigger transmissions.\n");
3140#endif 3072#endif
3141 try_transmission_to_peer (n); 3073 try_transmission_to_peer (n);
3142 } 3074 }
3143 return GNUNET_OK; 3075 return GNUNET_OK;
3144} 3076}
3145 3077
@@ -3155,47 +3087,43 @@ add_to_foreign_address_list (void *cls,
3155 */ 3087 */
3156static void 3088static void
3157add_hello_for_peer (void *cls, 3089add_hello_for_peer (void *cls,
3158 const struct GNUNET_PeerIdentity *peer, 3090 const struct GNUNET_PeerIdentity *peer,
3159 const struct GNUNET_HELLO_Message *h, 3091 const struct GNUNET_HELLO_Message *h, const char *err_msg)
3160 const char *err_msg)
3161{ 3092{
3162 struct NeighbourMapEntry *n = cls; 3093 struct NeighbourMapEntry *n = cls;
3163 3094
3164 if (err_msg != NULL) 3095 if (err_msg != NULL)
3165 { 3096 {
3166#if DEBUG_TRANSPORT 3097#if DEBUG_TRANSPORT
3167 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3098 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3168 _("Error in communication with PEERINFO service: %s\n"), 3099 _("Error in communication with PEERINFO service: %s\n"),
3169 err_msg); 3100 err_msg);
3170#endif 3101#endif
3171 /* return; */ 3102 /* return; */
3172 } 3103 }
3173 if (peer == NULL) 3104 if (peer == NULL)
3174 { 3105 {
3175 GNUNET_STATISTICS_update (stats, 3106 GNUNET_STATISTICS_update (stats,
3176 gettext_noop ("# outstanding peerinfo iterate requests"), 3107 gettext_noop
3177 -1, 3108 ("# outstanding peerinfo iterate requests"), -1,
3178 GNUNET_NO); 3109 GNUNET_NO);
3179 n->piter = NULL; 3110 n->piter = NULL;
3180 return; 3111 return;
3181 } 3112 }
3182 if (h == NULL) 3113 if (h == NULL)
3183 return; /* no HELLO available */ 3114 return; /* no HELLO available */
3184#if DEBUG_TRANSPORT 3115#if DEBUG_TRANSPORT
3185 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3116 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3186 "Peerinfo had `%s' message for peer `%4s', adding existing addresses.\n", 3117 "Peerinfo had `%s' message for peer `%4s', adding existing addresses.\n",
3187 "HELLO", 3118 "HELLO", GNUNET_i2s (peer));
3188 GNUNET_i2s (peer));
3189#endif 3119#endif
3190 if (GNUNET_YES != n->public_key_valid) 3120 if (GNUNET_YES != n->public_key_valid)
3191 { 3121 {
3192 GNUNET_HELLO_get_key (h, &n->publicKey); 3122 GNUNET_HELLO_get_key (h, &n->publicKey);
3193 n->public_key_valid = GNUNET_YES; 3123 n->public_key_valid = GNUNET_YES;
3194 } 3124 }
3195 GNUNET_HELLO_iterate_addresses (h, 3125 GNUNET_HELLO_iterate_addresses (h,
3196 GNUNET_NO, 3126 GNUNET_NO, &add_to_foreign_address_list, n);
3197 &add_to_foreign_address_list,
3198 n);
3199} 3127}
3200 3128
3201 3129
@@ -3209,79 +3137,73 @@ add_hello_for_peer (void *cls,
3209 * @return the new neighbour list entry 3137 * @return the new neighbour list entry
3210 */ 3138 */
3211static struct NeighbourMapEntry * 3139static struct NeighbourMapEntry *
3212setup_new_neighbour (const struct GNUNET_PeerIdentity *peer, 3140setup_new_neighbour (const struct GNUNET_PeerIdentity *peer, int do_hello)
3213 int do_hello)
3214{ 3141{
3215 struct NeighbourMapEntry *n; 3142 struct NeighbourMapEntry *n;
3216 struct TransportPlugin *tp; 3143 struct TransportPlugin *tp;
3217 struct ReadyList *rl; 3144 struct ReadyList *rl;
3218 3145
3219 GNUNET_assert (0 != memcmp (peer, 3146 GNUNET_assert (0 != memcmp (peer,
3220 &my_identity, 3147 &my_identity,
3221 sizeof (struct GNUNET_PeerIdentity))); 3148 sizeof (struct GNUNET_PeerIdentity)));
3222#if DEBUG_TRANSPORT 3149#if DEBUG_TRANSPORT
3223 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3150 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3224 "Setting up state for neighbour `%4s'\n", 3151 "Setting up state for neighbour `%4s'\n", GNUNET_i2s (peer));
3225 GNUNET_i2s (peer));
3226#endif 3152#endif
3227 GNUNET_STATISTICS_update (stats, 3153 GNUNET_STATISTICS_update (stats,
3228 gettext_noop ("# active neighbours"), 3154 gettext_noop ("# active neighbours"), 1, GNUNET_NO);
3229 1,
3230 GNUNET_NO);
3231 n = GNUNET_malloc (sizeof (struct NeighbourMapEntry)); 3155 n = GNUNET_malloc (sizeof (struct NeighbourMapEntry));
3232 n->id = *peer; 3156 n->id = *peer;
3233 n->peer_timeout = 3157 n->peer_timeout =
3234 GNUNET_TIME_relative_to_absolute 3158 GNUNET_TIME_relative_to_absolute
3235 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); 3159 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
3236 GNUNET_BANDWIDTH_tracker_init (&n->in_tracker, 3160 GNUNET_BANDWIDTH_tracker_init (&n->in_tracker,
3237 GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT, 3161 GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT,
3238 MAX_BANDWIDTH_CARRY_S); 3162 MAX_BANDWIDTH_CARRY_S);
3239 tp = plugins; 3163 tp = plugins;
3240 while (tp != NULL) 3164 while (tp != NULL)
3165 {
3166 if ((tp->api->send != NULL) && (!is_blacklisted (peer, tp)))
3241 { 3167 {
3242 if ((tp->api->send != NULL) && (!is_blacklisted(peer, tp))) 3168 rl = GNUNET_malloc (sizeof (struct ReadyList));
3243 { 3169 rl->neighbour = n;
3244 rl = GNUNET_malloc (sizeof (struct ReadyList)); 3170 rl->next = n->plugins;
3245 rl->neighbour = n; 3171 n->plugins = rl;
3246 rl->next = n->plugins; 3172 rl->plugin = tp;
3247 n->plugins = rl; 3173 rl->addresses = NULL;
3248 rl->plugin = tp;
3249 rl->addresses = NULL;
3250 }
3251 tp = tp->next;
3252 } 3174 }
3175 tp = tp->next;
3176 }
3253 n->latency = GNUNET_TIME_UNIT_FOREVER_REL; 3177 n->latency = GNUNET_TIME_UNIT_FOREVER_REL;
3254 n->distance = -1; 3178 n->distance = -1;
3255 n->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 3179 n->timeout_task =
3256 &neighbour_timeout_task, n); 3180 GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
3257 GNUNET_CONTAINER_multihashmap_put (neighbours, 3181 &neighbour_timeout_task, n);
3258 &n->id.hashPubKey, 3182 GNUNET_CONTAINER_multihashmap_put (neighbours, &n->id.hashPubKey, n,
3259 n, 3183 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
3260 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
3261 if (do_hello) 3184 if (do_hello)
3262 { 3185 {
3263 GNUNET_STATISTICS_update (stats, 3186 GNUNET_STATISTICS_update (stats,
3264 gettext_noop ("# peerinfo new neighbor iterate requests"), 3187 gettext_noop
3265 1, 3188 ("# peerinfo new neighbor iterate requests"), 1,
3266 GNUNET_NO); 3189 GNUNET_NO);
3267 GNUNET_STATISTICS_update (stats, 3190 GNUNET_STATISTICS_update (stats,
3268 gettext_noop ("# outstanding peerinfo iterate requests"), 3191 gettext_noop
3269 1, 3192 ("# outstanding peerinfo iterate requests"), 1,
3270 GNUNET_NO); 3193 GNUNET_NO);
3271 n->piter = GNUNET_PEERINFO_iterate (peerinfo, peer, 3194 n->piter =
3272 GNUNET_TIME_UNIT_FOREVER_REL, 3195 GNUNET_PEERINFO_iterate (peerinfo, peer, GNUNET_TIME_UNIT_FOREVER_REL,
3273 &add_hello_for_peer, n); 3196 &add_hello_for_peer, n);
3274 3197
3275 GNUNET_STATISTICS_update (stats, 3198 GNUNET_STATISTICS_update (stats,
3276 gettext_noop ("# HELLO's sent to new neighbors"), 3199 gettext_noop ("# HELLO's sent to new neighbors"),
3277 1, 3200 1, GNUNET_NO);
3278 GNUNET_NO); 3201 if (NULL != our_hello)
3279 if (NULL != our_hello) 3202 transmit_to_peer (NULL, NULL, 0,
3280 transmit_to_peer (NULL, NULL, 0, 3203 HELLO_ADDRESS_EXPIRATION,
3281 HELLO_ADDRESS_EXPIRATION, 3204 (const char *) our_hello, GNUNET_HELLO_size (our_hello),
3282 (const char *) our_hello, GNUNET_HELLO_size(our_hello), 3205 GNUNET_NO, n);
3283 GNUNET_NO, n); 3206 }
3284 }
3285 return n; 3207 return n;
3286} 3208}
3287 3209
@@ -3293,8 +3215,7 @@ setup_new_neighbour (const struct GNUNET_PeerIdentity *peer,
3293 * @param cls closure 3215 * @param cls closure
3294 * @param n NULL if communication is not acceptable 3216 * @param n NULL if communication is not acceptable
3295 */ 3217 */
3296typedef void (*SetupContinuation)(void *cls, 3218typedef void (*SetupContinuation) (void *cls, struct NeighbourMapEntry * n);
3297 struct NeighbourMapEntry *n);
3298 3219
3299 3220
3300/** 3221/**
@@ -3409,8 +3330,7 @@ static struct BlacklistCheck *bc_tail;
3409 * @param tc unused 3330 * @param tc unused
3410 */ 3331 */
3411static void 3332static void
3412do_blacklist_check (void *cls, 3333do_blacklist_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
3413 const struct GNUNET_SCHEDULER_TaskContext *tc);
3414 3334
3415/** 3335/**
3416 * Transmit blacklist query to the client. 3336 * Transmit blacklist query to the client.
@@ -3421,9 +3341,7 @@ do_blacklist_check (void *cls,
3421 * @return number of bytes copied to buf 3341 * @return number of bytes copied to buf
3422 */ 3342 */
3423static size_t 3343static size_t
3424transmit_blacklist_message (void *cls, 3344transmit_blacklist_message (void *cls, size_t size, void *buf)
3425 size_t size,
3426 void *buf)
3427{ 3345{
3428 struct BlacklistCheck *bc = cls; 3346 struct BlacklistCheck *bc = cls;
3429 struct Blacklisters *bl; 3347 struct Blacklisters *bl;
@@ -3431,19 +3349,18 @@ transmit_blacklist_message (void *cls,
3431 3349
3432 bc->th = NULL; 3350 bc->th = NULL;
3433 if (size == 0) 3351 if (size == 0)
3434 { 3352 {
3435 GNUNET_assert (bc->task == GNUNET_SCHEDULER_NO_TASK); 3353 GNUNET_assert (bc->task == GNUNET_SCHEDULER_NO_TASK);
3436 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, 3354 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc);
3437 bc); 3355 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3438 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 3356 "Failed to send blacklist test for peer `%s' to client\n",
3439 "Failed to send blacklist test for peer `%s' to client\n", 3357 GNUNET_i2s (&bc->peer));
3440 GNUNET_i2s (&bc->peer)); 3358 return 0;
3441 return 0; 3359 }
3442 }
3443#if DEBUG_TRANSPORT 3360#if DEBUG_TRANSPORT
3444 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3361 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3445 "Sending blacklist test for peer `%s' to client\n", 3362 "Sending blacklist test for peer `%s' to client\n",
3446 GNUNET_i2s (&bc->peer)); 3363 GNUNET_i2s (&bc->peer));
3447#endif 3364#endif
3448 bl = bc->bl_pos; 3365 bl = bc->bl_pos;
3449 bm.header.size = htons (sizeof (struct BlacklistMessage)); 3366 bm.header.size = htons (sizeof (struct BlacklistMessage));
@@ -3463,8 +3380,7 @@ transmit_blacklist_message (void *cls,
3463 * @param tc unused 3380 * @param tc unused
3464 */ 3381 */
3465static void 3382static void
3466do_blacklist_check (void *cls, 3383do_blacklist_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3467 const struct GNUNET_SCHEDULER_TaskContext *tc)
3468{ 3384{
3469 struct BlacklistCheck *bc = cls; 3385 struct BlacklistCheck *bc = cls;
3470 struct Blacklisters *bl; 3386 struct Blacklisters *bl;
@@ -3472,26 +3388,26 @@ do_blacklist_check (void *cls,
3472 bc->task = GNUNET_SCHEDULER_NO_TASK; 3388 bc->task = GNUNET_SCHEDULER_NO_TASK;
3473 bl = bc->bl_pos; 3389 bl = bc->bl_pos;
3474 if (bl == NULL) 3390 if (bl == NULL)
3475 { 3391 {
3476#if DEBUG_TRANSPORT 3392#if DEBUG_TRANSPORT
3477 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3393 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3478 "No blacklist clients active, will now setup neighbour record for peer `%s'\n", 3394 "No blacklist clients active, will now setup neighbour record for peer `%s'\n",
3479 GNUNET_i2s (&bc->peer)); 3395 GNUNET_i2s (&bc->peer));
3480#endif 3396#endif
3481 bc->cont (bc->cont_cls, 3397 bc->cont (bc->cont_cls, setup_new_neighbour (&bc->peer, bc->do_hello));
3482 setup_new_neighbour (&bc->peer, bc->do_hello)); 3398 GNUNET_free (bc);
3483 GNUNET_free (bc); 3399 return;
3484 return; 3400 }
3485 }
3486 if (bl->bc == NULL) 3401 if (bl->bc == NULL)
3487 { 3402 {
3488 bl->bc = bc; 3403 bl->bc = bc;
3489 bc->th = GNUNET_SERVER_notify_transmit_ready (bl->client, 3404 bc->th = GNUNET_SERVER_notify_transmit_ready (bl->client,
3490 sizeof (struct BlacklistMessage), 3405 sizeof (struct
3491 GNUNET_TIME_UNIT_FOREVER_REL, 3406 BlacklistMessage),
3492 &transmit_blacklist_message, 3407 GNUNET_TIME_UNIT_FOREVER_REL,
3493 bc); 3408 &transmit_blacklist_message,
3494 } 3409 bc);
3410 }
3495} 3411}
3496 3412
3497 3413
@@ -3509,33 +3425,31 @@ do_blacklist_check (void *cls,
3509 */ 3425 */
3510static void 3426static void
3511setup_peer_check_blacklist (const struct GNUNET_PeerIdentity *peer, 3427setup_peer_check_blacklist (const struct GNUNET_PeerIdentity *peer,
3512 int do_hello, 3428 int do_hello,
3513 SetupContinuation cont, 3429 SetupContinuation cont, void *cont_cls)
3514 void *cont_cls)
3515{ 3430{
3516 struct NeighbourMapEntry *n; 3431 struct NeighbourMapEntry *n;
3517 struct BlacklistCheck *bc; 3432 struct BlacklistCheck *bc;
3518 3433
3519 n = find_neighbour(peer); 3434 n = find_neighbour (peer);
3520 if (n != NULL) 3435 if (n != NULL)
3521 { 3436 {
3522#if DEBUG_TRANSPORT 3437#if DEBUG_TRANSPORT
3523 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 3438 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3524 "Neighbour record exists for peer `%s'\n", 3439 "Neighbour record exists for peer `%s'\n", GNUNET_i2s (peer));
3525 GNUNET_i2s(peer));
3526#endif 3440#endif
3527 if (cont != NULL) 3441 if (cont != NULL)
3528 cont (cont_cls, n); 3442 cont (cont_cls, n);
3529 return; 3443 return;
3530 } 3444 }
3531 if (bl_head == NULL) 3445 if (bl_head == NULL)
3532 { 3446 {
3533 if (cont != NULL) 3447 if (cont != NULL)
3534 cont (cont_cls, setup_new_neighbour (peer, do_hello)); 3448 cont (cont_cls, setup_new_neighbour (peer, do_hello));
3535 else 3449 else
3536 setup_new_neighbour(peer, do_hello); 3450 setup_new_neighbour (peer, do_hello);
3537 return; 3451 return;
3538 } 3452 }
3539 bc = GNUNET_malloc (sizeof (struct BlacklistCheck)); 3453 bc = GNUNET_malloc (sizeof (struct BlacklistCheck));
3540 GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, bc); 3454 GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, bc);
3541 bc->peer = *peer; 3455 bc->peer = *peer;
@@ -3543,8 +3457,7 @@ setup_peer_check_blacklist (const struct GNUNET_PeerIdentity *peer,
3543 bc->cont = cont; 3457 bc->cont = cont;
3544 bc->cont_cls = cont_cls; 3458 bc->cont_cls = cont_cls;
3545 bc->bl_pos = bl_head; 3459 bc->bl_pos = bl_head;
3546 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, 3460 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc);
3547 bc);
3548} 3461}
3549 3462
3550 3463
@@ -3556,24 +3469,22 @@ setup_peer_check_blacklist (const struct GNUNET_PeerIdentity *peer,
3556 * @param n NULL if we need to disconnect 3469 * @param n NULL if we need to disconnect
3557 */ 3470 */
3558static void 3471static void
3559confirm_or_drop_neighbour (void *cls, 3472confirm_or_drop_neighbour (void *cls, struct NeighbourMapEntry *n)
3560 struct NeighbourMapEntry *n)
3561{ 3473{
3562 struct NeighbourMapEntry * orig = cls; 3474 struct NeighbourMapEntry *orig = cls;
3563 3475
3564 if (n == NULL) 3476 if (n == NULL)
3565 { 3477 {
3566#if DEBUG_TRANSPORT 3478#if DEBUG_TRANSPORT
3567 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3479 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3568 "Disconnecting peer `%4s', %s\n", GNUNET_i2s(&orig->id), 3480 "Disconnecting peer `%4s', %s\n", GNUNET_i2s (&orig->id),
3569 "confirm_or_drop_neighboUr"); 3481 "confirm_or_drop_neighboUr");
3570#endif 3482#endif
3571 GNUNET_STATISTICS_update (stats, 3483 GNUNET_STATISTICS_update (stats,
3572 gettext_noop ("# disconnects due to blacklist"), 3484 gettext_noop ("# disconnects due to blacklist"),
3573 1, 3485 1, GNUNET_NO);
3574 GNUNET_NO); 3486 disconnect_neighbour (orig, GNUNET_NO);
3575 disconnect_neighbour (orig, GNUNET_NO); 3487 }
3576 }
3577} 3488}
3578 3489
3579 3490
@@ -3586,15 +3497,13 @@ struct TestConnectionContext
3586 3497
3587 3498
3588static int 3499static int
3589test_connection_ok (void *cls, 3500test_connection_ok (void *cls, const GNUNET_HashCode * key, void *value)
3590 const GNUNET_HashCode *key,
3591 void *value)
3592{ 3501{
3593 struct TestConnectionContext *tcc = cls; 3502 struct TestConnectionContext *tcc = cls;
3594 struct NeighbourMapEntry *n = value; 3503 struct NeighbourMapEntry *n = value;
3595 struct BlacklistCheck *bc; 3504 struct BlacklistCheck *bc;
3596 3505
3597 3506
3598 bc = GNUNET_malloc (sizeof (struct BlacklistCheck)); 3507 bc = GNUNET_malloc (sizeof (struct BlacklistCheck));
3599 GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, bc); 3508 GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, bc);
3600 bc->peer = n->id; 3509 bc->peer = n->id;
@@ -3603,13 +3512,12 @@ test_connection_ok (void *cls,
3603 bc->cont_cls = n; 3512 bc->cont_cls = n;
3604 bc->bl_pos = tcc->bl; 3513 bc->bl_pos = tcc->bl;
3605 if (GNUNET_YES == tcc->first) 3514 if (GNUNET_YES == tcc->first)
3606 { 3515 {
3607 /* all would wait for the same client, no need to 3516 /* all would wait for the same client, no need to
3608 create more than just the first task right now */ 3517 * create more than just the first task right now */
3609 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, 3518 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc);
3610 bc); 3519 tcc->first = GNUNET_NO;
3611 tcc->first = GNUNET_NO; 3520 }
3612 }
3613 return GNUNET_OK; 3521 return GNUNET_OK;
3614} 3522}
3615 3523
@@ -3623,23 +3531,23 @@ test_connection_ok (void *cls,
3623 */ 3531 */
3624static void 3532static void
3625handle_blacklist_init (void *cls, 3533handle_blacklist_init (void *cls,
3626 struct GNUNET_SERVER_Client *client, 3534 struct GNUNET_SERVER_Client *client,
3627 const struct GNUNET_MessageHeader *message) 3535 const struct GNUNET_MessageHeader *message)
3628{ 3536{
3629 struct Blacklisters *bl; 3537 struct Blacklisters *bl;
3630 struct TestConnectionContext tcc; 3538 struct TestConnectionContext tcc;
3631 3539
3632 bl = bl_head; 3540 bl = bl_head;
3633 while (bl != NULL) 3541 while (bl != NULL)
3542 {
3543 if (bl->client == client)
3634 { 3544 {
3635 if (bl->client == client) 3545 GNUNET_break (0);
3636 { 3546 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
3637 GNUNET_break (0); 3547 return;
3638 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
3639 return;
3640 }
3641 bl = bl->next;
3642 } 3548 }
3549 bl = bl->next;
3550 }
3643 bl = GNUNET_malloc (sizeof (struct Blacklisters)); 3551 bl = GNUNET_malloc (sizeof (struct Blacklisters));
3644 bl->client = client; 3552 bl->client = client;
3645 GNUNET_SERVER_client_keep (client); 3553 GNUNET_SERVER_client_keep (client);
@@ -3647,9 +3555,7 @@ handle_blacklist_init (void *cls,
3647 /* confirm that all existing connections are OK! */ 3555 /* confirm that all existing connections are OK! */
3648 tcc.bl = bl; 3556 tcc.bl = bl;
3649 tcc.first = GNUNET_YES; 3557 tcc.first = GNUNET_YES;
3650 GNUNET_CONTAINER_multihashmap_iterate (neighbours, 3558 GNUNET_CONTAINER_multihashmap_iterate (neighbours, &test_connection_ok, &tcc);
3651 &test_connection_ok,
3652 &tcc);
3653} 3559}
3654 3560
3655 3561
@@ -3662,59 +3568,55 @@ handle_blacklist_init (void *cls,
3662 */ 3568 */
3663static void 3569static void
3664handle_blacklist_reply (void *cls, 3570handle_blacklist_reply (void *cls,
3665 struct GNUNET_SERVER_Client *client, 3571 struct GNUNET_SERVER_Client *client,
3666 const struct GNUNET_MessageHeader *message) 3572 const struct GNUNET_MessageHeader *message)
3667{ 3573{
3668 const struct BlacklistMessage *msg = (const struct BlacklistMessage*) message; 3574 const struct BlacklistMessage *msg =
3575 (const struct BlacklistMessage *) message;
3669 struct Blacklisters *bl; 3576 struct Blacklisters *bl;
3670 struct BlacklistCheck *bc; 3577 struct BlacklistCheck *bc;
3671 3578
3672 bl = bl_head; 3579 bl = bl_head;
3673 while ( (bl != NULL) && 3580 while ((bl != NULL) && (bl->client != client))
3674 (bl->client != client) )
3675 bl = bl->next; 3581 bl = bl->next;
3676 if (bl == NULL) 3582 if (bl == NULL)
3677 { 3583 {
3678#if DEBUG_TRANSPORT 3584#if DEBUG_TRANSPORT
3679 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3585 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Blacklist client disconnected\n");
3680 "Blacklist client disconnected\n");
3681#endif 3586#endif
3682 /* FIXME: other error handling here!? */ 3587 /* FIXME: other error handling here!? */
3683 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 3588 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
3684 return; 3589 return;
3685 } 3590 }
3686 bc = bl->bc; 3591 bc = bl->bc;
3687 bl->bc = NULL; 3592 bl->bc = NULL;
3688 if (ntohl (msg->is_allowed) == GNUNET_SYSERR) 3593 if (ntohl (msg->is_allowed) == GNUNET_SYSERR)
3689 { 3594 {
3690#if DEBUG_TRANSPORT 3595#if DEBUG_TRANSPORT
3691 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3596 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3692 "Blacklist check failed, peer not allowed\n"); 3597 "Blacklist check failed, peer not allowed\n");
3693#endif 3598#endif
3694 bc->cont (bc->cont_cls, NULL); 3599 bc->cont (bc->cont_cls, NULL);
3695 GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, bc); 3600 GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, bc);
3696 GNUNET_free (bc); 3601 GNUNET_free (bc);
3697 } 3602 }
3698 else 3603 else
3699 { 3604 {
3700#if DEBUG_TRANSPORT 3605#if DEBUG_TRANSPORT
3701 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3606 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3702 "Blacklist check succeeded, continuing with checks\n"); 3607 "Blacklist check succeeded, continuing with checks\n");
3703#endif 3608#endif
3704 bc->bl_pos = bc->bl_pos->next; 3609 bc->bl_pos = bc->bl_pos->next;
3705 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, 3610 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc);
3706 bc); 3611 }
3707 }
3708 /* check if any other bc's are waiting for this blacklister */ 3612 /* check if any other bc's are waiting for this blacklister */
3709 bc = bc_head; 3613 bc = bc_head;
3710 while (bc != NULL) 3614 while (bc != NULL)
3711 { 3615 {
3712 if ( (bc->bl_pos == bl) && 3616 if ((bc->bl_pos == bl) && (GNUNET_SCHEDULER_NO_TASK == bc->task))
3713 (GNUNET_SCHEDULER_NO_TASK == bc->task) ) 3617 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc);
3714 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, 3618 bc = bc->next;
3715 bc); 3619 }
3716 bc = bc->next;
3717 }
3718} 3620}
3719 3621
3720 3622
@@ -3725,8 +3627,7 @@ handle_blacklist_reply (void *cls,
3725 * @param tc task context 3627 * @param tc task context
3726 */ 3628 */
3727static void 3629static void
3728send_periodic_ping (void *cls, 3630send_periodic_ping (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3729 const struct GNUNET_SCHEDULER_TaskContext *tc)
3730{ 3631{
3731 struct ForeignAddressList *peer_address = cls; 3632 struct ForeignAddressList *peer_address = cls;
3732 struct TransportPlugin *tp; 3633 struct TransportPlugin *tp;
@@ -3734,23 +3635,23 @@ send_periodic_ping (void *cls,
3734 struct NeighbourMapEntry *neighbour; 3635 struct NeighbourMapEntry *neighbour;
3735 struct TransportPingMessage ping; 3636 struct TransportPingMessage ping;
3736 struct CheckAddressExistsClosure caec; 3637 struct CheckAddressExistsClosure caec;
3737 char * message_buf; 3638 char *message_buf;
3738 uint16_t hello_size; 3639 uint16_t hello_size;
3739 size_t slen; 3640 size_t slen;
3740 size_t tsize; 3641 size_t tsize;
3741 3642
3742 peer_address->revalidate_task = GNUNET_SCHEDULER_NO_TASK; 3643 peer_address->revalidate_task = GNUNET_SCHEDULER_NO_TASK;
3743 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 3644 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
3744 return; 3645 return;
3745 GNUNET_assert (peer_address != NULL); 3646 GNUNET_assert (peer_address != NULL);
3746 tp = peer_address->ready_list->plugin; 3647 tp = peer_address->ready_list->plugin;
3747 neighbour = peer_address->ready_list->neighbour; 3648 neighbour = peer_address->ready_list->neighbour;
3748 if (GNUNET_YES != neighbour->public_key_valid) 3649 if (GNUNET_YES != neighbour->public_key_valid)
3749 { 3650 {
3750 /* no public key yet, try again later */ 3651 /* no public key yet, try again later */
3751 schedule_next_ping (peer_address); 3652 schedule_next_ping (peer_address);
3752 return; 3653 return;
3753 } 3654 }
3754 caec.addr = peer_address->addr; 3655 caec.addr = peer_address->addr;
3755 caec.addrlen = peer_address->addrlen; 3656 caec.addrlen = peer_address->addrlen;
3756 caec.tname = tp->short_name; 3657 caec.tname = tp->short_name;
@@ -3758,43 +3659,40 @@ send_periodic_ping (void *cls,
3758 caec.exists = GNUNET_NO; 3659 caec.exists = GNUNET_NO;
3759 3660
3760 GNUNET_CONTAINER_multihashmap_iterate (validation_map, 3661 GNUNET_CONTAINER_multihashmap_iterate (validation_map,
3761 &check_address_exists, 3662 &check_address_exists, &caec);
3762 &caec);
3763 if (caec.exists == GNUNET_YES) 3663 if (caec.exists == GNUNET_YES)
3764 { 3664 {
3765 /* During validation attempts we will likely trigger the other 3665 /* During validation attempts we will likely trigger the other
3766 peer trying to validate our address which in turn will cause 3666 * peer trying to validate our address which in turn will cause
3767 it to send us its HELLO, so we expect to hit this case rather 3667 * it to send us its HELLO, so we expect to hit this case rather
3768 frequently. Only print something if we are very verbose. */ 3668 * frequently. Only print something if we are very verbose. */
3769#if DEBUG_TRANSPORT > 1 3669#if DEBUG_TRANSPORT > 1
3770 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3670 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3771 "Some validation of address `%s' via `%s' for peer `%4s' already in progress.\n", 3671 "Some validation of address `%s' via `%s' for peer `%4s' already in progress.\n",
3772 (peer_address->addr != NULL) 3672 (peer_address->addr != NULL)
3773 ? a2s (tp->short_name, 3673 ? a2s (tp->short_name,
3774 peer_address->addr, 3674 peer_address->addr,
3775 peer_address->addrlen) 3675 peer_address->addrlen)
3776 : "<inbound>", 3676 : "<inbound>", tp->short_name, GNUNET_i2s (&neighbour->id));
3777 tp->short_name,
3778 GNUNET_i2s (&neighbour->id));
3779#endif 3677#endif
3780 schedule_next_ping (peer_address); 3678 schedule_next_ping (peer_address);
3781 return; 3679 return;
3782 } 3680 }
3783 va = GNUNET_malloc (sizeof (struct ValidationEntry) + peer_address->addrlen); 3681 va = GNUNET_malloc (sizeof (struct ValidationEntry) + peer_address->addrlen);
3784 va->transport_name = GNUNET_strdup (tp->short_name); 3682 va->transport_name = GNUNET_strdup (tp->short_name);
3785 va->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, 3683 va->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
3786 UINT_MAX); 3684 UINT_MAX);
3787 va->send_time = GNUNET_TIME_absolute_get(); 3685 va->send_time = GNUNET_TIME_absolute_get ();
3788 va->session = peer_address->session; 3686 va->session = peer_address->session;
3789 if (peer_address->addr != NULL) 3687 if (peer_address->addr != NULL)
3790 { 3688 {
3791 va->addr = (const void*) &va[1]; 3689 va->addr = (const void *) &va[1];
3792 memcpy (&va[1], peer_address->addr, peer_address->addrlen); 3690 memcpy (&va[1], peer_address->addr, peer_address->addrlen);
3793 va->addrlen = peer_address->addrlen; 3691 va->addrlen = peer_address->addrlen;
3794 } 3692 }
3795 memcpy(&va->publicKey, 3693 memcpy (&va->publicKey,
3796 &neighbour->publicKey, 3694 &neighbour->publicKey,
3797 sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); 3695 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
3798 3696
3799 va->timeout_task = GNUNET_SCHEDULER_add_delayed (HELLO_VERIFICATION_TIMEOUT, 3697 va->timeout_task = GNUNET_SCHEDULER_add_delayed (HELLO_VERIFICATION_TIMEOUT,
3800 &timeout_hello_validation, 3698 &timeout_hello_validation,
@@ -3805,83 +3703,75 @@ send_periodic_ping (void *cls,
3805 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 3703 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
3806 3704
3807 if (peer_address->validated != GNUNET_YES) 3705 if (peer_address->validated != GNUNET_YES)
3808 hello_size = GNUNET_HELLO_size(our_hello); 3706 hello_size = GNUNET_HELLO_size (our_hello);
3809 else 3707 else
3810 hello_size = 0; 3708 hello_size = 0;
3811 3709
3812 tsize = sizeof(struct TransportPingMessage) + hello_size; 3710 tsize = sizeof (struct TransportPingMessage) + hello_size;
3813 3711
3814 if (peer_address->addr != NULL) 3712 if (peer_address->addr != NULL)
3815 { 3713 {
3816 slen = strlen (tp->short_name) + 1; 3714 slen = strlen (tp->short_name) + 1;
3817 tsize += slen + peer_address->addrlen; 3715 tsize += slen + peer_address->addrlen;
3818 } 3716 }
3819 else 3717 else
3820 { 3718 {
3821 slen = 0; /* make gcc happy */ 3719 slen = 0; /* make gcc happy */
3822 } 3720 }
3823 message_buf = GNUNET_malloc(tsize); 3721 message_buf = GNUNET_malloc (tsize);
3824 ping.header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_PING); 3722 ping.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PING);
3825 ping.challenge = htonl(va->challenge); 3723 ping.challenge = htonl (va->challenge);
3826 memcpy(&ping.target, &neighbour->id, sizeof(struct GNUNET_PeerIdentity)); 3724 memcpy (&ping.target, &neighbour->id, sizeof (struct GNUNET_PeerIdentity));
3827 if (peer_address->validated != GNUNET_YES) 3725 if (peer_address->validated != GNUNET_YES)
3828 { 3726 {
3829 memcpy(message_buf, our_hello, hello_size); 3727 memcpy (message_buf, our_hello, hello_size);
3830 } 3728 }
3831 3729
3832 if (peer_address->addr != NULL) 3730 if (peer_address->addr != NULL)
3833 { 3731 {
3834 ping.header.size = htons(sizeof(struct TransportPingMessage) + 3732 ping.header.size = htons (sizeof (struct TransportPingMessage) +
3835 peer_address->addrlen + 3733 peer_address->addrlen + slen);
3836 slen); 3734 memcpy (&message_buf[hello_size + sizeof (struct TransportPingMessage)],
3837 memcpy(&message_buf[hello_size + sizeof (struct TransportPingMessage)], 3735 tp->short_name, slen);
3838 tp->short_name, 3736 memcpy (&message_buf
3839 slen); 3737 [hello_size + sizeof (struct TransportPingMessage) + slen],
3840 memcpy(&message_buf[hello_size + sizeof (struct TransportPingMessage) + slen], 3738 peer_address->addr, peer_address->addrlen);
3841 peer_address->addr, 3739 }
3842 peer_address->addrlen);
3843 }
3844 else 3740 else
3845 { 3741 {
3846 ping.header.size = htons(sizeof(struct TransportPingMessage)); 3742 ping.header.size = htons (sizeof (struct TransportPingMessage));
3847 } 3743 }
3848 3744
3849 memcpy(&message_buf[hello_size], 3745 memcpy (&message_buf[hello_size],
3850 &ping, 3746 &ping, sizeof (struct TransportPingMessage));
3851 sizeof(struct TransportPingMessage));
3852 3747
3853#if DEBUG_TRANSPORT_REVALIDATION 3748#if DEBUG_TRANSPORT_REVALIDATION
3854 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3749 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3855 "Performing re-validation of address `%s' via `%s' for peer `%4s' sending `%s' (%u bytes) and `%s'\n", 3750 "Performing re-validation of address `%s' via `%s' for peer `%4s' sending `%s' (%u bytes) and `%s'\n",
3856 (peer_address->addr != NULL) 3751 (peer_address->addr != NULL)
3857 ? a2s (peer_address->plugin->short_name, 3752 ? a2s (peer_address->plugin->short_name,
3858 peer_address->addr, 3753 peer_address->addr,
3859 peer_address->addrlen) 3754 peer_address->addrlen)
3860 : "<inbound>", 3755 : "<inbound>",
3861 tp->short_name, 3756 tp->short_name,
3862 GNUNET_i2s (&neighbour->id), 3757 GNUNET_i2s (&neighbour->id), "HELLO", hello_size, "PING");
3863 "HELLO", hello_size,
3864 "PING");
3865#endif 3758#endif
3866 if (peer_address->validated != GNUNET_YES) 3759 if (peer_address->validated != GNUNET_YES)
3867 GNUNET_STATISTICS_update (stats, 3760 GNUNET_STATISTICS_update (stats,
3868 gettext_noop ("# PING with HELLO messages sent"), 3761 gettext_noop ("# PING with HELLO messages sent"),
3869 1, 3762 1, GNUNET_NO);
3870 GNUNET_NO);
3871 else 3763 else
3872 GNUNET_STATISTICS_update (stats, 3764 GNUNET_STATISTICS_update (stats,
3873 gettext_noop ("# PING without HELLO messages sent"), 3765 gettext_noop
3874 1, 3766 ("# PING without HELLO messages sent"), 1,
3875 GNUNET_NO); 3767 GNUNET_NO);
3876 GNUNET_STATISTICS_update (stats, 3768 GNUNET_STATISTICS_update (stats,
3877 gettext_noop ("# PING messages sent for re-validation"), 3769 gettext_noop
3878 1, 3770 ("# PING messages sent for re-validation"), 1,
3879 GNUNET_NO); 3771 GNUNET_NO);
3880 transmit_to_peer (NULL, peer_address, 3772 transmit_to_peer (NULL, peer_address, GNUNET_SCHEDULER_PRIORITY_DEFAULT,
3881 GNUNET_SCHEDULER_PRIORITY_DEFAULT, 3773 HELLO_VERIFICATION_TIMEOUT, message_buf, tsize, GNUNET_YES,
3882 HELLO_VERIFICATION_TIMEOUT, 3774 neighbour);
3883 message_buf, tsize,
3884 GNUNET_YES, neighbour);
3885 GNUNET_free (message_buf); 3775 GNUNET_free (message_buf);
3886 schedule_next_ping (peer_address); 3776 schedule_next_ping (peer_address);
3887} 3777}
@@ -3899,37 +3789,36 @@ schedule_next_ping (struct ForeignAddressList *fal)
3899 struct GNUNET_TIME_Relative delay; 3789 struct GNUNET_TIME_Relative delay;
3900 3790
3901 if (fal->revalidate_task != GNUNET_SCHEDULER_NO_TASK) 3791 if (fal->revalidate_task != GNUNET_SCHEDULER_NO_TASK)
3902 { 3792 {
3903 GNUNET_SCHEDULER_cancel(fal->revalidate_task); 3793 GNUNET_SCHEDULER_cancel (fal->revalidate_task);
3904 fal->revalidate_task = GNUNET_SCHEDULER_NO_TASK; 3794 fal->revalidate_task = GNUNET_SCHEDULER_NO_TASK;
3905 } 3795 }
3906 delay = GNUNET_TIME_absolute_get_remaining (fal->expires); 3796 delay = GNUNET_TIME_absolute_get_remaining (fal->expires);
3907 delay.rel_value /= 2; /* do before expiration */ 3797 delay.rel_value /= 2; /* do before expiration */
3908 delay = GNUNET_TIME_relative_min (delay, 3798 delay = GNUNET_TIME_relative_min (delay, LATENCY_EVALUATION_MAX_DELAY);
3909 LATENCY_EVALUATION_MAX_DELAY);
3910 if (GNUNET_YES != fal->estimated) 3799 if (GNUNET_YES != fal->estimated)
3911 { 3800 {
3912 delay = GNUNET_TIME_UNIT_ZERO; 3801 delay = GNUNET_TIME_UNIT_ZERO;
3913 fal->estimated = GNUNET_YES; 3802 fal->estimated = GNUNET_YES;
3914 } 3803 }
3915 3804
3916 if (GNUNET_YES == fal->connected) 3805 if (GNUNET_YES == fal->connected)
3917 { 3806 {
3918 delay = GNUNET_TIME_relative_min (delay, 3807 delay = GNUNET_TIME_relative_min (delay,
3919 CONNECTED_LATENCY_EVALUATION_MAX_DELAY); 3808 CONNECTED_LATENCY_EVALUATION_MAX_DELAY);
3920 } 3809 }
3921 /* FIXME: also adjust delay based on how close the last 3810 /* FIXME: also adjust delay based on how close the last
3922 observed latency is to the latency of the best alternative */ 3811 * observed latency is to the latency of the best alternative */
3923 /* bound how fast we can go */ 3812 /* bound how fast we can go */
3924 delay = GNUNET_TIME_relative_max (delay, 3813 delay = GNUNET_TIME_relative_max (delay, GNUNET_TIME_UNIT_SECONDS);
3925 GNUNET_TIME_UNIT_SECONDS);
3926 /* randomize a bit (to avoid doing all at the same time) */ 3814 /* randomize a bit (to avoid doing all at the same time) */
3927 delay.rel_value += GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1000); 3815 delay.rel_value +=
3816 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1000);
3928 3817
3929 GNUNET_assert (fal->revalidate_task == GNUNET_SCHEDULER_NO_TASK); 3818 GNUNET_assert (fal->revalidate_task == GNUNET_SCHEDULER_NO_TASK);
3930 fal->revalidate_task = GNUNET_SCHEDULER_add_delayed(delay, 3819 fal->revalidate_task = GNUNET_SCHEDULER_add_delayed (delay,
3931 &send_periodic_ping, 3820 &send_periodic_ping,
3932 fal); 3821 fal);
3933} 3822}
3934 3823
3935 3824
@@ -3944,7 +3833,7 @@ schedule_next_ping (struct ForeignAddressList *fal)
3944 */ 3833 */
3945static void 3834static void
3946handle_payload_message (const struct GNUNET_MessageHeader *message, 3835handle_payload_message (const struct GNUNET_MessageHeader *message,
3947 struct NeighbourMapEntry *n) 3836 struct NeighbourMapEntry *n)
3948{ 3837{
3949 struct InboundMessage *im; 3838 struct InboundMessage *im;
3950 struct TransportClient *cpos; 3839 struct TransportClient *cpos;
@@ -3952,66 +3841,64 @@ handle_payload_message (const struct GNUNET_MessageHeader *message,
3952 3841
3953 msize = ntohs (message->size); 3842 msize = ntohs (message->size);
3954 if (n->received_pong == GNUNET_NO) 3843 if (n->received_pong == GNUNET_NO)
3955 { 3844 {
3956#if DEBUG_TRANSPORT 3845#if DEBUG_TRANSPORT
3957 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3846 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3958 "Received message of type %u and size %u from `%4s', but no pong yet!\n", 3847 "Received message of type %u and size %u from `%4s', but no pong yet!\n",
3959 ntohs (message->type), 3848 ntohs (message->type),
3960 ntohs (message->size), 3849 ntohs (message->size), GNUNET_i2s (&n->id));
3961 GNUNET_i2s (&n->id));
3962#endif 3850#endif
3963 GNUNET_free_non_null (n->pre_connect_message_buffer); 3851 GNUNET_free_non_null (n->pre_connect_message_buffer);
3964 n->pre_connect_message_buffer = GNUNET_malloc (msize); 3852 n->pre_connect_message_buffer = GNUNET_malloc (msize);
3965 memcpy (n->pre_connect_message_buffer, message, msize); 3853 memcpy (n->pre_connect_message_buffer, message, msize);
3966 return; 3854 return;
3967 } 3855 }
3968 3856
3969#if DEBUG_TRANSPORT 3857#if DEBUG_TRANSPORT
3970 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3858 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3971 "Received message of type %u and size %u from `%4s', sending to all clients.\n", 3859 "Received message of type %u and size %u from `%4s', sending to all clients.\n",
3972 ntohs (message->type), 3860 ntohs (message->type),
3973 ntohs (message->size), 3861 ntohs (message->size), GNUNET_i2s (&n->id));
3974 GNUNET_i2s (&n->id));
3975#endif 3862#endif
3976 if (GNUNET_YES == GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, 3863 if (GNUNET_YES == GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker,
3977 (ssize_t) msize)) 3864 (ssize_t) msize))
3978 { 3865 {
3979 n->quota_violation_count++; 3866 n->quota_violation_count++;
3980#if DEBUG_TRANSPORT 3867#if DEBUG_TRANSPORT
3981 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3868 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3982 "Bandwidth quota (%u b/s) violation detected (total of %u).\n", 3869 "Bandwidth quota (%u b/s) violation detected (total of %u).\n",
3983 n->in_tracker.available_bytes_per_s__, 3870 n->in_tracker.available_bytes_per_s__,
3984 n->quota_violation_count); 3871 n->quota_violation_count);
3985#endif 3872#endif
3986 /* Discount 32k per violation */ 3873 /* Discount 32k per violation */
3987 GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, 3874 GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, -32 * 1024);
3988 - 32 * 1024); 3875 }
3989 }
3990 else 3876 else
3877 {
3878 if (n->quota_violation_count > 0)
3991 { 3879 {
3992 if (n->quota_violation_count > 0) 3880 /* try to add 32k back */
3993 { 3881 GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, 32 * 1024);
3994 /* try to add 32k back */ 3882 n->quota_violation_count--;
3995 GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker,
3996 32 * 1024);
3997 n->quota_violation_count--;
3998 }
3999 } 3883 }
3884 }
4000 GNUNET_STATISTICS_update (stats, 3885 GNUNET_STATISTICS_update (stats,
4001 gettext_noop ("# payload received from other peers"), 3886 gettext_noop
4002 msize, 3887 ("# payload received from other peers"), msize,
4003 GNUNET_NO); 3888 GNUNET_NO);
4004 /* transmit message to all clients */ 3889 /* transmit message to all clients */
4005 uint32_t ats_count = 2; 3890 uint32_t ats_count = 2;
4006 size_t size = sizeof (struct InboundMessage) + ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information) + msize; 3891 size_t size =
3892 sizeof (struct InboundMessage) +
3893 ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information) + msize;
4007 if (size > GNUNET_SERVER_MAX_MESSAGE_SIZE) 3894 if (size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
4008 GNUNET_break(0); 3895 GNUNET_break (0);
4009 3896
4010 im = GNUNET_malloc (size); 3897 im = GNUNET_malloc (size);
4011 im->header.size = htons (size); 3898 im->header.size = htons (size);
4012 im->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RECV); 3899 im->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RECV);
4013 im->peer = n->id; 3900 im->peer = n->id;
4014 im->ats_count = htonl(ats_count); 3901 im->ats_count = htonl (ats_count);
4015 /* Setting ATS data */ 3902 /* Setting ATS data */
4016 (&(im->ats))[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE); 3903 (&(im->ats))[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
4017 (&(im->ats))[0].value = htonl (n->distance); 3904 (&(im->ats))[0].value = htonl (n->distance);
@@ -4020,13 +3907,13 @@ handle_payload_message (const struct GNUNET_MessageHeader *message,
4020 (&(im->ats))[ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); 3907 (&(im->ats))[ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
4021 (&(im->ats))[ats_count].value = htonl (0); 3908 (&(im->ats))[ats_count].value = htonl (0);
4022 3909
4023 memcpy (&((&(im->ats))[ats_count+1]), message, msize); 3910 memcpy (&((&(im->ats))[ats_count + 1]), message, msize);
4024 cpos = clients; 3911 cpos = clients;
4025 while (cpos != NULL) 3912 while (cpos != NULL)
4026 { 3913 {
4027 transmit_to_client (cpos, &im->header, GNUNET_YES); 3914 transmit_to_client (cpos, &im->header, GNUNET_YES);
4028 cpos = cpos->next; 3915 cpos = cpos->next;
4029 } 3916 }
4030 GNUNET_free (im); 3917 GNUNET_free (im);
4031} 3918}
4032 3919
@@ -4042,14 +3929,12 @@ handle_payload_message (const struct GNUNET_MessageHeader *message,
4042 * iterate (mismatch), GNUNET_NO if not (entry matched) 3929 * iterate (mismatch), GNUNET_NO if not (entry matched)
4043 */ 3930 */
4044static int 3931static int
4045check_pending_validation (void *cls, 3932check_pending_validation (void *cls, const GNUNET_HashCode * key, void *value)
4046 const GNUNET_HashCode * key,
4047 void *value)
4048{ 3933{
4049 const struct TransportPongMessage *pong = cls; 3934 const struct TransportPongMessage *pong = cls;
4050 struct ValidationEntry *ve = value; 3935 struct ValidationEntry *ve = value;
4051 struct AddValidatedAddressContext avac; 3936 struct AddValidatedAddressContext avac;
4052 unsigned int challenge = ntohl(pong->challenge); 3937 unsigned int challenge = ntohl (pong->challenge);
4053 struct GNUNET_HELLO_Message *hello; 3938 struct GNUNET_HELLO_Message *hello;
4054 struct GNUNET_PeerIdentity target; 3939 struct GNUNET_PeerIdentity target;
4055 struct NeighbourMapEntry *n; 3940 struct NeighbourMapEntry *n;
@@ -4064,217 +3949,201 @@ check_pending_validation (void *cls,
4064 3949
4065 ps = ntohs (pong->header.size); 3950 ps = ntohs (pong->header.size);
4066 if (ps < sizeof (struct TransportPongMessage)) 3951 if (ps < sizeof (struct TransportPongMessage))
3952 {
3953 GNUNET_break_op (0);
3954 return GNUNET_NO;
3955 }
3956 addr = (const char *) &pong[1];
3957 slen = strlen (ve->transport_name) + 1;
3958 if ((ps - sizeof (struct TransportPongMessage) < slen) ||
3959 (ve->challenge != challenge) ||
3960 (addr[slen - 1] != '\0') ||
3961 (0 != strcmp (addr, ve->transport_name)) ||
3962 (ntohl (pong->purpose.size)
3963 != sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
3964 sizeof (uint32_t) +
3965 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
3966 sizeof (struct GNUNET_PeerIdentity) + ps -
3967 sizeof (struct TransportPongMessage)))
3968 {
3969 return GNUNET_YES;
3970 }
3971
3972 alen = ps - sizeof (struct TransportPongMessage) - slen;
3973 switch (ntohl (pong->purpose.purpose))
3974 {
3975 case GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN:
3976 if ((ve->addrlen + slen != ntohl (pong->addrlen)) ||
3977 (0 != memcmp (&addr[slen], ve->addr, ve->addrlen)))
3978 {
3979 return GNUNET_YES; /* different entry, keep trying! */
3980 }
3981 if (0 != memcmp (&pong->pid, key, sizeof (struct GNUNET_PeerIdentity)))
4067 { 3982 {
4068 GNUNET_break_op (0); 3983 GNUNET_break_op (0);
4069 return GNUNET_NO; 3984 return GNUNET_NO;
4070 } 3985 }
4071 addr = (const char*) &pong[1]; 3986 if (GNUNET_OK !=
4072 slen = strlen (ve->transport_name) + 1; 3987 GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN,
4073 if ( (ps - sizeof (struct TransportPongMessage) < slen) || 3988 &pong->purpose,
4074 (ve->challenge != challenge) || 3989 &pong->signature, &ve->publicKey))
4075 (addr[slen-1] != '\0') ||
4076 (0 != strcmp (addr, ve->transport_name)) ||
4077 (ntohl (pong->purpose.size)
4078 != sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
4079 sizeof (uint32_t) +
4080 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
4081 sizeof (struct GNUNET_PeerIdentity) + ps - sizeof (struct TransportPongMessage)) )
4082 { 3990 {
4083 return GNUNET_YES; 3991 GNUNET_break_op (0);
3992 return GNUNET_NO;
4084 } 3993 }
4085 3994
4086 alen = ps - sizeof (struct TransportPongMessage) - slen;
4087 switch (ntohl (pong->purpose.purpose))
4088 {
4089 case GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN:
4090 if ( (ve->addrlen + slen != ntohl (pong->addrlen)) ||
4091 (0 != memcmp (&addr[slen],
4092 ve->addr,
4093 ve->addrlen)) )
4094 {
4095 return GNUNET_YES; /* different entry, keep trying! */
4096 }
4097 if (0 != memcmp (&pong->pid,
4098 key,
4099 sizeof (struct GNUNET_PeerIdentity)))
4100 {
4101 GNUNET_break_op (0);
4102 return GNUNET_NO;
4103 }
4104 if (GNUNET_OK !=
4105 GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN,
4106 &pong->purpose,
4107 &pong->signature,
4108 &ve->publicKey))
4109 {
4110 GNUNET_break_op (0);
4111 return GNUNET_NO;
4112 }
4113
4114#if DEBUG_TRANSPORT
4115 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4116 "Confirmed validity of address, peer `%4s' has address `%s' (%s).\n",
4117 GNUNET_h2s (key),
4118 a2s (ve->transport_name,
4119 (const struct sockaddr *) ve->addr,
4120 ve->addrlen),
4121 ve->transport_name);
4122#endif
4123 break;
4124 case GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_USING:
4125 if (0 != memcmp (&pong->pid,
4126 &my_identity,
4127 sizeof (struct GNUNET_PeerIdentity)))
4128 {
4129 char * peer;
4130
4131 GNUNET_asprintf(&peer, "%s",GNUNET_i2s (&pong->pid));
4132#if DEBUG_TRANSPORT 3995#if DEBUG_TRANSPORT
4133 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3996 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4134 "Received PONG for different identity: I am `%s', PONG identity: `%s'\n", 3997 "Confirmed validity of address, peer `%4s' has address `%s' (%s).\n",
4135 GNUNET_i2s (&my_identity), 3998 GNUNET_h2s (key),
4136 peer ); 3999 a2s (ve->transport_name,
4137#endif 4000 (const struct sockaddr *) ve->addr,
4138 GNUNET_free (peer); 4001 ve->addrlen), ve->transport_name);
4139 return GNUNET_NO;
4140 }
4141 if (ve->addrlen != 0)
4142 {
4143 /* must have been for a different validation entry */
4144 return GNUNET_YES;
4145 }
4146 tp = find_transport (ve->transport_name);
4147 if (tp == NULL)
4148 {
4149 GNUNET_break (0);
4150 return GNUNET_YES;
4151 }
4152 oal = tp->addresses;
4153 while (NULL != oal)
4154 {
4155 if ( (oal->addrlen == alen) &&
4156 (0 == memcmp (&oal[1],
4157 &addr[slen],
4158 alen)) )
4159 break;
4160 oal = oal->next;
4161 }
4162 if (oal == NULL)
4163 {
4164 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
4165 _("Not accepting PONG from `%s' with address `%s' since I cannot confirm using this address.\n"),
4166 GNUNET_i2s (&pong->pid),
4167 a2s (ve->transport_name,
4168 &addr[slen],
4169 alen));
4170 /* FIXME: since the sender of the PONG currently uses the
4171 wrong address (see FIMXE there!), we cannot run a
4172 proper check here... */
4173#if FIXME_URGENT
4174 return GNUNET_NO;
4175#endif 4002#endif
4176 } 4003 break;
4177 if (GNUNET_OK != 4004 case GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_USING:
4178 GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_USING, 4005 if (0 != memcmp (&pong->pid,
4179 &pong->purpose, 4006 &my_identity, sizeof (struct GNUNET_PeerIdentity)))
4180 &pong->signature, 4007 {
4181 &ve->publicKey)) 4008 char *peer;
4182 {
4183 GNUNET_break_op (0);
4184 return GNUNET_NO;
4185 }
4186 4009
4010 GNUNET_asprintf (&peer, "%s", GNUNET_i2s (&pong->pid));
4187#if DEBUG_TRANSPORT 4011#if DEBUG_TRANSPORT
4188 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4012 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4189 "Confirmed that peer `%4s' is talking to us using address `%s' (%s) for us.\n", 4013 "Received PONG for different identity: I am `%s', PONG identity: `%s'\n",
4190 GNUNET_h2s (key), 4014 GNUNET_i2s (&my_identity), peer);
4191 a2s (ve->transport_name,
4192 &addr[slen],
4193 alen),
4194 ve->transport_name);
4195#endif 4015#endif
4196 break; 4016 GNUNET_free (peer);
4197 default:
4198 GNUNET_break_op (0);
4199 return GNUNET_NO; 4017 return GNUNET_NO;
4200 } 4018 }
4201 if (GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh (pong->expiration)).rel_value == 0) 4019 if (ve->addrlen != 0)
4202 { 4020 {
4203 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 4021 /* must have been for a different validation entry */
4204 _("Received expired signature. Check system time.\n")); 4022 return GNUNET_YES;
4023 }
4024 tp = find_transport (ve->transport_name);
4025 if (tp == NULL)
4026 {
4027 GNUNET_break (0);
4028 return GNUNET_YES;
4029 }
4030 oal = tp->addresses;
4031 while (NULL != oal)
4032 {
4033 if ((oal->addrlen == alen) && (0 == memcmp (&oal[1], &addr[slen], alen)))
4034 break;
4035 oal = oal->next;
4036 }
4037 if (oal == NULL)
4038 {
4039 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
4040 _
4041 ("Not accepting PONG from `%s' with address `%s' since I cannot confirm using this address.\n"),
4042 GNUNET_i2s (&pong->pid), a2s (ve->transport_name, &addr[slen],
4043 alen));
4044 /* FIXME: since the sender of the PONG currently uses the
4045 * wrong address (see FIMXE there!), we cannot run a
4046 * proper check here... */
4047#if FIXME_URGENT
4205 return GNUNET_NO; 4048 return GNUNET_NO;
4049#endif
4206 } 4050 }
4051 if (GNUNET_OK !=
4052 GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_USING,
4053 &pong->purpose,
4054 &pong->signature, &ve->publicKey))
4055 {
4056 GNUNET_break_op (0);
4057 return GNUNET_NO;
4058 }
4059
4060#if DEBUG_TRANSPORT
4061 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4062 "Confirmed that peer `%4s' is talking to us using address `%s' (%s) for us.\n",
4063 GNUNET_h2s (key),
4064 a2s (ve->transport_name,
4065 &addr[slen], alen), ve->transport_name);
4066#endif
4067 break;
4068 default:
4069 GNUNET_break_op (0);
4070 return GNUNET_NO;
4071 }
4072 if (GNUNET_TIME_absolute_get_remaining
4073 (GNUNET_TIME_absolute_ntoh (pong->expiration)).rel_value == 0)
4074 {
4075 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
4076 _("Received expired signature. Check system time.\n"));
4077 return GNUNET_NO;
4078 }
4207 GNUNET_STATISTICS_update (stats, 4079 GNUNET_STATISTICS_update (stats,
4208 gettext_noop ("# address validation successes"), 4080 gettext_noop ("# address validation successes"),
4209 1, 4081 1, GNUNET_NO);
4210 GNUNET_NO);
4211 /* create the updated HELLO */ 4082 /* create the updated HELLO */
4212 GNUNET_CRYPTO_hash (&ve->publicKey, 4083 GNUNET_CRYPTO_hash (&ve->publicKey,
4213 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), 4084 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
4214 &target.hashPubKey); 4085 &target.hashPubKey);
4215 if (ve->addr != NULL) 4086 if (ve->addr != NULL)
4216 { 4087 {
4217 avac.done = GNUNET_NO; 4088 avac.done = GNUNET_NO;
4218 avac.ve = ve; 4089 avac.ve = ve;
4219 hello = GNUNET_HELLO_create (&ve->publicKey, 4090 hello = GNUNET_HELLO_create (&ve->publicKey, &add_validated_address, &avac);
4220 &add_validated_address, 4091 GNUNET_PEERINFO_add_peer (peerinfo, hello);
4221 &avac); 4092 GNUNET_free (hello);
4222 GNUNET_PEERINFO_add_peer (peerinfo, 4093 }
4223 hello);
4224 GNUNET_free (hello);
4225 }
4226 n = find_neighbour (&target); 4094 n = find_neighbour (&target);
4227 if (n != NULL) 4095 if (n != NULL)
4096 {
4097 n->publicKey = ve->publicKey;
4098 n->public_key_valid = GNUNET_YES;
4099 fal = add_peer_address (n,
4100 ve->transport_name,
4101 ve->session, ve->addr, ve->addrlen);
4102 GNUNET_assert (fal != NULL);
4103 fal->expires = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION);
4104 fal->validated = GNUNET_YES;
4105 mark_address_connected (fal);
4106 GNUNET_STATISTICS_update (stats,
4107 gettext_noop
4108 ("# peer addresses considered valid"), 1,
4109 GNUNET_NO);
4110 fal->latency = GNUNET_TIME_absolute_get_duration (ve->send_time);
4111 update_addr_value (fal,
4112 GNUNET_TIME_absolute_get_duration (ve->
4113 send_time).rel_value,
4114 GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY);
4115
4116 schedule_next_ping (fal);
4117 if (n->latency.rel_value == GNUNET_TIME_UNIT_FOREVER_REL.rel_value)
4118 n->latency = fal->latency;
4119 else
4120 n->latency.rel_value =
4121 (fal->latency.rel_value + n->latency.rel_value) / 2;
4122
4123 n->distance = fal->distance;
4124 if (GNUNET_NO == n->received_pong)
4125 {
4126 n->received_pong = GNUNET_YES;
4127 notify_clients_connect (&target, n->latency, n->distance);
4128 if (NULL != (prem = n->pre_connect_message_buffer))
4129 {
4130 n->pre_connect_message_buffer = NULL;
4131 handle_payload_message (prem, n);
4132 GNUNET_free (prem);
4133 }
4134 }
4135 if (n->retry_task != GNUNET_SCHEDULER_NO_TASK)
4228 { 4136 {
4229 n->publicKey = ve->publicKey; 4137 GNUNET_SCHEDULER_cancel (n->retry_task);
4230 n->public_key_valid = GNUNET_YES; 4138 n->retry_task = GNUNET_SCHEDULER_NO_TASK;
4231 fal = add_peer_address (n, 4139 try_transmission_to_peer (n);
4232 ve->transport_name,
4233 ve->session,
4234 ve->addr,
4235 ve->addrlen);
4236 GNUNET_assert (fal != NULL);
4237 fal->expires = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION);
4238 fal->validated = GNUNET_YES;
4239 mark_address_connected (fal);
4240 GNUNET_STATISTICS_update (stats,
4241 gettext_noop ("# peer addresses considered valid"),
4242 1,
4243 GNUNET_NO);
4244 fal->latency = GNUNET_TIME_absolute_get_duration (ve->send_time);
4245 update_addr_value (fal, GNUNET_TIME_absolute_get_duration (ve->send_time).rel_value, GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY);
4246
4247 schedule_next_ping (fal);
4248 if (n->latency.rel_value == GNUNET_TIME_UNIT_FOREVER_REL.rel_value)
4249 n->latency = fal->latency;
4250 else
4251 n->latency.rel_value = (fal->latency.rel_value + n->latency.rel_value) / 2;
4252
4253 n->distance = fal->distance;
4254 if (GNUNET_NO == n->received_pong)
4255 {
4256 n->received_pong = GNUNET_YES;
4257 notify_clients_connect (&target, n->latency, n->distance);
4258 if (NULL != (prem = n->pre_connect_message_buffer))
4259 {
4260 n->pre_connect_message_buffer = NULL;
4261 handle_payload_message (prem, n);
4262 GNUNET_free (prem);
4263 }
4264 }
4265 if (n->retry_task != GNUNET_SCHEDULER_NO_TASK)
4266 {
4267 GNUNET_SCHEDULER_cancel (n->retry_task);
4268 n->retry_task = GNUNET_SCHEDULER_NO_TASK;
4269 try_transmission_to_peer (n);
4270 }
4271 } 4140 }
4141 }
4272 4142
4273 /* clean up validation entry */ 4143 /* clean up validation entry */
4274 GNUNET_assert (GNUNET_YES == 4144 GNUNET_assert (GNUNET_YES ==
4275 GNUNET_CONTAINER_multihashmap_remove (validation_map, 4145 GNUNET_CONTAINER_multihashmap_remove (validation_map,
4276 key, 4146 key, ve));
4277 ve));
4278 abort_validation (NULL, NULL, ve); 4147 abort_validation (NULL, NULL, ve);
4279 return GNUNET_NO; 4148 return GNUNET_NO;
4280} 4149}
@@ -4298,51 +4167,44 @@ check_pending_validation (void *cls,
4298static void 4167static void
4299handle_pong (void *cls, const struct GNUNET_MessageHeader *message, 4168handle_pong (void *cls, const struct GNUNET_MessageHeader *message,
4300 const struct GNUNET_PeerIdentity *peer, 4169 const struct GNUNET_PeerIdentity *peer,
4301 const char *sender_address, 4170 const char *sender_address, size_t sender_address_len)
4302 size_t sender_address_len)
4303{ 4171{
4304 if (0 == memcmp (peer, 4172 if (0 == memcmp (peer, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
4305 &my_identity, 4173 {
4306 sizeof (struct GNUNET_PeerIdentity))) 4174 /* PONG send to self, ignore */
4307 { 4175 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4308 /* PONG send to self, ignore */ 4176 "Receiving `%s' message from myself\n", "PONG");
4309 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4177 return;
4310 "Receiving `%s' message from myself\n", 4178 }
4311 "PONG");
4312 return;
4313 }
4314#if DEBUG_TRANSPORT > 1 4179#if DEBUG_TRANSPORT > 1
4315 /* we get tons of these that just get discarded, only log 4180 /* we get tons of these that just get discarded, only log
4316 if we are quite verbose */ 4181 * if we are quite verbose */
4317 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4182 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4318 "Receiving `%s' message from `%4s'.\n", "PONG", 4183 "Receiving `%s' message from `%4s'.\n", "PONG",
4319 GNUNET_i2s (peer)); 4184 GNUNET_i2s (peer));
4320#endif 4185#endif
4321 GNUNET_STATISTICS_update (stats, 4186 GNUNET_STATISTICS_update (stats,
4322 gettext_noop ("# PONG messages received"), 4187 gettext_noop ("# PONG messages received"),
4323 1, 4188 1, GNUNET_NO);
4324 GNUNET_NO);
4325 if (GNUNET_SYSERR != 4189 if (GNUNET_SYSERR !=
4326 GNUNET_CONTAINER_multihashmap_get_multiple (validation_map, 4190 GNUNET_CONTAINER_multihashmap_get_multiple (validation_map,
4327 &peer->hashPubKey, 4191 &peer->hashPubKey,
4328 &check_pending_validation, 4192 &check_pending_validation,
4329 (void*) message)) 4193 (void *) message))
4330 { 4194 {
4331 /* This is *expected* to happen a lot since we send 4195 /* This is *expected* to happen a lot since we send
4332 PONGs to *all* known addresses of the sender of 4196 * PONGs to *all* known addresses of the sender of
4333 the PING, so most likely we get multiple PONGs 4197 * the PING, so most likely we get multiple PONGs
4334 per PING, and all but the first PONG will end up 4198 * per PING, and all but the first PONG will end up
4335 here. So really we should not print anything here 4199 * here. So really we should not print anything here
4336 unless we want to be very, very verbose... */ 4200 * unless we want to be very, very verbose... */
4337#if DEBUG_TRANSPORT > 2 4201#if DEBUG_TRANSPORT > 2
4338 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4202 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4339 "Received `%s' message from `%4s' but have no record of a matching `%s' message. Ignoring.\n", 4203 "Received `%s' message from `%4s' but have no record of a matching `%s' message. Ignoring.\n",
4340 "PONG", 4204 "PONG", GNUNET_i2s (peer), "PING");
4341 GNUNET_i2s (peer),
4342 "PING");
4343#endif 4205#endif
4344 return; 4206 return;
4345 } 4207 }
4346 4208
4347} 4209}
4348 4210
@@ -4354,92 +4216,86 @@ handle_pong (void *cls, const struct GNUNET_MessageHeader *message,
4354 * @param neighbour neighbour to validate, NULL if validation failed 4216 * @param neighbour neighbour to validate, NULL if validation failed
4355 */ 4217 */
4356static void 4218static void
4357transmit_hello_and_ping (void *cls, 4219transmit_hello_and_ping (void *cls, struct NeighbourMapEntry *neighbour)
4358 struct NeighbourMapEntry *neighbour)
4359{ 4220{
4360 struct ValidationEntry *va = cls; 4221 struct ValidationEntry *va = cls;
4361 struct ForeignAddressList *peer_address; 4222 struct ForeignAddressList *peer_address;
4362 struct TransportPingMessage ping; 4223 struct TransportPingMessage ping;
4363 uint16_t hello_size; 4224 uint16_t hello_size;
4364 size_t tsize; 4225 size_t tsize;
4365 char * message_buf; 4226 char *message_buf;
4366 struct GNUNET_PeerIdentity id; 4227 struct GNUNET_PeerIdentity id;
4367 size_t slen; 4228 size_t slen;
4368 4229
4369 GNUNET_CRYPTO_hash (&va->publicKey, 4230 GNUNET_CRYPTO_hash (&va->publicKey,
4370 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), 4231 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
4371 &id.hashPubKey); 4232 &id.hashPubKey);
4372 if (neighbour == NULL) 4233 if (neighbour == NULL)
4373 { 4234 {
4374 /* FIXME: stats... */ 4235 /* FIXME: stats... */
4375 GNUNET_break (GNUNET_OK == 4236 GNUNET_break (GNUNET_OK ==
4376 GNUNET_CONTAINER_multihashmap_remove (validation_map, 4237 GNUNET_CONTAINER_multihashmap_remove (validation_map,
4377 &id.hashPubKey, 4238 &id.hashPubKey, va));
4378 va)); 4239 abort_validation (NULL, NULL, va);
4379 abort_validation (NULL, NULL, va); 4240 return;
4380 return; 4241 }
4381 }
4382 neighbour->publicKey = va->publicKey; 4242 neighbour->publicKey = va->publicKey;
4383 neighbour->public_key_valid = GNUNET_YES; 4243 neighbour->public_key_valid = GNUNET_YES;
4384 peer_address = add_peer_address (neighbour, 4244 peer_address = add_peer_address (neighbour,
4385 va->transport_name, NULL, 4245 va->transport_name, NULL,
4386 (const void*) &va[1], 4246 (const void *) &va[1], va->addrlen);
4387 va->addrlen);
4388 if (peer_address == NULL) 4247 if (peer_address == NULL)
4389 { 4248 {
4390 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 4249 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
4391 "Failed to add peer `%4s' for plugin `%s'\n", 4250 "Failed to add peer `%4s' for plugin `%s'\n",
4392 GNUNET_i2s (&neighbour->id), 4251 GNUNET_i2s (&neighbour->id), va->transport_name);
4393 va->transport_name); 4252 GNUNET_break (GNUNET_OK ==
4394 GNUNET_break (GNUNET_OK == 4253 GNUNET_CONTAINER_multihashmap_remove (validation_map,
4395 GNUNET_CONTAINER_multihashmap_remove (validation_map, 4254 &id.hashPubKey, va));
4396 &id.hashPubKey, 4255 abort_validation (NULL, NULL, va);
4397 va)); 4256 return;
4398 abort_validation (NULL, NULL, va); 4257 }
4399 return;
4400 }
4401 if (NULL == our_hello) 4258 if (NULL == our_hello)
4402 refresh_hello_task (NULL, NULL); 4259 refresh_hello_task (NULL, NULL);
4403 hello_size = GNUNET_HELLO_size(our_hello); 4260 hello_size = GNUNET_HELLO_size (our_hello);
4404 slen = strlen(va->transport_name) + 1; 4261 slen = strlen (va->transport_name) + 1;
4405 tsize = sizeof(struct TransportPingMessage) + hello_size + va->addrlen + slen; 4262 tsize =
4406 message_buf = GNUNET_malloc(tsize); 4263 sizeof (struct TransportPingMessage) + hello_size + va->addrlen + slen;
4407 ping.challenge = htonl(va->challenge); 4264 message_buf = GNUNET_malloc (tsize);
4408 ping.header.size = htons(sizeof(struct TransportPingMessage) + slen + va->addrlen); 4265 ping.challenge = htonl (va->challenge);
4409 ping.header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_PING); 4266 ping.header.size =
4410 memcpy(&ping.target, &neighbour->id, sizeof(struct GNUNET_PeerIdentity)); 4267 htons (sizeof (struct TransportPingMessage) + slen + va->addrlen);
4411 memcpy(message_buf, our_hello, hello_size); 4268 ping.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PING);
4412 memcpy(&message_buf[hello_size], 4269 memcpy (&ping.target, &neighbour->id, sizeof (struct GNUNET_PeerIdentity));
4413 &ping, 4270 memcpy (message_buf, our_hello, hello_size);
4414 sizeof(struct TransportPingMessage)); 4271 memcpy (&message_buf[hello_size],
4415 memcpy(&message_buf[hello_size + sizeof (struct TransportPingMessage)], 4272 &ping, sizeof (struct TransportPingMessage));
4416 va->transport_name, 4273 memcpy (&message_buf[hello_size + sizeof (struct TransportPingMessage)],
4417 slen); 4274 va->transport_name, slen);
4418 memcpy(&message_buf[hello_size + sizeof (struct TransportPingMessage) + slen], 4275 memcpy (&message_buf
4419 &va[1], 4276 [hello_size + sizeof (struct TransportPingMessage) + slen], &va[1],
4420 va->addrlen); 4277 va->addrlen);
4421#if DEBUG_TRANSPORT 4278#if DEBUG_TRANSPORT
4422 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4279 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4423 "Performing validation of address `%s' via `%s' for peer `%4s' sending `%s' (%u bytes) and `%s' (%u bytes)\n", 4280 "Performing validation of address `%s' via `%s' for peer `%4s' sending `%s' (%u bytes) and `%s' (%u bytes)\n",
4424 (va->addrlen == 0) 4281 (va->addrlen == 0)
4425 ? "<inbound>" 4282 ? "<inbound>"
4426 : a2s (va->transport_name, 4283 : a2s (va->transport_name,
4427 (const void*) &va[1], va->addrlen), 4284 (const void *) &va[1], va->addrlen),
4428 va->transport_name, 4285 va->transport_name,
4429 GNUNET_i2s (&neighbour->id), 4286 GNUNET_i2s (&neighbour->id),
4430 "HELLO", hello_size, 4287 "HELLO", hello_size,
4431 "PING", sizeof (struct TransportPingMessage) + va->addrlen + slen); 4288 "PING",
4289 sizeof (struct TransportPingMessage) + va->addrlen + slen);
4432#endif 4290#endif
4433 4291
4434 GNUNET_STATISTICS_update (stats, 4292 GNUNET_STATISTICS_update (stats,
4435 gettext_noop ("# PING messages sent for initial validation"), 4293 gettext_noop
4436 1, 4294 ("# PING messages sent for initial validation"), 1,
4437 GNUNET_NO); 4295 GNUNET_NO);
4438 transmit_to_peer (NULL, peer_address, 4296 transmit_to_peer (NULL, peer_address, GNUNET_SCHEDULER_PRIORITY_DEFAULT,
4439 GNUNET_SCHEDULER_PRIORITY_DEFAULT, 4297 HELLO_VERIFICATION_TIMEOUT, message_buf, tsize, GNUNET_YES,
4440 HELLO_VERIFICATION_TIMEOUT, 4298 neighbour);
4441 message_buf, tsize,
4442 GNUNET_YES, neighbour);
4443 GNUNET_free (message_buf); 4299 GNUNET_free (message_buf);
4444} 4300}
4445 4301
@@ -4460,8 +4316,7 @@ static int
4460run_validation (void *cls, 4316run_validation (void *cls,
4461 const char *tname, 4317 const char *tname,
4462 struct GNUNET_TIME_Absolute expiration, 4318 struct GNUNET_TIME_Absolute expiration,
4463 const void *addr, 4319 const void *addr, uint16_t addrlen)
4464 uint16_t addrlen)
4465{ 4320{
4466 struct CheckHelloValidatedContext *chvc = cls; 4321 struct CheckHelloValidatedContext *chvc = cls;
4467 struct GNUNET_PeerIdentity id; 4322 struct GNUNET_PeerIdentity id;
@@ -4474,57 +4329,53 @@ run_validation (void *cls,
4474 GNUNET_assert (addr != NULL); 4329 GNUNET_assert (addr != NULL);
4475 4330
4476 GNUNET_STATISTICS_update (stats, 4331 GNUNET_STATISTICS_update (stats,
4477 gettext_noop ("# peer addresses scheduled for validation"), 4332 gettext_noop
4478 1, 4333 ("# peer addresses scheduled for validation"), 1,
4479 GNUNET_NO); 4334 GNUNET_NO);
4480 tp = find_transport (tname); 4335 tp = find_transport (tname);
4481 if (tp == NULL) 4336 if (tp == NULL)
4482 { 4337 {
4483 GNUNET_log (GNUNET_ERROR_TYPE_INFO | 4338 GNUNET_log (GNUNET_ERROR_TYPE_INFO |
4484 GNUNET_ERROR_TYPE_BULK, 4339 GNUNET_ERROR_TYPE_BULK,
4485 _ 4340 _
4486 ("Transport `%s' not loaded, will not try to validate peer address using this transport.\n"), 4341 ("Transport `%s' not loaded, will not try to validate peer address using this transport.\n"),
4487 tname); 4342 tname);
4488 GNUNET_STATISTICS_update (stats, 4343 GNUNET_STATISTICS_update (stats,
4489 gettext_noop ("# peer addresses not validated (plugin not available)"), 4344 gettext_noop
4490 1, 4345 ("# peer addresses not validated (plugin not available)"),
4491 GNUNET_NO); 4346 1, GNUNET_NO);
4492 return GNUNET_OK; 4347 return GNUNET_OK;
4493 } 4348 }
4494 /* check if this is one of our own addresses */ 4349 /* check if this is one of our own addresses */
4495 oal = tp->addresses; 4350 oal = tp->addresses;
4496 while (NULL != oal) 4351 while (NULL != oal)
4352 {
4353 if ((oal->addrlen == addrlen) && (0 == memcmp (&oal[1], addr, addrlen)))
4497 { 4354 {
4498 if ( (oal->addrlen == addrlen) && 4355 /* not plausible, this address is equivalent to our own address! */
4499 (0 == memcmp (&oal[1], 4356 GNUNET_STATISTICS_update (stats,
4500 addr, 4357 gettext_noop
4501 addrlen)) ) 4358 ("# peer addresses not validated (loopback)"),
4502 { 4359 1, GNUNET_NO);
4503 /* not plausible, this address is equivalent to our own address! */ 4360 return GNUNET_OK;
4504 GNUNET_STATISTICS_update (stats,
4505 gettext_noop ("# peer addresses not validated (loopback)"),
4506 1,
4507 GNUNET_NO);
4508 return GNUNET_OK;
4509 }
4510 oal = oal->next;
4511 } 4361 }
4362 oal = oal->next;
4363 }
4512 GNUNET_HELLO_get_key (chvc->hello, &pk); 4364 GNUNET_HELLO_get_key (chvc->hello, &pk);
4513 GNUNET_CRYPTO_hash (&pk, 4365 GNUNET_CRYPTO_hash (&pk,
4514 sizeof (struct 4366 sizeof (struct
4515 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), 4367 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
4516 &id.hashPubKey); 4368 &id.hashPubKey);
4517 4369
4518 if (is_blacklisted(&id, tp)) 4370 if (is_blacklisted (&id, tp))
4519 { 4371 {
4520#if DEBUG_TRANSPORT 4372#if DEBUG_TRANSPORT
4521 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4373 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4522 "Attempted to validate blacklisted peer `%s' using `%s'!\n", 4374 "Attempted to validate blacklisted peer `%s' using `%s'!\n",
4523 GNUNET_i2s(&id), 4375 GNUNET_i2s (&id), tname);
4524 tname);
4525#endif 4376#endif
4526 return GNUNET_OK; 4377 return GNUNET_OK;
4527 } 4378 }
4528 4379
4529 caec.addr = addr; 4380 caec.addr = addr;
4530 caec.addrlen = addrlen; 4381 caec.addrlen = addrlen;
@@ -4532,49 +4383,43 @@ run_validation (void *cls,
4532 caec.tname = tname; 4383 caec.tname = tname;
4533 caec.exists = GNUNET_NO; 4384 caec.exists = GNUNET_NO;
4534 GNUNET_CONTAINER_multihashmap_iterate (validation_map, 4385 GNUNET_CONTAINER_multihashmap_iterate (validation_map,
4535 &check_address_exists, 4386 &check_address_exists, &caec);
4536 &caec);
4537 if (caec.exists == GNUNET_YES) 4387 if (caec.exists == GNUNET_YES)
4538 { 4388 {
4539 /* During validation attempts we will likely trigger the other 4389 /* During validation attempts we will likely trigger the other
4540 peer trying to validate our address which in turn will cause 4390 * peer trying to validate our address which in turn will cause
4541 it to send us its HELLO, so we expect to hit this case rather 4391 * it to send us its HELLO, so we expect to hit this case rather
4542 frequently. Only print something if we are very verbose. */ 4392 * frequently. Only print something if we are very verbose. */
4543#if DEBUG_TRANSPORT > 1 4393#if DEBUG_TRANSPORT > 1
4544 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4394 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4545 "Validation of address `%s' via `%s' for peer `%4s' already in progress.\n", 4395 "Validation of address `%s' via `%s' for peer `%4s' already in progress.\n",
4546 a2s (tname, addr, addrlen), 4396 a2s (tname, addr, addrlen), tname, GNUNET_i2s (&id));
4547 tname,
4548 GNUNET_i2s (&id));
4549#endif 4397#endif
4550 GNUNET_STATISTICS_update (stats, 4398 GNUNET_STATISTICS_update (stats,
4551 gettext_noop ("# peer addresses not validated (in progress)"), 4399 gettext_noop
4552 1, 4400 ("# peer addresses not validated (in progress)"),
4553 GNUNET_NO); 4401 1, GNUNET_NO);
4554 return GNUNET_OK; 4402 return GNUNET_OK;
4555 } 4403 }
4556 va = GNUNET_malloc (sizeof (struct ValidationEntry) + addrlen); 4404 va = GNUNET_malloc (sizeof (struct ValidationEntry) + addrlen);
4557 va->chvc = chvc; 4405 va->chvc = chvc;
4558 chvc->ve_count++; 4406 chvc->ve_count++;
4559 va->transport_name = GNUNET_strdup (tname); 4407 va->transport_name = GNUNET_strdup (tname);
4560 va->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, 4408 va->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
4561 UINT_MAX); 4409 UINT_MAX);
4562 va->send_time = GNUNET_TIME_absolute_get(); 4410 va->send_time = GNUNET_TIME_absolute_get ();
4563 va->addr = (const void*) &va[1]; 4411 va->addr = (const void *) &va[1];
4564 memcpy (&va[1], addr, addrlen); 4412 memcpy (&va[1], addr, addrlen);
4565 va->addrlen = addrlen; 4413 va->addrlen = addrlen;
4566 GNUNET_HELLO_get_key (chvc->hello, 4414 GNUNET_HELLO_get_key (chvc->hello, &va->publicKey);
4567 &va->publicKey);
4568 va->timeout_task = GNUNET_SCHEDULER_add_delayed (HELLO_VERIFICATION_TIMEOUT, 4415 va->timeout_task = GNUNET_SCHEDULER_add_delayed (HELLO_VERIFICATION_TIMEOUT,
4569 &timeout_hello_validation, 4416 &timeout_hello_validation,
4570 va); 4417 va);
4571 GNUNET_CONTAINER_multihashmap_put (validation_map, 4418 GNUNET_CONTAINER_multihashmap_put (validation_map,
4572 &id.hashPubKey, 4419 &id.hashPubKey,
4573 va, 4420 va,
4574 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 4421 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
4575 setup_peer_check_blacklist (&id, GNUNET_NO, 4422 setup_peer_check_blacklist (&id, GNUNET_NO, &transmit_hello_and_ping, va);
4576 &transmit_hello_and_ping,
4577 va);
4578 return GNUNET_OK; 4423 return GNUNET_OK;
4579} 4424}
4580 4425
@@ -4601,111 +4446,98 @@ check_hello_validated (void *cls,
4601 struct NeighbourMapEntry *n; 4446 struct NeighbourMapEntry *n;
4602 4447
4603 if (err_msg != NULL) 4448 if (err_msg != NULL)
4604 { 4449 {
4605#if DEBUG_TRANSPORT 4450#if DEBUG_TRANSPORT
4606 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4451 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4607 _("Error in communication with PEERINFO service: %s\n"), 4452 _("Error in communication with PEERINFO service: %s\n"),
4608 err_msg); 4453 err_msg);
4609#endif 4454#endif
4610 /* return; */ 4455 /* return; */
4611 } 4456 }
4612 4457
4613 if (peer == NULL) 4458 if (peer == NULL)
4614 { 4459 {
4615 GNUNET_STATISTICS_update (stats, 4460 GNUNET_STATISTICS_update (stats,
4616 gettext_noop ("# outstanding peerinfo iterate requests"), 4461 gettext_noop
4617 -1, 4462 ("# outstanding peerinfo iterate requests"), -1,
4618 GNUNET_NO); 4463 GNUNET_NO);
4619 chvc->piter = NULL; 4464 chvc->piter = NULL;
4620 if (GNUNET_NO == chvc->hello_known) 4465 if (GNUNET_NO == chvc->hello_known)
4621 { 4466 {
4622 /* notify PEERINFO about the peer now, so that we at least 4467 /* notify PEERINFO about the peer now, so that we at least
4623 have the public key if some other component needs it */ 4468 * have the public key if some other component needs it */
4624 GNUNET_HELLO_get_key (chvc->hello, &pk); 4469 GNUNET_HELLO_get_key (chvc->hello, &pk);
4625 GNUNET_CRYPTO_hash (&pk, 4470 GNUNET_CRYPTO_hash (&pk,
4626 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), 4471 sizeof (struct
4627 &target.hashPubKey); 4472 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
4628 plain_hello = GNUNET_HELLO_create (&pk, 4473 &target.hashPubKey);
4629 NULL, 4474 plain_hello = GNUNET_HELLO_create (&pk, NULL, NULL);
4630 NULL); 4475 GNUNET_PEERINFO_add_peer (peerinfo, plain_hello);
4631 GNUNET_PEERINFO_add_peer (peerinfo, plain_hello); 4476 GNUNET_free (plain_hello);
4632 GNUNET_free (plain_hello);
4633#if DEBUG_TRANSPORT_HELLO 4477#if DEBUG_TRANSPORT_HELLO
4634 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4478 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4635 "PEERINFO had no `%s' message for peer `%4s', full validation needed.\n", 4479 "PEERINFO had no `%s' message for peer `%4s', full validation needed.\n",
4636 "HELLO", 4480 "HELLO", GNUNET_i2s (&target));
4637 GNUNET_i2s (&target));
4638#endif 4481#endif
4639 GNUNET_STATISTICS_update (stats, 4482 GNUNET_STATISTICS_update (stats,
4640 gettext_noop ("# new HELLOs requiring full validation"), 4483 gettext_noop
4641 1, 4484 ("# new HELLOs requiring full validation"), 1,
4642 GNUNET_NO); 4485 GNUNET_NO);
4643 GNUNET_HELLO_iterate_addresses (chvc->hello, 4486 GNUNET_HELLO_iterate_addresses (chvc->hello, GNUNET_NO, &run_validation,
4644 GNUNET_NO, 4487 chvc);
4645 &run_validation, 4488 }
4646 chvc); 4489 else
4647 } 4490 {
4648 else 4491 GNUNET_STATISTICS_update (stats,
4649 { 4492 gettext_noop ("# duplicate HELLO (peer known)"),
4650 GNUNET_STATISTICS_update (stats, 4493 1, GNUNET_NO);
4651 gettext_noop ("# duplicate HELLO (peer known)"), 4494 }
4652 1, 4495 chvc->ve_count--;
4653 GNUNET_NO); 4496 if (chvc->ve_count == 0)
4654 } 4497 {
4655 chvc->ve_count--; 4498 GNUNET_CONTAINER_DLL_remove (chvc_head, chvc_tail, chvc);
4656 if (chvc->ve_count == 0) 4499 GNUNET_free (chvc);
4657 {
4658 GNUNET_CONTAINER_DLL_remove (chvc_head,
4659 chvc_tail,
4660 chvc);
4661 GNUNET_free (chvc);
4662 }
4663 return;
4664 } 4500 }
4501 return;
4502 }
4665 if (h == NULL) 4503 if (h == NULL)
4666 return; 4504 return;
4667#if DEBUG_TRANSPORT_HELLO 4505#if DEBUG_TRANSPORT_HELLO
4668 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4506 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4669 "PEERINFO had `%s' message for peer `%4s', validating only new addresses.\n", 4507 "PEERINFO had `%s' message for peer `%4s', validating only new addresses.\n",
4670 "HELLO", 4508 "HELLO", GNUNET_i2s (peer));
4671 GNUNET_i2s (peer));
4672#endif 4509#endif
4673 chvc->hello_known = GNUNET_YES; 4510 chvc->hello_known = GNUNET_YES;
4674 n = find_neighbour (peer); 4511 n = find_neighbour (peer);
4675 if (n != NULL) 4512 if (n != NULL)
4676 { 4513 {
4677#if DEBUG_TRANSPORT_HELLO 4514#if DEBUG_TRANSPORT_HELLO
4678 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4515 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4679 "Calling hello_iterate_addresses for %s!\n", 4516 "Calling hello_iterate_addresses for %s!\n", GNUNET_i2s (peer));
4680 GNUNET_i2s (peer));
4681#endif 4517#endif
4682 GNUNET_HELLO_iterate_addresses (h, 4518 GNUNET_HELLO_iterate_addresses (h,
4683 GNUNET_NO, 4519 GNUNET_NO, &add_to_foreign_address_list, n);
4684 &add_to_foreign_address_list, 4520 try_transmission_to_peer (n);
4685 n); 4521 }
4686 try_transmission_to_peer (n);
4687 }
4688 else 4522 else
4689 { 4523 {
4690#if DEBUG_TRANSPORT_HELLO 4524#if DEBUG_TRANSPORT_HELLO
4691 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4525 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4692 "No existing neighbor record for %s!\n", 4526 "No existing neighbor record for %s!\n", GNUNET_i2s (peer));
4693 GNUNET_i2s (peer));
4694#endif 4527#endif
4695 GNUNET_STATISTICS_update (stats, 4528 GNUNET_STATISTICS_update (stats,
4696 gettext_noop ("# no existing neighbour record (validating HELLO)"), 4529 gettext_noop
4697 1, 4530 ("# no existing neighbour record (validating HELLO)"),
4698 GNUNET_NO); 4531 1, GNUNET_NO);
4699 } 4532 }
4700 GNUNET_STATISTICS_update (stats, 4533 GNUNET_STATISTICS_update (stats,
4701 gettext_noop ("# HELLO validations (update case)"), 4534 gettext_noop ("# HELLO validations (update case)"),
4702 1, 4535 1, GNUNET_NO);
4703 GNUNET_NO);
4704 GNUNET_HELLO_iterate_new_addresses (chvc->hello, 4536 GNUNET_HELLO_iterate_new_addresses (chvc->hello,
4705 h, 4537 h,
4706 GNUNET_TIME_relative_to_absolute (HELLO_REVALIDATION_START_TIME), 4538 GNUNET_TIME_relative_to_absolute
4707 &run_validation, 4539 (HELLO_REVALIDATION_START_TIME),
4708 chvc); 4540 &run_validation, chvc);
4709} 4541}
4710 4542
4711 4543
@@ -4726,6 +4558,7 @@ process_hello (struct TransportPlugin *plugin,
4726 struct CheckHelloValidatedContext *chvc; 4558 struct CheckHelloValidatedContext *chvc;
4727 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded publicKey; 4559 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded publicKey;
4728 struct NeighbourMapEntry *n; 4560 struct NeighbourMapEntry *n;
4561
4729#if DEBUG_TRANSPORT_HELLO > 2 4562#if DEBUG_TRANSPORT_HELLO > 2
4730 char *my_id; 4563 char *my_id;
4731#endif 4564#endif
@@ -4733,27 +4566,25 @@ process_hello (struct TransportPlugin *plugin,
4733 hsize = ntohs (message->size); 4566 hsize = ntohs (message->size);
4734 if ((ntohs (message->type) != GNUNET_MESSAGE_TYPE_HELLO) || 4567 if ((ntohs (message->type) != GNUNET_MESSAGE_TYPE_HELLO) ||
4735 (hsize < sizeof (struct GNUNET_MessageHeader))) 4568 (hsize < sizeof (struct GNUNET_MessageHeader)))
4736 { 4569 {
4737 GNUNET_break (0); 4570 GNUNET_break (0);
4738 return GNUNET_SYSERR; 4571 return GNUNET_SYSERR;
4739 } 4572 }
4740 GNUNET_STATISTICS_update (stats, 4573 GNUNET_STATISTICS_update (stats,
4741 gettext_noop ("# HELLOs received for validation"), 4574 gettext_noop ("# HELLOs received for validation"),
4742 1, 4575 1, GNUNET_NO);
4743 GNUNET_NO);
4744 4576
4745 hello = (const struct GNUNET_HELLO_Message *) message; 4577 hello = (const struct GNUNET_HELLO_Message *) message;
4746 if (GNUNET_OK != GNUNET_HELLO_get_key (hello, &publicKey)) 4578 if (GNUNET_OK != GNUNET_HELLO_get_key (hello, &publicKey))
4747 { 4579 {
4748#if DEBUG_TRANSPORT_HELLO 4580#if DEBUG_TRANSPORT_HELLO
4749 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4581 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4750 "Unable to get public key from `%s' for `%4s'!\n", 4582 "Unable to get public key from `%s' for `%4s'!\n",
4751 "HELLO", 4583 "HELLO", GNUNET_i2s (&target));
4752 GNUNET_i2s (&target));
4753#endif 4584#endif
4754 GNUNET_break_op (0); 4585 GNUNET_break_op (0);
4755 return GNUNET_SYSERR; 4586 return GNUNET_SYSERR;
4756 } 4587 }
4757 GNUNET_CRYPTO_hash (&publicKey, 4588 GNUNET_CRYPTO_hash (&publicKey,
4758 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), 4589 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
4759 &target.hashPubKey); 4590 &target.hashPubKey);
@@ -4761,111 +4592,103 @@ process_hello (struct TransportPlugin *plugin,
4761#if DEBUG_TRANSPORT_HELLO 4592#if DEBUG_TRANSPORT_HELLO
4762 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4593 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4763 "Received `%s' message for `%4s'\n", 4594 "Received `%s' message for `%4s'\n",
4764 "HELLO", 4595 "HELLO", GNUNET_i2s (&target));
4765 GNUNET_i2s (&target));
4766#endif 4596#endif
4767 if (0 == memcmp (&my_identity, 4597 if (0 == memcmp (&my_identity, &target, sizeof (struct GNUNET_PeerIdentity)))
4768 &target, 4598 {
4769 sizeof (struct GNUNET_PeerIdentity))) 4599 GNUNET_STATISTICS_update (stats,
4770 { 4600 gettext_noop
4771 GNUNET_STATISTICS_update (stats, 4601 ("# HELLOs ignored for validation (is my own HELLO)"),
4772 gettext_noop ("# HELLOs ignored for validation (is my own HELLO)"), 4602 1, GNUNET_NO);
4773 1, 4603 return GNUNET_OK;
4774 GNUNET_NO); 4604 }
4775 return GNUNET_OK;
4776 }
4777 n = find_neighbour (&target); 4605 n = find_neighbour (&target);
4778 if ( (NULL != n) && 4606 if ((NULL != n) && (!n->public_key_valid))
4779 (! n->public_key_valid) ) 4607 {
4780 { 4608 GNUNET_HELLO_get_key (hello, &n->publicKey);
4781 GNUNET_HELLO_get_key (hello, &n->publicKey); 4609 n->public_key_valid = GNUNET_YES;
4782 n->public_key_valid = GNUNET_YES; 4610 }
4783 }
4784 4611
4785 /* check if load is too high before doing expensive stuff */ 4612 /* check if load is too high before doing expensive stuff */
4786 if (GNUNET_SCHEDULER_get_load (GNUNET_SCHEDULER_PRIORITY_BACKGROUND) > MAX_HELLO_LOAD) 4613 if (GNUNET_SCHEDULER_get_load (GNUNET_SCHEDULER_PRIORITY_BACKGROUND) >
4787 { 4614 MAX_HELLO_LOAD)
4788 GNUNET_STATISTICS_update (stats, 4615 {
4789 gettext_noop ("# HELLOs ignored due to high load"), 4616 GNUNET_STATISTICS_update (stats,
4790 1, 4617 gettext_noop
4791 GNUNET_NO); 4618 ("# HELLOs ignored due to high load"), 1,
4619 GNUNET_NO);
4792#if DEBUG_TRANSPORT_HELLO 4620#if DEBUG_TRANSPORT_HELLO
4793 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4621 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4794 "Ignoring `%s' for `%4s', load too high.\n", 4622 "Ignoring `%s' for `%4s', load too high.\n",
4795 "HELLO", 4623 "HELLO", GNUNET_i2s (&target));
4796 GNUNET_i2s (&target));
4797#endif 4624#endif
4798 return GNUNET_OK; 4625 return GNUNET_OK;
4799 } 4626 }
4800 4627
4801 4628
4802 chvc = chvc_head; 4629 chvc = chvc_head;
4803 while (NULL != chvc) 4630 while (NULL != chvc)
4631 {
4632 if (GNUNET_HELLO_equals (hello,
4633 chvc->hello,
4634 GNUNET_TIME_absolute_get ()).abs_value > 0)
4804 { 4635 {
4805 if (GNUNET_HELLO_equals (hello,
4806 chvc->hello,
4807 GNUNET_TIME_absolute_get ()).abs_value > 0)
4808 {
4809#if DEBUG_TRANSPORT_HELLO > 2 4636#if DEBUG_TRANSPORT_HELLO > 2
4810 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4637 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4811 "Received duplicate `%s' message for `%4s'; ignored\n", 4638 "Received duplicate `%s' message for `%4s'; ignored\n",
4812 "HELLO", 4639 "HELLO", GNUNET_i2s (&target));
4813 GNUNET_i2s (&target));
4814#endif 4640#endif
4815 return GNUNET_OK; /* validation already pending */ 4641 return GNUNET_OK; /* validation already pending */
4816 }
4817 if (GNUNET_HELLO_size (hello) == GNUNET_HELLO_size (chvc->hello))
4818 GNUNET_break (0 != memcmp (hello, chvc->hello,
4819 GNUNET_HELLO_size(hello)));
4820 chvc = chvc->next;
4821 } 4642 }
4643 if (GNUNET_HELLO_size (hello) == GNUNET_HELLO_size (chvc->hello))
4644 GNUNET_break (0 != memcmp (hello, chvc->hello,
4645 GNUNET_HELLO_size (hello)));
4646 chvc = chvc->next;
4647 }
4822 4648
4823#if BREAK_TESTS 4649#if BREAK_TESTS
4824 struct NeighbourMapEntry *temp_neighbor = find_neighbour(&target); 4650 struct NeighbourMapEntry *temp_neighbor = find_neighbour (&target);
4651
4825 if ((NULL != temp_neighbor)) 4652 if ((NULL != temp_neighbor))
4826 { 4653 {
4827 fprintf(stderr, "Already know peer, ignoring hello\n"); 4654 fprintf (stderr, "Already know peer, ignoring hello\n");
4828 return GNUNET_OK; 4655 return GNUNET_OK;
4829 } 4656 }
4830#endif 4657#endif
4831 4658
4832#if DEBUG_TRANSPORT_HELLO > 2 4659#if DEBUG_TRANSPORT_HELLO > 2
4833 if (plugin != NULL) 4660 if (plugin != NULL)
4834 { 4661 {
4835#if DEBUG_TRANSPORT 4662#if DEBUG_TRANSPORT
4836 my_id = GNUNET_strdup(GNUNET_i2s(plugin->env.my_identity)); 4663 my_id = GNUNET_strdup (GNUNET_i2s (plugin->env.my_identity));
4837 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4664 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4838 "%s: Starting validation of `%s' message for `%4s' via '%s' of size %u\n", 4665 "%s: Starting validation of `%s' message for `%4s' via '%s' of size %u\n",
4839 my_id, 4666 my_id,
4840 "HELLO", 4667 "HELLO",
4841 GNUNET_i2s (&target), 4668 GNUNET_i2s (&target),
4842 plugin->short_name, 4669 plugin->short_name, GNUNET_HELLO_size (hello));
4843 GNUNET_HELLO_size(hello)); 4670 GNUNET_free (my_id);
4844 GNUNET_free (my_id);
4845#endif 4671#endif
4846 } 4672 }
4847#endif 4673#endif
4848 chvc = GNUNET_malloc (sizeof (struct CheckHelloValidatedContext) + hsize); 4674 chvc = GNUNET_malloc (sizeof (struct CheckHelloValidatedContext) + hsize);
4849 chvc->ve_count = 1; 4675 chvc->ve_count = 1;
4850 chvc->hello = (const struct GNUNET_HELLO_Message *) &chvc[1]; 4676 chvc->hello = (const struct GNUNET_HELLO_Message *) &chvc[1];
4851 memcpy (&chvc[1], hello, hsize); 4677 memcpy (&chvc[1], hello, hsize);
4852 GNUNET_CONTAINER_DLL_insert (chvc_head, 4678 GNUNET_CONTAINER_DLL_insert (chvc_head, chvc_tail, chvc);
4853 chvc_tail,
4854 chvc);
4855 /* finally, check if HELLO was previously validated 4679 /* finally, check if HELLO was previously validated
4856 (continuation will then schedule actual validation) */ 4680 * (continuation will then schedule actual validation) */
4857 GNUNET_STATISTICS_update (stats, 4681 GNUNET_STATISTICS_update (stats,
4858 gettext_noop ("# peerinfo process hello iterate requests"), 4682 gettext_noop
4859 1, 4683 ("# peerinfo process hello iterate requests"), 1,
4860 GNUNET_NO); 4684 GNUNET_NO);
4861 GNUNET_STATISTICS_update (stats, 4685 GNUNET_STATISTICS_update (stats,
4862 gettext_noop ("# outstanding peerinfo iterate requests"), 4686 gettext_noop
4863 1, 4687 ("# outstanding peerinfo iterate requests"), 1,
4864 GNUNET_NO); 4688 GNUNET_NO);
4865 chvc->piter = GNUNET_PEERINFO_iterate (peerinfo, 4689 chvc->piter =
4866 &target, 4690 GNUNET_PEERINFO_iterate (peerinfo, &target, HELLO_VERIFICATION_TIMEOUT,
4867 HELLO_VERIFICATION_TIMEOUT, 4691 &check_hello_validated, chvc);
4868 &check_hello_validated, chvc);
4869 return GNUNET_OK; 4692 return GNUNET_OK;
4870} 4693}
4871 4694
@@ -4894,144 +4717,134 @@ disconnect_neighbour (struct NeighbourMapEntry *n, int check)
4894 if (GNUNET_YES == n->in_disconnect) 4717 if (GNUNET_YES == n->in_disconnect)
4895 return; 4718 return;
4896 if (GNUNET_YES == check) 4719 if (GNUNET_YES == check)
4720 {
4721 rpos = n->plugins;
4722 while (NULL != rpos)
4897 { 4723 {
4898 rpos = n->plugins; 4724 peer_addresses = rpos->addresses;
4899 while (NULL != rpos) 4725 while (peer_addresses != NULL)
4726 {
4727 /* Do not disconnect if: an address is connected or an inbound address exists */
4728 if ((GNUNET_YES == peer_addresses->connected) ||
4729 (peer_addresses->addrlen == 0))
4900 { 4730 {
4901 peer_addresses = rpos->addresses;
4902 while (peer_addresses != NULL)
4903 {
4904 /* Do not disconnect if: an address is connected or an inbound address exists */
4905 if ((GNUNET_YES == peer_addresses->connected) || (peer_addresses->addrlen == 0))
4906 {
4907#if DEBUG_TRANSPORT 4731#if DEBUG_TRANSPORT
4908 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4732 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4909 "NOT Disconnecting from `%4s', still have live address `%s'!\n", 4733 "NOT Disconnecting from `%4s', still have live address `%s'!\n",
4910 GNUNET_i2s (&n->id), 4734 GNUNET_i2s (&n->id),
4911 a2s (peer_addresses->ready_list->plugin->short_name, 4735 a2s (peer_addresses->ready_list->plugin->short_name,
4912 peer_addresses->addr, 4736 peer_addresses->addr, peer_addresses->addrlen));
4913 peer_addresses->addrlen));
4914#endif 4737#endif
4915 return; /* still connected */ 4738 return; /* still connected */
4916 }
4917 peer_addresses = peer_addresses->next;
4918 }
4919 rpos = rpos->next;
4920 } 4739 }
4740 peer_addresses = peer_addresses->next;
4741 }
4742 rpos = rpos->next;
4921 } 4743 }
4744 }
4922#if DEBUG_TRANSPORT 4745#if DEBUG_TRANSPORT
4923 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 4746 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
4924 "Disconnecting from `%4s'\n", 4747 "Disconnecting from `%4s'\n", GNUNET_i2s (&n->id));
4925 GNUNET_i2s (&n->id));
4926#endif 4748#endif
4927 n->in_disconnect = GNUNET_YES; /* prevent recursive entry */ 4749 n->in_disconnect = GNUNET_YES; /* prevent recursive entry */
4928 4750
4929 /* notify all clients about disconnect */ 4751 /* notify all clients about disconnect */
4930 if (GNUNET_YES == n->received_pong) 4752 if (GNUNET_YES == n->received_pong)
4931 { 4753 {
4932 n->received_pong = GNUNET_NO; 4754 n->received_pong = GNUNET_NO;
4933 notify_clients_disconnect (&n->id); 4755 notify_clients_disconnect (&n->id);
4934 } 4756 }
4935#if HAVE_LIBGLPK 4757#if HAVE_LIBGLPK
4936 ats_modify_problem_state(ats, ATS_MODIFIED); 4758 ats_modify_problem_state (ats, ATS_MODIFIED);
4937#endif 4759#endif
4938 /* clean up all plugins, cancel connections and pending transmissions */ 4760 /* clean up all plugins, cancel connections and pending transmissions */
4939 while (NULL != (rpos = n->plugins)) 4761 while (NULL != (rpos = n->plugins))
4762 {
4763 n->plugins = rpos->next;
4764 rpos->plugin->api->disconnect (rpos->plugin->api->cls, &n->id);
4765 while (rpos->addresses != NULL)
4940 { 4766 {
4941 n->plugins = rpos->next; 4767 peer_pos = rpos->addresses;
4942 rpos->plugin->api->disconnect (rpos->plugin->api->cls, &n->id); 4768 rpos->addresses = peer_pos->next;
4943 while (rpos->addresses != NULL) 4769 if (peer_pos->connected == GNUNET_YES)
4944 { 4770 {
4945 peer_pos = rpos->addresses; 4771 GNUNET_STATISTICS_update (stats,
4946 rpos->addresses = peer_pos->next; 4772 gettext_noop ("# connected addresses"),
4947 if (peer_pos->connected == GNUNET_YES) 4773 -1, GNUNET_NO);
4948 { 4774 peer_pos->connected = GNUNET_NO;
4949 GNUNET_STATISTICS_update (stats, 4775 }
4950 gettext_noop ("# connected addresses"), 4776 if (GNUNET_YES == peer_pos->validated)
4951 -1, 4777 GNUNET_STATISTICS_update (stats,
4952 GNUNET_NO); 4778 gettext_noop
4953 peer_pos->connected = GNUNET_NO; 4779 ("# peer addresses considered valid"), -1,
4954 } 4780 GNUNET_NO);
4955 if (GNUNET_YES == peer_pos->validated) 4781 if (GNUNET_SCHEDULER_NO_TASK != peer_pos->revalidate_task)
4956 GNUNET_STATISTICS_update (stats, 4782 {
4957 gettext_noop ("# peer addresses considered valid"), 4783 GNUNET_SCHEDULER_cancel (peer_pos->revalidate_task);
4958 -1, 4784 peer_pos->revalidate_task = GNUNET_SCHEDULER_NO_TASK;
4959 GNUNET_NO); 4785 }
4960 if (GNUNET_SCHEDULER_NO_TASK != peer_pos->revalidate_task) 4786 GNUNET_free (peer_pos->ressources);
4961 { 4787 peer_pos->ressources = NULL;
4962 GNUNET_SCHEDULER_cancel (peer_pos->revalidate_task); 4788 GNUNET_free (peer_pos->quality);
4963 peer_pos->revalidate_task = GNUNET_SCHEDULER_NO_TASK; 4789 peer_pos->ressources = NULL;
4964 } 4790 GNUNET_free (peer_pos);
4965 GNUNET_free (peer_pos->ressources);
4966 peer_pos->ressources = NULL;
4967 GNUNET_free (peer_pos->quality);
4968 peer_pos->ressources = NULL;
4969 GNUNET_free (peer_pos);
4970 }
4971 GNUNET_free (rpos);
4972 } 4791 }
4792 GNUNET_free (rpos);
4793 }
4973 4794
4974 /* free all messages on the queue */ 4795 /* free all messages on the queue */
4975 while (NULL != (mq = n->messages_head)) 4796 while (NULL != (mq = n->messages_head))
4976 { 4797 {
4977 GNUNET_STATISTICS_update (stats, 4798 GNUNET_STATISTICS_update (stats,
4978 gettext_noop ("# bytes in message queue for other peers"), 4799 gettext_noop
4979 - (int64_t) mq->message_buf_size, 4800 ("# bytes in message queue for other peers"),
4980 GNUNET_NO); 4801 -(int64_t) mq->message_buf_size, GNUNET_NO);
4981 GNUNET_STATISTICS_update (stats, 4802 GNUNET_STATISTICS_update (stats,
4982 gettext_noop ("# bytes discarded due to disconnect"), 4803 gettext_noop
4983 mq->message_buf_size, 4804 ("# bytes discarded due to disconnect"),
4984 GNUNET_NO); 4805 mq->message_buf_size, GNUNET_NO);
4985 GNUNET_CONTAINER_DLL_remove (n->messages_head, 4806 GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq);
4986 n->messages_tail, 4807 GNUNET_assert (0 == memcmp (&mq->neighbour_id,
4987 mq); 4808 &n->id, sizeof (struct GNUNET_PeerIdentity)));
4988 GNUNET_assert (0 == memcmp(&mq->neighbour_id, 4809 GNUNET_free (mq);
4989 &n->id, 4810 }
4990 sizeof(struct GNUNET_PeerIdentity)));
4991 GNUNET_free (mq);
4992 }
4993 4811
4994 while (NULL != (mq = n->cont_head)) 4812 while (NULL != (mq = n->cont_head))
4995 { 4813 {
4996 4814
4997 GNUNET_CONTAINER_DLL_remove (n->cont_head, 4815 GNUNET_CONTAINER_DLL_remove (n->cont_head, n->cont_tail, mq);
4998 n->cont_tail, 4816 GNUNET_assert (0 == memcmp (&mq->neighbour_id,
4999 mq); 4817 &n->id, sizeof (struct GNUNET_PeerIdentity)));
5000 GNUNET_assert (0 == memcmp(&mq->neighbour_id, 4818 GNUNET_free (mq);
5001 &n->id, 4819 }
5002 sizeof(struct GNUNET_PeerIdentity)));
5003 GNUNET_free (mq);
5004 }
5005 4820
5006 if (n->timeout_task != GNUNET_SCHEDULER_NO_TASK) 4821 if (n->timeout_task != GNUNET_SCHEDULER_NO_TASK)
5007 { 4822 {
5008 GNUNET_SCHEDULER_cancel (n->timeout_task); 4823 GNUNET_SCHEDULER_cancel (n->timeout_task);
5009 n->timeout_task = GNUNET_SCHEDULER_NO_TASK; 4824 n->timeout_task = GNUNET_SCHEDULER_NO_TASK;
5010 } 4825 }
5011 if (n->retry_task != GNUNET_SCHEDULER_NO_TASK) 4826 if (n->retry_task != GNUNET_SCHEDULER_NO_TASK)
5012 { 4827 {
5013 GNUNET_SCHEDULER_cancel (n->retry_task); 4828 GNUNET_SCHEDULER_cancel (n->retry_task);
5014 n->retry_task = GNUNET_SCHEDULER_NO_TASK; 4829 n->retry_task = GNUNET_SCHEDULER_NO_TASK;
5015 } 4830 }
5016 if (n->piter != NULL) 4831 if (n->piter != NULL)
5017 { 4832 {
5018 GNUNET_PEERINFO_iterate_cancel (n->piter); 4833 GNUNET_PEERINFO_iterate_cancel (n->piter);
5019 GNUNET_STATISTICS_update (stats, 4834 GNUNET_STATISTICS_update (stats,
5020 gettext_noop ("# outstanding peerinfo iterate requests"), 4835 gettext_noop
5021 -1, 4836 ("# outstanding peerinfo iterate requests"), -1,
5022 GNUNET_NO); 4837 GNUNET_NO);
5023 n->piter = NULL; 4838 n->piter = NULL;
5024 } 4839 }
5025 4840
5026 GNUNET_assert (GNUNET_OK == 4841 GNUNET_assert (GNUNET_OK ==
5027 GNUNET_CONTAINER_multihashmap_remove (neighbours, 4842 GNUNET_CONTAINER_multihashmap_remove (neighbours,
5028 &n->id.hashPubKey, 4843 &n->id.hashPubKey, n));
5029 n));
5030 /* finally, free n itself */ 4844 /* finally, free n itself */
5031 GNUNET_STATISTICS_update (stats, 4845 GNUNET_STATISTICS_update (stats,
5032 gettext_noop ("# active neighbours"), 4846 gettext_noop ("# active neighbours"),
5033 -1, 4847 -1, GNUNET_NO);
5034 GNUNET_NO);
5035 GNUNET_free_non_null (n->pre_connect_message_buffer); 4848 GNUNET_free_non_null (n->pre_connect_message_buffer);
5036 GNUNET_free (n); 4849 GNUNET_free (n);
5037} 4850}
@@ -5043,13 +4856,12 @@ disconnect_neighbour (struct NeighbourMapEntry *n, int check)
5043 */ 4856 */
5044static int 4857static int
5045handle_ping (void *cls, const struct GNUNET_MessageHeader *message, 4858handle_ping (void *cls, const struct GNUNET_MessageHeader *message,
5046 const struct GNUNET_PeerIdentity *peer, 4859 const struct GNUNET_PeerIdentity *peer,
5047 struct Session *session, 4860 struct Session *session,
5048 const char *sender_address, 4861 const char *sender_address, uint16_t sender_address_len)
5049 uint16_t sender_address_len)
5050{ 4862{
5051 struct TransportPlugin *plugin = cls; 4863 struct TransportPlugin *plugin = cls;
5052 struct SessionHeader *session_header = (struct SessionHeader*) session; 4864 struct SessionHeader *session_header = (struct SessionHeader *) session;
5053 struct TransportPingMessage *ping; 4865 struct TransportPingMessage *ping;
5054 struct TransportPongMessage *pong; 4866 struct TransportPongMessage *pong;
5055 struct NeighbourMapEntry *n; 4867 struct NeighbourMapEntry *n;
@@ -5062,266 +4874,252 @@ handle_ping (void *cls, const struct GNUNET_MessageHeader *message,
5062 int did_pong; 4874 int did_pong;
5063 4875
5064 if (ntohs (message->size) < sizeof (struct TransportPingMessage)) 4876 if (ntohs (message->size) < sizeof (struct TransportPingMessage))
5065 { 4877 {
5066 GNUNET_break_op (0); 4878 GNUNET_break_op (0);
5067 return GNUNET_SYSERR; 4879 return GNUNET_SYSERR;
5068 } 4880 }
5069 4881
5070 ping = (struct TransportPingMessage *) message; 4882 ping = (struct TransportPingMessage *) message;
5071 if (0 != memcmp (&ping->target, 4883 if (0 != memcmp (&ping->target,
5072 plugin->env.my_identity, 4884 plugin->env.my_identity,
5073 sizeof (struct GNUNET_PeerIdentity))) 4885 sizeof (struct GNUNET_PeerIdentity)))
5074 { 4886 {
5075#if DEBUG_TRANSPORT 4887#if DEBUG_TRANSPORT
5076 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4888 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5077 _("Received `%s' message from `%s' destined for `%s' which is not me!\n"), 4889 _
5078 "PING", 4890 ("Received `%s' message from `%s' destined for `%s' which is not me!\n"),
5079 (sender_address != NULL) 4891 "PING", (sender_address != NULL) ? a2s (plugin->short_name,
5080 ? a2s (plugin->short_name, 4892 (const struct sockaddr
5081 (const struct sockaddr *)sender_address, 4893 *) sender_address,
5082 sender_address_len) 4894 sender_address_len) :
5083 : "<inbound>", 4895 "<inbound>", GNUNET_i2s (&ping->target));
5084 GNUNET_i2s (&ping->target));
5085#endif 4896#endif
5086 return GNUNET_SYSERR; 4897 return GNUNET_SYSERR;
5087 } 4898 }
5088#if DEBUG_PING_PONG 4899#if DEBUG_PING_PONG
5089 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 4900 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
5090 "Processing `%s' from `%s'\n", 4901 "Processing `%s' from `%s'\n",
5091 "PING", 4902 "PING",
5092 (sender_address != NULL) 4903 (sender_address != NULL)
5093 ? a2s (plugin->short_name, 4904 ? a2s (plugin->short_name,
5094 (const struct sockaddr *)sender_address, 4905 (const struct sockaddr *) sender_address,
5095 sender_address_len) 4906 sender_address_len) : "<inbound>");
5096 : "<inbound>");
5097#endif 4907#endif
5098 GNUNET_STATISTICS_update (stats, 4908 GNUNET_STATISTICS_update (stats,
5099 gettext_noop ("# PING messages received"), 4909 gettext_noop ("# PING messages received"),
5100 1, 4910 1, GNUNET_NO);
5101 GNUNET_NO); 4911 addr = (const char *) &ping[1];
5102 addr = (const char*) &ping[1];
5103 alen = ntohs (message->size) - sizeof (struct TransportPingMessage); 4912 alen = ntohs (message->size) - sizeof (struct TransportPingMessage);
5104 slen = strlen (plugin->short_name) + 1; 4913 slen = strlen (plugin->short_name) + 1;
5105 if (alen == 0) 4914 if (alen == 0)
4915 {
4916 /* peer wants to confirm that we have an outbound connection to him */
4917 if (session == NULL)
5106 { 4918 {
5107 /* peer wants to confirm that we have an outbound connection to him */ 4919 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
5108 if (session == NULL) 4920 _
5109 { 4921 ("Refusing to create PONG since I do not have a session with `%s'.\n"),
5110 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 4922 GNUNET_i2s (peer));
5111 _("Refusing to create PONG since I do not have a session with `%s'.\n"), 4923 return GNUNET_SYSERR;
5112 GNUNET_i2s (peer)); 4924 }
5113 return GNUNET_SYSERR; 4925 /* FIXME-urg: the use of 'sender_address' in the code below is doubly-wrong:
5114 } 4926 * 1) it is NULL when we need to have a real value
5115 /* FIXME-urg: the use of 'sender_address' in the code below is doubly-wrong: 4927 * 2) it is documented to be the address of the sender (source-IP), where
5116 1) it is NULL when we need to have a real value 4928 * what we actually want is our LISTEN IP (what we 'bound' to); which we don't even
5117 2) it is documented to be the address of the sender (source-IP), where 4929 * have...
5118 what we actually want is our LISTEN IP (what we 'bound' to); which we don't even 4930 */
5119 have... 4931 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5120 */ 4932 "Creating PONG indicating that we received a connection at our address `%s' from `%s'.\n",
5121 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4933 a2s (plugin->short_name,
5122 "Creating PONG indicating that we received a connection at our address `%s' from `%s'.\n", 4934 sender_address, sender_address_len), GNUNET_i2s (peer));
5123 a2s (plugin->short_name, 4935
5124 sender_address, 4936 pong =
5125 sender_address_len), 4937 GNUNET_malloc (sizeof (struct TransportPongMessage) +
5126 GNUNET_i2s (peer)); 4938 sender_address_len + slen);
5127 4939 pong->header.size =
5128 pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + sender_address_len + slen); 4940 htons (sizeof (struct TransportPongMessage) + sender_address_len +
5129 pong->header.size = htons (sizeof (struct TransportPongMessage) + sender_address_len + slen); 4941 slen);
5130 pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG); 4942 pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG);
5131 pong->purpose.size = 4943 pong->purpose.size =
5132 htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + 4944 htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
5133 sizeof (uint32_t) + 4945 sizeof (uint32_t) +
5134 sizeof (struct GNUNET_TIME_AbsoluteNBO) + 4946 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
5135 sizeof (struct GNUNET_PeerIdentity) + sender_address_len + slen); 4947 sizeof (struct GNUNET_PeerIdentity) + sender_address_len + slen);
5136 pong->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_USING); 4948 pong->purpose.purpose =
5137 pong->challenge = ping->challenge; 4949 htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_USING);
5138 pong->addrlen = htonl(sender_address_len + slen); 4950 pong->challenge = ping->challenge;
5139 memcpy(&pong->pid, 4951 pong->addrlen = htonl (sender_address_len + slen);
5140 peer, 4952 memcpy (&pong->pid, peer, sizeof (struct GNUNET_PeerIdentity));
5141 sizeof(struct GNUNET_PeerIdentity)); 4953 memcpy (&pong[1], plugin->short_name, slen);
5142 memcpy (&pong[1], 4954 if ((sender_address != NULL) && (sender_address_len > 0))
5143 plugin->short_name, 4955 memcpy (&((char *) &pong[1])[slen], sender_address, sender_address_len);
5144 slen); 4956 if (GNUNET_TIME_absolute_get_remaining
5145 if ((sender_address!=NULL) && (sender_address_len > 0)) 4957 (session_header->pong_sig_expires).rel_value <
5146 memcpy (&((char*)&pong[1])[slen], 4958 PONG_SIGNATURE_LIFETIME.rel_value / 4)
5147 sender_address, 4959 {
5148 sender_address_len); 4960 /* create / update cached sig */
5149 if (GNUNET_TIME_absolute_get_remaining (session_header->pong_sig_expires).rel_value < PONG_SIGNATURE_LIFETIME.rel_value / 4)
5150 {
5151 /* create / update cached sig */
5152#if DEBUG_TRANSPORT 4961#if DEBUG_TRANSPORT
5153 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4962 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5154 "Creating PONG signature to indicate active connection.\n"); 4963 "Creating PONG signature to indicate active connection.\n");
5155#endif 4964#endif
5156 session_header->pong_sig_expires = GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME); 4965 session_header->pong_sig_expires =
5157 pong->expiration = GNUNET_TIME_absolute_hton (session_header->pong_sig_expires); 4966 GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME);
5158 GNUNET_assert (GNUNET_OK == 4967 pong->expiration =
5159 GNUNET_CRYPTO_rsa_sign (my_private_key, 4968 GNUNET_TIME_absolute_hton (session_header->pong_sig_expires);
5160 &pong->purpose, 4969 GNUNET_assert (GNUNET_OK ==
5161 &session_header->pong_signature)); 4970 GNUNET_CRYPTO_rsa_sign (my_private_key, &pong->purpose,
5162 } 4971 &session_header->pong_signature));
5163 else 4972 }
5164 { 4973 else
5165 pong->expiration = GNUNET_TIME_absolute_hton (session_header->pong_sig_expires); 4974 {
5166 } 4975 pong->expiration =
5167 memcpy (&pong->signature, 4976 GNUNET_TIME_absolute_hton (session_header->pong_sig_expires);
5168 &session_header->pong_signature, 4977 }
5169 sizeof (struct GNUNET_CRYPTO_RsaSignature)); 4978 memcpy (&pong->signature,
4979 &session_header->pong_signature,
4980 sizeof (struct GNUNET_CRYPTO_RsaSignature));
5170 4981
5171 4982
5172 } 4983 }
5173 else 4984 else
4985 {
4986 /* peer wants to confirm that this is one of our addresses */
4987 addr += slen;
4988 alen -= slen;
4989 if (GNUNET_OK != plugin->api->check_address (plugin->api->cls, addr, alen))
4990 {
4991 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
4992 _
4993 ("Not confirming PING with address `%s' since I cannot confirm having this address.\n"),
4994 a2s (plugin->short_name, addr, alen));
4995 return GNUNET_NO;
4996 }
4997 oal = plugin->addresses;
4998 while (NULL != oal)
5174 { 4999 {
5175 /* peer wants to confirm that this is one of our addresses */ 5000 if ((oal->addrlen == alen) && (0 == memcmp (addr, &oal[1], alen)))
5176 addr += slen; 5001 break;
5177 alen -= slen; 5002 oal = oal->next;
5178 if (GNUNET_OK != 5003 }
5179 plugin->api->check_address (plugin->api->cls, 5004 pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + alen + slen);
5180 addr, 5005 pong->header.size =
5181 alen)) 5006 htons (sizeof (struct TransportPongMessage) + alen + slen);
5182 { 5007 pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG);
5183 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 5008 pong->purpose.size =
5184 _("Not confirming PING with address `%s' since I cannot confirm having this address.\n"), 5009 htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
5185 a2s (plugin->short_name, 5010 sizeof (uint32_t) +
5186 addr, 5011 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
5187 alen)); 5012 sizeof (struct GNUNET_PeerIdentity) + alen + slen);
5188 return GNUNET_NO; 5013 pong->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN);
5189 } 5014 pong->challenge = ping->challenge;
5190 oal = plugin->addresses; 5015 pong->addrlen = htonl (alen + slen);
5191 while (NULL != oal) 5016 memcpy (&pong->pid, &my_identity, sizeof (struct GNUNET_PeerIdentity));
5192 { 5017 memcpy (&pong[1], plugin->short_name, slen);
5193 if ( (oal->addrlen == alen) && 5018 memcpy (&((char *) &pong[1])[slen], addr, alen);
5194 (0 == memcmp (addr, 5019 if ((oal != NULL) &&
5195 &oal[1], 5020 (GNUNET_TIME_absolute_get_remaining (oal->pong_sig_expires).rel_value <
5196 alen)) ) 5021 PONG_SIGNATURE_LIFETIME.rel_value / 4))
5197 break; 5022 {
5198 oal = oal->next; 5023 /* create / update cached sig */
5199 }
5200 pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + alen + slen);
5201 pong->header.size = htons (sizeof (struct TransportPongMessage) + alen + slen);
5202 pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG);
5203 pong->purpose.size =
5204 htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
5205 sizeof (uint32_t) +
5206 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
5207 sizeof (struct GNUNET_PeerIdentity) + alen + slen);
5208 pong->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN);
5209 pong->challenge = ping->challenge;
5210 pong->addrlen = htonl(alen + slen);
5211 memcpy(&pong->pid,
5212 &my_identity,
5213 sizeof(struct GNUNET_PeerIdentity));
5214 memcpy (&pong[1], plugin->short_name, slen);
5215 memcpy (&((char*)&pong[1])[slen], addr, alen);
5216 if ( (oal != NULL) &&
5217 (GNUNET_TIME_absolute_get_remaining (oal->pong_sig_expires).rel_value < PONG_SIGNATURE_LIFETIME.rel_value / 4) )
5218 {
5219 /* create / update cached sig */
5220#if DEBUG_TRANSPORT 5024#if DEBUG_TRANSPORT
5221 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5025 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5222 "Creating PONG signature to indicate ownership.\n"); 5026 "Creating PONG signature to indicate ownership.\n");
5223#endif 5027#endif
5224 oal->pong_sig_expires = GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME); 5028 oal->pong_sig_expires =
5225 pong->expiration = GNUNET_TIME_absolute_hton (oal->pong_sig_expires); 5029 GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME);
5226 GNUNET_assert (GNUNET_OK == 5030 pong->expiration = GNUNET_TIME_absolute_hton (oal->pong_sig_expires);
5227 GNUNET_CRYPTO_rsa_sign (my_private_key, 5031 GNUNET_assert (GNUNET_OK ==
5228 &pong->purpose, 5032 GNUNET_CRYPTO_rsa_sign (my_private_key,
5229 &oal->pong_signature)); 5033 &pong->purpose,
5230 memcpy (&pong->signature, 5034 &oal->pong_signature));
5231 &oal->pong_signature, 5035 memcpy (&pong->signature,
5232 sizeof (struct GNUNET_CRYPTO_RsaSignature)); 5036 &oal->pong_signature, sizeof (struct GNUNET_CRYPTO_RsaSignature));
5233 } 5037 }
5234 else if (oal == NULL) 5038 else if (oal == NULL)
5235 { 5039 {
5236 /* not using cache (typically DV-only) */ 5040 /* not using cache (typically DV-only) */
5237 pong->expiration = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME)); 5041 pong->expiration =
5238 GNUNET_assert (GNUNET_OK == 5042 GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute
5239 GNUNET_CRYPTO_rsa_sign (my_private_key, 5043 (PONG_SIGNATURE_LIFETIME));
5240 &pong->purpose, 5044 GNUNET_assert (GNUNET_OK ==
5241 &pong->signature)); 5045 GNUNET_CRYPTO_rsa_sign (my_private_key, &pong->purpose,
5242 } 5046 &pong->signature));
5243 else 5047 }
5244 { 5048 else
5245 /* can used cached version */ 5049 {
5246 pong->expiration = GNUNET_TIME_absolute_hton (oal->pong_sig_expires); 5050 /* can used cached version */
5247 memcpy (&pong->signature, 5051 pong->expiration = GNUNET_TIME_absolute_hton (oal->pong_sig_expires);
5248 &oal->pong_signature, 5052 memcpy (&pong->signature,
5249 sizeof (struct GNUNET_CRYPTO_RsaSignature)); 5053 &oal->pong_signature, sizeof (struct GNUNET_CRYPTO_RsaSignature));
5250 }
5251 } 5054 }
5252 n = find_neighbour(peer); 5055 }
5056 n = find_neighbour (peer);
5253 GNUNET_assert (n != NULL); 5057 GNUNET_assert (n != NULL);
5254 did_pong = GNUNET_NO; 5058 did_pong = GNUNET_NO;
5255 /* first try reliable response transmission */ 5059 /* first try reliable response transmission */
5256 rl = n->plugins; 5060 rl = n->plugins;
5257 while (rl != NULL) 5061 while (rl != NULL)
5258 { 5062 {
5259 fal = rl->addresses; 5063 fal = rl->addresses;
5260 while (fal != NULL) 5064 while (fal != NULL)
5261 { 5065 {
5262 if (-1 != rl->plugin->api->send (rl->plugin->api->cls, 5066 if (-1 != rl->plugin->api->send (rl->plugin->api->cls,
5263 peer, 5067 peer,
5264 (const char*) pong, 5068 (const char *) pong,
5265 ntohs (pong->header.size), 5069 ntohs (pong->header.size),
5266 TRANSPORT_PONG_PRIORITY, 5070 TRANSPORT_PONG_PRIORITY,
5267 HELLO_VERIFICATION_TIMEOUT, 5071 HELLO_VERIFICATION_TIMEOUT,
5268 fal->session, 5072 fal->session,
5269 fal->addr, 5073 fal->addr,
5270 fal->addrlen, 5074 fal->addrlen, GNUNET_SYSERR, NULL, NULL))
5271 GNUNET_SYSERR, 5075 {
5272 NULL, NULL)) 5076 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5273 { 5077 "Transmitted PONG to `%s' via reliable mechanism\n",
5274 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5078 GNUNET_i2s (peer));
5275 "Transmitted PONG to `%s' via reliable mechanism\n", 5079 /* done! */
5276 GNUNET_i2s (peer)); 5080 GNUNET_STATISTICS_update (stats,
5277 /* done! */ 5081 gettext_noop
5278 GNUNET_STATISTICS_update (stats, 5082 ("# PONGs unicast via reliable transport"), 1,
5279 gettext_noop ("# PONGs unicast via reliable transport"), 5083 GNUNET_NO);
5280 1, 5084 GNUNET_free (pong);
5281 GNUNET_NO); 5085 return GNUNET_OK;
5282 GNUNET_free (pong); 5086 }
5283 return GNUNET_OK; 5087 did_pong = GNUNET_YES;
5284 } 5088 fal = fal->next;
5285 did_pong = GNUNET_YES;
5286 fal = fal->next;
5287 }
5288 rl = rl->next;
5289 } 5089 }
5090 rl = rl->next;
5091 }
5290 /* no reliable method found, do multicast */ 5092 /* no reliable method found, do multicast */
5291 GNUNET_STATISTICS_update (stats, 5093 GNUNET_STATISTICS_update (stats,
5292 gettext_noop ("# PONGs multicast to all available addresses"), 5094 gettext_noop
5293 1, 5095 ("# PONGs multicast to all available addresses"), 1,
5294 GNUNET_NO); 5096 GNUNET_NO);
5295 rl = n->plugins; 5097 rl = n->plugins;
5296 while (rl != NULL) 5098 while (rl != NULL)
5099 {
5100 fal = rl->addresses;
5101 while (fal != NULL)
5297 { 5102 {
5298 fal = rl->addresses; 5103 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5299 while (fal != NULL) 5104 "Transmitting PONG to `%s' via unreliable mechanism `%s':%s\n",
5300 { 5105 GNUNET_i2s (peer),
5301 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5106 a2s (rl->plugin->short_name,
5302 "Transmitting PONG to `%s' via unreliable mechanism `%s':%s\n", 5107 fal->addr, fal->addrlen), rl->plugin->short_name);
5303 GNUNET_i2s (peer), 5108 transmit_to_peer (NULL, fal,
5304 a2s (rl->plugin->short_name, 5109 TRANSPORT_PONG_PRIORITY,
5305 fal->addr, 5110 HELLO_VERIFICATION_TIMEOUT,
5306 fal->addrlen), 5111 (const char *) pong,
5307 rl->plugin->short_name); 5112 ntohs (pong->header.size), GNUNET_YES, n);
5308 transmit_to_peer(NULL, fal, 5113 did_pong = GNUNET_YES;
5309 TRANSPORT_PONG_PRIORITY, 5114 fal = fal->next;
5310 HELLO_VERIFICATION_TIMEOUT, 5115 }
5311 (const char *)pong, 5116 rl = rl->next;
5312 ntohs(pong->header.size), 5117 }
5313 GNUNET_YES, 5118 GNUNET_free (pong);
5314 n);
5315 did_pong = GNUNET_YES;
5316 fal = fal->next;
5317 }
5318 rl = rl->next;
5319 }
5320 GNUNET_free(pong);
5321 if (GNUNET_YES != did_pong) 5119 if (GNUNET_YES != did_pong)
5322 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 5120 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
5323 _("Could not send PONG to `%s': no address available\n"), 5121 _("Could not send PONG to `%s': no address available\n"),
5324 GNUNET_i2s (peer)); 5122 GNUNET_i2s (peer));
5325 return GNUNET_OK; 5123 return GNUNET_OK;
5326} 5124}
5327 5125
@@ -5350,8 +5148,7 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
5350 const struct GNUNET_TRANSPORT_ATS_Information *ats_data, 5148 const struct GNUNET_TRANSPORT_ATS_Information *ats_data,
5351 uint32_t ats_count, 5149 uint32_t ats_count,
5352 struct Session *session, 5150 struct Session *session,
5353 const char *sender_address, 5151 const char *sender_address, uint16_t sender_address_len)
5354 uint16_t sender_address_len)
5355{ 5152{
5356 struct TransportPlugin *plugin = cls; 5153 struct TransportPlugin *plugin = cls;
5357 struct ReadyList *service_context; 5154 struct ReadyList *service_context;
@@ -5362,14 +5159,12 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
5362 uint32_t distance; 5159 uint32_t distance;
5363 int c; 5160 int c;
5364 5161
5365 if (0 == memcmp (peer, 5162 if (0 == memcmp (peer, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
5366 &my_identity, 5163 {
5367 sizeof (struct GNUNET_PeerIdentity))) 5164 /* refuse to receive from myself */
5368 { 5165 GNUNET_break (0);
5369 /* refuse to receive from myself */ 5166 return GNUNET_TIME_UNIT_FOREVER_REL;
5370 GNUNET_break (0); 5167 }
5371 return GNUNET_TIME_UNIT_FOREVER_REL;
5372 }
5373 if (is_blacklisted (peer, plugin)) 5168 if (is_blacklisted (peer, plugin))
5374 return GNUNET_TIME_UNIT_FOREVER_REL; 5169 return GNUNET_TIME_UNIT_FOREVER_REL;
5375 n = find_neighbour (peer); 5170 n = find_neighbour (peer);
@@ -5382,157 +5177,160 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
5382 peer_address = NULL; 5177 peer_address = NULL;
5383 distance = 1; 5178 distance = 1;
5384 5179
5385 for (c=0; c<ats_count; c++) 5180 for (c = 0; c < ats_count; c++)
5386 if (ntohl(ats_data[c].type) == GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE) 5181 if (ntohl (ats_data[c].type) == GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE)
5387 distance = ntohl(ats_data[c].value); 5182 distance = ntohl (ats_data[c].value);
5388 5183
5389 5184
5390 if (message != NULL) 5185 if (message != NULL)
5391 { 5186 {
5392 if ( (session != NULL) || 5187 if ((session != NULL) || (sender_address != NULL))
5393 (sender_address != NULL) ) 5188 peer_address = add_peer_address (n,
5394 peer_address = add_peer_address (n, 5189 plugin->short_name,
5395 plugin->short_name, 5190 session,
5396 session, 5191 sender_address, sender_address_len);
5397 sender_address, 5192 if (peer_address != NULL)
5398 sender_address_len); 5193 {
5399 if (peer_address != NULL) 5194 update_addr_ats (peer_address, ats_data, ats_count);
5400 { 5195 update_addr_value (peer_address, distance,
5401 update_addr_ats(peer_address, ats_data, ats_count); 5196 GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
5402 update_addr_value(peer_address, distance, GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE); 5197
5403 5198 peer_address->distance = distance;
5404 peer_address->distance = distance; 5199 if (GNUNET_YES == peer_address->validated)
5405 if (GNUNET_YES == peer_address->validated) 5200 {
5406 { 5201 mark_address_connected (peer_address);
5407 mark_address_connected (peer_address); 5202 schedule_next_ping (peer_address);
5408 schedule_next_ping (peer_address); 5203 }
5409 } 5204 else
5410 else 5205 {
5411 {
5412#if DEBUG_TRANSPORT 5206#if DEBUG_TRANSPORT
5413 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5207 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5414 "New address is unvalidated, trying to validate it now\n"); 5208 "New address is unvalidated, trying to validate it now\n");
5415#endif 5209#endif
5416 if (peer_address->revalidate_task != GNUNET_SCHEDULER_NO_TASK) 5210 if (peer_address->revalidate_task != GNUNET_SCHEDULER_NO_TASK)
5417 { 5211 {
5418 GNUNET_SCHEDULER_cancel (peer_address->revalidate_task); 5212 GNUNET_SCHEDULER_cancel (peer_address->revalidate_task);
5419 peer_address->revalidate_task = GNUNET_SCHEDULER_NO_TASK; 5213 peer_address->revalidate_task = GNUNET_SCHEDULER_NO_TASK;
5420 } 5214 }
5421 peer_address->revalidate_task = GNUNET_SCHEDULER_add_now (&send_periodic_ping, peer_address); 5215 peer_address->revalidate_task =
5422 5216 GNUNET_SCHEDULER_add_now (&send_periodic_ping, peer_address);
5423 }
5424 peer_address->timeout
5425 = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
5426 }
5427 /* update traffic received amount ... */
5428 msize = ntohs (message->size);
5429 5217
5218 }
5219 peer_address->timeout
5220 =
5221 GNUNET_TIME_relative_to_absolute
5222 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
5223 }
5224 /* update traffic received amount ... */
5225 msize = ntohs (message->size);
5226
5227 GNUNET_STATISTICS_update (stats,
5228 gettext_noop
5229 ("# bytes received from other peers"), msize,
5230 GNUNET_NO);
5231 n->distance = distance;
5232 n->peer_timeout =
5233 GNUNET_TIME_relative_to_absolute
5234 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
5235 GNUNET_SCHEDULER_cancel (n->timeout_task);
5236 n->timeout_task =
5237 GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
5238 &neighbour_timeout_task, n);
5239 if (n->quota_violation_count > QUOTA_VIOLATION_DROP_THRESHOLD)
5240 {
5241 /* dropping message due to frequent inbound volume violations! */
5242 GNUNET_log (GNUNET_ERROR_TYPE_WARNING |
5243 GNUNET_ERROR_TYPE_BULK,
5244 _
5245 ("Dropping incoming message due to repeated bandwidth quota (%u b/s) violations (total of %u).\n"),
5246 n->in_tracker.available_bytes_per_s__,
5247 n->quota_violation_count);
5430 GNUNET_STATISTICS_update (stats, 5248 GNUNET_STATISTICS_update (stats,
5431 gettext_noop ("# bytes received from other peers"), 5249 gettext_noop
5432 msize, 5250 ("# bandwidth quota violations by other peers"),
5433 GNUNET_NO); 5251 1, GNUNET_NO);
5434 n->distance = distance; 5252 return GNUNET_CONSTANTS_QUOTA_VIOLATION_TIMEOUT;
5435 n->peer_timeout = 5253 }
5436 GNUNET_TIME_relative_to_absolute 5254 if ((ntohs (message->type) == GNUNET_MESSAGE_TYPE_TRANSPORT_ATS) &&
5437 (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); 5255 (ntohs (message->size) ==
5438 GNUNET_SCHEDULER_cancel (n->timeout_task); 5256 (sizeof (struct GNUNET_MessageHeader) + sizeof (uint32_t))))
5439 n->timeout_task = 5257 {
5440 GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
5441 &neighbour_timeout_task, n);
5442 if (n->quota_violation_count > QUOTA_VIOLATION_DROP_THRESHOLD)
5443 {
5444 /* dropping message due to frequent inbound volume violations! */
5445 GNUNET_log (GNUNET_ERROR_TYPE_WARNING |
5446 GNUNET_ERROR_TYPE_BULK,
5447 _
5448 ("Dropping incoming message due to repeated bandwidth quota (%u b/s) violations (total of %u).\n"),
5449 n->in_tracker.available_bytes_per_s__,
5450 n->quota_violation_count);
5451 GNUNET_STATISTICS_update (stats,
5452 gettext_noop ("# bandwidth quota violations by other peers"),
5453 1,
5454 GNUNET_NO);
5455 return GNUNET_CONSTANTS_QUOTA_VIOLATION_TIMEOUT;
5456 }
5457 if ((ntohs(message->type) == GNUNET_MESSAGE_TYPE_TRANSPORT_ATS) &&
5458 (ntohs(message->size) == (sizeof (struct GNUNET_MessageHeader) + sizeof (uint32_t))))
5459 {
5460#if HAVE_LIBGLPK 5258#if HAVE_LIBGLPK
5461 uint32_t value = ntohl(*((uint32_t *) &message[1])); 5259 uint32_t value = ntohl (*((uint32_t *) & message[1]));
5462 //GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GNUNET_MESSAGE_TYPE_TRANSPORT_ATS: %i \n", value); 5260
5463 /* Force ressource and quality update */ 5261 //GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GNUNET_MESSAGE_TYPE_TRANSPORT_ATS: %i \n", value);
5464 if ((value == 4) && (ats != NULL)) 5262 /* Force ressource and quality update */
5465 ats_modify_problem_state(ats, ATS_QUALITY_COST_UPDATED); 5263 if ((value == 4) && (ats != NULL))
5466 /* Force cost update */ 5264 ats_modify_problem_state (ats, ATS_QUALITY_COST_UPDATED);
5467 if ((value == 3) && (ats != NULL)) 5265 /* Force cost update */
5468 ats_modify_problem_state(ats, ATS_COST_UPDATED); 5266 if ((value == 3) && (ats != NULL))
5469 /* Force quality update */ 5267 ats_modify_problem_state (ats, ATS_COST_UPDATED);
5470 if ((value == 2) && (ats != NULL)) 5268 /* Force quality update */
5471 ats_modify_problem_state(ats, ATS_QUALITY_UPDATED); 5269 if ((value == 2) && (ats != NULL))
5472 /* Force full rebuild */ 5270 ats_modify_problem_state (ats, ATS_QUALITY_UPDATED);
5473 if ((value == 1) && (ats != NULL)) 5271 /* Force full rebuild */
5474 ats_modify_problem_state(ats, ATS_MODIFIED); 5272 if ((value == 1) && (ats != NULL))
5273 ats_modify_problem_state (ats, ATS_MODIFIED);
5475#endif 5274#endif
5476 } 5275 }
5477 5276
5478#if DEBUG_PING_PONG 5277#if DEBUG_PING_PONG
5479 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5278 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5480 "Received message of type %u and size %u from `%4s', sending to all clients.\n", 5279 "Received message of type %u and size %u from `%4s', sending to all clients.\n",
5481 ntohs (message->type), 5280 ntohs (message->type),
5482 ntohs (message->size), 5281 ntohs (message->size), GNUNET_i2s (peer));
5483 GNUNET_i2s (peer));
5484#endif 5282#endif
5485 switch (ntohs (message->type)) 5283 switch (ntohs (message->type))
5486 { 5284 {
5487 case GNUNET_MESSAGE_TYPE_HELLO: 5285 case GNUNET_MESSAGE_TYPE_HELLO:
5488 GNUNET_STATISTICS_update (stats, 5286 GNUNET_STATISTICS_update (stats,
5489 gettext_noop ("# HELLO messages received from other peers"), 5287 gettext_noop
5490 1, 5288 ("# HELLO messages received from other peers"),
5491 GNUNET_NO); 5289 1, GNUNET_NO);
5492 process_hello (plugin, message); 5290 process_hello (plugin, message);
5493 break; 5291 break;
5494 case GNUNET_MESSAGE_TYPE_TRANSPORT_PING: 5292 case GNUNET_MESSAGE_TYPE_TRANSPORT_PING:
5495 handle_ping (plugin, message, peer, session, sender_address, sender_address_len); 5293 handle_ping (plugin, message, peer, session, sender_address,
5496 if (GNUNET_YES != n->received_pong) 5294 sender_address_len);
5497 transmit_plain_ping (n); 5295 if (GNUNET_YES != n->received_pong)
5498 break; 5296 transmit_plain_ping (n);
5499 case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG: 5297 break;
5500 handle_pong (plugin, message, peer, sender_address, sender_address_len); 5298 case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG:
5501 break; 5299 handle_pong (plugin, message, peer, sender_address, sender_address_len);
5502 case GNUNET_MESSAGE_TYPE_TRANSPORT_ATS: 5300 break;
5503 break; 5301 case GNUNET_MESSAGE_TYPE_TRANSPORT_ATS:
5504 default: 5302 break;
5505 handle_payload_message (message, n); 5303 default:
5506 break; 5304 handle_payload_message (message, n);
5507 } 5305 break;
5508 } 5306 }
5307 }
5509 ret = GNUNET_BANDWIDTH_tracker_get_delay (&n->in_tracker, 0); 5308 ret = GNUNET_BANDWIDTH_tracker_get_delay (&n->in_tracker, 0);
5510 if (ret.rel_value > 0) 5309 if (ret.rel_value > 0)
5511 { 5310 {
5512#if DEBUG_TRANSPORT 5311#if DEBUG_TRANSPORT
5513 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5312 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5514 "Throttling read (%llu bytes excess at %u b/s), waiting %llu ms before reading more.\n", 5313 "Throttling read (%llu bytes excess at %u b/s), waiting %llu ms before reading more.\n",
5515 (unsigned long long) n->in_tracker.consumption_since_last_update__, 5314 (unsigned long long) n->
5516 (unsigned int) n->in_tracker.available_bytes_per_s__, 5315 in_tracker.consumption_since_last_update__,
5517 (unsigned long long) ret.rel_value); 5316 (unsigned int) n->in_tracker.available_bytes_per_s__,
5317 (unsigned long long) ret.rel_value);
5518#endif 5318#endif
5519 GNUNET_STATISTICS_update (stats, 5319 GNUNET_STATISTICS_update (stats,
5520 gettext_noop ("# ms throttling suggested"), 5320 gettext_noop ("# ms throttling suggested"),
5521 (int64_t) ret.rel_value, 5321 (int64_t) ret.rel_value, GNUNET_NO);
5522 GNUNET_NO); 5322 }
5523 }
5524 return ret; 5323 return ret;
5525} 5324}
5526 5325
5527 5326
5528static int 5327static int
5529notify_client_about_neighbour (void *cls, 5328notify_client_about_neighbour (void *cls,
5530 const GNUNET_HashCode *key, 5329 const GNUNET_HashCode * key, void *value)
5531 void *value)
5532{ 5330{
5533 struct TransportClient *c = cls; 5331 struct TransportClient *c = cls;
5534 struct NeighbourMapEntry *n = value; 5332 struct NeighbourMapEntry *n = value;
5535 struct ConnectInfoMessage * cim; 5333 struct ConnectInfoMessage *cim;
5536 uint32_t ats_count; 5334 uint32_t ats_count;
5537 size_t size; 5335 size_t size;
5538 5336
@@ -5540,23 +5338,25 @@ notify_client_about_neighbour (void *cls,
5540 return GNUNET_OK; 5338 return GNUNET_OK;
5541 5339
5542 ats_count = 2; 5340 ats_count = 2;
5543 size = sizeof (struct ConnectInfoMessage) + ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information); 5341 size =
5342 sizeof (struct ConnectInfoMessage) +
5343 ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
5544 GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE); 5344 GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE);
5545 cim = GNUNET_malloc (size); 5345 cim = GNUNET_malloc (size);
5546 cim->header.size = htons (size); 5346 cim->header.size = htons (size);
5547 cim->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT); 5347 cim->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
5548 cim->ats_count = htonl(ats_count); 5348 cim->ats_count = htonl (ats_count);
5549 (&(cim->ats))[2].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); 5349 (&(cim->ats))[2].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
5550 (&(cim->ats))[2].value = htonl (0); 5350 (&(cim->ats))[2].value = htonl (0);
5551 if (GNUNET_YES == n->received_pong) 5351 if (GNUNET_YES == n->received_pong)
5552 { 5352 {
5553 (&cim->ats)[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE); 5353 (&cim->ats)[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
5554 (&cim->ats)[0].value = htonl (n->distance); 5354 (&cim->ats)[0].value = htonl (n->distance);
5555 (&cim->ats)[1].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY); 5355 (&cim->ats)[1].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY);
5556 (&cim->ats)[1].value = htonl ((uint32_t) n->latency.rel_value); 5356 (&cim->ats)[1].value = htonl ((uint32_t) n->latency.rel_value);
5557 cim->id = n->id; 5357 cim->id = n->id;
5558 transmit_to_client (c, &cim->header, GNUNET_NO); 5358 transmit_to_client (c, &cim->header, GNUNET_NO);
5559 } 5359 }
5560 GNUNET_free (cim); 5360 GNUNET_free (cim);
5561 return GNUNET_OK; 5361 return GNUNET_OK;
5562} 5362}
@@ -5578,60 +5378,59 @@ handle_start (void *cls,
5578 const struct StartMessage *start; 5378 const struct StartMessage *start;
5579 struct TransportClient *c; 5379 struct TransportClient *c;
5580 5380
5581 start = (const struct StartMessage*) message; 5381 start = (const struct StartMessage *) message;
5582#if DEBUG_TRANSPORT 5382#if DEBUG_TRANSPORT
5583 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5383 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5584 "Received `%s' request from client\n", "START"); 5384 "Received `%s' request from client\n", "START");
5585#endif 5385#endif
5586 c = clients; 5386 c = clients;
5587 while (c != NULL) 5387 while (c != NULL)
5388 {
5389 if (c->client == client)
5588 { 5390 {
5589 if (c->client == client) 5391 /* client already on our list! */
5590 { 5392 GNUNET_break (0);
5591 /* client already on our list! */
5592 GNUNET_break (0);
5593 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5594 return;
5595 }
5596 c = c->next;
5597 }
5598 if ( (GNUNET_NO != ntohl (start->do_check)) &&
5599 (0 != memcmp (&start->self,
5600 &my_identity,
5601 sizeof (struct GNUNET_PeerIdentity))) )
5602 {
5603 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
5604 _("Rejecting control connection from peer `%s', which is not me!\n"),
5605 GNUNET_i2s (&start->self));
5606 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 5393 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5607 return; 5394 return;
5608 } 5395 }
5396 c = c->next;
5397 }
5398 if ((GNUNET_NO != ntohl (start->do_check)) &&
5399 (0 != memcmp (&start->self,
5400 &my_identity, sizeof (struct GNUNET_PeerIdentity))))
5401 {
5402 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
5403 _
5404 ("Rejecting control connection from peer `%s', which is not me!\n"),
5405 GNUNET_i2s (&start->self));
5406 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5407 return;
5408 }
5609 c = GNUNET_malloc (sizeof (struct TransportClient)); 5409 c = GNUNET_malloc (sizeof (struct TransportClient));
5610 c->next = clients; 5410 c->next = clients;
5611 clients = c; 5411 clients = c;
5612 c->client = client; 5412 c->client = client;
5613 if (our_hello != NULL) 5413 if (our_hello != NULL)
5614 { 5414 {
5615#if DEBUG_TRANSPORT 5415#if DEBUG_TRANSPORT
5616 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5416 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5617 "Sending our own `%s' to new client\n", "HELLO"); 5417 "Sending our own `%s' to new client\n", "HELLO");
5618#endif 5418#endif
5619 transmit_to_client (c, 5419 transmit_to_client (c,
5620 (const struct GNUNET_MessageHeader *) our_hello, 5420 (const struct GNUNET_MessageHeader *) our_hello,
5621 GNUNET_NO); 5421 GNUNET_NO);
5622 /* tell new client about all existing connections */ 5422 /* tell new client about all existing connections */
5623 GNUNET_CONTAINER_multihashmap_iterate (neighbours, 5423 GNUNET_CONTAINER_multihashmap_iterate (neighbours,
5624 &notify_client_about_neighbour, 5424 &notify_client_about_neighbour, c);
5625 c); 5425 }
5626 }
5627 else 5426 else
5628 { 5427 {
5629#if DEBUG_TRANSPORT_HELLO 5428#if DEBUG_TRANSPORT_HELLO
5630 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5429 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5631 "No HELLO created yet, will transmit HELLO to client later!\n"); 5430 "No HELLO created yet, will transmit HELLO to client later!\n");
5632#endif 5431#endif
5633 refresh_hello (); 5432 refresh_hello ();
5634 } 5433 }
5635 GNUNET_SERVER_receive_done (client, GNUNET_OK); 5434 GNUNET_SERVER_receive_done (client, GNUNET_OK);
5636} 5435}
5637 5436
@@ -5651,9 +5450,8 @@ handle_hello (void *cls,
5651 int ret; 5450 int ret;
5652 5451
5653 GNUNET_STATISTICS_update (stats, 5452 GNUNET_STATISTICS_update (stats,
5654 gettext_noop ("# HELLOs received from clients"), 5453 gettext_noop ("# HELLOs received from clients"),
5655 1, 5454 1, GNUNET_NO);
5656 GNUNET_NO);
5657 ret = process_hello (NULL, message); 5455 ret = process_hello (NULL, message);
5658 GNUNET_SERVER_receive_done (client, ret); 5456 GNUNET_SERVER_receive_done (client, ret);
5659} 5457}
@@ -5694,8 +5492,7 @@ struct TransmitClientMessageContext
5694 * @param n destination, or NULL on error (in that case, drop the message) 5492 * @param n destination, or NULL on error (in that case, drop the message)
5695 */ 5493 */
5696static void 5494static void
5697transmit_client_message (void *cls, 5495transmit_client_message (void *cls, struct NeighbourMapEntry *n)
5698 struct NeighbourMapEntry *n)
5699{ 5496{
5700 struct TransmitClientMessageContext *tcmc = cls; 5497 struct TransmitClientMessageContext *tcmc = cls;
5701 struct TransportClient *tc; 5498 struct TransportClient *tc;
@@ -5705,12 +5502,11 @@ transmit_client_message (void *cls,
5705 tc = tc->next; 5502 tc = tc->next;
5706 5503
5707 if (n != NULL) 5504 if (n != NULL)
5708 { 5505 {
5709 transmit_to_peer (tc, NULL, tcmc->priority, 5506 transmit_to_peer (tc, NULL, tcmc->priority,
5710 GNUNET_TIME_absolute_get_remaining (tcmc->timeout), 5507 GNUNET_TIME_absolute_get_remaining (tcmc->timeout),
5711 (char *)&tcmc[1], 5508 (char *) &tcmc[1], tcmc->msize, GNUNET_NO, n);
5712 tcmc->msize, GNUNET_NO, n); 5509 }
5713 }
5714 GNUNET_SERVER_receive_done (tcmc->client, GNUNET_OK); 5510 GNUNET_SERVER_receive_done (tcmc->client, GNUNET_OK);
5715 GNUNET_SERVER_client_drop (tcmc->client); 5511 GNUNET_SERVER_client_drop (tcmc->client);
5716 GNUNET_free (tcmc); 5512 GNUNET_free (tcmc);
@@ -5738,36 +5534,34 @@ handle_send (void *cls,
5738 size = ntohs (message->size); 5534 size = ntohs (message->size);
5739 if (size < 5535 if (size <
5740 sizeof (struct OutboundMessage) + sizeof (struct GNUNET_MessageHeader)) 5536 sizeof (struct OutboundMessage) + sizeof (struct GNUNET_MessageHeader))
5741 { 5537 {
5742 GNUNET_break (0); 5538 GNUNET_break (0);
5743 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 5539 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5744 return; 5540 return;
5745 } 5541 }
5746 GNUNET_STATISTICS_update (stats, 5542 GNUNET_STATISTICS_update (stats,
5747 gettext_noop ("# payload received for other peers"), 5543 gettext_noop ("# payload received for other peers"),
5748 size, 5544 size, GNUNET_NO);
5749 GNUNET_NO);
5750 obm = (const struct OutboundMessage *) message; 5545 obm = (const struct OutboundMessage *) message;
5751 obmm = (const struct GNUNET_MessageHeader *) &obm[1]; 5546 obmm = (const struct GNUNET_MessageHeader *) &obm[1];
5752 msize = size - sizeof (struct OutboundMessage); 5547 msize = size - sizeof (struct OutboundMessage);
5753#if DEBUG_TRANSPORT 5548#if DEBUG_TRANSPORT
5754 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5549 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5755 "Received `%s' request from client with target `%4s' and message of type %u and size %u\n", 5550 "Received `%s' request from client with target `%4s' and message of type %u and size %u\n",
5756 "SEND", GNUNET_i2s (&obm->peer), 5551 "SEND", GNUNET_i2s (&obm->peer), ntohs (obmm->type), msize);
5757 ntohs (obmm->type),
5758 msize);
5759#endif 5552#endif
5760 tcmc = GNUNET_malloc (sizeof (struct TransmitClientMessageContext) + msize); 5553 tcmc = GNUNET_malloc (sizeof (struct TransmitClientMessageContext) + msize);
5761 tcmc->client = client; 5554 tcmc->client = client;
5762 tcmc->priority = ntohl (obm->priority); 5555 tcmc->priority = ntohl (obm->priority);
5763 tcmc->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_ntoh (obm->timeout)); 5556 tcmc->timeout =
5557 GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_ntoh
5558 (obm->timeout));
5764 tcmc->msize = msize; 5559 tcmc->msize = msize;
5765 /* FIXME: this memcpy can be up to 7% of our total runtime */ 5560 /* FIXME: this memcpy can be up to 7% of our total runtime */
5766 memcpy (&tcmc[1], obmm, msize); 5561 memcpy (&tcmc[1], obmm, msize);
5767 GNUNET_SERVER_client_keep (client); 5562 GNUNET_SERVER_client_keep (client);
5768 setup_peer_check_blacklist (&obm->peer, GNUNET_YES, 5563 setup_peer_check_blacklist (&obm->peer, GNUNET_YES,
5769 &transmit_client_message, 5564 &transmit_client_message, tcmc);
5770 tcmc);
5771} 5565}
5772 5566
5773 5567
@@ -5784,19 +5578,18 @@ handle_request_connect (void *cls,
5784 const struct GNUNET_MessageHeader *message) 5578 const struct GNUNET_MessageHeader *message)
5785{ 5579{
5786 const struct TransportRequestConnectMessage *trcm = 5580 const struct TransportRequestConnectMessage *trcm =
5787 (const struct TransportRequestConnectMessage *) message; 5581 (const struct TransportRequestConnectMessage *) message;
5788 5582
5789 GNUNET_STATISTICS_update (stats, 5583 GNUNET_STATISTICS_update (stats,
5790 gettext_noop ("# REQUEST CONNECT messages received"), 5584 gettext_noop
5791 1, 5585 ("# REQUEST CONNECT messages received"), 1,
5792 GNUNET_NO); 5586 GNUNET_NO);
5793#if DEBUG_TRANSPORT 5587#if DEBUG_TRANSPORT
5794 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 5588 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5795 "Received a request connect message for peer `%s'\n", 5589 "Received a request connect message for peer `%s'\n",
5796 GNUNET_i2s(&trcm->peer)); 5590 GNUNET_i2s (&trcm->peer));
5797#endif 5591#endif
5798 setup_peer_check_blacklist (&trcm->peer, GNUNET_YES, 5592 setup_peer_check_blacklist (&trcm->peer, GNUNET_YES, NULL, NULL);
5799 NULL, NULL);
5800 GNUNET_SERVER_receive_done (client, GNUNET_OK); 5593 GNUNET_SERVER_receive_done (client, GNUNET_OK);
5801} 5594}
5802 5595
@@ -5813,47 +5606,43 @@ handle_set_quota (void *cls,
5813 struct GNUNET_SERVER_Client *client, 5606 struct GNUNET_SERVER_Client *client,
5814 const struct GNUNET_MessageHeader *message) 5607 const struct GNUNET_MessageHeader *message)
5815{ 5608{
5816 const struct QuotaSetMessage *qsm = 5609 const struct QuotaSetMessage *qsm = (const struct QuotaSetMessage *) message;
5817 (const struct QuotaSetMessage *) message;
5818 struct NeighbourMapEntry *n; 5610 struct NeighbourMapEntry *n;
5819 5611
5820 GNUNET_STATISTICS_update (stats, 5612 GNUNET_STATISTICS_update (stats,
5821 gettext_noop ("# SET QUOTA messages received"), 5613 gettext_noop ("# SET QUOTA messages received"),
5822 1, 5614 1, GNUNET_NO);
5823 GNUNET_NO);
5824 n = find_neighbour (&qsm->peer); 5615 n = find_neighbour (&qsm->peer);
5825 if (n == NULL) 5616 if (n == NULL)
5826 { 5617 {
5827 GNUNET_SERVER_receive_done (client, GNUNET_OK); 5618 GNUNET_SERVER_receive_done (client, GNUNET_OK);
5828 GNUNET_STATISTICS_update (stats, 5619 GNUNET_STATISTICS_update (stats,
5829 gettext_noop ("# SET QUOTA messages ignored (no such peer)"), 5620 gettext_noop
5830 1, 5621 ("# SET QUOTA messages ignored (no such peer)"),
5831 GNUNET_NO); 5622 1, GNUNET_NO);
5832 return; 5623 return;
5833 } 5624 }
5834#if DEBUG_TRANSPORT 5625#if DEBUG_TRANSPORT
5835 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5626 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5836 "Received `%s' request (new quota %u, old quota %u) from client for peer `%4s'\n", 5627 "Received `%s' request (new quota %u, old quota %u) from client for peer `%4s'\n",
5837 "SET_QUOTA", 5628 "SET_QUOTA",
5838 (unsigned int) ntohl (qsm->quota.value__), 5629 (unsigned int) ntohl (qsm->quota.value__),
5839 (unsigned int) n->in_tracker.available_bytes_per_s__, 5630 (unsigned int) n->in_tracker.available_bytes_per_s__,
5840 GNUNET_i2s (&qsm->peer)); 5631 GNUNET_i2s (&qsm->peer));
5841#endif 5632#endif
5842 GNUNET_BANDWIDTH_tracker_update_quota (&n->in_tracker, 5633 GNUNET_BANDWIDTH_tracker_update_quota (&n->in_tracker, qsm->quota);
5843 qsm->quota);
5844 if (0 == ntohl (qsm->quota.value__)) 5634 if (0 == ntohl (qsm->quota.value__))
5845 { 5635 {
5846#if DEBUG_TRANSPORT 5636#if DEBUG_TRANSPORT
5847 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5637 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5848 "Disconnecting peer `%4s', %s\n", GNUNET_i2s(&n->id), 5638 "Disconnecting peer `%4s', %s\n", GNUNET_i2s (&n->id),
5849 "SET_QUOTA"); 5639 "SET_QUOTA");
5850#endif 5640#endif
5851 GNUNET_STATISTICS_update (stats, 5641 GNUNET_STATISTICS_update (stats,
5852 gettext_noop ("# disconnects due to quota of 0"), 5642 gettext_noop ("# disconnects due to quota of 0"),
5853 1, 5643 1, GNUNET_NO);
5854 GNUNET_NO); 5644 disconnect_neighbour (n, GNUNET_NO);
5855 disconnect_neighbour (n, GNUNET_NO); 5645 }
5856 }
5857 GNUNET_SERVER_receive_done (client, GNUNET_OK); 5646 GNUNET_SERVER_receive_done (client, GNUNET_OK);
5858} 5647}
5859 5648
@@ -5872,17 +5661,17 @@ transmit_address_to_client (void *cls, const char *address)
5872 size_t slen; 5661 size_t slen;
5873 5662
5874 if (NULL != address) 5663 if (NULL != address)
5875 { 5664 {
5876 slen = strlen (address) + 1; 5665 slen = strlen (address) + 1;
5877 GNUNET_SERVER_transmit_context_append_data (tc, address, slen, 5666 GNUNET_SERVER_transmit_context_append_data (tc, address, slen,
5878 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY); 5667 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY);
5879 } 5668 }
5880 else 5669 else
5881 { 5670 {
5882 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, 5671 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
5883 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY); 5672 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY);
5884 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); 5673 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
5885 } 5674 }
5886} 5675}
5887 5676
5888 5677
@@ -5909,45 +5698,46 @@ handle_address_lookup (void *cls,
5909 5698
5910 size = ntohs (message->size); 5699 size = ntohs (message->size);
5911 if (size < sizeof (struct AddressLookupMessage)) 5700 if (size < sizeof (struct AddressLookupMessage))
5912 { 5701 {
5913 GNUNET_break_op (0); 5702 GNUNET_break_op (0);
5914 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 5703 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5915 return; 5704 return;
5916 } 5705 }
5917 alum = (const struct AddressLookupMessage *) message; 5706 alum = (const struct AddressLookupMessage *) message;
5918 uint32_t addressLen = ntohl (alum->addrlen); 5707 uint32_t addressLen = ntohl (alum->addrlen);
5708
5919 if (size <= sizeof (struct AddressLookupMessage) + addressLen) 5709 if (size <= sizeof (struct AddressLookupMessage) + addressLen)
5920 { 5710 {
5921 GNUNET_break_op (0); 5711 GNUNET_break_op (0);
5922 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 5712 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5923 return; 5713 return;
5924 } 5714 }
5925 address = (const char *) &alum[1]; 5715 address = (const char *) &alum[1];
5926 nameTransport = (const char *) &address[addressLen]; 5716 nameTransport = (const char *) &address[addressLen];
5927 if (nameTransport 5717 if (nameTransport
5928 [size - sizeof (struct AddressLookupMessage) - addressLen - 1] != '\0') 5718 [size - sizeof (struct AddressLookupMessage) - addressLen - 1] != '\0')
5929 { 5719 {
5930 GNUNET_break_op (0); 5720 GNUNET_break_op (0);
5931 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 5721 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5932 return; 5722 return;
5933 } 5723 }
5934 rtimeout = GNUNET_TIME_relative_ntoh (alum->timeout); 5724 rtimeout = GNUNET_TIME_relative_ntoh (alum->timeout);
5935 numeric = ntohl (alum->numeric_only); 5725 numeric = ntohl (alum->numeric_only);
5936 lsPlugin = find_transport (nameTransport); 5726 lsPlugin = find_transport (nameTransport);
5937 if (NULL == lsPlugin) 5727 if (NULL == lsPlugin)
5938 { 5728 {
5939 tc = GNUNET_SERVER_transmit_context_create (client); 5729 tc = GNUNET_SERVER_transmit_context_create (client);
5940 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, 5730 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
5941 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY); 5731 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY);
5942 GNUNET_SERVER_transmit_context_run (tc, rtimeout); 5732 GNUNET_SERVER_transmit_context_run (tc, rtimeout);
5943 return; 5733 return;
5944 } 5734 }
5945 GNUNET_SERVER_disable_receive_done_warning (client); 5735 GNUNET_SERVER_disable_receive_done_warning (client);
5946 tc = GNUNET_SERVER_transmit_context_create (client); 5736 tc = GNUNET_SERVER_transmit_context_create (client);
5947 lsPlugin->api->address_pretty_printer (lsPlugin->api->cls, 5737 lsPlugin->api->address_pretty_printer (lsPlugin->api->cls,
5948 nameTransport, 5738 nameTransport,
5949 address, addressLen, 5739 address, addressLen,
5950 numeric, 5740 numeric,
5951 rtimeout, 5741 rtimeout,
5952 &transmit_address_to_client, tc); 5742 &transmit_address_to_client, tc);
5953} 5743}
@@ -5961,8 +5751,8 @@ handle_address_lookup (void *cls,
5961 */ 5751 */
5962static void 5752static void
5963handle_peer_address_lookup (void *cls, 5753handle_peer_address_lookup (void *cls,
5964 struct GNUNET_SERVER_Client *client, 5754 struct GNUNET_SERVER_Client *client,
5965 const struct GNUNET_MessageHeader *message) 5755 const struct GNUNET_MessageHeader *message)
5966{ 5756{
5967 const struct PeerAddressLookupMessage *peer_address_lookup; 5757 const struct PeerAddressLookupMessage *peer_address_lookup;
5968 struct NeighbourMapEntry *neighbor_iterator; 5758 struct NeighbourMapEntry *neighbor_iterator;
@@ -5977,11 +5767,11 @@ handle_peer_address_lookup (void *cls,
5977 5767
5978 size = ntohs (message->size); 5768 size = ntohs (message->size);
5979 if (size < sizeof (struct PeerAddressLookupMessage)) 5769 if (size < sizeof (struct PeerAddressLookupMessage))
5980 { 5770 {
5981 GNUNET_break_op (0); 5771 GNUNET_break_op (0);
5982 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 5772 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5983 return; 5773 return;
5984 } 5774 }
5985 peer_address_lookup = (const struct PeerAddressLookupMessage *) message; 5775 peer_address_lookup = (const struct PeerAddressLookupMessage *) message;
5986 5776
5987 rtimeout = GNUNET_TIME_relative_ntoh (peer_address_lookup->timeout); 5777 rtimeout = GNUNET_TIME_relative_ntoh (peer_address_lookup->timeout);
@@ -5990,56 +5780,54 @@ handle_peer_address_lookup (void *cls,
5990 5780
5991 /* Found no neighbor matching this peer id (shouldn't be possible, but...) */ 5781 /* Found no neighbor matching this peer id (shouldn't be possible, but...) */
5992 if (neighbor_iterator == NULL) 5782 if (neighbor_iterator == NULL)
5993 { 5783 {
5994 GNUNET_break(0); 5784 GNUNET_break (0);
5995 tc = GNUNET_SERVER_transmit_context_create (client); 5785 tc = GNUNET_SERVER_transmit_context_create (client);
5996 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, 5786 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
5997 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY); 5787 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY);
5998 GNUNET_SERVER_transmit_context_run (tc, rtimeout); 5788 GNUNET_SERVER_transmit_context_run (tc, rtimeout);
5999 return; 5789 return;
6000 } 5790 }
6001 5791
6002 ready_iterator = neighbor_iterator->plugins; 5792 ready_iterator = neighbor_iterator->plugins;
6003 GNUNET_SERVER_disable_receive_done_warning (client); 5793 GNUNET_SERVER_disable_receive_done_warning (client);
6004 tc = GNUNET_SERVER_transmit_context_create (client); 5794 tc = GNUNET_SERVER_transmit_context_create (client);
6005 while(ready_iterator != NULL) 5795 while (ready_iterator != NULL)
5796 {
5797 foreign_address_iterator = ready_iterator->addresses;
5798 while (foreign_address_iterator != NULL)
6006 { 5799 {
6007 foreign_address_iterator = ready_iterator->addresses; 5800 transport_plugin = foreign_address_iterator->ready_list->plugin;
6008 while (foreign_address_iterator != NULL) 5801 if (foreign_address_iterator->addr != NULL)
6009 { 5802 {
6010 transport_plugin = foreign_address_iterator->ready_list->plugin; 5803 GNUNET_asprintf (&addr_buf, "%s --- %s, %s",
6011 if (foreign_address_iterator->addr != NULL) 5804 a2s (transport_plugin->short_name,
6012 { 5805 foreign_address_iterator->addr,
6013 GNUNET_asprintf (&addr_buf, "%s --- %s, %s", 5806 foreign_address_iterator->addrlen),
6014 a2s (transport_plugin->short_name, 5807 (foreign_address_iterator->connected
6015 foreign_address_iterator->addr, 5808 == GNUNET_YES) ? "CONNECTED"
6016 foreign_address_iterator->addrlen), 5809 : "DISCONNECTED",
6017 (foreign_address_iterator->connected 5810 (foreign_address_iterator->validated
6018 == GNUNET_YES) ? "CONNECTED" 5811 == GNUNET_YES) ? "VALIDATED" : "UNVALIDATED");
6019 : "DISCONNECTED", 5812 transmit_address_to_client (tc, addr_buf);
6020 (foreign_address_iterator->validated 5813 GNUNET_free (addr_buf);
6021 == GNUNET_YES) ? "VALIDATED" 5814 }
6022 : "UNVALIDATED"); 5815 else if (foreign_address_iterator->addrlen == 0)
6023 transmit_address_to_client(tc, addr_buf); 5816 {
6024 GNUNET_free (addr_buf); 5817 GNUNET_asprintf (&addr_buf, "%s --- %s, %s", "<inbound>",
6025 } 5818 (foreign_address_iterator->connected
6026 else if (foreign_address_iterator->addrlen == 0) 5819 == GNUNET_YES) ? "CONNECTED"
6027 { 5820 : "DISCONNECTED",
6028 GNUNET_asprintf (&addr_buf, "%s --- %s, %s", "<inbound>", 5821 (foreign_address_iterator->validated
6029 (foreign_address_iterator->connected 5822 == GNUNET_YES) ? "VALIDATED" : "UNVALIDATED");
6030 == GNUNET_YES) ? "CONNECTED" 5823 transmit_address_to_client (tc, addr_buf);
6031 : "DISCONNECTED", 5824 GNUNET_free (addr_buf);
6032 (foreign_address_iterator->validated 5825 }
6033 == GNUNET_YES) ? "VALIDATED" 5826
6034 : "UNVALIDATED"); 5827 foreign_address_iterator = foreign_address_iterator->next;
6035 transmit_address_to_client (tc, addr_buf);
6036 GNUNET_free (addr_buf);
6037 }
6038
6039 foreign_address_iterator = foreign_address_iterator->next;
6040 }
6041 ready_iterator = ready_iterator->next;
6042 } 5828 }
5829 ready_iterator = ready_iterator->next;
5830 }
6043 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, 5831 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
6044 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY); 5832 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY);
6045 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); 5833 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
@@ -6048,9 +5836,7 @@ handle_peer_address_lookup (void *cls,
6048 5836
6049 5837
6050static int 5838static int
6051output_addresses (void *cls, 5839output_addresses (void *cls, const GNUNET_HashCode * key, void *value)
6052 const GNUNET_HashCode *key,
6053 void *value)
6054{ 5840{
6055 struct GNUNET_SERVER_TransmitContext *tc = cls; 5841 struct GNUNET_SERVER_TransmitContext *tc = cls;
6056 struct NeighbourMapEntry *neighbor_iterator = value; 5842 struct NeighbourMapEntry *neighbor_iterator = value;
@@ -6061,46 +5847,44 @@ output_addresses (void *cls,
6061 5847
6062 ready_iterator = neighbor_iterator->plugins; 5848 ready_iterator = neighbor_iterator->plugins;
6063 while (ready_iterator != NULL) 5849 while (ready_iterator != NULL)
5850 {
5851 foreign_address_iterator = ready_iterator->addresses;
5852 while (foreign_address_iterator != NULL)
6064 { 5853 {
6065 foreign_address_iterator = ready_iterator->addresses; 5854 transport_plugin = foreign_address_iterator->ready_list->plugin;
6066 while (foreign_address_iterator != NULL) 5855 if (foreign_address_iterator->addr != NULL)
6067 { 5856 {
6068 transport_plugin = foreign_address_iterator->ready_list->plugin; 5857 GNUNET_asprintf (&addr_buf, "%s:%s --- %s, %s",
6069 if (foreign_address_iterator->addr != NULL) 5858 GNUNET_i2s (&neighbor_iterator->id),
6070 { 5859 a2s (transport_plugin->short_name,
6071 GNUNET_asprintf (&addr_buf, "%s:%s --- %s, %s", 5860 foreign_address_iterator->addr,
6072 GNUNET_i2s(&neighbor_iterator->id), 5861 foreign_address_iterator->addrlen),
6073 a2s (transport_plugin->short_name, 5862 (foreign_address_iterator->connected
6074 foreign_address_iterator->addr, 5863 == GNUNET_YES) ? "CONNECTED"
6075 foreign_address_iterator->addrlen), 5864 : "DISCONNECTED",
6076 (foreign_address_iterator->connected 5865 (foreign_address_iterator->validated
6077 == GNUNET_YES) ? "CONNECTED" 5866 == GNUNET_YES) ? "VALIDATED" : "UNVALIDATED");
6078 : "DISCONNECTED", 5867 transmit_address_to_client (tc, addr_buf);
6079 (foreign_address_iterator->validated 5868 GNUNET_free (addr_buf);
6080 == GNUNET_YES) ? "VALIDATED" 5869 }
6081 : "UNVALIDATED"); 5870 else if (foreign_address_iterator->addrlen == 0)
6082 transmit_address_to_client (tc, addr_buf); 5871 {
6083 GNUNET_free (addr_buf); 5872 GNUNET_asprintf (&addr_buf, "%s:%s --- %s, %s",
6084 } 5873 GNUNET_i2s (&neighbor_iterator->id),
6085 else if (foreign_address_iterator->addrlen == 0) 5874 "<inbound>",
6086 { 5875 (foreign_address_iterator->connected
6087 GNUNET_asprintf (&addr_buf, "%s:%s --- %s, %s", 5876 == GNUNET_YES) ? "CONNECTED"
6088 GNUNET_i2s (&neighbor_iterator->id), 5877 : "DISCONNECTED",
6089 "<inbound>", 5878 (foreign_address_iterator->validated
6090 (foreign_address_iterator->connected 5879 == GNUNET_YES) ? "VALIDATED" : "UNVALIDATED");
6091 == GNUNET_YES) ? "CONNECTED" 5880 transmit_address_to_client (tc, addr_buf);
6092 : "DISCONNECTED", 5881 GNUNET_free (addr_buf);
6093 (foreign_address_iterator->validated 5882 }
6094 == GNUNET_YES) ? "VALIDATED" 5883
6095 : "UNVALIDATED"); 5884 foreign_address_iterator = foreign_address_iterator->next;
6096 transmit_address_to_client (tc, addr_buf);
6097 GNUNET_free (addr_buf);
6098 }
6099
6100 foreign_address_iterator = foreign_address_iterator->next;
6101 }
6102 ready_iterator = ready_iterator->next;
6103 } 5885 }
5886 ready_iterator = ready_iterator->next;
5887 }
6104 return GNUNET_OK; 5888 return GNUNET_OK;
6105} 5889}
6106 5890
@@ -6122,16 +5906,14 @@ handle_address_iterate (void *cls,
6122 5906
6123 size = ntohs (message->size); 5907 size = ntohs (message->size);
6124 if (size < sizeof (struct AddressIterateMessage)) 5908 if (size < sizeof (struct AddressIterateMessage))
6125 { 5909 {
6126 GNUNET_break_op (0); 5910 GNUNET_break_op (0);
6127 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 5911 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
6128 return; 5912 return;
6129 } 5913 }
6130 GNUNET_SERVER_disable_receive_done_warning (client); 5914 GNUNET_SERVER_disable_receive_done_warning (client);
6131 tc = GNUNET_SERVER_transmit_context_create (client); 5915 tc = GNUNET_SERVER_transmit_context_create (client);
6132 GNUNET_CONTAINER_multihashmap_iterate (neighbours, 5916 GNUNET_CONTAINER_multihashmap_iterate (neighbours, &output_addresses, tc);
6133 &output_addresses,
6134 tc);
6135 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, 5917 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
6136 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY); 5918 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY);
6137 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); 5919 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
@@ -6141,7 +5923,7 @@ handle_address_iterate (void *cls,
6141static const struct GNUNET_MessageHeader * 5923static const struct GNUNET_MessageHeader *
6142do_get_our_hello () 5924do_get_our_hello ()
6143{ 5925{
6144 return (const struct GNUNET_MessageHeader*) our_hello; 5926 return (const struct GNUNET_MessageHeader *) our_hello;
6145} 5927}
6146 5928
6147 5929
@@ -6167,8 +5949,7 @@ create_environment (struct TransportPlugin *plug)
6167 * Start the specified transport (load the plugin). 5949 * Start the specified transport (load the plugin).
6168 */ 5950 */
6169static void 5951static void
6170start_transport (struct GNUNET_SERVER_Handle *server, 5952start_transport (struct GNUNET_SERVER_Handle *server, const char *name)
6171 const char *name)
6172{ 5953{
6173 struct TransportPlugin *plug; 5954 struct TransportPlugin *plug;
6174 char *libname; 5955 char *libname;
@@ -6184,31 +5965,29 @@ start_transport (struct GNUNET_SERVER_Handle *server,
6184 plugins = plug; 5965 plugins = plug;
6185 plug->api = GNUNET_PLUGIN_load (libname, &plug->env); 5966 plug->api = GNUNET_PLUGIN_load (libname, &plug->env);
6186 if (plug->api == NULL) 5967 if (plug->api == NULL)
6187 { 5968 {
6188 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 5969 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6189 _("Failed to load transport plugin for `%s'\n"), name); 5970 _("Failed to load transport plugin for `%s'\n"), name);
6190 GNUNET_free (plug->short_name); 5971 GNUNET_free (plug->short_name);
6191 plugins = plug->next; 5972 plugins = plug->next;
6192 GNUNET_free (libname); 5973 GNUNET_free (libname);
6193 GNUNET_free (plug); 5974 GNUNET_free (plug);
6194 } 5975 }
6195} 5976}
6196 5977
6197 5978
6198static int 5979static int
6199null_mq_client_pointers (void *cls, 5980null_mq_client_pointers (void *cls, const GNUNET_HashCode * key, void *value)
6200 const GNUNET_HashCode *key,
6201 void *value)
6202{ 5981{
6203 struct TransportClient *pos = cls; 5982 struct TransportClient *pos = cls;
6204 struct NeighbourMapEntry *n = value; 5983 struct NeighbourMapEntry *n = value;
6205 struct MessageQueue *mq; 5984 struct MessageQueue *mq;
6206 5985
6207 for (mq = n->messages_head; mq != NULL; mq = mq->next) 5986 for (mq = n->messages_head; mq != NULL; mq = mq->next)
6208 { 5987 {
6209 if (mq->client == pos) 5988 if (mq->client == pos)
6210 mq->client = NULL; /* do not use anymore! */ 5989 mq->client = NULL; /* do not use anymore! */
6211 } 5990 }
6212 return GNUNET_OK; 5991 return GNUNET_OK;
6213} 5992}
6214 5993
@@ -6221,8 +6000,7 @@ null_mq_client_pointers (void *cls,
6221 * @param client identification of the client 6000 * @param client identification of the client
6222 */ 6001 */
6223static void 6002static void
6224client_disconnect_notification (void *cls, 6003client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client)
6225 struct GNUNET_SERVER_Client *client)
6226{ 6004{
6227 struct TransportClient *pos; 6005 struct TransportClient *pos;
6228 struct TransportClient *prev; 6006 struct TransportClient *prev;
@@ -6239,89 +6017,81 @@ client_disconnect_notification (void *cls,
6239 /* clean up blacklister */ 6017 /* clean up blacklister */
6240 bl = bl_head; 6018 bl = bl_head;
6241 while (bl != NULL) 6019 while (bl != NULL)
6020 {
6021 if (bl->client == client)
6242 { 6022 {
6243 if (bl->client == client) 6023 bc = bc_head;
6244 { 6024 while (bc != NULL)
6245 bc = bc_head; 6025 {
6246 while (bc != NULL) 6026 if (bc->bl_pos == bl)
6247 { 6027 {
6248 if (bc->bl_pos == bl) 6028 bc->bl_pos = bl->next;
6249 { 6029 if (bc->th != NULL)
6250 bc->bl_pos = bl->next; 6030 {
6251 if (bc->th != NULL) 6031 GNUNET_CONNECTION_notify_transmit_ready_cancel (bc->th);
6252 { 6032 bc->th = NULL;
6253 GNUNET_CONNECTION_notify_transmit_ready_cancel (bc->th); 6033 }
6254 bc->th = NULL; 6034 if (bc->task == GNUNET_SCHEDULER_NO_TASK)
6255 } 6035 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc);
6256 if (bc->task == GNUNET_SCHEDULER_NO_TASK) 6036 break;
6257 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, 6037 }
6258 bc); 6038 bc = bc->next;
6259 break; 6039 }
6260 } 6040 GNUNET_CONTAINER_DLL_remove (bl_head, bl_tail, bl);
6261 bc = bc->next; 6041 GNUNET_SERVER_client_drop (bl->client);
6262 } 6042 GNUNET_free (bl);
6263 GNUNET_CONTAINER_DLL_remove (bl_head, 6043 break;
6264 bl_tail,
6265 bl);
6266 GNUNET_SERVER_client_drop (bl->client);
6267 GNUNET_free (bl);
6268 break;
6269 }
6270 bl = bl->next;
6271 } 6044 }
6045 bl = bl->next;
6046 }
6272 /* clean up 'normal' clients */ 6047 /* clean up 'normal' clients */
6273 prev = NULL; 6048 prev = NULL;
6274 pos = clients; 6049 pos = clients;
6275 while ((pos != NULL) && (pos->client != client)) 6050 while ((pos != NULL) && (pos->client != client))
6276 { 6051 {
6277 prev = pos; 6052 prev = pos;
6278 pos = pos->next; 6053 pos = pos->next;
6279 } 6054 }
6280 if (pos == NULL) 6055 if (pos == NULL)
6281 return; 6056 return;
6282 while (NULL != (mqe = pos->message_queue_head)) 6057 while (NULL != (mqe = pos->message_queue_head))
6283 { 6058 {
6284 GNUNET_CONTAINER_DLL_remove (pos->message_queue_head, 6059 GNUNET_CONTAINER_DLL_remove (pos->message_queue_head,
6285 pos->message_queue_tail, 6060 pos->message_queue_tail, mqe);
6286 mqe); 6061 pos->message_count--;
6287 pos->message_count--; 6062 GNUNET_free (mqe);
6288 GNUNET_free (mqe); 6063 }
6289 }
6290 if (NULL != neighbours) 6064 if (NULL != neighbours)
6291 GNUNET_CONTAINER_multihashmap_iterate (neighbours, 6065 GNUNET_CONTAINER_multihashmap_iterate (neighbours,
6292 &null_mq_client_pointers, 6066 &null_mq_client_pointers, pos);
6293 pos);
6294 if (prev == NULL) 6067 if (prev == NULL)
6295 clients = pos->next; 6068 clients = pos->next;
6296 else 6069 else
6297 prev->next = pos->next; 6070 prev->next = pos->next;
6298 if (GNUNET_YES == pos->tcs_pending) 6071 if (GNUNET_YES == pos->tcs_pending)
6299 { 6072 {
6300 pos->client = NULL; 6073 pos->client = NULL;
6301 return; 6074 return;
6302 } 6075 }
6303 if (pos->th != NULL) 6076 if (pos->th != NULL)
6304 { 6077 {
6305 GNUNET_CONNECTION_notify_transmit_ready_cancel (pos->th); 6078 GNUNET_CONNECTION_notify_transmit_ready_cancel (pos->th);
6306 pos->th = NULL; 6079 pos->th = NULL;
6307 } 6080 }
6308 GNUNET_break (0 == pos->message_count); 6081 GNUNET_break (0 == pos->message_count);
6309 GNUNET_free (pos); 6082 GNUNET_free (pos);
6310} 6083}
6311 6084
6312 6085
6313static int 6086static int
6314disconnect_all_neighbours (void *cls, 6087disconnect_all_neighbours (void *cls, const GNUNET_HashCode * key, void *value)
6315 const GNUNET_HashCode *key,
6316 void *value)
6317{ 6088{
6318 struct NeighbourMapEntry *n = value; 6089 struct NeighbourMapEntry *n = value;
6319 6090
6320#if DEBUG_TRANSPORT 6091#if DEBUG_TRANSPORT
6321 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 6092 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6322 "Disconnecting peer `%4s', %s\n", 6093 "Disconnecting peer `%4s', %s\n",
6323 GNUNET_i2s(&n->id), 6094 GNUNET_i2s (&n->id), "SHUTDOWN_TASK");
6324 "SHUTDOWN_TASK");
6325#endif 6095#endif
6326 disconnect_neighbour (n, GNUNET_NO); 6096 disconnect_neighbour (n, GNUNET_NO);
6327 return GNUNET_OK; 6097 return GNUNET_OK;
@@ -6344,44 +6114,42 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
6344 6114
6345 shutdown_in_progress = GNUNET_YES; 6115 shutdown_in_progress = GNUNET_YES;
6346 GNUNET_CONTAINER_multihashmap_iterate (neighbours, 6116 GNUNET_CONTAINER_multihashmap_iterate (neighbours,
6347 &disconnect_all_neighbours, 6117 &disconnect_all_neighbours, NULL);
6348 NULL);
6349#if DEBUG_TRANSPORT 6118#if DEBUG_TRANSPORT
6350 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 6119 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6351 "Transport service is unloading plugins...\n"); 6120 "Transport service is unloading plugins...\n");
6352#endif 6121#endif
6353 while (NULL != (plug = plugins)) 6122 while (NULL != (plug = plugins))
6123 {
6124 if (plug->address_update_task != GNUNET_SCHEDULER_NO_TASK)
6354 { 6125 {
6355 if (plug->address_update_task != GNUNET_SCHEDULER_NO_TASK) 6126 GNUNET_SCHEDULER_cancel (plug->address_update_task);
6356 { 6127 plug->address_update_task = GNUNET_SCHEDULER_NO_TASK;
6357 GNUNET_SCHEDULER_cancel (plug->address_update_task);
6358 plug->address_update_task = GNUNET_SCHEDULER_NO_TASK;
6359 }
6360 GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api));
6361 GNUNET_free (plug->lib_name);
6362 GNUNET_free (plug->short_name);
6363 while (NULL != (al = plug->addresses))
6364 {
6365 plug->addresses = al->next;
6366 GNUNET_free (al);
6367 }
6368 plugins = plug->next;
6369 GNUNET_free (plug);
6370 } 6128 }
6129 GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api));
6130 GNUNET_free (plug->lib_name);
6131 GNUNET_free (plug->short_name);
6132 while (NULL != (al = plug->addresses))
6133 {
6134 plug->addresses = al->next;
6135 GNUNET_free (al);
6136 }
6137 plugins = plug->next;
6138 GNUNET_free (plug);
6139 }
6371 if (my_private_key != NULL) 6140 if (my_private_key != NULL)
6372 GNUNET_CRYPTO_rsa_key_free (my_private_key); 6141 GNUNET_CRYPTO_rsa_key_free (my_private_key);
6373 GNUNET_free_non_null (our_hello); 6142 GNUNET_free_non_null (our_hello);
6374 6143
6375 GNUNET_CONTAINER_multihashmap_iterate (validation_map, 6144 GNUNET_CONTAINER_multihashmap_iterate (validation_map,
6376 &abort_validation, 6145 &abort_validation, NULL);
6377 NULL);
6378 GNUNET_CONTAINER_multihashmap_destroy (validation_map); 6146 GNUNET_CONTAINER_multihashmap_destroy (validation_map);
6379 validation_map = NULL; 6147 validation_map = NULL;
6380 6148
6381 6149
6382 if (ats_task != GNUNET_SCHEDULER_NO_TASK) 6150 if (ats_task != GNUNET_SCHEDULER_NO_TASK)
6383 { 6151 {
6384 GNUNET_SCHEDULER_cancel(ats_task); 6152 GNUNET_SCHEDULER_cancel (ats_task);
6385 ats_task = GNUNET_SCHEDULER_NO_TASK; 6153 ats_task = GNUNET_SCHEDULER_NO_TASK;
6386 } 6154 }
6387#if HAVE_LIBGLPK 6155#if HAVE_LIBGLPK
@@ -6391,41 +6159,41 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
6391 6159
6392 /* free 'chvc' data structure */ 6160 /* free 'chvc' data structure */
6393 while (NULL != (chvc = chvc_head)) 6161 while (NULL != (chvc = chvc_head))
6162 {
6163 chvc_head = chvc->next;
6164 if (chvc->piter != NULL)
6394 { 6165 {
6395 chvc_head = chvc->next; 6166 GNUNET_PEERINFO_iterate_cancel (chvc->piter);
6396 if (chvc->piter != NULL) 6167 GNUNET_STATISTICS_update (stats,
6397 { 6168 gettext_noop
6398 GNUNET_PEERINFO_iterate_cancel (chvc->piter); 6169 ("# outstanding peerinfo iterate requests"), -1,
6399 GNUNET_STATISTICS_update (stats, 6170 GNUNET_NO);
6400 gettext_noop ("# outstanding peerinfo iterate requests"), 6171 chvc->ve_count--;
6401 -1,
6402 GNUNET_NO);
6403 chvc->ve_count --;
6404 }
6405 else
6406 GNUNET_break (0);
6407 GNUNET_assert (chvc->ve_count == 0);
6408 GNUNET_free (chvc);
6409 } 6172 }
6173 else
6174 GNUNET_break (0);
6175 GNUNET_assert (chvc->ve_count == 0);
6176 GNUNET_free (chvc);
6177 }
6410 chvc_tail = NULL; 6178 chvc_tail = NULL;
6411 6179
6412 if (stats != NULL) 6180 if (stats != NULL)
6413 { 6181 {
6414 GNUNET_STATISTICS_destroy (stats, GNUNET_NO); 6182 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
6415 stats = NULL; 6183 stats = NULL;
6416 } 6184 }
6417 if (peerinfo != NULL) 6185 if (peerinfo != NULL)
6418 { 6186 {
6419 GNUNET_PEERINFO_disconnect (peerinfo); 6187 GNUNET_PEERINFO_disconnect (peerinfo);
6420 peerinfo = NULL; 6188 peerinfo = NULL;
6421 } 6189 }
6422 if (GNUNET_SCHEDULER_NO_TASK != hello_task) 6190 if (GNUNET_SCHEDULER_NO_TASK != hello_task)
6423 { 6191 {
6424 GNUNET_SCHEDULER_cancel (hello_task); 6192 GNUNET_SCHEDULER_cancel (hello_task);
6425 hello_task = GNUNET_SCHEDULER_NO_TASK; 6193 hello_task = GNUNET_SCHEDULER_NO_TASK;
6426 } 6194 }
6427 /* Can we assume those are gone by now, or do we need to clean up 6195 /* Can we assume those are gone by now, or do we need to clean up
6428 explicitly!? */ 6196 * explicitly!? */
6429 GNUNET_break (bl_head == NULL); 6197 GNUNET_break (bl_head == NULL);
6430 GNUNET_break (bc_head == NULL); 6198 GNUNET_break (bc_head == NULL);
6431 GNUNET_CONTAINER_multihashmap_destroy (neighbours); 6199 GNUNET_CONTAINER_multihashmap_destroy (neighbours);
@@ -6433,17 +6201,17 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
6433} 6201}
6434 6202
6435 6203
6436void ats_result_cb () 6204void
6205ats_result_cb ()
6437{ 6206{
6438 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 6207 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS Result callback\n");
6439 "ATS Result callback\n");
6440} 6208}
6441 6209
6442 6210
6443#if HAVE_LIBGLPK 6211#if HAVE_LIBGLPK
6444struct AtsBuildContext 6212struct AtsBuildContext
6445{ 6213{
6446 struct ATS_mechanism * mechanisms; 6214 struct ATS_mechanism *mechanisms;
6447 struct ATS_peer *peers; 6215 struct ATS_peer *peers;
6448 int c_peers; 6216 int c_peers;
6449 int c_mechs; 6217 int c_mechs;
@@ -6451,70 +6219,70 @@ struct AtsBuildContext
6451 6219
6452 6220
6453static int 6221static int
6454find_and_count_addresses (void *cls, 6222find_and_count_addresses (void *cls, const GNUNET_HashCode * key, void *value)
6455 const GNUNET_HashCode *key,
6456 void *value)
6457{ 6223{
6458 struct AtsBuildContext *abc = cls; 6224 struct AtsBuildContext *abc = cls;
6459 struct NeighbourMapEntry *next = value; 6225 struct NeighbourMapEntry *next = value;
6460 int found_addresses = GNUNET_NO; 6226 int found_addresses = GNUNET_NO;
6461 6227
6462 struct ReadyList *r_next = next->plugins; 6228 struct ReadyList *r_next = next->plugins;
6229
6463 while (r_next != NULL) 6230 while (r_next != NULL)
6231 {
6232 struct ForeignAddressList *a_next = r_next->addresses;
6233
6234 while (a_next != NULL)
6464 { 6235 {
6465 struct ForeignAddressList * a_next = r_next->addresses; 6236 abc->c_mechs++;
6466 while (a_next != NULL) 6237 found_addresses = GNUNET_YES;
6467 { 6238 a_next = a_next->next;
6468 abc->c_mechs++;
6469 found_addresses = GNUNET_YES;
6470 a_next = a_next->next;
6471 }
6472 r_next = r_next->next;
6473 } 6239 }
6474 if (found_addresses) 6240 r_next = r_next->next;
6241 }
6242 if (found_addresses)
6475 abc->c_peers++; 6243 abc->c_peers++;
6476 return GNUNET_OK; 6244 return GNUNET_OK;
6477} 6245}
6478 6246
6479 6247
6480static int 6248static int
6481setup_ats_problem (void *cls, 6249setup_ats_problem (void *cls, const GNUNET_HashCode * key, void *value)
6482 const GNUNET_HashCode *key,
6483 void *value)
6484{ 6250{
6485 struct AtsBuildContext *abc = cls; 6251 struct AtsBuildContext *abc = cls;
6486 struct NeighbourMapEntry *next = value; 6252 struct NeighbourMapEntry *next = value;
6487 6253
6488 int found_addresses = GNUNET_NO; 6254 int found_addresses = GNUNET_NO;
6489 struct ReadyList *r_next = next->plugins; 6255 struct ReadyList *r_next = next->plugins;
6256
6490 while (r_next != NULL) 6257 while (r_next != NULL)
6258 {
6259 struct ForeignAddressList *a_next = r_next->addresses;
6260
6261 while (a_next != NULL)
6491 { 6262 {
6492 struct ForeignAddressList * a_next = r_next->addresses; 6263 if (found_addresses == GNUNET_NO)
6493 while (a_next != NULL) 6264 {
6494 { 6265 abc->peers[abc->c_peers].peer = next->id;
6495 if (found_addresses == GNUNET_NO) 6266 abc->peers[abc->c_peers].m_head = NULL;
6496 { 6267 abc->peers[abc->c_peers].m_tail = NULL;
6497 abc->peers[abc->c_peers].peer = next->id; 6268 abc->peers[abc->c_peers].f = 1.0 / abc->c_mechs;
6498 abc->peers[abc->c_peers].m_head = NULL; 6269 }
6499 abc->peers[abc->c_peers].m_tail = NULL; 6270 abc->mechanisms[abc->c_mechs].addr = a_next;
6500 abc->peers[abc->c_peers].f = 1.0 / abc->c_mechs; 6271 abc->mechanisms[abc->c_mechs].col_index = abc->c_mechs;
6501 } 6272 abc->mechanisms[abc->c_mechs].peer = &abc->peers[abc->c_peers];
6502 abc->mechanisms[abc->c_mechs].addr = a_next; 6273 abc->mechanisms[abc->c_mechs].next = NULL;
6503 abc->mechanisms[abc->c_mechs].col_index = abc->c_mechs; 6274 abc->mechanisms[abc->c_mechs].plugin = r_next->plugin;
6504 abc->mechanisms[abc->c_mechs].peer = &abc->peers[abc->c_peers]; 6275 abc->mechanisms[abc->c_mechs].ressources = a_next->ressources;
6505 abc->mechanisms[abc->c_mechs].next = NULL; 6276 abc->mechanisms[abc->c_mechs].quality = a_next->quality;
6506 abc->mechanisms[abc->c_mechs].plugin = r_next->plugin; 6277 GNUNET_CONTAINER_DLL_insert_tail (abc->peers[abc->c_peers].m_head,
6507 abc->mechanisms[abc->c_mechs].ressources = a_next->ressources; 6278 abc->peers[abc->c_peers].m_tail,
6508 abc->mechanisms[abc->c_mechs].quality = a_next->quality; 6279 &abc->mechanisms[abc->c_mechs]);
6509 GNUNET_CONTAINER_DLL_insert_tail(abc->peers[abc->c_peers].m_head, 6280 found_addresses = GNUNET_YES;
6510 abc->peers[abc->c_peers].m_tail, 6281 abc->c_mechs++;
6511 &abc->mechanisms[abc->c_mechs]); 6282 a_next = a_next->next;
6512 found_addresses = GNUNET_YES; 6283 }
6513 abc->c_mechs++; 6284 r_next = r_next->next;
6514 a_next = a_next->next; 6285 }
6515 }
6516 r_next = r_next->next;
6517 }
6518 if (found_addresses == GNUNET_YES) 6286 if (found_addresses == GNUNET_YES)
6519 abc->c_peers++; 6287 abc->c_peers++;
6520 return GNUNET_OK; 6288 return GNUNET_OK;
@@ -6522,43 +6290,40 @@ setup_ats_problem (void *cls,
6522 6290
6523 6291
6524static void 6292static void
6525create_ats_information ( struct ATS_peer **p, 6293create_ats_information (struct ATS_peer **p,
6526 int * c_p, 6294 int *c_p, struct ATS_mechanism **m, int *c_m)
6527 struct ATS_mechanism ** m,
6528 int * c_m )
6529{ 6295{
6530 struct AtsBuildContext abc; 6296 struct AtsBuildContext abc;
6531 6297
6532#if VERBOSE_ATS 6298#if VERBOSE_ATS
6533 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 6299 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6534 "ATS requires clean address information\n"); 6300 "ATS requires clean address information\n");
6535#endif 6301#endif
6536 abc.c_peers = 0; 6302 abc.c_peers = 0;
6537 abc.c_mechs = 0; 6303 abc.c_mechs = 0;
6538 GNUNET_CONTAINER_multihashmap_iterate (neighbours, 6304 GNUNET_CONTAINER_multihashmap_iterate (neighbours,
6539 &find_and_count_addresses, 6305 &find_and_count_addresses, &abc);
6540 &abc);
6541#if VERBOSE_ATS 6306#if VERBOSE_ATS
6542 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 6307 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6543 "Found %u peers with % u transport mechanisms\n", c_peers, c_mechs); 6308 "Found %u peers with % u transport mechanisms\n", c_peers,
6309 c_mechs);
6544#endif 6310#endif
6545 6311
6546 if ( (abc.c_peers == 0) && (abc.c_mechs == 0) ) 6312 if ((abc.c_peers == 0) && (abc.c_mechs == 0))
6547 { 6313 {
6548 *p = NULL; 6314 *p = NULL;
6549 (*c_p) = 0; 6315 (*c_p) = 0;
6550 *m = NULL; 6316 *m = NULL;
6551 (*c_m) = 0; 6317 (*c_m) = 0;
6552 return; 6318 return;
6553 } 6319 }
6554 6320
6555 abc.mechanisms = GNUNET_malloc((1+abc.c_mechs) * sizeof (struct ATS_mechanism)); 6321 abc.mechanisms =
6556 abc.peers = GNUNET_malloc((1+abc.c_peers) * sizeof (struct ATS_peer)); 6322 GNUNET_malloc ((1 + abc.c_mechs) * sizeof (struct ATS_mechanism));
6323 abc.peers = GNUNET_malloc ((1 + abc.c_peers) * sizeof (struct ATS_peer));
6557 abc.c_mechs = 1; 6324 abc.c_mechs = 1;
6558 abc.c_peers = 1; 6325 abc.c_peers = 1;
6559 GNUNET_CONTAINER_multihashmap_iterate (neighbours, 6326 GNUNET_CONTAINER_multihashmap_iterate (neighbours, &setup_ats_problem, &abc);
6560 &setup_ats_problem,
6561 &abc);
6562 abc.c_mechs--; 6327 abc.c_mechs--;
6563 abc.c_peers--; 6328 abc.c_peers--;
6564 (*c_m) = abc.c_mechs; 6329 (*c_m) = abc.c_mechs;
@@ -6569,27 +6334,29 @@ create_ats_information ( struct ATS_peer **p,
6569 6334
6570 6335
6571static void 6336static void
6572schedule_ats (void *cls, 6337schedule_ats (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
6573 const struct GNUNET_SCHEDULER_TaskContext *tc)
6574{ 6338{
6575 struct ATS_Handle *ats = (struct ATS_Handle *) cls; 6339 struct ATS_Handle *ats = (struct ATS_Handle *) cls;
6576 if (ats==NULL) 6340
6341 if (ats == NULL)
6577 return; 6342 return;
6578 6343
6579 ats_task = GNUNET_SCHEDULER_NO_TASK; 6344 ats_task = GNUNET_SCHEDULER_NO_TASK;
6580 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 6345 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
6581 return; 6346 return;
6582 6347
6583 if (shutdown_in_progress == GNUNET_YES) 6348 if (shutdown_in_progress == GNUNET_YES)
6584 return; 6349 return;
6585 6350
6586 struct GNUNET_TIME_Relative delta = 6351 struct GNUNET_TIME_Relative delta =
6587 GNUNET_TIME_absolute_get_difference (last_ats_execution, GNUNET_TIME_absolute_get()); 6352 GNUNET_TIME_absolute_get_difference (last_ats_execution,
6353 GNUNET_TIME_absolute_get ());
6354
6588 if (delta.rel_value < ats_minimum_interval.rel_value) 6355 if (delta.rel_value < ats_minimum_interval.rel_value)
6589 { 6356 {
6590#if DEBUG_ATS 6357#if DEBUG_ATS
6591 GNUNET_log (GNUNET_ERROR_TYPE_BULK, 6358 GNUNET_log (GNUNET_ERROR_TYPE_BULK,
6592 "Minimum time between cycles not reached\n"); 6359 "Minimum time between cycles not reached\n");
6593#endif 6360#endif
6594 return; 6361 return;
6595 } 6362 }
@@ -6600,19 +6367,19 @@ schedule_ats (void *cls,
6600#if HAVE_LIBGLPK 6367#if HAVE_LIBGLPK
6601 ats_calculate_bandwidth_distribution (ats); 6368 ats_calculate_bandwidth_distribution (ats);
6602#endif 6369#endif
6603 last_ats_execution = GNUNET_TIME_absolute_get(); 6370 last_ats_execution = GNUNET_TIME_absolute_get ();
6604 6371
6605 ats_task = GNUNET_SCHEDULER_add_delayed (ats_regular_interval, 6372 ats_task = GNUNET_SCHEDULER_add_delayed (ats_regular_interval,
6606 &schedule_ats, ats); 6373 &schedule_ats, ats);
6607} 6374}
6608#endif 6375#endif
6609 6376
6610 6377
6611struct ForeignAddressList * get_preferred_ats_address ( 6378struct ForeignAddressList *
6612 struct NeighbourMapEntry *n) 6379get_preferred_ats_address (struct NeighbourMapEntry *n)
6613{ 6380{
6614 // TODO get ATS prefered address 6381 // TODO get ATS prefered address
6615 return find_ready_address(n); 6382 return find_ready_address (n);
6616} 6383}
6617 6384
6618/** 6385/**
@@ -6635,7 +6402,8 @@ run (void *cls,
6635 {&handle_send, NULL, 6402 {&handle_send, NULL,
6636 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND, 0}, 6403 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND, 0},
6637 {&handle_request_connect, NULL, 6404 {&handle_request_connect, NULL,
6638 GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_CONNECT, sizeof(struct TransportRequestConnectMessage)}, 6405 GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_CONNECT,
6406 sizeof (struct TransportRequestConnectMessage)},
6639 {&handle_set_quota, NULL, 6407 {&handle_set_quota, NULL,
6640 GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA, sizeof (struct QuotaSetMessage)}, 6408 GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA, sizeof (struct QuotaSetMessage)},
6641 {&handle_address_lookup, NULL, 6409 {&handle_address_lookup, NULL,
@@ -6648,9 +6416,11 @@ run (void *cls,
6648 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE, 6416 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE,
6649 0}, 6417 0},
6650 {&handle_blacklist_init, NULL, 6418 {&handle_blacklist_init, NULL,
6651 GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_INIT, sizeof (struct GNUNET_MessageHeader)}, 6419 GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_INIT,
6420 sizeof (struct GNUNET_MessageHeader)},
6652 {&handle_blacklist_reply, NULL, 6421 {&handle_blacklist_reply, NULL,
6653 GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY, sizeof (struct BlacklistMessage)}, 6422 GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY,
6423 sizeof (struct BlacklistMessage)},
6654 {NULL, NULL, 0, 0} 6424 {NULL, NULL, 0, 0}
6655 }; 6425 };
6656 char *plugs; 6426 char *plugs;
@@ -6674,61 +6444,60 @@ run (void *cls,
6674 GNUNET_CONFIGURATION_get_value_filename (c, 6444 GNUNET_CONFIGURATION_get_value_filename (c,
6675 "GNUNETD", 6445 "GNUNETD",
6676 "HOSTKEY", &keyfile))) 6446 "HOSTKEY", &keyfile)))
6447 {
6448 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6449 _
6450 ("Transport service is lacking key configuration settings. Exiting.\n"));
6451 GNUNET_SCHEDULER_shutdown ();
6452 if (stats != NULL)
6677 { 6453 {
6678 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 6454 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
6679 _ 6455 stats = NULL;
6680 ("Transport service is lacking key configuration settings. Exiting.\n"));
6681 GNUNET_SCHEDULER_shutdown ();
6682 if (stats != NULL)
6683 {
6684 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
6685 stats = NULL;
6686 }
6687 GNUNET_CONTAINER_multihashmap_destroy (validation_map);
6688 validation_map = NULL;
6689 GNUNET_CONTAINER_multihashmap_destroy (neighbours);
6690 neighbours = NULL;
6691 return;
6692 } 6456 }
6457 GNUNET_CONTAINER_multihashmap_destroy (validation_map);
6458 validation_map = NULL;
6459 GNUNET_CONTAINER_multihashmap_destroy (neighbours);
6460 neighbours = NULL;
6461 return;
6462 }
6693 6463
6694 max_connect_per_transport = (uint32_t) tneigh; 6464 max_connect_per_transport = (uint32_t) tneigh;
6695 peerinfo = GNUNET_PEERINFO_connect (cfg); 6465 peerinfo = GNUNET_PEERINFO_connect (cfg);
6696 if (peerinfo == NULL) 6466 if (peerinfo == NULL)
6467 {
6468 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6469 _("Could not access PEERINFO service. Exiting.\n"));
6470 GNUNET_SCHEDULER_shutdown ();
6471 if (stats != NULL)
6697 { 6472 {
6698 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 6473 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
6699 _("Could not access PEERINFO service. Exiting.\n")); 6474 stats = NULL;
6700 GNUNET_SCHEDULER_shutdown ();
6701 if (stats != NULL)
6702 {
6703 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
6704 stats = NULL;
6705 }
6706 GNUNET_CONTAINER_multihashmap_destroy (validation_map);
6707 validation_map = NULL;
6708 GNUNET_CONTAINER_multihashmap_destroy (neighbours);
6709 neighbours = NULL;
6710 GNUNET_free (keyfile);
6711 return;
6712 } 6475 }
6476 GNUNET_CONTAINER_multihashmap_destroy (validation_map);
6477 validation_map = NULL;
6478 GNUNET_CONTAINER_multihashmap_destroy (neighbours);
6479 neighbours = NULL;
6480 GNUNET_free (keyfile);
6481 return;
6482 }
6713 my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); 6483 my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
6714 GNUNET_free (keyfile); 6484 GNUNET_free (keyfile);
6715 if (my_private_key == NULL) 6485 if (my_private_key == NULL)
6486 {
6487 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6488 _("Transport service could not access hostkey. Exiting.\n"));
6489 GNUNET_SCHEDULER_shutdown ();
6490 if (stats != NULL)
6716 { 6491 {
6717 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 6492 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
6718 _ 6493 stats = NULL;
6719 ("Transport service could not access hostkey. Exiting.\n"));
6720 GNUNET_SCHEDULER_shutdown ();
6721 if (stats != NULL)
6722 {
6723 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
6724 stats = NULL;
6725 }
6726 GNUNET_CONTAINER_multihashmap_destroy (validation_map);
6727 validation_map = NULL;
6728 GNUNET_CONTAINER_multihashmap_destroy (neighbours);
6729 neighbours = NULL;
6730 return;
6731 } 6494 }
6495 GNUNET_CONTAINER_multihashmap_destroy (validation_map);
6496 validation_map = NULL;
6497 GNUNET_CONTAINER_multihashmap_destroy (neighbours);
6498 neighbours = NULL;
6499 return;
6500 }
6732 GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key); 6501 GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
6733 GNUNET_CRYPTO_hash (&my_public_key, 6502 GNUNET_CRYPTO_hash (&my_public_key,
6734 sizeof (my_public_key), &my_identity.hashPubKey); 6503 sizeof (my_public_key), &my_identity.hashPubKey);
@@ -6738,20 +6507,19 @@ run (void *cls,
6738 /* load plugins... */ 6507 /* load plugins... */
6739 no_transports = 1; 6508 no_transports = 1;
6740 if (GNUNET_OK == 6509 if (GNUNET_OK ==
6741 GNUNET_CONFIGURATION_get_value_string (c, 6510 GNUNET_CONFIGURATION_get_value_string (c, "TRANSPORT", "PLUGINS", &plugs))
6742 "TRANSPORT", "PLUGINS", &plugs)) 6511 {
6512 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
6513 _("Starting transport plugins `%s'\n"), plugs);
6514 pos = strtok (plugs, " ");
6515 while (pos != NULL)
6743 { 6516 {
6744 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 6517 start_transport (server, pos);
6745 _("Starting transport plugins `%s'\n"), plugs); 6518 no_transports = 0;
6746 pos = strtok (plugs, " "); 6519 pos = strtok (NULL, " ");
6747 while (pos != NULL)
6748 {
6749 start_transport (server, pos);
6750 no_transports = 0;
6751 pos = strtok (NULL, " ");
6752 }
6753 GNUNET_free (plugs);
6754 } 6520 }
6521 GNUNET_free (plugs);
6522 }
6755 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, 6523 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
6756 &shutdown_task, NULL); 6524 &shutdown_task, NULL);
6757 if (no_transports) 6525 if (no_transports)
@@ -6759,8 +6527,9 @@ run (void *cls,
6759 6527
6760 /* Initializing ATS */ 6528 /* Initializing ATS */
6761 int co; 6529 int co;
6762 char * section; 6530 char *section;
6763 unsigned long long value; 6531 unsigned long long value;
6532
6764#if HAVE_LIBGLPK 6533#if HAVE_LIBGLPK
6765 double D = 1.0; 6534 double D = 1.0;
6766 double U = 1.0; 6535 double U = 1.0;
@@ -6773,39 +6542,35 @@ run (void *cls,
6773 ats_regular_interval = ATS_EXEC_INTERVAL; 6542 ats_regular_interval = ATS_EXEC_INTERVAL;
6774 6543
6775 /* loading cost ressources */ 6544 /* loading cost ressources */
6776 for (co=0; co<available_ressources; co++) 6545 for (co = 0; co < available_ressources; co++)
6777 { 6546 {
6778 GNUNET_asprintf(&section,"%s_UP",ressources[co].cfg_param); 6547 GNUNET_asprintf (&section, "%s_UP", ressources[co].cfg_param);
6779 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", section)) 6548 if (GNUNET_CONFIGURATION_have_value (cfg, "transport", section))
6780 { 6549 {
6781 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(cfg, 6550 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg,
6782 "transport", 6551 "transport",
6783 section, 6552 section, &value))
6784 &value))
6785 { 6553 {
6786#if DEBUG_ATS 6554#if DEBUG_ATS
6787 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 6555 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6788 "Found ressource cost: [%s] = %llu\n", 6556 "Found ressource cost: [%s] = %llu\n", section, value);
6789 section, value);
6790#endif 6557#endif
6791 ressources[co].c_max = value; 6558 ressources[co].c_max = value;
6792 } 6559 }
6793 } 6560 }
6794 GNUNET_free (section); 6561 GNUNET_free (section);
6795 GNUNET_asprintf(&section,"%s_DOWN",ressources[co].cfg_param); 6562 GNUNET_asprintf (&section, "%s_DOWN", ressources[co].cfg_param);
6796 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", section)) 6563 if (GNUNET_CONFIGURATION_have_value (cfg, "transport", section))
6797 { 6564 {
6798 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(cfg, 6565 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg,
6799 "transport", 6566 "transport",
6800 section, 6567 section, &value))
6801 &value))
6802 { 6568 {
6803#if DEBUG_ATS 6569#if DEBUG_ATS
6804 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 6570 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6805 "Found ressource cost: [%s] = %llu\n", 6571 "Found ressource cost: [%s] = %llu\n", section, value);
6806 section, value);
6807#endif 6572#endif
6808 ressources[co].c_min = value; 6573 ressources[co].c_min = value;
6809 } 6574 }
6810 } 6575 }
6811 GNUNET_free (section); 6576 GNUNET_free (section);
@@ -6813,32 +6578,28 @@ run (void *cls,
6813#if HAVE_LIBGLPK 6578#if HAVE_LIBGLPK
6814 ats = ats_init (D, U, R, v_b_min, v_n_min, 6579 ats = ats_init (D, U, R, v_b_min, v_n_min,
6815 ATS_MAX_ITERATIONS, ATS_MAX_EXEC_DURATION, 6580 ATS_MAX_ITERATIONS, ATS_MAX_EXEC_DURATION,
6816 &create_ats_information, 6581 &create_ats_information, ats_result_cb);
6817 ats_result_cb); 6582 ats_set_logging_options (ats, stats, cfg);
6818 ats_set_logging_options (ats,
6819 stats,
6820 cfg);
6821 GNUNET_break (GNUNET_OK == 6583 GNUNET_break (GNUNET_OK ==
6822 GNUNET_CONFIGURATION_get_value_time (cfg, 6584 GNUNET_CONFIGURATION_get_value_time (cfg,
6823 "transport", 6585 "transport",
6824 "ATS_EXEC_INTERVAL", 6586 "ATS_EXEC_INTERVAL",
6825 &ats_regular_interval)); 6587 &ats_regular_interval));
6826 GNUNET_break (GNUNET_OK == 6588 GNUNET_break (GNUNET_OK ==
6827 GNUNET_CONFIGURATION_get_value_time (cfg, 6589 GNUNET_CONFIGURATION_get_value_time (cfg,
6828 "transport", 6590 "transport",
6829 "ATS_MIN_INTERVAL", 6591 "ATS_MIN_INTERVAL",
6830 &ats_minimum_interval)); 6592 &ats_minimum_interval));
6831 if (ats != NULL) 6593 if (ats != NULL)
6832 ats_task = GNUNET_SCHEDULER_add_now (&schedule_ats, ats); 6594 ats_task = GNUNET_SCHEDULER_add_now (&schedule_ats, ats);
6833#endif 6595#endif
6834 6596
6835 6597
6836#if DEBUG_TRANSPORT 6598#if DEBUG_TRANSPORT
6837 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 6599 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Transport service ready.\n"));
6838 _("Transport service ready.\n"));
6839#endif 6600#endif
6840 /* If we have a blacklist file, read from it */ 6601 /* If we have a blacklist file, read from it */
6841 read_blacklist_file(cfg); 6602 read_blacklist_file (cfg);
6842 /* process client requests */ 6603 /* process client requests */
6843 GNUNET_SERVER_add_handlers (server, handlers); 6604 GNUNET_SERVER_add_handlers (server, handlers);
6844} 6605}
@@ -6854,13 +6615,12 @@ run (void *cls,
6854int 6615int
6855main (int argc, char *const *argv) 6616main (int argc, char *const *argv)
6856{ 6617{
6857 a2s (NULL, NULL, 0); /* make compiler happy */ 6618 a2s (NULL, NULL, 0); /* make compiler happy */
6858 return (GNUNET_OK == 6619 return (GNUNET_OK ==
6859 GNUNET_SERVICE_run (argc, 6620 GNUNET_SERVICE_run (argc,
6860 argv, 6621 argv,
6861 "transport", 6622 "transport",
6862 GNUNET_SERVICE_OPTION_NONE, 6623 GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1;
6863 &run, NULL)) ? 0 : 1;
6864} 6624}
6865 6625
6866/* end of gnunet-service-transport.c */ 6626/* end of gnunet-service-transport.c */