Source/NFX.Erlang/Connect/ErlEpmd.cs
/// <summary>
/// Determine what port a node listens for incoming connections on
/// </summary>
/// <param name="home">Local node</param>
/// <param name="node">Remote lode for which to look up the port number from remote EPMD</param>
/// <param name="closeSocket">If true, close the connection to remote EPMD at return</param>
/// <returns>the listen port for the specified node, or 0 if the node
/// was not registered with Epmd</returns>
Determine what port a node listens for incoming connections on
Determine what port a node listens for incoming connections on
public static int LookupPort(ErlLocalNode home, ErlRemoteNode node,
        bool closeSocket = false)
    {
      IErlTransport s = null;
      try
      {
        var obuf = new ErlOutputStream(writeVersion: false, capacity: 4 + 3 + node.AliveName.Length + 1);
        s = node.Epmd;
        if (s == null)
        {
          s = ErlTransportFactory.Create(node.TransportClassName, node.NodeName.Value);
          s.Trace += (o, t, d, msg) => home.OnTrace(t, d, msg);
          node.AppendSSHParamsToTransport(s);
          s.Connect(node.Host, EPMD_PORT, node.ConnectTimeout);
        }
        obuf.Write2BE(node.AliveName.Length + 1);
        obuf.Write1((byte)Indicator.Port4req);
        byte[] buf = Encoding.ASCII.GetBytes(node.AliveName);
        obuf.Write(buf);
        obuf.WriteTo(s.GetStream());
        home.OnTrace(ErlTraceLevel.Epmd, Direction.Outbound,
                StringConsts.ERL_EPMD_LOOKUP_R4.Args(node.NodeName.Value));
        buf = new byte[100];
        int n = s.GetStream().Read(buf, 0, buf.Length);
        if (n < 0)
          throw new ErlException(StringConsts.ERL_EPMD_NOT_RESPONDING.Args(node.Host, node.AliveName));
        var ibuf = new ErlInputStream(buf, 0, n, checkVersion: false);
        if (Indicator.Port4resp == (Indicator)ibuf.Read1())
        {
          if (0 == ibuf.Read1())
          {
            node.Port = ibuf.Read2BE();
            node.Ntype = (ErlAbstractNode.NodeType)ibuf.Read1();
            node.Proto = ibuf.Read1();
            node.DistHigh = ibuf.Read2BE();
            node.DistLow = ibuf.Read2BE();
          }
        }
        if (!closeSocket)
        {
          node.Epmd = s;
          s = null;
        }
      }
      catch (Exception e)
      {
        home.OnTrace(ErlTraceLevel.Epmd, Direction.Inbound, StringConsts.ERL_EPMD_INVALID_RESPONSE_ERROR.Args(node.Host, node.AliveName, e.ToString()));
        throw new ErlException(StringConsts.ERL_EPMD_NOT_RESPONDING.Args(node.Host, node.AliveName, e.ToString()));
      }
      finally
      {
        if (s != null)
          try { s.Close(); } catch { }
        s = null;
      }
      home.OnTrace(ErlTraceLevel.Epmd, Direction.Inbound, () =>
          node.Port == 0 ? StringConsts.ERL_EPMD_NOT_FOUND : StringConsts.ERL_EPMD_PORT.Args(node.Port));
      return node.Port;
    }
public static int LookupPort ( ErlLocalNode home , ErlRemoteNode node , bool closeSocket = false ) { IErlTransport s = null ; try { var obuf = new ErlOutputStream ( writeVersion : false , capacity : 4 + 3 + node . AliveName . Length + 1 ) ; s = node . Epmd ; if ( s == null ) { s = ErlTransportFactory . Create ( node . TransportClassName , node . NodeName . Value ) ; s . Trace += ( o , t , d , msg ) => home . OnTrace ( t , d , msg ) ; node . AppendSSHParamsToTransport ( s ) ; s . Connect ( node . Host , EPMD_PORT , node . ConnectTimeout ) ; } obuf . Write2BE ( node . AliveName . Length + 1 ) ; obuf . Write1 ( ( byte ) Indicator . Port4req ) ; byte [ ] buf = Encoding . ASCII . GetBytes ( node . AliveName ) ; obuf . Write ( buf ) ; obuf . WriteTo ( s . GetStream ( ) ) ; home . OnTrace ( ErlTraceLevel . Epmd , Direction . Outbound , StringConsts . ERL_EPMD_LOOKUP_R4 . Args ( node . NodeName . Value ) ) ; buf = new byte [ 100 ] ; int n = s . GetStream ( ) . Read ( buf , 0 , buf . Length ) ; if ( n < 0 ) throw new ErlException ( StringConsts . ERL_EPMD_NOT_RESPONDING . Args ( node . Host , node . AliveName ) ) ; var ibuf = new ErlInputStream ( buf , 0 , n , checkVersion : false ) ; if ( Indicator . Port4resp == ( Indicator ) ibuf . Read1 ( ) ) { if ( 0 == ibuf . Read1 ( ) ) { node . Port = ibuf . Read2BE ( ) ; node . Ntype = ( ErlAbstractNode . NodeType ) ibuf . Read1 ( ) ; node . Proto = ibuf . Read1 ( ) ; node . DistHigh = ibuf . Read2BE ( ) ; node . DistLow = ibuf . Read2BE ( ) ; } } if ( ! closeSocket ) { node . Epmd = s ; s = null ; } } catch ( Exception e ) { home . OnTrace ( ErlTraceLevel . Epmd , Direction . Inbound , StringConsts . ERL_EPMD_INVALID_RESPONSE_ERROR . Args ( node . Host , node . AliveName , e . ToString ( ) ) ) ; throw new ErlException ( StringConsts . ERL_EPMD_NOT_RESPONDING . Args ( node . Host , node . AliveName , e . ToString ( ) ) ) ; } finally { if ( s != null ) try { s . Close ( ) ; } catch { } s = null ; } home . OnTrace ( ErlTraceLevel . Epmd , Direction . Inbound , ( ) => node . Port == 0 ? StringConsts . ERL_EPMD_NOT_FOUND : StringConsts . ERL_EPMD_PORT . Args ( node . Port ) ) ; return node . Port ; }
Determine what port a node listens for incoming connections on
Determine what port a node listens for incoming connections on
//create transport //append SSH params to transport //connect (I am not sure) // build and send epmd request // length[2], tag[1], alivename[n] (length = n+1) //UPGRADE_NOTE: This code will be optimized in the future; // send request // 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] // ignore rest of fields
the listen port for the specified node, or 0 if the node
was not registered with Epmd
the listen port for the specified node or 0 if the node was not registered with Epmd
home
ErlLocalNode
None
node
ErlRemoteNode
Remote lode for which to look up the port number from remote EPMD
Remote lode for which to look up the port number from remote EPMD
closeSocket
bool
If true, close the connection to remote EPMD at return
If true close the connection to remote EPMD at return