// send has receiver pid but no sender information internal OtpMsg(Erlang.Pid to, OtpInputStream paybuf) { this.tag = sendTag; this.from = null; this.to = to; this.toName = null; this.paybuf = paybuf; this.payload = null; }
// special case when reason is an atom (i.e. most of the time) private OtpMsg(Tag tag, Erlang.Pid from, Object /* Pid or string */ to, Erlang.Ref eref, System.String reason, OtpInputStream paybuf) { this.tag = tag; this.from = from; this.to = (Erlang.Pid)(to is Erlang.Pid ? to : null); this.toName = (string)(to is string?to : null); this.paybuf = paybuf; this.payload = new Erlang.Atom(reason); this.eref = eref; }
private static System.Net.Sockets.TcpClient r3_publish(OtpLocalNode node) { System.Net.Sockets.TcpClient s = null; try { OtpOutputStream obuf = new OtpOutputStream(); s = new System.Net.Sockets.TcpClient(System.Net.Dns.GetHostName(), epmdPort); obuf.write2BE(node.getAlive().Length + 3); obuf.write1(publish3req); obuf.write2BE(node.port()); //UPGRADE_NOTE: This code will be optimized in the future; byte[] tmpBytes; int i; string tmpStr; tmpStr = node.getAlive(); tmpBytes = new byte[tmpStr.Length]; i = 0; while (i < tmpStr.Length) { tmpBytes[i] = (byte) tmpStr[i]; i++; } obuf.writeN(tmpBytes); // send request obuf.writeTo((System.IO.Stream) s.GetStream()); if (traceLevel >= traceThreshold) OtpTrace.TraceEvent("-> PUBLISH (r3) " + node + " port=" + node.port()); byte[] tmpbuf = new byte[100]; int n = s.GetStream().Read(tmpbuf, 0, 100); if (n < 0) { if (s != null) s.Close(); if (traceLevel >= traceThreshold) OtpTrace.TraceEvent("<- (no response)"); return null; } OtpInputStream ibuf = new OtpInputStream(tmpbuf); if (ibuf.read1() == publish3ok) { node._creation = ibuf.read2BE(); if (traceLevel >= traceThreshold) OtpTrace.TraceEvent("<- OK"); return s; // success - don't close socket } } catch (System.IO.IOException) { // epmd closed the connection = fail if (s != null) s.Close(); if (traceLevel >= traceThreshold) OtpTrace.TraceEvent("<- (no response)"); throw new System.IO.IOException("Nameserver not responding on " + node.host() + " when publishing " + node.getAlive()); } catch (Erlang.Exception) { if (s != null) s.Close(); if (traceLevel >= traceThreshold) OtpTrace.TraceEvent("<- (invalid response)"); throw new System.IO.IOException("Nameserver not responding on " + node.host() + " when publishing " + node.getAlive()); } if (s != null) s.Close(); return null; // failure }
// send has receiver pid but no sender information internal OtpMsg(Erlang.Pid to, OtpInputStream paybuf) : this(Tag.sendTag, (Erlang.Pid)null, to, (Erlang.Ref)null, (Erlang.Object)null, paybuf) { }
/*this function will get an exception if it tries to talk to an r3 * epmd, or if something else happens that it cannot forsee. In both * cases we return an exception (and the caller should try again, using * the r3 protocol). * If we manage to successfully communicate with an r4 epmd, we return * either the socket, or null, depending on the result. */ private static System.Net.Sockets.TcpClient r4_publish(OtpLocalNode node) { System.Net.Sockets.TcpClient s = null; System.Exception error = null; try { OtpOutputStream obuf = new OtpOutputStream(); s = new TcpClient(System.Net.Dns.GetHostName(), epmdPort); obuf.write2BE(node.getAlive().Length + 13); obuf.write1(publish4req); obuf.write2BE(node.port()); obuf.write1(node.type()); obuf.write1(node.proto()); obuf.write2BE(node.distHigh()); obuf.write2BE(node.distLow()); obuf.write2BE(node.getAlive().Length); //UPGRADE_NOTE: This code will be optimized in the future; byte[] tmpBytes; int i; string tmpStr; tmpStr = node.getAlive(); tmpBytes = new byte[tmpStr.Length]; i = 0; while (i < tmpStr.Length) { tmpBytes[i] = (byte)tmpStr[i]; i++; } obuf.writeN(tmpBytes); obuf.write2BE(0); // No extra // send request obuf.writeTo((System.IO.Stream)s.GetStream()); if (traceLevel >= traceThreshold) { OtpTrace.TraceEvent("-> PUBLISH (r4) " + node + " port=" + node.port()); } // get reply byte[] tmpbuf = new byte[100]; int n = s.GetStream().Read(tmpbuf, 0, 100); if (n < 0) { // this was an r3 node => not a failure (yet) if (s != null) { s.Close(); } throw new System.IO.IOException("Nameserver not responding on " + node.host() + " when publishing " + node.getAlive()); } OtpInputStream ibuf = new OtpInputStream(tmpbuf); int response = ibuf.read1(); if (response == publish4resp) { int result = ibuf.read1(); if (result == 0) { node._creation = ibuf.read2BE(); if (traceLevel >= traceThreshold) { OtpTrace.TraceEvent("<- OK"); } return(s); // success } } } catch (System.IO.IOException e) { error = e; } catch (Erlang.Exception e) { error = e; } catch (System.Net.Sockets.SocketException e) { error = e; } if (error == null) { return(s); } else { // epmd closed the connection = fail if (s != null) { s.Close(); } if (traceLevel >= traceThreshold) { System.Console.Out.WriteLine("<- (no response)"); } string err = "Nameserver not responding on " + node.host() + " when publishing " + node.getAlive(); node.epmdFailedConnAttempt(node.node(), err); if (traceLevel >= traceThreshold) { System.Console.Out.WriteLine("Failed to connect to empd daemon!"); } if (!OtpLocalNode.ignoreLocalEpmdConnectErrors) { throw new System.Exception(err); } node._creation = 0; return(null); } }
private static int r4_lookupPort(AbstractNode node) { int port = 0; System.Net.Sockets.TcpClient s = null; try { OtpOutputStream obuf = new OtpOutputStream(); s = new System.Net.Sockets.TcpClient(node.host(), epmdPort); // build and send epmd request // length[2], tag[1], alivename[n] (length = n+1) obuf.write2BE(node.getAlive().Length + 1); obuf.write1(port4req); //UPGRADE_NOTE: This code will be optimized in the future; byte[] tmpBytes; int i; string tmpStr; tmpStr = node.getAlive(); tmpBytes = new byte[tmpStr.Length]; i = 0; while (i < tmpStr.Length) { tmpBytes[i] = (byte)tmpStr[i]; i++; } obuf.writeN(tmpBytes); // send request obuf.writeTo((System.IO.Stream)s.GetStream()); if (traceLevel >= traceThreshold) { OtpTrace.TraceEvent("-> LOOKUP (r4) " + node); } // receive and decode reply // resptag[1], result[1], port[2], ntype[1], proto[1], // disthigh[2], distlow[2], nlen[2], alivename[n], // elen[2], edata[m] byte[] tmpbuf = new byte[100]; int n = s.GetStream().Read(tmpbuf, 0, 100); if (n < 0) { // this was an r3 node => not a failure (yet) if (s != null) { s.Close(); } throw new System.IO.IOException("Nameserver not responding on " + node.host() + " when looking up " + node.getAlive()); } OtpInputStream ibuf = new OtpInputStream(tmpbuf); int response = ibuf.read1(); if (response == port4resp) { int result = ibuf.read1(); if (result == 0) { port = ibuf.read2BE(); node.ntype = ibuf.read1(); node._proto = ibuf.read1(); node._distHigh = ibuf.read2BE(); node._distLow = ibuf.read2BE(); // ignore rest of fields } } } catch (System.IO.IOException) { if (traceLevel >= traceThreshold) { OtpTrace.TraceEvent("<- (no response)"); } throw new System.IO.IOException("Nameserver not responding on " + node.host() + " when looking up " + node.getAlive()); } catch (Erlang.Exception) { if (traceLevel >= traceThreshold) { OtpTrace.TraceEvent("<- (invalid response)"); } throw new System.IO.IOException("Nameserver not responding on " + node.host() + " when looking up " + node.getAlive()); } catch (System.Net.Sockets.SocketException) { if (traceLevel >= traceThreshold) { OtpTrace.TraceEvent("<- (no epmd response)"); } throw new System.IO.IOException("Nameserver not responding on " + node.host() + " when looking up " + node.getAlive()); } finally { try { if (s != null) { s.Close(); } } catch (System.IO.IOException) { /*ignore close errors */ } s = null; } if (traceLevel >= traceThreshold) { if (port == 0) { OtpTrace.TraceEvent("<- NOT FOUND"); } else { OtpTrace.TraceEvent("<- PORT " + port); } } return(port); }
// send_reg has sender pid and receiver name internal OtpMsg(Erlang.Pid from, System.String toName, OtpInputStream paybuf) { this.tag = regSendTag; this.from = from; this.toName = toName; this.to = null; this.paybuf = paybuf; this.payload = null; }
// exit (etc) has from, to, reason internal OtpMsg(int tag, Erlang.Pid from, Erlang.Pid to, Erlang.Object reason) { this.tag = tag; this.from = from; this.to = to; this.paybuf = null; this.payload = reason; }
private static int r4_lookupPort(AbstractNode node) { int port = 0; System.Net.Sockets.TcpClient s = null; try { OtpOutputStream obuf = new OtpOutputStream(); s = new System.Net.Sockets.TcpClient(node.host(), epmdPort); // build and send epmd request // length[2], tag[1], alivename[n] (length = n+1) obuf.write2BE(node.getAlive().Length + 1); obuf.write1(port4req); //UPGRADE_NOTE: This code will be optimized in the future; byte[] tmpBytes; int i; string tmpStr; tmpStr = node.getAlive(); tmpBytes = new byte[tmpStr.Length]; i = 0; while (i < tmpStr.Length) { tmpBytes[i] = (byte) tmpStr[i]; i++; } obuf.writeN(tmpBytes); // send request obuf.writeTo((System.IO.Stream) s.GetStream()); if (traceLevel >= traceThreshold) System.Console.Out.WriteLine("-> LOOKUP (r4) " + node); // receive and decode reply // resptag[1], result[1], port[2], ntype[1], proto[1], // disthigh[2], distlow[2], nlen[2], alivename[n], // elen[2], edata[m] byte[] tmpbuf = new byte[100]; int n = s.GetStream().Read(tmpbuf, 0, 100); if (n < 0) { // this was an r3 node => not a failure (yet) if (s != null) s.Close(); throw new System.IO.IOException("Nameserver not responding on " + node.host() + " when looking up " + node.getAlive()); } OtpInputStream ibuf = new OtpInputStream(tmpbuf); int response = ibuf.read1(); if (response == port4resp) { int result = ibuf.read1(); if (result == 0) { port = ibuf.read2BE(); node.ntype = ibuf.read1(); node._proto = ibuf.read1(); node._distHigh = ibuf.read2BE(); node._distLow = ibuf.read2BE(); // ignore rest of fields } } } catch (System.IO.IOException) { if (traceLevel >= traceThreshold) System.Console.Out.WriteLine("<- (no response)"); throw new System.IO.IOException("Nameserver not responding on " + node.host() + " when looking up " + node.getAlive()); } catch (Erlang.DecodeException) { if (traceLevel >= traceThreshold) System.Console.Out.WriteLine("<- (invalid response)"); throw new System.IO.IOException("Nameserver not responding on " + node.host() + " when looking up " + node.getAlive()); } finally { try { if (s != null) s.Close(); } catch (System.IO.IOException) { /*ignore close errors */ } s = null; } if (traceLevel >= traceThreshold) { if (port == 0) System.Console.Out.WriteLine("<- NOT FOUND"); else System.Console.Out.WriteLine("<- PORT " + port); } return port; }
/*this function will get an exception if it tries to talk to an r3 * epmd, or if something else happens that it cannot forsee. In both * cases we return an exception (and the caller should try again, using * the r3 protocol). * If we manage to successfully communicate with an r4 epmd, we return * either the socket, or null, depending on the result. */ private static System.Net.Sockets.TcpClient r4_publish(OtpLocalNode node) { System.Net.Sockets.TcpClient s = null; try { OtpOutputStream obuf = new OtpOutputStream(); s = new TcpClient(System.Net.Dns.GetHostName(), epmdPort); obuf.write2BE(node.getAlive().Length + 13); obuf.write1(publish4req); obuf.write2BE(node.port()); obuf.write1(node.type()); obuf.write1(node.proto()); obuf.write2BE(node.distHigh()); obuf.write2BE(node.distLow()); obuf.write2BE(node.getAlive().Length); //UPGRADE_NOTE: This code will be optimized in the future; byte[] tmpBytes; int i; string tmpStr; tmpStr = node.getAlive(); tmpBytes = new byte[tmpStr.Length]; i = 0; while (i < tmpStr.Length) { tmpBytes[i] = (byte) tmpStr[i]; i++; } obuf.writeN(tmpBytes); obuf.write2BE(0); // No extra // send request obuf.writeTo((System.IO.Stream) s.GetStream()); if (traceLevel >= traceThreshold) System.Console.Out.WriteLine("-> PUBLISH (r4) " + node + " port=" + node.port()); // get reply byte[] tmpbuf = new byte[100]; int n = s.GetStream().Read(tmpbuf, 0, 100); if (n < 0) { // this was an r3 node => not a failure (yet) if (s != null) s.Close(); throw new System.IO.IOException("Nameserver not responding on " + node.host() + " when publishing " + node.getAlive()); } OtpInputStream ibuf = new OtpInputStream(tmpbuf); int response = ibuf.read1(); if (response == publish4resp) { int result = ibuf.read1(); if (result == 0) { node._creation = ibuf.read2BE(); if (traceLevel >= traceThreshold) System.Console.Out.WriteLine("<- OK"); return s; // success } } } catch (System.IO.IOException) { // epmd closed the connection = fail if (s != null) s.Close(); if (traceLevel >= traceThreshold) System.Console.Out.WriteLine("<- (no response)"); throw new System.IO.IOException("Nameserver not responding on " + node.host() + " when publishing " + node.getAlive()); } catch (Erlang.DecodeException) { if (s != null) s.Close(); if (traceLevel >= traceThreshold) System.Console.Out.WriteLine("<- (invalid response)"); throw new System.IO.IOException("Nameserver not responding on " + node.host() + " when publishing " + node.getAlive()); } if (s != null) s.Close(); return null; }
private static int r3_lookupPort(AbstractNode node) { int port = 0; System.Net.Sockets.TcpClient s = null; try { OtpOutputStream obuf = new OtpOutputStream(); s = new System.Net.Sockets.TcpClient(node.host(), epmdPort); // build and send epmd request // length[2], tag[1], alivename[n] (length = n+1) obuf.write2BE(node.getAlive().Length + 1); obuf.write1(port3req); //UPGRADE_NOTE: This code will be optimized in the future; byte[] tmpBytes; int i; string tmpStr; tmpStr = node.getAlive(); tmpBytes = new byte[tmpStr.Length]; i = 0; while (i < tmpStr.Length) { tmpBytes[i] = (byte) tmpStr[i]; i++; } obuf.writeN(tmpBytes); // send request obuf.writeTo((System.IO.Stream) s.GetStream()); if (traceLevel >= traceThreshold) System.Console.Out.WriteLine("-> LOOKUP (r3) " + node); // receive and decode reply byte[] tmpbuf = new byte[100]; s.GetStream().Read(tmpbuf, 0, 100); OtpInputStream ibuf = new OtpInputStream(tmpbuf); port = ibuf.read2BE(); } catch (System.IO.IOException) { if (traceLevel >= traceThreshold) System.Console.Out.WriteLine("<- (no response)"); throw new System.IO.IOException("Nameserver not responding on " + node.host() + " when looking up " + node.getAlive()); } catch (Erlang.DecodeException) { if (traceLevel >= traceThreshold) System.Console.Out.WriteLine("<- (invalid response)"); throw new System.IO.IOException("Nameserver not responding on " + node.host() + " when looking up " + node.getAlive()); } finally { try { if (s != null) s.Close(); } catch (System.IO.IOException) { /*ignore close errors */ } s = null; } if (traceLevel >= traceThreshold) { if (port == 0) System.Console.Out.WriteLine("<- NOT FOUND"); else System.Console.Out.WriteLine("<- PORT " + port); } return port; }
protected internal virtual int recvChallengeReply(int our_challenge) { int challenge; byte[] her_digest = new byte[16]; try { byte[] buf = read2BytePackage(); OtpInputStream ibuf = new OtpInputStream(buf); int tag = ibuf.read1(); if (tag != ChallengeReply) { throw new System.IO.IOException("Handshake protocol error"); } challenge = ibuf.read4BE(); 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 (Erlang.DecodeException) { throw new System.IO.IOException("Handshake failed - not enough data"); } if (traceLevel >= handshakeThreshold) { System.Console.Out.WriteLine("<- " + "HANDSHAKE recvChallengeReply" + " from=" + peer._node + " challenge=" + challenge + " digest=" + hex(her_digest) + " local=" + self); } return challenge; }
protected internal virtual void recvStatus() { try { byte[] buf = read2BytePackage(); OtpInputStream ibuf = new OtpInputStream(buf); int tag = ibuf.read1(); if (tag != ChallengeStatus) { throw new System.IO.IOException("Handshake protocol error"); } byte[] tmpbuf = new byte[buf.Length - 1]; ibuf.readN(tmpbuf); char[] tmpChar; tmpChar = new char[tmpbuf.Length]; tmpbuf.CopyTo(tmpChar, 0); System.String status = new System.String(tmpChar); if (status.CompareTo("ok") != 0) { throw new System.IO.IOException("Peer replied with status '" + status + "' instead of 'ok'"); } } catch (Erlang.DecodeException) { throw new System.IO.IOException("Handshake failed - not enough data"); } if (traceLevel >= handshakeThreshold) { System.Console.Out.WriteLine("<- " + "HANDSHAKE recvStatus (ok)" + " local=" + self); } }
public virtual void Start() { if (!connected) { deliver(new System.IO.IOException("Not connected")); return ; } byte[] lbuf = new byte[4]; OtpInputStream ibuf; Erlang.Object traceobj; int len; byte[] tock = new byte[]{0, 0, 0, 0}; try { while (!done) { // don't return until we get a real message // or a failure of some kind (e.g. EXIT) // read length and read buffer must be atomic! do { // read 4 bytes - get length of incoming packet // socket.getInputStream().read(lbuf); int n; if ((n = readSock(socket, lbuf)) < lbuf.Length) throw new System.Exception("Read " + n + " out of " + lbuf.Length + " bytes!"); ibuf = new OtpInputStream(lbuf); len = ibuf.read4BE(); // received tick? send tock! if (len == 0) lock(this) { System.Byte[] temp_bytearray; temp_bytearray = tock; if (socket != null) ((System.IO.Stream) socket.GetStream()).Write(temp_bytearray, 0, temp_bytearray.Length); } } while (len == 0); // tick_loop // got a real message (maybe) - read len bytes byte[] tmpbuf = new byte[len]; // i = socket.getInputStream().read(tmpbuf); int m = readSock(socket, tmpbuf); if (m < len) throw new System.Exception("Read " + m + " out of " + len + " bytes!"); ibuf = new OtpInputStream(tmpbuf); if (ibuf.read1() != passThrough) { goto receive_loop_brk; } // got a real message (really) Erlang.Atom reason = null; Erlang.Atom cookie = null; Erlang.Object tmp = null; Erlang.Tuple head = null; Erlang.Atom toName; Erlang.Pid to; Erlang.Pid from; Erlang.Ref eref; // decode the header tmp = ibuf.read_any(); if (!(tmp is Erlang.Tuple)) { goto receive_loop_brk; } head = (Erlang.Tuple) tmp; if (!(head.elementAt(0) is Erlang.Long)) { goto receive_loop_brk; } // lets see what kind of message this is OtpMsg.Tag tag = (OtpMsg.Tag)((Erlang.Long)(head.elementAt(0))).longValue(); switch (tag) { case OtpMsg.Tag.sendTag: case OtpMsg.Tag.sendTTTag: // { SEND, Cookie, ToPid, TraceToken } if (!cookieOk) { // we only check this once, he can send us bad cookies later if he likes if (!(head.elementAt(1) is Erlang.Atom)) { goto receive_loop_brk; } cookie = (Erlang.Atom) head.elementAt(1); if (sendCookie) { if (!cookie.atomValue().Equals(auth_cookie)) { cookieError(self, cookie); } } else { if (!cookie.atomValue().Equals("")) { cookieError(self, cookie); } } cookieOk = true; } if (traceLevel >= OtpTrace.Type.sendThreshold) { OtpTrace.TraceEvent("<- " + headerType(head) + " " + head.ToString()); /*show received payload too */ long mark = ibuf.Position; traceobj = ibuf.read_any(); if (traceobj != null) OtpTrace.TraceEvent(" " + traceobj.ToString()); else OtpTrace.TraceEvent(" (null)"); ibuf.Seek(mark, System.IO.SeekOrigin.Begin); } to = (Erlang.Pid) (head.elementAt(2)); deliver(new OtpMsg(to, ibuf)); break; case OtpMsg.Tag.regSendTag: case OtpMsg.Tag.regSendTTTag: // { REG_SEND, FromPid, Cookie, ToName, TraceToken } if (!cookieOk) { // we only check this once, he can send us bad cookies later if he likes if (!(head.elementAt(2) is Erlang.Atom)) { goto receive_loop_brk; } cookie = (Erlang.Atom) head.elementAt(2); if (sendCookie) { if (!cookie.atomValue().Equals(auth_cookie)) { cookieError(self, cookie); } } else { if (!cookie.atomValue().Equals("")) { cookieError(self, cookie); } } cookieOk = true; } if (traceLevel >= OtpTrace.Type.sendThreshold) { OtpTrace.TraceEvent("<- " + headerType(head) + " " + head.ToString()); /*show received payload too */ long mark = ibuf.Position; traceobj = ibuf.read_any(); if (traceobj != null) OtpTrace.TraceEvent(" " + traceobj.ToString()); else OtpTrace.TraceEvent(" (null)"); ibuf.Seek(mark, System.IO.SeekOrigin.Begin); } from = (Erlang.Pid) (head.elementAt(1)); toName = (Erlang.Atom) (head.elementAt(3)); deliver(new OtpMsg(from, toName.atomValue(), ibuf)); break; case OtpMsg.Tag.exitTag: case OtpMsg.Tag.exit2Tag: // { EXIT2, FromPid, ToPid, Reason } if (!(head.elementAt(3) is Erlang.Atom)) { goto receive_loop_brk; } if (traceLevel >= OtpTrace.Type.ctrlThreshold) { OtpTrace.TraceEvent("<- " + headerType(head) + " " + head.ToString()); } from = (Erlang.Pid) (head.elementAt(1)); to = (Erlang.Pid) (head.elementAt(2)); reason = (Erlang.Atom) head.elementAt(3); deliver(new OtpMsg(tag, from, to, reason)); break; case OtpMsg.Tag.exitTTTag: case OtpMsg.Tag.exit2TTTag: // { EXIT2, FromPid, ToPid, TraceToken, Reason } // as above, but bifferent element number if (!(head.elementAt(4) is Erlang.Atom)) { goto receive_loop_brk; } if (traceLevel >= OtpTrace.Type.ctrlThreshold) { OtpTrace.TraceEvent("<- " + headerType(head) + " " + head.ToString()); } from = (Erlang.Pid) (head.elementAt(1)); to = (Erlang.Pid) (head.elementAt(2)); reason = (Erlang.Atom) head.elementAt(4); deliver(new OtpMsg(tag, from, to, reason)); break; case OtpMsg.Tag.linkTag: case OtpMsg.Tag.unlinkTag: // { UNLINK, FromPid, ToPid} if (traceLevel >= OtpTrace.Type.ctrlThreshold) { OtpTrace.TraceEvent("<- " + headerType(head) + " " + head.ToString()); } from = (Erlang.Pid) (head.elementAt(1)); to = (Erlang.Pid) (head.elementAt(2)); deliver(new OtpMsg(tag, from, to)); break; // absolutely no idea what to do with these, so we ignore them... case OtpMsg.Tag.groupLeaderTag: case OtpMsg.Tag.nodeLinkTag: // { NODELINK } // (just show trace) if (traceLevel >= OtpTrace.Type.ctrlThreshold) { OtpTrace.TraceEvent("<- " + headerType(head) + " " + head.ToString()); } break; case OtpMsg.Tag.monitorPTag: // {MONITOR_P, FromPid, ToProc, Ref} case OtpMsg.Tag.demonitorPTag: // {DEMONITOR_P, FromPid, ToProc, Ref} if (traceLevel >= OtpTrace.Type.ctrlThreshold) { OtpTrace.TraceEvent("<- " + headerType(head) + " " + head.ToString()); } from = (Erlang.Pid)(head.elementAt(1)); to = (Erlang.Pid)(head.elementAt(2)); eref = (Erlang.Ref)(head.elementAt(3)); deliver(new OtpMsg(tag, from, to, eref)); break; case OtpMsg.Tag.monitorPexitTag: // {MONITOR_P_EXIT, FromPid, ToProc, Ref, Reason} if (traceLevel >= OtpTrace.Type.ctrlThreshold) { OtpTrace.TraceEvent("<- " + headerType(head) + " " + head.ToString()); } from = (Erlang.Pid)(head.elementAt(1)); to = (Erlang.Pid)(head.elementAt(2)); eref = (Erlang.Ref)(head.elementAt(3)); deliver(new OtpMsg(tag, from, to, eref, reason)); break; default: // garbage? if (traceLevel >= OtpTrace.Type.ctrlThreshold) { OtpTrace.TraceEvent("<- Unknown tag " + headerType(head) + " " + head.ToString()); } goto receive_loop_brk; } } receive_loop_brk: ; // end receive_loop // this section reachable only with break // we have received garbage from peer deliver(new Erlang.Exit("Remote is sending garbage")); } catch (OtpAuthException e) { deliver(e); } catch (Erlang.Exception e) { OtpTrace.TraceEvent(e.ToString()); deliver(new Erlang.Exit("Remote is sending garbage: " + e.ToString())); } catch (System.Exception e) { deliver(new Erlang.Exit("Remote has closed connection: " + e.ToString())); } finally { close(); OtpTrace.TraceEvent("exit connection "+System.Threading.Thread.CurrentThread.Name); } }
// send_reg has sender pid and receiver name internal OtpMsg(Erlang.Pid from, System.String toName, Erlang.Object payload) { this.tag = regSendTag; this.from = from; this.toName = toName; this.to = null; this.paybuf = null; this.payload = payload; }
// send_reg has sender pid and receiver name internal OtpMsg(Erlang.Pid from, string toName, OtpInputStream paybuf) : this(Tag.regSendTag, from, toName, (Erlang.Ref)null, (Erlang.Object)null, paybuf) { }
// special case when reason is an atom (i.e. most of the time) internal OtpMsg(int tag, Erlang.Pid from, Erlang.Pid to, System.String reason) { this.tag = tag; this.from = from; this.to = to; this.paybuf = null; this.payload = new Erlang.Atom(reason); }
protected internal virtual byte[] read2BytePackage() { byte[] lbuf = new byte[2]; byte[] tmpbuf; readSock(socket, lbuf); OtpInputStream ibuf = new OtpInputStream(lbuf); int len = ibuf.read2BE(); tmpbuf = new byte[len]; readSock(socket, tmpbuf); return tmpbuf; }
// send has receiver pid but no sender information internal OtpMsg(Erlang.Pid to, Erlang.Object payload) { this.tag = sendTag; this.from = null; this.to = to; this.toName = null; this.paybuf = null; this.payload = payload; }
protected internal virtual void recvName(OtpPeer peer) { System.String hisname = ""; try { byte[] tmpbuf = read2BytePackage(); OtpInputStream ibuf = new OtpInputStream(tmpbuf); byte[] tmpname; int len = (int) (tmpbuf.Length); peer.ntype = ibuf.read1(); if (peer.ntype != AbstractNode.NTYPE_R6) { throw new System.IO.IOException("Unknown remote node type"); } peer._distLow = (peer._distHigh = ibuf.read2BE()); if (peer._distLow < 5) { throw new System.IO.IOException("Unknown remote node type"); } peer.flags = ibuf.read4BE(); tmpname = new byte[len - 7]; ibuf.readN(tmpname); char[] tmpChar; tmpChar = new char[tmpname.Length]; tmpname.CopyTo(tmpChar, 0); hisname = new System.String(tmpChar); // 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.ntype = AbstractNode.NTYPE_R4_ERLANG; else peer.ntype = AbstractNode.NTYPE_R4_HIDDEN; if ((peer.flags & AbstractNode.dFlagExtendedReferences) == 0) { throw new System.IO.IOException("Handshake failed - peer cannot handle extended references"); } if (OtpSystem.useExtendedPidsPorts() && (peer.flags & AbstractNode.dFlagExtendedPidsPorts) == 0) if (true && (peer.flags & AbstractNode.dFlagExtendedPidsPorts) == 0) { throw new System.IO.IOException("Handshake failed - peer cannot handle extended pids and ports"); } } catch (Erlang.Exception) { throw new System.IO.IOException("Handshake failed - not enough data"); } int i = hisname.IndexOf((System.Char) '@', 0); peer._node = hisname; peer._alive = hisname.Substring(0, (i) - (0)); peer._host = hisname.Substring(i + 1, (hisname.Length) - (i + 1)); if (traceLevel >= OtpTrace.Type.handshakeThreshold) { OtpTrace.TraceEvent("<- " + "HANDSHAKE" + " ntype=" + peer.ntype + " dist=" + peer._distHigh + " remote=" + peer); } }
private static int r3_lookupPort(AbstractNode node) { int port = 0; System.Net.Sockets.TcpClient s = null; try { OtpOutputStream obuf = new OtpOutputStream(); s = new System.Net.Sockets.TcpClient(node.host(), epmdPort); // build and send epmd request // length[2], tag[1], alivename[n] (length = n+1) obuf.write2BE(node.getAlive().Length + 1); obuf.write1(port3req); //UPGRADE_NOTE: This code will be optimized in the future; byte[] tmpBytes; int i; string tmpStr; tmpStr = node.getAlive(); tmpBytes = new byte[tmpStr.Length]; i = 0; while (i < tmpStr.Length) { tmpBytes[i] = (byte)tmpStr[i]; i++; } obuf.writeN(tmpBytes); // send request obuf.writeTo((System.IO.Stream)s.GetStream()); if (traceLevel >= traceThreshold) { OtpTrace.TraceEvent("-> LOOKUP (r3) " + node); } // receive and decode reply byte[] tmpbuf = new byte[100]; s.GetStream().Read(tmpbuf, 0, 100); OtpInputStream ibuf = new OtpInputStream(tmpbuf); port = ibuf.read2BE(); } catch (System.IO.IOException) { if (traceLevel >= traceThreshold) { OtpTrace.TraceEvent("<- (no response)"); } throw new System.IO.IOException("Nameserver not responding on " + node.host() + " when looking up " + node.getAlive()); } catch (Erlang.Exception) { if (traceLevel >= traceThreshold) { OtpTrace.TraceEvent("<- (invalid response)"); } throw new System.IO.IOException("Nameserver not responding on " + node.host() + " when looking up " + node.getAlive()); } finally { try { if (s != null) { s.Close(); } } catch (System.IO.IOException) { /*ignore close errors */ } s = null; } if (traceLevel >= traceThreshold) { if (port == 0) { OtpTrace.TraceEvent("<- NOT FOUND"); } else { OtpTrace.TraceEvent("<- PORT " + port); } } return(port); }
protected internal virtual int recvChallenge() { int challenge; try { byte[] buf = read2BytePackage(); OtpInputStream ibuf = new OtpInputStream(buf); peer.ntype = ibuf.read1(); if (peer.ntype != AbstractNode.NTYPE_R6) { throw new System.IO.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); char[] tmpChar; tmpChar = new char[tmpname.Length]; tmpname.CopyTo(tmpChar, 0); System.String hisname = new System.String(tmpChar); int i = hisname.IndexOf((System.Char) '@', 0); peer._node = hisname; peer._alive = hisname.Substring(0, (i) - (0)); peer._host = hisname.Substring(i + 1, (hisname.Length) - (i + 1)); } catch (Erlang.Exception) { throw new System.IO.IOException("Handshake failed - not enough data"); } if (traceLevel >= OtpTrace.Type.handshakeThreshold) { OtpTrace.TraceEvent("<- " + "HANDSHAKE recvChallenge" + " from=" + peer._node + " challenge=" + challenge + " local=" + self); } return challenge; }
private static System.Net.Sockets.TcpClient r3_publish(OtpLocalNode node) { System.Net.Sockets.TcpClient s = null; try { OtpOutputStream obuf = new OtpOutputStream(); s = new System.Net.Sockets.TcpClient(System.Net.Dns.GetHostName(), epmdPort); obuf.write2BE(node.getAlive().Length + 3); obuf.write1(publish3req); obuf.write2BE(node.port()); //UPGRADE_NOTE: This code will be optimized in the future; byte[] tmpBytes; int i; string tmpStr; tmpStr = node.getAlive(); tmpBytes = new byte[tmpStr.Length]; i = 0; while (i < tmpStr.Length) { tmpBytes[i] = (byte)tmpStr[i]; i++; } obuf.writeN(tmpBytes); // send request obuf.writeTo((System.IO.Stream)s.GetStream()); if (traceLevel >= traceThreshold) { OtpTrace.TraceEvent("-> PUBLISH (r3) " + node + " port=" + node.port()); } byte[] tmpbuf = new byte[100]; int n = s.GetStream().Read(tmpbuf, 0, 100); if (n < 0) { if (s != null) { s.Close(); } if (traceLevel >= traceThreshold) { OtpTrace.TraceEvent("<- (no response)"); } return(null); } OtpInputStream ibuf = new OtpInputStream(tmpbuf); if (ibuf.read1() == publish3ok) { node._creation = ibuf.read2BE(); if (traceLevel >= traceThreshold) { OtpTrace.TraceEvent("<- OK"); } return(s); // success - don't close socket } } catch (System.IO.IOException) { // epmd closed the connection = fail if (s != null) { s.Close(); } if (traceLevel >= traceThreshold) { OtpTrace.TraceEvent("<- (no response)"); } throw new System.IO.IOException("Nameserver not responding on " + node.host() + " when publishing " + node.getAlive()); } catch (Erlang.Exception) { if (s != null) { s.Close(); } if (traceLevel >= traceThreshold) { OtpTrace.TraceEvent("<- (invalid response)"); } throw new System.IO.IOException("Nameserver not responding on " + node.host() + " when publishing " + node.getAlive()); } if (s != null) { s.Close(); } return(null); // failure }
protected internal virtual void recvChallengeAck(int our_challenge) { byte[] her_digest = new byte[16]; try { byte[] buf = read2BytePackage(); OtpInputStream ibuf = new OtpInputStream(buf); int tag = ibuf.read1(); if (tag != ChallengeAck) { throw new System.IO.IOException("Handshake protocol error"); } ibuf.readN(her_digest); byte[] our_digest = genDigest(our_challenge, auth_cookie); if (!digests_equals(her_digest, our_digest)) { throw new OtpAuthException("Peer authentication error."); } } catch (Erlang.Exception) { throw new System.IO.IOException("Handshake failed - not enough data"); } catch (System.Exception) { throw new OtpAuthException("Peer authentication error."); } if (traceLevel >= OtpTrace.Type.handshakeThreshold) { OtpTrace.TraceEvent("<- " + "HANDSHAKE recvChallengeAck" + " from=" + peer._node + " digest=" + hex(her_digest) + " local=" + self); } }
// special case when reason is an atom (i.e. most of the time) private OtpMsg(Tag tag, Erlang.Pid from, Object /* Pid or string */ to, Erlang.Ref eref, System.String reason, OtpInputStream paybuf) { this.tag = tag; this.from = from; this.to = (Erlang.Pid)(to is Erlang.Pid ? to : null); this.toName = (string)(to is string ? to : null); this.paybuf = paybuf; this.payload = new Erlang.Atom(reason); this.eref = eref; }
protected internal virtual void recvStatus() { try { byte[] buf = read2BytePackage(); OtpInputStream ibuf = new OtpInputStream(buf); int tag = ibuf.read1(); if (tag != ChallengeStatus) { throw new System.IO.IOException("Handshake protocol error"); } byte[] tmpbuf = new byte[buf.Length - 1]; ibuf.readN(tmpbuf); char[] tmpChar; tmpChar = new char[tmpbuf.Length]; tmpbuf.CopyTo(tmpChar, 0); System.String status = new System.String(tmpChar); if (status.CompareTo("ok") != 0) { throw new System.IO.IOException("Peer replied with status '" + status + "' instead of 'ok'"); } } catch (Erlang.Exception) { throw new System.IO.IOException("Handshake failed - not enough data"); } catch (System.Net.Sockets.SocketException e) { throw new System.IO.IOException("Peer dropped connection: " + e.ToString()); } if (traceLevel >= OtpTrace.Type.handshakeThreshold) { OtpTrace.TraceEvent("<- " + "HANDSHAKE recvStatus (ok)" + " local=" + self); } }
public void TestEncodeDecode() { { OtpOutputStream os = new OtpOutputStream(new Erlang.Atom("abc")); OtpInputStream ins = new OtpInputStream(os.getBuffer(), 0, os.size()); Assert.IsTrue("abc" == ins.read_atom()); } { OtpOutputStream os = new OtpOutputStream(new Erlang.String("string")); OtpInputStream ins = new OtpInputStream(os.getBuffer(), 0, os.size()); Assert.IsTrue("string" == ins.read_string()); } { Erlang.Pid pid = new Erlang.Pid("abc", 1, 2, 3); OtpOutputStream os = new OtpOutputStream(pid); OtpInputStream ins = new OtpInputStream(os.getBuffer(), 0, os.size()); Assert.IsTrue(pid.Equals(ins.read_pid())); } { Erlang.Port p = new Erlang.Port("abc", 1, 2); OtpOutputStream os = new OtpOutputStream(p); OtpInputStream ins = new OtpInputStream(os.getBuffer(), 0, os.size()); Assert.IsTrue(p.Equals(ins.read_port())); } { Erlang.Ref p = new Erlang.Ref("abc", new int[3] { 1, 2, 3 }, 2); OtpOutputStream os = new OtpOutputStream(p); OtpInputStream ins = new OtpInputStream(os.getBuffer(), 0, os.size()); Assert.IsTrue(p.Equals(ins.read_ref())); } { OtpOutputStream os = new OtpOutputStream(); os.write_long(1); OtpInputStream ins = new OtpInputStream(os.getBuffer(), 0, os.size()); long n = ins.read_long(); Assert.IsTrue(1 == n); } { OtpOutputStream os = new OtpOutputStream(); os.write_long(0xFFFFFF); OtpInputStream ins = new OtpInputStream(os.getBuffer(), 0, os.size()); long n = ins.read_long(); Assert.IsTrue(0xFFFFFF == n); } { OtpOutputStream os = new OtpOutputStream(); os.write_long(0xFFFFFFFF); OtpInputStream ins = new OtpInputStream(os.getBuffer(), 0, os.size()); long n = ins.read_long(); Assert.IsTrue(0xFFFFFFFF == n); } { OtpOutputStream os = new OtpOutputStream(); os.write_ulong((ulong)0xFFFFFFFFFF); OtpInputStream ins = new OtpInputStream(os.getBuffer(), 0, os.size()); ulong n = ins.read_ulong(); Assert.IsTrue((ulong)0xFFFFFFFFFF == n); } { OtpOutputStream os = new OtpOutputStream(); os.write_ulong((ulong)0xFFFFFFFFFFFF); OtpInputStream ins = new OtpInputStream(os.getBuffer(), 0, os.size()); ulong n = ins.read_ulong(); Assert.IsTrue((ulong)0xFFFFFFFFFFFF == n); } { OtpOutputStream os = new OtpOutputStream(); os.write_ulong((ulong)0xFFFFFFFFFFFFFF); OtpInputStream ins = new OtpInputStream(os.getBuffer(), 0, os.size()); ulong n = ins.read_ulong(); Assert.IsTrue((ulong)0xFFFFFFFFFFFFFF == n); } { OtpOutputStream os = new OtpOutputStream(); os.write_ulong((ulong)0xFFFFFFFFFFFFFFFF); OtpInputStream ins = new OtpInputStream(os.getBuffer(), 0, os.size()); ulong n = ins.read_ulong(); Assert.IsTrue((ulong)0xFFFFFFFFFFFFFFFF == n); } }