Author: mturk
Date: Sun Jul 17 09:55:57 2011
New Revision: 1147568

URL: http://svn.apache.org/viewvc?rev=1147568&view=rev
Log:
Add SocketServerEndpoint

Added:
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Address.java
      - copied, changed from r1147481, 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AbstractAddress.java
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketServerEndpoint.java
   (with props)
Removed:
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AbstractAddress.java
Modified:
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AbstractSocketAddress.java
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Inet4SocketAddress.java
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Inet6SocketAddress.java
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/InetSocketAddress.java
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketDescriptor.java
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketEndpoint.java
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Array.java
    commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c
    commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c

Modified: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AbstractSocketAddress.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AbstractSocketAddress.java?rev=1147568&r1=1147567&r2=1147568&view=diff
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AbstractSocketAddress.java
 (original)
+++ 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AbstractSocketAddress.java
 Sun Jul 17 09:55:57 2011
@@ -58,6 +58,14 @@ final class AbstractSocketAddress extend
     }
 
     /**
+     * Copy constructor.
+     */
+    public AbstractSocketAddress(EndpointAddress ea)
+    {
+        super(ea.getFamily(), Address.dup(ea));
+    }
+
+    /**
      * Create a new socket address with given family.
      */
     public AbstractSocketAddress(AddressFamily family)

Copied: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Address.java
 (from r1147481, 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AbstractAddress.java)
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Address.java?p2=commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Address.java&p1=commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AbstractAddress.java&r1=1147481&r2=1147568&rev=1147568&view=diff
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AbstractAddress.java
 (original)
+++ 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Address.java
 Sun Jul 17 09:55:57 2011
@@ -21,10 +21,12 @@ package org.apache.commons.runtime.net;
 /**
  * This class represents a network address.
  */
-final class AbstractAddress extends EndpointAddress
+final class Address extends EndpointAddress
 {
-    public  static final  int   SIZE;
-    private static native int   size0();
+    public  static final  int     SIZE;
+    private static native int     size0();
+    private static native boolean isany0(byte[] ba);
+    private static native boolean resolved0(byte[] ba);
 
     static {
         SIZE = size0();
@@ -33,7 +35,7 @@ final class AbstractAddress extends Endp
     /**
      * Creates a new EndpointAddress object.
      */
-    private AbstractAddress()
+    private Address()
     {
         // No instance
     }
@@ -42,12 +44,15 @@ final class AbstractAddress extends Endp
      * Creates a new AbstractAddress object.
      * @param family The address family to which the endpoint belongs.
      */
-    public AbstractAddress(AddressFamily family, byte[] sa)
+    public Address(AddressFamily family, byte[] sa)
     {
         super(family);
         this.sa = sa;
     }
 
+    /**
+     * Helper for accessing the EndpointAddress protected address field.
+     */
     public static void sockaddr(EndpointAddress e, byte[] ba)
     {
         e.sa = ba;
@@ -63,4 +68,21 @@ final class AbstractAddress extends Endp
         return new byte[SIZE];
     }
 
+    public static byte[] dup(final EndpointAddress e)
+    {
+        byte[] ba = alloc();
+        System.arraycopy(e.sa, 0, ba, 0, SIZE);
+        return ba;
+    }
+
+    public static boolean isany(final EndpointAddress e)
+    {
+        return isany0(e.sa);
+    }
+
+    public static boolean resolved(final EndpointAddress e)
+    {
+        return resolved0(e.sa);
+    }
+
 }

Modified: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Inet4SocketAddress.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Inet4SocketAddress.java?rev=1147568&r1=1147567&r2=1147568&view=diff
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Inet4SocketAddress.java
 (original)
+++ 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Inet4SocketAddress.java
 Sun Jul 17 09:55:57 2011
@@ -44,7 +44,7 @@ public final class Inet4SocketAddress ex
         if (hostname == null || hostname.length() == 0)
             throw new IllegalArgumentException(Local.sm.get("addr.EHOSTNAME"));
         byte[] sa = AbstractSocketAddress.getnameinfo(AddressFamily.INET, 
hostname, null, port);
-        AbstractAddress.sockaddr(this, sa);
+        Address.sockaddr(this, sa);
     }
 
     public Inet4SocketAddress(String hostname)

