/**
  * This handles the packet forwarding protocol
  */
 public void HandleData(MemBlock b, ISender ret_path, object state)
 {
   /*
    * Check it
    */
   AHSender ahs = ret_path as AHSender;
   if( ahs != null ) {
     //This was an AHSender:
     /*
      * This goes A -> B -> C
      */
     if( b[0] == 0 ) {
       int offset = 1;
       //This is the first leg, going from A->B
       Address add_c = AddressParser.Parse(b.Slice(offset, Address.MemSize));
       offset += Address.MemSize;
       //Since ahs a sender to return, we would be the source:
       Address add_a = ahs.Destination;
       short ttl = NumberSerializer.ReadShort(b, offset);//2 bytes
       offset += 2;
       ushort options = (ushort) NumberSerializer.ReadShort(b, offset);//2 bytes
       offset += 2;
       MemBlock payload = b.Slice(offset);
       MemBlock f_header = MemBlock.Reference( new byte[]{1} );
       /*
        * switch the packet from [A B f0 C] to [B C f 1 A]
        */
       ICopyable new_payload = new CopyList(PType.Protocol.Forwarding,
                                        f_header, add_a, payload);
       /*
        * ttl and options are present in the forwarding header.
        */
       AHSender next = new AHSender(_n, ahs.ReceivedFrom, add_c,
                                    ttl,
                                    options); 
       next.Send(new_payload);
     }
     else if ( b[0] == 1 ) {
       /*
        * This is the second leg: B->C
        * Make a Forwarding Sender, and unwrap the inside packet
        */
       Address add_a = AddressParser.Parse(b.Slice(1, Address.MemSize));
       Address add_b = ahs.Destination;
       MemBlock rest_of_payload = b.Slice(1 + Address.MemSize);
       //Here's the return path:
       ISender new_ret_path = new ForwardingSender(_n, add_b, add_a);
       _n.HandleData(rest_of_payload, new_ret_path, this);
     }
   }
   else {
     //This is not (currently) supported.
     Console.Error.WriteLine("Got a forwarding request from: {0}", ret_path);
   }
 }
Esempio n. 2
0
        public ARPPacket(int HardwareType, int ProtocolType, Operations Operation,
        MemBlock SenderHWAddress, MemBlock SenderProtoAddress, MemBlock TargetHWAddress,
        MemBlock TargetProtoAddress)
        {
            byte[] header = new byte[8];
              NumberSerializer.WriteUShort((ushort) HardwareType, header, 0);
              NumberSerializer.WriteUShort((ushort) ProtocolType, header, 2);
              header[4] = (byte) SenderHWAddress.Length;
              header[5] = (byte) SenderProtoAddress.Length;
              NumberSerializer.WriteUShort((ushort) Operation, header, 6);

              _icpacket = new CopyList(MemBlock.Reference(header), SenderHWAddress,
              SenderProtoAddress, TargetHWAddress, TargetProtoAddress);
        }
Esempio n. 3
0
    /**
    <summary>Takes in the IP Header fields and a payload to create an IP
    Packet.  Unlisted fields are generated by this constructor automatically.
    </summary>
    <param name="Protocol">The type of payload</param>
    <param name="SourceIP">The packets originating ip address</param>
    <param name="DestinationIP">The destination for the packet</param>
    <param name="hdr">The original header of the IPPacket</param>
    <param name="Payload">The data stored in the IP Packet</param>
    */
    public IPPacket(Protocols Protocol, MemBlock SourceIP,
                    MemBlock DestinationIP, MemBlock hdr, ICopyable Payload) {
      byte[] header = new byte[20];
      // Version | IHL
      header[0] = hdr[0];
      // Just a routine header!
      header[1] = hdr[1];
      int length = header.Length + Payload.Length;
      header[2] = (byte) ((length >> 8) & 0xFF);
      header[3] = (byte) (length & 0xFF);
      // Fragment crap
      header[4] = hdr[4];
      header[5] = hdr[5];
      header[6] = hdr[6];
      header[7] = hdr[7];
      // TTL
      header[8] = hdr[8];
      header[9] = hdr[9]; 
      for(int i = 0; i < 4; i++) {
        header[12 + i] = SourceIP[i];
        header[16 + i] = DestinationIP[i];
      }
      int checksum = GenerateChecksum(MemBlock.Reference(header));
      header[10] = (byte) ((checksum >> 8) & 0xFF);
      header[11] = (byte) (checksum & 0xFF);

      MemBlock Header = MemBlock.Reference(header);
      _icpacket = new CopyList(Header, Payload);

      this.Protocol = Protocol;
      this.SourceIP = SourceIP;
      this.DestinationIP = DestinationIP;
      _icpayload = Payload;
    }
