Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
41b349b4
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
41b349b4
编写于
10月 14, 2015
作者:
R
robm
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8133015: InetAddress.isReachable(tmout) returning wrong value on Windows for IPv6
Reviewed-by: michaelm
上级
d3be4c23
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
94 addition
and
487 deletion
+94
-487
src/windows/native/java/net/Inet4AddressImpl.c
src/windows/native/java/net/Inet4AddressImpl.c
+37
-238
src/windows/native/java/net/Inet6AddressImpl.c
src/windows/native/java/net/Inet6AddressImpl.c
+54
-246
test/java/net/Inet4Address/PingThis.java
test/java/net/Inet4Address/PingThis.java
+1
-1
test/java/net/InetAddress/IsHostReachableBug.java
test/java/net/InetAddress/IsHostReachableBug.java
+1
-1
test/java/net/InetAddress/IsReachable.java
test/java/net/InetAddress/IsReachable.java
+1
-1
未找到文件。
src/windows/native/java/net/Inet4AddressImpl.c
浏览文件 @
41b349b4
...
...
@@ -31,6 +31,8 @@
#include <malloc.h>
#include <sys/types.h>
#include <process.h>
#include <iphlpapi.h>
#include <icmpapi.h>
#include "java_net_InetAddress.h"
#include "java_net_Inet4AddressImpl.h"
...
...
@@ -297,114 +299,47 @@ Java_java_net_Inet4AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
* Returns true is an ECHO_REPLY is received, otherwise, false.
*/
static
jboolean
ping4
(
JNIEnv
*
env
,
jint
fd
,
struct
sockaddr_in
*
him
,
jint
timeout
,
struct
sockaddr_in
*
netif
,
jint
ttl
)
{
jint
size
;
jint
n
,
len
,
hlen1
,
icmplen
;
char
sendbuf
[
1500
];
char
recvbuf
[
1500
];
struct
icmp
*
icmp
;
struct
ip
*
ip
;
WSAEVENT
hEvent
;
struct
sockaddr
sa_recv
;
jint
tmout2
;
u_short
pid
,
seq
;
int
read_rv
=
0
;
/* Initialize the sequence number to a suitable random number and
shift right one place to allow sufficient room for increamenting. */
seq
=
((
unsigned
short
)
rand
())
>>
1
;
/* icmp_id is a 16 bit data type, therefore down cast the pid */
pid
=
(
u_short
)
_getpid
();
size
=
60
*
1024
;
setsockopt
(
fd
,
SOL_SOCKET
,
SO_RCVBUF
,
(
const
char
*
)
&
size
,
sizeof
(
size
));
/**
* A TTL was specified, let's set the socket option.
*/
if
(
ttl
>
0
)
{
setsockopt
(
fd
,
IPPROTO_IP
,
IP_TTL
,
(
const
char
*
)
&
ttl
,
sizeof
(
ttl
));
ping4
(
JNIEnv
*
env
,
unsigned
long
ipaddr
,
jint
timeout
)
{
// See https://msdn.microsoft.com/en-us/library/aa366050%28VS.85%29.aspx
HANDLE
hIcmpFile
;
DWORD
dwRetVal
=
0
;
char
SendData
[
32
]
=
{
0
};
LPVOID
ReplyBuffer
=
NULL
;
DWORD
ReplySize
=
0
;
hIcmpFile
=
IcmpCreateFile
();
if
(
hIcmpFile
==
INVALID_HANDLE_VALUE
)
{
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"Unable to open handle"
);
return
JNI_FALSE
;
}
/**
* A network interface was specified, let's bind to it.
*/
if
(
netif
!=
NULL
)
{
if
(
bind
(
fd
,
(
struct
sockaddr
*
)
netif
,
sizeof
(
struct
sockaddr_in
))
<
0
)
{
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"Can't bind socket"
);
closesocket
(
fd
);
ReplySize
=
sizeof
(
ICMP_ECHO_REPLY
)
+
sizeof
(
SendData
);
ReplyBuffer
=
(
VOID
*
)
malloc
(
ReplySize
);
if
(
ReplyBuffer
==
NULL
)
{
IcmpCloseHandle
(
hIcmpFile
);
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"Unable to allocate memory"
);
return
JNI_FALSE
;
}
}
/**
* Let's make the socket non blocking
*/
hEvent
=
WSACreateEvent
();
WSAEventSelect
(
fd
,
hEvent
,
FD_READ
|
FD_CONNECT
|
FD_CLOSE
);
dwRetVal
=
IcmpSendEcho
(
hIcmpFile
,
// HANDLE IcmpHandle,
ipaddr
,
// IPAddr DestinationAddress,
SendData
,
// LPVOID RequestData,
sizeof
(
SendData
),
// WORD RequestSize,
NULL
,
// PIP_OPTION_INFORMATION RequestOptions,
ReplyBuffer
,
// LPVOID ReplyBuffer,
ReplySize
,
// DWORD ReplySize,
timeout
);
// DWORD Timeout
/**
* send 1 ICMP REQUEST every second until either we get a valid reply
* or the timeout expired.
*/
do
{
/**
* construct the ICMP header
*/
memset
(
sendbuf
,
0
,
1500
);
icmp
=
(
struct
icmp
*
)
sendbuf
;
icmp
->
icmp_type
=
ICMP_ECHO
;
icmp
->
icmp_code
=
0
;
icmp
->
icmp_id
=
htons
(
pid
);
icmp
->
icmp_seq
=
htons
(
seq
);
/**
* checksum has to be set to zero before we can calculate the
* real checksum!
*/
icmp
->
icmp_cksum
=
0
;
icmp
->
icmp_cksum
=
in_cksum
((
u_short
*
)
icmp
,
64
);
/**
* Ping!
*/
n
=
sendto
(
fd
,
sendbuf
,
64
,
0
,
(
struct
sockaddr
*
)
him
,
sizeof
(
struct
sockaddr
));
if
(
n
<
0
&&
WSAGetLastError
()
!=
WSAEWOULDBLOCK
)
{
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"Can't send ICMP packet"
);
closesocket
(
fd
);
WSACloseEvent
(
hEvent
);
free
(
ReplyBuffer
);
IcmpCloseHandle
(
hIcmpFile
);
if
(
dwRetVal
!=
0
)
{
return
JNI_TRUE
;
}
else
{
return
JNI_FALSE
;
}
/*
* wait for 1 second at most
*/
tmout2
=
timeout
>
1000
?
1000
:
timeout
;
do
{
tmout2
=
NET_Wait
(
env
,
fd
,
NET_WAIT_READ
,
tmout2
);
if
(
tmout2
>=
0
)
{
len
=
sizeof
(
sa_recv
);
n
=
recvfrom
(
fd
,
recvbuf
,
sizeof
(
recvbuf
),
0
,
&
sa_recv
,
&
len
);
ip
=
(
struct
ip
*
)
recvbuf
;
hlen1
=
(
ip
->
ip_hl
)
<<
2
;
icmp
=
(
struct
icmp
*
)
(
recvbuf
+
hlen1
);
icmplen
=
n
-
hlen1
;
/**
* Is that a proper ICMP reply?
*/
if
(
icmplen
>=
8
&&
icmp
->
icmp_type
==
ICMP_ECHOREPLY
&&
(
ntohs
(
icmp
->
icmp_seq
)
==
seq
)
&&
(
ntohs
(
icmp
->
icmp_id
)
==
pid
))
{
closesocket
(
fd
);
WSACloseEvent
(
hEvent
);
return
JNI_TRUE
;
}
}
}
while
(
tmout2
>
0
);
timeout
-=
1000
;
seq
++
;
}
while
(
timeout
>
0
);
closesocket
(
fd
);
WSACloseEvent
(
hEvent
);
return
JNI_FALSE
;
}
}
/*
...
...
@@ -420,13 +355,7 @@ Java_java_net_Inet4AddressImpl_isReachable0(JNIEnv *env, jobject this,
jint
ttl
)
{
jint
addr
;
jbyte
caddr
[
4
];
jint
fd
;
struct
sockaddr_in
him
;
struct
sockaddr_in
*
netif
=
NULL
;
struct
sockaddr_in
inf
;
int
len
=
0
;
WSAEVENT
hEvent
;
int
connect_rv
=
-
1
;
int
sz
;
/**
...
...
@@ -444,135 +373,5 @@ Java_java_net_Inet4AddressImpl_isReachable0(JNIEnv *env, jobject this,
addr
|=
((
caddr
[
2
]
<<
8
)
&
0xff00
);
addr
|=
(
caddr
[
3
]
&
0xff
);
addr
=
htonl
(
addr
);
/**
* Socket address
*/
him
.
sin_addr
.
s_addr
=
addr
;
him
.
sin_family
=
AF_INET
;
len
=
sizeof
(
him
);
/**
* If a network interface was specified, let's convert its address
* as well.
*/
if
(
!
(
IS_NULL
(
ifArray
)))
{
memset
((
char
*
)
caddr
,
0
,
sizeof
(
caddr
));
(
*
env
)
->
GetByteArrayRegion
(
env
,
ifArray
,
0
,
4
,
caddr
);
addr
=
((
caddr
[
0
]
<<
24
)
&
0xff000000
);
addr
|=
((
caddr
[
1
]
<<
16
)
&
0xff0000
);
addr
|=
((
caddr
[
2
]
<<
8
)
&
0xff00
);
addr
|=
(
caddr
[
3
]
&
0xff
);
addr
=
htonl
(
addr
);
inf
.
sin_addr
.
s_addr
=
addr
;
inf
.
sin_family
=
AF_INET
;
inf
.
sin_port
=
0
;
netif
=
&
inf
;
}
#if 0
/*
* Windows implementation of ICMP & RAW sockets is too unreliable for now.
* Therefore it's best not to try it at all and rely only on TCP
* We may revisit and enable this code in the future.
*/
/*
* Let's try to create a RAW socket to send ICMP packets
* This usually requires "root" privileges, so it's likely to fail.
*/
fd = NET_Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (fd != -1) {
/*
* It didn't fail, so we can use ICMP_ECHO requests.
*/
return ping4(env, fd, &him, timeout, netif, ttl);
}
#endif
/*
* Can't create a raw socket, so let's try a TCP socket
*/
fd
=
NET_Socket
(
AF_INET
,
SOCK_STREAM
,
0
);
if
(
fd
==
JVM_IO_ERR
)
{
/* note: if you run out of fds, you may not be able to load
* the exception class, and get a NoClassDefFoundError
* instead.
*/
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"Can't create socket"
);
return
JNI_FALSE
;
}
if
(
ttl
>
0
)
{
setsockopt
(
fd
,
IPPROTO_IP
,
IP_TTL
,
(
const
char
*
)
&
ttl
,
sizeof
(
ttl
));
}
/*
* A network interface was specified, so let's bind to it.
*/
if
(
netif
!=
NULL
)
{
if
(
bind
(
fd
,
(
struct
sockaddr
*
)
netif
,
sizeof
(
struct
sockaddr_in
))
<
0
)
{
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"Can't bind socket"
);
closesocket
(
fd
);
return
JNI_FALSE
;
}
}
/*
* Make the socket non blocking so we can use select/poll.
*/
hEvent
=
WSACreateEvent
();
WSAEventSelect
(
fd
,
hEvent
,
FD_READ
|
FD_CONNECT
|
FD_CLOSE
);
/* no need to use NET_Connect as non-blocking */
him
.
sin_port
=
htons
(
7
);
/* Echo */
connect_rv
=
connect
(
fd
,
(
struct
sockaddr
*
)
&
him
,
len
);
/**
* connection established or refused immediately, either way it means
* we were able to reach the host!
*/
if
(
connect_rv
==
0
||
WSAGetLastError
()
==
WSAECONNREFUSED
)
{
WSACloseEvent
(
hEvent
);
closesocket
(
fd
);
return
JNI_TRUE
;
}
else
{
int
optlen
;
switch
(
WSAGetLastError
())
{
case
WSAEHOSTUNREACH
:
/* Host Unreachable */
case
WSAENETUNREACH
:
/* Network Unreachable */
case
WSAENETDOWN
:
/* Network is down */
case
WSAEPFNOSUPPORT
:
/* Protocol Family unsupported */
WSACloseEvent
(
hEvent
);
closesocket
(
fd
);
return
JNI_FALSE
;
}
if
(
WSAGetLastError
()
!=
WSAEWOULDBLOCK
)
{
NET_ThrowByNameWithLastError
(
env
,
JNU_JAVANETPKG
"ConnectException"
,
"connect failed"
);
WSACloseEvent
(
hEvent
);
closesocket
(
fd
);
return
JNI_FALSE
;
}
timeout
=
NET_Wait
(
env
,
fd
,
NET_WAIT_CONNECT
,
timeout
);
/* has connection been established */
if
(
timeout
>=
0
)
{
optlen
=
sizeof
(
connect_rv
);
if
(
getsockopt
(
fd
,
SOL_SOCKET
,
SO_ERROR
,
(
void
*
)
&
connect_rv
,
&
optlen
)
<
0
)
{
connect_rv
=
WSAGetLastError
();
}
if
(
connect_rv
==
0
||
connect_rv
==
WSAECONNREFUSED
)
{
WSACloseEvent
(
hEvent
);
closesocket
(
fd
);
return
JNI_TRUE
;
}
}
}
WSACloseEvent
(
hEvent
);
closesocket
(
fd
);
return
JNI_FALSE
;
return
ping4
(
env
,
addr
,
timeout
);
}
src/windows/native/java/net/Inet6AddressImpl.c
浏览文件 @
41b349b4
...
...
@@ -31,6 +31,8 @@
#include <malloc.h>
#include <sys/types.h>
#include <process.h>
#include <iphlpapi.h>
#include <icmpapi.h>
#include "java_net_InetAddress.h"
#include "java_net_Inet4AddressImpl.h"
...
...
@@ -366,139 +368,61 @@ Java_java_net_Inet6AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
* Returns true is an ECHO_REPLY is received, otherwise, false.
*/
static
jboolean
ping6
(
JNIEnv
*
env
,
jint
fd
,
struct
SOCKADDR_IN6
*
him
,
jint
timeout
,
struct
SOCKADDR_IN6
*
netif
,
jint
ttl
)
{
jint
size
;
jint
n
,
len
,
i
;
char
sendbuf
[
1500
];
char
auxbuf
[
1500
];
unsigned
char
recvbuf
[
1500
];
struct
icmp6_hdr
*
icmp6
;
struct
SOCKADDR_IN6
sa_recv
;
unsigned
short
pid
,
seq
;
int
read_rv
=
0
;
WSAEVENT
hEvent
;
struct
ip6_pseudo_hdr
*
pseudo_ip6
;
int
timestamp
;
int
tmout2
;
/* Initialize the sequence number to a suitable random number and
shift right one place to allow sufficient room for increamenting. */
seq
=
((
unsigned
short
)
rand
())
>>
1
;
/* icmp_id is a 16 bit data type, therefore down cast the pid */
pid
=
(
unsigned
short
)
_getpid
();
size
=
60
*
1024
;
setsockopt
(
fd
,
SOL_SOCKET
,
SO_RCVBUF
,
(
const
char
*
)
&
size
,
sizeof
(
size
));
/**
* A TTL was specified, let's set the socket option.
*/
if
(
ttl
>
0
)
{
setsockopt
(
fd
,
IPPROTO_IPV6
,
IPV6_UNICAST_HOPS
,
(
const
char
*
)
&
ttl
,
sizeof
(
ttl
));
ping6
(
JNIEnv
*
env
,
struct
sockaddr_in6
*
src
,
struct
sockaddr_in6
*
dest
,
jint
timeout
)
{
HANDLE
hIcmpFile
;
DWORD
dwRetVal
=
0
;
char
SendData
[
32
]
=
{
0
};
LPVOID
ReplyBuffer
=
NULL
;
DWORD
ReplySize
=
0
;
IP_OPTION_INFORMATION
ipInfo
=
{
255
,
0
,
0
,
0
,
NULL
};
struct
sockaddr_in6
sa6Source
;
hIcmpFile
=
Icmp6CreateFile
();
if
(
hIcmpFile
==
INVALID_HANDLE_VALUE
)
{
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"Unable to open handle"
);
return
JNI_FALSE
;
}
/**
* A network interface was specified, let's bind to it.
*/
if
(
netif
!=
NULL
)
{
if
(
NET_Bind
(
fd
,
(
struct
sockaddr
*
)
netif
,
sizeof
(
struct
sockaddr_in6
))
<
0
){
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"Can't bind socket to interface"
);
closesocket
(
fd
);
ReplySize
=
sizeof
(
ICMPV6_ECHO_REPLY
)
+
sizeof
(
SendData
);
ReplyBuffer
=
(
VOID
*
)
malloc
(
ReplySize
);
if
(
ReplyBuffer
==
NULL
)
{
IcmpCloseHandle
(
hIcmpFile
);
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"Unable to allocate memory"
);
return
JNI_FALSE
;
}
}
/*
* Make the socket non blocking
*/
hEvent
=
WSACreateEvent
();
WSAEventSelect
(
fd
,
hEvent
,
FD_READ
|
FD_CONNECT
|
FD_CLOSE
);
/**
* send 1 ICMP REQUEST every second until either we get a valid reply
* or the timeout expired.
*/
do
{
/* let's tag the ECHO packet with our pid so we can identify it */
timestamp
=
GetCurrentTime
();
memset
(
sendbuf
,
0
,
1500
);
icmp6
=
(
struct
icmp6_hdr
*
)
sendbuf
;
icmp6
->
icmp6_type
=
ICMP6_ECHO_REQUEST
;
icmp6
->
icmp6_code
=
0
;
icmp6
->
icmp6_id
=
htons
(
pid
);
icmp6
->
icmp6_seq
=
htons
(
seq
);
icmp6
->
icmp6_cksum
=
0
;
memcpy
((
icmp6
+
1
),
&
timestamp
,
sizeof
(
int
));
if
(
netif
!=
NULL
)
{
memset
(
auxbuf
,
0
,
1500
);
pseudo_ip6
=
(
struct
ip6_pseudo_hdr
*
)
auxbuf
;
memcpy
(
&
pseudo_ip6
->
ip6_src
,
&
netif
->
sin6_addr
,
sizeof
(
struct
in6_addr
));
memcpy
(
&
pseudo_ip6
->
ip6_dst
,
&
him
->
sin6_addr
,
sizeof
(
struct
in6_addr
));
pseudo_ip6
->
ip6_plen
=
htonl
(
64
);
pseudo_ip6
->
ip6_nxt
=
htonl
(
IPPROTO_ICMPV6
);
memcpy
(
auxbuf
+
sizeof
(
struct
ip6_pseudo_hdr
),
icmp6
,
64
);
/**
* We shouldn't have to do that as computing the checksum is supposed
* to be done by the IPv6 stack. Unfortunately windows, here too, is
* uterly broken, or non compliant, so let's do it.
* Problem is to compute the checksum I need to know the source address
* which happens only if I know the interface to be used...
*/
icmp6
->
icmp6_cksum
=
in_cksum
((
u_short
*
)
pseudo_ip6
,
sizeof
(
struct
ip6_pseudo_hdr
)
+
64
);
}
/**
* Ping!
*/
n
=
sendto
(
fd
,
sendbuf
,
64
,
0
,
(
struct
sockaddr
*
)
him
,
sizeof
(
struct
sockaddr_in6
));
if
(
n
<
0
&&
(
WSAGetLastError
()
==
WSAEINTR
||
WSAGetLastError
()
==
WSAEADDRNOTAVAIL
))
{
// Happens when using a "tunnel interface" for instance.
// Or trying to send a packet on a different scope.
closesocket
(
fd
);
WSACloseEvent
(
hEvent
);
return
JNI_FALSE
;
}
if
(
n
<
0
&&
WSAGetLastError
()
!=
WSAEWOULDBLOCK
)
{
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"Can't send ICMP packet"
);
closesocket
(
fd
);
WSACloseEvent
(
hEvent
);
//define local source information
sa6Source
.
sin6_addr
=
in6addr_any
;
sa6Source
.
sin6_family
=
AF_INET6
;
sa6Source
.
sin6_flowinfo
=
0
;
sa6Source
.
sin6_port
=
0
;
dwRetVal
=
Icmp6SendEcho2
(
hIcmpFile
,
// HANDLE IcmpHandle,
NULL
,
// HANDLE Event,
NULL
,
// PIO_APC_ROUTINE ApcRoutine,
NULL
,
// PVOID ApcContext,
&
sa6Source
,
// struct sockaddr_in6 *SourceAddress,
dest
,
// struct sockaddr_in6 *DestinationAddress,
SendData
,
// LPVOID RequestData,
sizeof
(
SendData
),
// WORD RequestSize,
&
ipInfo
,
// PIP_OPTION_INFORMATION RequestOptions,
ReplyBuffer
,
// LPVOID ReplyBuffer,
ReplySize
,
// DWORD ReplySize,
timeout
);
// DWORD Timeout
free
(
ReplyBuffer
);
IcmpCloseHandle
(
hIcmpFile
);
if
(
dwRetVal
!=
0
)
{
return
JNI_TRUE
;
}
else
{
return
JNI_FALSE
;
}
tmout2
=
timeout
>
1000
?
1000
:
timeout
;
do
{
tmout2
=
NET_Wait
(
env
,
fd
,
NET_WAIT_READ
,
tmout2
);
if
(
tmout2
>=
0
)
{
len
=
sizeof
(
sa_recv
);
memset
(
recvbuf
,
0
,
1500
);
/**
* For some unknown reason, besides plain stupidity, windows
* truncates the first 4 bytes of the icmpv6 header some we can't
* check for the ICMP_ECHOREPLY value.
* we'll check the other values, though
*/
n
=
recvfrom
(
fd
,
recvbuf
+
4
,
sizeof
(
recvbuf
)
-
4
,
0
,
(
struct
sockaddr
*
)
&
sa_recv
,
&
len
);
icmp6
=
(
struct
icmp6_hdr
*
)
(
recvbuf
);
memcpy
(
&
i
,
(
icmp6
+
1
),
sizeof
(
int
));
/**
* Is that the reply we were expecting?
*/
if
(
n
>=
8
&&
ntohs
(
icmp6
->
icmp6_seq
)
==
seq
&&
ntohs
(
icmp6
->
icmp6_id
)
==
pid
&&
i
==
timestamp
)
{
closesocket
(
fd
);
WSACloseEvent
(
hEvent
);
return
JNI_TRUE
;
}
}
}
while
(
tmout2
>
0
);
timeout
-=
1000
;
seq
++
;
}
while
(
timeout
>
0
);
closesocket
(
fd
);
WSACloseEvent
(
hEvent
);
return
JNI_FALSE
;
}
}
#endif
/* AF_INET6 */
...
...
@@ -516,11 +440,10 @@ Java_java_net_Inet6AddressImpl_isReachable0(JNIEnv *env, jobject this,
jint
ttl
,
jint
if_scope
)
{
#ifdef AF_INET6
jbyte
caddr
[
16
];
jint
fd
,
sz
;
jint
sz
;
struct
sockaddr_in6
him6
;
struct
sockaddr_in6
*
netif
=
NULL
;
struct
sockaddr_in6
inf6
;
WSAEVENT
hEvent
;
int
len
=
0
;
int
connect_rv
=
-
1
;
...
...
@@ -552,6 +475,7 @@ Java_java_net_Inet6AddressImpl_isReachable0(JNIEnv *env, jobject this,
him6
.
sin6_scope_id
=
scope
;
}
len
=
sizeof
(
struct
sockaddr_in6
);
/**
* A network interface was specified, let's convert the address
*/
...
...
@@ -565,123 +489,7 @@ Java_java_net_Inet6AddressImpl_isReachable0(JNIEnv *env, jobject this,
inf6
.
sin6_scope_id
=
if_scope
;
netif
=
&
inf6
;
}
#if 0
/*
* Windows implementation of ICMP & RAW sockets is too unreliable for now.
* Therefore it's best not to try it at all and rely only on TCP
* We may revisit and enable this code in the future.
*/
/*
* Right now, windows doesn't generate the ICMP checksum automatically
* so we have to compute it, but we can do it only if we know which
* interface will be used. Therefore, don't try to use ICMP if no
* interface was specified.
* When ICMPv6 support improves in windows, we may change this.
*/
if (!(IS_NULL(ifArray))) {
/*
* If we can create a RAW socket, then when can use the ICMP ECHO_REQUEST
* otherwise we'll try a tcp socket to the Echo port (7).
* Note that this is empiric, and not connecting could mean it's blocked
* or the echo servioe has been disabled.
*/
fd = NET_Socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
if (fd != -1) { /* Good to go, let's do a ping */
return ping6(env, fd, &him6, timeout, netif, ttl);
}
}
#endif
/* No good, let's fall back on TCP */
fd
=
NET_Socket
(
AF_INET6
,
SOCK_STREAM
,
0
);
if
(
fd
==
JVM_IO_ERR
)
{
/* note: if you run out of fds, you may not be able to load
* the exception class, and get a NoClassDefFoundError
* instead.
*/
NET_ThrowNew
(
env
,
errno
,
"Can't create socket"
);
return
JNI_FALSE
;
}
/**
* A TTL was specified, let's set the socket option.
*/
if
(
ttl
>
0
)
{
setsockopt
(
fd
,
IPPROTO_IPV6
,
IPV6_UNICAST_HOPS
,
(
const
char
*
)
&
ttl
,
sizeof
(
ttl
));
}
/**
* A network interface was specified, let's bind to it.
*/
if
(
netif
!=
NULL
)
{
if
(
NET_Bind
(
fd
,
(
struct
sockaddr
*
)
netif
,
sizeof
(
struct
sockaddr_in6
))
<
0
)
{
NET_ThrowNew
(
env
,
WSAGetLastError
(),
"Can't bind socket to interface"
);
closesocket
(
fd
);
return
JNI_FALSE
;
}
}
/**
* Make the socket non blocking.
*/
hEvent
=
WSACreateEvent
();
WSAEventSelect
(
fd
,
hEvent
,
FD_READ
|
FD_CONNECT
|
FD_CLOSE
);
/* no need to use NET_Connect as non-blocking */
him6
.
sin6_port
=
htons
((
short
)
7
);
/* Echo port */
connect_rv
=
connect
(
fd
,
(
struct
sockaddr
*
)
&
him6
,
len
);
/**
* connection established or refused immediately, either way it means
* we were able to reach the host!
*/
if
(
connect_rv
==
0
||
WSAGetLastError
()
==
WSAECONNREFUSED
)
{
WSACloseEvent
(
hEvent
);
closesocket
(
fd
);
return
JNI_TRUE
;
}
else
{
int
optlen
;
switch
(
WSAGetLastError
())
{
case
WSAEHOSTUNREACH
:
/* Host Unreachable */
case
WSAENETUNREACH
:
/* Network Unreachable */
case
WSAENETDOWN
:
/* Network is down */
case
WSAEPFNOSUPPORT
:
/* Protocol Family unsupported */
WSACloseEvent
(
hEvent
);
closesocket
(
fd
);
return
JNI_FALSE
;
}
if
(
WSAGetLastError
()
!=
WSAEWOULDBLOCK
)
{
NET_ThrowByNameWithLastError
(
env
,
JNU_JAVANETPKG
"ConnectException"
,
"connect failed"
);
WSACloseEvent
(
hEvent
);
closesocket
(
fd
);
return
JNI_FALSE
;
}
timeout
=
NET_Wait
(
env
,
fd
,
NET_WAIT_CONNECT
,
timeout
);
if
(
timeout
>=
0
)
{
/* has connection been established? */
optlen
=
sizeof
(
connect_rv
);
if
(
getsockopt
(
fd
,
SOL_SOCKET
,
SO_ERROR
,
(
void
*
)
&
connect_rv
,
&
optlen
)
<
0
)
{
connect_rv
=
WSAGetLastError
();
}
if
(
connect_rv
==
0
||
connect_rv
==
WSAECONNREFUSED
)
{
WSACloseEvent
(
hEvent
);
closesocket
(
fd
);
return
JNI_TRUE
;
}
}
}
WSACloseEvent
(
hEvent
);
closesocket
(
fd
);
return
ping6
(
env
,
netif
,
&
him6
,
timeout
);
#endif
/* AF_INET6 */
return
JNI_FALSE
;
}
test/java/net/Inet4Address/PingThis.java
浏览文件 @
41b349b4
...
...
@@ -26,7 +26,7 @@
*/
/* @test
* @bug 7163874
* @bug 7163874
8133015
* @summary InetAddress.isReachable is returning false
* for InetAdress 0.0.0.0 and ::0
* @run main PingThis
...
...
test/java/net/InetAddress/IsHostReachableBug.java
浏览文件 @
41b349b4
...
...
@@ -23,7 +23,7 @@
/**
* @test
* @bug 4922568
* @bug 4922568
8133015
* @run main/othervm -Djava.net.preferIPv4Stack=true IsHostReachableBug
* @summary isReachable returns true for IPv6
*/
...
...
test/java/net/InetAddress/IsReachable.java
浏览文件 @
41b349b4
...
...
@@ -23,7 +23,7 @@
/**
* @test
* @bug 4639861
* @bug 4639861
8133015
* @summary API to test reachability of a host
*/
import
java.net.InetAddress
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录