Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/java.base/share/native/libnet/net_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
/* check if SO_REUSEPORT is supported on this platform */
REUSEPORT_available = reuseport_supported(IPv6_available);


return JNI_VERSION_1_2;
}

Expand Down
34 changes: 22 additions & 12 deletions src/java.base/unix/native/libnet/Inet4AddressImpl.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_INET;

error = getaddrinfo(hostname, NULL, &hints, &res);
NET_RESTARTABLE(error, getaddrinfo(hostname, NULL, &hints, &res),
error == EAI_SYSTEM && errno == EINTR);

if (error) {
#if defined(MACOSX)
Expand Down Expand Up @@ -229,17 +230,21 @@ Java_java_net_Inet4AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
sa.sin_addr.s_addr = htonl(addr);
sa.sin_family = AF_INET;

if (getnameinfo((struct sockaddr *)&sa, sizeof(struct sockaddr_in),
host, sizeof(host), NULL, 0, NI_NAMEREQD)) {
JNU_ThrowByName(env, "java/net/UnknownHostException", NULL);
} else {
int r;

NET_RESTARTABLE(r, getnameinfo((struct sockaddr *)&sa, sizeof(struct sockaddr_in),
host, sizeof(host), NULL, 0, NI_NAMEREQD),
r == EAI_SYSTEM && errno == EINTR);

if (r == 0) {
ret = (*env)->NewStringUTF(env, host);
if (ret == NULL) {
JNU_ThrowByName(env, "java/net/UnknownHostException", NULL);
if (ret != NULL) {
return ret;
}
}

return ret;
JNU_ThrowByName(env, "java/net/UnknownHostException", NULL);
return NULL;
}

/**
Expand Down Expand Up @@ -283,7 +288,8 @@ tcp_ping4(JNIEnv *env, SOCKETADDRESS *sa, SOCKETADDRESS *netif, jint timeout,
SET_NONBLOCKING(fd);

sa->sa4.sin_port = htons(7); // echo port
connect_rv = connect(fd, &sa->sa, sizeof(struct sockaddr_in));
NET_RESTARTABLE(connect_rv, connect(fd, &sa->sa, sizeof(struct sockaddr_in)),
connect_rv == -1 && errno == EINTR);

// connection established or refused immediately, either way it means
// we were able to reach the host!
Expand Down Expand Up @@ -397,8 +403,11 @@ ping4(JNIEnv *env, jint fd, SOCKETADDRESS *sa, SOCKETADDRESS *netif,
icmp->icmp_cksum = 0;
// manually calculate checksum
icmp->icmp_cksum = in_cksum((u_short *)icmp, plen);

// send it
n = sendto(fd, sendbuf, plen, 0, &sa->sa, sizeof(struct sockaddr_in));
NET_RESTARTABLE(n, sendto(fd, sendbuf, plen, 0, &sa->sa, sizeof(struct sockaddr_in)),
n == -1 && errno == EINTR)

if (n < 0 && errno != EINPROGRESS) {
#if defined(__linux__)
/*
Expand All @@ -422,8 +431,9 @@ ping4(JNIEnv *env, jint fd, SOCKETADDRESS *sa, SOCKETADDRESS *netif,
tmout2 = NET_Wait(env, fd, NET_WAIT_READ, tmout2);
if (tmout2 >= 0) {
len = sizeof(sa_recv);
n = recvfrom(fd, recvbuf, sizeof(recvbuf), 0,
(struct sockaddr *)&sa_recv, &len);
NET_RESTARTABLE(n, recvfrom(fd, recvbuf, sizeof(recvbuf), 0,
(struct sockaddr *)&sa_recv, &len),
n == -1 && errno == EINTR);
// check if we received enough data
if (n < (jint)sizeof(struct ip)) {
continue;
Expand Down
32 changes: 21 additions & 11 deletions src/java.base/unix/native/libnet/Inet6AddressImpl.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
hints.ai_flags = AI_CANONNAME;
hints.ai_family = lookupCharacteristicsToAddressFamily(characteristics);

error = getaddrinfo(hostname, NULL, &hints, &res);
NET_RESTARTABLE(error, getaddrinfo(hostname, NULL, &hints, &res),
error == EAI_SYSTEM && errno == EINTR);

if (error) {
#if defined(MACOSX)
Expand Down Expand Up @@ -430,16 +431,20 @@ Java_java_net_Inet6AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
len = sizeof(struct sockaddr_in6);
}

if (getnameinfo(&sa.sa, len, host, sizeof(host), NULL, 0, NI_NAMEREQD)) {
JNU_ThrowByName(env, "java/net/UnknownHostException", NULL);
} else {
int r;

NET_RESTARTABLE(r, getnameinfo(&sa.sa, len, host, sizeof(host), NULL, 0, NI_NAMEREQD),
r == EAI_SYSTEM && errno == EINTR);

if (r == 0) {
ret = (*env)->NewStringUTF(env, host);
if (ret == NULL) {
JNU_ThrowByName(env, "java/net/UnknownHostException", NULL);
if (ret != NULL) {
return ret;
}
}

return ret;
JNU_ThrowByName(env, "java/net/UnknownHostException", NULL);
return NULL;
}

/**
Expand Down Expand Up @@ -483,7 +488,8 @@ tcp_ping6(JNIEnv *env, SOCKETADDRESS *sa, SOCKETADDRESS *netif, jint timeout,
SET_NONBLOCKING(fd);

sa->sa6.sin6_port = htons(7); // echo port
connect_rv = connect(fd, &sa->sa, sizeof(struct sockaddr_in6));
NET_RESTARTABLE(connect_rv, connect(fd, &sa->sa, sizeof(struct sockaddr_in6)),
connect_rv == -1 && errno == EINTR);

// connection established or refused immediately, either way it means
// we were able to reach the host!
Expand Down Expand Up @@ -604,7 +610,10 @@ ping6(JNIEnv *env, jint fd, SOCKETADDRESS *sa, SOCKETADDRESS *netif,
memcpy(sendbuf + sizeof(struct icmp6_hdr), &tv, sizeof(tv));
icmp6->icmp6_cksum = 0;
// send it
n = sendto(fd, sendbuf, plen, 0, &sa->sa, sizeof(struct sockaddr_in6));

NET_RESTARTABLE(n, sendto(fd, sendbuf, plen, 0, &sa->sa, sizeof(struct sockaddr_in6)),
n == -1 && errno == EINTR);

if (n < 0 && errno != EINPROGRESS) {
#if defined(__linux__)
/*
Expand All @@ -628,8 +637,9 @@ ping6(JNIEnv *env, jint fd, SOCKETADDRESS *sa, SOCKETADDRESS *netif,
tmout2 = NET_Wait(env, fd, NET_WAIT_READ, tmout2);
if (tmout2 >= 0) {
len = sizeof(sa_recv);
n = recvfrom(fd, recvbuf, sizeof(recvbuf), 0,
(struct sockaddr *)&sa_recv, &len);
NET_RESTARTABLE(n, recvfrom(fd, recvbuf, sizeof(recvbuf), 0,
(struct sockaddr *)&sa_recv, &len),
n == -1 && errno == EINTR);
// check if we received enough data
if (n < (jint)sizeof(struct icmp6_hdr)) {
continue;
Expand Down
15 changes: 6 additions & 9 deletions src/java.base/unix/native/libnet/net_util_md.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,6 @@ NET_ThrowNew(JNIEnv *env, int errorNumber, char *msg) {
jio_snprintf(fullMsg, sizeof(fullMsg), "socket closed: %s", msg);
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", fullMsg);
break;
case EINTR:
JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException", msg);
break;
default:
errno = errorNumber;
JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", msg);
Expand Down Expand Up @@ -627,25 +624,25 @@ NET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout)
pfd.fd = fd;
pfd.events = 0;
if (flags & NET_WAIT_READ)
pfd.events |= POLLIN;
pfd.events |= POLLIN;
if (flags & NET_WAIT_WRITE)
pfd.events |= POLLOUT;
pfd.events |= POLLOUT;
if (flags & NET_WAIT_CONNECT)
pfd.events |= POLLOUT;
pfd.events |= POLLOUT;

errno = 0;
read_rv = poll(&pfd, 1, nanoTimeout / NET_NSEC_PER_MSEC);

newNanoTime = JVM_NanoTime(env, 0);
nanoTimeout -= (newNanoTime - prevNanoTime);
if (nanoTimeout < NET_NSEC_PER_MSEC) {
return read_rv > 0 ? 0 : -1;
return read_rv > 0 ? 0 : -1;
}
prevNanoTime = newNanoTime;

if (read_rv > 0) {
break;
break;
}
} /* while */
} /* while */
return (nanoTimeout / NET_NSEC_PER_MSEC);
}
13 changes: 13 additions & 0 deletions src/java.base/unix/native/libnet/net_util_md.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,17 @@ void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
void NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
const char *defaultDetail);

/**
* Invokes CALL in a loop, setting RET to return value.
* Invokes PREDICATE for condition to restart CALL (in loop)
* Return RET otherwise
*/
#define NET_RESTARTABLE(RET,CALL,PREDICATE) \
while (1) { \
RET = CALL; \
if (!(PREDICATE)) { \
break; \
} \
}

#endif /* NET_UTILS_MD_H */