Esempio n. 1
0
      /**
       * @returns an enumerator for the local tunnel TAs. 
       */
      public IEnumerator GetEnumerator() {
        ArrayList nearest = _node.ConnectionTable.GetNearestTo( (AHAddress) _node.Address, 6);
        ArrayList forwarders = new ArrayList();
        foreach(Connection cons in nearest) {
#if TUNNEL_DEBUG
          Console.Error.WriteLine("TunnelEdgeListener: testing if we can tunnel using node: {0}", cons.Address);
#endif
          if (cons.Edge.TAType != TransportAddress.TAType.Tunnel) {
            forwarders.Add(cons.Address);
#if TUNNEL_DEBUG
            Console.Error.WriteLine("TunnelEdgeListener: added node: {0} to tunnel TA", cons.Address);
#endif
          }
        }
        if (forwarders.Count >= MIN_FORWARDERS ) {
          TransportAddress tun_ta = new TunnelTransportAddress(_node.Address, forwarders);
#if TUNNEL_DEBUG
          Console.Error.WriteLine("TunnelEdgeListener: built tunnel TA: {0}", tun_ta);
#endif          
          yield return tun_ta;
        }
      }
Esempio n. 2
0
    /**
     * When we get an EdgeRequest message, this is where we handle it.
     * @param remoteid remote id for the edge. 
     * @param localid local id for the edge. 
     * @param rest_of_payload control message.
     * @param return_path return path for the packet
     */
    protected void HandleEdgeRequest(int remoteid, int localid, MemBlock rest_of_payload, ISender return_path)
    {
#if TUNNEL_DEBUG
        Console.Error.WriteLine("Receiving edge request");
#endif
        //probably a new incoming edge
        bool is_new_edge = true;
        bool send_edge_event = false;
        TunnelEdge e = null;

        ArrayList args = (ArrayList) AdrConverter.Deserialize(rest_of_payload);
        Address target = AddressParser.Parse(MemBlock.Reference((byte[]) args[0]));
        //list of packet forwarders
        ArrayList forwarders = new ArrayList();
        for (int i = 1; i < args.Count; i++) {
          forwarders.Add(AddressParser.Parse(MemBlock.Reference((byte[]) args[i])));
        }
        //it is however possible that we have already created the edge locally

        lock( _sync ) {
        TunnelEdge e_dup = (TunnelEdge) _remote_id_ht[remoteid];
        if (e_dup != null) {
          TunnelTransportAddress remote_ta = new TunnelTransportAddress(target, forwarders);          
          //compare TAs
          TunnelTransportAddress e_rta = e_dup.RemoteTA as TunnelTransportAddress;
            if (e_rta != null && e_rta.Target.Equals( remote_ta.Target ) ) {
            //the fellow sent a duplicate edge request
            is_new_edge = false;
#if TUNNEL_DEBUG
            Console.Error.WriteLine("Duplicate edge request: from {0}", remote_ta);
#endif
            //but do send a response back
            //we also have to send a response back now
          } else {
            //someone else guessed the same id on its side
            //still okay, we can generate a unqiue id locally
          }
        } else {
          //this is the first edge request from a node and also
          //has a unique id on its side
          
        }
        if(is_new_edge) {
          do {
            localid = _rand.Next();
            //Make sure not to use negative ids
            if( localid < 0 ) { localid = ~localid; }
          } while( _id_ht.Contains(localid) || localid == 0 );
          
          //create an edge
          e = new TunnelEdge(this, true, _node, target, forwarders, localid, remoteid); 
#if TUNNEL_DEBUG
          Console.Error.WriteLine("Creating an instance of TunnelEdge: {0}", e);
          Console.Error.WriteLine("remoteid: {0}, localid: {1}", remoteid, localid);
#endif      

          _id_ht[localid] = e;
          _remote_id_ht[remoteid] = e;
          try {
            e.CloseEvent += this.CloseHandler;
          }
          catch {
            CloseHandler(e, null);
            throw;
          }
#if TUNNEL_DEBUG
          Console.Error.WriteLine("announcing tunnel edge (incoming): {0}", e);
#endif 
          send_edge_event = true;
        }
      }//Drop the lock

      /*
       * No matter what, we send a response back now
       */
        Packet p = null;
        using(MemoryStream ms = new MemoryStream()) {
          ms.WriteByte((byte) MessageType.EdgeResponse);
          NumberSerializer.WriteInt(localid, ms);
          NumberSerializer.WriteInt(remoteid, ms);
        
          //overwrite the first address in the edge response
          args[0] = _node.Address.ToMemBlock();

          AdrConverter.Serialize(args, ms);
          p = new AHPacket(1, 2, _node.Address, target, AHPacket.AHOptions.Exact, 
                                AHPacket.Protocol.Tunneling, ms.ToArray());
        }
        //send using the edge we received data on
#if TUNNEL_DEBUG
        Console.Error.WriteLine("Sending edge response: {0}", p);
#endif
        try {
          AHSender ahs = (AHSender)return_path;
          Edge from = (Edge)ahs.ReceivedFrom;
          from.Send(p);
#if TUNNEL_DEBUG
        } catch (Exception ex) {

          Console.Error.WriteLine(ex);
#else
        } catch (Exception) {
#endif
        }
        finally {
          if( send_edge_event ) {
            SendEdgeEvent(e);
          }
        }
    }