Modified: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Inet6SocketAddress.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Inet6SocketAddress.java?rev=1147568&r1=1147567&r2=1147568&view=diff
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Inet6SocketAddress.java
 (original)
+++ 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Inet6SocketAddress.java
 Sun Jul 17 09:55:57 2011
@@ -43,7 +43,7 @@ public final class Inet6SocketAddress ex
         if (hostname == null || hostname.length() == 0)
             throw new IllegalArgumentException(Local.sm.get("addr.EHOSTNAME"));
         byte[] sa = AbstractSocketAddress.getnameinfo(AddressFamily.INET6, 
hostname, null, port);
-        AbstractAddress.sockaddr(this, sa);
+        Address.sockaddr(this, sa);
     }
 
     public Inet6SocketAddress(String hostname)

Modified: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/InetSocketAddress.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/InetSocketAddress.java?rev=1147568&r1=1147567&r2=1147568&view=diff
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/InetSocketAddress.java
 (original)
+++ 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/InetSocketAddress.java
 Sun Jul 17 09:55:57 2011
@@ -45,7 +45,7 @@ public class InetSocketAddress extends S
         if (port < 0 || port > 65535)
             throw new InvalidRangeException(Local.sm.get("port.ERANGE"));
         byte[] sa = AbstractSocketAddress.getnameinfo(AddressFamily.UNSPEC, 
hostname, null, port);
-        AbstractAddress.sockaddr(this, sa);
+        Address.sockaddr(this, sa);
     }
 
     public InetSocketAddress(String hostname)
@@ -59,7 +59,7 @@ public class InetSocketAddress extends S
     {        
         if (port < 0 || port > 65535)
             throw new InvalidRangeException(Local.sm.get("port.ERANGE"));
-        int salen = AbstractAddress.SIZE;
+        int salen = Address.SIZE;
         byte[] sa = AbstractSocketAddress.getnameinfo(AddressFamily.UNSPEC, 
hostname, null, port);
         int naddr = sa.length / salen;
         SocketAddress[] a = new SocketAddress[naddr];

Modified: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketDescriptor.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketDescriptor.java?rev=1147568&r1=1147567&r2=1147568&view=diff
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketDescriptor.java
 (original)
+++ 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketDescriptor.java
 Sun Jul 17 09:55:57 2011
@@ -46,7 +46,9 @@ final class SocketDescriptor extends Des
     private static native int     optset1(long fd, int opt, boolean val);
     private static native int     optset2(long fd, int opt, boolean val);
     private static native int     shutdown0(long fd, int how);
-
+    private static native int     getlocal0(long fd, byte[] sa);
+    private static native int     getremote0(long fd, byte[] sa);
+    
     public SocketDescriptor()
     {
     }
@@ -127,6 +129,30 @@ final class SocketDescriptor extends Des
             throw new ClosedDescriptorException();
     }
 
