GeezerVison is showing github.com — deps: libuv: reapply 3a9a6e3e6b · nodejs/node@c6ccbd7
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: deps/uv/docs/src/tcp.rst +29Lines changed: 29 additions & 0 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
| 91 | 91 |
| 92 | 92 | .. versionchanged:: 1.49.0 If `delay` is less than 1 then ``UV_EINVAL``` is returned. | 93 | 93 |
| | 94 | +.. c:function:: int uv_tcp_keepalive_ex(uv_tcp_t* handle, int on, unsigned int idle, unsigned int intvl, unsigned int cnt) | | 95 | +
| | 96 | + Enable / disable TCP keep-alive with all socket options: `TCP_KEEPIDLE`, `TCP_KEEPINTVL` and `TCP_KEEPCNT`. | | 97 | + `idle` is the value for `TCP_KEEPIDLE`, `intvl` is the value for `TCP_KEEPINTVL`, | | 98 | + `cnt` is the value for `TCP_KEEPCNT`, ignored when `on` is zero. | | 99 | +
| | 100 | + With TCP keep-alive enabled, `idle` is the time (in seconds) the connection needs to remain idle before | | 101 | + TCP starts sending keep-alive probes. `intvl` is the time (in seconds) between individual keep-alive probes. | | 102 | + TCP will drop the connection after sending `cnt` probes without getting any replies from the peer, then the | | 103 | + handle is destroyed with a ``UV_ETIMEDOUT`` error passed to the corresponding callback. | | 104 | +
| | 105 | + If one of `idle`, `intvl`, or `cnt` is less than 1, ``UV_EINVAL`` is returned. | | 106 | +
| | 107 | + .. versionchanged:: 1.52.0 added support of setting `TCP_KEEPINTVL` and `TCP_KEEPCNT` socket options. | | 108 | +
| | 109 | + .. note:: | | 110 | + Ensure that the socket options are supported by the underlying operating system. | | 111 | + Currently supported platforms: | | 112 | + - AIX | | 113 | + - DragonFlyBSD | | 114 | + - FreeBSD | | 115 | + - HP-UX | | 116 | + - illumos | | 117 | + - Linux | | 118 | + - macOS | | 119 | + - NetBSD | | 120 | + - Solaris | | 121 | + - Windows | | 122 | +
| 94 | 123 | .. c:function:: int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) | 95 | 124 |
| 96 | 125 | Enable / disable simultaneous asynchronous accept requests that are | |
Collapse file Copy file name to clipboardExpand all lines: deps/uv/include/uv.h +5Lines changed: 5 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -602,6 +602,11 @@ UV_EXTERN int uv_tcp_nodelay(uv_tcp_t* handle, int enable); | 602 | 602 | UV_EXTERN int uv_tcp_keepalive(uv_tcp_t* handle, | 603 | 603 | int enable, | 604 | 604 | unsigned int delay); | | 605 | +UV_EXTERN int uv_tcp_keepalive_ex(uv_tcp_t* handle, | | 606 | + int on, | | 607 | + unsigned int idle, | | 608 | + unsigned int intvl, | | 609 | + unsigned int cnt); | 605 | 610 | UV_EXTERN int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable); | 606 | 611 |
| 607 | 612 | enum uv_tcp_flags { | |
Collapse file Copy file name to clipboardExpand all lines: deps/uv/src/unix/internal.h +5-1Lines changed: 5 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -359,7 +359,11 @@ int uv__slurp(const char* filename, char* buf, size_t len); | 359 | 359 | /* tcp */ | 360 | 360 | int uv__tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb); | 361 | 361 | int uv__tcp_nodelay(int fd, int on); | 362 | | -int uv__tcp_keepalive(int fd, int on, unsigned int delay); | | 362 | +int uv__tcp_keepalive(int fd, | | 363 | + int on, | | 364 | + unsigned int idle, | | 365 | + unsigned int intvl, | | 366 | + unsigned int cnt); | 363 | 367 |
| 364 | 368 | /* tty */ | 365 | 369 | void uv__tty_close(uv_tty_t* handle); | |
Collapse file Copy file name to clipboardExpand all lines: deps/uv/src/unix/stream.c +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -416,7 +416,7 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) { | 416 | 416 |
| 417 | 417 | /* TODO Use delay the user passed in. */ | 418 | 418 | if ((stream->flags & UV_HANDLE_TCP_KEEPALIVE) && | 419 | | - uv__tcp_keepalive(fd, 1, 60)) { | | 419 | + uv__tcp_keepalive(fd, 1, 60, 1, 10)) { | 420 | 420 | return UV__ERR(errno); | 421 | 421 | } | 422 | 422 | } | |
Collapse file Copy file name to clipboardExpand all lines: deps/uv/src/unix/tcp.c +25-22Lines changed: 25 additions & 22 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -465,22 +465,18 @@ int uv__tcp_nodelay(int fd, int on) { | 465 | 465 | #else | 466 | 466 | #define UV_KEEPALIVE_FACTOR(x) | 467 | 467 | #endif | 468 | | -int uv__tcp_keepalive(int fd, int on, unsigned int delay) { | 469 | | - int idle; | 470 | | - int intvl; | 471 | | - int cnt; | 472 | | - | 473 | | - (void) &idle; | 474 | | - (void) &intvl; | 475 | | - (void) &cnt; | 476 | | - | | 468 | +int uv__tcp_keepalive(int fd, | | 469 | + int on, | | 470 | + unsigned int idle, | | 471 | + unsigned int intvl, | | 472 | + unsigned int cnt) { | 477 | 473 | if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on))) | 478 | 474 | return UV__ERR(errno); | 479 | 475 |
| 480 | 476 | if (!on) | 481 | 477 | return 0; | 482 | 478 |
| 483 | | - if (delay < 1) | | 479 | + if (idle < 1 || intvl < 1 || cnt < 1) | 484 | 480 | return UV_EINVAL; | 485 | 481 |
| 486 | 482 | #ifdef __sun | @@ -506,13 +502,16 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) { | 506 | 502 | * The TCP connection will be aborted after certain amount of probes, which is set by TCP_KEEPCNT, without receiving response. | 507 | 503 | */ | 508 | 504 |
| 509 | | - idle = delay; | 510 | | - /* Kernel expects at least 10 seconds. */ | | 505 | + /* Kernel expects at least 10 seconds for TCP_KEEPIDLE and TCP_KEEPINTVL. */ | 511 | 506 | if (idle < 10) | 512 | 507 | idle = 10; | 513 | | - /* Kernel expects at most 10 days. */ | | 508 | + if (intvl < 10) | | 509 | + intvl = 10; | | 510 | + /* Kernel expects at most 10 days for TCP_KEEPIDLE and TCP_KEEPINTVL. */ | 514 | 511 | if (idle > 10*24*60*60) | 515 | 512 | idle = 10*24*60*60; | | 513 | + if (intvl > 10*24*60*60) | | 514 | + intvl = 10*24*60*60; | 516 | 515 |
| 517 | 516 | UV_KEEPALIVE_FACTOR(idle); | 518 | 517 |
| @@ -522,12 +521,10 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) { | 522 | 521 | if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle))) | 523 | 522 | return UV__ERR(errno); | 524 | 523 |
| 525 | | - intvl = 10; /* required at least 10 seconds */ | 526 | 524 | UV_KEEPALIVE_FACTOR(intvl); | 527 | 525 | if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl))) | 528 | 526 | return UV__ERR(errno); | 529 | 527 |
| 530 | | - cnt = 1; /* 1 retry, ensure (TCP_KEEPINTVL * TCP_KEEPCNT) is 10 seconds */ | 531 | 528 | if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt))) | 532 | 529 | return UV__ERR(errno); | 533 | 530 | #else | @@ -539,15 +536,14 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) { | 539 | 536 |
| 540 | 537 | /* Note that the consequent probes will not be sent at equal intervals on Solaris, | 541 | 538 | * but will be sent using the exponential backoff algorithm. */ | 542 | | - int time_to_abort = 10; /* 10 seconds */ | | 539 | + unsigned int time_to_abort = intvl * cnt; | 543 | 540 | UV_KEEPALIVE_FACTOR(time_to_abort); | 544 | 541 | if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE_ABORT_THRESHOLD, &time_to_abort, sizeof(time_to_abort))) | 545 | 542 | return UV__ERR(errno); | 546 | 543 | #endif | 547 | 544 |
| 548 | 545 | #else /* !defined(__sun) */ | 549 | 546 |
| 550 | | - idle = delay; | 551 | 547 | UV_KEEPALIVE_FACTOR(idle); | 552 | 548 | #ifdef TCP_KEEPIDLE | 553 | 549 | if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle))) | @@ -559,14 +555,12 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) { | 559 | 555 | #endif | 560 | 556 |
| 561 | 557 | #ifdef TCP_KEEPINTVL | 562 | | - intvl = 1; /* 1 second; same as default on Win32 */ | 563 | 558 | UV_KEEPALIVE_FACTOR(intvl); | 564 | 559 | if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl))) | 565 | 560 | return UV__ERR(errno); | 566 | 561 | #endif | 567 | 562 |
| 568 | 563 | #ifdef TCP_KEEPCNT | 569 | | - cnt = 10; /* 10 retries; same as hardcoded on Win32 */ | 570 | 564 | if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt))) | 571 | 565 | return UV__ERR(errno); | 572 | 566 | #endif | @@ -594,11 +588,20 @@ int uv_tcp_nodelay(uv_tcp_t* handle, int on) { | 594 | 588 | } | 595 | 589 |
| 596 | 590 |
| 597 | | -int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) { | | 591 | +int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int idle) { | | 592 | + return uv_tcp_keepalive_ex(handle, on, idle, 1, 10); | | 593 | +} | | 594 | + | | 595 | + | | 596 | +int uv_tcp_keepalive_ex(uv_tcp_t* handle, | | 597 | + int on, | | 598 | + unsigned int idle, | | 599 | + unsigned int intvl, | | 600 | + unsigned int cnt) { | 598 | 601 | int err; | 599 | 602 |
| 600 | 603 | if (uv__stream_fd(handle) != -1) { | 601 | | - err =uv__tcp_keepalive(uv__stream_fd(handle), on, delay); | | 604 | + err = uv__tcp_keepalive(uv__stream_fd(handle), on, idle, intvl, cnt); | 602 | 605 | if (err) | 603 | 606 | return err; | 604 | 607 | } | @@ -608,7 +611,7 @@ int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) { | 608 | 611 | else | 609 | 612 | handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE; | 610 | 613 |
| 611 | | - /* TODO Store delay if uv__stream_fd(handle) == -1 but don't want to enlarge | | 614 | + /* TODO Store idle if uv__stream_fd(handle) == -1 but don't want to enlarge | 612 | 615 | * uv_tcp_t with an int that's almost never used... | 613 | 616 | */ | 614 | 617 |
| |
Collapse file Copy file name to clipboardExpand all lines: deps/uv/src/win/tcp.c +95-31Lines changed: 95 additions & 31 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -49,29 +49,99 @@ static int uv__tcp_nodelay(uv_tcp_t* handle, SOCKET socket, int enable) { | 49 | 49 | } | 50 | 50 |
| 51 | 51 |
| 52 | | -static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsigned int delay) { | | 52 | +/* | | 53 | + * Check if Windows version is 10.0.16299 (Windows 10, version 1709) or later. | | 54 | + */ | | 55 | +static int minimal_windows10_version1709(void) { | | 56 | + OSVERSIONINFOW os_info; | | 57 | + if (!pRtlGetVersion) | | 58 | + return 0; | | 59 | + pRtlGetVersion(&os_info); | | 60 | + if (os_info.dwMajorVersion < 10) | | 61 | + return 0; | | 62 | + if (os_info.dwMajorVersion > 10) | | 63 | + return 1; | | 64 | + if (os_info.dwMinorVersion > 0) | | 65 | + return 1; | | 66 | + return os_info.dwBuildNumber >= 16299; | | 67 | +} | | 68 | + | | 69 | + | | 70 | +static int uv__tcp_keepalive(uv_tcp_t* handle, | | 71 | + SOCKET socket, | | 72 | + int on, | | 73 | + unsigned int idle, | | 74 | + unsigned int intvl, | | 75 | + unsigned int cnt) { | 53 | 76 | if (setsockopt(socket, | 54 | 77 | SOL_SOCKET, | 55 | 78 | SO_KEEPALIVE, | 56 | | - (const char*)&enable, | 57 | | - sizeof enable) == -1) { | | 79 | + (const char*)&on, | | 80 | + sizeof on) == -1) { | 58 | 81 | return WSAGetLastError(); | 59 | 82 | } | 60 | 83 |
| 61 | | - if (!enable) | | 84 | + if (!on) | 62 | 85 | return 0; | 63 | 86 |
| 64 | | - if (delay < 1) | | 87 | + if (idle < 1 || intvl < 1 || cnt < 1) | 65 | 88 | return UV_EINVAL; | 66 | 89 |
| 67 | | - if (setsockopt(socket, | 68 | | - IPPROTO_TCP, | 69 | | - TCP_KEEPALIVE, | 70 | | - (const char*)&delay, | 71 | | - sizeof delay) == -1) { | 72 | | - return WSAGetLastError(); | | 90 | + /* Windows 10, version 1709 (build 10.0.16299) and later require second units | | 91 | + * for TCP keepalive options. */ | | 92 | + if (minimal_windows10_version1709()) { | | 93 | + if (setsockopt(socket, | | 94 | + IPPROTO_TCP, | | 95 | + TCP_KEEPIDLE, | | 96 | + (const char*)&idle, | | 97 | + sizeof idle) == -1) { | | 98 | + return WSAGetLastError(); | | 99 | + } | | 100 | + | | 101 | + if (setsockopt(socket, | | 102 | + IPPROTO_TCP, | | 103 | + TCP_KEEPINTVL, | | 104 | + (const char*)&intvl, | | 105 | + sizeof intvl) == -1) { | | 106 | + return WSAGetLastError(); | | 107 | + } | | 108 | + | | 109 | + if (setsockopt(socket, | | 110 | + IPPROTO_TCP, | | 111 | + TCP_KEEPCNT, | | 112 | + (const char*)&cnt, | | 113 | + sizeof cnt) == -1) { | | 114 | + return WSAGetLastError(); | | 115 | + } | | 116 | + | | 117 | + return 0; | 73 | 118 | } | 74 | 119 |
| | 120 | + /* For those versions prior to Windows 10 version 1709, | | 121 | + * we fall back to SIO_KEEPALIVE_VALS that expects millisecond units. | | 122 | + * The SIO_KEEPALIVE_VALS IOCTL is supported on Windows 2000 | | 123 | + * and later versions of the operating system. */ | | 124 | + struct tcp_keepalive keepalive; | | 125 | + keepalive.onoff = on; | | 126 | + keepalive.keepalivetime = idle * 1000; | | 127 | + keepalive.keepaliveinterval = intvl * 1000; | | 128 | + /* On Windows Vista and later, the number of keep-alive probes | | 129 | + * (data retransmissions) is set to 10 and cannot be changed. | | 130 | + * On Windows Server 2003, Windows XP, and Windows 2000, the default setting | | 131 | + * for number of keep-alive probes is 5 and cannot be changed programmatically. | | 132 | + */ | | 133 | + DWORD dummy; | | 134 | + if (WSAIoctl(socket, | | 135 | + SIO_KEEPALIVE_VALS, | | 136 | + (LPVOID) &keepalive, | | 137 | + sizeof keepalive, | | 138 | + NULL, | | 139 | + 0, | | 140 | + &dummy, | | 141 | + NULL, | | 142 | + NULL) == -1) | | 143 | + return WSAGetLastError(); | | 144 | + | 75 | 145 | return 0; | 76 | 146 | } | 77 | 147 |
| @@ -132,7 +202,7 @@ static int uv__tcp_set_socket(uv_loop_t* loop, | 132 | 202 |
| 133 | 203 | /* TODO: Use stored delay. */ | 134 | 204 | if (handle->flags & UV_HANDLE_TCP_KEEPALIVE) { | 135 | | - err = uv__tcp_keepalive(handle, socket, 1, 60); | | 205 | + err = uv__tcp_keepalive(handle, socket, 1, 60, 1, 10); | 136 | 206 | if (err) | 137 | 207 | return err; | 138 | 208 | } | @@ -749,20 +819,6 @@ static int uv__is_loopback(const struct sockaddr_storage* storage) { | 749 | 819 | return 0; | 750 | 820 | } | 751 | 821 |
| 752 | | -// Check if Windows version is 10.0.16299 or later | 753 | | -static int uv__is_fast_loopback_fail_supported(void) { | 754 | | - OSVERSIONINFOW os_info; | 755 | | - if (!pRtlGetVersion) | 756 | | - return 0; | 757 | | - pRtlGetVersion(&os_info); | 758 | | - if (os_info.dwMajorVersion < 10) | 759 | | - return 0; | 760 | | - if (os_info.dwMajorVersion > 10) | 761 | | - return 1; | 762 | | - if (os_info.dwMinorVersion > 0) | 763 | | - return 1; | 764 | | - return os_info.dwBuildNumber >= 16299; | 765 | | -} | 766 | 822 |
| 767 | 823 | static int uv__tcp_try_connect(uv_connect_t* req, | 768 | 824 | uv_tcp_t* handle, | @@ -809,7 +865,7 @@ static int uv__tcp_try_connect(uv_connect_t* req, | 809 | 865 | * is not reachable, instead of waiting for 2s. We do not care if this fails. | 810 | 866 | * This only works on Windows version 10.0.16299 and later. | 811 | 867 | */ | 812 | | - if (uv__is_fast_loopback_fail_supported() && uv__is_loopback(&converted)) { | | 868 | + if (minimal_windows10_version1709() && uv__is_loopback(&converted)) { | 813 | 869 | memset(&retransmit_ioctl, 0, sizeof(retransmit_ioctl)); | 814 | 870 | retransmit_ioctl.Rtt = TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS; | 815 | 871 | retransmit_ioctl.MaxSynRetransmissions = TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS; | @@ -1335,22 +1391,30 @@ int uv_tcp_nodelay(uv_tcp_t* handle, int enable) { | 1335 | 1391 | } | 1336 | 1392 |
| 1337 | 1393 |
| 1338 | | -int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) { | | 1394 | +int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int idle) { | | 1395 | + return uv_tcp_keepalive_ex(handle, on, idle, 1, 10); | | 1396 | +} | | 1397 | + | | 1398 | +int uv_tcp_keepalive_ex(uv_tcp_t* handle, | | 1399 | + int on, | | 1400 | + unsigned int idle, | | 1401 | + unsigned int intvl, | | 1402 | + unsigned int cnt) { | 1339 | 1403 | int err; | 1340 | 1404 |
| 1341 | 1405 | if (handle->socket != INVALID_SOCKET) { | 1342 | | - err = uv__tcp_keepalive(handle, handle->socket, enable, delay); | | 1406 | + err = uv__tcp_keepalive(handle, handle->socket, on, idle, intvl, cnt); | 1343 | 1407 | if (err) | 1344 | 1408 | return uv_translate_sys_error(err); | 1345 | 1409 | } | 1346 | 1410 |
| 1347 | | - if (enable) { | | 1411 | + if (on) { | 1348 | 1412 | handle->flags |= UV_HANDLE_TCP_KEEPALIVE; | 1349 | 1413 | } else { | 1350 | 1414 | handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE; | 1351 | 1415 | } | 1352 | 1416 |
| 1353 | | - /* TODO: Store delay if handle->socket isn't created yet. */ | | 1417 | + /* TODO: Store idle if handle->socket isn't created yet. */ | 1354 | 1418 |
| 1355 | 1419 | return 0; | 1356 | 1420 | } | |
|