diff --git a/app/build.gradle b/app/build.gradle index 1d73fd07a3b2980ff8fd550758d3bf24c0b32c93..290474ed7369eeead6f3d893d9039a8f122604c2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -33,6 +33,7 @@ android { dependencies { compile project(':routerjars') + compile project(':client') compile 'com.android.support:support-v4:19.1.0' compile 'com.android.support:appcompat-v7:19.1.0' compile files('libs/androidplot-core-0.6.0.jar') diff --git a/client/src/main/java/net/i2p/client/DomainServerSocket.java b/client/src/main/java/net/i2p/client/DomainServerSocket.java new file mode 100644 index 0000000000000000000000000000000000000000..b1ac6b6f9342fea45df98b4c426a90ed14955d3a --- /dev/null +++ b/client/src/main/java/net/i2p/client/DomainServerSocket.java @@ -0,0 +1,172 @@ +package net.i2p.client; + +import android.net.LocalServerSocket; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketException; +import java.nio.channels.ServerSocketChannel; + +/** + * Bridge to LocalServerSocket. + * <p/> + * accept() returns a real Socket (a DomainSocket). + * <p/> + * DomainServerSockets are always bound. + * You may not create an unbound DomainServerSocket. + * Create this through the DomainSocketFactory. + * + * @author str4d + * @since 0.9.14 + */ +public class DomainServerSocket extends ServerSocket { + private final LocalServerSocket mLocalServerSocket; + private final DomainSocketFactory mDomainSocketFactory; + private volatile boolean mClosed; + + /** + * @throws IOException + */ + public DomainServerSocket(String name, DomainSocketFactory domainSocketFactory) throws IOException { + mLocalServerSocket = new LocalServerSocket(name); + mDomainSocketFactory = domainSocketFactory; + } + + /** + * @throws IOException + */ + @Override + public Socket accept() throws IOException { + return mDomainSocketFactory.createSocket(mLocalServerSocket.accept()); + } + + /** + * @throws UnsupportedOperationException always + */ + @Override + public void bind(SocketAddress endpoint) { + throw new UnsupportedOperationException(); + } + + /** + * @throws UnsupportedOperationException always + */ + @Override + public void bind(SocketAddress endpoint, int backlog) { + throw new UnsupportedOperationException(); + } + + /** + * @throws IOException + */ + @Override + public void close() throws IOException { + mLocalServerSocket.close(); + mClosed = true; + } + + /** + * @return null always + */ + @Override + public ServerSocketChannel getChannel() { + return null; + } + + /** + * @return null always + */ + @Override + public InetAddress getInetAddress() { + return null; + } + + /** + * @return -1 always + */ + @Override + public int getLocalPort() { + return -1; + } + + /** + * @return null always + */ + @Override + public SocketAddress getLocalSocketAddress() { + return null; + } + + /** + * @throws UnsupportedOperationException always + */ + @Override + public int getReceiveBufferSize() { + throw new UnsupportedOperationException(); + } + + /** + * @return false always + */ + @Override + public boolean getReuseAddress() { + return false; + } + + /** + * @throws UnsupportedOperationException always + */ + @Override + public int getSoTimeout() { + throw new UnsupportedOperationException(); + } + + /** + * @return true always + */ + @Override + public boolean isBound() { + return true; + } + + @Override + public boolean isClosed() { + return mClosed; + } + + /** + * Does nothing. + */ + @Override + public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) { + } + + /** + * Does nothing. + */ + @Override + public void setReceiveBufferSize(int size) { + } + + /** + * Does nothing. + */ + @Override + public void setReuseAddress(boolean on) { + } + + /** + * Does nothing. + */ + @Override + public void setSoTimeout(int timeout) throws SocketException { + } + + @Override + public String toString() { + return mLocalServerSocket.toString(); + } +} diff --git a/client/src/main/java/net/i2p/client/DomainSocket.java b/client/src/main/java/net/i2p/client/DomainSocket.java new file mode 100644 index 0000000000000000000000000000000000000000..0697f477cef58c918b421cb27da680a2b88c7ab2 --- /dev/null +++ b/client/src/main/java/net/i2p/client/DomainSocket.java @@ -0,0 +1,363 @@ +package net.i2p.client; + +import android.net.LocalSocket; +import android.net.LocalSocketAddress; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketException; +import java.nio.channels.SocketChannel; + +/** + * Bridge to LocalSocket. + * <p/> + * DomainSockets are always bound, and always start out connected. + * You may not create an unbound DomainSocket. + * Create this through the DomainSocketManager. + * + * @author str4d + * @since 0.9.14 + */ +public class DomainSocket extends Socket { + private final LocalSocket mLocalSocket; + + /** + * @throws IOException + * @throws UnsupportedOperationException always + */ + DomainSocket(String name) throws IOException { + mLocalSocket = new LocalSocket(); + mLocalSocket.connect(new LocalSocketAddress(name)); + } + + /** + * @param localSocket the LocalSocket to wrap. + */ + DomainSocket(LocalSocket localSocket) { + mLocalSocket = localSocket; + } + + /** + * @throws UnsupportedOperationException always + */ + @Override + public void bind(SocketAddress bindpoint) { + throw new UnsupportedOperationException(); + } + + /** + * @throws IOException + */ + @Override + public void close() throws IOException { + mLocalSocket.close(); + } + + /** + * @throws UnsupportedOperationException always + */ + @Override + public void connect(SocketAddress endpoint) { + throw new UnsupportedOperationException(); + } + + /** + * @throws UnsupportedOperationException always + */ + @Override + public void connect(SocketAddress endpoint, int timeout) { + throw new UnsupportedOperationException(); + } + + /** + * @return null always, unimplemented + */ + @Override + public SocketChannel getChannel() { + return null; + } + + /** + * @return null always + */ + @Override + public InetAddress getInetAddress() { + return null; + } + + /** + * @throws IOException + */ + @Override + public InputStream getInputStream() throws IOException { + return mLocalSocket.getInputStream(); + } + + /** + * @throws UnsupportedOperationException always + */ + @Override + public boolean getKeepAlive() { + throw new UnsupportedOperationException(); + } + + /** + * @return null always + */ + @Override + public InetAddress getLocalAddress() { + return null; + } + + /** + * @return -1 always + */ + @Override + public int getLocalPort() { + return -1; + } + + /** + * @return null always + */ + @Override + public SocketAddress getLocalSocketAddress() { + return null; + } + + /** + * @return false always + */ + @Override + public boolean getOOBInline() { + return false; + } + + /** + * @throws IOException + */ + @Override + public OutputStream getOutputStream() throws IOException { + return mLocalSocket.getOutputStream(); + } + + /** + * @return -1 always + */ + @Override + public int getPort() { + return -1; + } + + @Override + public int getReceiveBufferSize() throws SocketException { + try { + return mLocalSocket.getReceiveBufferSize(); + } catch (IOException e) { + throw new SocketException(e.getLocalizedMessage()); + } + } + + /** + * @throws UnsupportedOperationException always + */ + @Override + public SocketAddress getRemoteSocketAddress() { + throw new UnsupportedOperationException(); + } + + /** + * @return false always + */ + @Override + public boolean getReuseAddress() { + return false; + } + + /** + * @throws SocketException + */ + @Override + public int getSendBufferSize() throws SocketException { + try { + return mLocalSocket.getSendBufferSize(); + } catch (IOException e) { + throw new SocketException(e.getLocalizedMessage()); + } + } + + /** + * @throws UnsupportedOperationException always + */ + @Override + public int getSoLinger() { + throw new UnsupportedOperationException(); + } + + /** + * @throws SocketException + */ + @Override + public int getSoTimeout() throws SocketException { + try { + return mLocalSocket.getSoTimeout(); + } catch (IOException e) { + throw new SocketException(e.getLocalizedMessage()); + } + } + + /** + * @return false always + */ + @Override + public boolean getTcpNoDelay() { + return false; + } + + /** + * @return 0 always + */ + @Override + public int getTrafficClass() { + return 0; + } + + @Override + public boolean isBound() { + return mLocalSocket.isBound(); + } + + @Override + public boolean isClosed() { + return mLocalSocket.isClosed(); + } + + @Override + public boolean isConnected() { + return mLocalSocket.isConnected(); + } + + @Override + public boolean isInputShutdown() { + return mLocalSocket.isInputShutdown(); + } + + @Override + public boolean isOutputShutdown() { + return mLocalSocket.isOutputShutdown(); + } + + /** + * @throws UnsupportedOperationException always + */ + @Override + public void sendUrgentData(int data) { + throw new UnsupportedOperationException(); + } + + /** + * Does nothing. + */ + @Override + public void setKeepAlive(boolean on) { + } + + /** + * @throws UnsupportedOperationException if on is true + */ + @Override + public void setOOBInline(boolean on) { + if (on) + throw new UnsupportedOperationException(); + } + + /** + * Does nothing. + */ + @Override + public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) { + } + + /** + * @throws SocketException + */ + @Override + public void setReceiveBufferSize(int size) throws SocketException { + try { + mLocalSocket.setReceiveBufferSize(size); + } catch (IOException e) { + throw new SocketException(e.getLocalizedMessage()); + } + } + + /** + * Does nothing. + */ + @Override + public void setReuseAddress(boolean on) { + } + + /** + * @throws SocketException + */ + @Override + public void setSendBufferSize(int size) throws SocketException { + try { + mLocalSocket.setSendBufferSize(size); + } catch (IOException e) { + throw new SocketException(e.getLocalizedMessage()); + } + } + + /** + * Does nothing. + */ + @Override + public void setSoLinger(boolean on, int linger) { + } + + /** + * @throws SocketException + */ + @Override + public void setSoTimeout(int timeout) throws SocketException { + try { + mLocalSocket.setSoTimeout(timeout); + } catch (IOException e) { + throw new SocketException(e.getLocalizedMessage()); + } + } + + /** + * Does nothing. + */ + @Override + public void setTcpNoDelay(boolean on) { + } + + /** + * Does nothing. + */ + @Override + public void setTrafficClass(int tc) { + } + + @Override + public void shutdownInput() throws IOException { + mLocalSocket.shutdownInput(); + } + + @Override + public void shutdownOutput() throws IOException { + mLocalSocket.shutdownOutput(); + } + + @Override + public String toString() { + return mLocalSocket.toString(); + } +} diff --git a/client/src/main/java/net/i2p/client/DomainSocketFactory.java b/client/src/main/java/net/i2p/client/DomainSocketFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..511dacc0e67b74cb6de8b0cdb50d151c861c5fa8 --- /dev/null +++ b/client/src/main/java/net/i2p/client/DomainSocketFactory.java @@ -0,0 +1,34 @@ +package net.i2p.client; + +import android.net.LocalSocket; + +import net.i2p.I2PAppContext; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; + +/** + * Bridge to Android implementation of Unix domain sockets. + * + * @author str4d + * @since 0.9.14 + */ +public class DomainSocketFactory { + public static String I2CP_SOCKET_ADDRESS = "net.i2p.android.client.i2cp"; + + public DomainSocketFactory(I2PAppContext context) { + } + + public Socket createSocket(String name) throws IOException { + return new DomainSocket(name); + } + + public Socket createSocket(LocalSocket localSocket) { + return new DomainSocket(localSocket); + } + + public ServerSocket createServerSocket(String name) throws IOException { + return new DomainServerSocket(name, this); + } +} diff --git a/routerjars/build.xml b/routerjars/build.xml index ac84fc63cdd6a33636a7960529275bcca6f0c14b..9c5f26bfc99eeeee6c943502038ef7942c7d0e40 100644 --- a/routerjars/build.xml +++ b/routerjars/build.xml @@ -48,6 +48,7 @@ <!-- lots of unneeded stuff could be deleted here --> <jar destfile="${jar.libs.dir}/i2p.jar" > <zipfileset src="${i2pbase}/build/i2p.jar" > + <exclude name="net/i2p/client/DomainSocketFactory.class" /> <exclude name="net/i2p/util/LogWriter.class" /> </zipfileset> </jar>