Esempio n. 4
0
        /**
        <summary>Constructor when creating a DNS Query</summary>
        <param name="QNAME">the name of resource you are looking up, IP Address
        when QTYPE = PTR otherwise hostname</param>
        <param name="QTYPE"> the type of look up to perform</param>
        <param name="QCLASS">should always be IN</param>
        */
        public Question(String QNAME, DNSPacket.TYPES QTYPE, DNSPacket.CLASSES QCLASS)
        {
            this.QNAME = QNAME;
              this.QTYPE = QTYPE;
              this.QCLASS = QCLASS;

              if(QTYPE == DNSPacket.TYPES.A) {
            QNAME_BLOB = DNSPacket.HostnameStringToMemBlock(QNAME);
              }
              else if(QTYPE == DNSPacket.TYPES.PTR) {
            QNAME_BLOB = DNSPacket.PtrStringToMemBlock(QNAME);
              }
              else {
            throw new Exception("Invalid QTYPE: " + QTYPE + "!");
              }

            // 2 for QTYPE + 2 for QCLASS
              byte[] data = new byte[4];
              int idx = 0;
              data[idx++] = (byte) ((((int) QTYPE) >> 8) & 0xFF);
              data[idx++] = (byte) (((int) QTYPE) & 0xFF);
              data[idx++] = (byte) ((((int) QCLASS) >> 8) & 0xFF);
              data[idx++] = (byte) (((int) QCLASS) & 0xFF);
              _icpacket = new CopyList(QNAME_BLOB, MemBlock.Reference(data));
        }
 /// <summary>After a restart of the Security system, one guy may think
 /// we still have an association and there will be no way for him to know
 /// that our side is broken, unless we notify him as such.  We notify him
 /// by sending this packet.  How he deals with that is up to him.</summary>
 protected void NoSuchSA(int spi, ISender remote_sender) {
   SecurityControlMessage scm_reply = new SecurityControlMessage();
   scm_reply.Version = Version;
   scm_reply.SPI = spi;
   scm_reply.Type = SecurityControlMessage.MessageType.NoSuchSA;
   ICopyable to_send = new CopyList(Security, SecureControl, scm_reply.Packet);
   remote_sender.Send(to_send);
 }
Esempio n. 6
0
        /// <summary>Creates an Ethernet Packet from Ethernet fields and the payload</summary>
        /// <param name="DestinationAddress">Where the Ethernet packet is going.</param>
        /// <param name="SourceAddress">Where the Ethernet packet originated.</param>
        /// <param name="Type">Type of Ethernet payload.</param>
        /// <param name="Payload">Payload as an ICopyable</param>
        public EthernetPacket(MemBlock DestinationAddress, MemBlock SourceAddress,
                        Types Type, ICopyable Payload)
        {
            byte[] header = new byte[14];
              for(int i = 0; i < 6; i++) {
            header[i] = DestinationAddress[i];
            header[6 + i] = SourceAddress[i];
              }

              header[12] = (byte) (((int) Type >> 8) & 0xFF);
              header[13] = (byte) ((int) Type & 0xFF);

              _icpacket = new CopyList(MemBlock.Reference(header), Payload);
              _icpayload = Payload;

              this.DestinationAddress = DestinationAddress;
              this.SourceAddress = SourceAddress;
              this.Type = Type;
        }
Esempio n. 7
0
        public DHCPPacket(byte op, MemBlock xid, MemBlock ciaddr, MemBlock yiaddr,
                     MemBlock siaddr, MemBlock chaddr, Dictionary<OptionTypes, MemBlock> Options)
        {
            this.op = op;
              this.xid = xid;
              this.ciaddr = ciaddr;
              this.yiaddr = yiaddr;
              this.siaddr = siaddr;
              this.chaddr = chaddr;
              this.Options = Options;

              byte[] header = new byte[240];
              header[0] = op;
              header[1] = 1;
              header[2] = (byte) chaddr.Length;
              header[3] = 0;

              xid.CopyTo(header, 4);
              for(int i = 8; i < 12; i++) {
            header[i] = 0;
              }
              ciaddr.CopyTo(header, 12);
              yiaddr.CopyTo(header, 16);
              siaddr.CopyTo(header, 20);
              for(int i = 24; i < 28; i++) {
            header[i] = 0;
              }
              chaddr.CopyTo(header, 28);
              for(int i = 34; i < 236; i++) {
            header[i] = 0;
              }
              magic_key.CopyTo(header, 236);

              _icpacket = new CopyList(MemBlock.Reference(header));
              foreach(KeyValuePair<OptionTypes, MemBlock> kvp in Options) {
            MemBlock value = kvp.Value;

            byte[] tmp = new byte[2];
            tmp[0] = (byte) kvp.Key;
            tmp[1] = (byte) value.Length;

            _icpacket = new CopyList(_icpacket, MemBlock.Reference(tmp), value);
              }
              byte []end = new byte[1]{255}; /* End of Options */
              _icpacket = new CopyList(_icpacket, MemBlock.Reference(end));
        }
Esempio n. 8
0
 /**
  * Abandon any attempts to get requests for the given ID.
  * @throw Exception if handler is not the original handler for this Request
  */
 public void StopRequest(int request_id, IReplyHandler handler) {
   RequestState rs = null;
   lock( _sync ) {
     rs = (RequestState)_req_state_table[request_id];
     if( rs != null ) {
       if( rs.ReplyHandler != handler ) {
         throw new Exception( String.Format("Handler mismatch: {0} != {1}",
                                            handler, rs.ReplyHandler));
       }
       _req_state_table.Remove( request_id );
     }
   }
   if( rs != null ) {
      /*
       * Send an ack for this reply:
       */
      byte[] ack_payload = new byte[5];
      ack_payload[0] = (byte)ReqrepType.ReplyAck;
      NumberSerializer.WriteInt(request_id, ack_payload, 1);
      ICopyable data = new CopyList(PType.Protocol.ReqRep, MemBlock.Reference(ack_payload));
      foreach(ISender ret_path in rs.Repliers) {
        try {
          //Try to send an ack, but if we can't, oh well...
          ret_path.Send(data);
        }
        catch { }
      }
   }
 }
