Add hook for validating an outgoing connection.

Sometimes a present node uses a port to connect outwards that another
node is listening on.. I considered building-in some smarts for this
into the peer stuff, but for now at least I'll keep it simpler and
more flexible.
This commit is contained in:
Ray J. Greenwell
2018-09-24 12:54:25 -07:00
parent 63ff5753f4
commit 9c986bc4a9
@@ -75,6 +75,29 @@ import static com.threerings.presents.Log.log;
public class PresentsConnectionManager extends ConnectionManager public class PresentsConnectionManager extends ConnectionManager
implements ReportManager.Reporter implements ReportManager.Reporter
{ {
/**
* Used to validate outgoing connections.
*/
public interface OutgoingConnectionValidator
{
/**
* Validate the outgoing connection.
*/
public void validateOutgoing (SocketChannel sockchan)
throws IOException;
/**
* A default validator that does nothing.
*/
public static final OutgoingConnectionValidator DEFAULT =
new OutgoingConnectionValidator() {
public void validateOutgoing (SocketChannel sockchan)
throws IOException
{
// nada!
}
};
}
@Inject @Inject
public PresentsConnectionManager (Lifecycle cycle, ReportManager repmgr) public PresentsConnectionManager (Lifecycle cycle, ReportManager repmgr)
@@ -92,6 +115,14 @@ public class PresentsConnectionManager extends ConnectionManager
return ((PresentsConMgrStats)super.getStats()); return ((PresentsConMgrStats)super.getStats());
} }
/**
* Set the validator that checks outgoing connections.
*/
public void setOutgoingConnectionValidator (OutgoingConnectionValidator outConnValidator)
{
_outConnValidator = outConnValidator;
}
// from interface ReportManager.Reporter // from interface ReportManager.Reporter
public void appendReport (StringBuilder report, long now, long sinceLast, boolean reset) public void appendReport (StringBuilder report, long now, long sinceLast, boolean reset)
{ {
@@ -360,6 +391,7 @@ public class PresentsConnectionManager extends ConnectionManager
// start our connection process (now if we fail we need to clean things up) // start our connection process (now if we fail we need to clean things up)
NetEventHandler handler; NetEventHandler handler;
if (sockchan.connect(addr)) { if (sockchan.connect(addr)) {
_outConnValidator.validateOutgoing(sockchan); // may throw
// it is possible even for a non-blocking socket to connect immediately, in which // it is possible even for a non-blocking socket to connect immediately, in which
// case we stick the connection in as its event handler immediately // case we stick the connection in as its event handler immediately
handler = conn; handler = conn;
@@ -551,6 +583,7 @@ public class PresentsConnectionManager extends ConnectionManager
SocketChannel sockchan = _conn.getChannel(); SocketChannel sockchan = _conn.getChannel();
try { try {
if (sockchan.finishConnect()) { if (sockchan.finishConnect()) {
_outConnValidator.validateOutgoing(sockchan); // may throw
// great, we're ready to roll, wire up the connection // great, we're ready to roll, wire up the connection
_conn.selkey = sockchan.register(_selector, SelectionKey.OP_READ); _conn.selkey = sockchan.register(_selector, SelectionKey.OP_READ);
_handlers.put(_conn.selkey, _conn); _handlers.put(_conn.selkey, _conn);
@@ -599,6 +632,8 @@ public class PresentsConnectionManager extends ConnectionManager
protected FramingOutputStream _framer = new FramingOutputStream(); protected FramingOutputStream _framer = new FramingOutputStream();
protected ByteArrayOutputStream _flattener = new ByteArrayOutputStream(); protected ByteArrayOutputStream _flattener = new ByteArrayOutputStream();
protected OutgoingConnectionValidator _outConnValidator = OutgoingConnectionValidator.DEFAULT;
// some dependencies // some dependencies
@Inject @AuthInvoker protected Invoker _authInvoker; @Inject @AuthInvoker protected Invoker _authInvoker;
@Inject protected ClientManager _clmgr; @Inject protected ClientManager _clmgr;