private void Send_Ping(ClientInfo client) { client.NextPing = Core.TimeNow.AddSeconds(client.PingTimeout); LocationPing ping = new LocationPing(); ping.RemoteVersion = client.Data.Version; Network.LightComm.SendReliable(client, ServiceID, 0, ping); }
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 static LocationPing Decode(G2Header root) { LocationPing ping = new LocationPing(); G2Header child = new G2Header(root.Data); while (G2Protocol.ReadNextChild(root, child) == G2ReadResult.PACKET_GOOD) { if (!G2Protocol.ReadPayload(child)) { continue; } switch (child.Name) { case Packet_RemoteVersion: ping.RemoteVersion = CompactNum.ToUInt32(child.Data, child.PayloadPos, child.PayloadSize); break; } } return(ping); }
public static LocationPing Decode(G2Header root) { LocationPing ping = new LocationPing(); G2Header child = new G2Header(root.Data); while (G2Protocol.ReadNextChild(root, child) == G2ReadResult.PACKET_GOOD) { if (!G2Protocol.ReadPayload(child)) continue; switch (child.Name) { case Packet_RemoteVersion: ping.RemoteVersion = CompactNum.ToUInt32(child.Data, child.PayloadPos, child.PayloadSize); break; } } return ping; }