Removed UDT, as it has been deprecated and marked for removal upstream.
This commit is contained in:
parent
e62e4a59c1
commit
c884f5167b
8
LICENSE
8
LICENSE
|
@ -4,14 +4,6 @@
|
|||
Encrypted, high-performance, and event-driven/reactive network stack for Java 6+
|
||||
|
||||
|
||||
- Barchart UDT/UDTv4 - BSD 3-clause License
|
||||
https://github.com/barchart/barchart-udt
|
||||
http://udt.sourceforge.net
|
||||
http://www.barchart.com
|
||||
Copyright 2009-2013, Barchart, Inc.
|
||||
Copyright 2001 - 2011, The Board of Trustees of the University of Illinois
|
||||
|
||||
|
||||
- Bennidi Iterator - MIT License
|
||||
https://github.com/bennidi/mbassador
|
||||
Copyright 2012, Benjamin Diedrichsen
|
||||
|
|
|
@ -22,6 +22,5 @@
|
|||
<orderEntry type="library" name="junit-4.12" level="application" />
|
||||
<orderEntry type="library" name="dorkbox minlog_slf4j" level="application" />
|
||||
<orderEntry type="library" name="kryo" level="application" />
|
||||
<orderEntry type="module" module-name="Network-UDT" />
|
||||
</component>
|
||||
</module>
|
|
@ -1,7 +1,7 @@
|
|||
Network
|
||||
=======
|
||||
|
||||
The Network project is an encrypted, high-performance, event-driven/reactive Network stack with DNS and RMI, using Netty, Kryo, KryoNet RMI, and LZ4 via TCP/UDP/UDT.
|
||||
The Network project is an encrypted, high-performance, event-driven/reactive Network stack with DNS and RMI, using Netty, Kryo, KryoNet RMI, and LZ4 via TCP/UDP.
|
||||
|
||||
These are the main features:
|
||||
- The connection between endpoints is AES256-GCM / EC curve25519.
|
||||
|
@ -16,7 +16,7 @@ These are the main features:
|
|||
- "Pinging" the remote end (for measuring round-trip time)
|
||||
|
||||
|
||||
- The available transports are TCP, UDP, and UDT
|
||||
- The available transports are TCP and UDP
|
||||
- There are simple wrapper classes for:
|
||||
- Server
|
||||
- Client
|
||||
|
|
|
@ -29,11 +29,9 @@ import dorkbox.network.connection.idle.IdleSender;
|
|||
import dorkbox.network.connection.registration.local.RegistrationLocalHandlerClient;
|
||||
import dorkbox.network.connection.registration.remote.RegistrationRemoteHandlerClientTCP;
|
||||
import dorkbox.network.connection.registration.remote.RegistrationRemoteHandlerClientUDP;
|
||||
import dorkbox.network.connection.registration.remote.RegistrationRemoteHandlerClientUDT;
|
||||
import dorkbox.network.rmi.RemoteObject;
|
||||
import dorkbox.network.rmi.RemoteObjectCallback;
|
||||
import dorkbox.network.rmi.TimeoutException;
|
||||
import dorkbox.network.util.udt.UdtEndpointProxy;
|
||||
import dorkbox.util.NamedThreadFactory;
|
||||
import dorkbox.util.OS;
|
||||
import dorkbox.util.exceptions.InitializationException;
|
||||
|
@ -87,9 +85,9 @@ class Client<C extends Connection> extends EndPointClient<C> implements Connecti
|
|||
* Starts a TCP & UDP client (or a LOCAL client), with the specified serialization scheme
|
||||
*/
|
||||
public
|
||||
Client(String host, int tcpPort, int udpPort, int udtPort, String localChannelName)
|
||||
Client(String host, int tcpPort, int udpPort, String localChannelName)
|
||||
throws InitializationException, SecurityException, IOException {
|
||||
this(new Configuration(host, tcpPort, udpPort, udtPort, localChannelName));
|
||||
this(new Configuration(host, tcpPort, udpPort, localChannelName));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,13 +113,6 @@ class Client<C extends Connection> extends EndPointClient<C> implements Connecti
|
|||
|
||||
boolean isAndroid = PlatformDependent.isAndroid();
|
||||
|
||||
if (isAndroid && options.udtPort > 0) {
|
||||
// Android does not support UDT.
|
||||
if (logger2.isInfoEnabled()) {
|
||||
logger2.info("Android does not support UDT.");
|
||||
}
|
||||
options.udtPort = -1;
|
||||
}
|
||||
|
||||
final EventLoopGroup boss;
|
||||
|
||||
|
@ -139,7 +130,7 @@ class Client<C extends Connection> extends EndPointClient<C> implements Connecti
|
|||
|
||||
manageForShutdown(boss);
|
||||
|
||||
if (options.localChannelName != null && options.tcpPort < 0 && options.udpPort < 0 && options.udtPort < 0) {
|
||||
if (options.localChannelName != null && options.tcpPort < 0 && options.udpPort < 0) {
|
||||
// no networked bootstraps. LOCAL connection only
|
||||
Bootstrap localBootstrap = new Bootstrap();
|
||||
this.bootstraps.add(new BootstrapWrapper("LOCAL", options.localChannelName, -1, localBootstrap));
|
||||
|
@ -159,7 +150,7 @@ class Client<C extends Connection> extends EndPointClient<C> implements Connecti
|
|||
throw new IllegalArgumentException("You must define what host you want to connect to.");
|
||||
}
|
||||
|
||||
if (options.tcpPort < 0 && options.udpPort < 0 && options.udtPort < 0) {
|
||||
if (options.tcpPort < 0 && options.udpPort < 0) {
|
||||
throw new IllegalArgumentException("You must define what port you want to connect to.");
|
||||
}
|
||||
|
||||
|
@ -228,38 +219,6 @@ class Client<C extends Connection> extends EndPointClient<C> implements Connecti
|
|||
udpBootstrap.option(ChannelOption.SO_BROADCAST, false)
|
||||
.option(ChannelOption.SO_SNDBUF, udpMaxSize);
|
||||
}
|
||||
|
||||
|
||||
if (options.udtPort > 0) {
|
||||
// check to see if we have UDT available!
|
||||
boolean udtAvailable = false;
|
||||
try {
|
||||
Class.forName("com.barchart.udt.nio.SelectorProviderUDT");
|
||||
udtAvailable = true;
|
||||
} catch (Throwable e) {
|
||||
logger2.error("Requested a UDT connection on port {}, but the barchart UDT libraries are not loaded.", options.udtPort);
|
||||
}
|
||||
|
||||
if (udtAvailable) {
|
||||
// all of this must be proxied to another class, so THIS class doesn't have unmet dependencies.
|
||||
Bootstrap udtBootstrap = new Bootstrap();
|
||||
this.bootstraps.add(new BootstrapWrapper("UDT", options.host, options.udtPort, udtBootstrap));
|
||||
|
||||
EventLoopGroup udtBoss = UdtEndpointProxy.getWorker(DEFAULT_THREAD_POOL_SIZE, threadName, threadGroup);
|
||||
|
||||
UdtEndpointProxy.setChannelFactory(udtBootstrap);
|
||||
|
||||
udtBootstrap.group(udtBoss)
|
||||
.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
|
||||
.option(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(WRITE_BUFF_LOW, WRITE_BUFF_HIGH))
|
||||
.remoteAddress(options.host, options.udtPort)
|
||||
.handler(new RegistrationRemoteHandlerClientUDT<C>(threadName,
|
||||
registrationWrapper,
|
||||
serializationManager));
|
||||
|
||||
manageForShutdown(udtBoss);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -402,12 +361,6 @@ class Client<C extends Connection> extends EndPointClient<C> implements Connecti
|
|||
return this.connection.hasUDP();
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
boolean hasUDT() {
|
||||
return this.connection.hasUDT();
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose methods to send objects to a destination when the connection has become idle.
|
||||
*/
|
||||
|
|
|
@ -40,13 +40,6 @@ class Configuration {
|
|||
*/
|
||||
public int udpPort = -1;
|
||||
|
||||
/**
|
||||
* Specify the UDT port to use. The server will listen on this port, the client will connect to it.
|
||||
* <p>
|
||||
* UDT requires TCP to handshake
|
||||
*/
|
||||
public int udtPort = -1;
|
||||
|
||||
/**
|
||||
* Specify the local channel name to use, if the default is not wanted.
|
||||
* <p>
|
||||
|
@ -89,11 +82,10 @@ class Configuration {
|
|||
}
|
||||
|
||||
public
|
||||
Configuration(String host, int tcpPort, int udpPort, int udtPort, String localChannelName) {
|
||||
Configuration(String host, int tcpPort, int udpPort, String localChannelName) {
|
||||
this.host = host;
|
||||
this.tcpPort = tcpPort;
|
||||
this.udpPort = udpPort;
|
||||
this.udtPort = udtPort;
|
||||
this.localChannelName = localChannelName;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,8 +24,6 @@ import dorkbox.network.connection.EndPointServer;
|
|||
import dorkbox.network.connection.registration.local.RegistrationLocalHandlerServer;
|
||||
import dorkbox.network.connection.registration.remote.RegistrationRemoteHandlerServerTCP;
|
||||
import dorkbox.network.connection.registration.remote.RegistrationRemoteHandlerServerUDP;
|
||||
import dorkbox.network.connection.registration.remote.RegistrationRemoteHandlerServerUDT;
|
||||
import dorkbox.network.util.udt.UdtEndpointProxy;
|
||||
import dorkbox.util.NamedThreadFactory;
|
||||
import dorkbox.util.OS;
|
||||
import dorkbox.util.Property;
|
||||
|
@ -78,11 +76,9 @@ class Server<C extends Connection> extends EndPointServer<C> {
|
|||
private final ServerBootstrap localBootstrap;
|
||||
private final ServerBootstrap tcpBootstrap;
|
||||
private final Bootstrap udpBootstrap;
|
||||
private final ServerBootstrap udtBootstrap;
|
||||
|
||||
private final int tcpPort;
|
||||
private final int udpPort;
|
||||
private final int udtPort;
|
||||
|
||||
private final String localChannelName;
|
||||
private final String hostName;
|
||||
|
@ -106,17 +102,9 @@ class Server<C extends Connection> extends EndPointServer<C> {
|
|||
super(options);
|
||||
|
||||
Logger logger2 = logger;
|
||||
if (OS.isAndroid() && options.udtPort > 0) {
|
||||
// Android does not support UDT.
|
||||
if (logger2.isInfoEnabled()) {
|
||||
logger2.info("Android does not support UDT.");
|
||||
}
|
||||
options.udtPort = -1;
|
||||
}
|
||||
|
||||
tcpPort = options.tcpPort;
|
||||
udpPort = options.udpPort;
|
||||
udtPort = options.udtPort;
|
||||
|
||||
localChannelName = options.localChannelName;
|
||||
|
||||
|
@ -152,26 +140,6 @@ class Server<C extends Connection> extends EndPointServer<C> {
|
|||
|
||||
String threadName = Server.class.getSimpleName();
|
||||
|
||||
if (udtPort > 0) {
|
||||
// check to see if we have UDT available!
|
||||
boolean udtAvailable = false;
|
||||
try {
|
||||
Class.forName("com.barchart.udt.nio.SelectorProviderUDT");
|
||||
udtAvailable = true;
|
||||
} catch (Throwable e) {
|
||||
logger2.error("Requested a UDT service on port {}, but the barchart UDT libraries are not loaded.", udtPort);
|
||||
}
|
||||
|
||||
if (udtAvailable) {
|
||||
udtBootstrap = new ServerBootstrap();
|
||||
}
|
||||
else {
|
||||
udtBootstrap = null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
udtBootstrap = null;
|
||||
}
|
||||
|
||||
final EventLoopGroup boss;
|
||||
final EventLoopGroup worker;
|
||||
|
@ -295,30 +263,6 @@ class Server<C extends Connection> extends EndPointServer<C> {
|
|||
udpBootstrap.option(ChannelOption.SO_BROADCAST, false)
|
||||
.option(ChannelOption.SO_SNDBUF, udpMaxSize);
|
||||
}
|
||||
|
||||
|
||||
if (udtBootstrap != null) {
|
||||
EventLoopGroup udtBoss;
|
||||
EventLoopGroup udtWorker;
|
||||
|
||||
// all of this must be proxied to another class, so THIS class doesn't have unmet dependencies.
|
||||
udtBoss = UdtEndpointProxy.getBoss(DEFAULT_THREAD_POOL_SIZE, threadName, threadGroup);
|
||||
udtWorker = UdtEndpointProxy.getWorker(DEFAULT_THREAD_POOL_SIZE, threadName, threadGroup);
|
||||
|
||||
UdtEndpointProxy.setChannelFactory(udtBootstrap);
|
||||
udtBootstrap.group(udtBoss, udtWorker)
|
||||
.option(ChannelOption.SO_BACKLOG, backlogConnectionCount)
|
||||
.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
|
||||
.option(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(WRITE_BUFF_LOW, WRITE_BUFF_HIGH))
|
||||
// not binding to specific address, since it's driven by TCP, and that can be bound to a specific address
|
||||
.localAddress(udtPort)
|
||||
.childHandler(new RegistrationRemoteHandlerServerUDT<C>(threadName,
|
||||
registrationWrapper,
|
||||
serializationManager));
|
||||
|
||||
manageForShutdown(udtBoss);
|
||||
manageForShutdown(udtWorker);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -425,30 +369,6 @@ class Server<C extends Connection> extends EndPointServer<C> {
|
|||
manageForShutdown(future);
|
||||
}
|
||||
|
||||
// UDT
|
||||
if (udtBootstrap != null) {
|
||||
// Wait until the connection attempt succeeds or fails.
|
||||
try {
|
||||
future = udtBootstrap.bind();
|
||||
future.await();
|
||||
} catch (Exception e) {
|
||||
String errorMessage = stopWithErrorMessage(logger2, "Could not bind to address " + hostName + " UDT port " +
|
||||
udtPort + " on the server.", e);
|
||||
throw new IllegalArgumentException(errorMessage);
|
||||
}
|
||||
|
||||
if (!future.isSuccess()) {
|
||||
String errorMessage = stopWithErrorMessage(logger2,
|
||||
"Could not bind to address " + hostName + " UDT port " + udtPort +
|
||||
" on the server.",
|
||||
future.cause());
|
||||
throw new IllegalArgumentException(errorMessage);
|
||||
}
|
||||
|
||||
logger2.info("Listening on address {} at UDT port: {}", hostName, udtPort);
|
||||
manageForShutdown(future);
|
||||
}
|
||||
|
||||
// we now BLOCK until the stop method is called.
|
||||
// if we want to continue running code in the server, bind should be called in a separate, non-daemon thread.
|
||||
if (blockUntilTerminate) {
|
||||
|
|
|
@ -65,11 +65,6 @@ interface Connection {
|
|||
*/
|
||||
boolean hasUDP();
|
||||
|
||||
/**
|
||||
* @return true if this connection is also configured to use UDT
|
||||
*/
|
||||
boolean hasUDT();
|
||||
|
||||
/**
|
||||
* Expose methods to send objects to a destination (such as a custom object or a standard ping)
|
||||
*/
|
||||
|
|
|
@ -54,7 +54,6 @@ import io.netty.channel.epoll.EpollSocketChannel;
|
|||
import io.netty.channel.local.LocalChannel;
|
||||
import io.netty.channel.socket.nio.NioDatagramChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.channel.udt.nio.NioUdtByteConnectorChannel;
|
||||
import io.netty.handler.timeout.IdleState;
|
||||
import io.netty.handler.timeout.IdleStateEvent;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
|
@ -62,7 +61,7 @@ import io.netty.util.concurrent.Promise;
|
|||
|
||||
|
||||
/**
|
||||
* The "network connection" is established once the registration is validated for TCP/UDP/UDT
|
||||
* The "network connection" is established once the registration is validated for TCP/UDP
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@Sharable
|
||||
|
@ -248,7 +247,7 @@ class ConnectionImpl extends ChannelInboundHandlerAdapter implements ICryptoConn
|
|||
}
|
||||
|
||||
/**
|
||||
* Sends a "ping" packet, trying UDP, then UDT, then TCP (in that order) to measure <b>ROUND TRIP</b> time to the remote connection.
|
||||
* Sends a "ping" packet, trying UDP then TCP (in that order) to measure <b>ROUND TRIP</b> time to the remote connection.
|
||||
*
|
||||
* @return Ping can have a listener attached, which will get called when the ping returns.
|
||||
*/
|
||||
|
@ -273,16 +272,13 @@ class ConnectionImpl extends ChannelInboundHandlerAdapter implements ICryptoConn
|
|||
|
||||
/**
|
||||
* INTERNAL USE ONLY. Used to initiate a ping, and to return a ping.
|
||||
* Sends a ping message attempted in the following order: UDP, UDT, TCP
|
||||
* Sends a ping message attempted in the following order: UDP, TCP
|
||||
*/
|
||||
public final
|
||||
void ping0(PingMessage ping) {
|
||||
if (this.channelWrapper.udp() != null) {
|
||||
UDP(ping).flush();
|
||||
}
|
||||
else if (this.channelWrapper.udt() != null) {
|
||||
UDT(ping).flush();
|
||||
}
|
||||
else {
|
||||
TCP(ping).flush();
|
||||
}
|
||||
|
@ -311,15 +307,6 @@ class ConnectionImpl extends ChannelInboundHandlerAdapter implements ICryptoConn
|
|||
return this.channelWrapper.udp() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this connection is also configured to use UDT
|
||||
*/
|
||||
@Override
|
||||
public final
|
||||
boolean hasUDT() {
|
||||
return this.channelWrapper.udt() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
void channelWritabilityChanged(final ChannelHandlerContext ctx) throws Exception {
|
||||
|
@ -484,59 +471,7 @@ class ConnectionImpl extends ChannelInboundHandlerAdapter implements ICryptoConn
|
|||
}
|
||||
|
||||
/**
|
||||
* Sends the object over the network using TCP. (LOCAL channels do not care if its TCP or UDP)
|
||||
*/
|
||||
final
|
||||
ConnectionPoint UDT_backpressure(Object message) {
|
||||
Logger logger2 = this.logger;
|
||||
if (!this.closeInProgress.get()) {
|
||||
if (logger2.isTraceEnabled()) {
|
||||
logger2.trace("Sending UDT {}", message);
|
||||
}
|
||||
ConnectionPointWriter udt = this.channelWrapper.udt();
|
||||
// needed to place back-pressure when writing too much data to the connection. Will create deadlocks if called from
|
||||
// INSIDE the event loop
|
||||
controlBackPressure(udt);
|
||||
|
||||
udt.write(message);
|
||||
return udt;
|
||||
}
|
||||
else {
|
||||
if (logger2.isDebugEnabled()) {
|
||||
logger2.debug("writing UDT while closed: {}", message);
|
||||
}
|
||||
// we have to return something, otherwise dependent code will throw a null pointer exception
|
||||
return ChannelNull.get();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the object over the network using TCP. (LOCAL channels do not care if its TCP or UDP)
|
||||
*/
|
||||
@Override
|
||||
public final
|
||||
ConnectionPoint UDT(Object message) {
|
||||
Logger logger2 = this.logger;
|
||||
if (!this.closeInProgress.get()) {
|
||||
if (logger2.isTraceEnabled()) {
|
||||
logger2.trace("Sending UDT {}", message);
|
||||
}
|
||||
ConnectionPointWriter udt = this.channelWrapper.udt();
|
||||
udt.write(message);
|
||||
return udt;
|
||||
}
|
||||
else {
|
||||
if (logger2.isDebugEnabled()) {
|
||||
logger2.debug("writing UDT while closed: {}", message);
|
||||
}
|
||||
// we have to return something, otherwise dependent code will throw a null pointer exception
|
||||
return ChannelNull.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Flushes the contents of the TCP/UDP/UDT/etc pipes to the actual transport.
|
||||
* Flushes the contents of the TCP/UDP/etc pipes to the actual transport.
|
||||
*/
|
||||
@Override
|
||||
public final
|
||||
|
@ -642,9 +577,6 @@ class ConnectionImpl extends ChannelInboundHandlerAdapter implements ICryptoConn
|
|||
else if (channelClass == NioDatagramChannel.class || channelClass == EpollDatagramChannel.class) {
|
||||
type = "UDP";
|
||||
}
|
||||
else if (channelClass == NioUdtByteConnectorChannel.class) {
|
||||
type = "UDT";
|
||||
}
|
||||
else if (channelClass == LocalChannel.class) {
|
||||
type = "LOCAL";
|
||||
}
|
||||
|
@ -664,7 +596,7 @@ class ConnectionImpl extends ChannelInboundHandlerAdapter implements ICryptoConn
|
|||
// and connection.close() can be called by the user.
|
||||
this.sessionManager.connectionDisconnected(this);
|
||||
|
||||
// close TCP/UDP/UDT together!
|
||||
// close TCP/UDP together!
|
||||
close();
|
||||
}
|
||||
|
||||
|
|
|
@ -126,8 +126,8 @@ class ConnectionManager<C extends Connection> implements ListenerBridge, ISessio
|
|||
|
||||
// find the class that uses Listener.class.
|
||||
Class<?> clazz = listener.getClass();
|
||||
Class<?>[] interfaces = clazz.getInterfaces();
|
||||
|
||||
// Class<?>[] interfaces = clazz.getInterfaces();
|
||||
// for (Class<?> anInterface : interfaces) {
|
||||
// }
|
||||
//
|
||||
|
@ -320,8 +320,7 @@ class ConnectionManager<C extends Connection> implements ListenerBridge, ISessio
|
|||
.flush();
|
||||
}
|
||||
else {
|
||||
Logger logger2 = this.logger;
|
||||
if (logger2.isErrorEnabled()) {
|
||||
if (this.logger.isErrorEnabled()) {
|
||||
this.logger.warn("----------- LISTENER NOT REGISTERED FOR TYPE: {}",
|
||||
message.getClass()
|
||||
.getSimpleName());
|
||||
|
@ -708,27 +707,6 @@ class ConnectionManager<C extends Connection> implements ListenerBridge, ISessio
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the object to all server connections (except the specified one) over the network using UDT. (or via LOCAL when it's a local
|
||||
* channel).
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
ConnectionPoint UDT(final C connection, final Object message) {
|
||||
ConcurrentEntry<C> current = connectionsREF.get(this);
|
||||
C c;
|
||||
while (current != null) {
|
||||
c = current.getValue();
|
||||
current = current.next();
|
||||
|
||||
if (c != connection) {
|
||||
c.send()
|
||||
.UDT(message);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the message to other listeners INSIDE this endpoint for EVERY connection. It does not send it to a remote address.
|
||||
*/
|
||||
|
@ -781,25 +759,6 @@ class ConnectionManager<C extends Connection> implements ListenerBridge, ISessio
|
|||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends the object all server connections over the network using UDT. (or via LOCAL when it's a local channel).
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
ConnectionPoint UDT(final Object message) {
|
||||
ConcurrentEntry<C> current = connectionsREF.get(this);
|
||||
C c;
|
||||
while (current != null) {
|
||||
c = current.getValue();
|
||||
current = current.next();
|
||||
|
||||
c.send()
|
||||
.UDT(message);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
boolean equals(final Object o) {
|
||||
|
|
|
@ -24,7 +24,7 @@ interface ConnectionPoint {
|
|||
boolean isWritable();
|
||||
|
||||
/**
|
||||
* Flushes the contents of the TCP/UDP/UDT/etc pipes to the wire.
|
||||
* Flushes the contents of the TCP/UDP/etc pipes to the wire.
|
||||
*/
|
||||
void flush();
|
||||
}
|
||||
|
|
|
@ -118,8 +118,7 @@ class EndPoint<C extends Connection> {
|
|||
* To fit into that magic 576-byte MTU and avoid fragmentation, your
|
||||
* UDP payload should be restricted by 576-60-8=508 bytes.
|
||||
*
|
||||
* This can be set higher on an internal lan! (or use UDT to make UDP
|
||||
* transfers easy)
|
||||
* This can be set higher on an internal lan!
|
||||
*
|
||||
* DON'T go higher that 1400 over the internet, but 9k is possible
|
||||
* with jumbo frames on a local network (if it's supported)
|
||||
|
|
|
@ -166,14 +166,6 @@ class EndPointClient<C extends Connection> extends EndPoint<C> implements Runnab
|
|||
return udp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
ConnectionPoint UDT(Object message) {
|
||||
ConnectionPoint udt = connection.UDT_backpressure(message);
|
||||
udt.flush();
|
||||
return udt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
Ping ping() {
|
||||
|
|
|
@ -55,7 +55,7 @@ class RegistrationWrapper<C extends Connection> implements UdpServer {
|
|||
|
||||
private final EndPoint<C> endPoint;
|
||||
|
||||
// keeps track of connections (TCP/UDT/UDP-client)
|
||||
// keeps track of connections (TCP/UDP-client)
|
||||
private final ReentrantLock channelMapLock = new ReentrantLock();
|
||||
private final IntMap<MetaChannel> channelMap = new IntMap<MetaChannel>();
|
||||
|
||||
|
@ -392,8 +392,7 @@ class RegistrationWrapper<C extends Connection> implements UdpServer {
|
|||
|
||||
if (metaChannel.localChannel == channel ||
|
||||
metaChannel.tcpChannel == channel ||
|
||||
metaChannel.udpChannel == channel ||
|
||||
metaChannel.udtChannel == channel) {
|
||||
metaChannel.udpChannel == channel) {
|
||||
|
||||
entries.remove();
|
||||
metaChannel.close(maxShutdownWaitTimeInMilliSeconds);
|
||||
|
@ -469,7 +468,7 @@ class RegistrationWrapper<C extends Connection> implements UdpServer {
|
|||
}
|
||||
|
||||
public
|
||||
boolean associateChannels(final Channel channel, final InetAddress remoteAddress, final boolean isUdt) {
|
||||
boolean associateChannels(final Channel channel, final InetAddress remoteAddress) {
|
||||
boolean success = false;
|
||||
|
||||
try {
|
||||
|
@ -483,12 +482,7 @@ class RegistrationWrapper<C extends Connection> implements UdpServer {
|
|||
InetAddress tcpRemoteServer = inetSocketAddress.getAddress();
|
||||
if (checkEqual(tcpRemoteServer, remoteAddress)) {
|
||||
channelMap.put(channel.hashCode(), metaChannel);
|
||||
if (isUdt) {
|
||||
metaChannel.udtChannel = channel;
|
||||
}
|
||||
else {
|
||||
metaChannel.udpChannel = channel;
|
||||
}
|
||||
success = true;
|
||||
// only allow one server per registration!
|
||||
break;
|
||||
|
@ -501,36 +495,6 @@ class RegistrationWrapper<C extends Connection> implements UdpServer {
|
|||
return success;
|
||||
}
|
||||
|
||||
public
|
||||
MetaChannel getAssociatedChannel_UDT(final InetAddress remoteAddress) {
|
||||
try {
|
||||
MetaChannel metaChannel;
|
||||
IntMap<MetaChannel> channelMap = getAndLockChannelMap();
|
||||
IntMap.Entries<MetaChannel> entries = channelMap.entries();
|
||||
|
||||
while (entries.hasNext()) {
|
||||
metaChannel = entries.next().value;
|
||||
|
||||
// only look at connections that do not have UDP already setup.
|
||||
if (metaChannel.udtChannel == null) {
|
||||
InetSocketAddress tcpRemote = (InetSocketAddress) metaChannel.tcpChannel.remoteAddress();
|
||||
InetAddress tcpRemoteAddress = tcpRemote.getAddress();
|
||||
|
||||
if (RegistrationRemoteHandler.checkEqual(tcpRemoteAddress, remoteAddress)) {
|
||||
return metaChannel;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
releaseChannelMap();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public
|
||||
MetaChannel getAssociatedChannel_UDP(final InetAddress remoteAddress) {
|
||||
try {
|
||||
|
|
|
@ -20,14 +20,14 @@ import dorkbox.network.connection.Ping;
|
|||
public
|
||||
interface ConnectionBridge extends ConnectionBridgeBase {
|
||||
/**
|
||||
* Sends a "ping" packet, trying UDP, then UDT, then TCP (in that order) to measure <b>ROUND TRIP</b> time to the remote connection.
|
||||
* Sends a "ping" packet, trying UDP then TCP (in that order) to measure <b>ROUND TRIP</b> time to the remote connection.
|
||||
*
|
||||
* @return Ping can have a listener attached, which will get called when the ping returns.
|
||||
*/
|
||||
Ping ping();
|
||||
|
||||
/**
|
||||
* Flushes the contents of the TCP/UDP/UDT/etc pipes to the actual transport.
|
||||
* Flushes the contents of the TCP/UDP/etc pipes to the actual transport.
|
||||
*/
|
||||
void flush();
|
||||
}
|
||||
|
|
|
@ -33,9 +33,4 @@ interface ConnectionBridgeBase {
|
|||
* Sends the message over the network using UDP (or via LOCAL when it's a local channel).
|
||||
*/
|
||||
ConnectionPoint UDP(Object message);
|
||||
|
||||
/**
|
||||
* Sends the message over the network using UDT. (or via LOCAL when it's a local channel).
|
||||
*/
|
||||
ConnectionPoint UDT(Object message);
|
||||
}
|
||||
|
|
|
@ -32,10 +32,4 @@ interface ConnectionExceptSpecifiedBridgeServer<C extends Connection> {
|
|||
* channel).
|
||||
*/
|
||||
ConnectionPoint UDP(C connection, Object message);
|
||||
|
||||
/**
|
||||
* Sends the object to all server connections (except the specified one) over the network using UDT. (or via LOCAL when it's a local
|
||||
* channel).
|
||||
*/
|
||||
ConnectionPoint UDT(C connection, Object message);
|
||||
}
|
||||
|
|
|
@ -26,9 +26,4 @@ interface IdleBridge {
|
|||
* Sends the object over the network using UDP when the socket is in an "idle" state.
|
||||
*/
|
||||
void UDP();
|
||||
|
||||
/**
|
||||
* Sends the object over the network using UDT (or via LOCAL when it's a local channel) when the socket is in an "idle" state.
|
||||
*/
|
||||
void UDT();
|
||||
}
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright 2010 dorkbox, llc
|
||||
*
|
||||
* Licensed 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 dorkbox.network.connection.idle;
|
||||
|
||||
import dorkbox.network.connection.Connection;
|
||||
|
||||
public
|
||||
class IdleListenerUDT<C extends Connection, M> implements IdleListener<C, M> {
|
||||
|
||||
/**
|
||||
* used by the Idle Sender
|
||||
*/
|
||||
public
|
||||
IdleListenerUDT() {
|
||||
}
|
||||
|
||||
/**
|
||||
* used by the Idle Sender
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
void send(C connection, M message) {
|
||||
connection.send()
|
||||
.UDT(message);
|
||||
}
|
||||
}
|
|
@ -55,17 +55,4 @@ class IdleSenderFactory<C extends Connection, M> implements IdleBridge {
|
|||
.add(new IdleObjectSender(new IdleListenerUDP<C, M>(), message));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
void UDT() {
|
||||
if (message instanceof IdleSender) {
|
||||
connection.listeners()
|
||||
.add((IdleSender) message);
|
||||
}
|
||||
else {
|
||||
connection.listeners()
|
||||
.add(new IdleObjectSender(new IdleListenerUDT<C, M>(), message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,8 +42,6 @@ class MetaChannel {
|
|||
public Channel udpChannel = null;
|
||||
public InetSocketAddress udpRemoteAddress = null; // SERVER ONLY. needed to be aware of the remote address to send UDP replies to
|
||||
|
||||
public Channel udtChannel = null;
|
||||
|
||||
public ConnectionImpl connection; // only needed until the connection has been notified.
|
||||
|
||||
public ECPublicKeyParameters publicKey; // used for ECC crypto + handshake on NETWORK (remote) connections. This is the remote public key.
|
||||
|
@ -69,10 +67,6 @@ class MetaChannel {
|
|||
this.tcpChannel.close();
|
||||
}
|
||||
|
||||
if (this.udtChannel != null) {
|
||||
this.udtChannel.close();
|
||||
}
|
||||
|
||||
// only the CLIENT will have this.
|
||||
if (this.udpChannel != null && this.udpRemoteAddress == null) {
|
||||
this.udpChannel.close();
|
||||
|
@ -90,11 +84,6 @@ class MetaChannel {
|
|||
.awaitUninterruptibly(maxShutdownWaitTimeInMilliSeconds);
|
||||
}
|
||||
|
||||
if (this.udtChannel != null && this.udtChannel.isOpen()) {
|
||||
this.udtChannel.close()
|
||||
.awaitUninterruptibly(maxShutdownWaitTimeInMilliSeconds);
|
||||
}
|
||||
|
||||
// only the CLIENT will have this.
|
||||
if (this.udpChannel != null && this.udpRemoteAddress == null && this.udpChannel.isOpen()) {
|
||||
this.udpChannel.close()
|
||||
|
|
|
@ -19,7 +19,7 @@ import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
|||
import org.bouncycastle.crypto.params.IESParameters;
|
||||
|
||||
/**
|
||||
* Internal message to handle the TCP/UDP/UDT registration process
|
||||
* Internal message to handle the TCP/UDP registration process
|
||||
*/
|
||||
public
|
||||
class Registration {
|
||||
|
|
|
@ -15,6 +15,18 @@
|
|||
*/
|
||||
package dorkbox.network.connection.registration.remote;
|
||||
|
||||
import static dorkbox.network.connection.EndPoint.maxShutdownWaitTimeInMilliSeconds;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.bouncycastle.crypto.engines.AESFastEngine;
|
||||
import org.bouncycastle.crypto.engines.IESEngine;
|
||||
import org.bouncycastle.crypto.modes.GCMBlockCipher;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import dorkbox.network.connection.Connection;
|
||||
import dorkbox.network.connection.ConnectionImpl;
|
||||
import dorkbox.network.connection.RegistrationWrapper;
|
||||
|
@ -34,20 +46,8 @@ import io.netty.channel.epoll.EpollDatagramChannel;
|
|||
import io.netty.channel.epoll.EpollSocketChannel;
|
||||
import io.netty.channel.socket.nio.NioDatagramChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.channel.udt.nio.NioUdtByteConnectorChannel;
|
||||
import io.netty.handler.timeout.IdleStateHandler;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
import org.bouncycastle.crypto.engines.AESFastEngine;
|
||||
import org.bouncycastle.crypto.engines.IESEngine;
|
||||
import org.bouncycastle.crypto.modes.GCMBlockCipher;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static dorkbox.network.connection.EndPoint.maxShutdownWaitTimeInMilliSeconds;
|
||||
|
||||
public abstract
|
||||
class RegistrationRemoteHandler<C extends Connection> extends RegistrationHandler<C> {
|
||||
|
@ -158,9 +158,6 @@ class RegistrationRemoteHandler<C extends Connection> extends RegistrationHandle
|
|||
else if (channelClass == NioDatagramChannel.class || channelClass == EpollDatagramChannel.class) {
|
||||
stringBuilder.append("UDP");
|
||||
}
|
||||
else if (channelClass == NioUdtByteConnectorChannel.class) {
|
||||
stringBuilder.append("UDT");
|
||||
}
|
||||
else {
|
||||
stringBuilder.append("UNKNOWN");
|
||||
}
|
||||
|
@ -215,10 +212,6 @@ class RegistrationRemoteHandler<C extends Connection> extends RegistrationHandle
|
|||
if (metaChannel.udpChannel != null) {
|
||||
type += "/UDP";
|
||||
}
|
||||
if (metaChannel.udtChannel != null) {
|
||||
type += "/UDT";
|
||||
}
|
||||
|
||||
|
||||
InetSocketAddress address = (InetSocketAddress) metaChannel.tcpChannel.remoteAddress();
|
||||
this.logger.debug("Encrypting {} session with {}", type, address.getAddress());
|
||||
|
@ -247,18 +240,6 @@ class RegistrationRemoteHandler<C extends Connection> extends RegistrationHandle
|
|||
pipeline.replace(KRYO_DECODER, KRYO_CRYPTO_DECODER, new KryoDecoderUdpCrypto(this.serializationManager));
|
||||
pipeline.replace(KRYO_ENCODER, KRYO_CRYPTO_ENCODER, new KryoEncoderUdpCrypto(this.serializationManager));
|
||||
}
|
||||
|
||||
if (metaChannel.udtChannel != null) {
|
||||
pipeline = metaChannel.udtChannel.pipeline();
|
||||
pipeline.replace(FRAME_AND_KRYO_DECODER,
|
||||
FRAME_AND_KRYO_CRYPTO_DECODER,
|
||||
new KryoDecoderCrypto(this.serializationManager)); // cannot be shared because of possible fragmentation.
|
||||
|
||||
if (idleTimeout > 0) {
|
||||
pipeline.replace(IDLE_HANDLER, IDLE_HANDLER_FULL, new IdleStateHandler(0, 0, idleTimeout, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
pipeline.replace(FRAME_AND_KRYO_ENCODER, FRAME_AND_KRYO_CRYPTO_ENCODER, this.registrationWrapper.getKryoEncoderCrypto());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -268,7 +249,6 @@ class RegistrationRemoteHandler<C extends Connection> extends RegistrationHandle
|
|||
void establishConnection(MetaChannel metaChannel) {
|
||||
ChannelPipeline tcpPipe = metaChannel.tcpChannel.pipeline();
|
||||
ChannelPipeline udpPipe;
|
||||
ChannelPipeline udtPipe;
|
||||
|
||||
if (metaChannel.udpChannel != null && metaChannel.udpRemoteAddress == null) {
|
||||
// don't want to muck with the SERVER udp pipeline, as it NEVER CHANGES.
|
||||
|
@ -279,14 +259,6 @@ class RegistrationRemoteHandler<C extends Connection> extends RegistrationHandle
|
|||
udpPipe = null;
|
||||
}
|
||||
|
||||
if (metaChannel.udtChannel != null) {
|
||||
udtPipe = metaChannel.udtChannel.pipeline();
|
||||
}
|
||||
else {
|
||||
udtPipe = null;
|
||||
}
|
||||
|
||||
|
||||
// add the "connected"/"normal" handler now that we have established a "new" connection.
|
||||
// This will have state, etc. for this connection.
|
||||
ConnectionImpl connection = (ConnectionImpl) this.registrationWrapper.connection0(metaChannel);
|
||||
|
@ -299,10 +271,6 @@ class RegistrationRemoteHandler<C extends Connection> extends RegistrationHandle
|
|||
// remember, server is different than client!
|
||||
udpPipe.addLast(CONNECTION_HANDLER, connection);
|
||||
}
|
||||
|
||||
if (udtPipe != null) {
|
||||
udtPipe.addLast(CONNECTION_HANDLER, connection);
|
||||
}
|
||||
}
|
||||
|
||||
final
|
||||
|
@ -349,9 +317,6 @@ class RegistrationRemoteHandler<C extends Connection> extends RegistrationHandle
|
|||
if (metaChannel.udpChannel != null) {
|
||||
type += "/UDP";
|
||||
}
|
||||
if (metaChannel.udtChannel != null) {
|
||||
type += "/UDT";
|
||||
}
|
||||
|
||||
InetSocketAddress address = (InetSocketAddress) metaChannel.tcpChannel.remoteAddress();
|
||||
this.logger.info("Created a {} connection with {}", type, address.getAddress());
|
||||
|
|
|
@ -15,8 +15,25 @@
|
|||
*/
|
||||
package dorkbox.network.connection.registration.remote;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.bouncycastle.crypto.BasicAgreement;
|
||||
import org.bouncycastle.crypto.agreement.ECDHCBasicAgreement;
|
||||
import org.bouncycastle.crypto.digests.SHA384Digest;
|
||||
import org.bouncycastle.crypto.engines.IESEngine;
|
||||
import org.bouncycastle.crypto.modes.GCMBlockCipher;
|
||||
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||||
import org.bouncycastle.jce.ECNamedCurveTable;
|
||||
import org.bouncycastle.jce.spec.ECParameterSpec;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.esotericsoftware.kryo.io.Input;
|
||||
import com.esotericsoftware.kryo.io.Output;
|
||||
|
||||
import dorkbox.network.connection.Connection;
|
||||
import dorkbox.network.connection.RegistrationWrapper;
|
||||
import dorkbox.network.connection.registration.MetaChannel;
|
||||
|
@ -30,21 +47,6 @@ import dorkbox.util.serialization.EccPublicKeySerializer;
|
|||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
import org.bouncycastle.crypto.BasicAgreement;
|
||||
import org.bouncycastle.crypto.agreement.ECDHCBasicAgreement;
|
||||
import org.bouncycastle.crypto.digests.SHA384Digest;
|
||||
import org.bouncycastle.crypto.engines.IESEngine;
|
||||
import org.bouncycastle.crypto.modes.GCMBlockCipher;
|
||||
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||||
import org.bouncycastle.jce.ECNamedCurveTable;
|
||||
import org.bouncycastle.jce.spec.ECParameterSpec;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public
|
||||
class RegistrationRemoteHandlerClientTCP<C extends Connection> extends RegistrationRemoteHandlerClient<C> {
|
||||
|
@ -106,8 +108,7 @@ class RegistrationRemoteHandlerClientTCP<C extends Connection> extends Registrat
|
|||
.getSimpleName());
|
||||
|
||||
|
||||
// TCP & UDT
|
||||
|
||||
// TCP
|
||||
// use the default.
|
||||
super.initChannel(channel);
|
||||
}
|
||||
|
@ -125,7 +126,7 @@ class RegistrationRemoteHandlerClientTCP<C extends Connection> extends Registrat
|
|||
// look to see if we already have a connection (in progress) for the destined IP address.
|
||||
// Note: our CHANNEL MAP can only have one item at a time, since we do NOT RELEASE the registration lock until it's complete!!
|
||||
|
||||
// The ORDER has to be TCP (always) -> UDP (optional) -> UDT (optional)
|
||||
// The ORDER has to be TCP (always)
|
||||
// TCP
|
||||
MetaChannel metaChannel = new MetaChannel();
|
||||
metaChannel.tcpChannel = channel;
|
||||
|
|
|
@ -15,6 +15,12 @@
|
|||
*/
|
||||
package dorkbox.network.connection.registration.remote;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import dorkbox.network.connection.Connection;
|
||||
import dorkbox.network.connection.RegistrationWrapper;
|
||||
import dorkbox.network.connection.registration.MetaChannel;
|
||||
|
@ -27,11 +33,6 @@ import dorkbox.util.crypto.CryptoAES;
|
|||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public
|
||||
class RegistrationRemoteHandlerClientUDP<C extends Connection> extends RegistrationRemoteHandlerClient<C> {
|
||||
|
@ -77,14 +78,14 @@ class RegistrationRemoteHandlerClientUDP<C extends Connection> extends Registrat
|
|||
// look to see if we already have a connection (in progress) for the destined IP address.
|
||||
// Note: our CHANNEL MAP can only have one item at a time, since we do NOT RELEASE the registration lock until it's complete!!
|
||||
|
||||
// The ORDER has to be TCP (always) -> UDP (optional) -> UDT (optional)
|
||||
// The ORDER has to be TCP (always) -> UDP (optional)
|
||||
// UDP
|
||||
|
||||
InetSocketAddress udpRemoteAddress = (InetSocketAddress) channel.remoteAddress();
|
||||
if (udpRemoteAddress != null) {
|
||||
InetAddress udpRemoteServer = udpRemoteAddress.getAddress();
|
||||
|
||||
boolean success = registrationWrapper.associateChannels(channel, udpRemoteServer, false);
|
||||
boolean success = registrationWrapper.associateChannels(channel, udpRemoteServer);
|
||||
if (!success) {
|
||||
throw new IOException("UDP cannot connect to a remote server before TCP is established!");
|
||||
}
|
||||
|
|
|
@ -1,159 +0,0 @@
|
|||
/*
|
||||
* Copyright 2010 dorkbox, llc
|
||||
*
|
||||
* Licensed 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 dorkbox.network.connection.registration.remote;
|
||||
|
||||
import dorkbox.network.connection.Connection;
|
||||
import dorkbox.network.connection.RegistrationWrapper;
|
||||
import dorkbox.network.connection.registration.MetaChannel;
|
||||
import dorkbox.network.connection.registration.Registration;
|
||||
import dorkbox.network.util.CryptoSerializationManager;
|
||||
import dorkbox.util.bytes.OptimizeUtilsByteArray;
|
||||
import dorkbox.util.crypto.CryptoAES;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public
|
||||
class RegistrationRemoteHandlerClientUDT<C extends Connection> extends RegistrationRemoteHandlerClient<C> {
|
||||
|
||||
public
|
||||
RegistrationRemoteHandlerClientUDT(final String name,
|
||||
final RegistrationWrapper<C> registrationWrapper,
|
||||
final CryptoSerializationManager serializationManager) {
|
||||
super(name, registrationWrapper, serializationManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* STEP 1: Channel is first created
|
||||
*/
|
||||
@Override
|
||||
protected
|
||||
void initChannel(final Channel channel) {
|
||||
this.logger.trace("Channel registered: {}",
|
||||
channel.getClass()
|
||||
.getSimpleName());
|
||||
|
||||
// TCP & UDT
|
||||
|
||||
// use the default.
|
||||
super.initChannel(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* STEP 2: Channel is now active. Start the registration process
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
void channelActive(final ChannelHandlerContext context) throws Exception {
|
||||
super.channelActive(context);
|
||||
|
||||
Channel channel = context.channel();
|
||||
// look to see if we already have a connection (in progress) for the destined IP address.
|
||||
// Note: our CHANNEL MAP can only have one item at a time, since we do NOT RELEASE the registration lock until it's complete!!
|
||||
|
||||
// The ORDER has to be TCP (always) -> UDP (optional) -> UDT (optional)
|
||||
// UDT
|
||||
InetSocketAddress udtRemoteAddress = (InetSocketAddress) channel.remoteAddress();
|
||||
if (udtRemoteAddress != null) {
|
||||
InetAddress udtRemoteServer = udtRemoteAddress.getAddress();
|
||||
|
||||
boolean success = registrationWrapper.associateChannels(channel, udtRemoteServer, true);
|
||||
if (!success) {
|
||||
throw new IOException("UDT cannot connect to a remote server before TCP is established!");
|
||||
}
|
||||
|
||||
Logger logger2 = this.logger;
|
||||
if (logger2.isTraceEnabled()) {
|
||||
logger2.trace("Start new UDT Connection. Sending request to server");
|
||||
}
|
||||
|
||||
Registration registration = new Registration();
|
||||
// client start the handshake with a registration packet
|
||||
channel.writeAndFlush(registration);
|
||||
}
|
||||
else {
|
||||
throw new IOException("UDT cannot connect to remote server! No remote address specified!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings({"AutoUnboxing", "AutoBoxing"})
|
||||
@Override
|
||||
public
|
||||
void channelRead(final ChannelHandlerContext context, final Object message) throws Exception {
|
||||
Channel channel = context.channel();
|
||||
|
||||
// if we also have a UDP channel, we will receive the "connected" message on UDP (otherwise it will be on TCP)
|
||||
RegistrationWrapper<C> registrationWrapper2 = this.registrationWrapper;
|
||||
MetaChannel metaChannel = registrationWrapper2.getChannel(channel.hashCode());
|
||||
|
||||
Logger logger2 = this.logger;
|
||||
if (metaChannel != null) {
|
||||
if (message instanceof Registration) {
|
||||
Registration registration = (Registration) message;
|
||||
|
||||
// now decrypt channelID using AES
|
||||
byte[] payload = CryptoAES.decrypt(aesEngine.get(), metaChannel.aesKey, metaChannel.aesIV, registration.payload, logger);
|
||||
|
||||
if (!OptimizeUtilsByteArray.canReadInt(payload)) {
|
||||
logger2.error("Invalid decryption of connection ID. Aborting.");
|
||||
shutdown(registrationWrapper2, channel);
|
||||
|
||||
ReferenceCountUtil.release(message);
|
||||
return;
|
||||
}
|
||||
|
||||
Integer connectionID = OptimizeUtilsByteArray.readInt(payload, true);
|
||||
MetaChannel metaChannel2 = registrationWrapper2.getChannel(connectionID);
|
||||
|
||||
if (metaChannel2 != null) {
|
||||
// hooray! we are successful
|
||||
|
||||
// notify the client that we are ready to continue registering other session protocols (bootstraps)
|
||||
boolean isDoneWithRegistration = registrationWrapper2.registerNextProtocol0();
|
||||
|
||||
// tell the server we are done, and to setup crypto on it's side
|
||||
if (isDoneWithRegistration) {
|
||||
// bounce it back over TCP, so we can receive a "final" connected message over TCP.
|
||||
metaChannel.tcpChannel.writeAndFlush(registration);
|
||||
|
||||
// re-sync the TCP delta round trip time
|
||||
metaChannel.updateTcpRoundTripTime();
|
||||
}
|
||||
|
||||
// since we are done here, we need to REMOVE this handler
|
||||
channel.pipeline()
|
||||
.remove(this);
|
||||
|
||||
// if we are NOT done, then we will continue registering other protocols, so do nothing else here.
|
||||
ReferenceCountUtil.release(message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we get here, there was an error!
|
||||
|
||||
logger2.error("Error registering UDT with remote server!");
|
||||
shutdown(registrationWrapper2, channel);
|
||||
ReferenceCountUtil.release(message);
|
||||
}
|
||||
}
|
|
@ -40,7 +40,7 @@ class RegistrationRemoteHandlerServer<C extends Connection> extends Registration
|
|||
}
|
||||
|
||||
/**
|
||||
* Registers the metachannel for the UDP server (For the TCP/UDT streams)
|
||||
* Registers the metachannel for the UDP server
|
||||
*/
|
||||
@Override
|
||||
protected
|
||||
|
|
|
@ -15,20 +15,11 @@
|
|||
*/
|
||||
package dorkbox.network.connection.registration.remote;
|
||||
|
||||
import com.esotericsoftware.kryo.io.Input;
|
||||
import com.esotericsoftware.kryo.io.Output;
|
||||
import dorkbox.network.connection.Connection;
|
||||
import dorkbox.network.connection.RegistrationWrapper;
|
||||
import dorkbox.network.connection.registration.MetaChannel;
|
||||
import dorkbox.network.connection.registration.Registration;
|
||||
import dorkbox.network.util.CryptoSerializationManager;
|
||||
import dorkbox.util.bytes.OptimizeUtilsByteArray;
|
||||
import dorkbox.util.crypto.CryptoAES;
|
||||
import dorkbox.util.crypto.CryptoECC;
|
||||
import dorkbox.util.serialization.EccPublicKeySerializer;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
|
||||
import org.bouncycastle.crypto.BasicAgreement;
|
||||
import org.bouncycastle.crypto.agreement.ECDHCBasicAgreement;
|
||||
|
@ -41,10 +32,21 @@ import org.bouncycastle.jce.spec.ECParameterSpec;
|
|||
import org.bouncycastle.util.Arrays;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import com.esotericsoftware.kryo.io.Input;
|
||||
import com.esotericsoftware.kryo.io.Output;
|
||||
|
||||
import dorkbox.network.connection.Connection;
|
||||
import dorkbox.network.connection.RegistrationWrapper;
|
||||
import dorkbox.network.connection.registration.MetaChannel;
|
||||
import dorkbox.network.connection.registration.Registration;
|
||||
import dorkbox.network.util.CryptoSerializationManager;
|
||||
import dorkbox.util.bytes.OptimizeUtilsByteArray;
|
||||
import dorkbox.util.crypto.CryptoAES;
|
||||
import dorkbox.util.crypto.CryptoECC;
|
||||
import dorkbox.util.serialization.EccPublicKeySerializer;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
|
||||
public
|
||||
class RegistrationRemoteHandlerServerTCP<C extends Connection> extends RegistrationRemoteHandlerServer<C> {
|
||||
|
@ -80,7 +82,7 @@ class RegistrationRemoteHandlerServerTCP<C extends Connection> extends Registrat
|
|||
}
|
||||
|
||||
/**
|
||||
* STEP 1: Channel is first created (This is TCP/UDT only, as such it differs from the client which is TCP/UDP)
|
||||
* STEP 1: Channel is first created (This is TCP only, as such it differs from the client which is TCP/UDP)
|
||||
*/
|
||||
@Override
|
||||
protected
|
||||
|
@ -98,7 +100,7 @@ class RegistrationRemoteHandlerServerTCP<C extends Connection> extends Registrat
|
|||
|
||||
Channel channel = context.channel();
|
||||
|
||||
// The ORDER has to be TCP (always) -> UDP (optional, in UDP listener) -> UDT (optional)
|
||||
// The ORDER has to be TCP (always)
|
||||
// TCP
|
||||
// save this new connection in our associated map. We will get a new one for each new connection from a client.
|
||||
MetaChannel metaChannel = new MetaChannel();
|
||||
|
|
|
@ -1,125 +0,0 @@
|
|||
/*
|
||||
* Copyright 2010 dorkbox, llc
|
||||
*
|
||||
* Licensed 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 dorkbox.network.connection.registration.remote;
|
||||
|
||||
import dorkbox.network.connection.Connection;
|
||||
import dorkbox.network.connection.RegistrationWrapper;
|
||||
import dorkbox.network.connection.registration.MetaChannel;
|
||||
import dorkbox.network.connection.registration.Registration;
|
||||
import dorkbox.network.util.CryptoSerializationManager;
|
||||
import dorkbox.util.bytes.OptimizeUtilsByteArray;
|
||||
import dorkbox.util.crypto.CryptoAES;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public
|
||||
class RegistrationRemoteHandlerServerUDT<C extends Connection> extends RegistrationRemoteHandlerServer<C> {
|
||||
|
||||
public
|
||||
RegistrationRemoteHandlerServerUDT(final String name,
|
||||
final RegistrationWrapper<C> registrationWrapper,
|
||||
final CryptoSerializationManager serializationManager) {
|
||||
super(name, registrationWrapper, serializationManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* STEP 1: Channel is first created (This is TCP/UDT only, as such it differs from the client which is TCP/UDP)
|
||||
*/
|
||||
@Override
|
||||
protected
|
||||
void initChannel(final Channel channel) {
|
||||
super.initChannel(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* STEP 2: Channel is now active. Prepare the meta channel to listen for the registration process
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
void channelActive(final ChannelHandlerContext context) throws Exception {
|
||||
super.channelActive(context);
|
||||
|
||||
// UDT channels are added when the registration request arrives on a UDT channel.
|
||||
}
|
||||
|
||||
/**
|
||||
* STEP 3-XXXXX: We pass registration messages around until we the registration handshake is complete!
|
||||
*/
|
||||
@SuppressWarnings("AutoUnboxing")
|
||||
@Override
|
||||
public
|
||||
void channelRead(final ChannelHandlerContext context, final Object message) throws Exception {
|
||||
Channel channel = context.channel();
|
||||
|
||||
// only TCP will come across here for the server. (UDP here is called by the UDP handler/wrapper)
|
||||
|
||||
RegistrationWrapper<C> registrationWrapper2 = this.registrationWrapper;
|
||||
Logger logger2 = this.logger;
|
||||
|
||||
if (message instanceof Registration) {
|
||||
// find out and make sure that UDP and TCP are talking to the same server
|
||||
InetAddress udtRemoteAddress = ((InetSocketAddress) channel.remoteAddress()).getAddress();
|
||||
|
||||
MetaChannel metaChannel = registrationWrapper2.getAssociatedChannel_UDT(udtRemoteAddress);
|
||||
if (metaChannel != null) {
|
||||
// associate TCP and UDT!
|
||||
metaChannel.udtChannel = channel;
|
||||
|
||||
Registration register = new Registration();
|
||||
|
||||
// save off the connectionID as a byte array, then encrypt it
|
||||
int intLength = OptimizeUtilsByteArray.intLength(metaChannel.connectionID, true);
|
||||
byte[] idAsBytes = new byte[intLength];
|
||||
OptimizeUtilsByteArray.writeInt(idAsBytes, metaChannel.connectionID, true);
|
||||
|
||||
// now encrypt payload via AES
|
||||
register.payload = CryptoAES.encrypt(RegistrationRemoteHandler.aesEngine.get(),
|
||||
metaChannel.aesKey,
|
||||
metaChannel.aesIV,
|
||||
idAsBytes,
|
||||
logger);
|
||||
|
||||
// send back, so the client knows that UDP was ok. We include the encrypted connection ID, so the client knows it's a legit server
|
||||
channel.writeAndFlush(register);
|
||||
|
||||
// since we are done here, we need to REMOVE this handler
|
||||
channel.pipeline()
|
||||
.remove(this);
|
||||
|
||||
if (logger2.isTraceEnabled()) {
|
||||
logger2.trace("Register UDT connection from {}", udtRemoteAddress);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// if we get here, there was a failure!
|
||||
if (logger2.isErrorEnabled()) {
|
||||
logger2.error("Error trying to register UDT with incorrect udt specified! UDT: {}", udtRemoteAddress);
|
||||
}
|
||||
shutdown(registrationWrapper2, channel);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (logger2.isErrorEnabled()) {
|
||||
logger2.error("UDT attempting to spoof client! Unencrypted packet other than registration received.");
|
||||
}
|
||||
shutdown(registrationWrapper2, channel);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,6 +15,10 @@
|
|||
*/
|
||||
package dorkbox.network.connection.wrapper;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.bouncycastle.crypto.params.ParametersWithIV;
|
||||
|
||||
import dorkbox.network.connection.Connection;
|
||||
import dorkbox.network.connection.ConnectionPointWriter;
|
||||
import dorkbox.network.connection.EndPoint;
|
||||
|
@ -23,9 +27,6 @@ import dorkbox.network.connection.registration.MetaChannel;
|
|||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.local.LocalAddress;
|
||||
import org.bouncycastle.crypto.params.ParametersWithIV;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public
|
||||
class ChannelLocalWrapper<C extends Connection> implements ChannelWrapper<C>, ConnectionPointWriter {
|
||||
|
@ -72,12 +73,6 @@ class ChannelLocalWrapper<C extends Connection> implements ChannelWrapper<C>, Co
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
ConnectionPointWriter udt() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the connection with any extra info that is needed but was unavailable at the channel construction.
|
||||
*/
|
||||
|
|
|
@ -15,6 +15,11 @@
|
|||
*/
|
||||
package dorkbox.network.connection.wrapper;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import org.bouncycastle.crypto.params.KeyParameter;
|
||||
import org.bouncycastle.crypto.params.ParametersWithIV;
|
||||
|
||||
import dorkbox.network.connection.Connection;
|
||||
import dorkbox.network.connection.ConnectionPointWriter;
|
||||
import dorkbox.network.connection.EndPoint;
|
||||
|
@ -25,17 +30,12 @@ import dorkbox.util.FastThreadLocal;
|
|||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.util.NetUtil;
|
||||
import org.bouncycastle.crypto.params.KeyParameter;
|
||||
import org.bouncycastle.crypto.params.ParametersWithIV;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public
|
||||
class ChannelNetworkWrapper<C extends Connection> implements ChannelWrapper<C> {
|
||||
|
||||
private final ChannelNetwork tcp;
|
||||
private final ChannelNetwork udp;
|
||||
private final ChannelNetwork udt;
|
||||
|
||||
// did the remote connection public ECC key change?
|
||||
private final boolean remotePublicKeyChanged;
|
||||
|
@ -75,13 +75,6 @@ class ChannelNetworkWrapper<C extends Connection> implements ChannelWrapper<C> {
|
|||
this.udp = null;
|
||||
}
|
||||
|
||||
if (metaChannel.udtChannel != null) {
|
||||
this.udt = new ChannelNetwork(metaChannel.udtChannel);
|
||||
}
|
||||
else {
|
||||
this.udt = null;
|
||||
}
|
||||
|
||||
|
||||
this.remoteAddress = ((InetSocketAddress) tcpChannel.remoteAddress()).getAddress()
|
||||
.getHostAddress();
|
||||
|
@ -117,12 +110,6 @@ class ChannelNetworkWrapper<C extends Connection> implements ChannelWrapper<C> {
|
|||
return this.udp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
ConnectionPointWriter udt() {
|
||||
return this.udt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the connection with any extra info that is needed but was unavailable at the channel construction.
|
||||
*/
|
||||
|
@ -133,7 +120,7 @@ class ChannelNetworkWrapper<C extends Connection> implements ChannelWrapper<C> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Flushes the contents of the TCP/UDP/UDT/etc pipes to the actual transport.
|
||||
* Flushes the contents of the TCP/UDP/etc pipes to the actual transport.
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
|
@ -143,10 +130,6 @@ class ChannelNetworkWrapper<C extends Connection> implements ChannelWrapper<C> {
|
|||
if (this.udp != null) {
|
||||
this.udp.flush();
|
||||
}
|
||||
|
||||
if (this.udt != null) {
|
||||
this.udt.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -191,13 +174,9 @@ class ChannelNetworkWrapper<C extends Connection> implements ChannelWrapper<C> {
|
|||
this.udp.close(maxShutdownWaitTimeInMilliSeconds);
|
||||
}
|
||||
|
||||
if (this.udt != null) {
|
||||
this.udt.close(maxShutdownWaitTimeInMilliSeconds);
|
||||
|
||||
// we need to yield the thread here, so that the socket has a chance to close
|
||||
Thread.yield();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
|
|
|
@ -15,11 +15,12 @@
|
|||
*/
|
||||
package dorkbox.network.connection.wrapper;
|
||||
|
||||
import org.bouncycastle.crypto.params.ParametersWithIV;
|
||||
|
||||
import dorkbox.network.connection.Connection;
|
||||
import dorkbox.network.connection.ConnectionPointWriter;
|
||||
import dorkbox.network.connection.ISessionManager;
|
||||
import io.netty.channel.EventLoop;
|
||||
import org.bouncycastle.crypto.params.ParametersWithIV;
|
||||
|
||||
public
|
||||
interface ChannelWrapper<C extends Connection> {
|
||||
|
@ -28,15 +29,13 @@ interface ChannelWrapper<C extends Connection> {
|
|||
|
||||
ConnectionPointWriter udp();
|
||||
|
||||
ConnectionPointWriter udt();
|
||||
|
||||
/**
|
||||
* Initialize the connection with any extra info that is needed but was unavailable at the channel construction.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/**
|
||||
* Flushes the contents of the TCP/UDP/UDT/etc pipes to the actual transport.
|
||||
* Flushes the contents of the TCP/UDP/etc pipes to the actual transport.
|
||||
*/
|
||||
void flush();
|
||||
|
||||
|
@ -56,7 +55,7 @@ interface ChannelWrapper<C extends Connection> {
|
|||
boolean isLoopback();
|
||||
|
||||
/**
|
||||
* @return the remote host (can be local, tcp, udp, udt)
|
||||
* @return the remote host (can be local, tcp, udp)
|
||||
*/
|
||||
String getRemoteHost();
|
||||
|
||||
|
|
|
@ -103,15 +103,6 @@ interface RemoteObject {
|
|||
*/
|
||||
void setUDP();
|
||||
|
||||
/**
|
||||
* Specifies that remote method invocation will happen over UDT. Default is {@link #setTCP()}
|
||||
* <p>
|
||||
* UDT remote method invocations <b>will</b> return a response and the invoking thread <b>will</b> wait for a response. See {@link
|
||||
* #setAsync(boolean)} if you do not want to wait for a response, which can be retrieved later with {@link #waitForLastResponse()} or
|
||||
* {@link #waitForResponse(byte)}.
|
||||
*/
|
||||
void setUDT();
|
||||
|
||||
/**
|
||||
* Permits calls to {@link Object#toString()} to actually return the `toString()` method on the object.
|
||||
*
|
||||
|
|
|
@ -55,12 +55,12 @@ import dorkbox.network.util.RmiSerializationManager;
|
|||
import dorkbox.util.collections.ObjectIntMap;
|
||||
|
||||
/**
|
||||
* Allows methods on objects to be invoked remotely over TCP, UDP, UDT, or LOCAL. Local connections ignore TCP/UDP/UDT requests, and perform
|
||||
* Allows methods on objects to be invoked remotely over TCP, UDP, or LOCAL. Local connections ignore TCP/UDP requests, and perform
|
||||
* object transformation (because there is no serialization occurring) using a series of weak hashmaps.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* Objects are {@link RmiSerializationManager#registerRmiInterface(Class)}, and endpoint connections can then {@link
|
||||
* Connection#getRemoteObject(Class)} for the registered objects.
|
||||
* Connection#getRemoteObject(Class, RemoteObjectCallback)} for the registered objects.
|
||||
* <p/>
|
||||
* It costs at least 2 bytes more to use remote method invocation than just sending the parameters. If the method has a return value which
|
||||
* is not {@link RemoteObject#setAsync(boolean) ignored}, an extra byte is written. If the type of a parameter is not final (note that
|
||||
|
|
|
@ -76,7 +76,6 @@ class RmiProxyHandler implements InvocationHandler {
|
|||
private boolean enableToString;
|
||||
|
||||
private boolean udp;
|
||||
private boolean udt;
|
||||
|
||||
private Byte lastResponseID;
|
||||
private byte nextResponseId = (byte) 1;
|
||||
|
@ -159,17 +158,10 @@ class RmiProxyHandler implements InvocationHandler {
|
|||
}
|
||||
else if (name.equals("setTCP")) {
|
||||
this.udp = false;
|
||||
this.udt = false;
|
||||
return null;
|
||||
}
|
||||
else if (name.equals("setUDP")) {
|
||||
this.udp = true;
|
||||
this.udt = false;
|
||||
return null;
|
||||
}
|
||||
else if (name.equals("setUDT")) {
|
||||
this.udp = false;
|
||||
this.udt = true;
|
||||
return null;
|
||||
}
|
||||
else if (name.equals("enableToString")) {
|
||||
|
@ -286,11 +278,6 @@ class RmiProxyHandler implements InvocationHandler {
|
|||
.UDP(invokeMethod)
|
||||
.flush();
|
||||
}
|
||||
else if (this.udt) {
|
||||
this.connection.send()
|
||||
.UDT(invokeMethod)
|
||||
.flush();
|
||||
}
|
||||
else {
|
||||
this.connection.send()
|
||||
.TCP(invokeMethod)
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
* Copyright 2010 dorkbox, llc
|
||||
*
|
||||
* Licensed 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 dorkbox.network.util.udt;
|
||||
|
||||
import dorkbox.util.NamedThreadFactory;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
|
||||
/**
|
||||
* This 'proxy' class exists in order to permit the client/server/endpoint classes from barfing when loading (ie, the JVM classloader),
|
||||
* since the classloader only checks ONE level deep for deps, not TWO levels deep.
|
||||
* <p/>
|
||||
* This exploits the class loading behavior, but it nicely permits us to choose if we want to use UDT or not, without
|
||||
* classloading complications
|
||||
*/
|
||||
public
|
||||
class UdtEndpointProxy {
|
||||
public static
|
||||
EventLoopGroup getBoss(int threadPoolSize, String name, ThreadGroup nettyGroup) {
|
||||
return new NioEventLoopGroup(threadPoolSize,
|
||||
new NamedThreadFactory(name + "-boss-UDT", nettyGroup),
|
||||
io.netty.channel.udt.nio.NioUdtProvider.BYTE_PROVIDER);
|
||||
}
|
||||
|
||||
public static
|
||||
EventLoopGroup getWorker(int threadPoolSize, String name, ThreadGroup nettyGroup) {
|
||||
return new NioEventLoopGroup(threadPoolSize,
|
||||
new NamedThreadFactory(name + "-worker-UDT", nettyGroup),
|
||||
io.netty.channel.udt.nio.NioUdtProvider.BYTE_PROVIDER);
|
||||
}
|
||||
|
||||
public static
|
||||
void setChannelFactory(ServerBootstrap udtBootstrap) {
|
||||
udtBootstrap.channelFactory(io.netty.channel.udt.nio.NioUdtProvider.BYTE_ACCEPTOR);
|
||||
}
|
||||
|
||||
public static
|
||||
void setChannelFactory(Bootstrap udtBootstrap) {
|
||||
udtBootstrap.channelFactory(io.netty.channel.udt.nio.NioUdtProvider.BYTE_CONNECTOR);
|
||||
}
|
||||
}
|
|
@ -20,6 +20,13 @@
|
|||
package dorkbox.network;
|
||||
|
||||
|
||||
import static dorkbox.network.connection.EndPoint.THREADGROUP_NAME;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
|
@ -32,12 +39,6 @@ import dorkbox.util.entropy.Entropy;
|
|||
import dorkbox.util.entropy.SimpleEntropy;
|
||||
import dorkbox.util.exceptions.InitializationException;
|
||||
import io.netty.util.ResourceLeakDetector;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static dorkbox.network.connection.EndPoint.THREADGROUP_NAME;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public abstract
|
||||
class BaseTest {
|
||||
|
@ -45,7 +46,6 @@ class BaseTest {
|
|||
public static final String host = "localhost";
|
||||
public static final int tcpPort = 54558;
|
||||
public static final int udpPort = 54779;
|
||||
public static final int udtPort = 54580;
|
||||
|
||||
static {
|
||||
// we want our entropy generation to be simple (ie, no user interaction to generate)
|
||||
|
|
|
@ -41,8 +41,7 @@ public class ChunkedDataIdleTest extends BaseTest {
|
|||
|
||||
enum ConnectionType {
|
||||
TCP,
|
||||
UDP,
|
||||
UDT
|
||||
UDP
|
||||
}
|
||||
|
||||
// have to test sending objects
|
||||
|
@ -71,17 +70,6 @@ public class ChunkedDataIdleTest extends BaseTest {
|
|||
register(configuration.serialization);
|
||||
|
||||
sendObject(mainData, configuration, ConnectionType.UDP);
|
||||
|
||||
|
||||
System.err.println("-- UDT");
|
||||
configuration = new Configuration();
|
||||
configuration.tcpPort = tcpPort;
|
||||
configuration.udtPort = udtPort;
|
||||
configuration.host = host;
|
||||
configuration.serialization = CryptoSerializationManager.DEFAULT();
|
||||
register(configuration.serialization);
|
||||
|
||||
sendObject(mainData, configuration, ConnectionType.UDT);
|
||||
}
|
||||
|
||||
|
||||
|
@ -105,7 +93,6 @@ public class ChunkedDataIdleTest extends BaseTest {
|
|||
switch (type) {
|
||||
case TCP: sendOnIdle.TCP(); break;
|
||||
case UDP: sendOnIdle.UDP(); break;
|
||||
case UDT: sendOnIdle.UDT(); break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -89,46 +89,6 @@ class ConnectionTest extends BaseTest {
|
|||
waitForThreads(10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public
|
||||
void connectTcpUdt() throws InitializationException, SecurityException, IOException, InterruptedException {
|
||||
System.out.println("---- " + "TCP UDT");
|
||||
|
||||
Configuration configuration = new Configuration();
|
||||
configuration.tcpPort = tcpPort;
|
||||
configuration.udtPort = udtPort;
|
||||
configuration.serialization = CryptoSerializationManager.DEFAULT();
|
||||
register(configuration.serialization);
|
||||
|
||||
startServer(configuration);
|
||||
|
||||
configuration.host = host;
|
||||
startClient(configuration);
|
||||
|
||||
waitForThreads(10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public
|
||||
void connectTcpUdpUdt() throws InitializationException, SecurityException, IOException, InterruptedException {
|
||||
System.out.println("---- " + "TCP UDP UDT");
|
||||
|
||||
Configuration configuration = new Configuration();
|
||||
configuration.tcpPort = tcpPort;
|
||||
configuration.udpPort = udpPort;
|
||||
configuration.udtPort = udtPort;
|
||||
configuration.serialization = CryptoSerializationManager.DEFAULT();
|
||||
register(configuration.serialization);
|
||||
|
||||
startServer(configuration);
|
||||
|
||||
configuration.host = host;
|
||||
|
||||
startClient(configuration);
|
||||
|
||||
waitForThreads(10);
|
||||
}
|
||||
|
||||
private
|
||||
Server startServer(Configuration configuration) throws InitializationException, SecurityException, IOException {
|
||||
Server server = new Server(configuration);
|
||||
|
|
|
@ -36,7 +36,6 @@ import dorkbox.network.connection.idle.IdleBridge;
|
|||
import dorkbox.network.connection.idle.IdleListener;
|
||||
import dorkbox.network.connection.idle.IdleListenerTCP;
|
||||
import dorkbox.network.connection.idle.IdleListenerUDP;
|
||||
import dorkbox.network.connection.idle.IdleListenerUDT;
|
||||
import dorkbox.network.connection.idle.InputStreamSender;
|
||||
import dorkbox.util.SerializationManager;
|
||||
import dorkbox.util.exceptions.InitializationException;
|
||||
|
@ -50,8 +49,7 @@ class IdleTest extends BaseTest {
|
|||
|
||||
enum ConnectionType {
|
||||
TCP,
|
||||
UDP,
|
||||
UDT
|
||||
UDP
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -76,16 +74,6 @@ class IdleTest extends BaseTest {
|
|||
configuration.serialization = CryptoSerializationManager.DEFAULT(false, false);
|
||||
|
||||
streamSpecificType(largeDataSize, configuration, ConnectionType.UDP);
|
||||
|
||||
|
||||
System.err.println("-- UDT");
|
||||
configuration = new Configuration();
|
||||
configuration.tcpPort = tcpPort;
|
||||
configuration.udtPort = udtPort;
|
||||
configuration.host = host;
|
||||
configuration.serialization = CryptoSerializationManager.DEFAULT(false, false);
|
||||
|
||||
streamSpecificType(largeDataSize, configuration, ConnectionType.UDT);
|
||||
}
|
||||
|
||||
|
||||
|
@ -117,17 +105,6 @@ class IdleTest extends BaseTest {
|
|||
register(configuration.serialization);
|
||||
|
||||
sendObject(mainData, configuration, ConnectionType.TCP);
|
||||
|
||||
|
||||
System.err.println("-- UDT");
|
||||
configuration = new Configuration();
|
||||
configuration.tcpPort = tcpPort;
|
||||
configuration.udtPort = udtPort;
|
||||
configuration.host = host;
|
||||
configuration.serialization = CryptoSerializationManager.DEFAULT();
|
||||
register(configuration.serialization);
|
||||
|
||||
sendObject(mainData, configuration, ConnectionType.TCP);
|
||||
}
|
||||
|
||||
|
||||
|
@ -155,9 +132,6 @@ class IdleTest extends BaseTest {
|
|||
case UDP:
|
||||
sendOnIdle.UDP();
|
||||
break;
|
||||
case UDT:
|
||||
sendOnIdle.UDT();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -217,9 +191,6 @@ class IdleTest extends BaseTest {
|
|||
case UDP:
|
||||
listener = new IdleListenerUDP<Connection, byte[]>();
|
||||
break;
|
||||
case UDT:
|
||||
listener = new IdleListenerUDT<Connection, byte[]>();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
@ -247,9 +218,6 @@ class IdleTest extends BaseTest {
|
|||
case UDP:
|
||||
sendOnIdle.UDP();
|
||||
break;
|
||||
case UDT:
|
||||
sendOnIdle.UDT();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -45,7 +45,7 @@ class PingPongTest extends BaseTest {
|
|||
|
||||
|
||||
enum TYPE {
|
||||
TCP, UDP, UDT
|
||||
TCP, UDP
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -60,7 +60,6 @@ class PingPongTest extends BaseTest {
|
|||
Configuration configuration = new Configuration();
|
||||
configuration.tcpPort = tcpPort;
|
||||
configuration.udpPort = udpPort;
|
||||
configuration.udtPort = udtPort;
|
||||
configuration.host = host;
|
||||
configuration.serialization = CryptoSerializationManager.DEFAULT();
|
||||
register(configuration.serialization);
|
||||
|
@ -70,8 +69,6 @@ class PingPongTest extends BaseTest {
|
|||
populateData(dataTCP, TYPE.TCP);
|
||||
final Data dataUDP = new Data();
|
||||
populateDataTiny(dataUDP, TYPE.UDP); // UDP has a max size it can send!
|
||||
final Data dataUDT = new Data();
|
||||
populateData(dataUDT, TYPE.UDT);
|
||||
|
||||
Server server = new Server(configuration);
|
||||
addEndPoint(server);
|
||||
|
@ -105,14 +102,6 @@ class PingPongTest extends BaseTest {
|
|||
connection.send()
|
||||
.UDP(dataUDP);
|
||||
}
|
||||
else if (data.type == TYPE.UDT) {
|
||||
if (!data.equals(dataUDT)) {
|
||||
PingPongTest.this.fail = "UDT data is not equal on server.";
|
||||
throw new RuntimeException("Fail! " + PingPongTest.this.fail);
|
||||
}
|
||||
connection.send()
|
||||
.UDT(dataUDT);
|
||||
}
|
||||
else {
|
||||
PingPongTest.this.fail = "Unknown data type on server.";
|
||||
throw new RuntimeException("Fail! " + PingPongTest.this.fail);
|
||||
|
@ -134,8 +123,6 @@ class PingPongTest extends BaseTest {
|
|||
.TCP(dataTCP);
|
||||
connection.send()
|
||||
.UDP(dataUDP); // UDP ping pong stops if a UDP packet is lost.
|
||||
connection.send()
|
||||
.UDT(dataUDT);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -151,10 +138,8 @@ class PingPongTest extends BaseTest {
|
|||
listeners.add(new Listener.OnMessageReceived<Connection, Data>() {
|
||||
AtomicInteger checkTCP = new AtomicInteger(0);
|
||||
AtomicInteger checkUDP = new AtomicInteger(0);
|
||||
AtomicInteger checkUDT = new AtomicInteger(0);
|
||||
AtomicBoolean doneTCP = new AtomicBoolean(false);
|
||||
AtomicBoolean doneUDP = new AtomicBoolean(false);
|
||||
AtomicBoolean doneUDT = new AtomicBoolean(false);
|
||||
|
||||
@Override
|
||||
public
|
||||
|
@ -187,27 +172,13 @@ class PingPongTest extends BaseTest {
|
|||
this.doneUDP.set(true);
|
||||
}
|
||||
}
|
||||
else if (data.type == TYPE.UDT) {
|
||||
if (!data.equals(dataUDT)) {
|
||||
PingPongTest.this.fail = "UDT data is not equal on client.";
|
||||
throw new RuntimeException("Fail! " + PingPongTest.this.fail);
|
||||
}
|
||||
if (this.checkUDT.getAndIncrement() <= PingPongTest.this.tries) {
|
||||
connection.send()
|
||||
.UDT(dataUDT);
|
||||
}
|
||||
else {
|
||||
System.err.println("UDT done.");
|
||||
this.doneUDT.set(true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
PingPongTest.this.fail = "Unknown data type on client.";
|
||||
throw new RuntimeException("Fail! " + PingPongTest.this.fail);
|
||||
}
|
||||
|
||||
if (this.doneTCP.get() && this.doneUDP.get() && this.doneUDT.get()) {
|
||||
System.err.println("Ran TCP, UDP, UDT " + PingPongTest.this.tries + " times each");
|
||||
if (this.doneTCP.get() && this.doneUDP.get()) {
|
||||
System.err.println("Ran TCP, UDP " + PingPongTest.this.tries + " times each");
|
||||
stopEndPoints();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,23 +15,24 @@
|
|||
*/
|
||||
package dorkbox.network;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import dorkbox.network.connection.Connection;
|
||||
import dorkbox.network.connection.Ping;
|
||||
import dorkbox.network.connection.PingListener;
|
||||
import dorkbox.util.exceptions.InitializationException;
|
||||
import dorkbox.util.exceptions.SecurityException;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public
|
||||
class PingTest extends BaseTest {
|
||||
|
||||
private volatile int response = -1;
|
||||
|
||||
// ping prefers the following order: UDP, UDT, TCP
|
||||
// ping prefers the following order: UDP, TCP
|
||||
@Test
|
||||
public
|
||||
void pingTCP() throws InitializationException, SecurityException, IOException, InterruptedException {
|
||||
|
@ -166,7 +167,7 @@ class PingTest extends BaseTest {
|
|||
}
|
||||
}
|
||||
|
||||
// ping prefers the following order: UDP, UDT, TCP
|
||||
// ping prefers the following order: UDP, TCP
|
||||
@Test
|
||||
public
|
||||
void pingUDP() throws InitializationException, SecurityException, IOException, InterruptedException {
|
||||
|
@ -203,42 +204,4 @@ class PingTest extends BaseTest {
|
|||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ping prefers the following order: UDP, UDT, TCP
|
||||
@Test
|
||||
public
|
||||
void pingUDT() throws InitializationException, SecurityException, IOException, InterruptedException {
|
||||
this.response = -1;
|
||||
|
||||
Configuration configuration = new Configuration();
|
||||
configuration.tcpPort = tcpPort;
|
||||
configuration.udtPort = udtPort;
|
||||
configuration.host = host;
|
||||
|
||||
Server server = new Server(configuration);
|
||||
addEndPoint(server);
|
||||
server.bind(false);
|
||||
|
||||
// ----
|
||||
|
||||
Client client = new Client(configuration);
|
||||
addEndPoint(client);
|
||||
|
||||
client.connect(5000);
|
||||
|
||||
System.err.println("Testing UDT ping");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
this.response = client.send()
|
||||
.ping()
|
||||
.getResponse();
|
||||
System.err.println("Ping: " + this.response);
|
||||
}
|
||||
|
||||
stopEndPoints();
|
||||
|
||||
if (this.response == -1) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
*/
|
||||
public
|
||||
class TestCowImpl implements TestCow {
|
||||
// has to start at 1, because UDP/UDT method invocations ignore return values
|
||||
// has to start at 1, because UDP method invocations ignore return values
|
||||
static final AtomicInteger ID_COUNTER = new AtomicInteger(1);
|
||||
|
||||
public long value = System.currentTimeMillis();
|
||||
|
|
|
@ -80,7 +80,6 @@ class TestClient
|
|||
Configuration configuration = new Configuration();
|
||||
configuration.tcpPort = 2000;
|
||||
configuration.udpPort = 2001;
|
||||
configuration.udtPort = 2002;
|
||||
configuration.host = "localhost";
|
||||
|
||||
configuration.serialization = CryptoSerializationManager.DEFAULT();
|
||||
|
|
|
@ -23,7 +23,6 @@ class TestServer
|
|||
dorkbox.network.Configuration configuration = new dorkbox.network.Configuration();
|
||||
configuration.tcpPort = 2000;
|
||||
configuration.udpPort = 2001;
|
||||
configuration.udtPort = 2002;
|
||||
|
||||
configuration.serialization = CryptoSerializationManager.DEFAULT();
|
||||
RmiTest.register(configuration.serialization);
|
||||
|
|
Loading…
Reference in New Issue
Block a user