protected void SendChallenge(long her_flags, long our_flags, int challenge) { OtpOutputStream obuf = new OtpOutputStream(); string str = Local.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(Encoding.GetEncoding("ISO-8859-1").GetBytes(str)); } else { obuf.Write2BE(1 + 8 + 4 + 4 + 2 + str.Length); obuf.Write1('N'); obuf.Write8BE(our_flags); obuf.Write4BE(challenge); obuf.Write4BE(Local.Creation); obuf.Write2BE(str.Length); obuf.Write(Encoding.GetEncoding("ISO-8859-1").GetBytes(str)); } obuf.WriteTo(socket.OutputStream); if (TraceLevel >= TraceHandshake) { Logger.Debug($"-> HANDSHAKE sendChallenge flags={our_flags} challenge={challenge} local={Local}"); } }
protected int SendName(int dist, long aflags, int creation) { OtpOutputStream obuf = new OtpOutputStream(); string str = Local.Node; int nameTag = (dist == 5 ? 'n' : 'N'); if (dist == 5) { obuf.Write2BE(1 + 2 + 4 + str.Length); obuf.Write1(nameTag); obuf.Write2BE(dist); obuf.Write4BE(aflags); obuf.Write(Encoding.GetEncoding("ISO-8859-1").GetBytes(str)); } else { obuf.Write2BE(1 + 8 + 4 + 2 + str.Length); obuf.Write1(nameTag); obuf.Write8BE(aflags); obuf.Write4BE(creation); obuf.Write2BE(str.Length); obuf.Write(Encoding.GetEncoding("ISO-8859-1").GetBytes(str)); } obuf.WriteTo(socket.OutputStream); if (TraceLevel >= TraceHandshake) { Logger.Debug($"-> HANDSHAKE sendName flags={aflags} dist={dist} local={Local}"); } return(nameTag); }
/** * Send an exit signal to a remote process. * Used internally when "processes" terminate */ private void SendExit(int tag, OtpErlangPid from, OtpErlangPid dest, IOtpErlangObject reason) { if (!Connected) { throw new IOException("Not connected"); } OtpOutputStream header = new OtpOutputStream(headerLen); // preamble: 4 byte length + "passthrough" tag header.Write4BE(0); // reserve space for length header.Write1(passThrough); header.Write1(version); // header header.WriteTupleHead(4); header.WriteLong(tag); header.WriteAny(from); header.WriteAny(dest); header.WriteAny(reason); // fix up length in preamble header.Poke4BE(0, header.Length - 4); DoSend(header); }
/** * Send a pre-encoded message to a process on a remote node. */ protected void SendBuf(OtpErlangPid from, OtpErlangPid dest, OtpOutputStream payload) { if (!Connected) { throw new IOException("Not connected"); } OtpOutputStream header = new OtpOutputStream(headerLen); // preamble: 4 byte length + "passthrough" tag + version header.Write4BE(0); // reserve space for length header.Write1(passThrough); header.Write1(version); // header info header.WriteTupleHead(3); header.WriteLong(sendTag); if (sendCookie) { header.WriteAtom(Local.Cookie); } else { header.WriteAtom(""); } header.WriteAny(dest); // version for payload header.Write1(version); // fix up length in preamble header.Poke4BE(0, header.Length + payload.Length - 4); DoSend(header, payload); }
private async Task Names_R4(IOtpTransport socket) { try { if (traceLevel >= traceThreshold) { Logger.Debug("<- NAMES(r4) "); } OtpOutputStream obuf = new OtpOutputStream(); obuf.Write4BE(EpmdPort); foreach (var node in portmap.Values) { byte[] bytes = Encoding.GetEncoding("ISO-8859-1").GetBytes($"name {node.Alive} at port {node.Port}\n"); obuf.WriteN(bytes); Logger.Debug($"-> name {node.Alive} at port {node.Port}"); } await obuf.WriteToAsync(socket.OutputStream); } catch (IOException e) { if (traceLevel >= traceThreshold) { Logger.Debug("<- (no response)"); } throw new IOException("Request not responding", e); } }
protected void SendComplement(int nameTag) { if (nameTag == 'n' && (Peer.CapFlags & AbstractNode.dFlagHandshake23) != 0) { OtpOutputStream obuf = new OtpOutputStream(); obuf.Write2BE(1 + 4 + 4); obuf.Write1('c'); int flagsHigh = (int)(Local.CapFlags >> 32); obuf.Write4BE(flagsHigh); obuf.Write4BE(Local.Creation); obuf.WriteTo(socket.OutputStream); if (TraceLevel >= TraceHandshake) { Logger.Debug($"-> HANDSHAKE sendComplement flagsHigh={flagsHigh} creation={Local.Creation}"); } } }
/** * Send an auth error to peer because he sent a bad cookie. The auth error * uses his cookie (not revealing ours). This is just like send_reg * otherwise */ protected void CookieError(OtpLocalNode local, OtpErlangAtom cookie) { try { OtpOutputStream header = new OtpOutputStream(headerLen); // preamble: 4 byte length + "passthrough" tag + version header.Write4BE(0); // reserve space for length header.Write1(passThrough); header.Write1(version); header.WriteTupleHead(4); header.WriteLong(regSendTag); header.WriteAny(local.CreatePid()); // disposable pid header.WriteAtom(cookie.Value); // important: his cookie, // not mine... header.WriteAtom("auth"); // version for payload header.Write1(version); // the payload // the no_auth message (copied from Erlang) Don't change this // (Erlang will crash) // {$gen_cast, {print, "~n** Unauthorized cookie ~w **~n", // [foo@aule]}} IOtpErlangObject[] msg = new IOtpErlangObject[2]; IOtpErlangObject[] msgbody = new IOtpErlangObject[3]; msgbody[0] = new OtpErlangAtom("print"); msgbody[1] = new OtpErlangString("~n** Bad cookie sent to " + local + " **~n"); // Erlang will crash and burn if there is no third argument here... msgbody[2] = new OtpErlangList(); // empty list msg[0] = new OtpErlangAtom("$gen_cast"); msg[1] = new OtpErlangTuple(msgbody); OtpOutputStream payload = new OtpOutputStream(new OtpErlangTuple(msg)); // fix up length in preamble header.Poke4BE(0, header.Length + payload.Length - 4); try { DoSend(header, payload); } catch (IOException) { } // ignore } finally { Close(); } throw new OtpAuthException("Remote cookie not authorized: " + cookie.Value); }
protected void SendChallengeReply(int challenge, byte[] digest) { OtpOutputStream obuf = new OtpOutputStream(); obuf.Write2BE(21); obuf.Write1(ChallengeReply); obuf.Write4BE(challenge); obuf.Write(digest); obuf.WriteTo(socket.OutputStream); if (TraceLevel >= TraceHandshake) { Logger.Debug($"-> HANDSHAKE sendChallengeReply challenge={challenge} digest={Hex(digest)} local={Local}"); } }