+    public byte[] getLocalAddress()
+        throws IOException
+    {
+        if (closed())
+            throw new ClosedDescriptorException();
+        byte[] sa = Address.alloc();
+        int rc = getlocal0(fd, sa);
+        if (rc != 0)
+            throw new SocketException(Status.describe(rc));
+        return sa;
+    }
+
+    public byte[] getRemoteAddress()
+        throws IOException
+    {
+        if (closed())
+            throw new ClosedDescriptorException();
+        byte[] sa = Address.alloc();
+        int rc = getremote0(fd, sa);
+        if (rc != 0)
+            throw new SocketException(Status.describe(rc));
+        return sa;
+    }
+
     public void setTimeout(int timeout)
         throws IOException
     {

Modified: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketEndpoint.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketEndpoint.java?rev=1147568&r1=1147567&r2=1147568&view=diff
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketEndpoint.java
 (original)
+++ 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketEndpoint.java
 Sun Jul 17 09:55:57 2011
@@ -35,10 +35,10 @@ import org.apache.commons.runtime.Status
 public class SocketEndpoint extends Connection
 {
     private final SocketDescriptor      sd;
-    private SocketAddress               ea; // Remote address
-    private SocketAddress               sa; // Local  address
     private SelectionKeyImpl            key;
-    private SocketStream                stream = null;
+    private SocketAddress               ea        = null; // Remote address
+    private SocketAddress               sa        = null; // Local  address
+    private SocketStream                stream    = null;
     private boolean                     connected = false;
 
     /**
@@ -75,8 +75,8 @@ public class SocketEndpoint extends Conn
         SocketAddress sockaddr = (SocketAddress)endpoint;
         if (sd.closed())
             sd.create(sockaddr.getFamily(), SocketType.STREAM);
-
-        ea = sockaddr;
+        if (Address.resolved(sockaddr))
+            ea = sockaddr;
         connected = true;
     }
 
@@ -205,6 +205,28 @@ public class SocketEndpoint extends Conn
         return connected;
     }
 
+    public synchronized SocketAddress getLocalAddress()
+        throws IOException
+    {
+        if (closed())
+            throw new ClosedDescriptorException();
+        if (ea != null)
+            return ea;
+        ea = new AbstractSocketAddress(sd.getLocalAddress());
+        return ea;
+    }
+
+    public synchronized SocketAddress getRemoteAddress()
+        throws IOException
+    {
+        if (closed())
+            throw new ClosedDescriptorException();
+        if (sa != null)
+            return sa;
+        sa = new AbstractSocketAddress(sd.getRemoteAddress());
+        return sa;
+    }
+
     public boolean hasOption(SocketOption key)
         throws IOException
     {

Added: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketServerEndpoint.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketServerEndpoint.java?rev=1147568&view=auto
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketServerEndpoint.java
 (added)
+++ 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketServerEndpoint.java
 Sun Jul 17 09:55:57 2011
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.commons.runtime.net;
+
+import java.io.Closeable;
+import java.io.Flushable;
+import java.io.IOException;
+import java.io.SyncFailedException;
+import java.net.SocketException;
+import org.apache.commons.runtime.io.ClosedDescriptorException;
+import org.apache.commons.runtime.io.Descriptor;
+import org.apache.commons.runtime.io.OperationInProgressException;
+import org.apache.commons.runtime.io.OperationWouldBlockException;
+import org.apache.commons.runtime.OverflowException;
+import org.apache.commons.runtime.Status;
+
+/**
+ * This class represents inet protocol server endpoint.
+ * <p>
+ * </p>
+ */
+public class SocketServerEndpoint extends ServerEndpoint<SocketEndpoint>
+{
+    private static final int            LISTEN_BACKLOG =  50;
+    private final SocketDescriptor      sd;
+    private SelectionKeyImpl            key;
+    private SocketAddress               sa;
+    private boolean                     bound    = false;
+    private boolean                     blocking = true;
+    private final Object                mutex    = new Object();
+
+    /**
+     * Creates a new unbound local server endpoint.
+     */
+    public SocketServerEndpoint()
+    {
+        super(EndpointType.SOCKET);
+        this.sd = new SocketDescriptor();
+    }
+
+    /**
+     * Creates a new local server endpoint from the
+     * given socket descriptor.
+     */
+    public SocketServerEndpoint(SocketDescriptor sd)
+    {
+        super(EndpointType.SOCKET);
+        if (sd == null)
+            throw new NullPointerException();
+        this.sd = sd;
+    }
+
+    @Override
+    public Descriptor descriptor()
+    {
+        return sd;
+    }
+
+    @Override
+    public boolean isBlocking()
+        throws IOException
+    {
+        return blocking;
+    }
+
+    @Override
+    public Descriptor configureBlocking(boolean block)
+        throws IllegalBlockingModeException,
+               IOException
+    {
+        if (key != null && key.selected)
+            throw new IllegalBlockingModeException();
+        // Blocking mode must be set before the
+        // actual server endpoint is created.
+        if (sd.valid())
+            throw new IllegalBlockingModeException();
+        blocking = block;
+        return sd;
+    }
+
+
+    @Override
+    public void close()
+        throws IOException
+    {
+        synchronized(mutex) {
+            if (sd.valid()) {
+                if (key != null && key.selected) {
+                    try {
+                        key.cancel();
+                    } catch (Exception e) {
+                        // Ignore selector exceptions
+                    }
+                }
+                sd.close();
+            }
+            if (key != null) {
+                key.reset();
+                key = null;
+            }
+        }
+    }
+
+    @Override
+    public SelectionKey keyFor(Selector selector)
+    {
+        if (key != null && key.selector == selector && key.ievents != 0)
+            return key;
+        else
+            return null;
+    }
+
+    @Override
+    public SelectionKey register(Selector selector, int ops, Object att)
+        throws ClosedSelectorException,
+               IllegalSelectorException,
+               ClosedDescriptorException,
+               OverflowException,
+               IOException
+    {
+        ops = ops & 0x000f;
+        if (sd.closed())
+            throw new ClosedDescriptorException();
+        AbstractSelector sel = (AbstractSelector)selector;
+        //
+        // If key.ievents is zero, this means that the
+        // key was invalidated by Selector.close().
+        // In that case create a new key instance.
+        if (key == null || key.ievents == 0)
+            key = new SelectionKeyImpl(sel, this);
+        if (key.selector != sel)
+            throw new IllegalSelectorException();
+        if (att != null)
+            key.attach(att);
+        return key.queue(ops);
+    }
+
+    private static native int           bind0(long fd, byte[] sa, int backlog);
+    private static native long          accept0(long fd, byte[] sa, boolean 
block)
+        throws SocketException;
+
+    @Override
+    public synchronized void bind(EndpointAddress endpoint, int backlog)
+        throws IOException
+    {
+        if (bound)
+            throw new IOException(Local.sm.get("endpoint.EBOUND"));
+        if (sd.closed())
+            sd.create(endpoint.getFamily(), SocketType.STREAM, blocking);
+        sa = new AbstractSocketAddress(endpoint);
+        if (backlog == 0)
+            backlog = LISTEN_BACKLOG;
+        int rc = bind0(sd.fd(), sa.sockaddr(), backlog);
+        if (rc != 0) {
+            sd.close();
+            throw new IOException(Status.describe(rc));
+        }
+        bound = true;
+    }
+
+    @Override
+    public SocketEndpoint accept()
+        throws IOException
+    {
+        return accept(blocking);
+    }
+
+    @Override
+    public SocketEndpoint accept(boolean blocking)
+        throws IOException
+    {
+        if (sd.closed())
+            throw new ClosedDescriptorException();
+        long fd = accept0(sd.fd(), sa.sockaddr(), blocking);
+        SocketDescriptor ad = new SocketDescriptor(fd);
+        return new SocketEndpoint(ad, sa);
+    }
+
+    @Override
+    public synchronized void setTimeout(int timeout)
+        throws IOException
+    {
+        sd.setTimeout(timeout);
+        blocking = sd.hasOption(SocketOption.NONBLOCK) == false;
+    }
+
+    @Override
+    public synchronized final boolean closed()
+    {
+        return sd.closed();
+    }
+
+}

Propchange: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketServerEndpoint.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Array.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Array.java?rev=1147568&r1=1147567&r2=1147568&view=diff
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Array.java
 (original)
+++ 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Array.java
 Sun Jul 17 09:55:57 2011
@@ -197,7 +197,7 @@ public final class Array
     }
 
     /**
-     * Duplicate array to byte attay..
+     * Duplicate array to byte array..
      * <p>
      * Duplicates the number of {@code length} elements of the Array {@code 
src}
      * starting at the offset {@code srcPos} into the new byte array.

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c?rev=1147568&r1=1147567&r2=1147568&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c Sun Jul 17 
09:55:57 2011
@@ -25,6 +25,11 @@
 #include <poll.h>
 #include <sys/un.h>
 
+#define SOCKADDR_CAST(BA) \
+    (acr_sockaddr_t *)AcrGetArrayCritical(env, (BA))
+#define SOCKADDR_RELEASE(BA, SA) \
+    AcrReleaseArrayCritical(env, (BA), (SA))
+
 ACR_NET_EXPORT(jlong, SocketDescriptor, socket0)(JNI_STDARGS, jint saf,
                                                  jint stype, jboolean block)
 {
@@ -254,3 +259,34 @@ ACR_NET_EXPORT(jboolean, SocketDescripto
     else
         return JNI_TRUE;
 }
+
+ACR_NET_EXPORT(jint, SocketServerEndpoint, bind0)(JNI_STDARGS, jlong fp,
+                                                  jbyteArray ba,
+                                                  jint backlog)
+{
+    static char any[16] = { 0 }; /* big enough for IPv4 or IPv6 */    
+    int rc = 0;
+    acr_sockaddr_t *aa = SOCKADDR_CAST(ba);
+    acr_sd_t *fd       = J2P(fp, acr_sd_t *);
+
+    if (bind(fd->s, (const struct sockaddr *)&aa->sa, aa->salen) == -1) {
+        /* bind failed.
+         */
+        rc = ACR_GET_NETOS_ERROR();
+    }
+    else {
+        /* Check for ephemeral port and "any" address.
+         * The provided byte array is duplicate of the original
+         * so it can be modified.
+         */
+        if (aa->port == 0 || memcmp(&aa->sa.sin.sin_addr, any, aa->iplen) == 
0) {
+            /* Get the real address for the bound socket.
+             */
+            rc = AcrGetLocalAddr(fd, aa);
+        }
+    }
+    SOCKADDR_RELEASE(ba, aa);
+    if (rc == 0 && listen(fd->s, backlog) == -1)
+        rc = ACR_GET_NETOS_ERROR();
+    return rc;
+}

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=1147568&r1=1147567&r2=1147568&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c Sun Jul 17 
09:55:57 2011
@@ -40,9 +40,7 @@
 # else
 #  define SET_H_ERRNO(newval) h_errno = (newval)
 # endif