Esempio n. 9
0
 /**
  * Creates the tunnel header attached in front of packet sent on the tunnnel edge. 
  * We have to make this everytime _remote_id changes.
  * @param local_id local id of the edge. 
  * @param remote_id remote id of the edge. 
  * @param source local node address.
  * @param target target node address.
  */
 protected static ICopyable GetTunnelHeader(int local_id, int remote_id, Address source, Address target) {
   //The header always stays fixed for this TunnelEdge
   byte[] ids = new byte[9];
   ids[0] = (byte) TunnelEdgeListener.MessageType.EdgeData;
   //Write the IDs of the edge:
   //[edge data][local id 4 bytes][remote id 4 bytes][packet]
   NumberSerializer.WriteInt(local_id, ids, 1);
   NumberSerializer.WriteInt(remote_id, ids, 5);
   MemBlock ids_mb = MemBlock.Reference( ids );
   ICopyable header = new CopyList( PType.Protocol.AH,
                                    new AHHeader(1, 2, source, target, AHPacket.AHOptions.Exact),
                                    PType.Protocol.Tunneling,
                                    ids_mb );
   //Now we have assembled the full header to prepend to any data, but
   //it is a waste to do all the copying each time, so we copy it into
   //one buffer now:
   return MemBlock.Copy( (ICopyable) header );
 }
Esempio n. 10
0
        /**
        <summary>Creates a DNS packet from the parameters provided.</summary>
        <param name="ID">A unique ID for the packet, responses should be the same
        as the query</param>
        <param name="QUERY">True if a query, false if a response</param>
        <param name="OPCODE">0 = Query, which is the only supported parsing method
        </param>
        <param name="AA">Authoritative Answer, true if there is a resolution for
        the lookup.</param>
        <param name="Questions">A list of Questions.</param>
        <param name="Answers">A list of Answers.</param>
        */
        public DNSPacket(short ID, bool QUERY, byte OPCODE, bool AA, bool RA,
                     bool RD, Question[] Questions, Response[] Answers,
                     Response[] Authority, Response[] Additional)
        {
            byte[] header = new byte[12];

              this.ID = ID;
              header[0] = (byte) ((ID >> 8) & 0xFF);
              header[1] = (byte) (ID & 0xFF);

              this.QUERY = QUERY;
              if(!QUERY) {
            header[2] |= 0x80;
              }

              this.OPCODE = OPCODE;
              header[2] |= (byte) (OPCODE << 3);

              this.AA = AA;
              if(AA) {
            header[2] |= 0x4;
              }
              this.RD = RD;
              if(RD) {
            header[2] |= 0x1;
              }
              this.RA = RA;
              if(RA) {
            header[3] |= 0x80;
              }

              if(Questions != null) {
            this.Questions = Questions;
            header[4] = (byte) ((Questions.Length >> 8) & 0xFF);
            header[5] = (byte) (Questions.Length  & 0xFF);
              }
              else {
            this.Questions = new Question[0];
            header[4] = 0;
            header[5] = 0;
              }

              if(Answers != null) {
            this.Answers = Answers;
            header[6] = (byte) ((Answers.Length >> 8) & 0xFF);
            header[7] = (byte) (Answers.Length  & 0xFF);
              }
              else {
            this.Answers = new Response[0];
            header[6] = 0;
            header[7] = 0;
              }

              if(Authority != null) {
            this.Authority = Authority;
            header[8] = (byte) ((Authority.Length >> 8) & 0xFF);
            header[9] = (byte) (Authority.Length  & 0xFF);
              }
              else {
            this.Authority = new Response[0];
            header[8] = 0;
            header[9] = 0;
              }

              if(Additional != null) {
            this.Additional = Additional;
            header[10] = (byte) ((Additional.Length >> 8) & 0xFF);
            header[11] = (byte) (Additional.Length  & 0xFF);
              }
              else {
            this.Additional = new Response[0];
            header[10] = 0;
            header[11] = 0;
              }

              _icpacket = MemBlock.Reference(header);

              for(int i = 0; i < this.Questions.Length; i++) {
            _icpacket = new CopyList(_icpacket, Questions[i].ICPacket);
              }
              for(int i = 0; i < this.Answers.Length; i++) {
            _icpacket = new CopyList(_icpacket, Answers[i].ICPacket);
              }
              for(int i = 0; i < this.Authority.Length; i++) {
            _icpacket = new CopyList(_icpacket, Authority[i].ICPacket);
              }
              for(int i = 0; i < this.Additional.Length; i++) {
            _icpacket = new CopyList(_icpacket, Additional[i].ICPacket);
              }
        }
Esempio n. 11
0
    /// <summary>3b) Receive a Confirm, verify the entire stack and send a Confirm
    /// 4a)Receive a Confirm, verify the entire stack and all set to go</summary>
    /// <param name="sa">A security association that we wish to perform the
    /// specified control operation on.</param>
    /// <param name="scm">The received SecurityControlMessage.</param>
    /// <param name="scm_reply">A prepared reply message (with headers and such.</param>
    /// <param name="return_path">Where to send the result.</param>
    /// <param name="low_level_sender">We expect the return_path to not be an edge or
    /// some other type of "low level" sender, so this contains the parsed out value.</param>
    protected void HandleControlConfirm(SecurityAssociation sa,
        SecurityControlMessage scm, SecurityControlMessage scm_reply,
        ISender return_path, ISender low_level_sender)
    {
      ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Received Confirm from: " + low_level_sender);
      if(sa == null) {
        throw new Exception("No valid SA!");
      }
      HashAlgorithm sha1 = new SHA1CryptoServiceProvider();
      scm.Verify((RSACryptoServiceProvider) sa.RemoteCertificate.Value.RSA, sha1);

      if(return_path == low_level_sender) {
        sa.VerifyResponse(scm.Hash);
      } else {
        sa.VerifyRequest(scm.Hash);
        scm_reply.LocalCookie = scm.RemoteCookie;
        scm_reply.RemoteCookie = scm.LocalCookie;
        scm_reply.Hash = sa.DHEWithCertificateAndCAsInHash.Value;
        scm_reply.Type = SecurityControlMessage.MessageType.Confirm;
        lock(_private_key_lock) {
          scm_reply.Sign(_private_key, sha1);
        }
        ICopyable to_send = new CopyList(SecureControl, scm_reply.Packet);
        return_path.Send(to_send);
      }
      if(Verify(sa)) {
        sa.Enable();
      } else {
        sa.Close("Unable to verify the SA as being valid!");
      }

      ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Successful Confirm from: " + low_level_sender);
    }
