/** * 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); }
/** * 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); }