Esempio n. 3
0
    /**
     * When we get an a response to an EdgeRequest, we handle it here.
     * @param remoteid remote id for the edge. 
     * @param localid local id for the edge. 
     * @param rest_of_payload control message.
     */
    protected void HandleEdgeResponse(int remoteid, int localid, MemBlock rest_of_payload) {
        //assert (localid > 0) 
#if TUNNEL_DEBUG
        Console.Error.WriteLine("Receiving edge response");
#endif
        //possible response to our create edge request, make sure this 
        //is the case by verifying the remote TA
        ArrayList args = (ArrayList) AdrConverter.Deserialize(rest_of_payload);
        Address target = AddressParser.Parse(MemBlock.Reference((byte[]) args[0]));
        //list of packet forwarders
        ArrayList forwarders = new ArrayList();
        for (int i = 1; i < args.Count; i++) {
          forwarders.Add(AddressParser.Parse(MemBlock.Reference((byte[]) args[i])));
        }
        TunnelEdge e;
        EdgeCreationState ecs = null;
        lock( _sync ) {        
          //This gets the edge with the matching ids:
          e = GetTunnelEdge(localid, 0);
          if (e != null) {
  #if TUNNEL_DEBUG
            Console.Error.WriteLine("Must verify the remoteTA for the response");
  #endif
            TunnelTransportAddress remote_ta = new TunnelTransportAddress(target, forwarders);
  #if TUNNEL_DEBUG
            Console.Error.WriteLine("response.RemoteTA: {0}", remote_ta);
            Console.Error.WriteLine("edge.RemoteTA: {0}", e.RemoteTA);
  #endif
            TunnelTransportAddress e_rta = e.RemoteTA as TunnelTransportAddress;
            if (e_rta != null && e_rta.Target.Equals( remote_ta.Target ) ) {
              //Make sure they are trying to talk to us by checking
              //that the TA points to the same node
              e.RemoteID = remoteid;
  #if TUNNEL_DEBUG
              Console.Error.WriteLine("Edge protocol complete: {0}", e);
  #endif
              //raise an edge creation event 
              //this was an outgoing edge
              ecs = (EdgeCreationState) _ecs_ht[localid];
              _ecs_ht.Remove(localid);
              
            } else {
              //remote TAs do not match (ignore)
            } 
          }
        else {
          //We had no matching edge, or already handled this response
        }
          
        } //End of the lock

        if( ecs != null ) {
          try {
            e.CloseEvent += this.CloseHandler;
            //this would be an outgoing edge
#if TUNNEL_DEBUG
            Console.Error.WriteLine("remoteid: {0}, localid: {1}", remoteid, localid);
            Console.Error.WriteLine("announcing tunnel edge (outgoing): {0}", e);
#endif 
            ecs.CallECB(true, e, null);
          }
          catch(EdgeException) {
            /*
             * This edge has already closed so we need to handle it.
             * Note that we don't need to do CallECB which is handled
             * by the TimeoutChecker function.
             */
            CloseHandler(e, null);
          }
        }
        else {
            //This must have already been handled, we don't want to create
            //more than one edge, just ignore it.
        }
    }
