// used by send and send_reg (message types with payload) protected void DoSend(OtpOutputStream header, OtpOutputStream payload) { lock (objWrite) { try { if (TraceLevel >= TraceSend) { // Need to decode header and output buffer to show trace // message! // First make OtpInputStream, then decode. try { IOtpErlangObject h = header.Slice(5).ReadAny(); Logger.Debug("-> " + HeaderType(h) + " " + h); IOtpErlangObject o = payload.Slice(0).ReadAny(); Logger.Debug(" " + o); } catch (OtpDecodeException e) { Logger.Debug(" " + "can't decode output buffer:" + e); } } header.WriteTo(socket.OutputStream); payload.WriteTo(socket.OutputStream); } catch (IOException) { Close(); throw; } } }
private void r4_names(TcpClient s, OtpInputStream ibuf) { try { if (traceLevel >= traceThreshold) { log.Debug("<- NAMES(r4) "); } OtpOutputStream obuf = new OtpOutputStream(); obuf.write4BE(EpmdPort.get()); lock (portmap) { foreach (KeyValuePair <string, OtpPublishedNode> pair in portmap) { OtpPublishedNode node = pair.Value; string info = String.Format("name {0} at port {1}\n", node.Alive, node.Port); byte[] bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(info); obuf.writeN(bytes); } } obuf.WriteTo(s.GetStream()); } catch (IOException) { if (traceLevel >= traceThreshold) { log.Debug("<- (no response)"); } throw new IOException("Request not responding"); } return; }
// used by the other message types protected void DoSend(OtpOutputStream header) { lock (objWrite) { try { if (TraceLevel >= TraceCTRL) { try { IOtpErlangObject h = header.Slice(5).ReadAny(); Logger.Debug("-> " + HeaderType(h) + " " + h); } catch (OtpDecodeException e) { Logger.Debug(" " + "can't decode output buffer: " + e); } } header.WriteTo(socket.OutputStream); } catch (IOException) { Close(); throw; } } }
private void ListenActivity() { EndPoint remote = new IPEndPoint(IPAddress.Any, 0); for (;;) { byte[] message = new byte[BUF]; while (this.socket.Available == 0) { } int size = this.socket.ReceiveFrom(message, ref remote); if (size == 0) continue; Debug.Print("Received " + size + " bytes from " + ((IPEndPoint)remote).Address + " (" + ((IPEndPoint)remote).Port + ")"); string messageString = ""; for (int i = 0; i < size; ++i) { messageString += (int)message[i] + " "; } Debug.Print(messageString); OtpInputStream inStream = new OtpInputStream(message); OtpErlangObject msg = inStream.read_any(); Debug.Print(msg.ToString()); OtpErlangTuple t = new OtpErlangTuple(new OtpErlangObject[] { new OtpErlangAtom("ok"), msg }); OtpOutputStream outStream = new OtpOutputStream(t, false); byte[] answer = outStream.GetBuffer(); this.socket.SendTo(answer, remote); Debug.Print(t.ToString()); } }
private async Task Names_R4(IOtpTransport socket) { try { if (traceLevel >= traceThreshold) { Logger.Debug("<- NAMES(r4) "); } OtpOutputStream obuf = new OtpOutputStream(); obuf.Write4BE(EpmdPort); foreach (var node in portmap.Values) { byte[] bytes = Encoding.GetEncoding("ISO-8859-1").GetBytes($"name {node.Alive} at port {node.Port}\n"); obuf.WriteN(bytes); Logger.Debug($"-> name {node.Alive} at port {node.Port}"); } await obuf.WriteToAsync(socket.OutputStream); } catch (IOException e) { if (traceLevel >= traceThreshold) { Logger.Debug("<- (no response)"); } throw new IOException("Request not responding", e); } }
protected void SendChallenge(long her_flags, long our_flags, int challenge) { OtpOutputStream obuf = new OtpOutputStream(); string str = Local.Node; if ((her_flags & AbstractNode.dFlagHandshake23) == 0) { obuf.Write2BE(1 + 2 + 4 + 4 + str.Length); obuf.Write1('n'); obuf.Write2BE(5); obuf.Write4BE(our_flags & 0xffffffff); obuf.Write4BE(challenge); obuf.Write(Encoding.GetEncoding("ISO-8859-1").GetBytes(str)); } else { obuf.Write2BE(1 + 8 + 4 + 4 + 2 + str.Length); obuf.Write1('N'); obuf.Write8BE(our_flags); obuf.Write4BE(challenge); obuf.Write4BE(Local.Creation); obuf.Write2BE(str.Length); obuf.Write(Encoding.GetEncoding("ISO-8859-1").GetBytes(str)); } obuf.WriteTo(socket.OutputStream); if (TraceLevel >= TraceHandshake) { Logger.Debug($"-> HANDSHAKE sendChallenge flags={our_flags} challenge={challenge} local={Local}"); } }
public void WriteCompressed(IOtpErlangObject o, CompressionLevel level) { try { OtpOutputStream oos = new OtpOutputStream(o); if (oos.Length < 5) { oos.WriteTo(this); } else { Write1(OtpExternal.compressedTag); Write4BE(oos.Length); DeflateStream dos = new DeflateStream(this, level, true); oos.WriteTo(dos); dos.Close(); } } catch (ObjectDisposedException) { throw new ArgumentException("Intermediate stream failed for Erlang object " + o); } catch (IOException) { throw new ArgumentException("Intermediate stream failed for Erlang object " + o); } }
/** * 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 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); }
protected int SendName(int dist, long aflags, int creation) { OtpOutputStream obuf = new OtpOutputStream(); string str = Local.Node; int nameTag = (dist == 5 ? 'n' : 'N'); if (dist == 5) { obuf.Write2BE(1 + 2 + 4 + str.Length); obuf.Write1(nameTag); obuf.Write2BE(dist); obuf.Write4BE(aflags); obuf.Write(Encoding.GetEncoding("ISO-8859-1").GetBytes(str)); } else { obuf.Write2BE(1 + 8 + 4 + 2 + str.Length); obuf.Write1(nameTag); obuf.Write8BE(aflags); obuf.Write4BE(creation); obuf.Write2BE(str.Length); obuf.Write(Encoding.GetEncoding("ISO-8859-1").GetBytes(str)); } obuf.WriteTo(socket.OutputStream); if (TraceLevel >= TraceHandshake) { Logger.Debug($"-> HANDSHAKE sendName flags={aflags} dist={dist} local={Local}"); } return(nameTag); }
public void Encode(OtpOutputStream buf) { buf.WriteMapHead(Arity); foreach (var pair in this) { buf.WriteAny(pair.Key); buf.WriteAny(pair.Value); } }
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); } }
/** * 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); }
/** * Convert this number to the equivalent Erlang external representation. * * @param buf * an output stream to which the encoded number should be * written. */ public override void encode(OtpOutputStream buf) { if (!BigIntegerIsNull(bigVal)) { buf.write_big_integer(bigVal); } else { buf.write_long(val); } }
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; }
/** * Convert this tuple to the equivalent Erlang external representation. * * @param buf * an output stream to which the encoded tuple should be * written. */ public override void encode(OtpOutputStream buf) { int arity = elems.Length; buf.write_tuple_head(arity); for (int i = 0; i < arity; i++) { buf.write_any(elems[i]); } }
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; }
protected void SendStatus(string status) { OtpOutputStream obuf = new OtpOutputStream(); obuf.Write2BE(status.Length + 1); obuf.Write1(ChallengeStatus); obuf.Write(Encoding.GetEncoding("ISO-8859-1").GetBytes(status)); obuf.WriteTo(socket.OutputStream); if (TraceLevel >= TraceHandshake) { Logger.Debug($"-> HANDSHAKE sendStatus status={status} local={Local}"); } }
protected void SendChallengeAck(byte[] digest) { OtpOutputStream obuf = new OtpOutputStream(); obuf.Write2BE(17); obuf.Write1(ChallengeAck); obuf.Write(digest); obuf.WriteTo(socket.OutputStream); if (TraceLevel >= TraceHandshake) { Logger.Debug($"-> HANDSHAKE sendChallengeAck digest={Hex(digest)} local={Local}"); } }
protected void SendChallengeReply(int challenge, byte[] digest) { OtpOutputStream obuf = new OtpOutputStream(); obuf.Write2BE(21); obuf.Write1(ChallengeReply); obuf.Write4BE(challenge); obuf.Write(digest); obuf.WriteTo(socket.OutputStream); if (TraceLevel >= TraceHandshake) { Logger.Debug($"-> HANDSHAKE sendChallengeReply challenge={challenge} digest={Hex(digest)} local={Local}"); } }
/** * Write an arbitrary Erlang term to the stream in compressed format. * * @param o * the Erlang tem to write. */ public void write_compressed(OtpErlangObject o) { OtpOutputStream oos = new OtpOutputStream(o); write1(OtpExternal.compressedTag); write4BE(oos.Length); DeflateStream dos = new DeflateStream(this, CompressionMode.Compress, true); try { oos.WriteTo(dos); dos.Close(); } catch (ObjectDisposedException) { throw new ArgumentException("Intremediate stream failed for Erlang object " + o); } }
private async Task <string> Publish_R4(IOtpTransport socket, OtpInputStream ibuf) { try { int port = ibuf.Read2BE(); int type = ibuf.Read1(); int proto = ibuf.Read1(); int distHigh = ibuf.Read2BE(); int distLow = ibuf.Read2BE(); string name = ibuf.ReadStringData(); ibuf.ReadStringData(); // extra AbstractNode node = new AbstractNode() { Node = name, Port = port, Type = type, DistHigh = distHigh, DistLow = distLow, Proto = proto }; if (traceLevel >= traceThreshold) { Logger.Debug($"<- PUBLISH (r4) {name} port={node.Port}"); } OtpOutputStream obuf = new OtpOutputStream(); obuf.Write1(ALIVE2_RESP); obuf.Write1(0); obuf.Write2BE(NextCreation()); await obuf.WriteToAsync(socket.OutputStream); portmap.TryAdd(name, node); return(name); } catch (IOException e) { if (traceLevel >= traceThreshold) { Logger.Debug("<- (no response)"); } throw new IOException("Request not responding", e); } }
protected void SendComplement(int nameTag) { if (nameTag == 'n' && (Peer.CapFlags & AbstractNode.dFlagHandshake23) != 0) { OtpOutputStream obuf = new OtpOutputStream(); obuf.Write2BE(1 + 4 + 4); obuf.Write1('c'); int flagsHigh = (int)(Local.CapFlags >> 32); obuf.Write4BE(flagsHigh); obuf.Write4BE(Local.Creation); obuf.WriteTo(socket.OutputStream); if (TraceLevel >= TraceHandshake) { Logger.Debug($"-> HANDSHAKE sendComplement flagsHigh={flagsHigh} creation={Local.Creation}"); } } }
protected void encode(OtpOutputStream buf, int start) { int arity = this.arity() - start; if (arity > 0) { buf.write_list_head(arity); for (int i = start; i < arity + start; i++) { buf.write_any(elems[i]); } } if (lastTail == null) { buf.write_nil(); } else { buf.write_any(lastTail); } }
// 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 */ { } }
protected void sendChallengeReply(int challenge, byte[] digest) { OtpOutputStream obuf = new OtpOutputStream(); obuf.write2BE(21); obuf.write1(ChallengeReply); obuf.write4BE(challenge); obuf.write(digest); obuf.WriteTo(socket.GetOutputStream()); if (traceLevel >= handshakeThreshold) { log.Debug("-> " + "HANDSHAKE sendChallengeReply" + " challenge=" + challenge + " digest=" + hex(digest) + " local=" + self); } }
protected void sendStatus(String status) { OtpOutputStream obuf = new OtpOutputStream(); obuf.write2BE(status.Length + 1); obuf.write1(ChallengeStatus); obuf.write(Encoding.GetEncoding("iso-8859-1").GetBytes(status)); obuf.WriteTo(socket.GetOutputStream()); if (traceLevel >= handshakeThreshold) { log.Debug("-> " + "HANDSHAKE sendStatus" + " status=" + status + " local=" + self); } }
private void sendExit(int tag, OtpErlangPid from, OtpErlangPid dest, OtpErlangObject 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.write_tuple_head(4); header.write_long(tag); header.write_any(from); header.write_any(dest); header.write_any(reason); // fix up length in preamble header.poke4BE(0, header.size() - 4); do_send(header); }
// used by the other message types protected void do_send(OtpOutputStream header) { lock (this) { try { if (traceLevel >= ctrlThreshold) { try { OtpErlangObject h = header.getOtpInputStream(5).read_any(); log.Debug("-> " + headerType(h) + " " + h); } catch (OtpErlangDecodeException e) { log.Debug(" " + "can't decode output buffer: " + e); } } header.WriteTo(socket.GetOutputStream()); } catch (IOException e) { close(); throw e; } } }
/** * Convert this atom to the equivalent Erlang external representation. * * @param buf * an output stream to which the encoded atom should be * written. */ public override void encode(OtpOutputStream buf) { buf.write_atom(atom); }
/** * Convert this double to the equivalent Erlang external representation. * * @param buf * an output stream to which the encoded value should be * written. */ public override void encode(OtpOutputStream buf) { buf.write_double(d); }
public override void encode(OtpOutputStream buf) { buf.write_fun(pid, module, old_index, arity, md5, index, uniq, freeVars); }
/** * Convert this number to the equivalent Erlang external representation. * * @param buf * an output stream to which the encoded number should be * written. */ public override void encode(OtpOutputStream buf) { buf.write_long(val); }
/** * Convert this list to the equivalent Erlang external representation. Note * that this method never encodes lists as strings, even when it is possible * to do so. * * @param buf * An output stream to which the encoded list should be written. * */ public override void encode(OtpOutputStream buf) { encode(buf, 0); }
public override void encode(OtpOutputStream stream) { parent.encode(stream, start); }
/** * Send a pre-encoded message to a process on a remote node. * * @param dest * the Erlang PID of the remote process. * @param msg * the encoded message to send. * * @exception java.io.IOException * if the connection is not active or a communication error * occurs. */ 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.write_tuple_head(3); header.write_long(sendTag); if (sendCookie) { header.write_atom(self.Cookie); } else { header.write_atom(""); } header.write_any(dest); // version for payload header.write1(version); // fix up length in preamble header.poke4BE(0, header.size() + payload.size() - 4); do_send(header, payload); }
/** * Convert the object according to the rules of the Erlang external format. * This is mainly used for sending Erlang terms in messages, however it can * also be used for storing terms to disk. * * @param buf * an output stream to which the encoded term should be * written. */ public abstract void encode(OtpOutputStream buf);
/** * Convert this port to the equivalent Erlang external representation. */ public void Encode(OtpOutputStream buf) => buf.WritePort(this);
private static int r4_lookupPort(AbstractNode node) { int port = 0; try { OtpOutputStream obuf = new OtpOutputStream(); using (TcpClient s = new TcpClient(node.Host, EpmdPort.get())) { // build and send epmd request // length[2], tag[1], alivename[n] (length = n+1) obuf.write2BE(node.Alive.Length + 1); obuf.write1(port4req); obuf.writeN(Encoding.GetEncoding("iso-8859-1").GetBytes(node.Alive)); // send request obuf.WriteTo(s.GetStream()); if (traceLevel >= traceThreshold) { log.Debug("-> 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, tmpbuf.Length); if (n < 0) { // this was an r3 node => not a failure (yet) throw new IOException("Nameserver not responding on " + node.Host + " when looking up " + node.Alive); } OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0); int response = ibuf.read1(); if (response == port4resp) { int result = ibuf.read1(); if (result == 0) { port = ibuf.read2BE(); node.Type = ibuf.read1(); node.Proto = ibuf.read1(); node.DistHigh = ibuf.read2BE(); node.DistLow = ibuf.read2BE(); // ignore rest of fields } } } } catch (SocketException) { if (traceLevel >= traceThreshold) { log.Debug("<- (no response)"); } throw new IOException("Nameserver not responding on " + node.Host); } catch (IOException) { if (traceLevel >= traceThreshold) { log.Debug("<- (no response)"); } throw new IOException("Nameserver not responding on " + node.Host + " when looking up " + node.Alive); } catch (OtpErlangDecodeException) { if (traceLevel >= traceThreshold) { log.Debug("<- (invalid response)"); } throw new IOException("Nameserver not responding on " + node.Host + " when looking up " + node.Alive); } if (traceLevel >= traceThreshold) { if (port == 0) { log.Debug("<- NOT FOUND"); } else { log.Debug("<- PORT " + port); } } return(port); }
/** * Convert this bitstr to the equivalent Erlang external representation. * * @param buf * an output stream to which the encoded bitstr should be * written. */ public override void encode(OtpOutputStream buf) { buf.write_bitstr(bin, pad_bits); }
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 }
/** * Convert this PID to the equivalent Erlang external representation. * * @param buf * an output stream to which the encoded PID should be * written. */ public override void encode(OtpOutputStream buf) { buf.write_pid(node, id, serial, creation); }
/* * 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); }
// used by send and send_reg (message types with payload) protected void do_send(OtpOutputStream header, OtpOutputStream payload) { lock (this) { try { if (traceLevel >= sendThreshold) { // Need to decode header and output buffer to show trace // message! // First make OtpInputStream, then decode. try { OtpErlangObject h = header.getOtpInputStream(5).read_any(); log.Debug("-> " + headerType(h) + " " + h); OtpErlangObject o = payload.getOtpInputStream(0).read_any(); log.Debug(" " + o); o = null; } catch (OtpErlangDecodeException e) { log.Debug(" " + "can't decode output buffer:" + e); } } header.WriteTo(socket.GetOutputStream()); payload.WriteTo(socket.GetOutputStream()); } catch (IOException e) { close(); throw e; } } }
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"); } }
/* * 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()); }
private void r4_names(TcpClient s, OtpInputStream ibuf) { try { if (traceLevel >= traceThreshold) { log.Debug("<- NAMES(r4) "); } OtpOutputStream obuf = new OtpOutputStream(); obuf.write4BE(EpmdPort.get()); lock (portmap) { foreach (KeyValuePair<string, OtpPublishedNode> pair in portmap) { OtpPublishedNode node = pair.Value; string info = String.Format("name {0} at port {1}\n", node.Alive, node.Port); byte[] bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(info); obuf.writeN(bytes); } } obuf.WriteTo(s.GetStream()); } catch (IOException) { if (traceLevel >= traceThreshold) { log.Debug("<- (no response)"); } throw new IOException("Request not responding"); } return; }
protected void sendName(int dist, int flags) { OtpOutputStream obuf = new OtpOutputStream(); String str = self.Node; obuf.write2BE(str.Length + 7); // 7 bytes + nodename obuf.write1(AbstractNode.NTYPE_R6); obuf.write2BE(dist); obuf.write4BE(flags); obuf.write(Encoding.GetEncoding("iso-8859-1").GetBytes(str)); obuf.WriteTo(socket.GetOutputStream()); if (traceLevel >= handshakeThreshold) { log.Debug("-> " + "HANDSHAKE sendName" + " flags=" + flags + " dist=" + dist + " local=" + self); } }
/** * Convert this string to the equivalent Erlang external representation. * * @param buf * an output stream to which the encoded string should be * written. */ public override void encode(OtpOutputStream buf) { buf.write_string(str); }
protected void sendChallengeAck(byte[] digest) { OtpOutputStream obuf = new OtpOutputStream(); obuf.write2BE(17); obuf.write1(ChallengeAck); obuf.write(digest); obuf.WriteTo(socket.GetOutputStream()); if (traceLevel >= handshakeThreshold) { log.Debug("-> " + "HANDSHAKE sendChallengeAck" + " digest=" + hex(digest) + " local=" + self); } }
/** * Convert this binary to the equivalent Erlang external representation. * * @param buf * an output stream to which the encoded binary should be * written. */ public override void encode(OtpOutputStream buf) { buf.write_binary(bin); }
/** * Convert this port to the equivalent Erlang external representation. * * @param buf * an output stream to which the encoded port should be * written. */ public override void encode(OtpOutputStream buf) { buf.write_port(node, id, creation); }
/** * Send a pre-encoded message to a process on a remote node. * * @param dest * the Erlang PID of the remote process. * @param msg * the encoded message to send. * * @exception java.io.IOException * if the connection is not active or a communication * error occurs. */ public void sendBuf(OtpErlangPid dest, OtpOutputStream payload) { base.sendBuf(self.Pid, dest, payload); }