public void TrySend(DhtNetwork network) { // check if stuff in queue if (Packets.Count == 0 || Addresses.Count == 0 || network.Core.TimeNow < NextTry) { return; } Attempts++; if (Attempts >= Addresses.Count * 2) // every address known tried twice { Attempts = 0; Packets.RemoveFirst(); return; } RudpAddress target = Addresses.First.Value; Addresses.RemoveFirst(); Addresses.AddLast(target); NextTry = network.Core.TimeNow.AddSeconds(3); Tuple <uint, RudpPacket> tuple = Packets.First.Value; RudpPacket packet = tuple.Param2; packet.Ident = target.Ident; int sentBytes = SendtoAddress(network, target, packet); network.Core.ServiceBandwidth[tuple.Param1].OutPerSec += sentBytes; }
public void SendTracked(TrackPacket tracked) { if (AddressMap.Count == 0) { return; } RudpAddress target = tracked.SpecialTarget ? tracked.Target : PrimaryAddress; LastSend = Core.TimeNow; tracked.TimeSent = Core.TimeNow.Ticks; tracked.Target = target; tracked.Packet.SenderID = Network.Local.UserID; tracked.Packet.SenderClient = Network.Local.ClientID; if (tracked.Packet.PacketType != RudpPacketType.Syn) { SendPacket(tracked.Packet, target); } else { PrimaryAddress.Reset = true; foreach (RudpAddress address in AddressMap.Values) { tracked.Packet.Ident = address.Ident; tracked.Target = address; SendPacket(tracked.Packet, address); } } }
public static int SendtoAddress(DhtNetwork network, RudpAddress target, RudpPacket packet) { Debug.Assert(packet.Payload != null || packet.PacketType == RudpPacketType.LightAck); int sentBytes = 0; // same code used in rudpSocket if (network.Core.Firewall != FirewallType.Blocked && target.LocalProxy == null) { sentBytes = network.SendPacket(target.Address, packet); } else if (target.Address.TunnelClient != null) { sentBytes = network.SendTunnelPacket(target.Address, packet); } else { packet.ToAddress = target.Address; TcpConnect proxy = network.TcpControl.GetProxy(target.LocalProxy); if (proxy != null) { sentBytes = proxy.SendPacket(packet); } else { sentBytes = network.TcpControl.SendRandomProxy(packet); } } return(sentBytes); }
public void AddAddress(RudpAddress address) { if (!AddressMap.ContainsKey(address.GetHashCode())) { address.Ident = (uint)Core.RndGen.Next(); AddressMap[address.GetHashCode()] = address; } if (PrimaryAddress == null) { PrimaryAddress = address; } }
public void SendPacket(RudpPacket packet, RudpAddress target) { Debug.Assert(packet.Payload != null); // sending syn to (tracked target) through (address target) udp / tcp /*string log = "Sending " + tracked.Packet.PacketType.ToString(); * if (tracked.Packet.Ident != 0) log += ", ID " + tracked.Packet.Ident.ToString(); * log += " to " + Utilities.IDtoBin(tracked.Packet.TargetID).Substring(0, 10); * log += " target address " + target.Address.ToString();*/ int sentBytes = 0; // same code used in lightComm if (Core.Firewall != FirewallType.Blocked && target.LocalProxy == null) { sentBytes = Network.SendPacket(target.Address, packet); } else if (target.Address.TunnelClient != null) { sentBytes = Network.SendTunnelPacket(target.Address, packet); } else { packet.ToAddress = target.Address; TcpConnect proxy = Network.TcpControl.GetProxy(target.LocalProxy); if (proxy != null) { sentBytes = proxy.SendPacket(packet); } else { sentBytes = Network.TcpControl.SendRandomProxy(packet); } //log += " proxied by local tcp"; } Bandwidth.OutPerSec += sentBytes; //Session.Log(log); }
void SendPing(RudpAddress address) { RudpPacket ping = new RudpPacket(); ping.TargetID = Session.UserID; ping.TargetClient = Session.ClientID; ping.PeerID = RemotePeerID; ping.PacketType = RudpPacketType.Ping; ping.Sequence = 0; ping.Payload = BitConverter.GetBytes(address.Ident); //Session.Log("Keep Alive Sent, Seq " + alive.Sequence.ToString() + ", ID " + alive.PeerID.ToString()); TrackPacket tracked = new TrackPacket(ping); tracked.Target = address; tracked.SpecialTarget = true; SendTracked(tracked); }
private void SetPrimaryAddress(uint ident) { foreach (RudpAddress address in AddressMap.Values) { if (address.Ident == ident) { address.LastAck = Core.TimeNow; // if primary address needs to be reset, replace with this one // (which would be first/fastest received) if (PrimaryAddress.Reset) { PrimaryAddress.Reset = false; PrimaryAddress = address; } break; } } }
public void AddAddress(OpCore core, RudpAddress address, bool moveFront) { Debug.Assert(address.Address.UdpPort != 0); foreach (RudpAddress check in Addresses) { if (check.GetHashCode() == address.GetHashCode()) { if (moveFront) { Addresses.Remove(check); Addresses.AddFirst(check); } return; } } address.Ident = (uint)core.RndGen.Next(); Addresses.AddLast(address); }
public void SecondTimer() { int packetLoss = 0; if (State == RudpState.Connected) { //Debug.WriteLine(Core.User.Settings.UserName + ":" + Core.TimeNow.Second + " - Send Window: " + SendWindowSize + ", Packets Sent: " + PacketsCompleted + ", Retransmits: " + ReTransmits); //crit delete PacketsCompleted = 0; // manage send window packetLoss = 0; if (InOrderAcks > 0) { packetLoss = ReTransmits * 100 / InOrderAcks; } ReTransmits = 0; InOrderAcks = 0; //Session.Log("PL: " + packetLoss.ToString() + // ", SW: " + SendWindowSize.ToString() + // ", SQ: " + SendPacketMap.Count.ToString() + // ", SB: " + SendBuffLength.ToString()); if (packetLoss < 10 && SendWindowSize < MAX_WINDOW_SIZE) { SendWindowSize++; } if (packetLoss > 20 && SendWindowSize > 1) { SendWindowSize /= 2; } // if data waiting to be read if (State == RudpState.Connected && RecvBuffLength > 0) { Session.OnReceive(); } // dead - 5 secs send ping, 10 secs reset primary addr, 15 secs close DateTime lastRecv = PrimaryAddress.LastAck; // if nothing received for 15 seconds disconnect if (Core.TimeNow > lastRecv.AddSeconds(15)) { RudpClose(CloseReason.TIMEOUT); } // re-analyze alternate routes after 10 secs dead, or half min interval else if (Core.TimeNow > lastRecv.AddSeconds(10) || Core.TimeNow > NextCheckRoutes) { // after connection this should immediately be called to find best route CheckRoutes(); NextCheckRoutes = Core.TimeNow.AddSeconds(30); } // send keep alive if nothing received after 5 secs else if (Core.TimeNow > lastRecv.AddSeconds(5)) { SendPing(PrimaryAddress); } } // prune addressMap to last 6 addresses seen while (AddressMap.Count > 6) { RudpAddress lastSeen = null; foreach (RudpAddress address in AddressMap.Values) { if (lastSeen == null || address.LastAck < lastSeen.LastAck) { lastSeen = address; } } AddressMap.Remove(lastSeen.GetHashCode()); } // finishing if (State == RudpState.Finishing) { if (!FinSent) { TrySendFin(); } if (FinTimeout > 0) { FinTimeout--; } if (FinTimeout == 0) { ChangeState(RudpState.Closed); } // buffer clear, all packets acked in sequence including fins if (FinSent && FinReceived && SendPacketMap.Count == 0) { ChangeState(RudpState.Closed); } } // re-send packets in out buffer if (State != RudpState.Closed) { ManageSendWindow(); } // update bandwidth rate used for determining public send buffer AvgBytesSent.Next(); // bandwidth stats Bandwidth.NextSecond(); }
private void SetPrimaryAddress(uint ident) { foreach (RudpAddress address in AddressMap.Values) if (address.Ident == ident) { address.LastAck = Core.TimeNow; // if primary address needs to be reset, replace with this one // (which would be first/fastest received) if (PrimaryAddress.Reset) { PrimaryAddress.Reset = false; PrimaryAddress = address; } break; } }
void SendPing(RudpAddress address) { RudpPacket ping = new RudpPacket(); ping.TargetID = Session.UserID; ping.TargetClient = Session.ClientID; ping.PeerID = RemotePeerID; ping.PacketType = RudpPacketType.Ping; ping.Sequence = 0; ping.Payload = BitConverter.GetBytes(address.Ident); //Session.Log("Keep Alive Sent, Seq " + alive.Sequence.ToString() + ", ID " + alive.PeerID.ToString()); TrackPacket tracked = new TrackPacket(ping); tracked.Target = address; tracked.SpecialTarget = true; SendTracked(tracked); }
public void SendPacket(RudpPacket packet, RudpAddress target) { Debug.Assert(packet.Payload != null); // sending syn to (tracked target) through (address target) udp / tcp /*string log = "Sending " + tracked.Packet.PacketType.ToString(); if (tracked.Packet.Ident != 0) log += ", ID " + tracked.Packet.Ident.ToString(); log += " to " + Utilities.IDtoBin(tracked.Packet.TargetID).Substring(0, 10); log += " target address " + target.Address.ToString();*/ int sentBytes = 0; // same code used in lightComm if (Core.Firewall != FirewallType.Blocked && target.LocalProxy == null) { sentBytes = Network.SendPacket(target.Address, packet); } else if (target.Address.TunnelClient != null) sentBytes = Network.SendTunnelPacket(target.Address, packet); else { packet.ToAddress = target.Address; TcpConnect proxy = Network.TcpControl.GetProxy(target.LocalProxy); if (proxy != null) sentBytes = proxy.SendPacket(packet); else sentBytes = Network.TcpControl.SendRandomProxy(packet); //log += " proxied by local tcp"; } Bandwidth.OutPerSec += sentBytes; //Session.Log(log); }
public void AddAddress(RudpAddress address) { if (!AddressMap.ContainsKey(address.GetHashCode())) { address.Ident = (uint) Core.RndGen.Next(); AddressMap[address.GetHashCode()] = address; } if (PrimaryAddress == null) PrimaryAddress = address; }