Loading README.md +1 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ Available versions: | JInterface | Erlang versions supported | |------------|---------------------------| | 1.13 | >=25, <25.1 | | 1.12.2 | >=24.3, <25 | | 1.12.1 | >=24.1, <24.3 | | 1.12 | >=24, <24.1 | Loading java_src/com/ericsson/otp/erlang/AbstractConnection.java +74 −131 Original line number Diff line number Diff line /* * %CopyrightBegin% * * Copyright Ericsson AB 2000-2021. All Rights Reserved. * Copyright Ericsson AB 2000-2022. 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. Loading Loading @@ -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'; Loading Loading @@ -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"); Loading @@ -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; Loading Loading @@ -1025,7 +1033,6 @@ public abstract class AbstractConnection extends Thread { sendStatus("ok"); final int our_challenge = genChallenge(); sendChallenge(peer.flags, localNode.flags, our_challenge); recvComplement(send_name_tag); final int her_challenge = recvChallengeReply(our_challenge); final byte[] our_digest = genDigest(her_challenge, localNode.cookie()); Loading @@ -1052,27 +1059,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; Loading Loading @@ -1149,15 +1180,6 @@ 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); Loading @@ -1165,63 +1187,29 @@ public abstract class AbstractConnection extends Thread { 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.write4BE(localNode.creation()); obuf.write2BE(str.length()); obuf.write(str.getBytes()); } obuf.writeToAndFlush(socket.getOutputStream()); Loading Loading @@ -1259,21 +1247,15 @@ public abstract class AbstractConnection extends Thread { final int len = tmpbuf.length; send_name_tag = ibuf.read1(); switch (send_name_tag) { case 'n': apeer.distLow = apeer.distHigh = ibuf.read2BE(); if (apeer.distLow != 5) throw new IOException("Invalid handshake version"); apeer.flags = ibuf.read4BE(); tmpname = new byte[len - 7]; ibuf.readN(tmpname); hisname = OtpErlangString.newString(tmpname); break; case 'N': apeer.distLow = apeer.distHigh = 6; apeer.flags = ibuf.read8BE(); 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); Loading @@ -1283,21 +1265,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 & AbstractNode.mandatoryFlags) != AbstractNode.mandatoryFlags) { 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()); Loading @@ -1319,23 +1296,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: Loading @@ -1348,15 +1318,9 @@ public abstract class AbstractConnection extends Thread { throw new IOException( "Handshake failed - peer has wrong name: " + hisname); } if ((peer.flags & AbstractNode.dFlagExtendedReferences) == 0) { throw new IOException( "Handshake failed - peer cannot handle extended references"); } if ((peer.flags & AbstractNode.dFlagExtendedPidsPorts) == 0) { if ((peer.flags & AbstractNode.mandatoryFlags) != AbstractNode.mandatoryFlags) { throw new IOException( "Handshake failed - peer cannot handle extended pids and ports"); "Handshake failed - peer cannot handle all mandatory capabilities"); } } catch (final OtpErlangDecodeException e) { Loading @@ -1372,27 +1336,6 @@ public abstract class AbstractConnection extends Thread { return challenge; } protected void recvComplement(int send_name_tag) throws IOException { if (send_name_tag == 'n' && (peer.flags & AbstractNode.dFlagHandshake23) != 0) { try { final byte[] tmpbuf = read2BytePackage(); @SuppressWarnings("resource") final OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0); if (ibuf.read1() != 'c') throw new IOException("Not a complement tag"); final long flagsHigh = ibuf.read4BE(); peer.flags |= flagsHigh << 32; peer.creation = ibuf.read4BE(); } catch (final OtpErlangDecodeException e) { throw new IOException("Handshake failed - not enough data"); } } } protected void sendChallengeReply(final int challenge, final byte[] digest) throws IOException { Loading java_src/com/ericsson/otp/erlang/AbstractNode.java +73 −12 Original line number Diff line number Diff line /* * %CopyrightBegin% * * Copyright Ericsson AB 2000-2021. All Rights Reserved. * Copyright Ericsson AB 2000-2022. 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. Loading Loading @@ -95,21 +95,35 @@ public class AbstractNode implements OtpTransportFactory { static final int dFlagBigCreation = 0x40000; static final int dFlagHandshake23 = 0x1000000; static final int dFlagUnlinkId = 0x2000000; static final int dFlagMandatory25Digest = 0x4000000; static final long dFlagV4PidsRefs = 0x4L << 32; /* Mandatory flags in OTP 25. */ static final long mandatoryFlags25 = dFlagExtendedReferences | dFlagFunTags | dFlagExtendedPidsPorts | dFlagUtf8Atoms | dflagNewFunTags | dFlagBigCreation | dFlagNewFloats | dFlagMapTag | dFlagExportPtrTag | dFlagBitBinaries | dFlagHandshake23; /* Mandatory flags for distribution. Keep them in sync with DFLAG_DIST_MANDATORY in erts/emulator/beam/dist.h. */ static final long mandatoryFlags = mandatoryFlags25; int ntype = NTYPE_R6; int proto = 0; // tcp/ip int distHigh = 6; int distLow = 5; // Cannot talk to nodes before R6 int creation = 0; long flags = dFlagExtendedReferences | dFlagExtendedPidsPorts | dFlagBitBinaries | dFlagNewFloats | dFlagFunTags | dflagNewFunTags | dFlagUtf8Atoms | dFlagMapTag | dFlagExportPtrTag | dFlagBigCreation | dFlagHandshake23 int distLow = 6; // Cannot talk to nodes before OTP 23 private int creation = 0x710000; long flags = mandatoryFlags | dFlagUnlinkId | dFlagV4PidsRefs; | dFlagV4PidsRefs | dFlagMandatory25Digest; /* initialize hostname and default cookie */ static { Loading Loading @@ -190,7 +204,7 @@ public class AbstractNode implements OtpTransportFactory { this.cookie = cookie; this.transportFactory = transportFactory; final int i = name.indexOf('@', 0); final int i = name.indexOf('@'); if (i < 0) { alive = name; host = localHost; Loading Loading @@ -271,6 +285,13 @@ public class AbstractNode implements OtpTransportFactory { return creation; } void setCreation(int cr) throws OtpErlangDecodeException { if (cr == 0) { throw new OtpErlangDecodeException("Node creation 0 not allowed"); } this.creation = cr; } /** * Set the authorization cookie used by this node. * Loading Loading @@ -311,4 +332,44 @@ public class AbstractNode implements OtpTransportFactory { throws IOException { return transportFactory.createServerTransport(port); } /** * Create a client-side transport for alternative distribution protocols * using a transport factory extending the OtpGenericTransportFactory * abstract class. Connect it to the specified server. * * @param peer * the peer identifying the server to connect to * */ public OtpTransport createTransport(final OtpPeer peer) throws IOException { if (transportFactory instanceof OtpGenericTransportFactory) { return ((OtpGenericTransportFactory) transportFactory) .createTransport(peer); } throw new IOException("Method createTransport(OtpPeer) " + "applicable only for Nodes with a transport " + "factory instance of OtpGenericTransportFactory"); } /** * Create a server-side transport for alternative distribution protocols * using a transport factory extending the OtpGenericTransportFactory * abstract class. * * @param node * the local node identifying the transport to create server-side * */ public OtpServerTransport createServerTransport(final OtpLocalNode node) throws IOException { if (transportFactory instanceof OtpGenericTransportFactory) { return ((OtpGenericTransportFactory) transportFactory) .createServerTransport(node); } throw new IOException("Method createServerTransport(OtpLocalNode) " + "applicable only for Nodes with a transport " + "factory instance of OtpGenericTransportFactory"); } } java_src/com/ericsson/otp/erlang/OtpConnection.java +3 −3 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ import java.io.IOException; * * <p> * If an exception occurs in any of the methods in this class, the connection * will be closed and must be explicitely reopened in order to resume * will be closed and must be explicitly reopened in order to resume * communication with the peer. * * <p> Loading Loading @@ -317,7 +317,7 @@ public class OtpConnection extends AbstractConnection { } /** * Receive a messge complete with sender and recipient information. * Receive a message complete with sender and recipient information. * * @return an {@link OtpMsg OtpMsg} containing the header information about * the sender and recipient, as well as the actual message contents. Loading Loading @@ -352,7 +352,7 @@ public class OtpConnection extends AbstractConnection { } /** * Receive a messge complete with sender and recipient information. This * Receive a message complete with sender and recipient information. This * method blocks at most for the specified time. * * @param timeout Loading java_src/com/ericsson/otp/erlang/OtpCookedConnection.java +1 −1 Original line number Diff line number Diff line Loading @@ -182,7 +182,7 @@ public class OtpCookedConnection extends AbstractConnection { } /* * this one called explicitely by user code => use exit2 * this one called explicitly by user code => use exit2 */ void exit2(final OtpErlangPid from, final OtpErlangPid to, final OtpErlangObject reason) { Loading Loading
README.md +1 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ Available versions: | JInterface | Erlang versions supported | |------------|---------------------------| | 1.13 | >=25, <25.1 | | 1.12.2 | >=24.3, <25 | | 1.12.1 | >=24.1, <24.3 | | 1.12 | >=24, <24.1 | Loading
java_src/com/ericsson/otp/erlang/AbstractConnection.java +74 −131 Original line number Diff line number Diff line /* * %CopyrightBegin% * * Copyright Ericsson AB 2000-2021. All Rights Reserved. * Copyright Ericsson AB 2000-2022. 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. Loading Loading @@ -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'; Loading Loading @@ -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"); Loading @@ -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; Loading Loading @@ -1025,7 +1033,6 @@ public abstract class AbstractConnection extends Thread { sendStatus("ok"); final int our_challenge = genChallenge(); sendChallenge(peer.flags, localNode.flags, our_challenge); recvComplement(send_name_tag); final int her_challenge = recvChallengeReply(our_challenge); final byte[] our_digest = genDigest(her_challenge, localNode.cookie()); Loading @@ -1052,27 +1059,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; Loading Loading @@ -1149,15 +1180,6 @@ 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); Loading @@ -1165,63 +1187,29 @@ public abstract class AbstractConnection extends Thread { 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.write4BE(localNode.creation()); obuf.write2BE(str.length()); obuf.write(str.getBytes()); } obuf.writeToAndFlush(socket.getOutputStream()); Loading Loading @@ -1259,21 +1247,15 @@ public abstract class AbstractConnection extends Thread { final int len = tmpbuf.length; send_name_tag = ibuf.read1(); switch (send_name_tag) { case 'n': apeer.distLow = apeer.distHigh = ibuf.read2BE(); if (apeer.distLow != 5) throw new IOException("Invalid handshake version"); apeer.flags = ibuf.read4BE(); tmpname = new byte[len - 7]; ibuf.readN(tmpname); hisname = OtpErlangString.newString(tmpname); break; case 'N': apeer.distLow = apeer.distHigh = 6; apeer.flags = ibuf.read8BE(); 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); Loading @@ -1283,21 +1265,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 & AbstractNode.mandatoryFlags) != AbstractNode.mandatoryFlags) { 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()); Loading @@ -1319,23 +1296,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: Loading @@ -1348,15 +1318,9 @@ public abstract class AbstractConnection extends Thread { throw new IOException( "Handshake failed - peer has wrong name: " + hisname); } if ((peer.flags & AbstractNode.dFlagExtendedReferences) == 0) { throw new IOException( "Handshake failed - peer cannot handle extended references"); } if ((peer.flags & AbstractNode.dFlagExtendedPidsPorts) == 0) { if ((peer.flags & AbstractNode.mandatoryFlags) != AbstractNode.mandatoryFlags) { throw new IOException( "Handshake failed - peer cannot handle extended pids and ports"); "Handshake failed - peer cannot handle all mandatory capabilities"); } } catch (final OtpErlangDecodeException e) { Loading @@ -1372,27 +1336,6 @@ public abstract class AbstractConnection extends Thread { return challenge; } protected void recvComplement(int send_name_tag) throws IOException { if (send_name_tag == 'n' && (peer.flags & AbstractNode.dFlagHandshake23) != 0) { try { final byte[] tmpbuf = read2BytePackage(); @SuppressWarnings("resource") final OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0); if (ibuf.read1() != 'c') throw new IOException("Not a complement tag"); final long flagsHigh = ibuf.read4BE(); peer.flags |= flagsHigh << 32; peer.creation = ibuf.read4BE(); } catch (final OtpErlangDecodeException e) { throw new IOException("Handshake failed - not enough data"); } } } protected void sendChallengeReply(final int challenge, final byte[] digest) throws IOException { Loading
java_src/com/ericsson/otp/erlang/AbstractNode.java +73 −12 Original line number Diff line number Diff line /* * %CopyrightBegin% * * Copyright Ericsson AB 2000-2021. All Rights Reserved. * Copyright Ericsson AB 2000-2022. 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. Loading Loading @@ -95,21 +95,35 @@ public class AbstractNode implements OtpTransportFactory { static final int dFlagBigCreation = 0x40000; static final int dFlagHandshake23 = 0x1000000; static final int dFlagUnlinkId = 0x2000000; static final int dFlagMandatory25Digest = 0x4000000; static final long dFlagV4PidsRefs = 0x4L << 32; /* Mandatory flags in OTP 25. */ static final long mandatoryFlags25 = dFlagExtendedReferences | dFlagFunTags | dFlagExtendedPidsPorts | dFlagUtf8Atoms | dflagNewFunTags | dFlagBigCreation | dFlagNewFloats | dFlagMapTag | dFlagExportPtrTag | dFlagBitBinaries | dFlagHandshake23; /* Mandatory flags for distribution. Keep them in sync with DFLAG_DIST_MANDATORY in erts/emulator/beam/dist.h. */ static final long mandatoryFlags = mandatoryFlags25; int ntype = NTYPE_R6; int proto = 0; // tcp/ip int distHigh = 6; int distLow = 5; // Cannot talk to nodes before R6 int creation = 0; long flags = dFlagExtendedReferences | dFlagExtendedPidsPorts | dFlagBitBinaries | dFlagNewFloats | dFlagFunTags | dflagNewFunTags | dFlagUtf8Atoms | dFlagMapTag | dFlagExportPtrTag | dFlagBigCreation | dFlagHandshake23 int distLow = 6; // Cannot talk to nodes before OTP 23 private int creation = 0x710000; long flags = mandatoryFlags | dFlagUnlinkId | dFlagV4PidsRefs; | dFlagV4PidsRefs | dFlagMandatory25Digest; /* initialize hostname and default cookie */ static { Loading Loading @@ -190,7 +204,7 @@ public class AbstractNode implements OtpTransportFactory { this.cookie = cookie; this.transportFactory = transportFactory; final int i = name.indexOf('@', 0); final int i = name.indexOf('@'); if (i < 0) { alive = name; host = localHost; Loading Loading @@ -271,6 +285,13 @@ public class AbstractNode implements OtpTransportFactory { return creation; } void setCreation(int cr) throws OtpErlangDecodeException { if (cr == 0) { throw new OtpErlangDecodeException("Node creation 0 not allowed"); } this.creation = cr; } /** * Set the authorization cookie used by this node. * Loading Loading @@ -311,4 +332,44 @@ public class AbstractNode implements OtpTransportFactory { throws IOException { return transportFactory.createServerTransport(port); } /** * Create a client-side transport for alternative distribution protocols * using a transport factory extending the OtpGenericTransportFactory * abstract class. Connect it to the specified server. * * @param peer * the peer identifying the server to connect to * */ public OtpTransport createTransport(final OtpPeer peer) throws IOException { if (transportFactory instanceof OtpGenericTransportFactory) { return ((OtpGenericTransportFactory) transportFactory) .createTransport(peer); } throw new IOException("Method createTransport(OtpPeer) " + "applicable only for Nodes with a transport " + "factory instance of OtpGenericTransportFactory"); } /** * Create a server-side transport for alternative distribution protocols * using a transport factory extending the OtpGenericTransportFactory * abstract class. * * @param node * the local node identifying the transport to create server-side * */ public OtpServerTransport createServerTransport(final OtpLocalNode node) throws IOException { if (transportFactory instanceof OtpGenericTransportFactory) { return ((OtpGenericTransportFactory) transportFactory) .createServerTransport(node); } throw new IOException("Method createServerTransport(OtpLocalNode) " + "applicable only for Nodes with a transport " + "factory instance of OtpGenericTransportFactory"); } }
java_src/com/ericsson/otp/erlang/OtpConnection.java +3 −3 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ import java.io.IOException; * * <p> * If an exception occurs in any of the methods in this class, the connection * will be closed and must be explicitely reopened in order to resume * will be closed and must be explicitly reopened in order to resume * communication with the peer. * * <p> Loading Loading @@ -317,7 +317,7 @@ public class OtpConnection extends AbstractConnection { } /** * Receive a messge complete with sender and recipient information. * Receive a message complete with sender and recipient information. * * @return an {@link OtpMsg OtpMsg} containing the header information about * the sender and recipient, as well as the actual message contents. Loading Loading @@ -352,7 +352,7 @@ public class OtpConnection extends AbstractConnection { } /** * Receive a messge complete with sender and recipient information. This * Receive a message complete with sender and recipient information. This * method blocks at most for the specified time. * * @param timeout Loading
java_src/com/ericsson/otp/erlang/OtpCookedConnection.java +1 −1 Original line number Diff line number Diff line Loading @@ -182,7 +182,7 @@ public class OtpCookedConnection extends AbstractConnection { } /* * this one called explicitely by user code => use exit2 * this one called explicitly by user code => use exit2 */ void exit2(final OtpErlangPid from, final OtpErlangPid to, final OtpErlangObject reason) { Loading