-# define ACR_SOCKET(s) (s)
 #else
-# define ACR_SOCKET(s) (SOCKET)(s)
 # define SET_H_ERRNO(newval)
 #endif
 
@@ -191,11 +189,10 @@ inet_ntop6(const unsigned char *src, cha
     /*
      * Check for overflow, copy, and we're done.
      */
-    if ((int)(tp - tmp) > size) {
+    if (strlcpy(dst, tmp, size) >= size) {
         ACR_SET_OS_ERROR(ACR_ENOSPC);
         return 0;
     }
-    strcpy(dst, tmp);
     return dst;
 }
 
@@ -411,7 +408,7 @@ sockaddr_to_ipstr(char *buf, int buflen,
 int
 AcrGetLocalAddr(acr_sd_t *sockfd, acr_sockaddr_t *sockaddr)
 {
-    socklen_t salen = sizeof(sockaddr->sa);
+    socklen_t salen = ISIZEOF(sockaddr->sa);
     if (getsockname(sockfd->s, (struct sockaddr *)&sockaddr->sa, &salen) == 
SOCKET_ERROR) {
         return ACR_GET_NETOS_ERROR();
     }
@@ -425,7 +422,7 @@ AcrGetLocalAddr(acr_sd_t *sockfd, acr_so
 int
 AcrGetRemoteAddr(acr_sd_t *sockfd, acr_sockaddr_t *sockaddr)
 {
-    socklen_t salen = sizeof(sockaddr->sa);
+    socklen_t salen = ISIZEOF(sockaddr->sa);
     if (getpeername(sockfd->s, (struct sockaddr *)&sockaddr->sa, &salen) == 
SOCKET_ERROR) {
         return ACR_GET_NETOS_ERROR();
     }
@@ -891,11 +888,91 @@ ACR_NET_EXPORT(jbyteArray, LocalEndpoint
     return ba;
 }
 
-ACR_NET_EXPORT(jint, AbstractAddress, size0)(JNI_STDARGS)
+ACR_NET_EXPORT(jint, Address, size0)(JNI_STDARGS)
 {
     return ISIZEOF(acr_sockaddr_t);
 }
 
+ACR_NET_EXPORT(jboolean, Address, isany0)(JNI_STDARGS, jbyteArray a)
+{
+    static char any[16] = { 0 }; /* big enough for IPv4 or IPv6 */
+    jboolean rv = JNI_FALSE;
+    acr_sockaddr_t *sa = SOCKADDR_CAST(a);
+
+    if (sa != 0) {
+        if (sa->family != AF_LOCAL) {
+            if (memcmp(&sa->sa.sin.sin_addr, any, sa->iplen) == 0)
+                rv = JNI_TRUE;
+        }
+    }
+    SOCKADDR_RELEASE(a, sa);
+    return rv;
+}
+
+ACR_NET_EXPORT(jboolean, Address, resolved0)(JNI_STDARGS, jbyteArray a)
+{
+    static char any[16] = { 0 }; /* big enough for IPv4 or IPv6 */
+    jboolean rv = JNI_FALSE;
+    acr_sockaddr_t *sa = SOCKADDR_CAST(a);
+
+    if (sa != 0) {
+        if (sa->family == AF_LOCAL) {
+            if (sa->hostname[0] != 0)
+                rv = JNI_TRUE;
+        }
+        else if (sa->port != 0) {
+            if (memcmp(&sa->sa.sin.sin_addr, any, sa->iplen) != 0)
+                rv = JNI_TRUE;
+        }
+    }
+    SOCKADDR_RELEASE(a, sa);
+    return rv;
+}
+
+ACR_NET_EXPORT(jint, SocketDescriptor, getlocal0)(JNI_STDARGS, jlong sp,
+                                                 jbyteArray a)
+{
+    int rc = ACR_EINVAL;
+    acr_sd_t       *sd = J2P(sp, acr_sd_t *);
+    acr_sockaddr_t *sa = SOCKADDR_CAST(a);
+
+    if (sd != 0 && sa != 0) {
+        socklen_t salen = ISIZEOF(sa->sa);
+        if (getsockname(sd->s, (struct sockaddr *)&sa->sa, &salen) == 
SOCKET_ERROR) {
+            rc = ACR_GET_NETOS_ERROR();
+        }
+        else {
+            /* XXX assumes sin_port and sin6_port at same offset */
+            sa->port = ntohs(sa->sa.sin.sin_port);
+            rc = 0;
+        }
+    }
+    SOCKADDR_RELEASE(a, sa);
+    return rc;
+}
+
+ACR_NET_EXPORT(jint, SocketDescriptor, getremote0)(JNI_STDARGS, jlong sp,
+                                                   jbyteArray a)
+{
+    int rc = ACR_EINVAL;
+    acr_sd_t       *sd = J2P(sp, acr_sd_t *);
+    acr_sockaddr_t *sa = SOCKADDR_CAST(a);
+
+    if (sd != 0 && sa != 0) {
+        socklen_t salen = ISIZEOF(sa->sa);
+        if (getpeername(sd->s, (struct sockaddr *)&sa->sa, &salen) == 
SOCKET_ERROR) {
+            rc = ACR_GET_NETOS_ERROR();
+        }
+        else {
+            /* XXX assumes sin_port and sin6_port at same offset */
+            sa->port = ntohs(sa->sa.sin.sin_port);
+            rc = 0;
+        }
+    }
+    SOCKADDR_RELEASE(a, sa);
+    return rc;
+}
+
 ACR_NET_EXPORT(jstring, SocketAddress, hostname0)(JNI_STDARGS, jbyteArray a)
 {
     jstring rv = 0;


Reply via email to