summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dalvik/src/main/java/dalvik/system/BlockGuard.java5
-rw-r--r--luni/src/main/java/java/net/DatagramSocket.java11
-rw-r--r--luni/src/main/java/java/net/SocketOptions.java11
-rw-r--r--luni/src/main/java/libcore/io/ForwardingOs.java2
-rw-r--r--luni/src/main/java/libcore/io/IoUtils.java16
-rw-r--r--luni/src/main/java/libcore/io/Os.java2
-rw-r--r--luni/src/main/java/libcore/io/OsConstants.java1
-rw-r--r--luni/src/main/java/libcore/io/Posix.java2
-rw-r--r--luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java11
-rw-r--r--luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java3
-rw-r--r--luni/src/main/native/libcore_io_OsConstants.cpp1
-rw-r--r--luni/src/main/native/libcore_io_Posix.cpp24
-rw-r--r--luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp79
13 files changed, 47 insertions, 121 deletions
diff --git a/dalvik/src/main/java/dalvik/system/BlockGuard.java b/dalvik/src/main/java/dalvik/system/BlockGuard.java
index d3c5088..d212cfc 100644
--- a/dalvik/src/main/java/dalvik/system/BlockGuard.java
+++ b/dalvik/src/main/java/dalvik/system/BlockGuard.java
@@ -264,11 +264,6 @@ public final class BlockGuard {
return mNetwork.select(readFDs, writeFDs, numReadable, numWritable, timeout, flags);
}
- public void setSocketOption(FileDescriptor aFD, int opt, Object optVal)
- throws SocketException {
- mNetwork.setSocketOption(aFD, opt, optVal);
- }
-
public void close(FileDescriptor aFD) throws IOException {
// We exclude sockets without SO_LINGER so that apps can close their network connections
// in methods like onDestroy, which will run on the UI thread, without jumping through
diff --git a/luni/src/main/java/java/net/DatagramSocket.java b/luni/src/main/java/java/net/DatagramSocket.java
index ad9a551..95f1003 100644
--- a/luni/src/main/java/java/net/DatagramSocket.java
+++ b/luni/src/main/java/java/net/DatagramSocket.java
@@ -19,6 +19,9 @@ package java.net;
import java.io.IOException;
import java.nio.channels.DatagramChannel;
+import libcore.io.ErrnoException;
+import libcore.io.Libcore;
+import static libcore.io.OsConstants.*;
/**
* This class implements a UDP socket for sending and receiving {@code
@@ -377,7 +380,7 @@ public class DatagramSocket {
* via this socket are transmitted via the specified interface. Any
* packets received by this socket will come from the specified
* interface. Broadcast datagrams received on this interface will
- * be processed by this socket. {@see SocketOptions#SO_BINDTODEVICE}
+ * be processed by this socket. This corresponds to Linux's SO_BINDTODEVICE.
*
* @hide used by GoogleTV for DHCP
*/
@@ -385,7 +388,11 @@ public class DatagramSocket {
if (netInterface == null) {
throw new NullPointerException("networkInterface == null");
}
- impl.setOption(SocketOptions.SO_BINDTODEVICE, Integer.valueOf(netInterface.getIndex()));
+ try {
+ Libcore.os.setsockoptIfreq(impl.fd, SOL_SOCKET, SO_BINDTODEVICE, netInterface.getName());
+ } catch (ErrnoException errnoException) {
+ throw errnoException.rethrowAsSocketException();
+ }
}
/**
diff --git a/luni/src/main/java/java/net/SocketOptions.java b/luni/src/main/java/java/net/SocketOptions.java
index b2a1bb1..e23fc97 100644
--- a/luni/src/main/java/java/net/SocketOptions.java
+++ b/luni/src/main/java/java/net/SocketOptions.java
@@ -97,17 +97,6 @@ public interface SocketOptions {
public static final int SO_RCVBUF = 4098;
/**
- * This integer option can be used to bind a datagram socket to a
- * particular network interface. When this is done, only packets
- * received on the specified interface will be processed by the
- * socket. Packets sent via this socket will be transmitted by
- * the specified interface. The argument to this operation is the
- * network interface index.
- * @hide
- */
- public static final int SO_BINDTODEVICE = 8192;
-
- /**
* This boolean option specifies whether the kernel sends keepalive messages.
*/
public static final int SO_KEEPALIVE = 8;
diff --git a/luni/src/main/java/libcore/io/ForwardingOs.java b/luni/src/main/java/libcore/io/ForwardingOs.java
index 397fa10..8149e9a 100644
--- a/luni/src/main/java/libcore/io/ForwardingOs.java
+++ b/luni/src/main/java/libcore/io/ForwardingOs.java
@@ -73,7 +73,9 @@ public class ForwardingOs implements Os {
public void rename(String oldPath, String newPath) throws ErrnoException { os.rename(oldPath, newPath); }
public long sendfile(FileDescriptor outFd, FileDescriptor inFd, MutableLong inOffset, long byteCount) throws ErrnoException { return os.sendfile(outFd, inFd, inOffset, byteCount); }
public void setsockoptByte(FileDescriptor fd, int level, int option, int value) throws ErrnoException { os.setsockoptByte(fd, level, option, value); }
+ public void setsockoptIfreq(FileDescriptor fd, int level, int option, String value) throws ErrnoException { os.setsockoptIfreq(fd, level, option, value); }
public void setsockoptInt(FileDescriptor fd, int level, int option, int value) throws ErrnoException { os.setsockoptInt(fd, level, option, value); }
+ public void setsockoptIpMreqn(FileDescriptor fd, int level, int option, int value) throws ErrnoException { os.setsockoptIpMreqn(fd, level, option, value); }
public void setsockoptGroupReq(FileDescriptor fd, int level, int option, StructGroupReq value) throws ErrnoException { os.setsockoptGroupReq(fd, level, option, value); }
public void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException { os.setsockoptLinger(fd, level, option, value); }
public void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException { os.setsockoptTimeval(fd, level, option, value); }
diff --git a/luni/src/main/java/libcore/io/IoUtils.java b/luni/src/main/java/libcore/io/IoUtils.java
index 6334d2b..bf4e422 100644
--- a/luni/src/main/java/libcore/io/IoUtils.java
+++ b/luni/src/main/java/libcore/io/IoUtils.java
@@ -289,7 +289,7 @@ public final class IoUtils {
case SocketOptions.TCP_NODELAY:
return booleanFromInt(Libcore.os.getsockoptInt(fd, IPPROTO_TCP, TCP_NODELAY));
default:
- throw new SocketException("unknown socket option " + option);
+ throw new SocketException("Unknown socket option: " + option);
}
}
@@ -316,12 +316,11 @@ public final class IoUtils {
private static void setSocketOptionErrno(FileDescriptor fd, int option, Object value) throws SocketException {
switch (option) {
case SocketOptions.IP_MULTICAST_IF:
- // TODO
- org.apache.harmony.luni.platform.Platform.NETWORK.setSocketOption(fd, option, value);
- return;
+ throw new UnsupportedOperationException("Use IP_MULTICAST_IF2 on Android");
case SocketOptions.IP_MULTICAST_IF2:
- // TODO
- org.apache.harmony.luni.platform.Platform.NETWORK.setSocketOption(fd, option, value);
+ // Although IPv6 was cleaned up to use int, IPv4 uses an ip_mreqn containing an int.
+ Libcore.os.setsockoptIpMreqn(fd, IPPROTO_IP, IP_MULTICAST_IF, (Integer) value);
+ Libcore.os.setsockoptInt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, (Integer) value);
return;
case SocketOptions.IP_MULTICAST_LOOP:
// Although IPv6 was cleaned up to use int, IPv4 multicast loopback uses a byte.
@@ -382,10 +381,7 @@ public final class IoUtils {
Libcore.os.setsockoptGroupReq(fd, level, op, groupReq);
return;
default:
- // TODO
- org.apache.harmony.luni.platform.Platform.NETWORK.setSocketOption(fd, option, value);
- return;
- //throw new SocketException("unknown socket option " + option);
+ throw new SocketException("Unknown socket option: " + option);
}
}
diff --git a/luni/src/main/java/libcore/io/Os.java b/luni/src/main/java/libcore/io/Os.java
index 08b8564..6be0313 100644
--- a/luni/src/main/java/libcore/io/Os.java
+++ b/luni/src/main/java/libcore/io/Os.java
@@ -64,7 +64,9 @@ public interface Os {
public void rename(String oldPath, String newPath) throws ErrnoException;
public long sendfile(FileDescriptor outFd, FileDescriptor inFd, MutableLong inOffset, long byteCount) throws ErrnoException;
public void setsockoptByte(FileDescriptor fd, int level, int option, int value) throws ErrnoException;
+ public void setsockoptIfreq(FileDescriptor fd, int level, int option, String value) throws ErrnoException;
public void setsockoptInt(FileDescriptor fd, int level, int option, int value) throws ErrnoException;
+ public void setsockoptIpMreqn(FileDescriptor fd, int level, int option, int value) throws ErrnoException;
public void setsockoptGroupReq(FileDescriptor fd, int level, int option, StructGroupReq value) throws ErrnoException;
public void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException;
public void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException;
diff --git a/luni/src/main/java/libcore/io/OsConstants.java b/luni/src/main/java/libcore/io/OsConstants.java
index 616e60a..72a64f0 100644
--- a/luni/src/main/java/libcore/io/OsConstants.java
+++ b/luni/src/main/java/libcore/io/OsConstants.java
@@ -207,6 +207,7 @@ public final class OsConstants {
public static final int SOCK_SEQPACKET = placeholder();
public static final int SOCK_STREAM = placeholder();
public static final int SOL_SOCKET = placeholder();
+ public static final int SO_BINDTODEVICE = placeholder();
public static final int SO_BROADCAST = placeholder();
public static final int SO_DEBUG = placeholder();
public static final int SO_DONTROUTE = placeholder();
diff --git a/luni/src/main/java/libcore/io/Posix.java b/luni/src/main/java/libcore/io/Posix.java
index 72ebc62..682416e 100644
--- a/luni/src/main/java/libcore/io/Posix.java
+++ b/luni/src/main/java/libcore/io/Posix.java
@@ -73,7 +73,9 @@ public final class Posix implements Os {
public native void rename(String oldPath, String newPath) throws ErrnoException;
public native long sendfile(FileDescriptor outFd, FileDescriptor inFd, MutableLong inOffset, long byteCount) throws ErrnoException;
public native void setsockoptByte(FileDescriptor fd, int level, int option, int value) throws ErrnoException;
+ public native void setsockoptIfreq(FileDescriptor fd, int level, int option, String value) throws ErrnoException;
public native void setsockoptInt(FileDescriptor fd, int level, int option, int value) throws ErrnoException;
+ public native void setsockoptIpMreqn(FileDescriptor fd, int level, int option, int value) throws ErrnoException;
public native void setsockoptGroupReq(FileDescriptor fd, int level, int option, StructGroupReq value) throws ErrnoException;
public native void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException;
public native void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException;
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
index e5a511e..8d1c76f 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
@@ -96,17 +96,6 @@ public interface INetworkSystem {
int numReadable, int numWritable, long timeout, int[] flags)
throws SocketException;
- /*
- * Set the nominated socket option in the IP stack.
- *
- * @param fd the socket descriptor @param opt the option selector @param
- * optVal the nominated option value
- *
- * @throws SocketException if the option is invalid or cannot be set
- */
- public void setSocketOption(FileDescriptor fd, int opt, Object optVal)
- throws SocketException;
-
/**
* It is an error to close the same file descriptor from multiple threads
* concurrently.
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
index 3fc4ab4..1796507 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
@@ -91,9 +91,6 @@ final class OSNetworkSystem implements INetworkSystem {
public native void sendUrgentData(FileDescriptor fd, byte value);
- public native void setSocketOption(FileDescriptor fd, int opt, Object optVal)
- throws SocketException;
-
public native void close(FileDescriptor fd) throws IOException;
public native int write(FileDescriptor fd, byte[] data, int offset, int count)
diff --git a/luni/src/main/native/libcore_io_OsConstants.cpp b/luni/src/main/native/libcore_io_OsConstants.cpp
index 6165256..a461262 100644
--- a/luni/src/main/native/libcore_io_OsConstants.cpp
+++ b/luni/src/main/native/libcore_io_OsConstants.cpp
@@ -210,6 +210,7 @@ static void OsConstants_initConstants(JNIEnv* env, jclass c) {
initConstant(env, c, "SOCK_SEQPACKET", SOCK_SEQPACKET);
initConstant(env, c, "SOCK_STREAM", SOCK_STREAM);
initConstant(env, c, "SOL_SOCKET", SOL_SOCKET);
+ initConstant(env, c, "SO_BINDTODEVICE", SO_BINDTODEVICE);
initConstant(env, c, "SO_BROADCAST", SO_BROADCAST);
initConstant(env, c, "SO_DEBUG", SO_DEBUG);
initConstant(env, c, "SO_DONTROUTE", SO_DONTROUTE);
diff --git a/luni/src/main/native/libcore_io_Posix.cpp b/luni/src/main/native/libcore_io_Posix.cpp
index 883719c..cf1c56e 100644
--- a/luni/src/main/native/libcore_io_Posix.cpp
+++ b/luni/src/main/native/libcore_io_Posix.cpp
@@ -27,6 +27,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <net/if.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <sys/ioctl.h>
@@ -604,11 +605,32 @@ static void Posix_setsockoptByte(JNIEnv* env, jobject, jobject javaFd, jint leve
throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &byte, sizeof(byte))));
}
+static void Posix_setsockoptIfreq(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jstring value) {
+ ScopedUtfChars interfaceName(env, value);
+ if (interfaceName.c_str() == NULL) {
+ return;
+ }
+ struct ifreq req;
+ memset(&req, 0, sizeof(req));
+ strncpy(req.ifr_name, interfaceName.c_str(), sizeof(req.ifr_name));
+ req.ifr_name[sizeof(req.ifr_name) - 1] = '\0';
+ int fd = jniGetFDFromFileDescriptor(env, javaFd);
+ throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &req, sizeof(req))));
+}
+
static void Posix_setsockoptInt(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jint value) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &value, sizeof(value))));
}
+static void Posix_setsockoptIpMreqn(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jint value) {
+ ip_mreqn req;
+ memset(&req, 0, sizeof(req));
+ req.imr_ifindex = value;
+ int fd = jniGetFDFromFileDescriptor(env, javaFd);
+ throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &req, sizeof(req))));
+}
+
static void Posix_setsockoptGroupReq(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaGroupReq) {
struct group_req value;
@@ -788,7 +810,9 @@ static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Posix, rename, "(Ljava/lang/String;Ljava/lang/String;)V"),
NATIVE_METHOD(Posix, sendfile, "(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Llibcore/util/MutableLong;J)J"),
NATIVE_METHOD(Posix, setsockoptByte, "(Ljava/io/FileDescriptor;III)V"),
+ NATIVE_METHOD(Posix, setsockoptIfreq, "(Ljava/io/FileDescriptor;IILjava/lang/String;)V"),
NATIVE_METHOD(Posix, setsockoptInt, "(Ljava/io/FileDescriptor;III)V"),
+ NATIVE_METHOD(Posix, setsockoptIpMreqn, "(Ljava/io/FileDescriptor;III)V"),
NATIVE_METHOD(Posix, setsockoptGroupReq, "(Ljava/io/FileDescriptor;IILlibcore/io/StructGroupReq;)V"),
NATIVE_METHOD(Posix, setsockoptLinger, "(Ljava/io/FileDescriptor;IILlibcore/io/StructLinger;)V"),
NATIVE_METHOD(Posix, setsockoptTimeval, "(Ljava/io/FileDescriptor;IILlibcore/io/StructTimeval;)V"),
diff --git a/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp b/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
index 96c2c4b..9e8f4e8 100644
--- a/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
+++ b/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
@@ -40,10 +40,6 @@
#include <sys/un.h>
#include <unistd.h>
-#define JAVASOCKOPT_IP_MULTICAST_IF 16
-#define JAVASOCKOPT_IP_MULTICAST_IF2 31
-#define JAVASOCKOPT_SO_BINDTODEVICE 8192
-
/* constants for OSNetworkSystem_selectImpl */
#define SOCKET_OP_NONE 0
#define SOCKET_OP_READ 1
@@ -765,80 +761,6 @@ static jboolean OSNetworkSystem_selectImpl(JNIEnv* env, jclass,
translateFdSet(env, writeFDArray, countWriteC, writeFds, flagArray.get(), countReadC, SOCKET_OP_WRITE);
}
-template <typename T>
-static void setSocketOption(JNIEnv* env, const NetFd& fd, int level, int option, T* value) {
- int rc = setsockopt(fd.get(), level, option, value, sizeof(*value));
- if (rc == -1) {
- LOGE("setSocketOption(fd=%i, level=%i, option=%i) failed: %s (errno=%i)",
- fd.get(), level, option, strerror(errno), errno);
- jniThrowSocketException(env, errno);
- }
-}
-
-static void OSNetworkSystem_setSocketOption(JNIEnv* env, jobject, jobject fileDescriptor, jint option, jobject optVal) {
- NetFd fd(env, fileDescriptor);
- if (fd.isClosed()) {
- return;
- }
-
- int intVal;
- bool wasBoolean = false;
- if (env->IsInstanceOf(optVal, JniConstants::integerClass)) {
- intVal = intValue(env, optVal);
- } else if (env->IsInstanceOf(optVal, JniConstants::booleanClass)) {
- intVal = (int) booleanValue(env, optVal);
- wasBoolean = true;
- } else if (env->IsInstanceOf(optVal, JniConstants::inetAddressClass)) {
- // We use optVal directly as an InetAddress for IP_MULTICAST_IF.
- } else {
- jniThrowSocketException(env, EINVAL);
- return;
- }
-
- switch (option) {
- case JAVASOCKOPT_SO_BINDTODEVICE: {
- // intVal contains the interface index
- char ifname[IF_NAMESIZE];
-
- if (if_indextoname(intVal, ifname) == NULL) {
- jniThrowSocketException(env, ENODEV);
- } else {
- ifreq ifr;
-
- memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
- ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
- setSocketOption(env, fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr);
- }
- return;
- }
- case JAVASOCKOPT_IP_MULTICAST_IF:
- {
- sockaddr_storage sockVal;
- if (!env->IsInstanceOf(optVal, JniConstants::inetAddressClass) ||
- !inetAddressToSocketAddress(env, optVal, 0, &sockVal)) {
- return;
- }
- ip_mreqn mcast_req;
- memset(&mcast_req, 0, sizeof(mcast_req));
- mcast_req.imr_address = reinterpret_cast<sockaddr_in*>(&sockVal)->sin_addr;
- setSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_IF, &mcast_req);
- return;
- }
- case JAVASOCKOPT_IP_MULTICAST_IF2:
- // IP_MULTICAST_IF expects a pointer to an ip_mreqn struct.
- ip_mreqn multicastRequest;
- memset(&multicastRequest, 0, sizeof(multicastRequest));
- multicastRequest.imr_ifindex = intVal;
- setSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_IF, &multicastRequest);
- // IPV6_MULTICAST_IF expects a pointer to an integer.
- setSocketOption(env, fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &intVal);
- return;
- default:
- jniThrowSocketException(env, ENOPROTOOPT);
- }
-}
-
static void OSNetworkSystem_close(JNIEnv* env, jobject, jobject fileDescriptor) {
NetFd fd(env, fileDescriptor);
if (fd.isClosed()) {
@@ -869,7 +791,6 @@ static JNINativeMethod gMethods[] = {
NATIVE_METHOD(OSNetworkSystem, send, "(Ljava/io/FileDescriptor;[BIIILjava/net/InetAddress;)I"),
NATIVE_METHOD(OSNetworkSystem, sendDirect, "(Ljava/io/FileDescriptor;IIIILjava/net/InetAddress;)I"),
NATIVE_METHOD(OSNetworkSystem, sendUrgentData, "(Ljava/io/FileDescriptor;B)V"),
- NATIVE_METHOD(OSNetworkSystem, setSocketOption, "(Ljava/io/FileDescriptor;ILjava/lang/Object;)V"),
NATIVE_METHOD(OSNetworkSystem, write, "(Ljava/io/FileDescriptor;[BII)I"),
NATIVE_METHOD(OSNetworkSystem, writeDirect, "(Ljava/io/FileDescriptor;III)I"),
};