Esempio n. 12
0
    /// <summary>3a) Receive a DHEWithCertificate, verify the certificate and DHE and
    /// send a Confirm that you are ready to Verify the stack and start the
    /// system.</summary>
    /// <param name="sa">A security association that we wish to perform the
    /// specified control operation on.</param>
    /// <param name="scm">The received SecurityControlMessage.</param>
    /// <param name="scm_reply">A prepared reply message (with headers and such.</param>
    /// <param name="return_path">Where to send the result.</param>
    /// <param name="low_level_sender">We expect the return_path to not be an edge or
    /// some other type of "low level" sender, so this contains the parsed out value.</param>
    protected void HandleControlDHEWithCertificates(SecurityAssociation sa,
        SecurityControlMessage scm, SecurityControlMessage scm_reply,
        ISender return_path, ISender low_level_sender)
    {
      ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Received DHEWithCertificate from: " + low_level_sender);
      if(sa == null) {
        throw new Exception("No valid SA!");
      }
      byte[] cert = new byte[scm.Certificate.Length];
      scm.Certificate.CopyTo(cert, 0);
      X509Certificate rcert = new X509Certificate(cert);
      HashAlgorithm sha1 = new SHA1CryptoServiceProvider();
      scm.Verify((RSACryptoServiceProvider) rcert.RSA, sha1);
      _ch.Verify(rcert);

      sa.RemoteCertificate.Value = rcert;
      sa.RDHE.Value = scm.DHE;

      scm_reply.LocalCookie = scm.RemoteCookie;
      scm_reply.RemoteCookie = scm.LocalCookie;
      scm_reply.Hash = MemBlock.Reference(sha1.ComputeHash((byte[]) scm.Packet));
      scm_reply.Type = SecurityControlMessage.MessageType.Confirm;
      lock(_private_key_lock) {
        scm_reply.Sign(_private_key, sha1);
      }

      ICopyable to_send = new CopyList(Security, SecureControl, scm_reply.Packet);
      _rrman.SendRequest(return_path, ReqrepManager.ReqrepType.Request,
          to_send, this, sa);
      ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Successful DHEWithCertificate from: " + low_level_sender);
    }
Esempio n. 13
0
    /// <summary>2b) Receive a DHEWithCertificateAndCAs, verify the certificate and attempt
    /// to find a matching Certificate for the list of CAs, if you find one,
    /// finish the DHE handshake and send the certificate via a DHEWithCertificate</summary>
    /// <param name="sa">A security association that we wish to perform the
    /// specified control operation on.</param>
    /// <param name="scm">The received SecurityControlMessage.</param>
    /// <param name="scm_reply">A prepared reply message (with headers and such.</param>
    /// <param name="return_path">Where to send the result.</param>
    /// <param name="low_level_sender">We expect the return_path to not be an edge or
    /// some other type of "low level" sender, so this contains the parsed out value.</param>
    protected void HandleControlDHEWithCertificateAndCAs(SecurityAssociation sa,
        SecurityControlMessage scm, SecurityControlMessage scm_reply,
        ISender return_path, ISender low_level_sender)
    {
      ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Received DHEWithCertificateAndCAs from: " + low_level_sender);
      if(sa == null) {
        sa = CreateSecurityAssociation(low_level_sender, scm.SPI, false);
      }
      byte[] cert = new byte[scm.Certificate.Length];
      scm.Certificate.CopyTo(cert, 0);
      X509Certificate rcert = new X509Certificate(cert);
      _ch.Verify(rcert);
      HashAlgorithm sha1 = new SHA1CryptoServiceProvider();
      scm.Verify((RSACryptoServiceProvider) rcert.RSA, sha1);

      X509Certificate lcert = null;
      if(SecurityPolicy.GetPolicy(scm.SPI).PreExchangedKeys) {
        lcert = _ch.DefaultCertificate;
      } else {
        lcert = _ch.FindCertificate(scm.CAs);
      }

      sa.LocalCertificate.Value = lcert;
      sa.RemoteCertificate.Value = rcert;
      sa.RDHE.Value = scm.DHE;
      sa.DHEWithCertificateAndCAsInHash.Value = MemBlock.Reference(sha1.ComputeHash((byte[]) scm.Packet));

      scm_reply.LocalCookie = scm.RemoteCookie;
      scm_reply.RemoteCookie = scm.LocalCookie;
      scm_reply.DHE = sa.LDHE;
      scm_reply.Certificate = MemBlock.Reference(lcert.RawData);
      scm_reply.Type = SecurityControlMessage.MessageType.DHEWithCertificate;
      lock(_private_key_lock) {
        scm_reply.Sign(_private_key, sha1);
      }
      sa.DHEWithCertificateHash.Value = MemBlock.Reference(sha1.ComputeHash((byte[]) scm_reply.Packet));

      ICopyable to_send = new CopyList(SecureControl, scm_reply.Packet);
      return_path.Send(to_send);
      ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Successful DHEWithCertificateAndCAs from: " + low_level_sender);
    }
