public OtpErlangRef(OtpLocalNode self) { OtpErlangRef r = self.createRef(); ids = r.Ids; creation = r.Creation; node = r.Node; }
public OtpErlangPid(OtpLocalNode self) { OtpErlangPid p = self.createPid(); id = p.id; serial = p.serial; creation = p.creation; node = p.node; }
/** * Intiate and open a connection to a remote node. * * @exception java.io.IOException if it was not possible to connect to the * peer. * * @exception OtpAuthException if handshake resulted in an authentication * error. */ protected AbstractConnection(OtpLocalNode self, OtpPeer other) : base("receive", true) { peer = other; this.self = self; socket = null; int port; traceLevel = defaultLevel; // now get a connection between the two... 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 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); name = peer.Node; connected = true; }
/** * 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 java.io.IOException if it was not possible to connect to the * peer. * * @exception OtpAuthException if handshake resulted in an authentication * error */ protected AbstractConnection(OtpLocalNode self, BufferedTcpClient s) : base("receive", true) { this.self = self; peer = new OtpPeer(); socket = s; traceLevel = defaultLevel; if (traceLevel >= handshakeThreshold) { log.Debug("<- ACCEPT FROM " + s.Client.RemoteEndPoint); } // get his info recvName(peer); // now find highest common dist value if (peer.Proto != self.Proto || self.DistHigh < peer.DistLow || self.DistLow > peer.DistHigh) { close(); throw new 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(); name = peer.Node; }
/* * 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()); }
/* * 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 TcpClient r4_publish(OtpLocalNode node) { TcpClient s = null; try { OtpOutputStream obuf = new OtpOutputStream(); s = new TcpClient(node.Host, EpmdPort.get()); obuf.write2BE(node.Alive.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.Alive.Length); obuf.writeN(Encoding.GetEncoding("iso-8859-1").GetBytes(node.Alive)); obuf.write2BE(0); // No extra // send request obuf.WriteTo(s.GetStream()); if (traceLevel >= traceThreshold) { log.Debug("-> PUBLISH (r4) " + node + " port=" + node.Port); } // get reply byte[] tmpbuf = new byte[100]; int n = s.GetStream().Read(tmpbuf, 0, tmpbuf.Length); if (n < 0) { // this was an r3 node => not a failure (yet) if (s != null) { s.Close(); } throw new IOException("Nameserver not responding on " + node.Host + " when publishing " + node.Alive); } OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0); int response = ibuf.read1(); if (response == publish4resp) { int result = ibuf.read1(); if (result == 0) { node.Creation = ibuf.read2BE(); if (traceLevel >= traceThreshold) { log.Debug("<- OK"); } return s; // success } } } catch (SocketException) { if (traceLevel >= traceThreshold) { log.Debug("<- (no response)"); } throw new IOException("Nameserver not responding on " + node.Host); } catch (IOException) { // epmd closed the connection = fail if (s != null) { s.Close(); } if (traceLevel >= traceThreshold) { log.Debug("<- (no response)"); } throw new IOException("Nameserver not responding on " + node.Host + " when publishing " + node.Alive); } catch (OtpErlangDecodeException) { if (s != null) { s.Close(); } if (traceLevel >= traceThreshold) { log.Debug("<- (invalid response)"); } throw new IOException("Nameserver not responding on " + node.Host + " when publishing " + node.Alive); } if (s != null) { s.Close(); } return null; }
private static TcpClient r3_publish(OtpLocalNode node) { TcpClient s; try { OtpOutputStream obuf = new OtpOutputStream(); s = new TcpClient(node.Host, EpmdPort.get()); obuf.write2BE(node.Alive.Length + 3); obuf.write1(publish3req); obuf.write2BE(node.Port); obuf.writeN(Encoding.GetEncoding("iso-8859-1").GetBytes(node.Alive)); // send request obuf.WriteTo(s.GetStream()); if (traceLevel >= traceThreshold) { log.Debug("-> PUBLISH (r3) " + node + " port=" + node.Port); } byte[] tmpbuf = new byte[100]; int n = s.GetStream().Read(tmpbuf, 0, tmpbuf.Length); if (n < 0) { if (traceLevel >= traceThreshold) { log.Debug("<- (no response)"); } return null; } OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0); if (ibuf.read1() == publish3ok) { node.Creation = ibuf.read2BE(); if (traceLevel >= traceThreshold) { log.Debug("<- OK"); } return s; // success - don't close socket } } catch (SocketException) { if (traceLevel >= traceThreshold) { log.Debug("<- (no response)"); } throw new IOException("Nameserver not responding on " + node.Host); } catch (IOException) { // epmd closed the connection = fail if (traceLevel >= traceThreshold) { log.Debug("<- (no response)"); } throw new IOException("Nameserver not responding on " + node.Host + " when publishing " + node.Alive); } catch (OtpErlangDecodeException) { if (traceLevel >= traceThreshold) { log.Debug("<- (invalid response)"); } throw new IOException("Nameserver not responding on " + node.Host + " when publishing " + node.Alive); } return null; // failure }
// 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) { try { using (TcpClient s = new TcpClient(Dns.GetHostName(), EpmdPort.get())) { OtpOutputStream obuf = new OtpOutputStream(); obuf.write2BE(node.Alive.Length + 1); obuf.write1(stopReq); obuf.writeN(Encoding.GetEncoding("iso-8859-1").GetBytes(node.Alive)); obuf.WriteTo(s.GetStream()); // don't even wait for a response (is there one?) if (traceLevel >= traceThreshold) { log.Debug("-> UNPUBLISH " + node + " port=" + node.Port); log.Debug("<- OK (assumed)"); } } } catch (Exception) /* ignore all failures */ { } }
/** * 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 java.io.IOException * if there was no response from the name server. */ public static bool publishPort(OtpLocalNode node) { TcpClient s = null; try { s = r4_publish(node); } catch (IOException) { s = r3_publish(node); } node.setEpmd(s); return s != null; }