void ProcessBoostrapResponse(IMessage message) { PeerInfo pi = new PeerInfo(); pi.Id = message.peerID; pi.EndPoint = message.SourceEndPoint; UpdatePeer(pi); }
void ProcessPongResponse(IMessage message) { PeerInfo peer = buckets.GetPeer(message.SourceEndPoint); if (peer != null) { UpdatePeer(peer); } }
void ProcessBoostrapRequest(IMessage message) { var response = new Message(message.SourceEndPoint); response.CreateBoostrap(me.Id, Opcode.BoostrapResponse); Send(response, response.DestPeer); PeerInfo pi = new PeerInfo(); pi.Id = message.peerID; pi.EndPoint = message.SourceEndPoint; UpdatePeer(pi); }
public void DownloadNodes(string hiveUrl = Settings.HIVE_URL_BASE, string hiveUrlNodes = Settings.HIVE_URL_NODES) { WebClient wc = new WebClient(); //wc.Headers.Set(HttpRequestHeader.UserAgent,"EvolutionDHT v" + GetVersion() ); wc.Headers.Set(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.32"); wc.Proxy = null; // TODO: Let client specify proxy try { string list = wc.DownloadString(hiveUrl + hiveUrlNodes); // Get master list string[] hosts = list.Split('\n'); foreach (string host in hosts) { // Each line is <ip> <port> string[] parts = host.Split(':'); if (parts.Length == 2) { try { IPEndPoint node = new IPEndPoint(IPAddress.Parse(parts[0]), int.Parse(parts[1])); // Provo a fare bootstrap sui nodi scaricati per aggiungerli in lista if (node != null) { // Non mi piace aggiungere i peer cosi' PeerInfo peer = new PeerInfo(); peer.EndPoint = node; this.bootstrapPeers.Add(peer); logger.Info("Added node: " + node); } else { logger.Warn("Adding node: " + node + "Failed."); } } catch (Exception ex) { Console.WriteLine("Bad entry from hive server!" + ex.Message); } } } } catch (Exception ex) { logger.Error("Download della lista nodi fallito!" + ex.Message); } }
// Un giorno il thread transport non mandera' anche i messaggi ma sara' solo un listener ora fa entrambe le cose public void Send(Message message, PeerInfo peer = null) { logger.Info("SendMessage " + Enum.GetName(typeof(Opcode), message.FinalMessage[1]) + " (" + message.DestPeer.EndPoint.ToString() + ")"); lock (buckets) { PeerInfo bucketPeer = buckets.GetPeer(peer.Id); if (bucketPeer != null) { bucketPeer.LastSend = DateTime.Now; } } // non serve piu'? // message.Peer = Me; transport.Send(message, peer); // transport.Send(message, peer); // transport.Send(message, peer); }
public void UpdatePeer(PeerInfo newPeer) { lock (buckets) { buckets.UpdatePeer(newPeer); } //TODO: Check storage for replication // Controlla che il nuovo peer sia adatto alla replica delle "nostre" keys // (statement da verificare) foreach (string key in storages.Keys) { PeerId keyId = PeerId.CalculateId(key); if (PeerId.CalculateDistance(Me.Id, keyId) > PeerId.CalculateDistance(newPeer.Id, keyId)) { var message = new Message(newPeer); message.CreateStoreRequest(key, storages[key].Val); Send(message, newPeer); } } }
public List <PeerInfo> GetCloserPeers(PeerId id, int count) { List <PeerInfo> closerPeers = new List <PeerInfo>(); lock (buckets) { foreach (PeerInfo peer in buckets) { bool inserted = false; int i; for (i = 0; i < closerPeers.Count; i++) { PeerInfo closerPeer = closerPeers[i]; try { if (PeerId.CalculateDistance(closerPeer.Id, id) > PeerId.CalculateDistance(peer.Id, id)) { closerPeers.Insert(i, peer); inserted = true; break; } } catch (Exception) { // TODO: Gestire in modo più responsabile perché ricevo un id nullo logger.Error("Mannaggia! Mi è stato passato un id nullo :S"); } } if (!inserted) { closerPeers.Add(peer); } } } if (count < closerPeers.Count) { closerPeers.RemoveRange(count, closerPeers.Count - count); } return(closerPeers); }
private IMessage DeserializeMessage(byte[] memStream, IPEndPoint srcIPEndpoint) { if (memStream.Length == 0) { return(null); } var rcvMex = new MessageReceived(); // Scartiamo tutto il traffico non di EvolutionDHT Header hd; if (!Enum.TryParse <Header>(memStream[0].ToString(), out hd)) { return(null); } if (Header.EvolutionDHT.Equals(rcvMex.header)) { return(null); } rcvMex.opcode = (Opcode)Enum.Parse(typeof(Opcode), memStream[1].ToString()); var payloadLength = int.Parse(memStream[2].ToString() + memStream[3].ToString()); byte[] tmpKey = new byte[Settings.ID_LENGTH]; switch (rcvMex.opcode) { case Opcode.Ping: break; case Opcode.Pong: break; case Opcode.StoreRequest: Array.Copy(memStream, 4, tmpKey, 0, Settings.ID_LENGTH); rcvMex.key = HexEncoding.ToString(tmpKey); rcvMex.val = UTF8Encoding.ASCII.GetString(memStream, 4 + Settings.ID_LENGTH, payloadLength - Settings.ID_LENGTH); break; case Opcode.StoreResponse: break; case Opcode.BoostrapRequest: case Opcode.BoostrapResponse: case Opcode.FindnodeRequest: rcvMex.peerID = new PeerId(); Array.Copy(memStream, 4, rcvMex.peerID.Id, 0, Settings.ID_LENGTH); break; case Opcode.FindnodeResponse: // il 4 di questo offset potebbe diventare 16 quando implementeremo l'IPV6 int offset = 4 + 4 + Settings.ID_LENGTH; var rcvPeerCount = payloadLength / (offset); byte[] address = new byte[4]; byte[] port = new byte[4]; // Inizializzo lista peers rcvMex.peers = new List <PeerInfo>(); for (int i = 0; i < rcvPeerCount; i++) { var tmpPeer = new PeerInfo(); Array.Copy(memStream, 4 + i * offset, tmpPeer.Id.Id, 0, Settings.ID_LENGTH); Array.Copy(memStream, (4 + Settings.ID_LENGTH) + i * offset, address, 0, 4); Array.Copy(memStream, (4 + 4 + Settings.ID_LENGTH) + i * offset, port, 0, 4); // facciamo casino nella deserializzazione di ip e porta presumibilmente leggiamo shiftato di 2 byte tmpPeer.EndPoint = new IPEndPoint(new IPAddress(address), BitConverter.ToInt32(port, 0)); rcvMex.peers.Add(tmpPeer); } break; case Opcode.FindvalueRequest: Array.Copy(memStream, 4, tmpKey, 0, Settings.ID_LENGTH); rcvMex.key = HexEncoding.ToString(tmpKey); break; case Opcode.FindvalueResponse: Array.Copy(memStream, 4, tmpKey, 0, Settings.ID_LENGTH); rcvMex.key = HexEncoding.ToString(tmpKey); rcvMex.val = UTF8Encoding.ASCII.GetString(memStream, 4 + Settings.ID_LENGTH, payloadLength - Settings.ID_LENGTH); break; case Opcode.GODValue: // aggiungere format del pc al destPeer :P break; default: break; } rcvMex.SourceEndPoint = srcIPEndpoint; return(rcvMex); }
// Peer non serve piu' perche' lo mettiamo nella classe message il destinatario public void Send(Message message, PeerInfo peer = null) { udp.Send(message.FinalMessage, message.FinalMessage.Length, message.DestPeer.EndPoint); }
public bool Equals(PeerInfo peer) { return(this.id == peer.id || this.EndPoint == peer.EndPoint); }
public void Update(PeerInfo peer) { endpoint = peer.endpoint; rtt = peer.rtt; lastSeen = DateTime.Now; }
// Ma....dobbiamo inviare tutto un peerInfo nel pacchetto? // O ci basta sapere il source endpoint quando lo riceviamo? // Non ci servirebbe anche l'id del peer che mi ha inviato il messaggio?! public Message(IPEndPoint ipEndPoint) { destPeer = new PeerInfo(); destPeer.EndPoint = ipEndPoint; }
public Message(PeerInfo dPeer) { destPeer = dPeer; }