You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2011/05/06 18:09:11 UTC

svn commit: r1100260 - in /commons/sandbox/runtime/trunk/src/main: java/org/apache/commons/runtime/net/ native/shared/

Author: mturk
Date: Fri May  6 16:09:10 2011
New Revision: 1100260

URL: http://svn.apache.org/viewvc?rev=1100260&view=rev
Log:
Simplify the native address code by making EndpointAddress.sa protected. It is visible but cannot be accessed outside Runtime, so safe

Modified:
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/EndpointAddress.java
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalEndpointAddress.java
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketAddress.java
    commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c

Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/EndpointAddress.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/EndpointAddress.java?rev=1100260&r1=1100259&r2=1100260&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/EndpointAddress.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/EndpointAddress.java Fri May  6 16:09:10 2011
@@ -18,30 +18,25 @@
 
 package org.apache.commons.runtime.net;
 
-import java.net.SocketAddress;
-
 /**
  * This class represents a network address.
  */
-public abstract class EndpointAddress extends SocketAddress
+public abstract class EndpointAddress
 {
-    private int  family;
     /**
-     * Native representation of @{code this} address.
-     * This is pointer to acr_sockaddr_t and is directly
-     * used by socket functions.
+     * Native representation of {@code this} address.
+     * This is pointer to Operating System sockaddr structure and is used
+     * used internally by socket functions.
      */
-    private long sa;
+    protected long sa;
 
-    private static native void    init0();
+    private int    family;
     private static native int     family0(long sa);
     private static native void    free0(long sa);
     private static native boolean hasnext0(long sa);
+    private static native boolean equals0(long sa1, long sa2);
     private static native String  name0(long sa);
 
-    static {
-        init0();
-    }
     /**
      * Creates a new EndpointAddress object.
      */
@@ -91,6 +86,26 @@ public abstract class EndpointAddress ex
     }
 
     /**
+     * Compares this {@code SocketAddress} to the specified object.
+     *
+     * @param other the reference {@code SocketAddress} with which to compare.
+     * @return  {@code true} if the class of this {@code SocketAddress} object and the
+     *      class of {@code other} are exactly equal; {@code false} otherwise.
+     */
+    @Override
+    public final boolean equals(Object other)
+    {
+        if (other == null)
+            return false;
+        if (other == this)
+            return true;
+        if (other instanceof EndpointAddress)
+            return equals0(sa, ((EndpointAddress)other).sa);
+        else
+           return false;
+    }
+
+    /**
      * Called by the garbage collector when the object is destroyed.
      * The class will free internal resources allocated by the Operating system.
      * @see Object#finalize()

Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalEndpointAddress.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalEndpointAddress.java?rev=1100260&r1=1100259&r2=1100260&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalEndpointAddress.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalEndpointAddress.java Fri May  6 16:09:10 2011
@@ -34,7 +34,9 @@ import org.apache.commons.runtime.Invali
 public final class LocalEndpointAddress extends EndpointAddress
 {
 
-    private native int sockaddr0(String name);
+    private long sa;
+    private native long sockaddr0(String name)
+        throws OutOfMemoryError, NetworkException;
     
     private LocalEndpointAddress()
     {
@@ -50,13 +52,7 @@ public final class LocalEndpointAddress 
         super(AddressFamily.LOCAL);
         if (name == null || name.length() == 0)
             throw new InvalidArgumentException();
-        int rc = sockaddr0(name);
-        if (rc != 0) {
-            if (rc == Errno.ENOMEM)
-                throw new OutOfMemoryError();
-            else
-                throw new NetworkException(Status.describe(rc));
-        }
+        super.sa = sockaddr0(name);
     }
 
     /**
@@ -69,13 +65,7 @@ public final class LocalEndpointAddress 
         String name = path.getPath();
         if (name == null || name.length() == 0)
             throw new InvalidArgumentException();
-        int rc = sockaddr0(name);
-        if (rc != 0) {
-            if (rc == Errno.ENOMEM)
-                throw new OutOfMemoryError();
-            else
-                throw new NetworkException(Status.describe(rc));
-        }
+        super.sa = sockaddr0(name);
     }
 
 }

Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketAddress.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketAddress.java?rev=1100260&r1=1100259&r2=1100260&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketAddress.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketAddress.java Fri May  6 16:09:10 2011
@@ -31,6 +31,8 @@ import org.apache.commons.runtime.Invali
  */
 public abstract class SocketAddress extends EndpointAddress
 {
+    // Hide parent field.
+    // private long sa;
     /**
      * First query for IPv4 addresses; only look
      * for IPv6 addresses if the first query failed;
@@ -47,17 +49,17 @@ public abstract class SocketAddress exte
     private static final int IPV6_ADDR_OK  = 2;
 
     /* Structure members */
-    private native String  hostname0();
-    private native String  servname0();
-    private native int     port0();
-
-    private native String  ipaddr0()
-        throws InvalidArgumentException;
-    private native int     sockaddr0(String hostname, int family, int port, int flags);
-    private native boolean equals0(SocketAddress other);
-    private native int     next0();
-    private native int     next1(SocketAddress next);
+    private static native String  hostname0(long sa);
+    private static native String  hostname1(long sa);
+    private static native String  servname0(long sa);
+    private static native int     port0(long sa);
+
+    private static native String  ipaddr0(long sa);
+    private static native long    sockaddr0(String hostname, int family, int port, int flags)
+        throws OutOfMemoryError, NetworkException;
+    private static native int     next0(long sa);
 
+    private String fqdn = null;
     /**
      * Creates an new object
      */
@@ -78,13 +80,7 @@ public abstract class SocketAddress exte
                NetworkException
     {
         super(family);
-        int rc = sockaddr0(host, family.valueOf(), port, flags);
-        if (rc != 0) {
-            if (rc == Errno.ENOMEM)
-                throw new OutOfMemoryError();
-            else
-                throw new NetworkException(Status.describe(rc));
-        }
+        super.sa = sockaddr0(host, family.valueOf(), port, flags);
     }
 
     protected SocketAddress(String host, AddressFamily family)
@@ -92,23 +88,34 @@ public abstract class SocketAddress exte
                NetworkException
     {
         super(family);
-        int rc = sockaddr0(host, family.valueOf(), 0, 0);
-        if (rc != 0) {
-            if (rc == Errno.ENOMEM)
-                throw new OutOfMemoryError();
-            else
-                throw new NetworkException(Status.describe(rc));
-        }
+        super.sa = sockaddr0(host, family.valueOf(), 0, 0);
     }
 
     /**
      * Gets the hostname of this socket.
-     *
+     * <p>
+     * The methods does not resolve the host name. If the address was
+     * not resloved already the method returns IP notion of the address.
+     * </p>
      * @return the socket endpoint hostname.
      */
     public final String getHostName()
     {
-        return hostname0();
+        return hostname0(super.sa);
+    }
+
+    /**
+     * Gets the fully qualified domain name of this address.
+     * <p>
+     * The methods resolves the host name.
+     * </p>
+     * @return the socket endpoint hostname.
+     */
+    public final String getCanonicalHostName()
+    {
+        if (fqdn == null)
+            fqdn = hostname1(super.sa);
+        return fqdn;
     }
 
     /**
@@ -118,7 +125,7 @@ public abstract class SocketAddress exte
      */
     public final String getServiceName()
     {
-        return servname0();
+        return servname0(super.sa);
     }
 
     /**
@@ -128,51 +135,7 @@ public abstract class SocketAddress exte
      */
     public final int getPort()
     {
-        return port0();
-    }
-
-    /**
-     * Gets the next address.
-     */
-    public SocketAddress next()
-    {
-        int family = next0();
-        if (family == -1)
-            return null;
-        AbstractSocketAddress next;
-        try {
-            next = new AbstractSocketAddress(AddressFamily.valueOf(family));
-        } catch (Exception e) {
-            // This should never happen.
-            // Throw OOM since this is the only logical reason.
-            throw new OutOfMemoryError();
-        }
-        int rc = next1(next);
-        if (rc != 0) {
-            next = null;
-            throw new RuntimeException("internal error");
-        }
-        return next;
-    }
-
-    /**
-     * Compares this {@code SocketAddress} to the specified object.
-     *
-     * @param other the reference {@code SocketAddress} with which to compare.
-     * @return  {@code true} if the class of this {@code SocketAddress} object and the
-     *      class of {@code other} are exactly equal; {@code false} otherwise.
-     */
-    @Override
-    public final boolean equals(Object other)
-    {
-        if (other == null)
-            return false;
-        if (other == this)
-            return true;
-        if (other instanceof SocketAddress)
-            return equals0((SocketAddress)other);
-        else
-           return false;
+        return port0(super.sa);
     }
 
 

Modified: commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c?rev=1100260&r1=1100259&r2=1100260&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c Fri May  6 16:09:10 2011
@@ -45,22 +45,6 @@
 # define SET_H_ERRNO(newval)
 #endif
 
-J_DECLARE_CLAZZ = {
-    INVALID_FIELD_OFFSET,
-    0,
-    0,
-    0,
-    ACR_NET_CP "EndpointAddress"
-};
-
-J_DECLARE_F_ID(0000) = {
-    INVALID_FIELD_OFFSET,
-    INVALID_FIELD_OFFSET,
-    0,
-    "sa",
-    "J"
-};
-
 /* const char *
  * inet_ntop4(src, dst, size)
  *      format an IPv4 address, more or less like inet_ntoa()
@@ -606,7 +590,7 @@ AcrFindAddresses(acr_sockaddr_t **sa, co
 
 #define GETHOSTBYNAME_BUFLEN 512
 int
-AcrGetNameInfo(char **hostname, acr_sockaddr_t *sockaddr, int flags)
+AcrGetNameInfo(const char **hostname, acr_sockaddr_t *sockaddr, int flags)
 {
     int rc;
     char tmphostname[NI_MAXHOST];
@@ -633,7 +617,7 @@ AcrGetNameInfo(char **hostname, acr_sock
 #endif
 
         rc = getnameinfo((const struct sockaddr *)&tmpsa, sizeof(tmpsa),
-                         tmphostname, NI_MAXHOST, NULL, 0,
+                         tmphostname, NI_MAXHOST, 0, 0,
                          flags != 0 ? flags : NI_NAMEREQD);
     }
     else if (sockaddr->family == AF_UNIX) {
@@ -642,7 +626,7 @@ AcrGetNameInfo(char **hostname, acr_sock
     }
     else
         rc = getnameinfo((const struct sockaddr *)&sockaddr->sa, sockaddr->salen,
-                         tmphostname, NI_MAXHOST, NULL, 0,
+                         tmphostname, NI_MAXHOST, 0, 0,
                          flags != 0 ? flags : NI_NAMEREQD);
     if (rc != 0) {
         *hostname = 0;
@@ -671,14 +655,68 @@ AcrGetNameInfo(char **hostname, acr_sock
     return 0;
 }
 
-ACR_NET_EXPORT(void, EndpointAddress, init0)(JNI_STDARGS)
+int
+AcrGetServInfo(const char **servname, acr_sockaddr_t *sockaddr, int flags)
 {
-    _clazzn.i = (jclass)(*env)->NewGlobalRef(env, obj);
-    if (_clazzn.i == 0)
-        return;
-    V_LOAD_IFIELD(0000);
-    UNSAFE_IFIELD(0000);
-    _clazzn.u = 1;
+    int rc;
+    char tmpservname[NI_MAXSERV];
+
+    /* don't know if it is portable for getnameinfo() to set h_errno;
+     * clear it then see if it was set */
+    SET_H_ERRNO(0);
+
+    /* For IPv4-mapped IPv6 addresses, drop down to IPv4 before calling
+     * getnameinfo() to avoid getnameinfo bugs (MacOS X, glibc).
+     */
+    if (sockaddr->family == AF_INET6 &&
+        IN6_IS_ADDR_V4MAPPED(&sockaddr->sa.sin6.sin6_addr)) {
+        struct sockaddr_in tmpsa;
+        tmpsa.sin_family = AF_INET;
+        tmpsa.sin_port   = 0;
+        tmpsa.sin_addr.s_addr = ((acr_u32_t *)sockaddr->ipaddr)[3];
+#ifdef SIN6_LEN
+        tmpsa.sin_len    = sizeof(tmpsa);
+#endif
+
+        rc = getnameinfo((const struct sockaddr *)&tmpsa, sizeof(tmpsa),
+                         0, 0, tmpservname, NI_MAXSERV, flags);
+    }
+    else if (sockaddr->family == AF_UNIX) {
+#if defined(WINDOWS)
+        *servname = "pipe";
+#else
+        *servname = "socket";
+#endif
+        return 0;
+    }
+    else
+        rc = getnameinfo((const struct sockaddr *)&sockaddr->sa, sockaddr->salen,
+                         0, 0, tmpservname, NI_MAXSERV, flags);
+    if (rc != 0) {
+        *servname = 0;
+
+#if !defined(WINDOWS)
+        /* something went wrong. Look at the EAI_ error code */
+        if (rc == EAI_SYSTEM) {
+            /* EAI_SYSTEM      System error returned in errno. */
+            /* IMHO, Implementations that set h_errno a simply broken. */
+            if (h_errno) /* for broken implementations which set h_errno */
+                return h_errno + ACR_OS_START_SYSERR;
+            else /* "normal" case */
+                return errno + ACR_OS_START_SYSERR;
+        }
+        else
+#endif
+        {
+#if defined(NEGATIVE_EAI)
+            if (rc < 0) rc = -rc;
+#endif
+            return rc + ACR_OS_START_EAIERR; /* return the EAI_ error */
+        }
+    }
+    strlcpy(sockaddr->servname, tmpservname, NI_MAXSERV);
+    *servname = sockaddr->servname;
+    return 0;
 }
 
 ACR_NET_EXPORT(void, EndpointAddress, free0)(JNI_STDARGS, jlong sa)