Esempio n. 14
0
    /// <summary>2a) Receive a CookieResponse that contains a list of CAs, if you have
    /// a Certificate that supports one of the CAs send it along with a DHE
    /// and a list of your supported CAs in a DHEWithCertificateAndCAs.</summary>
    /// <param name="sa">A security association that we wish to perform the
    /// specified control operation on.</param>
    /// <param name="scm">The received SecurityControlMessage.</param>
    /// <param name="scm_reply">A prepared reply message (with headers and such.</param>
    /// <param name="return_path">Where to send the result.</param>
    /// <param name="low_level_sender">We expect the return_path to not be an edge or
    /// some other type of "low level" sender, so this contains the parsed out value.</param>
    protected void HandleControlCookieResponse(SecurityAssociation sa,
        SecurityControlMessage scm, SecurityControlMessage scm_reply,
        ISender return_path, ISender low_level_sender)
    {
      ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Received CookieResponse from: " + low_level_sender);
      if(sa == null) {
        throw new Exception("No valid SA!");
      }
      // This seems like unnecessary code
      scm_reply.Type = SecurityControlMessage.MessageType.CookieResponse;
      X509Certificate lcert = null;
      if(SecurityPolicy.GetPolicy(scm.SPI).PreExchangedKeys) {
        lcert = _ch.DefaultCertificate;
      } else {
        lcert = _ch.FindCertificate(scm.CAs);
      }

      sa.RemoteCookie.Value = scm.LocalCookie;
      sa.LocalCertificate.Value = lcert;
      scm_reply.Certificate = lcert.RawData;

      scm_reply.DHE = sa.LDHE;
      scm_reply.LocalCookie = scm.RemoteCookie;
      scm_reply.RemoteCookie = scm.LocalCookie;
      scm_reply.Type = SecurityControlMessage.MessageType.DHEWithCertificateAndCAs;
      if(SecurityPolicy.GetPolicy(scm.SPI).PreExchangedKeys) {
        scm_reply.CAs = new List<MemBlock>(0);
      } else {
        scm_reply.CAs = _ch.SupportedCAs;
      }
      HashAlgorithm sha1 = new SHA1CryptoServiceProvider();
      lock(_private_key_lock) {
        scm_reply.Sign(_private_key, sha1);
      }

      sa.DHEWithCertificateAndCAsOutHash.Value = sha1.ComputeHash((byte[]) scm_reply.Packet);
      ICopyable to_send = new CopyList(Security, SecureControl, scm_reply.Packet);
      _rrman.SendRequest(return_path, ReqrepManager.ReqrepType.Request,
          to_send, this, sa);
      ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Successful CookieResponse from: " + low_level_sender);
    }
Esempio n. 15
0
 /// <summary>1b) Receive a Cookie which responds with a CookieResponse</summary>
 /// <param name="sa">A security association that we wish to perform the
 /// specified control operation on.</param>
 /// <param name="calc_cookie">Cookie value for the association sender.</param>
 /// <param name="scm">The received SecurityControlMessage.</param>
 /// <param name="scm_reply">A prepared reply message (with headers and such.</param>
 /// <param name="return_path">Where to send the result.</param>
 /// <param name="low_level_sender">We expect the return_path to not be an edge or
 /// some other type of "low level" sender, so this contains the parsed out value.</param>
 protected void HandleControlCookie(SecurityAssociation sa,
     MemBlock calc_cookie, SecurityControlMessage scm,
     SecurityControlMessage scm_reply, ISender return_path,
     ISender low_level_sender)
 {
   ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Received Cookie from: " + low_level_sender);
   scm_reply.Type = SecurityControlMessage.MessageType.CookieResponse;
   scm_reply.RemoteCookie = scm.LocalCookie;
   scm_reply.LocalCookie = calc_cookie;
   if(SecurityPolicy.GetPolicy(scm.SPI).PreExchangedKeys) {
     scm_reply.CAs = new List<MemBlock>(0);
   } else {
     scm_reply.CAs = _ch.SupportedCAs;
   }
   ICopyable to_send = new CopyList(SecureControl, scm_reply.Packet);
   return_path.Send(to_send);
   ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Successful Cookie from: " + low_level_sender);
 }
Esempio n. 16
0
 /**
  * Abandon any attempts to get requests for the given ID.
  * @throw Exception if handler is not the original handler for this Request
  */
 public void StopRequest(int request_id, IReplyHandler handler) {
   RequestState rs = null;
   lock( _sync ) {
     if( !_req_state_table.TryTake(request_id, out rs)) {
       rs = null;
     }
   }
   if( rs != null ) {
      /*
       * Send an ack for this reply:
       */
      byte[] ack_payload = new byte[5];
      ack_payload[0] = (byte)ReqrepType.ReplyAck;
      NumberSerializer.WriteInt(request_id, ack_payload, 1);
      ICopyable data = new CopyList(PType.Protocol.ReqRep, MemBlock.Reference(ack_payload));
      foreach(ISender ret_path in rs.Repliers) {
        try {
          //Try to send an ack, but if we can't, oh well...
          ret_path.Send(data);
        }
        catch { }
      }
   }
 }
