// Ask epmd to close his end of the connection. // Caller should close his epmd socket as well. // This method is pretty forgiving... /* * Unregister from Epmd. Other nodes wishing to connect will no * longer be able to. * * <p> This method does not report any failures. **/ public static void unPublishPort(OtpLocalNode node) { TcpClient s = null; try { s = new TcpClient(System.Net.Dns.GetHostName(), epmdPort); OtpOutputStream obuf = new OtpOutputStream(); obuf.write2BE(node.getAlive().Length + 1); obuf.write1(stopReq); //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.writeTo((System.IO.Stream)s.GetStream()); // don't even wait for a response (is there one?) if (traceLevel >= traceThreshold) { OtpTrace.TraceEvent("-> UNPUBLISH " + node + " port=" + node.port()); OtpTrace.TraceEvent("<- OK (assumed)"); } } catch (System.Exception) { /*ignore all failures */ } finally { try { if (s != null) { s.Close(); } } catch (System.IO.IOException) { /*ignore close failure */ } s = null; } }
/* * Register with Epmd, so that other nodes are able to find and * connect to it. * * @param node the server node that should be registered with Epmd. * * @return true if the operation was successful. False if the node * was already registered. * * @exception C#.io.IOException if there was no response from the * name server. **/ public static bool publishPort(OtpLocalNode node) { System.Net.Sockets.TcpClient s = null; try { s = r4_publish(node); } catch (System.IO.IOException) { s = r3_publish(node); } node.setEpmd(s); return(s != null); }
/*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 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 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, Erlang.Atom 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((long)OtpMsg.Tag.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]}} Erlang.Object[] msg = new Erlang.Object[2]; Erlang.Object[] msgbody = new Erlang.Object[3]; msgbody[0] = new Erlang.Atom("print"); msgbody[1] = new Erlang.String("~n** Bad cookie sent to " + local + " **~n"); // Erlang will crash and burn if there is no third argument here... msgbody[2] = new Erlang.List(); // empty list msg[0] = new Erlang.Atom("$gen_cast"); msg[1] = new Erlang.Tuple(msgbody); OtpOutputStream payload = new OtpOutputStream(new Erlang.Tuple(msg)); // fix up length in preamble header.poke4BE(0, header.count() + payload.count() - 4); try { do_send(header, payload); } catch (System.IO.IOException) { } // ignore } finally { close(); throw new OtpAuthException("Remote cookie not authorized: " + cookie.atomValue()); } }
/* * Intiate and open a connection to a remote node. * * @exception C#.io.IOException if it was not possible to connect to the peer. * @exception OtpAuthException if handshake resulted in an authentication error. */ protected internal AbstractConnection(OtpLocalNode self, OtpPeer other) : this(self, other, self.cookie()) { }
/* * Intiate and open a connection to a remote node. * * @exception C#.io.IOException if it was not possible to connect to the peer. * @exception OtpAuthException if handshake resulted in an authentication error. */ protected internal AbstractConnection(OtpLocalNode self, OtpPeer other, string cookie) { this.peer = other; this.self = self; this.socket = null; this.auth_cookie = cookie; //this.IsBackground = true; // now get a connection between the two... int port = OtpEpmd.lookupPort(peer); // now find highest common dist value if ((peer._proto != self._proto) || (self._distHigh < peer._distLow) || (self._distLow > peer._distHigh)) { throw new System.IO.IOException("No common protocol found - cannot connect"); } // highest common version: min(peer.distHigh, self.distHigh) peer.distChoose = (peer._distHigh > self._distHigh ? self._distHigh : peer._distHigh); doConnect(port); this.name = peer.node(); this.connected = true; }
private AbstractConnection(OtpLocalNode self, OtpPeer peer, System.Net.Sockets.TcpClient s, string cookie) { this.peer = peer; this.self = self; this.socket = s; this.auth_cookie = cookie ?? self._cookie; this.sentBytes = 0; this.receivedBytes = 0; this.maxPayloadLength = defaultMaxPayloadLength; }
/* * Accept an incoming connection from a remote node. Used by {@link * OtpSelf#accept() OtpSelf.accept()} to create a connection * based on data received when handshaking with the peer node, when * the remote node is the connection intitiator. * * @exception C#.io.IOException if it was not possible to connect to the peer. * @exception OtpAuthException if handshake resulted in an authentication error */ protected internal AbstractConnection(OtpLocalNode self, System.Net.Sockets.TcpClient s) { this.self = self; this.peer = new OtpPeer(); this.socket = s; this.auth_cookie = self.cookie(); this.socket.NoDelay = true; // Use keepalive timer this.socket.Client.SetSocketOption( System.Net.Sockets.SocketOptionLevel.Socket, System.Net.Sockets.SocketOptionName.KeepAlive, true); // Close socket gracefully this.socket.Client.SetSocketOption( System.Net.Sockets.SocketOptionLevel.Socket, System.Net.Sockets.SocketOptionName.DontLinger, true); //this.socket.ReceiveTimeout = 5000; if (traceLevel >= OtpTrace.Type.handshakeThreshold) { OtpTrace.TraceEvent("<- ACCEPT FROM " + System.Net.IPAddress.Parse(s.Client.RemoteEndPoint.ToString()).ToString() + ":" + (s.Client.RemoteEndPoint as System.Net.IPEndPoint).Port.ToString()); } // get his info recvName(this.peer); // now find highest common dist value if ((peer._proto != self._proto) || (self._distHigh < peer._distLow) || (self._distLow > peer._distHigh)) { close(); throw new System.IO.IOException("No common protocol found - cannot accept connection"); } // highest common version: min(peer.distHigh, self.distHigh) peer.distChoose = (peer._distHigh > self._distHigh?self._distHigh:peer._distHigh); doAccept(); this.name = peer.node(); }
/*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; }
// Ask epmd to close his end of the connection. // Caller should close his epmd socket as well. // This method is pretty forgiving... /* * Unregister from Epmd. Other nodes wishing to connect will no * longer be able to. * * <p> This method does not report any failures. **/ public static void unPublishPort(OtpLocalNode node) { TcpClient s = null; try { s = new TcpClient(System.Net.Dns.GetHostName(), epmdPort); OtpOutputStream obuf = new OtpOutputStream(); obuf.write2BE(node.getAlive().Length + 1); obuf.write1(stopReq); //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.writeTo((System.IO.Stream) s.GetStream()); // don't even wait for a response (is there one?) if (traceLevel >= traceThreshold) { System.Console.Out.WriteLine("-> UNPUBLISH " + node + " port=" + node.port()); System.Console.Out.WriteLine("<- OK (assumed)"); } } catch (System.Exception) { /*ignore all failures */ } finally { try { if (s != null) s.Close(); } catch (System.IO.IOException) { /*ignore close failure */ } s = null; } }
/* * Register with Epmd, so that other nodes are able to find and * connect to it. * * @param node the server node that should be registered with Epmd. * * @return true if the operation was successful. False if the node * was already registered. * * @exception C#.io.IOException if there was no response from the * name server. **/ public static bool publishPort(OtpLocalNode node) { System.Net.Sockets.TcpClient s = null; try { s = r4_publish(node); } catch (System.IO.IOException) { s = r3_publish(node); } node.setEpmd(s); return (s != null); }
/* * Accept an incoming connection from a remote node. Used by {@link * OtpSelf#accept() OtpSelf.accept()} to create a connection * based on data received when handshaking with the peer node, when * the remote node is the connection intitiator. * * @exception C#.io.IOException if it was not possible to connect to the peer. * @exception OtpAuthException if handshake resulted in an authentication error */ protected internal AbstractConnection(OtpLocalNode self, System.Net.Sockets.TcpClient s) { this.self = self; this.peer = new OtpPeer(); this.socket = s; this.socket.NoDelay = true; this.traceLevel = defaultLevel; if (traceLevel >= handshakeThreshold) { System.Console.Out.WriteLine("<- ACCEPT FROM ?"); /* System.Net.Sockets.Socket sock = s.Client; //UPGRADE_TODO: Expression C#.net.Socket.getInetAddress could not be converted.; //UPGRADE_TODO: Expression C#.net.Socket.getPort could not be converted.; System.Console.Out.WriteLine("<- ACCEPT FROM " + IPAddress.Parse(((IPEndPoint)s.RemoteEndPoint).Address.ToString())+ ":" + ((IPEndPoint)s.RemoteEndPoint).Port.ToString()); */ } // get his info recvName(this.peer); // now find highest common dist value if ((peer._proto != self._proto) || (self._distHigh < peer._distLow) || (self._distLow > peer._distHigh)) { close(); throw new System.IO.IOException("No common protocol found - cannot accept connection"); } // highest common version: min(peer.distHigh, self.distHigh) peer.distChoose = (peer._distHigh > self._distHigh?self._distHigh:peer._distHigh); doAccept(); this.name = peer.node(); }
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 }