Skip to content

Commit

Permalink
Upgrade NIO Datagram Channel Implementation with help from GitPod
Browse files Browse the repository at this point in the history
  • Loading branch information
Jessie Lesbian committed Jul 30, 2021
1 parent 17d7503 commit 478dcb1
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 18 deletions.
16 changes: 8 additions & 8 deletions openjdk/java/net/net_util_md.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import static ikvm.internal.JNI.*;
import static ikvm.internal.Winsock.*;

final class net_util_md
public final class net_util_md
{
private net_util_md() { }

Expand Down Expand Up @@ -121,7 +121,7 @@ private static class WinsockError
* Since winsock doesn't have the equivalent of strerror(errno)
* use table to lookup error text for the error.
*/
static SocketException NET_ThrowNew(int errorNum, String msg)
public static SocketException NET_ThrowNew(int errorNum, String msg)
{
int i;
int table_size = winsock_errors.length;
Expand Down Expand Up @@ -652,7 +652,7 @@ static int NET_BindV6(ipv6bind b, boolean exclBind) {
static int NET_InetAddressToSockaddr(JNIEnv env, InetAddress iaObj, int port, SOCKETADDRESS him, boolean v4MappedAddress) {
return NET_InetAddressToSockaddr(iaObj, port, him, v4MappedAddress);
}
static int NET_InetAddressToSockaddr(InetAddress iaObj, int port, SOCKETADDRESS him, boolean v4MappedAddress) {
public static int NET_InetAddressToSockaddr(InetAddress iaObj, int port, SOCKETADDRESS him, boolean v4MappedAddress) {
if (iaObj.holder().family == InetAddress.IPv4) {
him.set(new IPEndPoint(new IPAddress(htonl(iaObj.holder().address) & 0xFFFFFFFFL), port));
return 0;
Expand All @@ -669,7 +669,7 @@ static int NET_InetAddressToSockaddr(InetAddress iaObj, int port, SOCKETADDRESS
}
}

static int NET_GetPortFromSockaddr(SOCKETADDRESS him) {
public static int NET_GetPortFromSockaddr(SOCKETADDRESS him) {
return ntohs(GET_PORT(him));
}

Expand Down Expand Up @@ -732,7 +732,7 @@ static boolean IN6ADDR_ISANY(SOCKETADDRESS him) {
return b == 0;
}

static boolean NET_SockaddrEqualsInetAddress(SOCKETADDRESS him, InetAddress iaObj) {
public static boolean NET_SockaddrEqualsInetAddress(SOCKETADDRESS him, InetAddress iaObj) {
int family = iaObj.holder().family == InetAddress.IPv4 ? AF_INET : AF_INET6;

if (him.sa_family == AF_INET6) {
Expand Down Expand Up @@ -780,11 +780,11 @@ static boolean NET_SockaddrEqualsInetAddress(SOCKETADDRESS him, InetAddress iaOb
}
}

static InetAddress NET_SockaddrToInetAddress(JNIEnv env, SOCKETADDRESS him, int[] port) {
public static InetAddress NET_SockaddrToInetAddress(JNIEnv env, SOCKETADDRESS him, int[] port) {
return NET_SockaddrToInetAddress(him, port);
}

static InetAddress NET_SockaddrToInetAddress(SOCKETADDRESS him, int[] port) {
public static InetAddress NET_SockaddrToInetAddress(SOCKETADDRESS him, int[] port) {
InetAddress iaObj;
if (him.sa_family == AF_INET6) {
byte[] caddr = him.him6.sin6_addr;
Expand Down Expand Up @@ -818,7 +818,7 @@ static boolean IN6_IS_ADDR_MULTICAST(in6_addr address) {
return (address.s6_bytes()[0] & 0xff) == 0xff;
}

static final class SOCKETADDRESS implements IIPEndPointWrapper {
public static final class SOCKETADDRESS implements IIPEndPointWrapper {
final SOCKETADDRESS him = this;
final SOCKETADDRESS him4 = this;
final SOCKETADDRESS him6 = this;
Expand Down
137 changes: 127 additions & 10 deletions openjdk/sun/nio/ch/DatagramChannelImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
import java.util.*;
import sun.net.ResourceManager;
import sun.net.ExtendedOptionsImpl;
import static ikvm.internal.JNI.*;
import static ikvm.internal.Winsock.*;
import static java.net.net_util_md.*;

/**
* An implementation of DatagramChannels.
Expand Down Expand Up @@ -1122,22 +1125,136 @@ public int getFDVal() {

// -- Native methods --

private static native void initIDs();
private static void disconnect0(FileDescriptor fd1, boolean isIPv6) throws IOException{
cli.System.Net.Sockets.Socket fd = fd1.getSocket();
SOCKETADDRESS sa = new SOCKETADDRESS();
int rv = ikvm.internal.Winsock.connect(fd, sa);
if (rv == SOCKET_ERROR) {
throw NET_ThrowNew(WSAGetLastError(), "connect");
} else{
WSAIoctl(fd, SIO_UDP_CONNRESET, true);
}
}

private static native void disconnect0(FileDescriptor fd, boolean isIPv6)
throws IOException;
static boolean purgeOutstandingICMP(cli.System.Net.Sockets.Socket fd)
{
boolean got_icmp = false;
byte[] buf = new byte[1];
fd_set tbl = new fd_set();
timeval t = new timeval();
SOCKETADDRESS rmtaddr = null;

/*
* Peek at the queue to see if there is an ICMP port unreachable. If there
* is then receive it.
*/
FD_ZERO(tbl);
FD_SET(fd, tbl);
while(true) {
if (select(tbl, null, null, t) <= 0) {
break;
}
if (recvfrom(fd, buf, 1, MSG_PEEK,
rmtaddr) != JVM_IO_ERR) {
break;
}
if (WSAGetLastError() != WSAECONNRESET) {
/* some other error - we don't care here */
break;
}

recvfrom(fd, buf, 1, 0, rmtaddr);
got_icmp = JNI_TRUE;
}

return got_icmp;
}
static final int JVM_IO_ERR = -1;
static final int JVM_IO_INTR = -2;
private int receive0(FileDescriptor fd0, byte[] buf, int pos, int len, boolean connected) throws IOException{
cli.System.Net.Sockets.Socket fd = fd0.getSocket();
SOCKETADDRESS sa = new SOCKETADDRESS();
boolean retry = true;
int n = SOCKET_ERROR;
InetAddress senderAddr;
while (retry){
retry = false;
n = recvfrom(fd, buf, len, 0, sa);

if (n == SOCKET_ERROR) {
int theErr = WSAGetLastError();
if (theErr == WSAEMSGSIZE) {
/* Spec says the rest of the data will be discarded... */
n = len;
} else if (theErr == WSAECONNRESET) {
purgeOutstandingICMP(fd);
if (connected) {
throw new java.net.PortUnreachableException();
} else {
retry = true;
}
} else if (theErr == WSAEWOULDBLOCK) {
return IOStatus.UNAVAILABLE;
} else {
throw NET_ThrowNew(theErr, "Socket receive failed to fucking work!");
}
}
}
/*
* If the source address and port match the cached address
* and port in DatagramChannelImpl then we don't need to
* create InetAddress and InetSocketAddress objects.
*/
senderAddr = cachedSenderInetAddress;
if (senderAddr != null) {
if (!NET_SockaddrEqualsInetAddress(sa, senderAddr)) {
senderAddr = null;
} else {
int port = cachedSenderPort;
if (port != NET_GetPortFromSockaddr(sa)) {
senderAddr = null;
}
}
}
if (senderAddr == null) {

int[] portptr = new int[1];
InetAddress ia = NET_SockaddrToInetAddress(sa, portptr);
int port = portptr[0];
InetSocketAddress isa = new InetSocketAddress(ia, port);
if(isa == null){
return IOStatus.THROWN;
} else{
// update cachedSenderInetAddress/cachedSenderPort
cachedSenderInetAddress = ia;
cachedSenderPort = NET_GetPortFromSockaddr(sa);
sender = isa;
}
}
return n;
}

private native int receive0(FileDescriptor fd, byte[] buf, int pos, int len,
boolean connected)
throws IOException;
private int send0(boolean preferIPv6, FileDescriptor fdo, byte[] buf, int pos, int len, InetAddress addr, int port) throws IOException{
cli.System.Net.Sockets.Socket fd = fdo.getSocket();
SOCKETADDRESS sa = new SOCKETADDRESS();
if (NET_InetAddressToSockaddr(addr, port, sa, preferIPv6) != 0) {
return IOStatus.THROWN;
}

private native int send0(boolean preferIPv6, FileDescriptor fd, byte[] buf, int pos,
int len, InetAddress addr, int port)
throws IOException;
int rv = sendto(fd, buf, len, 0, 0, sa);
if (rv == SOCKET_ERROR) {
int theErr = WSAGetLastError();
if (theErr == WSAEWOULDBLOCK) {
return IOStatus.UNAVAILABLE;
} else{
throw NET_ThrowNew(theErr, "Socket receive failed to fucking work!");
}
}
return rv;
}

static {
IOUtil.load();
initIDs();
}

}

0 comments on commit 478dcb1

Please sign in to comment.