diff options
author | Martin Schanzenbach <schanzen@gnunet.org> | 2023-07-08 16:48:39 +0200 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2023-07-08 16:48:39 +0200 |
commit | fcfcd0979331b8435beee97e847c775f16785f11 (patch) | |
tree | c5ee95f4519493728096819233fcf1df49cf6cb3 /src/transport/gnunet-communicator-udp.c | |
parent | 146b879bcf2d0eee090f47171ca10a4478a85ffb (diff) | |
download | gnunet-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.c | 382 |
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 | } |