1
0
mirror of https://github.com/libuv/libuv synced 2025-03-28 21:13:16 +00:00

Merge 0c19b0a52eeb72219994e76c710ea28205d882a2 into 612a8262b840a1d104afcd9c45b2b88cde6b9e6d

This commit is contained in:
theanarkh 2025-03-02 09:34:08 +08:00 committed by GitHub
commit 4d905de5e1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 177 additions and 2 deletions

View File

@ -651,6 +651,12 @@ UV_EXTERN int uv_tcp_nodelay(uv_tcp_t* handle, int enable);
UV_EXTERN int uv_tcp_keepalive(uv_tcp_t* handle,
int enable,
unsigned int delay);
UV_EXTERN int uv_tcp_keepalive_ex(uv_tcp_t* handle,
int enable,
unsigned int delay,
unsigned int interval,
unsigned int count);
UV_EXTERN int uv_tcp_timeout(uv_tcp_t* handle, unsigned int timeout);
UV_EXTERN int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable);
enum uv_tcp_flags {

View File

@ -291,6 +291,12 @@ int uv__slurp(const char* filename, char* buf, size_t len);
int uv__tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb);
int uv__tcp_nodelay(int fd, int on);
int uv__tcp_keepalive(int fd, int on, unsigned int delay);
int uv__tcp_keepalive_ex(int fd,
int on,
unsigned int delay,
unsigned int interval,
unsigned int count);
int uv_tcp_timeout(uv_tcp_t* handle, unsigned int timeout);
/* tty */
void uv__tty_close(uv_tty_t* handle);

View File

@ -616,6 +616,90 @@ int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) {
return 0;
}
int uv_tcp_keepalive_ex(uv_tcp_t* handle,
int on,
unsigned int delay,
unsigned int interval,
unsigned int count) {
int err;
if (uv__stream_fd(handle) != -1) {
err =uv__tcp_keepalive_ex(uv__stream_fd(handle),
on,
delay,
interval,
count);
if (err)
return err;
}
/*
follow the uv_tcp_keepalive api
TO DO: save params on handle and set when handle is attached to a fd
*/
if (on)
handle->flags |= UV_HANDLE_TCP_KEEPALIVE;
else
handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE;
return 0;
}
int uv_tcp_timeout(uv_tcp_t* handle, unsigned int timeout) {
#ifdef TCP_USER_TIMEOUT
int fd = uv__stream_fd(handle);
if (fd != -1 && setsockopt(fd,
IPPROTO_TCP,
TCP_USER_TIMEOUT,
&timeout,
sizeof(timeout))) {
return UV__ERR(errno);
}
#endif
return 0;
}
int uv__tcp_keepalive_ex(int fd,
int on,
unsigned int delay,
unsigned int interval,
unsigned int count) {
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)))
return UV__ERR(errno);
#ifdef TCP_KEEPIDLE
if (on && delay &&setsockopt(fd,
IPPROTO_TCP,
TCP_KEEPIDLE,
&delay,
sizeof(delay)))
return UV__ERR(errno);
#endif
#ifdef TCP_KEEPINTVL
if (on && interval && setsockopt(fd,
IPPROTO_TCP,
TCP_KEEPINTVL,
&interval,
sizeof(interval)))
return UV__ERR(errno);
#endif
#ifdef TCP_KEEPCNT
if (on && count && setsockopt(fd,
IPPROTO_TCP,
TCP_KEEPCNT,
&count,
sizeof(count)))
return UV__ERR(errno);
#endif
/* Solaris/SmartOS, if you don't support keep-alive,
* then don't advertise it in your system headers...
*/
/* FIXME(bnoordhuis) That's possibly because sizeof(delay) should be 1. */
#if defined(TCP_KEEPALIVE) && !defined(__sun)
if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &delay, sizeof(delay)))
return UV__ERR(errno);
#endif
return 0;
}
int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
return 0;

View File

@ -1301,7 +1301,6 @@ int uv_tcp_nodelay(uv_tcp_t* handle, int enable) {
return 0;
}
int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
int err;
@ -1316,12 +1315,86 @@ int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
} else {
handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE;
}
/* TODO: Store delay if handle->socket isn't created yet. */
return 0;
}
int uv_tcp_keepalive_ex(uv_tcp_t* handle,
int enable,
unsigned int delay,
unsigned int interval,
unsigned int count) {
int err;
if (handle->socket != INVALID_SOCKET) {
err = uv__tcp_keepalive_ex(handle,
handle->socket,
enable,
delay,
interval,
count);
if (err)
return err;
}
if (enable) {
handle->flags |= UV_HANDLE_TCP_KEEPALIVE;
} else {
handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE;
}
return 0;
}
static int uv__tcp_keepalive_ex(uv_tcp_t* handle,
SOCKET socket,
int enable,
unsigned int delay,
unsigned int interval,
unsigned int count) {
if (setsockopt(socket,
SOL_SOCKET,
SO_KEEPALIVE,
(const char*)&enable,
sizeof enable) == -1) {
return WSAGetLastError();
}
#ifdef TCP_KEEPIDLE
if (enable && delay && setsockopt(socket,
IPPROTO_TCP,
TCP_KEEPIDLE,
(const char*)&delay,
sizeof delay) == -1) {
return WSAGetLastError();
}
#endif
#ifdef TCP_KEEPINTVL
if (enable && interval && setsockopt(socket,
IPPROTO_TCP,
TCP_KEEPINTVL,
(const char*)&interval,
sizeof interval) == -1) {
return WSAGetLastError();
}
#endif
#ifdef TCP_KEEPCNT
if (enable && count && setsockopt(socket,
IPPROTO_TCP,
TCP_KEEPCNT,
(const char*)&count,
sizeof count) == -1) {
return WSAGetLastError();
}
#endif
return 0;
}
/* windows don't support this */
int uv_tcp_timeout(uv_tcp_t* handle, unsigned int timeout) {
return 0;
}
int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
if (handle->flags & UV_HANDLE_CONNECTION) {

View File

@ -49,6 +49,12 @@ TEST_IMPL(tcp_flags) {
r = uv_tcp_keepalive(&handle, 1, 0);
ASSERT_EQ(r, UV_EINVAL);
r = uv_tcp_keepalive_ex(&handle, 1, 60, 60, 60);
ASSERT(r == 0);
r = uv_tcp_timeout(&handle, 1000);
ASSERT(r == 0);
uv_close((uv_handle_t*)&handle, NULL);
r = uv_run(loop, UV_RUN_DEFAULT);