Esempio n. 4
0
    /**
     * This method creates an instance of a tunnel edge to a remote node, given its 
     * tunnel transport URI.
     * @param ta TransportAddress to create an edge to
     * @param ecb the EdgeCreationCallback to call when done
     * @throw EdgeException if we try to call this before calling
     * Start.
     */
    public override void CreateEdgeTo(TransportAddress ta, EdgeCreationCallback ecb) 
    {
      try {
      if (!IsStarted) {
        throw new EdgeException("TunnelEdgeListener not started");
      }
      else if (0 == _running) {
        throw new EdgeException("TunnelEdgeListener not running");
      }
      else if (ta.TransportAddressType != this.TAType) {
	throw new EdgeException(ta.TransportAddressType.ToString()
				+ " is not my type: " + this.TAType.ToString());
      }
      else {
#if TUNNEL_DEBUG
        Console.Error.WriteLine("CreateEdgeTo TunnelEdge to: {0}", ta);
#endif  
        TunnelTransportAddress tun_ta = ta as TunnelTransportAddress;
        ArrayList forwarders = new ArrayList();
        ArrayList forwarding_edges = new ArrayList();
#if TUNNEL_DEBUG
        Console.Error.WriteLine("TunnelEdgeListener: Finding structured connections to tunnel over");
#endif
        IEnumerable struc_cons = _node.ConnectionTable.GetConnections(ConnectionType.Structured);
        if (struc_cons ==  null) {
#if TUNNEL_DEBUG
          Console.Error.WriteLine("List of structured connections is null");
#endif 
        }
#if TUNNEL_DEBUG
        Console.Error.WriteLine("TunnelEdgeListener: Browsing list of structured connections");
#endif
        foreach (Connection con in struc_cons) {
#if TUNNEL_DEBUG
          Console.Error.WriteLine("TunnelEdgeListener: Testing : {0}", con.Address);
#endif
          if (con.Edge.TAType == TransportAddress.TAType.Tunnel) {
#if TUNNEL_DEBUG
            Console.Error.WriteLine("Cannot tunnel over tunnel: " + con.Address.ToString());
#endif
            continue;
          }
          if (!tun_ta.ContainsForwarder(con.Address)) {
#if TUNNEL_DEBUG
            Console.Error.WriteLine("Cannot tunnel over connection: " + con.Address.ToString());
#endif
            continue;
          }
#if TUNNEL_DEBUG
          Console.Error.WriteLine("Can tunnel over connection: " + con.Address.ToString());
#endif
          forwarders.Add(con.Address);
          forwarding_edges.Add(con.Edge);
        }

        if (forwarders.Count < MIN_FORWARDERS) {
          ecb(false, null, new EdgeException("Cannot create edge over TA: " + tun_ta + ", not many forwarders"));
          return;
        }
        tun_ta = new TunnelTransportAddress(tun_ta.Target, forwarders);
        
        //choose a locally unique id
        lock( _sync ) {
          //Get a random ID for this edge:
          int localid;
          int remoteid = 0;
          do {
            localid = _rand.Next();
            //Make sure we don't have negative ids
            if( localid < 0 ) { localid = ~localid; }
          } while( _id_ht.Contains(localid) || localid == 0 );      
          //looks like the new edge is ready
          TunnelEdge e = new TunnelEdge(this, false, _node, tun_ta.Target, forwarders, localid, remoteid);
#if TUNNEL_DEBUG
          Console.Error.WriteLine("Creating an instance of TunnelEdge: {0}", e);
          Console.Error.WriteLine("remoteid: {0}, localid: {1}", remoteid, localid);
#endif      
          _id_ht[localid] = e;
          //we will defer the new edge event for later
          //when we actually get a response
          
          //now build the packet payload
          Packet p = null;
          using(MemoryStream ms = new MemoryStream()) {
            ms.WriteByte((byte) MessageType.EdgeRequest);
            NumberSerializer.WriteInt(localid, ms);
            NumberSerializer.WriteInt(remoteid, ms);
    #if TUNNEL_DEBUG
            Console.Error.WriteLine("Written off type, localid, remoteid");
    #endif
            
            ArrayList args = new ArrayList();
            //add the target address
            byte[] addr_bytes = new byte[Address.MemSize];
            _node.Address.CopyTo(addr_bytes);
            args.Add(addr_bytes.Clone());
    #if TUNNEL_DEBUG
            Console.Error.WriteLine("Added target address");
    #endif
            
            foreach (Address fwd in  forwarders) {
              //add forwarding addresses
              fwd.CopyTo(addr_bytes);
              args.Add(addr_bytes.Clone());
    #if TUNNEL_DEBUG
              Console.Error.WriteLine("Added a forwarding address");
    #endif
    
            }
    #if TUNNEL_DEBUG
            Console.Error.WriteLine("Creating a memory stream holding the payload");
    #endif
            AdrConverter.Serialize(args, ms);
            p = new AHPacket(1, 2, _node.Address, tun_ta.Target, AHPacket.AHOptions.Exact, 
                                 AHPacket.Protocol.Tunneling, ms.ToArray());
          }
#if TUNNEL_DEBUG
          Console.Error.WriteLine("Created a request packet.");
#endif
          EdgeCreationState ecs = new EdgeCreationState(localid, forwarding_edges, p, ecb);
          _ecs_ht[localid] = ecs;

#if TUNNEL_DEBUG
          Console.Error.WriteLine("Created an edge creation state for the tunnel edge: {0}", e);
#endif
        }
      }
      //we will defer this sending to next heartbeat; an artificial delay from out own side
      } catch(Exception e) {
	ecb(false, null, e);
      }
    }
