protected void recvChallengeAck(int our_challenge) { byte[] her_digest = new byte[16]; try { byte[] buf = read2BytePackage(); OtpInputStream ibuf = new OtpInputStream(buf, 0); int tag = ibuf.read1(); if (tag != ChallengeAck) { throw new IOException("Handshake protocol error"); } ibuf.readN(her_digest); byte[] our_digest = genDigest(our_challenge, self.Cookie); if (!digests_equals(her_digest, our_digest)) { throw new OtpAuthException("Peer authentication error."); } } catch (OtpErlangDecodeException) { throw new IOException("Handshake failed - not enough data"); } catch (Exception) { throw new OtpAuthException("Peer authentication error."); } if (traceLevel >= handshakeThreshold) { log.Debug("<- " + "HANDSHAKE recvChallengeAck" + " from=" + peer.Node + " digest=" + hex(her_digest) + " local=" + self); } }
protected int recvChallenge() { int challenge; try { byte[] buf = read2BytePackage(); OtpInputStream ibuf = new OtpInputStream(buf, 0); peer.Type = ibuf.read1(); if (peer.Type != AbstractNode.NTYPE_R6) { throw new IOException("Unexpected peer type"); } peer.DistLow = peer.DistHigh = ibuf.read2BE(); peer.Flags = ibuf.read4BE(); challenge = ibuf.read4BE(); byte[] tmpname = new byte[buf.Length - 11]; ibuf.readN(tmpname); String hisname = OtpErlangString.newString(tmpname); if (!hisname.Equals(peer.Node)) { 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) { throw new IOException("Handshake failed - peer cannot handle extended pids and ports"); } } catch (OtpErlangDecodeException) { throw new IOException("Handshake failed - not enough data"); } if (traceLevel >= handshakeThreshold) { log.Debug("<- " + "HANDSHAKE recvChallenge" + " from=" + peer.Node + " challenge=" + challenge + " local=" + self); } return challenge; }
protected void recvStatus() { try { byte[] buf = read2BytePackage(); OtpInputStream ibuf = new OtpInputStream(buf, 0); int tag = ibuf.read1(); if (tag != ChallengeStatus) { throw new IOException("Handshake protocol error"); } byte[] tmpbuf = new byte[buf.Length - 1]; ibuf.readN(tmpbuf); String status = OtpErlangString.newString(tmpbuf); if (status.CompareTo("ok") != 0) { throw new IOException("Peer replied with status '" + status + "' instead of 'ok'"); } } catch (OtpErlangDecodeException) { throw new IOException("Handshake failed - not enough data"); } if (traceLevel >= handshakeThreshold) { log.Debug("<- " + "HANDSHAKE recvStatus (ok)" + " local=" + self); } }
protected void recvName(OtpPeer peer) { String hisname = ""; try { byte[] tmpbuf = read2BytePackage(); OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0); byte[] tmpname; int len = tmpbuf.Length; peer.Type = ibuf.read1(); if (peer.Type != AbstractNode.NTYPE_R6) { throw new IOException("Unknown remote node type"); } peer.DistLow = peer.DistHigh = ibuf.read2BE(); if (peer.DistLow < 5) { throw new IOException("Unknown remote node type"); } peer.Flags = ibuf.read4BE(); tmpname = new byte[len - 7]; ibuf.readN(tmpname); hisname = OtpErlangString.newString(tmpname); // Set the old nodetype parameter to indicate hidden/normal status // When the old handshake is removed, the ntype should also be. if ((peer.Flags & AbstractNode.dFlagPublished) != 0) { peer.Type = AbstractNode.NTYPE_R4_ERLANG; } else { peer.Type = AbstractNode.NTYPE_R4_HIDDEN; } if ((peer.Flags & AbstractNode.dFlagExtendedReferences) == 0) { 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"); } } catch (OtpErlangDecodeException) { throw new IOException("Handshake failed - not enough data"); } int i = hisname.IndexOf('@', 0); peer.Node = hisname; peer.Alive = hisname.Substring(0, i); peer.Host = hisname.Substring(i + 1, hisname.Length - (i + 1)); if (traceLevel >= handshakeThreshold) { log.Debug("<- " + "HANDSHAKE" + " ntype=" + peer.Type + " dist=" + peer.DistHigh + " remote=" + peer); } }
private void r4_publish(TcpClient s, OtpInputStream ibuf) { try { int port = ibuf.read2BE(); int type = ibuf.read1(); int proto = ibuf.read1(); int distHigh = ibuf.read2BE(); int distLow = ibuf.read2BE(); int len = ibuf.read2BE(); byte[] alive = new byte[len]; ibuf.readN(alive); int elen = ibuf.read2BE(); byte[] extra = new byte[elen]; ibuf.readN(extra); String name = OtpErlangString.newString(alive); OtpPublishedNode node = new OtpPublishedNode(name); node.Type = type; node.DistHigh = distHigh; node.DistLow = distLow; node.Proto = proto; node.Port = port; if (traceLevel >= traceThreshold) { log.Debug("<- PUBLISH (r4) " + name + " port=" + node.Port); } OtpOutputStream obuf = new OtpOutputStream(); obuf.write1(publish4resp); obuf.write1(0); obuf.write2BE(epmd.Creation); obuf.WriteTo(s.GetStream()); lock (portmap) { portmap.Add(name, node); } publishedPort.Add(name); } catch (IOException) { if (traceLevel >= traceThreshold) { log.Debug("<- (no response)"); } throw new IOException("Request not responding"); } return; }
private void r4_port(TcpClient s, OtpInputStream ibuf) { try { int len = (int)(ibuf.Length - 1); byte[] alive = new byte[len]; ibuf.readN(alive); String name = OtpErlangString.newString(alive); OtpPublishedNode node = null; if (traceLevel >= traceThreshold) { log.Debug("<- PORT (r4) " + name); } lock (portmap) { if (portmap.ContainsKey(name)) { node = portmap[name]; } } OtpOutputStream obuf = new OtpOutputStream(); if (node != null) { obuf.write1(port4resp); obuf.write1(0); obuf.write2BE(node.Port); obuf.write1(node.Type); obuf.write1(node.Proto); obuf.write2BE(node.DistHigh); obuf.write2BE(node.DistLow); obuf.write2BE(len); obuf.writeN(alive); obuf.write2BE(0); } else { obuf.write1(port4resp); obuf.write1(1); } obuf.WriteTo(s.GetStream()); } catch (IOException) { if (traceLevel >= traceThreshold) { log.Debug("<- (no response)"); } throw new IOException("Request not responding"); } return; }