diff --git a/README.md b/README.md index 8c0093ccdea15215a336c52cdb74586a65e292eb..91077cd4f0dceac03583f11f928f1c66b20cc3f1 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ Available versions: | JInterface | Erlang versions supported | |------------|---------------------------| +| 1.13.2 | >=25.3, <26 | | 1.13.1 | >=25.1, <25.3 | | 1.13 | >=25, <25.1 | | 1.12.2 | >=24.3, <25 | diff --git a/java_src/com/ericsson/otp/erlang/AbstractConnection.java b/java_src/com/ericsson/otp/erlang/AbstractConnection.java index 5949bce166ebf0c0ddbc51a0346ae4b6b1920192..9e6a35ec36872fe5806dd6d3a8becaedacda7b26 100644 --- a/java_src/com/ericsson/otp/erlang/AbstractConnection.java +++ b/java_src/com/ericsson/otp/erlang/AbstractConnection.java @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2000-2022. 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. @@ -1033,6 +1033,7 @@ 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()); @@ -1245,11 +1246,26 @@ 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': + 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); + break; case 'N': apeer.distLow = apeer.distHigh = 6; apeer.flags = ibuf.read8BE(); + flag_mask = ~0L; if ((apeer.flags & AbstractNode.dFlagMandatory25Digest) != 0) { apeer.flags |= AbstractNode.mandatoryFlags25; } @@ -1265,7 +1281,7 @@ public abstract class AbstractConnection extends Thread { throw new IOException("Unknown remote node type"); } - if ((apeer.flags & AbstractNode.mandatoryFlags) != AbstractNode.mandatoryFlags) { + if ((~apeer.flags & flag_mask & AbstractNode.mandatoryFlags) != 0) { throw new IOException( "Handshake failed - peer cannot handle all mandatory capabilities"); } @@ -1336,6 +1352,29 @@ public abstract class AbstractConnection extends Thread { return challenge; } + protected void recvComplement(int send_name_tag) throws IOException { + + if (send_name_tag == 'n') { + 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; + 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"); + } + } + } + protected void sendChallengeReply(final int challenge, final byte[] digest) throws IOException { diff --git a/pom.xml b/pom.xml index eac9effd395a38e7b7a4adbea777383fd084effa..a50acccb8bc095a01aac19c63b0bb40de47fab8f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ program-slicing erlang-jinterface jar - 1.13.1 + 1.13.2 jinterface Jinterface Java package contains java classes, which help you integrate programs written in Java with Erlang.