aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-communicator-udp.c
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2023-07-08 16:48:39 +0200
committerMartin Schanzenbach <schanzen@gnunet.org>2023-07-08 16:48:39 +0200
commitfcfcd0979331b8435beee97e847c775f16785f11 (patch)
treec5ee95f4519493728096819233fcf1df49cf6cb3 /src/transport/gnunet-communicator-udp.c
parent146b879bcf2d0eee090f47171ca10a4478a85ffb (diff)
downloadgnunet-fcfcd0979331b8435beee97e847c775f16785f11.tar.gz
gnunet-fcfcd0979331b8435beee97e847c775f16785f11.zip
TRANSPORT: Use loop for UDP communicator to handle buffer
Diffstat (limited to 'src/transport/gnunet-communicator-udp.c')
-rw-r--r--src/transport/gnunet-communicator-udp.c382
1 files changed, 194 insertions, 188 deletions
diff --git a/src/transport/gnunet-communicator-udp.c b/src/transport/gnunet-communicator-udp.c
index 4657a7220..f4a25328f 100644
--- a/src/transport/gnunet-communicator-udp.c
+++ b/src/transport/gnunet-communicator-udp.c
@@ -2218,222 +2218,228 @@ sock_read (void *cls)
2218 udp_sock, 2218 udp_sock,
2219 &sock_read, 2219 &sock_read,
2220 NULL); 2220 NULL);
2221 rcvd = GNUNET_NETWORK_socket_recvfrom (udp_sock, 2221 while (1)
2222 buf, 2222 {
2223 sizeof(buf), 2223 rcvd = GNUNET_NETWORK_socket_recvfrom (udp_sock,
2224 (struct sockaddr *) &sa, 2224 buf,
2225 &salen); 2225 sizeof(buf),
2226 if (-1 == rcvd) 2226 (struct sockaddr *) &sa,
2227 { 2227 &salen);
2228 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "recv"); 2228 if (-1 == rcvd)
2229 return; 2229 {
2230 } 2230 if (EAGAIN == errno)
2231 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2231 break; // We are done reading data
2232 "Read %lu bytes\n", rcvd); 2232 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "recv");
2233 return;
2234 }
2235 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2236 "Read %lu bytes\n", rcvd);
2233 2237
2234 if (rcvd > sizeof(struct UDPRekey)) 2238 if (rcvd > sizeof(struct UDPRekey))
2235 { 2239 {
2236 const struct UDPRekey *rekey; 2240 const struct UDPRekey *rekey;
2237 const struct UDPBox *box; 2241 const struct UDPBox *box;
2238 struct KeyCacheEntry *kce; 2242 struct KeyCacheEntry *kce;
2239 struct SenderAddress *sender; 2243 struct SenderAddress *sender;
2240 int do_decrypt = GNUNET_NO; 2244 int do_decrypt = GNUNET_NO;
2241 2245
2242 rekey = (const struct UDPRekey *) buf; 2246 rekey = (const struct UDPRekey *) buf;
2243 box = (const struct UDPBox *) buf; 2247 box = (const struct UDPBox *) buf;
2244 kce = GNUNET_CONTAINER_multishortmap_get (key_cache, &rekey->kid); 2248 kce = GNUNET_CONTAINER_multishortmap_get (key_cache, &rekey->kid);
2245 2249
2246 if ((GNUNET_YES == box->rekeying) || (GNUNET_NO == box->rekeying)) 2250 if ((GNUNET_YES == box->rekeying) || (GNUNET_NO == box->rekeying))
2247 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2251 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2248 "UDPRekey has rekeying %u\n", 2252 "UDPRekey has rekeying %u\n",
2249 box->rekeying); 2253 box->rekeying);
2250 else 2254 else
2251 do_decrypt = GNUNET_YES; 2255 do_decrypt = GNUNET_YES;
2256
2257 if ((GNUNET_YES == do_decrypt) && (NULL != kce) && (GNUNET_YES ==
2258 kce->ss->sender->
2259 rekeying))
2260 {
2261 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2262 "UDPRekey with kid %s\n",
2263 GNUNET_sh2s (&rekey->kid));
2264 sender = setup_sender (&rekey->sender, (const struct sockaddr *) &sa,
2265 salen);
2252 2266
2253 if ((GNUNET_YES == do_decrypt) && (NULL != kce) && (GNUNET_YES == 2267 if (NULL != sender->ss_rekey)
2254 kce->ss->sender-> 2268 return;
2255 rekeying))
2256 {
2257 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2258 "UDPRekey with kid %s\n",
2259 GNUNET_sh2s (&rekey->kid));
2260 sender = setup_sender (&rekey->sender, (const struct sockaddr *) &sa,
2261 salen);
2262 2269
2263 if (NULL != sender->ss_rekey) 2270 decrypt_rekey (rekey, (size_t) rcvd, kce, sender);
2264 return; 2271 return;
2265 2272 }
2266 decrypt_rekey (rekey, (size_t) rcvd, kce, sender);
2267 return;
2268 } 2273 }
2269 }
2270 2274
2271 /* first, see if it is a UDPBox */ 2275 /* first, see if it is a UDPBox */
2272 if (rcvd > sizeof(struct UDPBox)) 2276 if (rcvd > sizeof(struct UDPBox))
2273 {
2274 const struct UDPBox *box;
2275 struct KeyCacheEntry *kce;
2276
2277 box = (const struct UDPBox *) buf;
2278 kce = GNUNET_CONTAINER_multishortmap_get (key_cache, &box->kid);
2279 if (NULL != kce)
2280 { 2277 {
2281 decrypt_box (box, (size_t) rcvd, kce); 2278 const struct UDPBox *box;
2282 return; 2279 struct KeyCacheEntry *kce;
2283 }
2284 }
2285 2280
2286 /* next, check if it is a broadcast */ 2281 box = (const struct UDPBox *) buf;
2287 if (sizeof(struct UDPBroadcast) == rcvd) 2282 kce = GNUNET_CONTAINER_multishortmap_get (key_cache, &box->kid);
2288 { 2283 if (NULL != kce)
2289 const struct UDPBroadcast *ub; 2284 {
2290 struct UdpBroadcastSignature uhs; 2285 decrypt_box (box, (size_t) rcvd, kce);
2291 struct GNUNET_PeerIdentity sender; 2286 continue;
2287 }
2288 }
2292 2289
2293 addr_verify = GNUNET_memdup (&sa, salen); 2290 /* next, check if it is a broadcast */
2294 addr_verify->sin_port = 0; 2291 if (sizeof(struct UDPBroadcast) == rcvd)
2295 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2296 "received UDPBroadcast from %s\n",
2297 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2298 ub = (const struct UDPBroadcast *) buf;
2299 uhs.purpose.purpose = htonl (
2300 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST);
2301 uhs.purpose.size = htonl (sizeof(uhs));
2302 uhs.sender = ub->sender;
2303 sender = ub->sender;
2304 if (0 == memcmp (&sender, &my_identity, sizeof (struct
2305 GNUNET_PeerIdentity)))
2306 { 2292 {
2293 const struct UDPBroadcast *ub;
2294 struct UdpBroadcastSignature uhs;
2295 struct GNUNET_PeerIdentity sender;
2296
2297 addr_verify = GNUNET_memdup (&sa, salen);
2298 addr_verify->sin_port = 0;
2307 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2299 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2308 "Received our own broadcast\n"); 2300 "received UDPBroadcast from %s\n",
2309 GNUNET_free (addr_verify); 2301 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2310 return; 2302 ub = (const struct UDPBroadcast *) buf;
2311 } 2303 uhs.purpose.purpose = htonl (
2312 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2304 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST);
2313 "checking UDPBroadcastSignature for %s\n", 2305 uhs.purpose.size = htonl (sizeof(uhs));
2314 GNUNET_i2s (&sender)); 2306 uhs.sender = ub->sender;
2315 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen, &uhs.h_address); 2307 sender = ub->sender;
2316 if (GNUNET_OK == 2308 if (0 == memcmp (&sender, &my_identity, sizeof (struct
2317 GNUNET_CRYPTO_eddsa_verify ( 2309 GNUNET_PeerIdentity)))
2318 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST, 2310 {
2319 &uhs, 2311 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2320 &ub->sender_sig, 2312 "Received our own broadcast\n");
2321 &ub->sender.public_key)) 2313 GNUNET_free (addr_verify);
2322 { 2314 continue;
2323 char *addr_s; 2315 }
2324 enum GNUNET_NetworkType nt;
2325
2326 addr_s =
2327 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2328 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2329 /* use our own mechanism to determine network type */
2330 nt =
2331 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2332 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2316 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2333 "validating address %s received from UDPBroadcast\n", 2317 "checking UDPBroadcastSignature for %s\n",
2334 GNUNET_i2s (&sender)); 2318 GNUNET_i2s (&sender));
2335 GNUNET_TRANSPORT_application_validate (ah, &sender, nt, addr_s); 2319 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2336 GNUNET_free (addr_s); 2320 &uhs.h_address);
2321 if (GNUNET_OK ==
2322 GNUNET_CRYPTO_eddsa_verify (
2323 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST,
2324 &uhs,
2325 &ub->sender_sig,
2326 &ub->sender.public_key))
2327 {
2328 char *addr_s;
2329 enum GNUNET_NetworkType nt;
2330
2331 addr_s =
2332 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2333 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2334 /* use our own mechanism to determine network type */
2335 nt =
2336 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2337 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2338 "validating address %s received from UDPBroadcast\n",
2339 GNUNET_i2s (&sender));
2340 GNUNET_TRANSPORT_application_validate (ah, &sender, nt, addr_s);
2341 GNUNET_free (addr_s);
2342 GNUNET_free (addr_verify);
2343 continue;
2344 }
2345 else
2346 {
2347 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2348 "VerifyingPeer %s is verifying UDPBroadcast\n",
2349 GNUNET_i2s (&my_identity));
2350 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2351 "Verifying UDPBroadcast from %s failed\n",
2352 GNUNET_i2s (&ub->sender));
2353 }
2337 GNUNET_free (addr_verify); 2354 GNUNET_free (addr_verify);
2338 return; 2355 /* continue with KX, mostly for statistics... */
2339 } 2356 }
2340 else
2341 {
2342 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2343 "VerifyingPeer %s is verifying UDPBroadcast\n",
2344 GNUNET_i2s (&my_identity));
2345 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2346 "Verifying UDPBroadcast from %s failed\n",
2347 GNUNET_i2s (&ub->sender));
2348 }
2349 GNUNET_free (addr_verify);
2350 /* continue with KX, mostly for statistics... */
2351 }
2352 2357
2353 2358
2354 /* finally, test if it is a KX */ 2359 /* finally, test if it is a KX */
2355 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX)) 2360 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2356 {
2357 GNUNET_STATISTICS_update (stats,
2358 "# messages dropped (no kid, too small for KX)",
2359 1,
2360 GNUNET_NO);
2361 return;
2362 }
2363 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2364 "Got KX\n");
2365 {
2366 const struct InitialKX *kx;
2367 struct SharedSecret *ss;
2368 char pbuf[rcvd - sizeof(struct InitialKX)];
2369 const struct UDPConfirmation *uc;
2370 struct SenderAddress *sender;
2371
2372 kx = (const struct InitialKX *) buf;
2373 ss = setup_shared_secret_dec (&kx->ephemeral);
2374 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2375 "Before DEC\n");
2376
2377 if (GNUNET_OK != try_decrypt (ss,
2378 kx->gcm_tag,
2379 0,
2380 &buf[sizeof(*kx)],
2381 sizeof(pbuf),
2382 pbuf))
2383 { 2361 {
2384 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2385 "Unable to decrypt tag, dropping...\n");
2386 GNUNET_free (ss);
2387 GNUNET_STATISTICS_update (
2388 stats,
2389 "# messages dropped (no kid, AEAD decryption failed)",
2390 1,
2391 GNUNET_NO);
2392 return;
2393 }
2394 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2395 "Before VERIFY\n");
2396
2397 uc = (const struct UDPConfirmation *) pbuf;
2398 if (GNUNET_OK != verify_confirmation (&kx->ephemeral, uc))
2399 {
2400 GNUNET_break_op (0);
2401 GNUNET_free (ss);
2402 GNUNET_STATISTICS_update (stats, 2362 GNUNET_STATISTICS_update (stats,
2403 "# messages dropped (sender signature invalid)", 2363 "# messages dropped (no kid, too small for KX)",
2404 1, 2364 1,
2405 GNUNET_NO); 2365 GNUNET_NO);
2406 return; 2366 continue;
2407 } 2367 }
2408 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2368 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2409 "Before SETUP_SENDER\n"); 2369 "Got KX\n");
2410
2411 calculate_cmac (ss);
2412 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2413 ss->sender = sender;
2414 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2415 sender->num_secrets++;
2416 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2417 GNUNET_STATISTICS_update (stats,
2418 "# messages decrypted without BOX",
2419 1,
2420 GNUNET_NO);
2421 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2422 if ((GNUNET_NO == kx->rekeying) && (GNUNET_YES == ss->sender->rekeying))
2423 { 2370 {
2424 ss->sender->rekeying = GNUNET_NO; 2371 const struct InitialKX *kx;
2425 sender->ss_rekey = NULL; 2372 struct SharedSecret *ss;
2426 // destroy_all_secrets (ss, GNUNET_NO); 2373 char pbuf[rcvd - sizeof(struct InitialKX)];
2374 const struct UDPConfirmation *uc;
2375 struct SenderAddress *sender;
2376
2377 kx = (const struct InitialKX *) buf;
2378 ss = setup_shared_secret_dec (&kx->ephemeral);
2427 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2379 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2428 "Receiver stopped rekeying.\n"); 2380 "Before DEC\n");
2429 } 2381
2430 else if (GNUNET_NO == kx->rekeying) 2382 if (GNUNET_OK != try_decrypt (ss,
2431 consider_ss_ack (ss, GNUNET_YES); 2383 kx->gcm_tag,
2432 else 2384 0,
2433 { 2385 &buf[sizeof(*kx)],
2434 ss->sender->rekeying = GNUNET_YES; 2386 sizeof(pbuf),
2387 pbuf))
2388 {
2389 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2390 "Unable to decrypt tag, dropping...\n");
2391 GNUNET_free (ss);
2392 GNUNET_STATISTICS_update (
2393 stats,
2394 "# messages dropped (no kid, AEAD decryption failed)",
2395 1,
2396 GNUNET_NO);
2397 continue;
2398 }
2399 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2400 "Before VERIFY\n");
2401
2402 uc = (const struct UDPConfirmation *) pbuf;
2403 if (GNUNET_OK != verify_confirmation (&kx->ephemeral, uc))
2404 {
2405 GNUNET_break_op (0);
2406 GNUNET_free (ss);
2407 GNUNET_STATISTICS_update (stats,
2408 "# messages dropped (sender signature invalid)",
2409 1,
2410 GNUNET_NO);
2411 continue;
2412 }
2435 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2413 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2436 "Got KX: Receiver doing rekeying.\n"); 2414 "Before SETUP_SENDER\n");
2415
2416 calculate_cmac (ss);
2417 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2418 ss->sender = sender;
2419 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2420 sender->num_secrets++;
2421 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2422 GNUNET_STATISTICS_update (stats,
2423 "# messages decrypted without BOX",
2424 1,
2425 GNUNET_NO);
2426 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2427 if ((GNUNET_NO == kx->rekeying) && (GNUNET_YES == ss->sender->rekeying))
2428 {
2429 ss->sender->rekeying = GNUNET_NO;
2430 sender->ss_rekey = NULL;
2431 // destroy_all_secrets (ss, GNUNET_NO);
2432 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2433 "Receiver stopped rekeying.\n");
2434 }
2435 else if (GNUNET_NO == kx->rekeying)
2436 consider_ss_ack (ss, GNUNET_YES);
2437 else
2438 {
2439 ss->sender->rekeying = GNUNET_YES;
2440 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2441 "Got KX: Receiver doing rekeying.\n");
2442 }
2437 } 2443 }
2438 } 2444 }
2439} 2445}