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/04 19:05:43 UTC
svn commit: r1099521 - in /commons/sandbox/runtime/trunk/src/main:
java/org/apache/commons/runtime/net/ native/include/acr/ native/os/unix/
native/os/win32/ native/shared/
Author: mturk
Date: Wed May 4 17:05:43 2011
New Revision: 1099521
URL: http://svn.apache.org/viewvc?rev=1099521&view=rev
Log:
Add core sockaddr wrapper class
Added:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AbstractSocketAddress.java (with props)
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AddressFamily.java (with props)
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalSocketAddress.java
commons/sandbox/runtime/trunk/src/main/native/include/acr/error.h
commons/sandbox/runtime/trunk/src/main/native/include/acr/netapi.h
commons/sandbox/runtime/trunk/src/main/native/include/acr/netdefs.h
commons/sandbox/runtime/trunk/src/main/native/os/unix/usock.c
commons/sandbox/runtime/trunk/src/main/native/os/win32/wpipe.c
commons/sandbox/runtime/trunk/src/main/native/shared/error.c
commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c
Added: 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=1099521&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AbstractSocketAddress.java (added)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AbstractSocketAddress.java Wed May 4 17:05:43 2011
@@ -0,0 +1,105 @@
+/*
+ * 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.File;
+import java.net.SocketException;
+import java.net.SocketAddress;
+import java.net.UnknownHostException;
+import org.apache.commons.runtime.Status;
+
+/**
+ * This class represents an socket address.
+ *
+ */
+abstract class AbstractSocketAddress extends SocketAddress
+{
+
+ /**
+ * First query for IPv4 addresses; only look
+ * for IPv6 addresses if the first query failed;
+ * only valid if family is UNSPEC and hostname
+ * isn't null; mutually exclusive with IPV6_ADDR_OK
+ */
+ public static final int IPV4_ADDR_OK = 1;
+ /**
+ * First query for IPv6 addresses; only look
+ * for IPv4 addresses if the first query failed;
+ * only valid if family is UNSPEC and hostname
+ * isn't null; mutually exclusive with IPV4_ADDR_OK
+ */
+ public static final int IPV6_ADDR_OK = 2;
+
+ private static native long alloc0()
+ throws OutOfMemoryError;
+ private static native void free0(long addr);
+ /* Structure members */
+ private static native String hostname0(long addr);
+ private static native String servname0(long addr);
+ private static native int port0(long addr);
+ private static native int family0(long addr);
+
+ private static native String ipaddr0(long addr);
+ private static native long geti0(String hostname, int family, int port, int flags)
+ throws UnknownHostException;
+ /**
+ * Native representation of @{code this} address.
+ * This is pointer to acr_sockaddr_t and is directly
+ * used by socket functions.
+ *
+ */
+ protected long addr;
+ /**
+ * True if this address has been resolved.
+ */
+ protected boolean resolved;
+
+ /**
+ * Creates an new object
+ */
+ protected AbstractSocketAddress()
+ {
+ addr = 0L;
+ resolved = false;
+ }
+
+ protected void create(String hostname, AddressFamily family, int port, int flags)
+ throws UnknownHostException
+ {
+ addr = geti0(hostname, family.valueOf(), port, flags);
+ }
+
+ /**
+ * Called by the garbage collector when the object is destroyed.
+ * The class will free internal resources allocated by the Operating system.
+ * @see Object#finalize()
+ * @throws Throwable the {@code Exception} raised by this method.
+ */
+ @Override
+ protected void finalize()
+ throws Throwable
+ {
+ try {
+ free0(addr);
+ } finally {
+ addr = 0L;
+ }
+ }
+
+}
Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AbstractSocketAddress.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AddressFamily.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AddressFamily.java?rev=1099521&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AddressFamily.java (added)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AddressFamily.java Wed May 4 17:05:43 2011
@@ -0,0 +1,53 @@
+/* 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;
+
+/** Represents the protocol family which will be used for communication.
+ */
+public enum AddressFamily
+{
+ /** Unspecified address family */
+ UNSPEC( 0),
+ /** IPv4 Internet protocols */
+ INET( 1),
+ /** IPv6 Internet protocols */
+ INET6( 2),
+ /** Local communication */
+ LOCAL( 3);
+
+
+ private int value;
+ private AddressFamily(int v)
+ {
+ value = v;
+ }
+
+ public int valueOf()
+ {
+ return value;
+ }
+
+ public static AddressFamily valueOf(int value)
+ {
+ for (AddressFamily e : values()) {
+ if (e.value == value)
+ return e;
+ }
+ return UNSPEC;
+ }
+
+}
Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/AddressFamily.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalSocketAddress.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalSocketAddress.java?rev=1099521&r1=1099520&r2=1099521&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalSocketAddress.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalSocketAddress.java Wed May 4 17:05:43 2011
@@ -19,73 +19,32 @@
package org.apache.commons.runtime.net;
import java.io.File;
-import java.net.SocketAddress;
import java.net.SocketException;
+import java.net.UnknownHostException;
import org.apache.commons.runtime.Memory;
import org.apache.commons.runtime.Status;
-public final class LocalSocketAddress extends SocketAddress
+public final class LocalSocketAddress extends AbstractSocketAddress
{
- private static native long addr0(String name);
- private static native String prefix0();
- private static final String prefix;
- static {
- prefix = prefix0();
-
- }
private LocalSocketAddress()
{
// No instance
}
- private long addr;
- private String path;
public LocalSocketAddress(String name)
+ throws UnknownHostException
{
if (name == null)
throw new IllegalArgumentException("name can't be null");
- StringBuilder pn = new StringBuilder(prefix);
- // Normalize the pipe or unix socket name
- //
- for (int i = 0; i < name.length(); i++) {
- char c = name.charAt(i);
- if (c == '\\' || c == '/')
- c = '_';
- pn.append(c);
- }
- path = pn.toString();
- addr = addr0(name);
+ create(name, AddressFamily.LOCAL, 0, 0);
}
public LocalSocketAddress(File path)
+ throws UnknownHostException
{
if (path == null)
throw new IllegalArgumentException("path can't be null");
- // path is presumed to be correctly
- // formatted.
- this.path = path.getPath();
- addr = addr0(this.path);
- }
-
- /**
- * Called by the garbage collector when the object is destroyed.
- * The class will free internal resources allocated by the Operating system.
- * @see Object#finalize()
- * @throws Throwable the {@code Exception} raised by this method.
- */
- @Override
- protected final void finalize()
- throws Throwable
- {
- if (addr != 0)
- Memory.free(addr);
- }
-
-
- @Override
- public String toString()
- {
- return this.path;
+ create(path.getPath(), AddressFamily.LOCAL, 0, 0);
}
}
Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr/error.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr/error.h?rev=1099521&r1=1099520&r2=1099521&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr/error.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr/error.h Wed May 4 17:05:43 2011
@@ -42,6 +42,8 @@ enum {
ACR_EX_ENULL, /* java/lang/NullPointerException */
ACR_EX_ENOSYS, /* java/lang/UnsupportedOperationException */
ACR_EX_EIO, /* java/io/IOException */
+ ACR_EX_ESOCK, /* java/net/SocketException */
+ ACR_EX_EHOST, /* java/net/UnknownHostException */
ACR_EX_EBADF, /* io/InvalidDescriptorException */
ACR_EX_EACCES, /* AccessDeniedException */
@@ -1342,6 +1344,9 @@ enum {
#define ACR_ENOMSG ENOMSG
#endif
+#if EAI_FAMILY < 0
+# define NEGATIVE_EAI 1
+#endif
#endif
#define ACR_OS_LAST_CANONERR (ACR_OS_START_CANONERR + 91)
Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr/netapi.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr/netapi.h?rev=1099521&r1=1099520&r2=1099521&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr/netapi.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr/netapi.h Wed May 4 17:05:43 2011
@@ -23,9 +23,9 @@
typedef struct acr_sockaddr_t acr_sockaddr_t;
struct acr_sockaddr_t {
/** The hostname */
- char hostname[256];
+ char hostname[NI_MAXHOST];
/** Either a string of the port number or the service name for the port */
- char servname[256];
+ char servname[NI_MAXSERV];
/** The numeric port */
int port;
/** The family */
Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr/netdefs.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr/netdefs.h?rev=1099521&r1=1099520&r2=1099521&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr/netdefs.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr/netdefs.h Wed May 4 17:05:43 2011
@@ -51,6 +51,12 @@
#define EAFNOSUPPORT WSAEAFNOSUPPORT
#endif
+#if !defined(NI_MAXHOST)
+# define NI_MAXHOST 1025
+#endif
+#if !defined(NI_MAXSERV)
+# define NI_MAXSERV 32
+#endif
#define ACR_IPV4_ADDR_OK 0x01
#define ACR_IPV6_ADDR_OK 0x02
Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/usock.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/usock.c?rev=1099521&r1=1099520&r2=1099521&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/usock.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/usock.c Wed May 4 17:05:43 2011
@@ -27,26 +27,3 @@
#include <poll.h>
#include <sys/un.h>
-ACR_NET_EXPORT(jstring, LocalSocketAddress, prefix0)(JNI_STDARGS)
-{
- return CSTR_TO_JSTRING(VAR_RUN_PATH "/");
-}
-
-ACR_NET_EXPORT(jlong, LocalSocketAddress, addr0)(JNI_STDARGS, jstring name)
-{
- struct sockaddr_un *un = 0;
-
- un = ACR_TALLOC(struct sockaddr_un);
- if (un == 0)
- return 0;
- WITH_CSTR(name) {
- size_t len = strlcpy(un->sun_path, J2S(name), sizeof(un->sun_path));
- if (len >= sizeof(un->sun_path)) {
- AcrFree(un);
- un = 0;
- ACR_THROW(ACR_EX_ERANGE, 0);
- }
-
- } DONE_WITH_STR(name);
- return P2J(un);
-}
Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/wpipe.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/wpipe.c?rev=1099521&r1=1099520&r2=1099521&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/wpipe.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/wpipe.c Wed May 4 17:05:43 2011
@@ -23,21 +23,3 @@
#include "acr/unsafe.h"
#include "arch_opts.h"
-ACR_NET_EXPORT(jstring, LocalSocketAddress, prefix0)(JNI_STDARGS)
-{
- return WSTR_TO_JSTRING(L"\\\\.\\pipe\\");
-}
-
-ACR_NET_EXPORT(jlong, LocalSocketAddress, addr0)(JNI_STDARGS, jstring name)
-{
- wchar_t *addr = 0;
-
- WITH_WSTR(name) {
- addr = wcsdup(J2S(name));
- if (addr == 0) {
- ACR_THROW(ACR_EX_ENOMEM, 0);
- }
-
- } DONE_WITH_STR(name);
- return P2J(addr);
-}
Modified: commons/sandbox/runtime/trunk/src/main/native/shared/error.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/error.c?rev=1099521&r1=1099520&r2=1099521&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/error.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/error.c Wed May 4 17:05:43 2011
@@ -36,6 +36,8 @@ static struct {
{ 0, "java/lang/NullPointerException" }, /* EISNULL */
{ 0, "java/lang/UnsupportedOperationException" }, /* ENOSYS */
{ 0, "java/io/IOException" }, /* I/O Error */
+ { 0, "java/net/SocketException" }, /* Net Error */
+ { 0, "java/net/UnknownHostException" }, /* Net Error */
{ 0, ACR_IO_CP "InvalidDescriptorException" }, /* EBADF */
{ 0, ACR_CLASS_PATH "AccessDeniedException" }, /* EACCESS */
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=1099521&r1=1099520&r2=1099521&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c Wed May 4 17:05:43 2011
@@ -38,7 +38,9 @@
# 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
@@ -378,6 +380,54 @@ AcrInetPton(int af, const char *src, voi
/* NOTREACHED */
}
+int
+AcrGetSockaddrIp(char *buf, int buflen, acr_sockaddr_t *sockaddr)
+{
+ if (AcrInetNtop(sockaddr->family, sockaddr->ipaddr, buf, buflen) == 0)
+ return ACR_ENOSPC;
+ if (sockaddr->family == AF_INET6 &&
+ IN6_IS_ADDR_V4MAPPED((struct in6_addr *)sockaddr->ipaddr) &&
+ buflen > 7) {
+ /* Number 7 here is strlen("::ffff:") */
+ /* This is an IPv4-mapped IPv6 address; drop the leading
+ * part of the address string so we're left with the familiar
+ * IPv4 format.
+ */
+ memmove(buf, buf + 7, strlen(buf + 7) + 1);
+ }
+ /* ensure NUL termination if the buffer is too short
+ */
+ buf[buflen - 1] = '\0';
+ return 0;
+}
+
+int
+AcrGetLocalAddr(int sockfd, acr_sockaddr_t *sockaddr)
+{
+ socklen_t salen = sizeof(sockaddr->sa);
+ if (getsockname(ACR_SOCKET(sockfd), (struct sockaddr *)&sockaddr->sa, &salen) < 0) {
+ return ACR_GET_NETOS_ERROR();
+ }
+ else {
+ /* XXX assumes sin_port and sin6_port at same offset */
+ sockaddr->port = ntohs(sockaddr->sa.sin.sin_port);
+ return 0;
+ }
+}
+
+int
+AcrGetRemoteAddr(int sockfd, acr_sockaddr_t *sockaddr)
+{
+ socklen_t salen = sizeof(sockaddr->sa);
+ if (getpeername(ACR_SOCKET(sockfd), (struct sockaddr *)&sockaddr->sa, &salen) < 0) {
+ return ACR_GET_NETOS_ERROR();
+ }
+ else {
+ /* XXX assumes sin_port and sin6_port at same offset */
+ sockaddr->port = ntohs(sockaddr->sa.sin.sin_port);
+ return 0;
+ }
+}
static void
sockaddr_vars_set(acr_sockaddr_t *addr, int family, int port)
@@ -496,11 +546,11 @@ call_resolver(acr_sockaddr_t **sa, const
if (!prev_sa) { /* first element in new list */
if (hostname != 0)
- strlcpy(new_sa->hostname, hostname, 256);
+ strlcpy(new_sa->hostname, hostname, NI_MAXHOST);
*sa = new_sa;
}
else {
- strlcpy(new_sa->hostname, prev_sa->hostname, 256);
+ strlcpy(new_sa->hostname, prev_sa->hostname, NI_MAXHOST);
prev_sa->next = new_sa;
}
@@ -537,8 +587,13 @@ AcrGetSockaddrInfo(acr_sockaddr_t **sa,
int family, int port, int flags)
{
int masked;
+#if defined(WINDOWS)
+ char *np;
+#endif
*sa = 0;
+ /* TODO: Move the param checks to java code
+ */
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)) {
@@ -566,7 +621,14 @@ AcrGetSockaddrInfo(acr_sockaddr_t **sa,
*sa = calloc(1, sizeof(acr_sockaddr_t));
if (*sa == 0)
return ACR_ENOMEM;
- strlcpy((*sa)->hostname, hostname, sizeof((*sa)->hostname));
+ strlcpy((*sa)->hostname, "\\\\.\\pipe\\", sizeof((*sa)->hostname));
+ strlcat((*sa)->hostname, hostname, sizeof((*sa)->hostname));
+ np = (*sa)->hostname + 9;
+ while (*np != '\0') {
+ if (*np == '/' || *np == '\\'|| *np == ' ')
+ *np = '_';
+ np++;
+ }
(*sa)->family = AF_LOCAL;
(*sa)->addrlen = ISIZEOF((*sa)->hostname);
(*sa)->ipaddr = &((*sa)->hostname);
@@ -585,6 +647,17 @@ AcrGetSockaddrInfo(acr_sockaddr_t **sa,
return find_addresses(sa, hostname, family, port, flags);
}
+void
+AcrFreeSockaddr(acr_sockaddr_t *sa)
+{
+ acr_sockaddr_t *sp = sa;
+ while (sp != 0) {
+ sa = sp->next;
+ AcrFree(sp);
+ sp = sa;
+ }
+}
+
int
AcrIsSockaddrEqual(const acr_sockaddr_t *addr1,
const acr_sockaddr_t *addr2)
@@ -606,9 +679,6 @@ int
AcrGetNameInfo(char **hostname, acr_sockaddr_t *sockaddr, int flags)
{
int rc;
-#if !defined(NI_MAXHOST)
-# define NI_MAXHOST 256
-#endif
char tmphostname[NI_MAXHOST];
/* don't know if it is portable for getnameinfo() to set h_errno;
@@ -666,7 +736,100 @@ AcrGetNameInfo(char **hostname, acr_sock
return rc + ACR_OS_START_EAIERR; /* return the EAI_ error */
}
}
- strlcpy(sockaddr->hostname, tmphostname, 256);
+ strlcpy(sockaddr->hostname, tmphostname, NI_MAXHOST);
*hostname = sockaddr->hostname;
return 0;
}
+
+ACR_NET_EXPORT(jlong, AbstractSocketAddress, alloc0)(JNI_STDARGS)
+{
+ return P2J(ACR_TALLOC(acr_sockaddr_t));
+}
+
+ACR_NET_EXPORT(void, AbstractSocketAddress, free0)(JNI_STDARGS, jlong sa)
+{
+ AcrFreeSockaddr(J2P(sa, acr_sockaddr_t *));
+}
+
+ACR_NET_EXPORT(jstring, AbstractSocketAddress, hostname0)(JNI_STDARGS, jlong sa)
+{
+ acr_sockaddr_t *a = J2P(sa, acr_sockaddr_t *);
+ if (a->hostname != '\0')
+ return AcrNewJavaStringA(env, a->hostname);
+ else
+ return 0;
+}
+
+ACR_NET_EXPORT(jstring, AbstractSocketAddress, servname0)(JNI_STDARGS, jlong sa)
+{
+ acr_sockaddr_t *a = J2P(sa, acr_sockaddr_t *);
+ if (a->servname != '\0')
+ return AcrNewJavaStringA(env, a->servname);
+ else
+ return 0;
+}
+
+ACR_NET_EXPORT(jstring, AbstractSocketAddress, ipaddr0)(JNI_STDARGS, jlong sa)
+{
+ char buf[256];
+ acr_sockaddr_t *a = J2P(sa, acr_sockaddr_t *);
+
+ if (AcrGetSockaddrIp(buf, 256, a) == 0)
+ return AcrNewJavaStringA(env, buf);
+ else {
+ ACR_THROW(ACR_EX_ENOMEM, ACR_ENOSPC);
+ return 0;
+ }
+}
+
+ACR_NET_EXPORT(jint, AbstractSocketAddress, port0)(JNI_STDARGS, jlong sa)
+{
+ acr_sockaddr_t *a = J2P(sa, acr_sockaddr_t *);
+ return a->port;
+}
+
+ACR_NET_EXPORT(jint, AbstractSocketAddress, family0)(JNI_STDARGS, jlong sa)
+{
+ acr_sockaddr_t *a = J2P(sa, acr_sockaddr_t *);
+ switch (a->family) {
+ case AF_INET:
+ return 1;
+ case AF_INET6:
+ return 2;
+ case AF_LOCAL:
+ return 3;
+ default:
+ break;
+ }
+ return 0;
+}
+
+ACR_NET_EXPORT(jlong, AbstractSocketAddress, geti0)(JNI_STDARGS, jstring hostname,
+ jint family, jint port, jint flags)
+{
+ acr_sockaddr_t *sa = 0;
+ int ffamily = AF_UNSPEC;
+ int rc = 0;
+
+ switch (family) {
+ case 1:
+ ffamily = AF_INET;
+ break;
+ case 2:
+ ffamily = AF_INET6;
+ break;
+ case 3:
+ ffamily = AF_LOCAL;
+ break;
+ }
+ WITH_CSTR(hostname) {
+ rc = AcrGetSockaddrInfo(&sa, J2S(hostname), ffamily, port, flags);
+ } DONE_WITH_STR(hostname);
+
+ if (rc != 0) {
+ /* XXX: Throw UnknownHostException?
+ */
+ ACR_THROW(ACR_EX_EHOST, rc);
+ }
+ return P2J(sa);
+}