Esempio n. 17
0
        /**
        <summary>Creates a response from the parameter fields with RDATA being
        a memory chunk.  This is for MDNS which supports caching</summary>
        <param name="NAME">The name resolved.</param>
        <param name="TYPE">The query type.</param>
        <param name="CLASS">The network type.</param>
        <param name="CACHE_FLUSH">Flush the dns cache in the client.</param>
        <param name="TTL">How long to hold the result in the local dns cache.</param>
        <param name="RDATA">RDATA in String format.</param>
        */
        public Response(String NAME, DNSPacket.TYPES TYPE, DNSPacket.CLASSES CLASS,
                    bool CACHE_FLUSH, int TTL, String RDATA)
        {
            this.NAME = NAME;
              this.CLASS = CLASS;
              this.TTL = TTL;

              this.TYPE = TYPE;
              this.CLASS = CLASS;
              this.CACHE_FLUSH = CACHE_FLUSH;
              this.RDATA = RDATA;

              if(TYPE == DNSPacket.TYPES.A) {
            NAME_BLOB = DNSPacket.HostnameStringToMemBlock(NAME);
            RDATA_BLOB = DNSPacket.IPStringToMemBlock(RDATA);
              }
              else if(TYPE == DNSPacket.TYPES.PTR) {
            if(DNSPacket.StringIsIP(NAME)) {
              NAME_BLOB = DNSPacket.PtrStringToMemBlock(NAME);
            }
            else {
              NAME_BLOB = DNSPacket.HostnameStringToMemBlock(NAME);
            }
            RDATA_BLOB = DNSPacket.HostnameStringToMemBlock(RDATA);
              }
              else {
            throw new Exception("Invalid Query TYPE: " + TYPE + "!");
              }

              RDLENGTH = (short) RDATA_BLOB.Length;
              // 2 for TYPE + 2 for CLASS + 4 for TTL + 2 for RDLENGTH
              byte[] data = new byte[10];
              int idx = 0;
              data[idx++] = (byte) ((((int) TYPE) >> 8) & 0xFF);
              data[idx++] = (byte) (((int) TYPE) & 0xFF);

              byte cache_flush = 0x80;
              if(!CACHE_FLUSH) {
            cache_flush = 0x00;
              }

              data[idx++] = (byte) (((((int) CLASS) >> 8) & 0x7F) | cache_flush);
              data[idx++] = (byte) (((int) CLASS) & 0xFF);
              data[idx++] = (byte) ((TTL >> 24) & 0xFF);
              data[idx++] = (byte) ((TTL >> 16) & 0xFF);
              data[idx++] = (byte) ((TTL >> 8) & 0xFF);
              data[idx++] = (byte) (TTL & 0xFF);
              data[idx++] = (byte) ((RDLENGTH >> 8) & 0xFF);
              data[idx] = (byte) (RDLENGTH & 0xFF);

              _icpacket = new CopyList(NAME_BLOB, MemBlock.Reference(data), RDATA_BLOB);
        }
