void ReceiveAck(G2ReceivedPacket raw, LightClient client, RudpPacket packet) { // remove acked packet foreach (Tuple <uint, RudpPacket> tuple in client.Packets) { if (tuple.Param2.PeerID == packet.PeerID) { client.Packets.Remove(tuple); client.Attempts = 0; break; } } // read ack ident and move to top foreach (RudpAddress address in client.Addresses) { if (address.Ident == packet.Ident) { client.Addresses.Remove(address); client.Addresses.AddFirst(address); address.LastAck = Core.TimeNow; break; } } client.NextTry = Core.TimeNow; // receieved ack, try to send next packet immediately client.TrySend(Network); }
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 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 SendAck(LightClient light, RudpPacket packet, uint service) { RudpPacket comm = new RudpPacket(); comm.SenderID = Network.Local.UserID; comm.SenderClient = Network.Local.ClientID; comm.TargetID = light.Client.UserID; comm.TargetClient = light.Client.ClientID; comm.PacketType = RudpPacketType.LightAck; comm.PeerID = packet.PeerID; // so remote knows which packet we're acking comm.Ident = packet.Ident; // so remote knows which address is good comm.Sequence = 0; // send ack to first address, addresses moved to front on receive packet int sentBytes = LightClient.SendtoAddress(Network, light.Addresses.First.Value, comm); Core.ServiceBandwidth[service].OutPerSec += sentBytes; // on resend packet from remote we receive it through different proxy, so that address // is moved to the front of the list automatically and our ack takes that direction }
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); } }