Esempio n. 5
0
    protected static TransportAddress NoCacheCreateInstance(string s) {
      string scheme = s.Substring(0, s.IndexOf(":"));
      string t = scheme.Substring(scheme.IndexOf('.') + 1);
      //Console.Error.WriteLine(t);
      
      TransportAddress result = null;
      TransportAddress.TAType ta_type = StringToType(t);
      
      if (ta_type ==  TransportAddress.TAType.Tcp) {
	result = new IPTransportAddress(s);
      }
      if (ta_type ==  TransportAddress.TAType.Udp) {
	result = new IPTransportAddress(s);
      }
      if (ta_type ==  TransportAddress.TAType.Function) {
	result = new IPTransportAddress(s);
      }
      if (ta_type ==  TransportAddress.TAType.Tls) {
	result = new IPTransportAddress(s);
      }
      if (ta_type ==  TransportAddress.TAType.TlsTest) {
	result = new IPTransportAddress(s);
      }
      if (ta_type ==  TransportAddress.TAType.Tunnel) {
	result = new TunnelTransportAddress(s);
      }
      return result;
    }
Esempio n. 6
0
    public void Test() {
      TransportAddress ta1 = TransportAddressFactory.CreateInstance("brunet.udp://10.5.144.69:5000");
      Assert.AreEqual(ta1.ToString(), "brunet.udp://10.5.144.69:5000", "Testing TA parsing");
      
      TransportAddress ta2 = TransportAddressFactory.CreateInstance("brunet.udp://10.5.144.69:5000"); 
      Assert.AreEqual(ta1, ta2, "Testing TA Equals");
      
      string ta_string = "brunet.tunnel://UBU72YLHU5C3SY7JMYMJRTKK4D5BGW22/FE4QWASN+FE4QWASM";
      TransportAddress ta = TransportAddressFactory.CreateInstance("brunet.tunnel://UBU72YLHU5C3SY7JMYMJRTKK4D5BGW22/FE4QWASN+FE4QWASM");
      Assert.AreEqual(ta.ToString(), ta_string, "testing tunnel TA parsing");
      //Console.WriteLine(ta);

      TunnelTransportAddress tun_ta = (TunnelTransportAddress) TransportAddressFactory.CreateInstance("brunet.tunnel://OIHZCNNUAXTLLARQIOBNCUWXYNAS62LO/CADSL6GV+CADSL6GU");

      ArrayList fwd = new ArrayList();
      fwd.Add(new AHAddress(Base32.Decode("CADSL6GVVBM6V442CETP4JTEAWACLC5A")));
      fwd.Add(new AHAddress(Base32.Decode("CADSL6GUVBM6V442CETP4JTEAWACLC5A")));
      
      TunnelTransportAddress test_ta = new TunnelTransportAddress(tun_ta.Target, fwd);
      Assert.AreEqual(tun_ta, test_ta, "testing tunnel TA compression enhancements");
      //Console.WriteLine(tun_ta.ToString());
      //Console.WriteLine(test_ta.ToString());
      Assert.AreEqual(tun_ta.ToString(), test_ta.ToString(), "testing tunnel TA compression enhancements (toString)");

      Assert.AreEqual(tun_ta.ContainsForwarder(new AHAddress(Base32.Decode("CADSL6GVVBM6V442CETP4JTEAWACLC5A"))), true, 
		      "testing tunnel TA contains forwarder (1)");

      Assert.AreEqual(tun_ta.ContainsForwarder(new AHAddress(Base32.Decode("CADSL6GUVBM6V442CETP4JTEAWACLC5A"))), true, 
		      "testing tunnel TA contains forwarder (2)");

      
      
      string StrLocalHost = Dns.GetHostName();
      IPHostEntry IPEntry = Dns.GetHostEntry(StrLocalHost);
      TransportAddress local_ta = TransportAddressFactory.CreateInstance("brunet.udp://" +  IPEntry.AddressList[0].ToString() + 
									 ":" + 5000);
      IEnumerable locals = TransportAddressFactory.CreateForLocalHost(TransportAddress.TAType.Udp, 5000);

      bool match = false;
      foreach (TransportAddress test_ta1 in locals) {
	//Console.WriteLine("test_ta: {0}", test_ta1);
	if (test_ta1.Equals(local_ta)) {
	  match = true;
	}
      }
      Assert.AreEqual(match, true, "testing local TA matches");
      //testing function TA
      TransportAddress func_ta = TransportAddressFactory.CreateInstance("brunet.function://localhost:3000");
      TransportAddress func_ta2 = TransportAddressFactory.CreateInstance("brunet.function://localhost:3000");
      Assert.AreEqual(func_ta, func_ta2, "equality of instances");
      Assert.IsTrue(func_ta == func_ta2, "reference equality, test of caching");
      Assert.AreEqual(func_ta.ToString(), "brunet.function://localhost:3000", "Testing function TA parsing");
      
    }
    protected static TransportAddress NoCacheCreateInstance(string s) {
      string scheme = s.Substring(0, s.IndexOf(":"));
      string t = scheme.Substring(scheme.IndexOf('.') + 1);
      //Console.Error.WriteLine(t);
      
      TransportAddress result = null;
      TransportAddress.TAType ta_type = StringToType(t);
      
      switch(ta_type) {
        case TransportAddress.TAType.Tcp:
          result = new IPTransportAddress(s);
          break;
        case TransportAddress.TAType.Udp:
          result = new IPTransportAddress(s);
          break;
        case TransportAddress.TAType.Function:
          result = new IPTransportAddress(s);
          break;
        case TransportAddress.TAType.S:
          result = new SimulationTransportAddress(s);
          break;
        case TransportAddress.TAType.Tls:
          result = new IPTransportAddress(s);
          break;
        case TransportAddress.TAType.TlsTest:
          result = new IPTransportAddress(s);
          break;
        case TransportAddress.TAType.Tunnel:
          result = new TunnelTransportAddress(s);
          break;
      }

      return result;
    }