Esempio n. 18
0
    static void Main(string[] args)
    {
    //log.Debug( "Starting the Brunet Echo Tester" );

      String config_file = args[0];
      NetworkConfiguration network_configuration = NetworkConfiguration.Deserialize(config_file);

      int port_selection = Convert.ToInt32(args[1]); //There will be 10 different ports available for use: 0, 1, 2..
      //for example, node 0 on a machine will use port_selection # 0, node 1 on a machine will use port_selection # 1

      ///There will be multiple BruNet nodes on the same machine. The following is a list of possible ports used
      int list_size = 150;
      int [] port_list = new int[list_size];
      for(int i = 0; i < list_size; i++){
	port_list[i] = 25000 + i;
      }
	
      ///The line below is used when there is only one node per machine
      //int local_host_index = network_configuration.GetLocalHostIndex();                                                                
	
      int desired_port = port_list[port_selection];
      int local_host_index = network_configuration.GetLocalHostIndex(desired_port); 

      NodeConfiguration this_node_configuration = (NodeConfiguration)network_configuration.Nodes[local_host_index];
      TransportAddressConfiguration local_ta_configuration = (TransportAddressConfiguration)this_node_configuration.TransportAddresses[0];
      short port = local_ta_configuration.Port;

      SHA1 sha = new SHA1CryptoServiceProvider();
      String local_ta = local_ta_configuration.GetTransportAddressURI();
      //We take the local transport address plus the port number to be hashed to obtain a random AHAddress
      byte[] hashedbytes = sha.ComputeHash(Encoding.UTF8.GetBytes(local_ta + port));
      //inforce type 0
      hashedbytes[Address.MemSize - 1] &= 0xFE;
      AHAddress _local_ahaddress = new AHAddress(hashedbytes);
      Node this_node = new StructuredNode( _local_ahaddress );
      ///Node this_node = new HybridNode( new AHAddress( new BigInteger( 2*(local_host_index+1) ) ) );      

      String file_string = "./data/brunetadd" + Convert.ToString(desired_port) + ".log";
      StreamWriter sw = new StreamWriter(file_string, false);
      sw.WriteLine( "local_address " + this_node.Address.ToBigInteger().ToString() + " " + Dns.GetHostName()
		      + ":" + port); 
      sw.Close();

      if ( local_ta_configuration.Protocol == "tcp" ) {
        this_node.AddEdgeListener( new TcpEdgeListener(port) );
      } 
      else if( local_ta_configuration.Protocol == "udp" ) {
        this_node.AddEdgeListener( new UdpEdgeListener(port) );        
      }

      int remote_node_index = local_host_index-1;
      int num_remote_ta = 20; //20 nodes on the list to try to bootstrap to

      if (local_host_index!=0) {
        NodeConfiguration remote_node_configuration = (NodeConfiguration)network_configuration.Nodes[0];
        TransportAddressConfiguration remote_ta_configuration = (TransportAddressConfiguration)remote_node_configuration.TransportAddresses[0];

        String remote_ta = remote_ta_configuration.GetTransportAddressURI(); 
        this_node.RemoteTAs.Add( TransportAddressFactory.CreateInstance( remote_ta  ) );
      }
      
      while ( (remote_node_index>=0) && (num_remote_ta>=0) ) { 
        NodeConfiguration remote_node_configuration = (NodeConfiguration)network_configuration.Nodes[remote_node_index];
        TransportAddressConfiguration remote_ta_configuration = (TransportAddressConfiguration)remote_node_configuration.TransportAddresses[0];

        String remote_ta = remote_ta_configuration.GetTransportAddressURI(); 
        this_node.RemoteTAs.Add( TransportAddressFactory.CreateInstance( remote_ta  ) );

        System.Console.WriteLine("Adding {0}", remote_ta);

          remote_node_index--;
          num_remote_ta--;
        }

     /* NodeConfiguration remote_node_configuration = (NodeConfiguration)network_configuration.Nodes[remote_node_index];
      TransportAddressConfiguration remote_ta_configuration = (TransportAddressConfiguration)remote_node_configuration.TransportAddresses[0];

      String remote_ta = remote_ta_configuration.GetTransportAddressURI(); 
      this_node.RemoteTAs.Add( TransportAddressFactory.CreateInstance( remote_ta  ) );*/
 
      EchoTester echo_printer = new EchoTester();
      this_node.GetTypeSource(PType.Protocol.Echo).Subscribe(echo_printer, this_node);

      this_node.Connect();

       //Send a "hello message" to a random neighbor

      ASCIIEncoding ascii = new ASCIIEncoding();

      //Make the target addresses      
      AHAddress target  = new AHAddress( new BigInteger( 2*(remote_node_index+1) ) );

      string hello_msg = "hello, brunet";
      int byteCount = ascii.GetByteCount(hello_msg);
      byte[] bytes = new byte[byteCount + 1];
      ascii.GetBytes(hello_msg, 0, hello_msg.Length, bytes, 1);

      // update the payload
      // This is a request, so the first byte is greater than zero
      bytes[0] = (byte) 1;
      ICopyable p = new CopyList(PType.Protocol.AH,
                                 new AHHeader(0, 30, this_node.Address,
                                              target, AHHeader.Options.Greedy),
                                 PType.Protocol.Echo, MemBlock.Reference(bytes));

      ///RDP Experiment: sending the echo packet periodically
/*      int seq = 0;
      while(true){
	int start_time = System.DateTime.Now.Millisecond;
	this_node.Send(p);
	Console.WriteLine("Seq = {0}, Start Time = {1}", seq, start_time);
        System.Threading.Thread.Sleep(10000);
	seq++;
      }*/


///The following is a while-loop for the local node to Brunet-ping all other nodes in the network
      System.Threading.Thread.Sleep(60000);  ///IMPORTANT: change this parameter so we wait longer for larger network
      Random uid_generator = new Random( DateTime.Now.Millisecond + local_ta.GetHashCode() + port);
      bytes = new byte[5];
      int target_index = 0, num_pings = 10, wait_time = 10000; //the wait_time is in ms
      double ping_time;
      PingWrapper pw = new PingWrapper();    
      
      while( target_index < network_configuration.Nodes.Count ){
 
 	  if(target_index != local_host_index){///we do not ping the local machine
	      NodeConfiguration target_node_configuration = (NodeConfiguration)network_configuration.Nodes[target_index];
	      TransportAddressConfiguration target_ta_configuration = (TransportAddressConfiguration)target_node_configuration.TransportAddresses[0];
	      short target_port = target_ta_configuration.Port;
	      double ping1 = pw.Ping(target_ta_configuration.Address, 10000);
	      double ping2 = pw.Ping(target_ta_configuration.Address, 10000);
	      if(ping1 >= 0 || ping2 >= 0){ //we gather the data only when the node is ping-able
		  sha = new SHA1CryptoServiceProvider();
		  String target_ta = target_ta_configuration.GetTransportAddressURI();
		  //We take the transport address plus the port number to be hashed to obtain a random AHAddress
		  hashedbytes = sha.ComputeHash(Encoding.UTF8.GetBytes(target_ta + target_port));
		  //inforce type 0
		  hashedbytes[Address.MemSize - 1] &= 0xFE;
		  AHAddress _target_ahaddress = new AHAddress(hashedbytes);	      
		  for(int i = 0; i < num_pings; i++){
		    //ping and Brunet-ping the target node for a number of times
		    int uid = uid_generator.Next(); //this is the unique id of the packet
		    // update the payload
		    // This is a request, so the first byte is greater than zero
		    bytes[0] = (byte) 1;
		    NumberSerializer.WriteInt(uid, bytes, 1);
                    p = new CopyList(PType.Protocol.AH,
                                 new AHHeader(0, 30, this_node.Address,
                                              _target_ahaddress, AHHeader.Options.Greedy),
                                 PType.Protocol.Echo, MemBlock.Reference(bytes));

		    this_node.Send(p);
		    ping_time = pw.Ping(target_ta_configuration.Address, wait_time); //wait wait_time number of ms
		    System.Console.WriteLine("Ping time: {0}",ping_time);
		    System.Threading.Thread.Sleep(wait_time); 
		  }//end of for-loop 
		}                  

          }//end of if-loop    

    
    	  target_index++;
       }//end of while-loop

     }
Esempio n. 19
0
    /**
    <summary>Sends the data over the unicast socket.</summary>
    <param name="data">The data to send.</summary>
    */
    public virtual void Send(ICopyable data) {
      // Silly users can trigger a handful of exceptions here...
      try {
        data = new CopyList(IPHandler.MagicCookie, data);
        byte[] buffer = new byte[data.Length];
        int length = data.CopyTo(buffer, 0);

        _s.SendTo(buffer, 0, length, 0, EndPoint);
      }
      catch(System.Net.Sockets.SocketException sx) {
        throw new SendException(true, "SocketException", sx);
      }
      catch (ObjectDisposedException odx) {
        throw new SendException(false, "Socket appears to be disposed", odx);
      }
      catch (Exception e) {
        ProtocolLog.WriteIf(ProtocolLog.Exceptions, "ERROR: " + e);
        throw new SendException(true, "Socket appears to be disposed", e);
      }
    }
