public override bool Equals(object a) { if (a == null) { //If the other is null, clearly it's not equal to a non-null return(false); } if (this == a) { //Clearly we are the Equal to ourselves return(true); } if (a is byte[]) { /** * @todo * This is very questionable to just treat byte[] as MemBlock, * because the hashcodes won't be equal, but we have code * that does this. We should remove the assumption that MemBlock * can equal a byte[] */ a = MemBlock.Reference((byte[])a); } if (this.GetHashCode() != a.GetHashCode()) { //Hashcodes must be equal for the objects to be equal return(false); } else { return(this.CompareTo(a) == 0); } }
/// <summary>Parse a revocation message.</summary> public UserRevocationMessage(Certificate cacert, MemBlock data) { _data = data; int pos = 0; int length = 0; Username = AdrConverter.Deserialize(data, pos, out length) as string; pos += length; // Random number to reduce likelihood of malicious duplication of messages NumberSerializer.ReadInt(data, pos); pos += 4; // Verify that there is a date contained therein, perhaps we should verify the time new DateTime(NumberSerializer.ReadLong(data, pos)); pos += 8; Signature = new byte[data.Length - pos]; data.Slice(pos).CopyTo(Signature, 0); // hash the data SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider(); Hash = sha1.ComputeHash(data, 0, data.Length - Signature.Length); if(!cacert.PublicKey.VerifyHash(Hash, CryptoConfig.MapNameToOID("SHA1"), Signature)) { throw new Exception("Invalid UserRevocationMessage signature"); } }
/** * Shorter MemBlocks are less than longer ones. MemBlocks of identical * length are compared from first byte to last byte. The first byte * that differs is compared to get the result of the function */ public int CompareTo(object o) { if (this == o) { return(0); } MemBlock other = o as MemBlock; if (other == null) { byte[] data = o as byte[]; if (data != null) { other = MemBlock.Reference(data); } else { //Put us ahead of all other types, this might not be smart return(-1); } } int t_l = this.Length; int o_l = other.Length; if (t_l == o_l) { for (int i = 0; i < t_l; i++) { byte t_b = this._buffer[this._offset + i]; byte o_b = other._buffer[other._offset + i]; if (t_b != o_b) { //OKAY! They are different: if (t_b < o_b) { return(-1); } else { return(1); } } else { //This position is equal, go to the next } } //We must be equal return(0); } else if (t_l < o_l) { return(-1); } else { return(1); } }
public DhtGet(Node node, MemBlock key, EventHandler enqueue, EventHandler close) : base(close) { Node = node; Key = key; _enqueue = enqueue; Results = new Queue<MemBlock>(); }
//Too bad we can't use a template here, .Net generics *may* do the job public static int ReadInt(MemBlock mb, int offset) { int val = 0; for(int i = 0; i < 4; i++) { val = (val << 8) | mb[i + offset]; } return val; }
/// <summary>Adds a local signed public certificate to this CH.</summary> public bool AddSignedCertificate(X509Certificate cert) { Brunet.Util.MemBlock sn = Brunet.Util.MemBlock.Reference(cert.SerialNumber); lock (_sync) { _lc[sn] = cert; _lc_issuers.Add(sn); } return(true); }
public void HandleData(MemBlock b, ISender return_path, object state) { byte b0 = b[0]; if( b0 == 0 ) { //This is a request: MemBlock data = b.Slice(1); //Make sure node to reply with a zero return_path.Send( new CopyList( PType.Protocol.Echo, REPLY_HEADER, data) ); } }
public static float ReadFloat(MemBlock mb, int offset) { byte[] bin = new byte[4]; for (int i = 0; i < 4; i++) { bin[i] = mb[offset + i]; } return(ReadFloat(bin, 0)); }
/// <summary>Adds CA certificate to this CH.</summary> virtual public bool AddCACertificate(X509Certificate cert) { Brunet.Util.MemBlock sn = Brunet.Util.MemBlock.Reference(cert.SerialNumber); lock (_sync) { _cas[sn] = cert; _supported_cas.Add(sn); } return(true); }
public DhtPut(Node node, MemBlock key, MemBlock value, int ttl, EventHandler finished) : base(finished) { Node = node; Key = key; Value = value; Ttl = ttl; _result = null; }
public static double ReadDouble(MemBlock mb, int offset) { byte[] bin = new byte[8]; for (int i = 0; i < 8; i++) { bin[i] = mb[offset + i]; } return(ReadDouble(bin, 0)); }
override public void HandleData(MemBlock data, ISender return_path, object state) { SecurityAssociation sa = return_path as SecurityAssociation; if(sa == null) { ProtocolLog.WriteIf(ProtocolLog.Exceptions, String.Format( "Insecure sender {0} sent ptype {1}", return_path, _ptype)); return; } base.HandleData(data, return_path, state); }
/// <summary>Create a new Attribute.</summary> public Attribute(AttributeType type, MemBlock value) { Type = type; Value = value; byte[] data = new byte[4 + value.Length]; NumberSerializer.WriteUShort((ushort) type, data, 0); NumberSerializer.WriteUShort((ushort) value.Length, data, 2); value.CopyTo(data, 4); Data = MemBlock.Reference(data); }
// coded by hand for speed (profiled on mono) public static long ReadLong(MemBlock bin, int offset) { long val = 0; for (int i = 0; i < 8; i++) { val = (val << 8) | bin[i + offset]; } return(val); }
//Too bad we can't use a template here, .Net generics *may* do the job public static int ReadInt(MemBlock mb, int offset) { int val = 0; for (int i = 0; i < 4; i++) { val = (val << 8) | mb[i + offset]; } return(val); }
/** Parse the first LENGTH bytes to get the AHHeader */ public AHHeader(MemBlock mb) { Hops = NumberSerializer.ReadShort(mb, 0); Ttl = NumberSerializer.ReadShort(mb, 2); //We parse the Address objects lazily Opts = (ushort)NumberSerializer.ReadShort(mb, 2 * Address.MemSize + 4); if( mb.Length != LENGTH ) { mb = mb.Slice(0,LENGTH); } _data = mb; }
protected AHHeader(short hops, AHHeader head) { //Set a new number of hops: Hops = hops; //Copy the rest: Ttl = head.Ttl; Opts = head.Opts; _src = head._src; _dest = head._dest; _data = head._data; }
/** * 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); } }
public DirectionalAddress(MemBlock mb) { if (ClassOf(mb) != this.Class) { throw new System. ArgumentException ("This is not an AHAddress (Class 124) : ", this.ToString()); } _buffer = mb; _dir = (Direction) NumberSerializer.ReadInt(mb, 0); }
public void HandleData(MemBlock data, ISender return_path, object state) { MemBlock user_data; // Parse BroadcastSender BroadcastSender bs = BroadcastSender.Parse(Node, data, out user_data); // Present the packet to the local handler BroadcastReceiver br = new BroadcastReceiver(bs); Node.HandleData(user_data, br, null); // Broadcast to the next hop bs.Send(user_data); }
public void StringTests() { string test_ascii = "Hello simple test"; MemBlock b = MemBlock.Reference(System.Text.Encoding.UTF8.GetBytes(test_ascii)); Assert.IsTrue(b.IsAscii(0, b.Length), "IsAscii"); string test_unicode = "la\u00dfen"; b = MemBlock.Reference(System.Text.Encoding.UTF8.GetBytes(test_unicode)); Assert.IsFalse(b.IsAscii(0, b.Length), "Unicode not ascii"); }
/// <summary>Adds a local signed public certificate to this CH.</summary> virtual public bool AddSignedCertificate(X509Certificate cert) { if (_local_id != String.Empty && !Verify(cert, _local_id)) { throw new Exception("Invalid certificate: " + cert); } Brunet.Util.MemBlock sn = Brunet.Util.MemBlock.Reference(cert.SerialNumber); lock (_sync) { _lc[sn] = cert; _lc_issuers.Add(sn); } return(true); }
public ConnectionHandler(PType ptype, StructuredNode node) { _node = node; _ondemand = new OnDemandConnectionOverlord(node); _node.AddConnectionOverlord(_ondemand); _ptype = ptype; _ptype_mb = ptype.ToMemBlock(); _address_to_sender = new Dictionary<Address, ISender>(); _sender_to_address = new Dictionary<ISender, Address>(); node.GetTypeSource(_ptype).Subscribe(this, null); node.ConnectionTable.ConnectionEvent += HandleConnection; node.ConnectionTable.DisconnectionEvent += HandleDisconnection; }
public void SomeInsanityTests() { byte[] data; bool got_x; MemBlock b; System.Random r = new System.Random(); for (int i = 0; i < 100; i++) { int size = r.Next(1024); data = new byte[size]; r.NextBytes(data); int overshoot = r.Next(1, 1024); got_x = false; b = null; try { //Should throw an exception: b = MemBlock.Reference(data, 0, size + overshoot); } catch { got_x = true; } Assert.IsNull(b, "Reference failure test"); Assert.IsTrue(got_x, "Exception catch test"); overshoot = r.Next(1, 1024); got_x = false; b = MemBlock.Reference(data); try { //Should throw an exception: byte tmp = b[size + overshoot]; } catch { got_x = true; } Assert.IsTrue(got_x, "index out of range exception"); got_x = false; try { //Should throw an exception: byte tmp = b[b.Length]; } catch { got_x = true; } Assert.IsTrue(got_x, "index out of range exception"); } }
public void HandleData(MemBlock b, ISender from, object state) { MemBlock payload = null; PType t = null; try { t = PType.Parse(b, out payload); if(t.Equals(PType.Protocol.ReqRep)) { _rrm.HandleData(payload, from, state); } else if(t.Equals(PType.Protocol.Rpc)) { Rpc.HandleData(payload, from, state); } } catch(Exception x) { Console.Error.WriteLine("Packet Handling Exception: {3}\n\tType: {0}\n\t\n\tFrom: {1}\n\tData: {2}", t, from, payload.GetString(System.Text.Encoding.ASCII), x); } }
/// <summary>Uses the Dht for the bootstrap problem.</summary> /// <param name="node">The node needing remote tas.</param> /// <param name="dht">The dht for the shared overlay.</param> /// <param name="dht_proxy">A dht proxy for the shared overlay.</param> public DhtDiscovery(StructuredNode node, IDht dht, string shared_namespace, RpcDhtProxy dht_proxy) : base(node) { _dht = dht; _dht_proxy = dht_proxy; _node = node; _shared_namespace = shared_namespace; string skey = "PrivateOverlay:" + node.Realm; byte[] bkey = Encoding.UTF8.GetBytes(skey); _p2p_address = node.Address.ToMemBlock(); _private_dht_key = MemBlock.Reference(bkey); _ongoing = 0; _steady_state = 0; _dht_proxy.Register(_private_dht_key, _p2p_address, PUT_DELAY_S); }
public GroupGraph(int count, int near, int shortcuts, int random_seed, List<List<int>> dataset, int group_count) : base(count, near, shortcuts, random_seed, dataset) { if(group_count > count || group_count < 0) { throw new Exception("Invalid group count: " + group_count); } _group_members = new List<GraphNode>(); for(int i = 0; i < group_count; i++) { int index = _rand.Next(0, count); AHAddress addr = _addrs[index]; _group_members.Add(_addr_to_node[addr]); } _group_identifier = GenerateAddress().ToMemBlock(); }
/// <summary>Parses an incoming revocation and updates the revoked users /// hashtable if successful.</summary> public void HandleData(MemBlock data, ISender ret, object state) { UserRevocationMessage urm = null; try { urm = new UserRevocationMessage(_ca_cert, data); } catch(Exception e) { ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions, e.ToString()); return; } lock(_revoked_users) { if(_revoked_users.Contains(urm.Username)) { return; } _revoked_users[urm.Username] = true; } _so.VerifySAs(); }
/** * This method is used by subclasses. * @param b the packet to send a ReceivedPacket event for */ public void ReceivedPacketEvent(BU.MemBlock b) { if (1 == _is_closed) { //We should not be receiving packets on closed edges: throw new EdgeClosedException( String.Format("Trying to Receive on a Closed Edge: {0}", this)); } try { _sub.Handle(b, this); Interlocked.Exchange(ref _last_in_packet_datetime, DateTime.UtcNow.Ticks); } catch (System.NullReferenceException) { //this can happen if _sub is null //We don't record the time of this packet. We don't //want unhandled packets to keep edges open. // //This packet is going into the trash: // Console.Error.WriteLine("{0} lost packet {1}",this,b.ToBase16String()); } }
/// <summary>Create a new revocation message.</summary> public UserRevocationMessage(RSACryptoServiceProvider private_key, string username) { Username = username; int signature_length = private_key.KeySize / 8; byte[] data = null; using(MemoryStream ms = new MemoryStream()) { AdrConverter.Serialize(Username, ms); Random rand = new Random(); NumberSerializer.WriteInt(rand.Next(), ms); NumberSerializer.WriteLong(DateTime.UtcNow.Ticks, ms); data = new byte[ms.Length + signature_length]; ms.Position = 0; ms.Read(data, 0, (int) ms.Length); } SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider(); Hash = sha1.ComputeHash(data, 0, data.Length - signature_length); Signature = private_key.SignHash(Hash, CryptoConfig.MapNameToOID("SHA1")); Signature.CopyTo(data, data.Length - signature_length); _data = MemBlock.Reference(data); }
public static string ReadString(MemBlock b, int offset, out int bytelength) { int null_idx = b.IndexOf(0, offset); int raw_length = null_idx - offset; bytelength = raw_length + 1; //One for the null Encoding e; /* * Benchmarks of mono show this to be about twice as fast as just * using UTF8. That really means UTF8 could be optimized in mono */ if (b.IsAscii(offset, raw_length)) { e = Encoding.ASCII; } else { e = Encoding.UTF8; } return(b.GetString(e, offset, raw_length)); }
protected void StartQueueProcessing() { /* * Simulate packet loss */ Random r = new Random(); try { bool timedout; while (1 == _is_started) { FQEntry ent = (FQEntry)_queue.Dequeue(-1, out timedout); if (r.NextDouble() > _ploss_prob) { //Stop in this case if (ent.P == null) { return; } FunctionEdge fe = ent.Edge; BU.MemBlock data_to_send = ent.P as BU.MemBlock; if (data_to_send == null) { data_to_send = BU.MemBlock.Copy(ent.P); } try { fe.ReceivedPacketEvent(data_to_send); } catch (EdgeClosedException) { //The edge may have closed, just ignore it } } } } catch (InvalidOperationException) { // The queue has been closed } }
public MemBlock ToMemBlock() { if (_raw_data != null) { return(_raw_data); } //Else make it: if (IsValidNumeric(_type_num)) { byte[] buf = new byte[1]; buf[0] = (byte)_type_num; _raw_data = MemBlock.Reference(buf); } else { //It's a string type: int l = NumberSerializer.GetByteCount(_string_rep); byte[] buf = new byte[l]; NumberSerializer.WriteString(_string_rep, buf, 0); _raw_data = MemBlock.Reference(buf); } return(_raw_data); }
/// <summary>True if this certificate is signed by a CA whose cetificate /// we have, false otherwise.</summary> public bool Verify(X509Certificate x509, ISender sender) { Brunet.Util.MemBlock sn = Brunet.Util.MemBlock.Reference(x509.SerialNumber); lock (_sync) { if (!_cas.ContainsKey(sn)) { throw new Exception("Unsupported CA!"); } if (!x509.VerifySignature(_cas[sn].RSA)) { throw new Exception("Unable to verify certificate, bad signature!"); } } foreach (ICertificateVerification icv in _certificate_verifiers) { if (!icv.Verify(x509, sender)) { throw new Exception("Certificate not valid, reason unsure"); } } return(true); }
public void Send(ICopyable data) { /* * Assemble an AHPacket: */ if( _header == null ) { AHHeader ahh = new AHHeader(_hops, _ttl, _source, _dest, _options); _header = MemBlock.Copy(new CopyList( PType.Protocol.AH, ahh)); _header_length = _header.Length; } byte[] ah_packet; int packet_length; int packet_offset; //Try to get the shared BufferAllocator, useful when //we don't know how big the data is, which in general //is just as expensive as doing a CopyTo... BufferAllocator ba = Interlocked.Exchange<BufferAllocator>(ref _buf_alloc, null); if( ba != null ) { try { ah_packet = ba.Buffer; packet_offset = ba.Offset; int tmp_off = packet_offset; tmp_off += _header.CopyTo(ah_packet, packet_offset); tmp_off += data.CopyTo(ah_packet, tmp_off); packet_length = tmp_off - packet_offset; ba.AdvanceBuffer(packet_length); } catch(System.Exception x) { throw new SendException(false, "could not write the packet, is it too big?", x); } finally { //Put the BA back Interlocked.Exchange<BufferAllocator>(ref _buf_alloc, ba); } } else { //Oh well, someone else is using the buffer, just go ahead //and allocate new memory: packet_offset = 0; packet_length = _header_length + data.Length; ah_packet = new byte[ packet_length ]; int off_to_data = _header.CopyTo(ah_packet, 0); data.CopyTo(ah_packet, off_to_data); } MemBlock mb_packet = MemBlock.Reference(ah_packet, packet_offset, packet_length); /* * Now we announce this packet, the AHHandler will * handle routing it for us */ _n.HandleData(mb_packet, _from, this); }
public static float ReadFloat(MemBlock mb) { return(ReadFloat(mb, 0)); }
/* * Handle the data from our underlying edge */ public void HandleData(MemBlock b, ISender ret, object state) { MemBlock tmp = b.Slice(0, PType.Protocol.Pathing.Length); if(tmp.Equals(PType.Protocol.Pathing.ToMemBlock())) { _pem.HandleData(b, ret, null); return; } ReceivedPacketEvent(b); }
/** Handle incoming data on an Edge */ public void HandleData(MemBlock data, ISender retpath, object state) { MemBlock rest_of_data; PType p; if( state == null ) { try { p = PType.Parse(data, out rest_of_data); } catch(ParseException) { ProtocolLog.WriteIf(ProtocolLog.Pathing, "Invalid PType from: " + data); return; } p = PType.Parse(data, out rest_of_data); } else { //a demux has already happened: p = (PType)state; rest_of_data = data; } if( PType.Protocol.Pathing.Equals(p) ) { /* * We use a special PType to denote this transaction so * we don't confuse it with other RepRep communication */ _rrm.HandleData(rest_of_data, retpath, null); } else if( PType.Protocol.Rpc.Equals(p) ) { /* * Send this to the RpcHandler */ Rpc.HandleData(rest_of_data, retpath, null); } else { /* * This is some other data * It is either: * 1) Time to announce an already created edge. * 2) Assume this is a "default path" edge creation, to be backwards * compatible */ Edge e = null; PathEdge pe = null; try { e = (Edge)retpath; PathEdgeListener pel = null; lock( _sync ) { if( _unannounced.TryGetValue(e, out pe) ) { // _unannounced.Remove(e); pel = _pel_map[pe.LocalPath]; } } if( pe == null ) { if(! _pel_map.ContainsKey(Root) ) { ProtocolLog.WriteIf(ProtocolLog.Pathing, "No root, can't create edge"); if(e != null) { e.Close(); } return; } /* * This must be a "default path" incoming connection */ pel = _pel_map[Root]; pe = new PathEdge(this, e, Root, Root); } pel.SendPathEdgeEvent(pe); pe.Subscribe(); pe.ReceivedPacketEvent(data); } catch(Exception x) { if( pe != null ) { //This closes both edges: pe.Close(); } else if( e != null ) { ProtocolLog.WriteIf(ProtocolLog.Pathing, String.Format("Closing ({0}) due to: {1}", e, x)); e.Close(); } } } }
/** * This reads a packet from buf which came from end, with * the given ids */ protected void HandleDataPacket(int remoteid, int localid, MemBlock packet, EndPoint end, object state) { bool read_packet = true; bool is_new_edge = false; //It is threadsafe to read from Hashtable UdpEdge edge = (UdpEdge)_id_ht[localid]; if( localid == 0 ) { //This is a potentially a new incoming edge is_new_edge = true; //Check to see if it is a dup: UdpEdge e_dup = (UdpEdge)_remote_id_ht[remoteid]; if( e_dup != null ) { //Lets check to see if this is a true dup: if( e_dup.End.Equals( end ) ) { //Same id from the same endpoint, looks like a dup... is_new_edge = false; //Reuse the existing edge: edge = e_dup; } else { //This is just a coincidence. } } if( is_new_edge ) { TransportAddress rta = TransportAddressFactory.CreateInstance(this.TAType,(IPEndPoint)end); if( _ta_auth.Authorize(rta) == TAAuthorizer.Decision.Deny ) { //This is bad news... Ignore it... ///@todo perhaps we should send a control message... I don't know is_new_edge= false; read_packet = false; if(ProtocolLog.UdpEdge.Enabled) ProtocolLog.Write(ProtocolLog.UdpEdge, String.Format( "Denying: {0}", rta)); } else { //We need to assign it a local ID: lock( _id_ht ) { /* * Now we need to lock the table so that it cannot * be written to by anyone else while we work */ do { localid = _rand.Next(); //Make sure not to use negative ids if( localid < 0 ) { localid = ~localid; } } while( _id_ht.Contains(localid) || localid == 0 ); /* * We copy the endpoint because (I think) .Net * overwrites it each time. Since making new * edges is rare, this is better than allocating * a new endpoint each time */ IPEndPoint this_end = (IPEndPoint)end; IPEndPoint my_end = new IPEndPoint(this_end.Address, this_end.Port); edge = new UdpEdge(_send_handler, true, my_end, _local_ep, localid, remoteid); _id_ht[localid] = edge; _remote_id_ht[remoteid] = edge; } } } } else if ( edge == null ) { /* * This is the case where the Edge is not a new edge, * but we don't know about it. It is probably an old edge * that we have closed. We can ignore this packet */ read_packet = false; //Send a control packet SendControlPacket(end, remoteid, localid, ControlCode.EdgeClosed, state); } else if ( edge.RemoteID == 0 ) { /* This is the response to our edge creation */ edge.RemoteID = remoteid; } else if( edge.RemoteID != remoteid ) { /* * This could happen as a result of packet loss or duplication * on the first packet. We should ignore any packet that * does not have both ids matching. */ read_packet = false; //Tell the other guy to close this ignored edge SendControlPacket(end, remoteid, localid, ControlCode.EdgeClosed, state); edge = null; } if( (edge != null) && !edge.End.Equals(end) ) { //This happens when a NAT mapping changes if(ProtocolLog.UdpEdge.Enabled) ProtocolLog.Write(ProtocolLog.UdpEdge, String.Format( "Remote NAT Mapping changed on Edge: {0}\n{1} -> {2}", edge, edge.End, end)); //Actually update: TransportAddress rta = TransportAddressFactory.CreateInstance(this.TAType,(IPEndPoint)end); if( _ta_auth.Authorize(rta) != TAAuthorizer.Decision.Deny ) { IPEndPoint this_end = (IPEndPoint) end; edge.End = new IPEndPoint(this_end.Address, this_end.Port); NatDataPoint dp = new RemoteMappingChangePoint(DateTime.UtcNow, edge); Interlocked.Exchange<NatHistory>(ref _nat_hist, _nat_hist + dp); Interlocked.Exchange<IEnumerable>(ref _nat_tas, new NatTAs( _tas, _nat_hist )); //Tell the other guy: SendControlPacket(end, remoteid, localid, ControlCode.EdgeDataAnnounce, state); } else { /* * Looks like the new TA is no longer authorized. */ SendControlPacket(end, remoteid, localid, ControlCode.EdgeClosed, state); RequestClose(edge); CloseHandler(edge, null); } } if( is_new_edge ) { try { NatDataPoint dp = new NewEdgePoint(DateTime.UtcNow, edge); Interlocked.Exchange<NatHistory>(ref _nat_hist, _nat_hist + dp); Interlocked.Exchange<IEnumerable>(ref _nat_tas, new NatTAs( _tas, _nat_hist )); edge.CloseEvent += this.CloseHandler; //If we make it here, the edge wasn't closed, go ahead and process it. SendEdgeEvent(edge); // Stun support SendControlPacket(end, remoteid, localid, ControlCode.EdgeDataAnnounce, state); } catch { //Make sure this edge is closed and we are done with it. RequestClose(edge); CloseHandler(edge, null); read_packet = false; //This was a new edge, so the other node has our id as zero, send //with that localid: SendControlPacket(end, remoteid, 0, ControlCode.EdgeClosed, state); } } if( read_packet ) { //We have the edge, now tell the edge to announce the packet: try { edge.ReceivedPacketEvent(packet); } catch(EdgeClosedException) { SendControlPacket(end, remoteid, localid, ControlCode.EdgeClosed, state); //Make sure we record that this edge has been closed CloseHandler(edge, null); } } }
/** * This handles lightweight control messages that may be sent * by UDP */ protected void HandleControlPacket(int remoteid, int n_localid, MemBlock buffer, object state) { int local_id = ~n_localid; UdpEdge e = _id_ht[local_id] as UdpEdge; if(e == null) { return; } if(e.RemoteID == 0) { try { e.RemoteID = remoteid; } catch { return; } } if(e.RemoteID != remoteid) { return; } try { ControlCode code = (ControlCode)NumberSerializer.ReadInt(buffer, 0); if(ProtocolLog.UdpEdge.Enabled) ProtocolLog.Write(ProtocolLog.UdpEdge, String.Format( "Got control {1} from: {0}", e, code)); if( code == ControlCode.EdgeClosed ) { //The edge has been closed on the other side RequestClose(e); CloseHandler(e, null); } else if( code == ControlCode.EdgeDataAnnounce ) { //our NAT mapping may have changed: IDictionary info = (IDictionary)AdrConverter.Deserialize( buffer.Slice(4) ); string our_local_ta = (string)info["RemoteTA"]; //his remote is our local if( our_local_ta != null ) { //Update our list: TransportAddress new_ta = TransportAddressFactory.CreateInstance(our_local_ta); TransportAddress old_ta = e.PeerViewOfLocalTA; if( ! new_ta.Equals( old_ta ) ) { if(ProtocolLog.UdpEdge.Enabled) ProtocolLog.Write(ProtocolLog.UdpEdge, String.Format( "Local NAT Mapping changed on Edge: {0}\n{1} => {2}", e, old_ta, new_ta)); //Looks like matters have changed: this.UpdateLocalTAs(e, new_ta); /** * @todo, maybe we should ping the other edges sharing this * EndPoint, but we need to be careful not to do some O(E^2) * operation, which could easily happen if each EdgeDataAnnounce * triggered E packets to be sent */ } } } else if( code == ControlCode.Null ) { //Do nothing in this case } } catch(Exception x) { //This could happen if this is some control message we don't understand if(ProtocolLog.Exceptions.Enabled) ProtocolLog.Write(ProtocolLog.Exceptions, x.ToString()); } }
public void Test() { //8 is long enough to hold all the numbers: byte[] buffer = new byte[8]; System.Random r = new System.Random(); int tests = 100; //Here are shorts: for (int i = 0; i < tests; i++) { short val = (short)r.Next(Int16.MaxValue); WriteShort(val, buffer, 0); Assert.AreEqual(val, ReadShort(buffer, 0)); } //Ints: for (int i = 0; i < tests; i++) { int val = r.Next(); WriteInt(val, buffer, 0); Assert.AreEqual(val, ReadInt(buffer, 0)); } //Longs: for (int i = 0; i < tests; i++) { long val = r.Next(); val <<= 4; val |= r.Next(); WriteLong(val, buffer, 0); Assert.AreEqual(val, ReadLong(buffer, 0)); } //Floats: for (int i = 0; i < tests; i++) { float val = (float)r.NextDouble(); WriteFloat(val, buffer, 0); Assert.AreEqual(val, ReadFloat(buffer, 0)); } //Doubles: for (int i = 0; i < tests; i++) { double val = r.NextDouble(); WriteDouble(val, buffer, 0); Assert.AreEqual(val, ReadDouble(buffer, 0)); } //Strings: for (int i = 0; i < tests; i++) { byte[] bin = new byte[1000]; r.NextBytes(bin); //Here's a random ascii string: string s = Base32.Encode(bin); if (i % 2 == 0) { //Half the time make sure there is some unicode bit: s = s + "la\u00dfen"; } byte[] enc = Encoding.UTF8.GetBytes(s); byte[] enc_null = new byte[enc.Length + 1]; Array.Copy(enc, 0, enc_null, 0, enc.Length); enc_null[enc.Length] = 0; int l; string s2 = ReadString(enc_null, 0, out l); Assert.AreEqual(s, s2, "byte[] readstring"); Assert.AreEqual(l, enc_null.Length, "byte[] string length"); string s3 = ReadString(MemBlock.Reference(enc_null), 0, out l); Assert.AreEqual(s, s3, "byte[] readstring"); Assert.AreEqual(l, enc_null.Length, "byte[] string length"); } /* * Round tripping is great, but we still might have some * brain damage: we could be cancel out the error when reading * the data back in. */ Assert.AreEqual((short)511, ReadShort(new byte[] { 1, 255 }, 0)); Assert.AreEqual((short)511, ReadShort(new MemoryStream(new byte[] { 1, 255 }))); Assert.AreEqual((short)1535, ReadShort(new byte[] { 5, 255 }, 0)); Assert.AreEqual((short)1535, ReadShort(new MemoryStream(new byte[] { 5, 255 }))); Assert.AreEqual(43046721, ReadInt(new byte[] { 2, 144, 215, 65 }, 0)); Assert.AreEqual(43046721, ReadInt(new MemoryStream(new byte[] { 2, 144, 215, 65 }))); Assert.AreEqual(59296646043258912L, ReadLong(new byte[] { 0, 210, 169, 252, 67, 199, 208, 32 }, 0)); Assert.AreEqual(59296646043258912L, ReadLong(new MemoryStream(new byte[] { 0, 210, 169, 252, 67, 199, 208, 32 }))); }
public bool HandleReply(ReqrepManager man, ReqrepManager.ReqrepType rt, int mid, PType prot, MemBlock payload, ISender returnpath, ReqrepManager.Statistics statistics, object state) { DateTime reply_time = DateTime.UtcNow; ListDictionary res_dict = new ListDictionary(); AHSender ah_rp = returnpath as AHSender; if( ah_rp != null ) { res_dict["target"] = ah_rp.Destination.ToString(); } //Here are the number of microseconds res_dict["musec"] = (int)( 1000.0 * ((reply_time - _start_time).TotalMilliseconds) ); //Send the RPC result now; RpcManager my_rpc = System.Threading.Interlocked.Exchange(ref _rpc, null); if( my_rpc != null ) { //We have not sent any reply yet: my_rpc.SendResult(_req_state, res_dict); } return false; }
public static short ReadShort(MemBlock bin, int offset) { return((short)((bin[offset] << 8) | bin[offset + 1])); }
public static double ReadDouble(MemBlock mb) { return(ReadDouble(mb, 0)); }
public void Test() { System.Random r = new System.Random(); byte[] data; for (int i = 0; i < 100; i++) { data = new byte[r.Next(1024)]; r.NextBytes(data); int offset = r.Next(data.Length); MemBlock mb1 = new MemBlock(data, 0, data.Length); MemBlock mb1a = MemBlock.Copy(data, 0, data.Length); Assert.IsTrue(mb1.Equals(mb1a), "MemBlock.Copy"); Assert.IsTrue(mb1.Equals(data), "MemBlock == byte[]"); MemBlock mb2 = new MemBlock(data, offset, data.Length - offset); MemBlock mb2a = mb1.Slice(offset); MemBlock mb3 = new MemBlock(data, 0, offset); MemBlock mb3a = mb1.Slice(0, offset); Assert.IsTrue(mb3.Equals(mb3a), "mb3.Equals(mb3a)"); Assert.IsTrue(mb3a.Equals(mb3), "mb3a.Equals(mb3)"); Assert.IsTrue(mb3.CompareTo(mb2) + mb2.CompareTo(mb3) == 0, "CompareTo"); Assert.IsTrue(mb2.Equals(mb2a), "mb2.Equals(mb2a)"); Assert.IsTrue(mb2a.Equals(mb2), "mb2a.Equals(mb2)"); MemBlock cat = MemBlock.Concat(mb3, mb2); MemBlock cata = MemBlock.Concat(mb3a, mb2a); Assert.IsTrue(cat.Equals(cata), "Concat Equals"); Assert.IsTrue(cata.Equals(cat), "Concat a Equals"); Assert.IsTrue(mb1.Equals(cat), "Concat Equals Original"); if (offset != 0) { //These should not be equal Assert.IsFalse(mb2.Equals(mb1), "mb2 != mb1"); } int mb2a_l = mb2a.Length; byte[] tmp_data = new byte[mb2a_l]; mb2a.CopyTo(tmp_data, 0); MemBlock mb2b = new MemBlock(tmp_data, 0, tmp_data.Length); Assert.IsTrue(mb2a.Equals(mb2b), "mb2a.Equals(mb2b)"); Assert.IsTrue(mb2b.Equals(mb2a), "mb2b.Equals(mb2a)"); //Check the Hash: Assert.IsTrue(mb2b.GetHashCode() == mb2a.GetHashCode(), "GetHashCode"); //Here are some manual equality testing using the indexer bool all_equals = true; int j = 0; while (all_equals && (j < mb1.Length)) { all_equals = (mb1[j] == cat[j]); j++; } Assert.IsTrue(all_equals, "Manual equality test mb1"); all_equals = true; j = 0; while (all_equals && (j < mb2.Length)) { all_equals = (mb2[j] == mb2a[j]); j++; } Assert.IsTrue(all_equals, "Manual equality test mb2"); all_equals = true; j = 0; while (all_equals && (j < mb2.Length)) { all_equals = (mb2[j] == mb2b[j]); j++; } Assert.IsTrue(all_equals, "Manual equality test mb2b"); } }
public DhtPut(Node node, MemBlock key, MemBlock value, int ttl, EventHandler callback) { _node = node; _key = key; _value = value; _ttl = ttl; _callback = callback; _successful = false; }
public void HandleData(MemBlock data, ISender sender, object state) { BroadcastReceiver br = sender as BroadcastReceiver; _estimated_time_left = DateTime.UtcNow.AddSeconds(1); _results.Add(br); }
/** * Here we handle routing AHPackets */ public void HandleData(MemBlock data, ISender ret_path, object st) { AHState state = _state; //Read the state, it can't change after the read var header = new AHHeader(data); var payload = data.Slice(header.Length); Connection next_con; //Check to see if we can use a Leaf connection: int dest_idx = state.Leafs.IndexOf(header.Destination); if( dest_idx >= 0 ) { next_con = state.Leafs[dest_idx]; } else { var alg = state.GetRoutingAlgo(header); Pair<Connection, bool> result = alg.NextConnection(ret_path as Edge, header); if( result.Second ) { //Send a response exactly back to the node that sent to us var resp_send = new AHSender(_n, ret_path, header.Source, AHSender.DefaultTTLFor(_n.NetworkSize), AHHeader.Options.Exact); _n.HandleData( payload, resp_send, this); } next_con = result.First; } //Send it on: if( next_con != null ) { //Now we do the sending: var new_packet = new CopyList(PType.Protocol.AH, header.IncrementHops(), payload); try { next_con.Edge.Send(new_packet); } catch(EdgeException) { //Just drop the packet... } } }
public void Test() { System.Random r = new System.Random(); //Test numeric type codes: for (int i = 1; i < 32; i++) { PType p = new PType(i); MemBlock b = p.ToMemBlock(); byte[] buf = new byte[100]; r.NextBytes(buf); //Get some junk: MemBlock junk = MemBlock.Reference(buf); MemBlock b1 = MemBlock.Concat(b, junk); MemBlock rest = null; PType pp = PType.Parse(b1, out rest); byte[] buf2 = new byte[1]; buf2[0] = (byte)i; MemBlock b2 = MemBlock.Reference(buf2); Assert.AreEqual(p, pp, System.String.Format("Round trip int: {0}", i)); Assert.AreEqual(b, b2, System.String.Format("Convert to MemBlock int: {0}", i)); Assert.AreEqual(i, pp.TypeNumber, "Typenumber equality"); Assert.AreEqual(rest, junk, "rest in int PType"); } //Test string types: for (int i = 0; i < 1000; i++) { //Make a random string: // byte[] buf = new byte[r.Next(1, 100)]; r.NextBytes(buf); string s = Base32.Encode(buf); PType p1 = new PType(s); r.NextBytes(buf); //Get some junk: MemBlock b = MemBlock.Copy(buf); MemBlock combine = MemBlock.Concat(p1.ToMemBlock(), b); MemBlock b2 = null; PType p2 = PType.Parse(combine, out b2); Assert.AreEqual(p1, p2, "Round trip string: " + s); Assert.AreEqual(b, b2, "Round trip rest"); Assert.AreEqual(s, p2.ToString(), "Round trip to string"); Assert.AreEqual(s, p1.ToString(), "Round trip to string"); Assert.AreEqual(p1.TypeNumber, p2.TypeNumber, "RT: TypeNumber test"); } //Test all one byte ascii strings: for (byte b = 32; b < ASCII_UPPER_BOUND; b++) { MemBlock raw = MemBlock.Reference(new byte[] { b, 0 }); MemBlock rest; PType p1 = PType.Parse(raw, out rest); Assert.AreEqual(rest, MemBlock.Null, "Rest is null"); PType p2 = PType.Parse(raw, out rest); Assert.AreEqual(rest, MemBlock.Null, "Rest is null"); Assert.IsTrue(p1 == p2, "reference equality of single byte type"); Assert.AreEqual(p1, p2, "equality of single byte type"); Assert.AreEqual(p1, new PType(p1.ToString()), "Round trip string"); } //Test TypeNumber of string types: for (int i = 0; i < 100; i++) { byte[] buf = new byte[20]; r.NextBytes(buf); for (int j = 1; j < 4; j++) { string s = Base32.Encode(buf).Substring(0, j); PType p1 = new PType(s); byte[] buf2 = System.Text.Encoding.UTF8.GetBytes(s); int t = 0; for (int k = 0; k < buf2.Length; k++) { t = t | buf2[k]; t <<= 8; } Assert.AreEqual(t, p1.TypeNumber, System.String.Format("String type number: {0}, s={1}", t, s)); } } //Console.Error.WriteLine("Tested PType"); }
public AHHeader(short hops, short ttl, Address source, Address dest, ushort options) { //Make the header part: byte[] header = new byte[ LENGTH ]; int offset = 0; //Write hops: NumberSerializer.WriteShort(hops, header, offset); Hops = hops; offset += 2; NumberSerializer.WriteShort(ttl, header, offset); Ttl = ttl; offset += 2; _src = source; offset += source.CopyTo(header, offset); _dest = dest; offset += dest.CopyTo(header, offset); Opts = options; NumberSerializer.WriteShort((short)options, header, offset); offset += 2; _data = MemBlock.Reference(header, 0, offset); }
override protected bool HandleIncoming(MemBlock data, out MemBlock app_data) { app_data = null; int count = 0; lock(_buffer_sync) { if(data != null) { data.CopyTo(_buffer, 0); _read.Write(_buffer, data.Length); } count = _ssl.Read(_buffer, _buffer.Length); if(count > 0) { app_data = MemBlock.Copy(_buffer, 0, count); } } if(app_data != null) { // If the read was successful, Dtls has received an incoming data // message and decrypted it return true; } else { SslError error = _ssl.GetError(count); if(error == SslError.SSL_ERROR_WANT_READ) { if(SslState == SslState.OK) { UpdateState(States.Active); // In the SslCtx verify, there's no way to get the underlying Sender _ch.Verify(RemoteCertificate, Sender); } HandleWouldBlock(); } else if(error == SslError.SSL_ERROR_SSL) { var ose = new OpenSslException(); Close("Received unrecoverable error: " + ose.ToString()); throw ose; } else if(error == SslError.SSL_ERROR_ZERO_RETURN) { Close("Received clean close notification"); } else { ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions, "Receive other: " + error); } } return false; }
/** * Parse the PType starting at mb, and return all of mb <b>after</b> * the PType. */ public static PType Parse(MemBlock mb, out MemBlock rest) { PType result = null; byte fb = mb[0]; bool is_v_n = IsValidNumeric((int)fb); /** * Since ptypes must be valid UTF8 strings, * if the second byte is null, the first byte is an ascii character * and hence has a value less than ASCII_UPPER_BOUND */ bool store_in_tbl = (is_v_n || (mb[1] == 0)); if (store_in_tbl) { //This is stored in our table: result = _table[fb]; if (result != null) { if (is_v_n) { //There is no null rest = mb.Slice(1); } else { //Skip the null rest = mb.Slice(2); } return(result); } } //Otherwise we have to make it: MemBlock raw_data = null; result = new PType(); if (is_v_n) { /* * Don't set the raw_data since it is only one byte and we may not need * it */ rest = mb.Slice(1); result._type_num = (int)fb; } else { int null_pos = mb.IndexOf(0); if (null_pos > 0) { //Include the "null", but make a copy so we don't keep some data in //scope for ever raw_data = MemBlock.Copy((ICopyable)mb.Slice(0, null_pos + 1)); rest = mb.Slice(null_pos + 1); } else { //There is no terminating Null, panic!! throw new ParseException( System.String.Format("PType not null terminated: {0}", mb.ToBase16String())); } result._type_num = -2; result._raw_data = raw_data; } if (store_in_tbl) { //Make sure we don't have to create an object like this again _table[fb] = result; } return(result); }
public void Test() { System.Random r = new System.Random(); byte[] data; for(int i = 0; i < 100; i++) { data = new byte[ r.Next(1024) ]; r.NextBytes(data); int offset = r.Next(data.Length); MemBlock mb1 = new MemBlock(data, 0, data.Length); MemBlock mb1a = MemBlock.Copy(data, 0, data.Length); Assert.IsTrue(mb1.Equals(mb1a), "MemBlock.Copy"); Assert.IsTrue(mb1.Equals(data), "MemBlock == byte[]"); MemBlock mb2 = new MemBlock(data, offset, data.Length - offset); MemBlock mb2a = mb1.Slice(offset); MemBlock mb3 = new MemBlock(data, 0, offset); MemBlock mb3a = mb1.Slice(0, offset); Assert.IsTrue(mb3.Equals( mb3a ), "mb3.Equals(mb3a)"); Assert.IsTrue(mb3a.Equals( mb3 ), "mb3a.Equals(mb3)"); Assert.IsTrue(mb3.CompareTo(mb2) + mb2.CompareTo(mb3) == 0, "CompareTo"); Assert.IsTrue(mb2.Equals( mb2a ), "mb2.Equals(mb2a)"); Assert.IsTrue(mb2a.Equals( mb2 ), "mb2a.Equals(mb2)"); MemBlock cat = MemBlock.Concat(mb3, mb2); MemBlock cata = MemBlock.Concat(mb3a, mb2a); Assert.IsTrue(cat.Equals(cata), "Concat Equals"); Assert.IsTrue(cata.Equals(cat), "Concat a Equals"); Assert.IsTrue(mb1.Equals(cat), "Concat Equals Original"); if( offset != 0 ) { //These should not be equal Assert.IsFalse(mb2.Equals(mb1), "mb2 != mb1"); } int mb2a_l = mb2a.Length; byte[] tmp_data = new byte[mb2a_l]; mb2a.CopyTo(tmp_data, 0); MemBlock mb2b = new MemBlock(tmp_data, 0, tmp_data.Length); Assert.IsTrue(mb2a.Equals(mb2b), "mb2a.Equals(mb2b)"); Assert.IsTrue(mb2b.Equals(mb2a), "mb2b.Equals(mb2a)"); //Check the Hash: Assert.IsTrue(mb2b.GetHashCode() == mb2a.GetHashCode(), "GetHashCode"); //Here are some manual equality testing using the indexer bool all_equals = true; int j = 0; while( all_equals && (j < mb1.Length) ) { all_equals = (mb1[ j ] == cat[ j ]); j++; } Assert.IsTrue(all_equals, "Manual equality test mb1"); all_equals = true; j = 0; while( all_equals && (j < mb2.Length) ) { all_equals = (mb2[ j ] == mb2a[ j ]); j++; } Assert.IsTrue(all_equals, "Manual equality test mb2"); all_equals = true; j = 0; while( all_equals && (j < mb2.Length) ) { all_equals = (mb2[ j ] == mb2b[ j ]); j++; } Assert.IsTrue(all_equals, "Manual equality test mb2b"); } }