Signed-off-by: Juan José Arboleda <soyjuanarbol@gmail.com>
This commit is contained in:
Juan José Arboleda 2026-01-27 20:17:59 -05:00
parent 09499f580c
commit 40a308e2b8
2 changed files with 117 additions and 234 deletions

View File

@ -1074,20 +1074,24 @@ int uv_socket_get_tos(const uv_handle_t* handle, int* tos) {
struct sockaddr_storage storage; struct sockaddr_storage storage;
addrlen = sizeof(storage); addrlen = sizeof(storage);
tos_ = 0; tos_ = 0;
optlen = sizeof(tos_); optlen = sizeof(tos_);
switch (handle->type) { switch (handle->type) {
case UV_TCP: case UV_TCP:
r = uv_tcp_getsockname((uv_tcp_t*)handle, (struct sockaddr*)&storage, &addrlen); r = uv_tcp_getsockname((uv_tcp_t*)handle,
(struct sockaddr*)&storage,
&addrlen);
break; break;
case UV_UDP: case UV_UDP:
r = uv_udp_getsockname((uv_udp_t*)handle, (struct sockaddr*)&storage, &addrlen); r = uv_udp_getsockname((uv_udp_t*)handle,
(struct sockaddr*)&storage,
&addrlen);
break; break;
default: default:
return UV_EINVAL; return UV_EINVAL;
} }
if (r) if (r)
return r; return r;
@ -1107,7 +1111,7 @@ int uv_socket_get_tos(const uv_handle_t* handle, int* tos) {
default: default:
return UV_EAFNOSUPPORT; return UV_EAFNOSUPPORT;
} }
r = getsockopt(fd, level, option, &tos_, &optlen); r = getsockopt(fd, level, option, &tos_, &optlen);
if (r) if (r)
return r; return r;
@ -1143,6 +1147,7 @@ int uv_socket_set_tos(const uv_handle_t* handle, int tos) {
if (r) if (r)
return r; return r;
r = uv_fileno(handle, &fd); r = uv_fileno(handle, &fd);
if (r) if (r)
return r; return r;

View File

@ -19,307 +19,185 @@
* IN THE SOFTWARE. * IN THE SOFTWARE.
*/ */
#include "uv.h"
#include "task.h" #include "task.h"
#include "uv.h"
#include <stdio.h> static void setup_tcp(uv_loop_t* loop, uv_tcp_t* tcp, const char* ip,
#include <stdlib.h> int is_ip6) {
#include <string.h> struct sockaddr_in addr4;
struct sockaddr_in6 addr6;
int r;
r = uv_tcp_init(loop, tcp);
ASSERT_OK(r);
if (is_ip6) {
r = uv_ip6_addr(ip, TEST_PORT, &addr6);
ASSERT_OK(r);
r = uv_tcp_bind(tcp, (const struct sockaddr*)&addr6, 0);
} else {
r = uv_ip4_addr(ip, TEST_PORT, &addr4);
ASSERT_OK(r);
r = uv_tcp_bind(tcp, (const struct sockaddr*)&addr4, 0);
}
ASSERT_OK(r);
}
static void setup_udp(uv_loop_t* loop, uv_udp_t* udp, const char* ip,
int is_ip6) {
struct sockaddr_in addr4;
struct sockaddr_in6 addr6;
int r;
r = uv_udp_init(loop, udp);
ASSERT_OK(r);
if (is_ip6) {
r = uv_ip6_addr(ip, TEST_PORT, &addr6);
ASSERT_OK(r);
r = uv_udp_bind(udp, (const struct sockaddr*)&addr6, 0);
} else {
r = uv_ip4_addr(ip, TEST_PORT, &addr4);
ASSERT_OK(r);
r = uv_udp_bind(udp, (const struct sockaddr*)&addr4, 0);
}
ASSERT_OK(r);
}
static void check_tos(uv_handle_t* handle, int tos) {
int r;
int tos_out;
r = uv_socket_set_tos(handle, tos);
ASSERT_OK(r);
r = uv_socket_get_tos(handle, &tos_out);
ASSERT_OK(r);
/* Linux masks the TOS value. Sometimes (?) */
#if defined(__linux__)
ASSERT((tos_out == tos) || tos_out == (tos & 0xFC));
#else
ASSERT_EQ(tos_out, tos);
#endif
}
static void check_tos_fail(uv_handle_t* handle, int tos) {
ASSERT_EQ(uv_socket_set_tos(handle, tos), UV_EINVAL);
}
TEST_IMPL(tcp_socket_set_get_tos) { TEST_IMPL(tcp_socket_set_get_tos) {
uv_loop_t* loop;
uv_tcp_t tcp; uv_tcp_t tcp;
struct sockaddr_in addr;
int r;
int tos_in;
int tos_out;
loop = uv_default_loop(); setup_tcp(uv_default_loop(), &tcp, "0.0.0.0", 0);
r = uv_tcp_init(loop, &tcp); check_tos((uv_handle_t*)&tcp, 0);
ASSERT_OK(r); check_tos((uv_handle_t*)&tcp, 128);
check_tos((uv_handle_t*)&tcp, 255);
r = uv_ip4_addr("0.0.0.0", TEST_PORT, &addr); check_tos_fail((uv_handle_t*)&tcp, -1);
ASSERT_OK(r); check_tos_fail((uv_handle_t*)&tcp, 256);
check_tos_fail((uv_handle_t*)&tcp, 1000);
r = uv_tcp_bind(&tcp, (const struct sockaddr*) &addr, 0); uv_close((uv_handle_t*)&tcp, NULL);
ASSERT_OK(r); ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
/* Test valid TOS values */ MAKE_VALGRIND_HAPPY(uv_default_loop());
tos_in = 0;
r = uv_socket_set_tos((uv_handle_t*) &tcp, tos_in);
ASSERT_OK(r);
r = uv_socket_get_tos((uv_handle_t*) &tcp, &tos_out);
ASSERT_OK(r);
ASSERT_EQ(tos_out, tos_in);
tos_in = 128;
r = uv_socket_set_tos((uv_handle_t*) &tcp, tos_in);
ASSERT_OK(r);
r = uv_socket_get_tos((uv_handle_t*) &tcp, &tos_out);
ASSERT_OK(r);
ASSERT_EQ(tos_out, tos_in);
tos_in = 255;
r = uv_socket_set_tos((uv_handle_t*) &tcp, tos_in);
ASSERT_OK(r);
r = uv_socket_get_tos((uv_handle_t*) &tcp, &tos_out);
ASSERT_OK(r);
ASSERT_EQ(tos_out, tos_in);
/* Test invalid TOS values */
r = uv_socket_set_tos((uv_handle_t*) &tcp, -1);
ASSERT_EQ(r, UV_EINVAL);
r = uv_socket_set_tos((uv_handle_t*) &tcp, 256);
ASSERT_EQ(r, UV_EINVAL);
r = uv_socket_set_tos((uv_handle_t*) &tcp, 1000);
ASSERT_EQ(r, UV_EINVAL);
uv_close((uv_handle_t*) &tcp, NULL);
r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT_OK(r);
MAKE_VALGRIND_HAPPY(loop);
return 0; return 0;
} }
TEST_IMPL(tcp6_socket_set_get_tos) { TEST_IMPL(tcp6_socket_set_get_tos) {
uv_loop_t* loop;
uv_tcp_t tcp; uv_tcp_t tcp;
struct sockaddr_in6 addr;
int r;
int tos_in;
int tos_out;
loop = uv_default_loop(); setup_tcp(uv_default_loop(), &tcp, "::1", 1);
r = uv_tcp_init(loop, &tcp); check_tos((uv_handle_t*)&tcp, 0);
ASSERT_OK(r); check_tos((uv_handle_t*)&tcp, 64);
check_tos((uv_handle_t*)&tcp, 255);
r = uv_ip6_addr("::1", TEST_PORT, &addr); uv_close((uv_handle_t *)&tcp, NULL);
ASSERT_OK(r); ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
r = uv_tcp_bind(&tcp, (const struct sockaddr*) &addr, 0); MAKE_VALGRIND_HAPPY(uv_default_loop());
ASSERT_OK(r);
/* Test valid TOS values */
tos_in = 0;
r = uv_socket_set_tos((uv_handle_t*) &tcp, tos_in);
ASSERT_OK(r);
r = uv_socket_get_tos((uv_handle_t*) &tcp, &tos_out);
ASSERT_OK(r);
ASSERT_EQ(tos_out, tos_in);
tos_in = 64;
r = uv_socket_set_tos((uv_handle_t*) &tcp, tos_in);
ASSERT_OK(r);
r = uv_socket_get_tos((uv_handle_t*) &tcp, &tos_out);
ASSERT_OK(r);
ASSERT_EQ(tos_out, tos_in);
tos_in = 255;
r = uv_socket_set_tos((uv_handle_t*) &tcp, tos_in);
ASSERT_OK(r);
r = uv_socket_get_tos((uv_handle_t*) &tcp, &tos_out);
ASSERT_OK(r);
ASSERT_EQ(tos_out, tos_in);
uv_close((uv_handle_t*) &tcp, NULL);
r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT_OK(r);
MAKE_VALGRIND_HAPPY(loop);
return 0; return 0;
} }
TEST_IMPL(udp_socket_set_get_tos) { TEST_IMPL(udp_socket_set_get_tos) {
uv_loop_t* loop;
uv_udp_t udp; uv_udp_t udp;
struct sockaddr_in addr;
int r;
int tos_in;
int tos_out;
loop = uv_default_loop(); setup_udp(uv_default_loop(), &udp, "0.0.0.0", 0);
r = uv_udp_init(loop, &udp); check_tos((uv_handle_t*)&udp, 0);
ASSERT_OK(r); check_tos((uv_handle_t*)&udp, 32);
check_tos((uv_handle_t*)&udp, 255);
r = uv_ip4_addr("0.0.0.0", TEST_PORT, &addr); check_tos_fail((uv_handle_t *)&udp, -1);
ASSERT_OK(r); check_tos_fail((uv_handle_t *)&udp, 256);
r = uv_udp_bind(&udp, (const struct sockaddr*) &addr, 0); uv_close((uv_handle_t *)&udp, NULL);
ASSERT_OK(r); ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
/* Test valid TOS values */ MAKE_VALGRIND_HAPPY(uv_default_loop());
tos_in = 0;
r = uv_socket_set_tos((uv_handle_t*) &udp, tos_in);
ASSERT_OK(r);
r = uv_socket_get_tos((uv_handle_t*) &udp, &tos_out);
ASSERT_OK(r);
ASSERT_EQ(tos_out, tos_in);
tos_in = 32;
r = uv_socket_set_tos((uv_handle_t*) &udp, tos_in);
ASSERT_OK(r);
r = uv_socket_get_tos((uv_handle_t*) &udp, &tos_out);
ASSERT_OK(r);
ASSERT_EQ(tos_out, tos_in);
tos_in = 255;
r = uv_socket_set_tos((uv_handle_t*) &udp, tos_in);
ASSERT_OK(r);
r = uv_socket_get_tos((uv_handle_t*) &udp, &tos_out);
ASSERT_OK(r);
ASSERT_EQ(tos_out, tos_in);
/* Test invalid TOS values */
r = uv_socket_set_tos((uv_handle_t*) &udp, -1);
ASSERT_EQ(r, UV_EINVAL);
r = uv_socket_set_tos((uv_handle_t*) &udp, 256);
ASSERT_EQ(r, UV_EINVAL);
uv_close((uv_handle_t*) &udp, NULL);
r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT_OK(r);
MAKE_VALGRIND_HAPPY(loop);
return 0; return 0;
} }
TEST_IMPL(udp6_socket_set_get_tos) { TEST_IMPL(udp6_socket_set_get_tos) {
uv_loop_t* loop;
uv_udp_t udp; uv_udp_t udp;
struct sockaddr_in6 addr;
int r;
int tos_in;
int tos_out;
loop = uv_default_loop(); setup_udp(uv_default_loop(), &udp, "::1", 1);
r = uv_udp_init(loop, &udp); check_tos((uv_handle_t*)&udp, 0);
ASSERT_OK(r); check_tos((uv_handle_t*)&udp, 96);
check_tos((uv_handle_t*)&udp, 255);
r = uv_ip6_addr("::1", TEST_PORT, &addr); uv_close((uv_handle_t*)&udp, NULL);
ASSERT_OK(r); ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
r = uv_udp_bind(&udp, (const struct sockaddr*) &addr, 0); MAKE_VALGRIND_HAPPY(uv_default_loop());
ASSERT_OK(r);
/* Test valid TOS values */
tos_in = 0;
r = uv_socket_set_tos((uv_handle_t*) &udp, tos_in);
ASSERT_OK(r);
r = uv_socket_get_tos((uv_handle_t*) &udp, &tos_out);
ASSERT_OK(r);
ASSERT_EQ(tos_out, tos_in);
tos_in = 96;
r = uv_socket_set_tos((uv_handle_t*) &udp, tos_in);
ASSERT_OK(r);
r = uv_socket_get_tos((uv_handle_t*) &udp, &tos_out);
ASSERT_OK(r);
ASSERT_EQ(tos_out, tos_in);
tos_in = 255;
r = uv_socket_set_tos((uv_handle_t*) &udp, tos_in);
ASSERT_OK(r);
r = uv_socket_get_tos((uv_handle_t*) &udp, &tos_out);
ASSERT_OK(r);
ASSERT_EQ(tos_out, tos_in);
uv_close((uv_handle_t*) &udp, NULL);
r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT_OK(r);
MAKE_VALGRIND_HAPPY(loop);
return 0; return 0;
} }
TEST_IMPL(socket_tos_invalid_handle) { TEST_IMPL(socket_tos_invalid_handle) {
uv_loop_t* loop;
uv_timer_t timer; uv_timer_t timer;
uv_pipe_t pipe;
int r; int r;
int tos; int tos;
loop = uv_default_loop();
/* Test with invalid handle types */ /* Test with invalid handle types */
r = uv_timer_init(loop, &timer); r = uv_timer_init(uv_default_loop(), &timer);
ASSERT_OK(r); ASSERT_OK(r);
r = uv_socket_set_tos((uv_handle_t*) &timer, 64); r = uv_socket_set_tos((uv_handle_t*)&timer, 64);
ASSERT_EQ(r, UV_EINVAL); ASSERT_EQ(r, UV_EINVAL);
r = uv_socket_get_tos((uv_handle_t*) &timer, &tos); r = uv_socket_get_tos((uv_handle_t*)&timer, &tos);
ASSERT_EQ(r, UV_EINVAL); ASSERT_EQ(r, UV_EINVAL);
uv_close((uv_handle_t*) &timer, NULL); uv_close((uv_handle_t*)&timer, NULL);
/* Test with pipe handle */ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
r = uv_pipe_init(loop, &pipe, 0);
ASSERT_OK(r); ASSERT_OK(r);
r = uv_socket_set_tos((uv_handle_t*) &pipe, 64); MAKE_VALGRIND_HAPPY(uv_default_loop());
ASSERT_EQ(r, UV_EINVAL);
r = uv_socket_get_tos((uv_handle_t*) &pipe, &tos);
ASSERT_EQ(r, UV_EINVAL);
uv_close((uv_handle_t*) &pipe, NULL);
r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT_OK(r);
MAKE_VALGRIND_HAPPY(loop);
return 0; return 0;
} }
TEST_IMPL(socket_tos_unbound_tcp) { TEST_IMPL(socket_tos_unbound_tcp) {
uv_loop_t* loop;
uv_tcp_t tcp; uv_tcp_t tcp;
int r; int r;
int tos; int tos;
loop = uv_default_loop(); r = uv_tcp_init(uv_default_loop(), &tcp);
/* Test with unbound TCP socket - should fail since no address family */
r = uv_tcp_init(loop, &tcp);
ASSERT_OK(r); ASSERT_OK(r);
/* Getting/setting TOS on unbound socket should fail */ r = uv_socket_set_tos((uv_handle_t*)&tcp, 64);
r = uv_socket_set_tos((uv_handle_t*) &tcp, 64);
ASSERT_NE(r, 0); ASSERT_NE(r, 0);
r = uv_socket_get_tos((uv_handle_t*) &tcp, &tos); r = uv_socket_get_tos((uv_handle_t*)&tcp, &tos);
ASSERT_NE(r, 0); ASSERT_NE(r, 0);
uv_close((uv_handle_t*) &tcp, NULL); uv_close((uv_handle_t*)&tcp, NULL);
r = uv_run(loop, UV_RUN_DEFAULT); r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT_OK(r); ASSERT_OK(r);
MAKE_VALGRIND_HAPPY(loop); MAKE_VALGRIND_HAPPY(uv_default_loop());
return 0; return 0;
} }