8058965: Remove IPv6 support from TwoStacksPlainSocketImpl [win]
Reviewed-by: chegar
This commit is contained in:
parent
d8dc99ec5c
commit
b5c20a6e1c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -29,42 +29,13 @@ import java.io.FileDescriptor;
|
|||||||
import sun.net.ResourceManager;
|
import sun.net.ResourceManager;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This class defines the plain SocketImpl that is used for all
|
* This class defines the plain SocketImpl that is used when
|
||||||
* Windows version lower than Vista. It adds support for IPv6 on
|
* the System property java.net.preferIPv4Stack is set to true.
|
||||||
* these platforms where available.
|
|
||||||
*
|
|
||||||
* For backward compatibility Windows platforms that do not have IPv6
|
|
||||||
* support also use this implementation, and fd1 gets set to null
|
|
||||||
* during socket creation.
|
|
||||||
*
|
*
|
||||||
* @author Chris Hegarty
|
* @author Chris Hegarty
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl
|
class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl {
|
||||||
{
|
|
||||||
/* second fd, used for ipv6 on windows only.
|
|
||||||
* fd1 is used for listeners and for client sockets at initialization
|
|
||||||
* until the socket is connected. Up to this point fd always refers
|
|
||||||
* to the ipv4 socket and fd1 to the ipv6 socket. After the socket
|
|
||||||
* becomes connected, fd always refers to the connected socket
|
|
||||||
* (either v4 or v6) and fd1 is closed.
|
|
||||||
*
|
|
||||||
* For ServerSockets, fd always refers to the v4 listener and
|
|
||||||
* fd1 the v6 listener.
|
|
||||||
*/
|
|
||||||
private FileDescriptor fd1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Needed for ipv6 on windows because we need to know
|
|
||||||
* if the socket is bound to ::0 or 0.0.0.0, when a caller
|
|
||||||
* asks for it. Otherwise we don't know which socket to ask.
|
|
||||||
*/
|
|
||||||
private InetAddress anyLocalBoundAddr = null;
|
|
||||||
|
|
||||||
/* to prevent starvation when listening on two sockets, this is
|
|
||||||
* is used to hold the id of the last socket we accepted on.
|
|
||||||
*/
|
|
||||||
private int lastfd = -1;
|
|
||||||
|
|
||||||
// true if this socket is exclusively bound
|
// true if this socket is exclusively bound
|
||||||
private final boolean exclusiveBind;
|
private final boolean exclusiveBind;
|
||||||
@ -85,43 +56,11 @@ class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl
|
|||||||
exclusiveBind = exclBind;
|
exclusiveBind = exclBind;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a socket with a boolean that specifies whether this
|
|
||||||
* is a stream socket (true) or an unconnected UDP socket (false).
|
|
||||||
*/
|
|
||||||
protected synchronized void create(boolean stream) throws IOException {
|
|
||||||
fd1 = new FileDescriptor();
|
|
||||||
try {
|
|
||||||
super.create(stream);
|
|
||||||
} catch (IOException e) {
|
|
||||||
fd1 = null;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Binds the socket to the specified address of the specified local port.
|
|
||||||
* @param address the address
|
|
||||||
* @param port the port
|
|
||||||
*/
|
|
||||||
protected synchronized void bind(InetAddress address, int lport)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
super.bind(address, lport);
|
|
||||||
if (address.isAnyLocalAddress()) {
|
|
||||||
anyLocalBoundAddr = address;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getOption(int opt) throws SocketException {
|
public Object getOption(int opt) throws SocketException {
|
||||||
if (isClosedOrPending()) {
|
if (isClosedOrPending()) {
|
||||||
throw new SocketException("Socket Closed");
|
throw new SocketException("Socket Closed");
|
||||||
}
|
}
|
||||||
if (opt == SO_BINDADDR) {
|
if (opt == SO_BINDADDR) {
|
||||||
if (fd != null && fd1 != null ) {
|
|
||||||
/* must be unbound or else bound to anyLocal */
|
|
||||||
return anyLocalBoundAddr;
|
|
||||||
}
|
|
||||||
InetAddressContainer in = new InetAddressContainer();
|
InetAddressContainer in = new InetAddressContainer();
|
||||||
socketGetOption(opt, in);
|
socketGetOption(opt, in);
|
||||||
return in.addr;
|
return in.addr;
|
||||||
@ -161,7 +100,7 @@ class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl
|
|||||||
@Override
|
@Override
|
||||||
protected void close() throws IOException {
|
protected void close() throws IOException {
|
||||||
synchronized(fdLock) {
|
synchronized(fdLock) {
|
||||||
if (fd != null || fd1 != null) {
|
if (fd != null) {
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
ResourceManager.afterUdpClose();
|
ResourceManager.afterUdpClose();
|
||||||
}
|
}
|
||||||
@ -172,7 +111,6 @@ class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl
|
|||||||
closePending = true;
|
closePending = true;
|
||||||
socketClose();
|
socketClose();
|
||||||
fd = null;
|
fd = null;
|
||||||
fd1 = null;
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
@ -191,39 +129,11 @@ class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
void reset() throws IOException {
|
|
||||||
if (fd != null || fd1 != null) {
|
|
||||||
socketClose();
|
|
||||||
}
|
|
||||||
fd = null;
|
|
||||||
fd1 = null;
|
|
||||||
super.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return true if already closed or close is pending
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean isClosedOrPending() {
|
|
||||||
/*
|
|
||||||
* Lock on fdLock to ensure that we wait if a
|
|
||||||
* close is in progress.
|
|
||||||
*/
|
|
||||||
synchronized (fdLock) {
|
|
||||||
if (closePending || (fd == null && fd1 == null)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Native methods */
|
/* Native methods */
|
||||||
|
|
||||||
static native void initProto();
|
static native void initProto();
|
||||||
|
|
||||||
native void socketCreate(boolean isServer) throws IOException;
|
native void socketCreate(boolean stream) throws IOException;
|
||||||
|
|
||||||
native void socketConnect(InetAddress address, int port, int timeout)
|
native void socketConnect(InetAddress address, int port, int timeout)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -37,14 +37,12 @@
|
|||||||
static jfieldID IO_fd_fdID;
|
static jfieldID IO_fd_fdID;
|
||||||
|
|
||||||
jfieldID psi_fdID;
|
jfieldID psi_fdID;
|
||||||
jfieldID psi_fd1ID;
|
|
||||||
jfieldID psi_addressID;
|
jfieldID psi_addressID;
|
||||||
jfieldID psi_portID;
|
jfieldID psi_portID;
|
||||||
jfieldID psi_localportID;
|
jfieldID psi_localportID;
|
||||||
jfieldID psi_timeoutID;
|
jfieldID psi_timeoutID;
|
||||||
jfieldID psi_trafficClassID;
|
jfieldID psi_trafficClassID;
|
||||||
jfieldID psi_serverSocketID;
|
jfieldID psi_serverSocketID;
|
||||||
jfieldID psi_lastfdID;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* the level of the TCP protocol for setsockopt and getsockopt
|
* the level of the TCP protocol for setsockopt and getsockopt
|
||||||
@ -62,15 +60,6 @@ static int getFD(JNIEnv *env, jobject this) {
|
|||||||
return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
|
return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getFD1(JNIEnv *env, jobject this) {
|
|
||||||
jobject fdObj = (*env)->GetObjectField(env, this, psi_fd1ID);
|
|
||||||
|
|
||||||
if (fdObj == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The initProto function is called whenever TwoStacksPlainSocketImpl is
|
* The initProto function is called whenever TwoStacksPlainSocketImpl is
|
||||||
@ -90,15 +79,11 @@ Java_java_net_TwoStacksPlainSocketImpl_initProto(JNIEnv *env, jclass cls) {
|
|||||||
|
|
||||||
psi_fdID = (*env)->GetFieldID(env, cls , "fd", "Ljava/io/FileDescriptor;");
|
psi_fdID = (*env)->GetFieldID(env, cls , "fd", "Ljava/io/FileDescriptor;");
|
||||||
CHECK_NULL(psi_fdID);
|
CHECK_NULL(psi_fdID);
|
||||||
psi_fd1ID =(*env)->GetFieldID(env, cls , "fd1", "Ljava/io/FileDescriptor;");
|
|
||||||
CHECK_NULL(psi_fd1ID);
|
|
||||||
psi_addressID = (*env)->GetFieldID(env, cls, "address",
|
psi_addressID = (*env)->GetFieldID(env, cls, "address",
|
||||||
"Ljava/net/InetAddress;");
|
"Ljava/net/InetAddress;");
|
||||||
CHECK_NULL(psi_addressID);
|
CHECK_NULL(psi_addressID);
|
||||||
psi_portID = (*env)->GetFieldID(env, cls, "port", "I");
|
psi_portID = (*env)->GetFieldID(env, cls, "port", "I");
|
||||||
CHECK_NULL(psi_portID);
|
CHECK_NULL(psi_portID);
|
||||||
psi_lastfdID = (*env)->GetFieldID(env, cls, "lastfd", "I");
|
|
||||||
CHECK_NULL(psi_lastfdID);
|
|
||||||
psi_localportID = (*env)->GetFieldID(env, cls, "localport", "I");
|
psi_localportID = (*env)->GetFieldID(env, cls, "localport", "I");
|
||||||
CHECK_NULL(psi_localportID);
|
CHECK_NULL(psi_localportID);
|
||||||
psi_timeoutID = (*env)->GetFieldID(env, cls, "timeout", "I");
|
psi_timeoutID = (*env)->GetFieldID(env, cls, "timeout", "I");
|
||||||
@ -120,8 +105,8 @@ Java_java_net_TwoStacksPlainSocketImpl_initProto(JNIEnv *env, jclass cls) {
|
|||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
Java_java_net_TwoStacksPlainSocketImpl_socketCreate(JNIEnv *env, jobject this,
|
Java_java_net_TwoStacksPlainSocketImpl_socketCreate(JNIEnv *env, jobject this,
|
||||||
jboolean stream) {
|
jboolean stream) {
|
||||||
jobject fdObj, fd1Obj;
|
jobject fdObj;
|
||||||
int fd, fd1;
|
int fd;
|
||||||
|
|
||||||
fdObj = (*env)->GetObjectField(env, this, psi_fdID);
|
fdObj = (*env)->GetObjectField(env, this, psi_fdID);
|
||||||
|
|
||||||
@ -139,30 +124,6 @@ Java_java_net_TwoStacksPlainSocketImpl_socketCreate(JNIEnv *env, jobject this,
|
|||||||
SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, FALSE);
|
SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, FALSE);
|
||||||
(*env)->SetIntField(env, fdObj, IO_fd_fdID, (int)fd);
|
(*env)->SetIntField(env, fdObj, IO_fd_fdID, (int)fd);
|
||||||
}
|
}
|
||||||
if (ipv6_available()) {
|
|
||||||
fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
|
|
||||||
|
|
||||||
if (IS_NULL(fd1Obj)) {
|
|
||||||
(*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
|
|
||||||
NET_SocketClose(fd);
|
|
||||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
|
||||||
"null fd1 object");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fd1 = socket(AF_INET6, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
|
|
||||||
if (fd1 == -1) {
|
|
||||||
(*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
|
|
||||||
NET_SocketClose(fd);
|
|
||||||
NET_ThrowCurrent(env, "create");
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
/* Set socket attribute so it is not passed to any child process */
|
|
||||||
SetHandleInformation((HANDLE)(UINT_PTR)fd1, HANDLE_FLAG_INHERIT, FALSE);
|
|
||||||
(*env)->SetIntField(env, fd1Obj, IO_fd_fdID, fd1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
(*env)->SetObjectField(env, this, psi_fd1ID, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -182,16 +143,10 @@ Java_java_net_TwoStacksPlainSocketImpl_socketConnect(JNIEnv *env, jobject this,
|
|||||||
|
|
||||||
/* family and localport are int fields of iaObj */
|
/* family and localport are int fields of iaObj */
|
||||||
int family;
|
int family;
|
||||||
jint fd = -1, fd1 = -1;
|
jint fd = -1;
|
||||||
jint len;
|
jint len;
|
||||||
int ipv6_supported = ipv6_available();
|
|
||||||
|
|
||||||
/* fd initially points to the IPv4 socket and fd1 to the IPv6 socket
|
|
||||||
* If we want to connect to IPv6 then we swap the two sockets/objects
|
|
||||||
* This way, fd is always the connected socket, and fd1 always gets closed.
|
|
||||||
*/
|
|
||||||
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
|
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
|
||||||
jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
|
|
||||||
|
|
||||||
SOCKETADDRESS sa;
|
SOCKETADDRESS sa;
|
||||||
|
|
||||||
@ -203,10 +158,6 @@ Java_java_net_TwoStacksPlainSocketImpl_socketConnect(JNIEnv *env, jobject this,
|
|||||||
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
|
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ipv6_supported && !IS_NULL(fd1Obj)) {
|
|
||||||
fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_NULL(iaObj)) {
|
if (IS_NULL(iaObj)) {
|
||||||
JNU_ThrowNullPointerException(env, "inet address argument is null.");
|
JNU_ThrowNullPointerException(env, "inet address argument is null.");
|
||||||
return;
|
return;
|
||||||
@ -218,35 +169,15 @@ Java_java_net_TwoStacksPlainSocketImpl_socketConnect(JNIEnv *env, jobject this,
|
|||||||
}
|
}
|
||||||
|
|
||||||
family = sa.sa.sa_family;
|
family = sa.sa.sa_family;
|
||||||
if (family == AF_INET6) {
|
if (family != AF_INET) {
|
||||||
if (!ipv6_supported) {
|
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
||||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
"Protocol family not supported");
|
||||||
"Protocol family not supported");
|
}
|
||||||
return;
|
if (fd == -1) {
|
||||||
} else {
|
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
||||||
if (fd1 == -1) {
|
"Destination unreachable");
|
||||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
return;
|
||||||
"Destination unreachable");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* close the v4 socket, and set fd to be the v6 socket */
|
|
||||||
(*env)->SetObjectField(env, this, psi_fdID, fd1Obj);
|
|
||||||
(*env)->SetObjectField(env, this, psi_fd1ID, NULL);
|
|
||||||
NET_SocketClose(fd);
|
|
||||||
fd = fd1; fdObj = fd1Obj;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (fd1 != -1) {
|
|
||||||
(*env)->SetIntField(env, fd1Obj, IO_fd_fdID, -1);
|
|
||||||
NET_SocketClose(fd1);
|
|
||||||
}
|
|
||||||
if (fd == -1) {
|
|
||||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
|
||||||
"Destination unreachable");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
(*env)->SetObjectField(env, this, psi_fd1ID, NULL);
|
|
||||||
|
|
||||||
if (timeout <= 0) {
|
if (timeout <= 0) {
|
||||||
connect_res = connect(fd, &sa.sa, sizeof(SOCKETADDRESS));
|
connect_res = connect(fd, &sa.sa, sizeof(SOCKETADDRESS));
|
||||||
@ -388,10 +319,9 @@ Java_java_net_TwoStacksPlainSocketImpl_socketBind(JNIEnv *env, jobject this,
|
|||||||
jboolean exclBind) {
|
jboolean exclBind) {
|
||||||
|
|
||||||
/* fdObj is the FileDescriptor field on this */
|
/* fdObj is the FileDescriptor field on this */
|
||||||
jobject fdObj, fd1Obj;
|
jobject fdObj;
|
||||||
/* fd is an int field on fdObj */
|
/* fd is an int field on fdObj */
|
||||||
int fd, fd1 = -1, len = 0;
|
int fd, len = 0;
|
||||||
int ipv6_supported = ipv6_available();
|
|
||||||
|
|
||||||
/* family is an int field of iaObj */
|
/* family is an int field of iaObj */
|
||||||
int family;
|
int family;
|
||||||
@ -400,25 +330,21 @@ Java_java_net_TwoStacksPlainSocketImpl_socketBind(JNIEnv *env, jobject this,
|
|||||||
SOCKETADDRESS sa;
|
SOCKETADDRESS sa;
|
||||||
|
|
||||||
fdObj = (*env)->GetObjectField(env, this, psi_fdID);
|
fdObj = (*env)->GetObjectField(env, this, psi_fdID);
|
||||||
fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
|
|
||||||
|
|
||||||
family = getInetAddress_family(env, iaObj);
|
family = getInetAddress_family(env, iaObj);
|
||||||
|
|
||||||
if (family == java_net_InetAddress_IPv6 && !ipv6_supported) {
|
if (family != java_net_InetAddress_IPv4) {
|
||||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
||||||
"Protocol family not supported");
|
"Protocol family not supported");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_NULL(fdObj) || (ipv6_supported && IS_NULL(fd1Obj))) {
|
if (IS_NULL(fdObj)) {
|
||||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
||||||
"Socket closed");
|
"Socket closed");
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
|
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
|
||||||
if (ipv6_supported) {
|
|
||||||
fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (IS_NULL(iaObj)) {
|
if (IS_NULL(iaObj)) {
|
||||||
JNU_ThrowNullPointerException(env, "inet address argument");
|
JNU_ThrowNullPointerException(env, "inet address argument");
|
||||||
@ -429,42 +355,7 @@ Java_java_net_TwoStacksPlainSocketImpl_socketBind(JNIEnv *env, jobject this,
|
|||||||
JNI_FALSE) != 0) {
|
JNI_FALSE) != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ipv6_supported) {
|
rv = NET_WinBind(fd, &sa, len, exclBind);
|
||||||
struct ipv6bind v6bind;
|
|
||||||
v6bind.addr = &sa.sa;
|
|
||||||
v6bind.ipv4_fd = fd;
|
|
||||||
v6bind.ipv6_fd = fd1;
|
|
||||||
rv = NET_BindV6(&v6bind, exclBind);
|
|
||||||
if (rv != -1) {
|
|
||||||
/* check if the fds have changed */
|
|
||||||
if (v6bind.ipv4_fd != fd) {
|
|
||||||
fd = v6bind.ipv4_fd;
|
|
||||||
if (fd == -1) {
|
|
||||||
/* socket is closed. */
|
|
||||||
(*env)->SetObjectField(env, this, psi_fdID, NULL);
|
|
||||||
} else {
|
|
||||||
/* socket was re-created */
|
|
||||||
(*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (v6bind.ipv6_fd != fd1) {
|
|
||||||
fd1 = v6bind.ipv6_fd;
|
|
||||||
if (fd1 == -1) {
|
|
||||||
/* socket is closed. */
|
|
||||||
(*env)->SetObjectField(env, this, psi_fd1ID, NULL);
|
|
||||||
} else {
|
|
||||||
/* socket was re-created */
|
|
||||||
(*env)->SetIntField(env, fd1Obj, IO_fd_fdID, fd1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* NET_BindV6() closes both sockets upon a failure */
|
|
||||||
(*env)->SetObjectField(env, this, psi_fdID, NULL);
|
|
||||||
(*env)->SetObjectField(env, this, psi_fd1ID, NULL);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rv = NET_WinBind(fd, &sa, len, exclBind);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rv == -1) {
|
if (rv == -1) {
|
||||||
NET_ThrowCurrent(env, "NET_Bind");
|
NET_ThrowCurrent(env, "NET_Bind");
|
||||||
@ -482,7 +373,7 @@ Java_java_net_TwoStacksPlainSocketImpl_socketBind(JNIEnv *env, jobject this,
|
|||||||
int len = sizeof(SOCKETADDRESS);
|
int len = sizeof(SOCKETADDRESS);
|
||||||
u_short port;
|
u_short port;
|
||||||
|
|
||||||
if (getsockname(sa.sa.sa_family == AF_INET ? fd : fd1, &sa.sa, &len) == -1) {
|
if (getsockname(fd, &sa.sa, &len) == -1) {
|
||||||
NET_ThrowCurrent(env, "getsockname in plain socketBind");
|
NET_ThrowCurrent(env, "getsockname in plain socketBind");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -505,14 +396,13 @@ Java_java_net_TwoStacksPlainSocketImpl_socketListen
|
|||||||
{
|
{
|
||||||
/* this FileDescriptor fd field */
|
/* this FileDescriptor fd field */
|
||||||
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
|
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
|
||||||
jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
|
|
||||||
jobject address;
|
jobject address;
|
||||||
/* fdObj's int fd field */
|
/* fdObj's int fd field */
|
||||||
int fd = INVALID_SOCKET, fd1 = INVALID_SOCKET;
|
int fd = INVALID_SOCKET;
|
||||||
SOCKETADDRESS addr;
|
SOCKETADDRESS addr;
|
||||||
int addrlen;
|
int addrlen;
|
||||||
|
|
||||||
if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
|
if (IS_NULL(fdObj)) {
|
||||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
||||||
"socket closed");
|
"socket closed");
|
||||||
return;
|
return;
|
||||||
@ -521,10 +411,6 @@ Java_java_net_TwoStacksPlainSocketImpl_socketListen
|
|||||||
if (!IS_NULL(fdObj)) {
|
if (!IS_NULL(fdObj)) {
|
||||||
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
|
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
|
||||||
}
|
}
|
||||||
/* Listen on V4 if address type is v4 or if v6 and address is ::0.
|
|
||||||
* Listen on V6 if address type is v6 or if v4 and address is 0.0.0.0.
|
|
||||||
* In cases, where we listen on one space only, we close the other socket.
|
|
||||||
*/
|
|
||||||
address = (*env)->GetObjectField(env, this, psi_addressID);
|
address = (*env)->GetObjectField(env, this, psi_addressID);
|
||||||
if (IS_NULL(address)) {
|
if (IS_NULL(address)) {
|
||||||
JNU_ThrowNullPointerException(env, "socket address");
|
JNU_ThrowNullPointerException(env, "socket address");
|
||||||
@ -535,27 +421,15 @@ Java_java_net_TwoStacksPlainSocketImpl_socketListen
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr.sa.sa_family == AF_INET || IN6ADDR_ISANY(&addr.sa6)) {
|
if (addr.sa.sa_family == AF_INET) {
|
||||||
/* listen on v4 */
|
/* listen on v4 */
|
||||||
if (listen(fd, count) == -1) {
|
if (listen(fd, count) == -1) {
|
||||||
NET_ThrowCurrent(env, "listen failed");
|
NET_ThrowCurrent(env, "listen failed");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
NET_SocketClose (fd);
|
NET_SocketClose(fd);
|
||||||
(*env)->SetObjectField(env, this, psi_fdID, NULL);
|
(*env)->SetObjectField(env, this, psi_fdID, NULL);
|
||||||
}
|
}
|
||||||
if (ipv6_available() && !IS_NULL(fd1Obj)) {
|
|
||||||
fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
|
|
||||||
if (addr.sa.sa_family == AF_INET6 || addr.sa4.sin_addr.s_addr == INADDR_ANY) {
|
|
||||||
/* listen on v6 */
|
|
||||||
if (listen(fd1, count) == -1) {
|
|
||||||
NET_ThrowCurrent(env, "listen failed");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
NET_SocketClose (fd1);
|
|
||||||
(*env)->SetObjectField(env, this, psi_fd1ID, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -571,35 +445,31 @@ Java_java_net_TwoStacksPlainSocketImpl_socketAccept(JNIEnv *env, jobject this,
|
|||||||
jint port;
|
jint port;
|
||||||
jint timeout = (*env)->GetIntField(env, this, psi_timeoutID);
|
jint timeout = (*env)->GetIntField(env, this, psi_timeoutID);
|
||||||
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
|
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
|
||||||
jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
|
|
||||||
|
|
||||||
/* the FileDescriptor field on socket */
|
/* the FileDescriptor field on socket */
|
||||||
jobject socketFdObj;
|
jobject socketFdObj;
|
||||||
|
|
||||||
/* cache the Inet4/6Address classes */
|
/* cache the Inet4 class */
|
||||||
static jclass inet4Cls;
|
static jclass inet4Cls;
|
||||||
static jclass inet6Cls;
|
|
||||||
|
|
||||||
/* the InetAddress field on socket */
|
/* the InetAddress field on socket */
|
||||||
jobject socketAddressObj;
|
jobject socketAddressObj;
|
||||||
|
|
||||||
/* the fd int field on fdObj */
|
/* the fd int field on fdObj */
|
||||||
jint fd=-1, fd1=-1;
|
jint fd=-1;
|
||||||
|
|
||||||
SOCKETADDRESS sa;
|
SOCKETADDRESS sa;
|
||||||
jint len;
|
jint len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
|
if (IS_NULL(fdObj)) {
|
||||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
||||||
"Socket closed");
|
"Socket closed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!IS_NULL(fdObj)) {
|
|
||||||
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
|
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
|
||||||
}
|
|
||||||
if (!IS_NULL(fd1Obj)) {
|
|
||||||
fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
|
|
||||||
}
|
|
||||||
if (IS_NULL(socket)) {
|
if (IS_NULL(socket)) {
|
||||||
JNU_ThrowNullPointerException(env, "socket is null");
|
JNU_ThrowNullPointerException(env, "socket is null");
|
||||||
return;
|
return;
|
||||||
@ -611,72 +481,26 @@ Java_java_net_TwoStacksPlainSocketImpl_socketAccept(JNIEnv *env, jobject this,
|
|||||||
JNU_ThrowNullPointerException(env, "socket address or fd obj");
|
JNU_ThrowNullPointerException(env, "socket address or fd obj");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fd != -1 && fd1 != -1) {
|
|
||||||
fd_set rfds;
|
len = sizeof(struct sockaddr_in);
|
||||||
struct timeval t, *tP=&t;
|
if (timeout) {
|
||||||
int lastfd, res, fd2;
|
ret = NET_Timeout(fd, timeout);
|
||||||
FD_ZERO(&rfds);
|
if (ret == 0) {
|
||||||
FD_SET(fd,&rfds);
|
|
||||||
FD_SET(fd1,&rfds);
|
|
||||||
if (timeout) {
|
|
||||||
t.tv_sec = timeout/1000;
|
|
||||||
t.tv_usec = (timeout%1000)*1000;
|
|
||||||
} else {
|
|
||||||
tP = NULL;
|
|
||||||
}
|
|
||||||
res = select (fd, &rfds, NULL, NULL, tP);
|
|
||||||
if (res == 0) {
|
|
||||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
|
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
|
||||||
"Accept timed out");
|
"Accept timed out");
|
||||||
return;
|
return;
|
||||||
} else if (res == 1) {
|
} else if (ret == -1) {
|
||||||
fd2 = FD_ISSET(fd, &rfds)? fd: fd1;
|
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
|
||||||
} else if (res == 2) {
|
/* REMIND: SOCKET CLOSED PROBLEM */
|
||||||
/* avoid starvation */
|
/* NET_ThrowCurrent(env, "Accept failed"); */
|
||||||
lastfd = (*env)->GetIntField(env, this, psi_lastfdID);
|
return;
|
||||||
if (lastfd != -1) {
|
} else if (ret == -2) {
|
||||||
fd2 = lastfd==fd? fd1: fd;
|
JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
|
||||||
} else {
|
"operation interrupted");
|
||||||
fd2 = fd;
|
|
||||||
}
|
|
||||||
(*env)->SetIntField(env, this, psi_lastfdID, fd2);
|
|
||||||
} else {
|
|
||||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
|
||||||
"select failed");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fd2 == fd) { /* v4 */
|
|
||||||
len = sizeof(struct sockaddr_in);
|
|
||||||
} else {
|
|
||||||
len = sizeof(struct sockaddr_in6);
|
|
||||||
}
|
|
||||||
fd = fd2;
|
|
||||||
} else {
|
|
||||||
int ret;
|
|
||||||
if (fd1 != -1) {
|
|
||||||
fd = fd1;
|
|
||||||
len = sizeof(struct sockaddr_in6);
|
|
||||||
} else {
|
|
||||||
len = sizeof(struct sockaddr_in);
|
|
||||||
}
|
|
||||||
if (timeout) {
|
|
||||||
ret = NET_Timeout(fd, timeout);
|
|
||||||
if (ret == 0) {
|
|
||||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
|
|
||||||
"Accept timed out");
|
|
||||||
return;
|
|
||||||
} else if (ret == -1) {
|
|
||||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
|
|
||||||
/* REMIND: SOCKET CLOSED PROBLEM */
|
|
||||||
/* NET_ThrowCurrent(env, "Accept failed"); */
|
|
||||||
return;
|
|
||||||
} else if (ret == -2) {
|
|
||||||
JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
|
|
||||||
"operation interrupted");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = accept(fd, &sa.sa, &len);
|
fd = accept(fd, &sa.sa, &len);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
/* REMIND: SOCKET CLOSED PROBLEM */
|
/* REMIND: SOCKET CLOSED PROBLEM */
|
||||||
@ -692,65 +516,40 @@ Java_java_net_TwoStacksPlainSocketImpl_socketAccept(JNIEnv *env, jobject this,
|
|||||||
SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, 0);
|
SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, 0);
|
||||||
(*env)->SetIntField(env, socketFdObj, IO_fd_fdID, fd);
|
(*env)->SetIntField(env, socketFdObj, IO_fd_fdID, fd);
|
||||||
|
|
||||||
if (sa.sa.sa_family == AF_INET) {
|
if (sa.sa.sa_family != AF_INET) {
|
||||||
if (inet4Cls == NULL) {
|
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
||||||
jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
|
"Protocol family not supported");
|
||||||
if (c != NULL) {
|
return;
|
||||||
inet4Cls = (*env)->NewGlobalRef(env, c);
|
|
||||||
(*env)->DeleteLocalRef(env, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* fill up the remote peer port and address in the new socket structure
|
|
||||||
*/
|
|
||||||
if (inet4Cls != NULL) {
|
|
||||||
socketAddressObj = (*env)->NewObject(env, inet4Cls, ia4_ctrID);
|
|
||||||
} else {
|
|
||||||
socketAddressObj = NULL;
|
|
||||||
}
|
|
||||||
if (socketAddressObj == NULL) {
|
|
||||||
/*
|
|
||||||
* FindClass or NewObject failed so close connection and
|
|
||||||
* exist (there will be a pending exception).
|
|
||||||
*/
|
|
||||||
NET_SocketClose(fd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setInetAddress_addr(env, socketAddressObj, ntohl(sa.sa4.sin_addr.s_addr));
|
|
||||||
setInetAddress_family(env, socketAddressObj, java_net_InetAddress_IPv4);
|
|
||||||
(*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj);
|
|
||||||
} else {
|
|
||||||
/* AF_INET6 -> Inet6Address */
|
|
||||||
if (inet6Cls == 0) {
|
|
||||||
jclass c = (*env)->FindClass(env, "java/net/Inet6Address");
|
|
||||||
if (c != NULL) {
|
|
||||||
inet6Cls = (*env)->NewGlobalRef(env, c);
|
|
||||||
(*env)->DeleteLocalRef(env, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inet6Cls != NULL) {
|
|
||||||
socketAddressObj = (*env)->NewObject(env, inet6Cls, ia6_ctrID);
|
|
||||||
} else {
|
|
||||||
socketAddressObj = NULL;
|
|
||||||
}
|
|
||||||
if (socketAddressObj == NULL) {
|
|
||||||
/*
|
|
||||||
* FindClass or NewObject failed so close connection and
|
|
||||||
* exist (there will be a pending exception).
|
|
||||||
*/
|
|
||||||
NET_SocketClose(fd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setInet6Address_ipaddress(env, socketAddressObj, (char *)&sa.sa6.sin6_addr);
|
|
||||||
setInetAddress_family(env, socketAddressObj, java_net_InetAddress_IPv6);
|
|
||||||
setInet6Address_scopeid(env, socketAddressObj, sa.sa6.sin6_scope_id);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/* fields common to AF_INET and AF_INET6 */
|
|
||||||
|
|
||||||
|
if (inet4Cls == NULL) {
|
||||||
|
jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
|
||||||
|
if (c != NULL) {
|
||||||
|
inet4Cls = (*env)->NewGlobalRef(env, c);
|
||||||
|
(*env)->DeleteLocalRef(env, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fill up the remote peer port and address in the new socket structure
|
||||||
|
*/
|
||||||
|
if (inet4Cls != NULL) {
|
||||||
|
socketAddressObj = (*env)->NewObject(env, inet4Cls, ia4_ctrID);
|
||||||
|
} else {
|
||||||
|
socketAddressObj = NULL;
|
||||||
|
}
|
||||||
|
if (socketAddressObj == NULL) {
|
||||||
|
/*
|
||||||
|
* FindClass or NewObject failed so close connection and
|
||||||
|
* exit (there will be a pending exception).
|
||||||
|
*/
|
||||||
|
NET_SocketClose(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setInetAddress_addr(env, socketAddressObj, ntohl(sa.sa4.sin_addr.s_addr));
|
||||||
|
setInetAddress_family(env, socketAddressObj, java_net_InetAddress_IPv4);
|
||||||
|
(*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj);
|
||||||
port = ntohs ((u_short)GET_PORT(&sa));
|
port = ntohs ((u_short)GET_PORT(&sa));
|
||||||
(*env)->SetIntField(env, socket, psi_portID, (int)port);
|
(*env)->SetIntField(env, socket, psi_portID, (int)port);
|
||||||
port = (*env)->GetIntField(env, this, psi_localportID);
|
port = (*env)->GetIntField(env, this, psi_localportID);
|
||||||
@ -795,10 +594,9 @@ Java_java_net_TwoStacksPlainSocketImpl_socketClose0(JNIEnv *env, jobject this,
|
|||||||
jboolean useDeferredClose) {
|
jboolean useDeferredClose) {
|
||||||
|
|
||||||
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
|
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
|
||||||
jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
|
jint fd=-1;
|
||||||
jint fd=-1, fd1=-1;
|
|
||||||
|
|
||||||
if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
|
if (IS_NULL(fdObj)) {
|
||||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
|
||||||
"socket already closed");
|
"socket already closed");
|
||||||
return;
|
return;
|
||||||
@ -806,17 +604,10 @@ Java_java_net_TwoStacksPlainSocketImpl_socketClose0(JNIEnv *env, jobject this,
|
|||||||
if (!IS_NULL(fdObj)) {
|
if (!IS_NULL(fdObj)) {
|
||||||
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
|
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
|
||||||
}
|
}
|
||||||
if (!IS_NULL(fd1Obj)) {
|
|
||||||
fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
|
|
||||||
}
|
|
||||||
if (fd != -1) {
|
if (fd != -1) {
|
||||||
(*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
|
(*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
|
||||||
NET_SocketClose(fd);
|
NET_SocketClose(fd);
|
||||||
}
|
}
|
||||||
if (fd1 != -1) {
|
|
||||||
(*env)->SetIntField(env, fd1Obj, IO_fd_fdID, -1);
|
|
||||||
NET_SocketClose(fd1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -831,7 +622,7 @@ JNIEXPORT void JNICALL
|
|||||||
Java_java_net_TwoStacksPlainSocketImpl_socketNativeSetOption
|
Java_java_net_TwoStacksPlainSocketImpl_socketNativeSetOption
|
||||||
(JNIEnv *env, jobject this, jint cmd, jboolean on, jobject value)
|
(JNIEnv *env, jobject this, jint cmd, jboolean on, jobject value)
|
||||||
{
|
{
|
||||||
int fd, fd1;
|
int fd;
|
||||||
int level = 0, optname = 0, optlen = 0;
|
int level = 0, optname = 0, optlen = 0;
|
||||||
union {
|
union {
|
||||||
int i;
|
int i;
|
||||||
@ -843,8 +634,7 @@ Java_java_net_TwoStacksPlainSocketImpl_socketNativeSetOption
|
|||||||
* Get SOCKET and check that it hasn't been closed
|
* Get SOCKET and check that it hasn't been closed
|
||||||
*/
|
*/
|
||||||
fd = getFD(env, this);
|
fd = getFD(env, this);
|
||||||
fd1 = getFD1(env, this);
|
if (fd < 0) {
|
||||||
if (fd < 0 && fd1 < 0) {
|
|
||||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
|
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -901,12 +691,6 @@ Java_java_net_TwoStacksPlainSocketImpl_socketNativeSetOption
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fd1 != -1) {
|
|
||||||
if (setsockopt(fd1, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
|
|
||||||
sizeof(timeout)) < 0) {
|
|
||||||
NET_ThrowCurrent(env, "setsockopt SO_RCVTIMEO");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -980,12 +764,6 @@ Java_java_net_TwoStacksPlainSocketImpl_socketNativeSetOption
|
|||||||
NET_ThrowCurrent(env, "setsockopt");
|
NET_ThrowCurrent(env, "setsockopt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd1 != -1) {
|
|
||||||
if (NET_SetSockOpt(fd1, level, optname, (void *)&optval, optlen) < 0) {
|
|
||||||
NET_ThrowCurrent(env, "setsockopt");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -998,7 +776,7 @@ JNIEXPORT jint JNICALL
|
|||||||
Java_java_net_TwoStacksPlainSocketImpl_socketGetOption
|
Java_java_net_TwoStacksPlainSocketImpl_socketGetOption
|
||||||
(JNIEnv *env, jobject this, jint opt, jobject iaContainerObj)
|
(JNIEnv *env, jobject this, jint opt, jobject iaContainerObj)
|
||||||
{
|
{
|
||||||
int fd, fd1;
|
int fd;
|
||||||
int level = 0, optname = 0, optlen = 0;
|
int level = 0, optname = 0, optlen = 0;
|
||||||
union {
|
union {
|
||||||
int i;
|
int i;
|
||||||
@ -1009,18 +787,12 @@ Java_java_net_TwoStacksPlainSocketImpl_socketGetOption
|
|||||||
* Get SOCKET and check it hasn't been closed
|
* Get SOCKET and check it hasn't been closed
|
||||||
*/
|
*/
|
||||||
fd = getFD(env, this);
|
fd = getFD(env, this);
|
||||||
fd1 = getFD1(env, this);
|
|
||||||
memset((char *)&optval, 0, sizeof(optval));
|
memset((char *)&optval, 0, sizeof(optval));
|
||||||
|
|
||||||
if (fd < 0 && fd1 < 0) {
|
if (fd < 0) {
|
||||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
|
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (fd < 0) {
|
|
||||||
fd = fd1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For IPv6, we assume both sockets have the same setting always */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SO_BINDADDR isn't a socket option
|
* SO_BINDADDR isn't a socket option
|
||||||
@ -1035,13 +807,6 @@ Java_java_net_TwoStacksPlainSocketImpl_socketGetOption
|
|||||||
|
|
||||||
memset((char *)&sa, 0, len);
|
memset((char *)&sa, 0, len);
|
||||||
|
|
||||||
if (fd == -1) {
|
|
||||||
/* must be an IPV6 only socket. Case where both sockets are != -1
|
|
||||||
* is handled in java
|
|
||||||
*/
|
|
||||||
fd = getFD1 (env, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getsockname(fd, &sa.sa, &len) < 0) {
|
if (getsockname(fd, &sa.sa, &len) < 0) {
|
||||||
JNU_ThrowByNameWithMessageAndLastError
|
JNU_ThrowByNameWithMessageAndLastError
|
||||||
(env, JNU_JAVANETPKG "SocketException", "Error getting socket name");
|
(env, JNU_JAVANETPKG "SocketException", "Error getting socket name");
|
||||||
|
Loading…
Reference in New Issue
Block a user