@@ -465,22 +465,18 @@ int uv__tcp_nodelay(int fd, int on) {
465465#else
466466#define UV_KEEPALIVE_FACTOR (x )
467467#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 ) {
477473 if (setsockopt (fd , SOL_SOCKET , SO_KEEPALIVE , & on , sizeof (on )))
478474 return UV__ERR (errno );
479475
480476 if (!on )
481477 return 0 ;
482478
483- if (delay < 1 )
479+ if (idle < 1 || intvl < 1 || cnt < 1 )
484480 return UV_EINVAL ;
485481
486482#ifdef __sun
@@ -506,13 +502,16 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
506502 * The TCP connection will be aborted after certain amount of probes, which is set by TCP_KEEPCNT, without receiving response.
507503 */
508504
509- idle = delay ;
510- /* Kernel expects at least 10 seconds. */
505+ /* Kernel expects at least 10 seconds for TCP_KEEPIDLE and TCP_KEEPINTVL. */
511506 if (idle < 10 )
512507 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. */
514511 if (idle > 10 * 24 * 60 * 60 )
515512 idle = 10 * 24 * 60 * 60 ;
513+ if (intvl > 10 * 24 * 60 * 60 )
514+ intvl = 10 * 24 * 60 * 60 ;
516515
517516 UV_KEEPALIVE_FACTOR (idle );
518517
@@ -522,12 +521,10 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
522521 if (setsockopt (fd , IPPROTO_TCP , TCP_KEEPIDLE , & idle , sizeof (idle )))
523522 return UV__ERR (errno );
524523
525- intvl = 10 ; /* required at least 10 seconds */
526524 UV_KEEPALIVE_FACTOR (intvl );
527525 if (setsockopt (fd , IPPROTO_TCP , TCP_KEEPINTVL , & intvl , sizeof (intvl )))
528526 return UV__ERR (errno );
529527
530- cnt = 1 ; /* 1 retry, ensure (TCP_KEEPINTVL * TCP_KEEPCNT) is 10 seconds */
531528 if (setsockopt (fd , IPPROTO_TCP , TCP_KEEPCNT , & cnt , sizeof (cnt )))
532529 return UV__ERR (errno );
533530#else
@@ -539,15 +536,14 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
539536
540537 /* Note that the consequent probes will not be sent at equal intervals on Solaris,
541538 * 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 ;
543540 UV_KEEPALIVE_FACTOR (time_to_abort );
544541 if (setsockopt (fd , IPPROTO_TCP , TCP_KEEPALIVE_ABORT_THRESHOLD , & time_to_abort , sizeof (time_to_abort )))
545542 return UV__ERR (errno );
546543#endif
547544
548545#else /* !defined(__sun) */
549546
550- idle = delay ;
551547 UV_KEEPALIVE_FACTOR (idle );
552548#ifdef TCP_KEEPIDLE
553549 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) {
559555#endif
560556
561557#ifdef TCP_KEEPINTVL
562- intvl = 1 ; /* 1 second; same as default on Win32 */
563558 UV_KEEPALIVE_FACTOR (intvl );
564559 if (setsockopt (fd , IPPROTO_TCP , TCP_KEEPINTVL , & intvl , sizeof (intvl )))
565560 return UV__ERR (errno );
566561#endif
567562
568563#ifdef TCP_KEEPCNT
569- cnt = 10 ; /* 10 retries; same as hardcoded on Win32 */
570564 if (setsockopt (fd , IPPROTO_TCP , TCP_KEEPCNT , & cnt , sizeof (cnt )))
571565 return UV__ERR (errno );
572566#endif
@@ -594,11 +588,20 @@ int uv_tcp_nodelay(uv_tcp_t* handle, int on) {
594588}
595589
596590
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 ) {
598601 int err ;
599602
600603 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 );
602605 if (err )
603606 return err ;
604607 }
@@ -608,7 +611,7 @@ int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) {
608611 else
609612 handle -> flags &= ~UV_HANDLE_TCP_KEEPALIVE ;
610613
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
612615 * uv_tcp_t with an int that's almost never used...
613616 */
614617
0 commit comments