/** * Read an Erlang atom from the stream. * * @return a String containing the value of the atom. * * @exception OtpErlangDecodeException * if the next term in the stream is not an atom. */ public String read_atom() { int tag; int len; byte[] strbuf; String atom; tag = read1skip_version(); if (tag != OtpExternal.atomTag) { throw new OtpErlangDecodeException("wrong tag encountered, expected " + OtpExternal.atomTag + ", got " + tag); } len = read2BE(); strbuf = new byte[len]; this.readN(strbuf); atom = OtpErlangString.newString(strbuf); if (atom.Length > OtpExternal.maxAtomLength) { atom = atom.Substring(0, OtpExternal.maxAtomLength); } return(atom); }
/** * Read a string from the stream. */ public string ReadString() { int len; int tag = Read1SkipVersion(); switch (tag) { case OtpExternal.stringTag: return(ReadStringData()); case OtpExternal.nilTag: return(""); case OtpExternal.listTag: // List when unicode + len = Read4BE(); int[] cps = new int[len]; for (int i = 0; i < len; i++) { cps[i] = ReadInt(); } string s = OtpErlangString.FromCodePoints(cps); ReadNil(); return(s); default: throw new OtpDecodeException("Wrong tag encountered, expected " + OtpExternal.stringTag + " or " + OtpExternal.listTag + ", got " + tag); } }
private async Task Port_R4(IOtpTransport socket, OtpInputStream ibuf) { try { int len = (int)(ibuf.Length - 1); byte[] alive = ibuf.ReadN(len); string name = OtpErlangString.FromEncoding(alive); if (traceLevel >= traceThreshold) { Logger.Debug($"<- PORT (r4) {name}"); } if (!portmap.TryGetValue(name, out AbstractNode node)) { node = null; } 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); if (traceLevel >= traceThreshold) { Logger.Debug("-> 0 (success)"); } } else { obuf.Write1(port4resp); obuf.Write1(1); if (traceLevel >= traceThreshold) { Logger.Debug("-> 1 (failure)"); } } await obuf.WriteToAsync(socket.OutputStream); } catch (IOException e) { if (traceLevel >= traceThreshold) { Logger.Debug("<- (no response)"); } throw new IOException("Request not responding", e); } }
/** * Create a list of Erlang integers representing Unicode codePoints. * This method does not check if the string contains valid code points. */ public OtpErlangList(string str) : base(str.Length) { if (string.IsNullOrWhiteSpace(str)) { return; } AddRange(OtpErlangString.ToCodePoints(str).Select((cp) => new OtpErlangInt(cp))); }
/** * 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); }
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; }
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; }
/** * Read a string from the stream. * * @return the value of the string. * * @exception OtpErlangDecodeException * if the next term in the stream is not a string. */ public String read_string() { int tag; int len; byte[] strbuf; tag = read1skip_version(); switch (tag) { case OtpExternal.stringTag: len = read2BE(); strbuf = new byte[len]; this.readN(strbuf); return(OtpErlangString.newString(strbuf)); case OtpExternal.nilTag: return(""); case OtpExternal.listTag: // List when unicode + len = read4BE(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < len; i++) { uint cp = (uint)read_int(); if (!OtpErlangString.isValidCodePoint((int)cp)) { throw new OtpErlangDecodeException("Invalid CodePoint: " + cp); } if (1 <= (cp >> 16)) { cp -= 0x10000; char high = (char)((cp / 0x400) + 0xD800); char low = (char)((cp % 0x400) + 0xDC00); sb.Append(high); sb.Append(low); } else { sb.Append((char)cp); } } read_nil(); return(sb.ToString()); default: throw new OtpErlangDecodeException("Wrong tag encountered, expected " + OtpExternal.stringTag + " or " + OtpExternal.listTag + ", got " + tag); } }
/** * Create a list of Erlang integers representing Unicode codePoints. * This method does not check if the string contains valid code points. * * @param str * the characters from which to create the list. */ public OtpErlangList(String str) { if (str == null || str.Length == 0) { elems = NO_ELEMENTS; } else { int[] codePoints = OtpErlangString.stringToCodePoints(str); elems = new OtpErlangObject[codePoints.Length]; for (int i = 0; i < elems.Length; i++) { elems[i] = new OtpErlangInt(codePoints[i]); } } }
/** * Write a string to the stream. * * @param s * the string to write. */ public void write_string(String s) { int len = s.Length; switch (len) { case 0: write_nil(); break; default: if (len <= 65535 && is8bitString(s)) // 8-bit string { try { byte[] bytebuf = Encoding.GetEncoding("iso-8859-1").GetBytes(s); write1(OtpExternal.stringTag); write2BE(len); writeN(bytebuf); } catch (EncoderFallbackException) { write_nil(); // it should never ever get here... } } else // unicode or longer, must code as list { int[] codePoints = OtpErlangString.stringToCodePoints(s); write_list_head(codePoints.Length); foreach (int codePoint in codePoints) { write_int(codePoint); } write_nil(); } break; } }
/** * Read an Erlang float from the stream. * * @return the float value, as a double. * * @exception OtpErlangDecodeException * if the next term in the stream is not a float. */ public double read_double() { int tag; // parse the stream tag = read1skip_version(); switch (tag) { case OtpExternal.newFloatTag: { return(BitConverter.ToDouble(BitConverter.GetBytes(readBE(8)), 0)); } case OtpExternal.floatTag: { byte[] strbuf = new byte[31]; String str; double val; // get the string this.readN(strbuf); str = OtpErlangString.newString(strbuf); if (!Double.TryParse(str, out val)) { throw new OtpErlangDecodeException("Invalid float format: '" + str + "'"); } return(val); } default: throw new OtpErlangDecodeException("Wrong tag encountered, expected " + OtpExternal.newFloatTag + ", got " + tag); } }
public override IEnumerator<OtpActor.Continuation> GetEnumerator() { m_log.Info("[Distributed PC] New PCVM is ready: " + m_mbox.Self); while (true) { OtpMsg msg = null; yield return (delegate(OtpMsg received) { msg = received; }); OtpErlangObject obj = msg.getMsg(); if (obj is OtpErlangAtom) { string atom = ((OtpErlangAtom)obj).atomValue(); if (!String.IsNullOrEmpty(atom) && atom == "noconnection") { break; } } OtpErlangPid sender = null; OtpErlangObject[] reply = new OtpErlangObject[3]; try { OtpErlangTuple t = (OtpErlangTuple)obj; sender = (OtpErlangPid)t.elementAt(0); reply[0] = sender; reply[1] = new OtpErlangAtom("ok"); string instr = ((OtpErlangAtom)t.elementAt(1)).ToString(); if (instr == "load") { Parser parser = PCVM.MakeParser(); string script = String.Empty; if (t.elementAt(2) is OtpErlangString) { script = ((OtpErlangString)t.elementAt(2)).stringValue(); } else { script = OtpErlangString.newString(((OtpErlangBinary)t.elementAt(2)).binaryValue()); } bool debug = ((OtpErlangAtom)t.elementAt(3)).boolValue(); SYMBOL ast = parser.Parse(script); m_vm.Call((Compiler.ExpPair)ast); if (debug) { reply[2] = new OtpErlangAtom("continue"); } else { Queue<PCObj> popped = new Queue<PCObj>(); try { m_vm.Finish(popped); } finally { reply = new OtpErlangObject[] { reply[0], reply[1], new OtpErlangAtom("finished"), ErlangObjectFromPCVMObject(popped.ToArray()) }; } } } else if (instr == "step") { bool cont = true; Queue<PCObj> popped = new Queue<PCObj>(); try { cont = m_vm.Step(popped); } finally { reply = new OtpErlangObject[] { reply[0], reply[1], new OtpErlangAtom(cont ? "continue" : "finished"), ErlangObjectFromPCVMObject(popped.ToArray()) }; } } else if (instr == "finish") { Queue<PCObj> popped = new Queue<PCObj>(); try { m_vm.Finish(popped); } finally { reply = new OtpErlangObject[] { reply[0], reply[1], new OtpErlangAtom("finished"), ErlangObjectFromPCVMObject(popped.ToArray()) }; } } else if (instr == "echo") { reply[2] = t.elementAt(2); } else if (instr == "exit") { reply[2] = new OtpErlangAtom("bye"); break; } } catch (Exception e) { m_log.Debug("[Distributed PC] Invalid message format: " + msg.getMsg()); reply[1] = new OtpErlangAtom("error"); reply[2] = new OtpErlangString(e.Message); } finally { if (sender != null) { m_mbox.send(sender, new OtpErlangTuple(reply)); } } } m_log.Info("[Distributed PC] Delete PCVM instance: " + m_mbox.Self); m_vm.Dispose(); }
public override IEnumerator<OtpActor.Continuation> GetEnumerator() { while (true) { OtpMsg msg = null; OtpErlangPid sender = null; OtpErlangTuple reply = null; yield return (delegate(OtpMsg received) { msg = received; }); try { OtpErlangTuple t = (OtpErlangTuple)msg.getMsg(); sender = (OtpErlangPid)t.elementAt(0); string instr = ((OtpErlangAtom)t.elementAt(1)).ToString(); if (instr == "echo") { OtpErlangObject[] v = new OtpErlangObject[3]; v[0] = sender; v[1] = new OtpErlangAtom("ok"); v[2] = t.elementAt(2); reply = new OtpErlangTuple(v); } else if (instr == "new") { OtpActorMbox newmbox = (OtpActorMbox)m_node.createMbox(false); PCVMActor newactor = new PCVMActor(m_scene, m_source, m_node, newmbox); m_node.react(newactor); OtpErlangObject[] v = new OtpErlangObject[3]; v[0] = sender; v[1] = new OtpErlangAtom("ok"); v[2] = newmbox.Self; reply = new OtpErlangTuple(v); } } catch (Exception e) { m_log.Debug("[Distributed PC] Invalid message format: " + msg.getMsg()); OtpErlangObject[] v = new OtpErlangObject[3]; v[0] = sender; v[1] = new OtpErlangAtom("error"); v[2] = new OtpErlangString(e.Message); reply = new OtpErlangTuple(v); } finally { if (sender != null) { m_mbox.send(sender, reply); } } } }
public static String[] lookupNames(IPAddress address) { try { OtpOutputStream obuf = new OtpOutputStream(); using (TcpClient s = new TcpClient(address.ToString(), EpmdPort.get())) { obuf.write2BE(1); obuf.write1(names4req); // send request obuf.WriteTo(s.GetStream()); if (traceLevel >= traceThreshold) { log.Debug("-> NAMES (r4) "); } // get reply byte[] buffer = new byte[256]; MemoryStream ms = new MemoryStream(256); while (true) { int bytesRead = s.GetStream().Read(buffer, 0, buffer.Length); if (bytesRead == -1) { break; } ms.Write(buffer, 0, bytesRead); } byte[] tmpbuf = ms.GetBuffer(); OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0); ibuf.read4BE(); // read port int // int port = ibuf.read4BE(); // check if port = epmdPort int n = tmpbuf.Length; byte[] buf = new byte[n - 4]; Array.Copy(tmpbuf, 4, buf, 0, n - 4); String all = OtpErlangString.newString(buf); return(all.Split(new char[] { '\n' })); } } catch (SocketException) { if (traceLevel >= traceThreshold) { log.Debug("<- (no response)"); } throw new IOException("Nameserver not responding on " + address); } catch (IOException) { if (traceLevel >= traceThreshold) { log.Debug("<- (no response)"); } throw new IOException("Nameserver not responding when requesting names"); } catch (OtpErlangDecodeException) { if (traceLevel >= traceThreshold) { log.Debug("<- (invalid response)"); } throw new IOException("Nameserver not responding when requesting names"); } }
public static OtpErlangTuple Load(OtpMbox mbox, OtpErlangPid pid, string script) { OtpErlangObject body; OtpErlangBoolean debug = new OtpErlangBoolean(false); OtpErlangObject message; if (script.Length <= 65535) { body = new OtpErlangString(script); } else { body = new OtpErlangBinary(System.Text.Encoding.GetEncoding("iso-8859-1").GetBytes(script)); } message = new OtpErlangTuple(new OtpErlangObject[] { mbox.Self, new OtpErlangAtom("load"), body, debug }); mbox.send(pid, message); OtpErlangTuple reply = (OtpErlangTuple)mbox.receive(); Console.WriteLine("Load: {0}", reply); return reply; }
/** * Read string data of len from stream */ public string ReadStringData(int len, string encoding = "ISO-8859-1") { byte[] strbuf = ReadN(len); return(OtpErlangString.FromEncoding(strbuf, encoding)); }
/* * 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 */ private 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.write_tuple_head(4); header.write_long(regSendTag); header.write_any(local.createPid()); // disposable pid header.write_atom(cookie.atomValue()); // important: his cookie, // not mine... header.write_atom("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]}} OtpErlangObject[] msg = new OtpErlangObject[2]; OtpErlangObject[] msgbody = new OtpErlangObject[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.size() + payload.size() - 4); try { do_send(header, payload); } catch (IOException) { } // ignore } finally { close(); } throw new OtpAuthException("Remote cookie not authorized: " + cookie.atomValue()); }