Esempio n. 8
0
    /**
     * Handle a synchornization packet from tunnel edge target.  
     * @param forwarders list of forwarding addresses the target is
     * using.
     */
    public void HandleSyncPacket(ArrayList forwarders) {
      //This does not require a lock, and stuct_cons can't change after this call
      IEnumerable struct_cons =
          _node.ConnectionTable.GetConnections(ConnectionType.Structured);
      ArrayList temp_forwarders = new ArrayList();
      ArrayList temp_senders = new ArrayList();
      foreach(Connection c in struct_cons) {
        if(forwarders.Contains(c.Address)) {
          if(c.Edge.TAType != TAType) {
            temp_forwarders.Add(c.Address);
            temp_senders.Add(c.Edge);
          }
        }
      }
      TransportAddress new_local 
        = new TunnelTransportAddress(_node.Address, temp_forwarders);
      TransportAddress new_remote
        = new TunnelTransportAddress(_target, temp_forwarders);
      /*
       * We are clearly only holding on lock in the below code
       * since we are only writing to memory and not calling any
       * functions
       */
      lock(_sync) {
        _forwarders = temp_forwarders;
        _packet_senders = temp_senders;
        _localta = new_local;
        _remoteta = new_remote;	  
      }
#if TUNNEL_DEBUG
      Console.Error.WriteLine("Synchronized edge: {0}.", this);
#endif 
      if (temp_forwarders.Count == 0) {
        //Now we have no forwarders, so close the edge
        Close();
      }
    }