unix: fix udp_options test on OS X and Solaris

setsockopt(IP_TTL) will happily let you set a TTL > 255 on OS X, cap it.

-1 or 0 is a valid TTL on Linux but not portable, deny it.
This commit is contained in:
Ben Noordhuis 2012-04-11 16:24:20 +02:00
parent 3c415975d9
commit 42d3533487
2 changed files with 31 additions and 32 deletions

View File

@ -530,21 +530,6 @@ int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr,
}
#define X(name, level, option) \
int uv_udp_set_##name(uv_udp_t* handle, int flag) { \
if (setsockopt(handle->fd, level, option, &flag, sizeof(flag))) { \
uv__set_sys_error(handle->loop, errno); \
return -1; \
} \
return 0; \
}
X(broadcast, SOL_SOCKET, SO_BROADCAST)
X(ttl, IPPROTO_IP, IP_TTL)
#undef X
static int uv__setsockopt_maybe_char(uv_udp_t* handle, int option, int val) {
#if __sun
char arg = val;
@ -552,17 +537,30 @@ static int uv__setsockopt_maybe_char(uv_udp_t* handle, int option, int val) {
int arg = val;
#endif
#if __sun
if (val < 0 || val > 255) {
uv__set_sys_error(handle->loop, EINVAL);
return -1;
}
#endif
if (val < 0 || val > 255)
return uv__set_sys_error(handle->loop, EINVAL);
if (setsockopt(handle->fd, IPPROTO_IP, option, &arg, sizeof(arg))) {
uv__set_sys_error(handle->loop, errno);
return -1;
}
if (setsockopt(handle->fd, IPPROTO_IP, option, &arg, sizeof(arg)))
return uv__set_sys_error(handle->loop, errno);
return 0;
}
int uv_udp_set_broadcast(uv_udp_t* handle, int on) {
if (setsockopt(handle->fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)))
return uv__set_sys_error(handle->loop, errno);
return 0;
}
int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
if (ttl < 1 || ttl > 255)
return uv__set_sys_error(handle->loop, EINVAL);
if (setsockopt(handle->fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)))
return uv__set_sys_error(handle->loop, errno);
return 0;
}

View File

@ -28,6 +28,7 @@
TEST_IMPL(udp_options) {
static int invalid_ttls[] = { -1, 0, 256 };
uv_loop_t* loop;
uv_udp_t h;
int i, r;
@ -48,17 +49,17 @@ TEST_IMPL(udp_options) {
r |= uv_udp_set_broadcast(&h, 0);
ASSERT(r == 0);
/* values 0-255 should work */
for (i = 0; i <= 255; i++) {
/* values 1-255 should work */
for (i = 1; i <= 255; i++) {
r = uv_udp_set_ttl(&h, i);
ASSERT(r == 0);
}
/* anything >255 should fail */
r = uv_udp_set_ttl(&h, 256);
ASSERT(r == -1);
ASSERT(uv_last_error(loop).code == UV_EINVAL);
/* don't test ttl=-1, it's a valid value on some platforms */
for (i = 0; i < (int) ARRAY_SIZE(invalid_ttls); i++) {
r = uv_udp_set_ttl(&h, invalid_ttls[i]);
ASSERT(r == -1);
ASSERT(uv_last_error(loop).code == UV_EINVAL);
}
r = uv_udp_set_multicast_loop(&h, 1);
r |= uv_udp_set_multicast_loop(&h, 1);