private void ReceiveAudio(AudioPacket packet, DhtClient client) { if (!RemoteVoices.ContainsKey(client.UserID)) { RemoteVoices[client.UserID] = new RemoteVoice(); } RemoteVoice user = RemoteVoices[client.UserID]; if (!user.Streams.ContainsKey(client.RoutingID)) { user.Streams[client.RoutingID] = new PlayAudio(this, packet.FrameSize, user); Players.SafeAdd(user.Streams[client.RoutingID]); } PlayAudio stream = user.Streams[client.RoutingID]; // reset if user changed quality setting if (stream.FrameSize != packet.FrameSize) { stream.Dispose(); user.Streams[client.RoutingID] = new PlayAudio(this, packet.FrameSize, user); Players.SafeAdd(user.Streams[client.RoutingID]); stream = user.Streams[client.RoutingID]; } StartAudioThread(false); stream.Receive_AudioData(packet.Audio); UpdateVolume(); }
void Receive_Notify(DhtClient client, LocationNotify notify) { if (notify.SignedLocation != null) { Store_Local(new DataReq(null, client.UserID, ServiceID, 0, notify.SignedLocation)); } ClientInfo info; if (!Clients.SafeTryGetValue(client.RoutingID, out info)) { return; } if (notify.GoingOffline) { Clients.SafeRemove(client.RoutingID); SignalUpdate(info, false); return; } info.LastSeen = Core.TimeNow; info.PingTimeout = notify.Timeout; info.NextPing = Core.TimeNow.AddSeconds(notify.Timeout); }
public void DownloadLink(string text) { FileLink link = FileLink.Decode(text, Core); SharedFile file = new SharedFile(Core.Network.Local.ClientID); file.Name = link.FileName; if (!Utilities.MemCompare(link.PublicOpID, Core.User.Settings.PublicOpID)) { throw new Exception("File Link is not for this Op"); } file.Size = link.Size; file.Hash = link.Hash; file.FileKey = link.Key; file.FileID = OpTransfer.GetFileID(ServiceID, file.Hash, file.Size); if (link.Sources != null) { for (int i = 0; i < link.Sources.Length; i += 10) { file.Sources.Add(DhtClient.FromBytes(link.Sources, i)); } } DownloadFile(file); }
private void ReceivePublicDetails(RudpSession session, ShareCollection file) { ShareCollection collection; if (!Collections.SafeTryGetValue(session.UserID, out collection)) { return; } collection.Key = file.Key; collection.Size = file.Size; collection.Hash = file.Hash; foreach (DhtClient done in collection.ToRequest.Where(t => t.ClientID == session.ClientID).ToArray()) { collection.ToRequest.Remove(done); } FileDetails details = new FileDetails(ServiceID, DataTypePublic, file.Hash, file.Size, null); object[] args = new object[] { collection, (object)session.ClientID }; DhtClient client = new DhtClient(session.UserID, session.ClientID); OpTransfer transfer = Core.Transfers.StartDownload(client.UserID, details, GetPublicPath(collection), new EndDownloadHandler(CollectionDownloadFinished), args); transfer.AddPeer(client); transfer.DoSearch = false; collection.Status = "Starting List Download"; }
public string GetFileLink(ulong user, SharedFile file) { byte[] sources = null; // if local shared file, get the sources we know of if (user == Core.UserID && file.ClientID == Core.Network.Local.ClientID) { foreach (DhtClient client in file.Sources) { sources = (sources == null) ? client.ToBytes() : Utilities.CombineArrays(sources, client.ToBytes()); } } // else getting link from remote share, so add it's address as a location else { sources = new DhtClient(user, file.ClientID).ToBytes(); } FileLink link = new FileLink() { OpName = Core.User.Settings.Operation, FileName = file.Name, PublicOpID = Core.User.Settings.PublicOpID, Size = file.Size, Hash = file.Hash, Key = file.FileKey, Sources = sources }; return(link.Encode(Core)); }
private TcpRelayService(BinaryID networkID, int servicePort, DhtClient dhtClient) { _trackerManager = new TrackerManager(networkID, servicePort, dhtClient, BIT_CHAT_TRACKER_UPDATE_INTERVAL); //start keep alive timer _tcpRelayConnectionKeepAliveTimer = new Timer(RelayConnectionKeepAliveTimerCallback, null, TCP_RELAY_KEEP_ALIVE_INTERVAL, Timeout.Infinite); }
public void SendReliable(DhtClient client, uint service, int type, G2Packet packet, bool expedite) { if (!Clients.ContainsKey(client.RoutingID)) { return; } RudpPacket comm = CreateRudpPacket(client, service, type, packet, true); LightClient target = Clients[client.RoutingID]; if (expedite) { target.NextTry = Core.TimeNow; target.Packets.AddFirst(new Tuple <uint, RudpPacket>(service, comm)); target.TrySend(Network); return; } Active[client.RoutingID] = target; target.Packets.AddLast(new Tuple <uint, RudpPacket>(service, comm)); while (target.Packets.Count > 30) { //crit - log to console? Debug.Assert(false); target.Packets.RemoveFirst(); } target.TrySend(Network); }
public bool Connect(DhtClient client) { if (client.UserID == Network.Local.UserID && client.ClientID == Network.Local.ClientID) { return(false); } // sessionmap and socketmap both need to have the same # of entries // if a session is fin or closed, we need to wait for fins to complete before re-assigning entry if (SessionMap.ContainsKey(client.RoutingID)) { return(SessionMap[client.RoutingID].Status != SessionStatus.Closed); } RudpSession session = new RudpSession(this, client.UserID, client.ClientID, false); SessionMap[client.RoutingID] = session; if (Network.LightComm.Clients.ContainsKey(client.RoutingID)) { foreach (RudpAddress address in Network.LightComm.Clients[client.RoutingID].Addresses) { session.Comm.AddAddress(address); } } session.Connect(); return(true); // indicates that we will eventually notify caller with close, so caller can clean up }
public void Send_CrawlRequest(DhtAddress address, DhtClient target) { CrawlRequest request = new CrawlRequest(); request.Target = target; SendPacket(address, request); }
public TrackerManager(BinaryID networkID, int servicePort, DhtClient dhtClient, int customUpdateInterval, bool lookupOnly = false) { _networkID = networkID; _servicePort = servicePort; _dhtClient = dhtClient; _customUpdateInterval = customUpdateInterval; _lookupOnly = lookupOnly; }
public TcpConnect GetProxy(DhtClient client) { if (client == null) { return(null); } return(GetProxy(client.UserID, client.ClientID)); }
public void Update(DhtClient client, DhtAddress address) { // clients can have different userids than their address (proxied) if (!Clients.ContainsKey(client.RoutingID)) { Clients[client.RoutingID] = new LightClient(client); } Clients[client.RoutingID].AddAddress(Core, address, false); }
public string GetNameAndLocation(DhtClient client) { string text = Core.GetName(client.UserID); // only show user's location if more than one are active if (Core.Locations.ActiveClientCount(client.UserID) > 1) { text += " @" + Core.Locations.GetLocationName(client.UserID, client.ClientID); } return(text); }
public void Send_StoreReq(DhtAddress address, DhtClient localProxy, DataReq publish) { if (address == null) { return; } StoreReq store = new StoreReq(); store.Source = Network.GetLocalSource(); store.Key = publish.Target; store.Service = publish.Service; store.DataType = publish.DataType; store.Data = publish.Data; int sentBytes = 0; TcpConnect direct = Network.TcpControl.GetProxy(address); if (direct != null) { sentBytes = direct.SendPacket(store); } else if (address.TunnelClient != null) { sentBytes = Network.SendTunnelPacket(address, store); } // if blocked send tcp with to tag else if (Core.Firewall == FirewallType.Blocked) { store.ToAddress = address; TcpConnect proxy = Network.TcpControl.GetProxy(localProxy); if (proxy != null) { sentBytes = proxy.SendPacket(store); } else { sentBytes = Network.TcpControl.SendRandomProxy(store); } } else { sentBytes = Network.UdpControl.SendTo(address, store); } Core.ServiceBandwidth[store.Service].OutPerSec += sentBytes; }
void Comm_ReceiveData(DhtClient client, byte[] data) { G2Header root = new G2Header(data); if (G2Protocol.ReadPacket(root)) { switch (root.Name) { case VoicePacket.Audio: ReceiveAudio(AudioPacket.Decode(root), client); break; } } }
private OpTransfer StartTransfer(DhtClient client, SharedFile file) { FileDetails details = new FileDetails(ServiceID, DataTypeShare, file.Hash, file.Size, null); object[] args = new object[] { file }; OpTransfer transfer = Core.Transfers.StartDownload(client.UserID, details, GetFilePath(file), new EndDownloadHandler(FileDownloadFinished), args); transfer.AddPeer(client); file.TransferStatus = "Starting download from " + Core.GetName(client.UserID); return(transfer); }
public AcceptFileForm(OpCore core, DhtClient client, SharedFile share) { InitializeComponent(); Core = core; Sharing = core.GetService(ServiceIDs.Share) as ShareService; TheFile = share; Source = client; DescriptionLabel.Text = core.GetName(client.UserID) + " wants to send you a file"; NameLabel.Text = TheFile.Name; SizeLabel.Text = Utilities.ByteSizetoDecString(TheFile.Size); }
public AcceptFileForm(OpCore core, DhtClient client, SharedFile share) { InitializeComponent(); Core = core; Sharing = core.GetService(ServiceIDs.Share) as ShareService; TheFile = share; Source = client; DescriptionLabel.Text = core.GetName(client.UserID) + " wants to send you a file"; NameLabel.Text = TheFile.Name; SizeLabel.Text = Utilities.ByteSizetoDecString(TheFile.Size); }
void Session_Update(RudpSession session) { DhtClient client = new DhtClient(session.UserID, session.ClientID); if (session.Status == SessionStatus.Active) { ShareCollection collection; if (Collections.SafeTryGetValue(session.UserID, out collection)) { if (collection.ToRequest.Any(t => t.ClientID == session.ClientID)) { SendPublicRequest(session, collection); } } } }
/*public void SendUnreliable(RudpAddress address, uint service, int type, G2Packet packet) * { * // insecure, rudp provides this same method which is more secure, if a rudp connection is already established * * RudpPacket wrap = CreateRudpPacket(address.Address, service, type, packet, false); * * int sentBytes = LightClient.SendtoAddress(Core.Network, address, wrap); * * Core.ServiceBandwidth[service].OutPerSec += sentBytes; * }*/ public void ReceivePacket(G2ReceivedPacket raw, RudpPacket packet) { DhtClient client = new DhtClient(packet.SenderID, packet.SenderClient); if (!Clients.ContainsKey(client.RoutingID)) { Clients[client.RoutingID] = new LightClient(client); } LightClient light = Clients[client.RoutingID]; light.LastSeen = Core.TimeNow; // either direct, or node's proxy light.AddAddress(Core, new RudpAddress(raw.Source), true); if (raw.ReceivedTcp) // add this second so sending ack through tcp proxy is perferred { light.AddAddress(Core, new RudpAddress(raw.Source, raw.Tcp), true); } if (packet.PacketType == RudpPacketType.LightAck) { ReceiveAck(raw, light, packet); } else if (packet.PacketType == RudpPacketType.Light) { RudpLight info = new RudpLight(packet.Payload); if (Core.ServiceBandwidth.ContainsKey(info.Service)) { Core.ServiceBandwidth[info.Service].InPerSec += raw.Root.Data.Length; } if (Data.Contains(info.Service, info.Type)) { Data[info.Service, info.Type].Invoke(client, info.Data); } if (packet.Sequence == 1) // reliable packet { SendAck(light, packet, info.Service); } } }
void Receive_Ping(DhtClient client, LocationPing ping) { if (Core.User.Settings.Invisible) { return; } LocationNotify notify = new LocationNotify(); RecentPings.AddFirst(Core.TimeNow); while (RecentPings.Count > 30) { RecentPings.RemoveLast(); } // we want a target of 20 pings per minute ( 1 every 3 seconds) // pings per minute = RecentPings.count / (Core.TimeNow - RecentPings.Last).ToMinutes() float pingsPerMinute = (float)RecentPings.Count / (float)(Core.TimeNow - RecentPings.Last.Value).Minutes; notify.Timeout = (int)(60.0 * pingsPerMinute / 20.0); // 20 is target rate, so if we have 40ppm, multiplier is 2, timeout 120seconds notify.Timeout = Math.Max(60, notify.Timeout); // use 60 as lowest timeout CurrentTimeout = notify.Timeout; if (ping.RemoteVersion < LocalClient.Data.Version) { notify.SignedLocation = LocalClient.SignedData; } if (PendingNotifications.Contains(client)) { PendingNotifications.Remove(client); } //put node on interested list NotifyUsers[client] = Core.TimeNow.AddSeconds(notify.Timeout + 15); // *** small security concern, notifies are not signed so they could be forged // signing vs unsigning is 144 vs 7 bytes, the bandwidth benefits outweigh forging // someone's online status at the moment // byte[] unsigned = notify.Encode(Network.Protocol); // byte[] signed = SignedData.Encode(Network.Protocol, Core.User.Settings.KeyPair, notify); Network.LightComm.SendReliable(client, ServiceID, 0, notify); }
void LightComm_ReceiveData(DhtClient client, byte[] data) { G2Header root = new G2Header(data); if (G2Protocol.ReadPacket(root)) { if (root.Name == LocationPacket.Ping) { Receive_Ping(client, LocationPing.Decode(root)); } if (root.Name == LocationPacket.Notify) { Receive_Notify(client, LocationNotify.Decode(root)); } } }
public DhtNetwork(OpCore core, bool lookup) { Core = core; IsLookup = lookup; Cache = new OpCache(this); // lookup config loads cache entries if (IsLookup) { Core.Context.LookupConfig.Load(this); Lookup = Core.Context.LookupConfig; } Local = new DhtClient(); Local.UserID = IsLookup ? Lookup.Ports.UserID : Utilities.KeytoID(Core.User.Settings.KeyPublic); Local.ClientID = (ushort)Core.RndGen.Next(1, ushort.MaxValue); OpID = Utilities.KeytoID(IsLookup ? LookupKey : Core.User.Settings.OpKey); OpCrypt = new RijndaelManaged(); // load encryption if (IsLookup) { OpCrypt.Key = LookupKey; } else { OpCrypt.Key = Core.User.Settings.OpKey; } LocalAugmentedKey = GetAugmentedKey(Local.UserID); Protocol = new G2Protocol(); TcpControl = new TcpHandler(this); UdpControl = new UdpHandler(this); LanControl = new LanHandler(this); RudpControl = new RudpHandler(this); LightComm = new LightCommHandler(this); UPnPControl = new UPnPHandler(this); Routing = new DhtRouting(this); Store = new DhtStore(this); Searches = new DhtSearchControl(this); }
RudpPacket CreateRudpPacket(DhtClient client, uint service, int type, G2Packet packet, bool reliable) { RudpPacket comm = new RudpPacket(); comm.SenderID = Network.Local.UserID; comm.SenderClient = Network.Local.ClientID; comm.TargetID = client.UserID; comm.TargetClient = client.ClientID; comm.PacketType = RudpPacketType.Light; comm.Payload = RudpLight.Encode(service, type, packet.Encode(Network.Protocol)); if (reliable) { comm.PeerID = (ushort)Core.RndGen.Next(ushort.MaxValue); // used to ack comm.Sequence = 1; } return(comm); }
void Search_FoundLocation(byte[] data, object arg) { SharedFile file = arg as SharedFile; if (file.Completed) { return; } OpTransfer transfer = null; // add locations to running transfer LocationData loc = LocationData.Decode(data); DhtClient client = new DhtClient(loc.UserID, loc.Source.ClientID); if (transfer == null) { transfer = StartTransfer(client, file); } Core.Network.LightComm.Update(loc); transfer.AddPeer(client); }
public void Update(LocationData location) { DhtClient client = new DhtClient(location.Source); if (!Clients.ContainsKey(client.RoutingID)) { Clients[client.RoutingID] = new LightClient(client); } LightClient light = Clients[client.RoutingID]; light.AddAddress(Core, new DhtAddress(location.IP, location.Source), false); foreach (DhtAddress address in location.Proxies) { light.AddAddress(Core, address, false); } foreach (DhtAddress server in location.TunnelServers) { light.AddAddress(Core, new DhtContact(location.Source, location.IP, location.TunnelClient, server), false); } }
void Search_FoundRoom(byte[] data, object arg) { ChatRoom room = arg as ChatRoom; if (!room.Active) { return; } // add locations to running transfer LocationData loc = LocationData.Decode(data); DhtClient client = new DhtClient(loc.UserID, loc.Source.ClientID); Core.Network.LightComm.Update(loc); if (!room.Members.SafeContains(client.UserID)) { room.AddMember(client.UserID); Core.Locations.Research(client.UserID); } // connect to new members ConnectRoom(room); }
private void ReceiveAudio(AudioPacket packet, DhtClient client) { if (!RemoteVoices.ContainsKey(client.UserID)) RemoteVoices[client.UserID] = new RemoteVoice(); RemoteVoice user = RemoteVoices[client.UserID]; if (!user.Streams.ContainsKey(client.RoutingID)) { user.Streams[client.RoutingID] = new PlayAudio(this, packet.FrameSize, user); Players.SafeAdd(user.Streams[client.RoutingID]); } PlayAudio stream = user.Streams[client.RoutingID]; // reset if user changed quality setting if (stream.FrameSize != packet.FrameSize) { stream.Dispose(); user.Streams[client.RoutingID] = new PlayAudio(this, packet.FrameSize, user); Players.SafeAdd(user.Streams[client.RoutingID]); stream = user.Streams[client.RoutingID]; } StartAudioThread(false); stream.Receive_AudioData(packet.Audio); UpdateVolume(); }
public string GetFileLink(ulong user, SharedFile file) { byte[] sources = null; // if local shared file, get the sources we know of if (user == Core.UserID && file.ClientID == Core.Network.Local.ClientID) { foreach (DhtClient client in file.Sources) sources = (sources == null) ? client.ToBytes() : Utilities.CombineArrays(sources, client.ToBytes()); } // else getting link from remote share, so add it's address as a location else sources = new DhtClient(user, file.ClientID).ToBytes(); FileLink link = new FileLink() { OpName = Core.User.Settings.Operation, FileName = file.Name, PublicOpID = Core.User.Settings.PublicOpID, Size = file.Size, Hash = file.Hash, Key = file.FileKey, Sources = sources }; return link.Encode(Core); }
void Comm_ReceiveData(DhtClient client, byte[] data) { G2Header root = new G2Header(data); if (G2Protocol.ReadPacket(root)) { switch (root.Name) { case VoicePacket.Audio: ReceiveAudio(AudioPacket.Decode(root), client); break; } } }
private static void RunSpider() { var dhtSection = ConfigurationManager.Default.GetSection("DhtConfig"); var dhtConfig = new DhtConfig() { NodeQueueMaxSize = dhtSection.GetInt("NodeQueueMaxSize", 10240), Port = (ushort)dhtSection.GetInt("Port"), ProcessResponseThreadNum = dhtSection.GetInt("ProcessResponseThreadNum", 1), ProcessRequestThreadNum = dhtSection.GetInt("ProcessRequestThreadNum", 1), SendQueueMaxSize = dhtSection.GetInt("SendQueueMaxSize", 20480), SendRateLimit = dhtSection.GetInt("SendRateLimit", 150), ReceiveRateLimit = dhtSection.GetInt("ReceiveRateLimit", 150), ReceiveQueueMaxSize = dhtSection.GetInt("ReceiveQueueMaxSize", 20480), RequestQueueMaxSize = dhtSection.GetInt("RequestQueueMaxSize", 20480), ResponseQueueMaxSize = dhtSection.GetInt("ResponseQueueMaxSize", 20480), KTableSize = dhtSection.GetInt("KTableSize", 1024) }; var dhtClient = new DhtClient(dhtConfig); dhtClient.OnFindPeer += DhtClient_OnFindPeer; dhtClient.OnReceiveInfoHash += DhtClient_OnReceiveInfoHash; dhtClient.OnAnnouncePeer += DhtClient_OnAnnouncePeer; dhtClient.Run(); Task.Run(async() => { while (true) { watchLog.Info($"收到消息数:{dhtClient.ReceviceMessageCount},收到请求消息数:{dhtClient.RequestMessageCount},收到回复消息数:{dhtClient.ResponseMessageCount},发送消息数:{dhtClient.SendMessageCount},回复消息数:{dhtClient.ReplyMessageCount},待查找节点数:{dhtClient.FindNodeCount},待记录InfoHash数:{InfoHashQueue.Count},待下载InfoHash数:{DownLoadQueue.Count},堆积的infoHash数:{InfoStore.Count},下载线程数:{DownTaskList.Count}"); await Task.Delay(60 * 1000); } }); var reTryDown = ConfigurationManager.Default.GetBool("ReTryDownHash"); if (reTryDown) { Task.Factory.StartNew(() => { while (true) { var infoHashFiles = Directory.GetFiles(InfoPath, "*.retry"); foreach (var hashFile in infoHashFiles) { var allDown = true; using (var stream = File.OpenRead(hashFile)) { using (var reader = new StreamReader(stream)) { while (reader.Peek() > 0) { var line = reader.ReadLine(); if (line.IsBlank()) { break; } if (line.IndexOf(':') > 0) { line = line.Substring(0, 40); } if (DownlaodedSet.Contains(line)) { continue; } var hashBytes = line.HexStringToByteArray(); while (dhtClient.SendMessageCount >= dhtConfig.SendQueueMaxSize) { Thread.Sleep(2000); } dhtClient.GetPeers(hashBytes); allDown = false; } } } if (allDown) { File.Delete(hashFile); } } log.Info("LOOP COMPLETE"); Thread.Sleep(TimeSpan.FromMinutes(15)); } }, TaskCreationOptions.LongRunning); } Console.CancelKeyPress += (sender, e) => { dhtClient.ShutDown(); e.Cancel = true; }; }
public DhtNetwork(OpCore core, bool lookup) { Core = core; IsLookup = lookup; Cache = new OpCache(this); // lookup config loads cache entries if (IsLookup) { Core.Context.LookupConfig.Load(this); Lookup = Core.Context.LookupConfig; } Local = new DhtClient(); Local.UserID = IsLookup ? Lookup.Ports.UserID : Utilities.KeytoID(Core.User.Settings.KeyPublic); Local.ClientID = (ushort)Core.RndGen.Next(1, ushort.MaxValue); OpID = Utilities.KeytoID(IsLookup ? LookupKey : Core.User.Settings.OpKey); OpCrypt = new RijndaelManaged(); // load encryption if (IsLookup) OpCrypt.Key = LookupKey; else OpCrypt.Key = Core.User.Settings.OpKey; LocalAugmentedKey = GetAugmentedKey(Local.UserID); Protocol = new G2Protocol(); TcpControl = new TcpHandler(this); UdpControl = new UdpHandler(this); LanControl = new LanHandler(this); RudpControl = new RudpHandler(this); LightComm = new LightCommHandler(this); UPnPControl = new UPnPHandler(this); Routing = new DhtRouting(this); Store = new DhtStore(this); Searches = new DhtSearchControl(this); }
public void Send_CrawlRequest(DhtAddress address, DhtClient target) { CrawlRequest request = new CrawlRequest(); request.Target = target; SendPacket(address, request); }
void Search_FoundLocation(byte[] data, object arg) { SharedFile file = arg as SharedFile; if (file.Completed) return; OpTransfer transfer = null; // add locations to running transfer LocationData loc = LocationData.Decode(data); DhtClient client = new DhtClient(loc.UserID, loc.Source.ClientID); if (transfer == null) transfer = StartTransfer(client, file); Core.Network.LightComm.Update(loc); transfer.AddPeer(client); }
public RudpAddress(DhtAddress address, TcpConnect proxy) { Address = address; LocalProxy = new DhtClient(proxy); }
public bool Connect(DhtClient client) { if (client.UserID == Network.Local.UserID && client.ClientID == Network.Local.ClientID) return false; // sessionmap and socketmap both need to have the same # of entries // if a session is fin or closed, we need to wait for fins to complete before re-assigning entry if(SessionMap.ContainsKey(client.RoutingID)) return SessionMap[client.RoutingID].Status != SessionStatus.Closed; RudpSession session = new RudpSession(this, client.UserID, client.ClientID, false); SessionMap[client.RoutingID] = session; if (Network.LightComm.Clients.ContainsKey(client.RoutingID)) foreach (RudpAddress address in Network.LightComm.Clients[client.RoutingID].Addresses) session.Comm.AddAddress(address); session.Connect(); return true; // indicates that we will eventually notify caller with close, so caller can clean up }
public RudpSession GetActiveSession(DhtClient client) { return(GetActiveSession(client.UserID, client.ClientID)); }
public static TcpRelayService StartTcpRelay(BinaryID networkID, Connection connection, int servicePort, DhtClient dhtClient, Uri[] tracketURIs) { TcpRelayService relay; lock (_relays) { if (_relays.ContainsKey(networkID)) { relay = _relays[networkID]; } else { relay = new TcpRelayService(networkID, servicePort, dhtClient); _relays.Add(networkID, relay); } lock (relay._relayConnections) { relay._relayConnections.Add(connection.RemotePeerID, connection); } } relay._trackerManager.AddTracker(tracketURIs); relay._trackerManager.StartTracking(); return(relay); }
internal void AcceptRequest(DhtClient client, SharedFile file) { if (Core.InvokeRequired) { Core.RunInCoreAsync(() => AcceptRequest(client, file)); return; } file.Ignore = false; StartTransfer(client, file); ResearchFile(file); SaveHeaders(); }
private OpTransfer StartTransfer(DhtClient client, SharedFile file) { FileDetails details = new FileDetails(ServiceID, DataTypeShare, file.Hash, file.Size, null); object[] args = new object[] { file }; OpTransfer transfer = Core.Transfers.StartDownload(client.UserID, details, args, new EndDownloadHandler(FileDownloadFinished)); transfer.AddPeer(client); file.TransferStatus = "Starting download from " + Core.GetName(client.UserID); return transfer; }
void Session_Update(RudpSession session) { DhtClient client = new DhtClient(session.UserID, session.ClientID); if (session.Status == SessionStatus.Active) { Local.Files.LockReading(() => { foreach (SharedFile file in Local.Files.Where(s => s.ToRequest.Any(c => c.UserID == session.UserID && c.ClientID == session.ClientID))) SendFileRequest(session, file); }); ShareCollection collection; if (Collections.SafeTryGetValue(session.UserID, out collection)) if (collection.ToRequest.Any(t => t.ClientID == session.ClientID)) SendPublicRequest(session, collection); } }
private void ReceivePublicDetails(RudpSession session, ShareCollection file) { ShareCollection collection; if (!Collections.SafeTryGetValue(session.UserID, out collection)) return; collection.Key = file.Key; collection.Size = file.Size; collection.Hash = file.Hash; foreach (DhtClient done in collection.ToRequest.Where(t => t.ClientID == session.ClientID).ToArray()) collection.ToRequest.Remove(done); FileDetails details = new FileDetails(ServiceID, DataTypePublic, file.Hash, file.Size, null); object[] args = new object[] { collection, (object) session.ClientID }; DhtClient client = new DhtClient(session.UserID, session.ClientID); OpTransfer transfer = Core.Transfers.StartDownload(client.UserID, details, args, new EndDownloadHandler(CollectionDownloadFinished)); transfer.AddPeer(client); transfer.DoSearch = false; collection.Status = "Starting List Download"; }
public void Send_StoreReq(DhtAddress address, DhtClient localProxy, DataReq publish) { if (address == null) return; StoreReq store = new StoreReq(); store.Source = Network.GetLocalSource(); store.Key = publish.Target; store.Service = publish.Service; store.DataType = publish.DataType; store.Data = publish.Data; int sentBytes = 0; TcpConnect direct = Network.TcpControl.GetProxy(address); if (direct != null) sentBytes = direct.SendPacket(store); else if (address.TunnelClient != null) sentBytes = Network.SendTunnelPacket(address, store); // if blocked send tcp with to tag else if (Core.Firewall == FirewallType.Blocked) { store.ToAddress = address; TcpConnect proxy = Network.TcpControl.GetProxy(localProxy); if (proxy != null) sentBytes = proxy.SendPacket(store); else sentBytes = Network.TcpControl.SendRandomProxy(store); } else sentBytes = Network.UdpControl.SendTo(address, store); Core.ServiceBandwidth[store.Service].OutPerSec += sentBytes; }
public TcpConnect GetProxy(DhtClient client) { if (client == null) return null; return GetProxy(client.UserID, client.ClientID); }
internal string GetFileLink(ulong user, SharedFile file) { // riseop://op/file/filename/opid~size~hash~key/targetlist string link = "riseop://" + HttpUtility.UrlEncode(Core.User.Settings.Operation) + "/file/" + HttpUtility.UrlEncode(file.Name) + "/"; byte[] endtag = Core.User.Settings.InviteKey; // 8 endtag = Utilities.CombineArrays(endtag, BitConverter.GetBytes(file.Size)); // 8 endtag = Utilities.CombineArrays(endtag, file.Hash); // 20 endtag = Utilities.CombineArrays(endtag, file.FileKey); // 32 link += Utilities.ToBase64String(endtag) + "/"; byte[] sources = null; // if local shared file, get the sources we know of if (user == Core.UserID && file.ClientID == Core.Network.Local.ClientID) { foreach (DhtClient client in file.Sources) sources = (sources == null) ? client.ToBytes() : Utilities.CombineArrays(sources, client.ToBytes()); } // else getting link from remote share, so add it's address as a location else sources = new DhtClient(user, file.ClientID).ToBytes(); if(sources != null) link += Utilities.ToBase64String(sources); return link; }
void LightComm_ReceiveData(DhtClient client, byte[] data) { Comm_ReceiveData(client, data); }
internal void TrySendRequest(SharedFile file, DhtClient target) { RudpSession session = Network.RudpControl.GetActiveSession(target); if (session == null) { Network.RudpControl.Connect(target); file.TransferStatus = "Connecting to " + Core.GetName(target.UserID); } else SendFileRequest(session, file); }
void EndLocationSearch(DhtSearch search) { if (search.FoundValues.Count == 0) return; SharedFile file = search.Carry as SharedFile; if (file.Completed) return; OpTransfer transfer = null; // add locations to running transfer foreach (byte[] result in search.FoundValues.Select(v => v.Value)) { LocationData loc = LocationData.Decode(result); DhtClient client = new DhtClient(loc.UserID, loc.Source.ClientID); if (transfer == null) transfer = StartTransfer(client, file); Core.Network.LightComm.Update(loc); transfer.AddPeer(client); } }
public RudpSession GetActiveSession(DhtClient client) { return GetActiveSession(client.UserID, client.ClientID); }
void Session_Update(RudpSession session) { DhtClient client = new DhtClient(session.UserID, session.ClientID); if (session.Status == SessionStatus.Active) { ShareCollection collection; if (Collections.SafeTryGetValue(session.UserID, out collection)) if (collection.ToRequest.Any(t => t.ClientID == session.ClientID)) SendPublicRequest(session, collection); } }
public ConnectionManager(BitChatProfile profile) { IPEndPoint localEP; switch (Environment.OSVersion.Platform) { case PlatformID.Win32NT: if (Environment.OSVersion.Version.Major < 6) { //below vista _tcpListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); localEP = new IPEndPoint(IPAddress.Any, profile.LocalPort); } else { //vista & above _tcpListener = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); _tcpListener.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false); localEP = new IPEndPoint(IPAddress.IPv6Any, profile.LocalPort); } break; case PlatformID.Unix: //mono framework if (Socket.OSSupportsIPv6) { _tcpListener = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); localEP = new IPEndPoint(IPAddress.IPv6Any, profile.LocalPort); } else { _tcpListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); localEP = new IPEndPoint(IPAddress.Any, profile.LocalPort); } break; default: //unknown _tcpListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); localEP = new IPEndPoint(IPAddress.Any, profile.LocalPort); break; } try { _tcpListener.Bind(localEP); _tcpListener.Listen(10); } catch { localEP.Port = 0; _tcpListener.Bind(localEP); _tcpListener.Listen(10); } _profile = profile; _localPort = (_tcpListener.LocalEndPoint as IPEndPoint).Port; _localPeerID = BinaryID.GenerateRandomID160(); //start dht _dhtClient = new DhtClient(_localPort, this); _dhtClient.ProxyEnabled = (_profile.Proxy != null); _dhtClient.AddNode(profile.BootstrapDhtNodes); //setup dht seeding tracker _dhtSeedingTracker = new TrackerManager(_dhtSeedingNetworkID, _localPort, null, DHT_SEED_TRACKER_UPDATE_INTERVAL); _dhtSeedingTracker.Proxy = _profile.Proxy; _dhtSeedingTracker.DiscoveredPeers += dhtSeedingTracker_DiscoveredPeers; _dhtSeedingTracker.StartTracking(profile.TrackerURIs); //start accepting connections _tcpListenerThread = new Thread(AcceptTcpConnectionAsync); _tcpListenerThread.IsBackground = true; _tcpListenerThread.Start(_tcpListener); //start upnp process _connectivityCheckTimer = new Timer(ConnectivityCheckTimerCallback, null, 1000, Timeout.Infinite); }
private void ReceiveFileRequest(RudpSession session, SharedFile file) { DhtClient client = new DhtClient(session.UserID, session.ClientID); // check if file hash already on sharelist, if it is ignore bool alertUser = true; Local.Files.LockReading(() => { SharedFile existing = Local.Files.Where(s => Utilities.MemCompare(s.Hash, file.Hash)).FirstOrDefault(); // transfer exists, but this is from another source, or we started up and someone is trying // to resend file to us, which this auto adds the new source if (existing != null) { if (!existing.Ignore) StartTransfer(client, existing); alertUser = false; } }); if (!alertUser) return; file.Ignore = true; // turned off once accepted, allowing this item to be saved to header file.FileID = OpTransfer.GetFileID(ServiceID, file.Hash, file.Size); Local.Files.SafeAdd(file); Core.RunInGuiThread(GuiFileUpdate, file); file.TransferStatus = "Request received from " + Core.GetName(session.UserID); Core.RunInGuiThread((System.Windows.Forms.MethodInvoker) delegate() { new AcceptFileForm(Core, client, file).ShowDialog(); }); }