Esempio n. 20
0
 /**
 <summary>Sends the data over the multicast socket.</summary>
 <param name="data">The data to send.</summary>
 */
 public override void Send(ICopyable data) {
   IPAddress[] ips = LocalIPAddresses;
   if(ips == null) {
     ips = IPHandler.GetLocalIPAddresses();
   }
   // Silly users can trigger a handful of exceptions here...
   try {
     data = new CopyList(IPHandler.MagicCookie, data);
     byte[] buffer = new byte[data.Length];
     int length = data.CopyTo(buffer, 0);
     // I REALLY HATE THIS but we can't be setting this option in more than one thread!
     lock(_s) {
       foreach(IPAddress ip in ips) {
         /*
          * This can throw an exception on an invalid address, we need to skip it and move on!
          * Never showed to be an issue in Linux, but Windows does some weird things.
          */
         try {
           _s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface,
                             IPHandler.IPAddressToInt(ip));
         }
         catch {
           continue;
         }
         _s.SendTo(buffer, 0, length, 0, EndPoint);
       }
     }
   }
   catch(System.Net.Sockets.SocketException sx) {
     throw new SendException(true, "SocketException", sx);
   }
   // Can't pass the fact that the IPHandler is not running :-/
   catch (ObjectDisposedException odx) {
     throw new SendException(false, "Socket appears to be disposed", odx);
   }
   catch (Exception e) {
     ProtocolLog.WriteIf(ProtocolLog.Exceptions, "ERROR: " + e);
     throw new SendException(true, "Socket appears to be disposed", e);
   }
 }
 protected override void UpdatePacket() {
   try {
     byte[] b = new byte[4 + 4 + 4];
     int pos = 0;
     NumberSerializer.WriteInt(_spi, b, pos);
     pos += 4;
     NumberSerializer.WriteInt(_epoch, b, pos);
     pos += 4;
     NumberSerializer.WriteInt(_seqid, b, pos);
     MemBlock header = MemBlock.Reference(b);
     _icpacket = new CopyList(header, _encrypted_data);
   } catch(Exception e) {
     throw new Exception("Missing data to build packet!");
   }
   base.UpdatePacket();
 }
    ///<summary>All outgoing data filters through here.</summary>
    public void Send(ICopyable data) {
      if(!_active) {
        if(_closed == 1) {
          throw new SendException(false, "SA closed, unable to send!");
        }
        UpdateSH(null, null);
        return;
      }

      // prepare the packet
      SecurityDataMessage sdm = new SecurityDataMessage();
      sdm.SPI = _spi;
      sdm.Data = data as MemBlock;
      if(sdm.Data == null) {
        byte[] b = new byte[data.Length];
        data.CopyTo(b, 0);
        sdm.Data = MemBlock.Reference(b);
      }

      // Encrypt it!
      SecurityHandler sh = _current_sh;
      try {
        sh.SignAndEncrypt(sdm);
      } catch {
        if(sh != _current_sh) {
          _current_sh.SignAndEncrypt(sdm);
        } else {
          throw;
        }
      }

      // Prepare for sending and send over the underlying ISender!
      data = new CopyList(SecurityOverlord.Security, SecurityOverlord.SecureData, sdm.ICPacket);
      try {
        _sender.Send(data);
        _running = true;
      } catch (Exception e) {
        Close("Failed on sending");
        throw new SendException(false, "Failed on sending closing...", e);
      }
    }
Esempio n. 23
0
  /**
   * This is how you invoke a method on a remote host.
   * Results are put into the Channel.
   * 
   * If you want to have an Event based approach, listen to the EnqueueEvent
   * on the Channel you pass for the results.  That will be fired
   * immediately from the thread that gets the result.
   *
   * When a result comes back, we put and RpcResult into the Channel.
   * When you have enough responses, Close the queue (please).  The code
   * will stop sending requests after the queue is closed.  If you never close
   * the queue, this will be wasteful of resources.
   *
   * @param target the sender to use when making the RPC call
   * @param q the Channel into which the RpcResult objects will be placed.
   *            q may be null if you don't care about the response.
   * @param method the Rpc method to call
   *
   * @throw Exception if we cannot send the request for some reason.
   */
  virtual public void Invoke(ISender target, Channel q, string method,
                              params object[] args)
  {
    //build state for the RPC call
    RpcRequestState rs = new RpcRequestState();
    rs.Results = q;
    rs.RpcTarget = target;

    object[] rpc_call = new object[2];
    rpc_call[0] = method;
    if( args != null ) {
      rpc_call[1] = args;
    }
    else {
      //There are no args, which we represent as a zero length list
      rpc_call[1] = new object[0];
    }
    
    AdrCopyable req_copy = new AdrCopyable(rpc_call);
#if RPC_DEBUG
    Console.Error.WriteLine("[RpcClient: {0}] Invoking method: {1} on target: {2}",
                     _rrman.Info, method, target);
#endif
    ICopyable rrpayload = new CopyList( PType.Protocol.Rpc, req_copy ); 
    int reqid = _rrman.SendRequest(target, ReqrepManager.ReqrepType.Request,
                                   rrpayload, this, rs);
  
    //Make sure we stop this request when the queue is closed.
    if( q != null ) {
      try {
        q.CloseEvent += delegate(object qu, EventArgs eargs) {
          _rrman.StopRequest(reqid, this);
       };
      }
      catch {
        if(q.Closed) {
          _rrman.StopRequest(reqid, this);
        }
        else {
          throw;
        }
      }
    }
  }
Esempio n. 24
0
    /// <summary>This begins the SecurityAssociation exchange protocol over the
    /// specified SecurityAssociation.</summary>
    protected void StartSA(SecurityAssociation sa) {
      SecurityControlMessage scm_reply = new SecurityControlMessage();
      scm_reply.Version = Version;
      scm_reply.SPI = sa.SPI;
      scm_reply.Type = SecurityControlMessage.MessageType.Cookie;
      scm_reply.LocalCookie = CalculateCookie(sa.Sender);

      ICopyable to_send = new CopyList(Security, SecureControl, scm_reply.Packet);

      _rrman.SendRequest(sa.Sender, ReqrepManager.ReqrepType.Request,
          to_send, this, sa);
    }