@@ -723,61 +761,41 @@ ACR_NET_EXPORT(jboolean, EndpointAddress
 ACR_NET_EXPORT(jstring, EndpointAddress, name0)(JNI_STDARGS, jlong sa)
 {
     char buf[256];
-    const char *name = 0;
+    const char *name = "(null)";
     acr_sockaddr_t *a = J2P(sa, acr_sockaddr_t *);
 
-    if (a == 0)
-        return 0;
-    if (a->hostname[0] == '\0') {
-        /* Return IP address representation
-         */
-        if (AcrGetSockaddrIp(buf, 256, a) == 0)
-            name = buf;
-    }
-    else
-        name = a->hostname;
-    return AcrNewJavaStringA(env, name);
-}
-
-acr_sockaddr_t *
-AcrGetSockaddr(JNI_STDARGS)
-{
-    jlong sa = 0;
-
-    if (J4FLD_OFF(0000) != INVALID_FIELD_OFFSET) {
-        char *oa = *(char **)obj;
-        if (oa != 0) {
-            char *fa = (oa + J4FLD_PTR(0000));
-            sa = *((jlong *)fa);
+    if (a != 0) {
+        if (a->hostname[0] == '\0') {
+            /* Return IP address representation
+             */
+            if (AcrGetSockaddrIp(buf, 256, a) == 0)
+                name = buf;
         }
+        else
+            name = a->hostname;
     }
-    else if (CLAZZ_LOADED) {
-        sa = GET_IFIELD_J(0000, obj);
-    }
-    return J2P(sa, acr_sockaddr_t *);
+    return AcrNewJavaStringA(env, name);
 }
 
-int
-AcrSetSockaddr(JNI_STDARGS, acr_sockaddr_t *sa)
+ACR_NET_EXPORT(jboolean, EndpointAddress, equals0)(JNI_STDARGS, jlong sa1, jlong sa2)
 {
-    int rc = ACR_EBADF;
+    acr_sockaddr_t *addr1 = J2P(sa1, acr_sockaddr_t *);
+    acr_sockaddr_t *addr2 = J2P(sa2, acr_sockaddr_t *);
 
-    if (J4FLD_OFF(0000) != INVALID_FIELD_OFFSET) {
-        char *oa = *(char **)obj;
-        if (oa != 0) {
-            char *fa = (oa + J4FLD_PTR(0000));
-            *((jlong *)fa) = P2J(sa);
-            rc = 0;
-        }
-    }
-    else if (CLAZZ_LOADED) {
-        SET_IFIELD_P(0000, obj, sa);
-        rc = 0;
+    if (addr1 == 0 || addr2 == 0)
+        return JNI_FALSE;
+    if (addr1->iplen == addr2->iplen &&
+        memcmp(addr1->ipaddr, addr2->ipaddr, addr1->iplen) == 0) {
+        return JNI_TRUE;
     }
-    return rc;
+    if (V4MAPPED_EQUAL(addr1, addr2))
+        return 1;
+    if (V4MAPPED_EQUAL(addr2, addr1))
+        return JNI_TRUE;
+    return JNI_FALSE; /* not equal */
 }
 
-ACR_NET_EXPORT(jint, LocalEndpointAddress, sockaddr0)(JNI_STDARGS, jstring hostname)
+ACR_NET_EXPORT(jlong, LocalEndpointAddress, sockaddr0)(JNI_STDARGS, jstring hostname)
 {
     acr_sockaddr_t *sa = 0;
     char *np;
@@ -829,57 +847,84 @@ ACR_NET_EXPORT(jint, LocalEndpointAddres
 #endif
     } DONE_WITH_STR(hostname);
 
-    if (rc == 0)
-        rc = AcrSetSockaddr(env, obj, sa);
-    return rc;
+    if (rc != 0)
+        ACR_THROW_NET_ERROR(rc);
+    return P2J(sa);;
 }
 
-ACR_NET_EXPORT(jstring, SocketAddress, hostname0)(JNI_STDARGS)
+ACR_NET_EXPORT(jstring, SocketAddress, hostname0)(JNI_STDARGS, jlong a)
 {
-    acr_sockaddr_t *sa = AcrGetSockaddr(env, obj);
+    acr_sockaddr_t *sa = J2P(a, acr_sockaddr_t *);
     if (sa != 0 && sa->hostname != '\0')
         return AcrNewJavaStringA(env, sa->hostname);
-    else
+    else {
+        char buf[256];
+        if (AcrGetSockaddrIp(buf, 256, sa) == 0)
+            return AcrNewJavaStringA(env, buf);
+    }
+    return 0;
+}
+
+ACR_NET_EXPORT(jstring, SocketAddress, hostname1)(JNI_STDARGS, jlong a)
+{
+    const char *host = 0;
+    int   rc;
+    acr_sockaddr_t *sa = J2P(a, acr_sockaddr_t *);
+
+    if (sa == 0)
         return 0;
+    rc = AcrGetNameInfo(&host, sa, 0);
+    if (rc == 0)
+        return AcrNewJavaStringA(env, host);
+    else {
+        char buf[256];
+        if (AcrGetSockaddrIp(buf, 256, sa) == 0)
+            return AcrNewJavaStringA(env, buf);
+    }
+    return 0;
 }
 
-ACR_NET_EXPORT(jstring, SocketAddress, servname0)(JNI_STDARGS)
+ACR_NET_EXPORT(jstring, SocketAddress, servname0)(JNI_STDARGS, jlong a)
 {
-    acr_sockaddr_t *sa = AcrGetSockaddr(env, obj);
+    const char *serv = 0;
+    int   rc;
+    acr_sockaddr_t *sa = J2P(a, acr_sockaddr_t *);
+
     if (sa != 0 && sa->servname != '\0')
         return AcrNewJavaStringA(env, sa->servname);
-    else
-        return 0;
+    else {
+        rc = AcrGetServInfo(&serv, sa, 0);
+        if (rc == 0)
+            return AcrNewJavaStringA(env, serv);
+        else
+            return 0;
+    }
 }
 
-ACR_NET_EXPORT(jstring, SocketAddress, ipaddr0)(JNI_STDARGS)
+ACR_NET_EXPORT(jstring, SocketAddress, ipaddr0)(JNI_STDARGS, jlong a)
 {
     char buf[256];
-    acr_sockaddr_t *sa = AcrGetSockaddr(env, obj);
+    acr_sockaddr_t *sa = J2P(a, acr_sockaddr_t *);
 
-    if (sa == 0) {
-        ACR_THROW(ACR_EX_ENULL, 0);
+    if (sa == 0)
         return 0;
-    }
     if (AcrGetSockaddrIp(buf, 256, sa) == 0)
         return AcrNewJavaStringA(env, buf);
-    else {
-        ACR_THROW_NET_ERROR(ACR_EINVAL);
+    else
         return 0;
-    }
 }
 
-ACR_NET_EXPORT(jint, SocketAddress, port0)(JNI_STDARGS)
+ACR_NET_EXPORT(jint, SocketAddress, port0)(JNI_STDARGS, jlong a)
 {
-    acr_sockaddr_t *sa = AcrGetSockaddr(env, obj);
+    acr_sockaddr_t *sa = J2P(a, acr_sockaddr_t *);
     if (sa != 0)
         return sa->port;
     else
         return 0;
 }
 
-ACR_NET_EXPORT(jint, SocketAddress, sockaddr0)(JNI_STDARGS, jstring hostname,
-                                               jint family, jint port, jint flags)
+ACR_NET_EXPORT(jlong, SocketAddress, sockaddr0)(JNI_STDARGS, jstring hostname,
+                                                jint family, jint port, jint flags)
 {
     acr_sockaddr_t *sa = 0;
     int ffamily = AF_UNSPEC;
@@ -902,7 +947,8 @@ ACR_NET_EXPORT(jint, SocketAddress, sock
     if ((masked = flags & (ACR_IPV4_ADDR_OK | ACR_IPV6_ADDR_OK))) {
         if (hostname == 0 || family != AF_UNSPEC ||
             masked == (ACR_IPV4_ADDR_OK | ACR_IPV6_ADDR_OK)) {
-            return ACR_EINVAL;
+            ACR_THROW(ACR_EX_EINVAL, 0);
+            return 0;
         }
     }
     
@@ -910,32 +956,14 @@ ACR_NET_EXPORT(jint, SocketAddress, sock
         rc = AcrFindAddresses(&sa, J2S(hostname), ffamily, port, flags);
     } DONE_WITH_STR(hostname);
 
-    if (rc == 0)
-        rc = AcrSetSockaddr(env, obj, sa);
-    return rc;
-}
-
-ACR_NET_EXPORT(jboolean, SocketAddress, equals0)(JNI_STDARGS, jobject sa2)
-{
-    acr_sockaddr_t *addr1 = AcrGetSockaddr(env, obj);
-    acr_sockaddr_t *addr2 = AcrGetSockaddr(env, sa2);
-
-    if (addr1 == 0 || addr2 == 0)
-        return JNI_FALSE;
-    if (addr1->iplen == addr2->iplen &&
-        memcmp(addr1->ipaddr, addr2->ipaddr, addr1->iplen) == 0) {
-        return JNI_TRUE;
-    }
-    if (V4MAPPED_EQUAL(addr1, addr2))
-        return 1;
-    if (V4MAPPED_EQUAL(addr2, addr1))
-        return JNI_TRUE;
-    return JNI_FALSE; /* not equal */
+    if (rc != 0)
+        ACR_THROW_NET_ERROR(rc);
+    return P2J(sa);
 }
 
-ACR_NET_EXPORT(jint, SocketAddress, next0)(JNI_STDARGS)
+ACR_NET_EXPORT(jint, SocketAddress, next0)(JNI_STDARGS, jlong a)
 {
-    acr_sockaddr_t *sa = AcrGetSockaddr(env, obj);
+    acr_sockaddr_t *sa = J2P(a, acr_sockaddr_t *);
 
     if (sa == 0 || sa->next == 0)
         return -1;
@@ -953,19 +981,3 @@ ACR_NET_EXPORT(jint, SocketAddress, next
     }
     return 0;
 }
-
-ACR_NET_EXPORT(jint, SocketAddress, next1)(JNI_STDARGS, jobject na)
-{
-    int rc;
-    acr_sockaddr_t *sa = AcrGetSockaddr(env, obj);
-
-    if (sa == 0 || sa->next == 0)
-        return ACR_EBADF;
-    /* Detach the next address so that
-     * cleanup can work.
-     */
-    rc = AcrSetSockaddr(env, na, sa->next);
-    if (rc == 0)
-        sa->next = 0;
-    return rc;
-}