diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2022-01-31 18:29:45 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2022-01-31 18:29:45 +0300 |
commit | 464d174103165453f149141d505ec8a09cc2fb17 (patch) | |
tree | 40cd9b2694d654f4fab948fc816c27671dcd89dc | |
parent | 1e82d32256c98de9bda8b61444eb53c626f76561 (diff) | |
download | libmicrohttpd-464d174103165453f149141d505ec8a09cc2fb17.tar.gz libmicrohttpd-464d174103165453f149141d505ec8a09cc2fb17.zip |
MHD_ip_limit_add(): do not use syscalls while holding the lock
-rw-r--r-- | src/microhttpd/daemon.c | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index 47fe742d..587000de 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -378,9 +378,9 @@ MHD_ip_limit_add (struct MHD_Daemon *daemon, | |||
378 | const struct sockaddr *addr, | 378 | const struct sockaddr *addr, |
379 | socklen_t addrlen) | 379 | socklen_t addrlen) |
380 | { | 380 | { |
381 | struct MHD_IPCount *key; | 381 | struct MHD_IPCount *newkeyp; |
382 | void **nodep; | 382 | struct MHD_IPCount *keyp; |
383 | void *node; | 383 | struct MHD_IPCount **nodep; |
384 | enum MHD_Result result; | 384 | enum MHD_Result result; |
385 | 385 | ||
386 | daemon = MHD_get_master (daemon); | 386 | daemon = MHD_get_master (daemon); |
@@ -388,45 +388,47 @@ MHD_ip_limit_add (struct MHD_Daemon *daemon, | |||
388 | if (0 == daemon->per_ip_connection_limit) | 388 | if (0 == daemon->per_ip_connection_limit) |
389 | return MHD_YES; | 389 | return MHD_YES; |
390 | 390 | ||
391 | if (NULL == (key = malloc (sizeof(*key)))) | 391 | newkeyp = (struct MHD_IPCount *) malloc (sizeof(struct MHD_IPCount)); |
392 | if (NULL == newkeyp) | ||
392 | return MHD_NO; | 393 | return MHD_NO; |
393 | 394 | ||
394 | /* Initialize key */ | 395 | /* Initialize key */ |
395 | if (MHD_NO == MHD_ip_addr_to_key (addr, | 396 | if (MHD_NO == MHD_ip_addr_to_key (addr, |
396 | addrlen, | 397 | addrlen, |
397 | key)) | 398 | newkeyp)) |
398 | { | 399 | { |
399 | /* Allow unhandled address types through */ | 400 | free (newkeyp); |
400 | free (key); | 401 | return MHD_YES; /* Allow unhandled address types through */ |
401 | return MHD_YES; | ||
402 | } | 402 | } |
403 | |||
403 | MHD_ip_count_lock (daemon); | 404 | MHD_ip_count_lock (daemon); |
404 | 405 | ||
405 | /* Search for the IP address */ | 406 | /* Search for the IP address */ |
406 | if (NULL == (nodep = tsearch (key, | 407 | nodep = (struct MHD_IPCount **) tsearch (newkeyp, |
407 | &daemon->per_ip_connection_count, | 408 | &daemon->per_ip_connection_count, |
408 | &MHD_ip_addr_compare))) | 409 | &MHD_ip_addr_compare); |
410 | if (NULL == nodep) | ||
409 | { | 411 | { |
412 | MHD_ip_count_unlock (daemon); | ||
413 | free (newkeyp); | ||
410 | #ifdef HAVE_MESSAGES | 414 | #ifdef HAVE_MESSAGES |
411 | MHD_DLOG (daemon, | 415 | MHD_DLOG (daemon, |
412 | _ ("Failed to add IP connection count node.\n")); | 416 | _ ("Failed to add IP connection count node.\n")); |
413 | #endif | 417 | #endif |
414 | MHD_ip_count_unlock (daemon); | ||
415 | free (key); | ||
416 | return MHD_NO; | 418 | return MHD_NO; |
417 | } | 419 | } |
418 | node = *nodep; | 420 | keyp = *nodep; |
419 | /* If we got an existing node back, free the one we created */ | ||
420 | if (node != key) | ||
421 | free (key); | ||
422 | key = (struct MHD_IPCount *) node; | ||
423 | /* Test if there is room for another connection; if so, | 421 | /* Test if there is room for another connection; if so, |
424 | * increment count */ | 422 | * increment count */ |
425 | result = (key->count < daemon->per_ip_connection_limit) ? MHD_YES : MHD_NO; | 423 | result = (keyp->count < daemon->per_ip_connection_limit) ? MHD_YES : MHD_NO; |
426 | if (MHD_NO != result) | 424 | if (MHD_NO != result) |
427 | ++key->count; | 425 | ++keyp->count; |
428 | |||
429 | MHD_ip_count_unlock (daemon); | 426 | MHD_ip_count_unlock (daemon); |
427 | |||
428 | /* If we got an existing node back, free the one we created */ | ||
429 | if (keyp != newkeyp) | ||
430 | free (newkeyp); | ||
431 | |||
430 | return result; | 432 | return result; |
431 | } | 433 | } |
432 | 434 | ||