diff options
Diffstat (limited to 'lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java')
-rw-r--r-- | lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java | 194 |
1 files changed, 88 insertions, 106 deletions
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java index 7ea5d52da7..9e6a35ec36 100644 --- a/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java +++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2000-2021. All Rights Reserved. + * Copyright Ericsson AB 2000-2023. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -79,7 +79,7 @@ public abstract class AbstractConnection extends Thread { protected static final int unlinkIdTag = 35; protected static final int unlinkIdAckTag = 36; - // MD5 challenge messsage tags + // MD5 challenge message tags protected static final int ChallengeReply = 'r'; protected static final int ChallengeAck = 'a'; protected static final int ChallengeStatus = 's'; @@ -166,18 +166,12 @@ public abstract class AbstractConnection extends Thread { throws IOException, OtpAuthException { peer = other; localNode = self; - socket = null; int port; traceLevel = defaultLevel; setDaemon(true); - // now get a connection between the two... - port = OtpEpmd.lookupPort(peer); - if (port == 0) - throw new IOException("No remote node found - cannot connect"); - - // now find highest common dist value + // Find highest common dist value if (peer.proto != self.proto || self.distHigh < peer.distLow || self.distLow > peer.distHigh) { throw new IOException("No common protocol found - cannot connect"); @@ -187,7 +181,21 @@ public abstract class AbstractConnection extends Thread { peer.distChoose = peer.distHigh > self.distHigh ? self.distHigh : peer.distHigh; - doConnect(port); + // Now get a connection between the two nodes + if (self.transportFactory instanceof OtpGenericTransportFactory) { + // For alternative distribution protocols using a transport factory + // extending the OtpGenericTransportFactory class, the notion of + // socket port is not used so the remote node is not registered + // with Epmd. + doGenericConnect(); + + } else { + // Get the listening port of the remote node registered with Epmd + port = OtpEpmd.lookupPort(peer); + if (port == 0) + throw new IOException("No remote node found - cannot connect"); + doPortConnect(port); + } name = peer.node(); connected = true; @@ -1052,27 +1060,51 @@ public abstract class AbstractConnection extends Thread { } } - protected void doConnect(final int port) throws IOException, + protected void doPortConnect(final int port) throws IOException, OtpAuthException { try { socket = peer.createTransport(peer.host(), port); - if (traceLevel >= handshakeThreshold) { System.out.println("-> MD5 CONNECT TO " + peer.host() + ":" + port); } + doConnect(); + + } catch (final OtpAuthException ae) { + close(); + throw ae; + } catch (final Exception e) { + close(); + final IOException ioe = new IOException( + "Cannot connect to peer node"); + ioe.initCause(e); + throw ioe; + } + } + + protected void doConnect() throws IOException, OtpAuthException { final int send_name_tag = sendName(peer.distChoose, localNode.flags, - localNode.creation); + localNode.creation()); recvStatus(); final int her_challenge = recvChallenge(); final byte[] our_digest = genDigest(her_challenge, localNode.cookie()); final int our_challenge = genChallenge(); - sendComplement(send_name_tag); sendChallengeReply(our_challenge, our_digest); recvChallengeAck(our_challenge); cookieOk = true; sendCookie = false; + } + + protected void doGenericConnect() throws IOException, + OtpAuthException { + try { + socket = peer.createTransport(peer); + if (traceLevel >= handshakeThreshold) { + System.out.println("-> MD5 CONNECT TO " + peer.node()); + } + doConnect(); + } catch (final OtpAuthException ae) { close(); throw ae; @@ -1149,79 +1181,36 @@ public abstract class AbstractConnection extends Thread { final OtpOutputStream obuf = new OtpOutputStream(); final String str = localNode.node(); int send_name_tag; - if (dist == 5) { - obuf.write2BE(1+2+4 + str.length()); - send_name_tag = 'n'; - obuf.write1(send_name_tag); - obuf.write2BE(dist); - obuf.write4BE(aflags); - obuf.write(str.getBytes()); - } - else { - obuf.write2BE(1+8+4+2 + str.length()); - send_name_tag = 'N'; - obuf.write1(send_name_tag); - obuf.write8BE(aflags); - obuf.write4BE(creation); - obuf.write2BE(str.length()); - obuf.write(str.getBytes()); - } + obuf.write2BE(1+8+4+2 + str.length()); + send_name_tag = 'N'; + obuf.write1(send_name_tag); + obuf.write8BE(aflags); + obuf.write4BE(creation); + obuf.write2BE(str.length()); + obuf.write(str.getBytes()); obuf.writeToAndFlush(socket.getOutputStream()); if (traceLevel >= handshakeThreshold) { System.out.println("-> " + "HANDSHAKE sendName" + " flags=" - + aflags + " dist=" + dist + " local=" + localNode); + + aflags + " local=" + localNode); } return send_name_tag; } - protected void sendComplement(final int send_name_tag) - throws IOException { - - if (send_name_tag == 'n' && - (peer.flags & AbstractNode.dFlagHandshake23) != 0) { - @SuppressWarnings("resource") - final OtpOutputStream obuf = new OtpOutputStream(); - obuf.write2BE(1+4+4); - obuf.write1('c'); - final int flagsHigh = (int)(localNode.flags >> 32); - obuf.write4BE(flagsHigh); - obuf.write4BE(localNode.creation); - - obuf.writeToAndFlush(socket.getOutputStream()); - - if (traceLevel >= handshakeThreshold) { - System.out.println("-> " + "HANDSHAKE sendComplement" + - " flagsHigh=" + flagsHigh + - " creation=" + localNode.creation); - } - } - } - protected void sendChallenge(final long her_flags, final long our_flags, final int challenge) throws IOException { @SuppressWarnings("resource") final OtpOutputStream obuf = new OtpOutputStream(); final String str = localNode.node(); - if ((her_flags & AbstractNode.dFlagHandshake23) == 0) { - obuf.write2BE(1+2+4+4 + str.length()); - obuf.write1('n'); - obuf.write2BE(5); - obuf.write4BE(our_flags & 0xffffffff); - obuf.write4BE(challenge); - obuf.write(str.getBytes()); - } - else { - obuf.write2BE(1+8+4+4+2 + str.length()); - obuf.write1('N'); - obuf.write8BE(our_flags); - obuf.write4BE(challenge); - obuf.write4BE(localNode.creation); - obuf.write2BE(str.length()); - obuf.write(str.getBytes()); - } + obuf.write2BE(1+8+4+4+2 + str.length()); + obuf.write1('N'); + obuf.write8BE(our_flags); + obuf.write4BE(challenge); + obuf.write4BE(localNode.creation()); + obuf.write2BE(str.length()); + obuf.write(str.getBytes()); obuf.writeToAndFlush(socket.getOutputStream()); @@ -1257,13 +1246,18 @@ public abstract class AbstractConnection extends Thread { final OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0); byte[] tmpname; final int len = tmpbuf.length; + long flag_mask; + send_name_tag = ibuf.read1(); switch (send_name_tag) { case 'n': - apeer.distLow = apeer.distHigh = ibuf.read2BE(); - if (apeer.distLow != 5) + if (ibuf.read2BE() != 5) throw new IOException("Invalid handshake version"); apeer.flags = ibuf.read4BE(); + flag_mask = (1L << 32) - 1; + if ((apeer.flags & AbstractNode.dFlagHandshake23) == 0) + throw new IOException("Missing DFLAG_HANDSHAKE_23"); + apeer.distLow = apeer.distHigh = 6; tmpname = new byte[len - 7]; ibuf.readN(tmpname); hisname = OtpErlangString.newString(tmpname); @@ -1271,9 +1265,13 @@ public abstract class AbstractConnection extends Thread { case 'N': apeer.distLow = apeer.distHigh = 6; apeer.flags = ibuf.read8BE(); + flag_mask = ~0L; + if ((apeer.flags & AbstractNode.dFlagMandatory25Digest) != 0) { + apeer.flags |= AbstractNode.mandatoryFlags25; + } if ((apeer.flags & AbstractNode.dFlagHandshake23) == 0) throw new IOException("Missing DFLAG_HANDSHAKE_23"); - apeer.creation = ibuf.read4BE(); + apeer.setCreation(ibuf.read4BE()); int namelen = ibuf.read2BE(); tmpname = new byte[namelen]; ibuf.readN(tmpname); @@ -1283,21 +1281,16 @@ public abstract class AbstractConnection extends Thread { throw new IOException("Unknown remote node type"); } - if ((apeer.flags & AbstractNode.dFlagExtendedReferences) == 0) { - throw new IOException( - "Handshake failed - peer cannot handle extended references"); - } - - if ((apeer.flags & AbstractNode.dFlagExtendedPidsPorts) == 0) { + if ((~apeer.flags & flag_mask & AbstractNode.mandatoryFlags) != 0) { throw new IOException( - "Handshake failed - peer cannot handle extended pids and ports"); + "Handshake failed - peer cannot handle all mandatory capabilities"); } } catch (final OtpErlangDecodeException e) { throw new IOException("Handshake failed - not enough data"); } - final int i = hisname.indexOf('@', 0); + final int i = hisname.indexOf('@'); apeer.node = hisname; apeer.alive = hisname.substring(0, i); apeer.host = hisname.substring(i + 1, hisname.length()); @@ -1319,23 +1312,16 @@ public abstract class AbstractConnection extends Thread { final OtpInputStream ibuf = new OtpInputStream(buf, 0); int namelen; switch (ibuf.read1()) { - case 'n': - if (peer.distChoose != 5) - throw new IOException("Old challenge wrong version"); - peer.distLow = peer.distHigh = ibuf.read2BE(); - peer.flags = ibuf.read4BE(); - if ((peer.flags & AbstractNode.dFlagHandshake23) != 0) - throw new IOException("Old challenge unexpected DFLAG_HANDHAKE_23"); - challenge = ibuf.read4BE(); - namelen = buf.length - (1+2+4+4); - break; case 'N': peer.distLow = peer.distHigh = peer.distChoose = 6; peer.flags = ibuf.read8BE(); + if ((peer.flags & AbstractNode.dFlagMandatory25Digest) != 0) { + peer.flags |= AbstractNode.mandatoryFlags25; + } if ((peer.flags & AbstractNode.dFlagHandshake23) == 0) throw new IOException("New challenge missing DFLAG_HANDHAKE_23"); challenge = ibuf.read4BE(); - peer.creation = ibuf.read4BE(); + peer.setCreation(ibuf.read4BE()); namelen = ibuf.read2BE(); break; default: @@ -1348,15 +1334,9 @@ public abstract class AbstractConnection extends Thread { throw new IOException( "Handshake failed - peer has wrong name: " + hisname); } - - if ((peer.flags & AbstractNode.dFlagExtendedReferences) == 0) { + if ((peer.flags & AbstractNode.mandatoryFlags) != AbstractNode.mandatoryFlags) { throw new IOException( - "Handshake failed - peer cannot handle extended references"); - } - - if ((peer.flags & AbstractNode.dFlagExtendedPidsPorts) == 0) { - throw new IOException( - "Handshake failed - peer cannot handle extended pids and ports"); + "Handshake failed - peer cannot handle all mandatory capabilities"); } } catch (final OtpErlangDecodeException e) { @@ -1374,8 +1354,7 @@ public abstract class AbstractConnection extends Thread { protected void recvComplement(int send_name_tag) throws IOException { - if (send_name_tag == 'n' && - (peer.flags & AbstractNode.dFlagHandshake23) != 0) { + if (send_name_tag == 'n') { try { final byte[] tmpbuf = read2BytePackage(); @SuppressWarnings("resource") @@ -1385,8 +1364,11 @@ public abstract class AbstractConnection extends Thread { final long flagsHigh = ibuf.read4BE(); peer.flags |= flagsHigh << 32; - peer.creation = ibuf.read4BE(); - + if ((~peer.flags & AbstractNode.mandatoryFlags) != 0) { + throw new IOException("Handshake failed - peer missing" + + " mandatory capabilities"); + } + peer.setCreation(ibuf.read4BE()); } catch (final OtpErlangDecodeException e) { throw new IOException("Handshake failed - not enough data"); } |