public PacketListViewItem(PacketLogEntry logEntry, string[] subItems, bool incoming) : base(subItems) { LogEntry = logEntry; ForeColor = incoming ? Color.DarkBlue : Color.DarkRed; }
private void AddListItem(PacketLogEntry logEntry) { if ((logEntry.Protocol == TransportProtocol.Tcp && MenuItemTcp.Checked) || (logEntry.Protocol == TransportProtocol.Udp && MenuItemUdp.Checked) || (logEntry.Protocol == TransportProtocol.LAN && MenuItemLAN.Checked) || (logEntry.Protocol == TransportProtocol.Rudp && MenuItemRudp.Checked) || (logEntry.Protocol == TransportProtocol.Tunnel && MenuItemTunnel.Checked)) ListViewPackets.Items.Add(PackettoItem(logEntry)); }
public void AsyncUpdateLog(PacketLogEntry logEntry) { if(menuItemPause.Checked) return; AddListItem(logEntry); if (!ListViewPackets.Focused && ListViewPackets.Items.Count > 0) ListViewPackets.EnsureVisible(ListViewPackets.Items.Count - 1); }
public ListViewItem PackettoItem(PacketLogEntry logEntry) { // hash, protocol, direction, address, type, size string hash = Utilities.BytestoHex(sha.ComputeHash( logEntry.Data), 0, 2, false); string protocol = logEntry.Protocol.ToString(); // Network - Search / Search Req / Store ... - Component // Comm - Data / Ack / Syn // Rudp - Type - Component string name = "?"; G2Header root = new G2Header(logEntry.Data); if (G2Protocol.ReadPacket(root)) { if(logEntry.Protocol == TransportProtocol.Rudp) { name = TransportProtocol.Rudp.ToString() + " - "; name += GetVariableName(typeof(CommPacket), root.Name); if (root.Name == CommPacket.Data) { CommData data = CommData.Decode(root); name += " - " + Network.Core.GetServiceName(data.Service); } } else { name = GetVariableName(typeof(RootPacket), root.Name) + " - "; if (root.Name == RootPacket.Comm) { RudpPacket commPacket = RudpPacket.Decode(root); name += GetVariableName(typeof(RudpPacketType), commPacket.PacketType); } if (root.Name == RootPacket.Network) { NetworkPacket netPacket = NetworkPacket.Decode(root); G2Header internalRoot = new G2Header(netPacket.InternalData); if (G2Protocol.ReadPacket(internalRoot)) { name += GetVariableName(typeof(NetworkPacket), internalRoot.Name); uint id = 0; G2ReceivedPacket wrap = new G2ReceivedPacket(); wrap.Root = internalRoot; // search request / search acks / stores have component types if (internalRoot.Name == NetworkPacket.SearchRequest) { SearchReq req = SearchReq.Decode(wrap); id = req.Service; } if (internalRoot.Name == NetworkPacket.SearchAck) { SearchAck ack = SearchAck.Decode(wrap); id = ack.Service; } if (internalRoot.Name == NetworkPacket.StoreRequest) { StoreReq store = StoreReq.Decode(wrap); id = store.Service; } if(id != 0) name += " - " + Network.Core.GetServiceName(id); // GetVariableName(typeof(ServiceID), id); } } } } string time = logEntry.Time.ToString("HH:mm:ss:ff"); string address = (logEntry.Address == null) ? "Broadcast" : logEntry.Address.ToString(); return new PacketListViewItem(logEntry, new string[] { time, protocol, address, name, logEntry.Data.Length.ToString(), hash }, logEntry.Direction == DirectionType.In ); }
public int SendPacket(G2Packet packet) { if (Core.InvokeRequired) Debug.Assert(false); if (State != TcpState.Connected) return 0; // usually when an inbound connection (dont know remote userId) is determined to be a loopback, we close the connection // even before the userId is set, if the userId is not set then the encryptor cant be init'd to send the 'close' packet if (UserID == 0) return 0; if (Core.Sim == null || Core.Sim.Internet.TestEncryption) if(Encryptor == null) CreateEncryptor(); try { if (packet is NetworkPacket) { ((NetworkPacket)packet).SourceID = Network.Local.UserID; ((NetworkPacket)packet).ClientID = Network.Local.ClientID; } byte[] encoded = packet.Encode(Network.Protocol); PacketLogEntry logEntry = new PacketLogEntry(Core.TimeNow, TransportProtocol.Tcp, DirectionType.Out, new DhtAddress(RemoteIP, this), encoded); Network.LogPacket(logEntry); lock(FinalSendBuffer) { // fill up final buffer, keep encrypt buffer clear if (BUFF_SIZE - FinalSendBuffSize < encoded.Length + 128) throw new Exception("SendBuff Full"); //crit check packet log // encrypt, turn off encryption during simulation if (Core.Sim == null || Core.Sim.Internet.TestEncryption) { encoded.CopyTo(SendBuffer, SendBuffSize); SendBuffSize += encoded.Length; int remainder = SendBuffSize % Encryptor.InputBlockSize; if (remainder > 0) { CryptPadding padding = new CryptPadding(); int fillerNeeded = Encryptor.InputBlockSize - remainder; if (fillerNeeded > 2) padding.Filler = new byte[fillerNeeded - 2]; encoded = padding.Encode(Network.Protocol); encoded.CopyTo(SendBuffer, SendBuffSize); SendBuffSize += encoded.Length; } int tryTransform = SendBuffSize - (SendBuffSize % Encryptor.InputBlockSize); if (tryTransform == 0) return 0; int tranformed = Encryptor.TransformBlock(SendBuffer, 0, tryTransform, FinalSendBuffer, FinalSendBuffSize); if (tranformed == 0) return 0; FinalSendBuffSize += tranformed; SendBuffSize -= tranformed; Buffer.BlockCopy(SendBuffer, tranformed, SendBuffer, 0, SendBuffSize); } else { encoded.CopyTo(FinalSendBuffer, FinalSendBuffSize); FinalSendBuffSize += encoded.Length; } } TrySend(); // record bandwidth return encoded.Length; } catch(Exception ex) { LogException("SendPacket", ex.Message); } return 0; }
void ReceivePackets() { int Start = 0; G2ReadResult streamStatus = G2ReadResult.PACKET_GOOD; while(streamStatus == G2ReadResult.PACKET_GOOD) { G2ReceivedPacket packet = new G2ReceivedPacket(); packet.Root = new G2Header(FinalRecvBuffer); streamStatus = G2Protocol.ReadNextPacket(packet.Root, ref Start, ref FinalRecvBuffSize); if( streamStatus != G2ReadResult.PACKET_GOOD ) break; packet.Tcp = this; packet.Source = new DhtContact(this, RemoteIP); // extract data from final recv buffer so it can be referenced without being overwritten by this thread byte[] extracted = Utilities.ExtractBytes(packet.Root.Data, packet.Root.PacketPos, packet.Root.PacketSize); packet.Root = new G2Header(extracted); G2Protocol.ReadPacket(packet.Root); LastPacket = packet; PacketLogEntry logEntry = new PacketLogEntry(Core.TimeNow, TransportProtocol.Tcp, DirectionType.In, packet.Source, packet.Root.Data); Network.LogPacket(logEntry); Network.IncomingPacket(packet); } // re-align buffer if (Start > 0 && FinalRecvBuffSize > 0) { Buffer.BlockCopy(FinalRecvBuffer, Start, FinalRecvBuffer, 0, FinalRecvBuffSize); //Network.UpdateConsole(PacketBytesReady.ToString() + " bytes moved to front of receive buffer"); } }
public void ReceiveTunnelPacket(G2ReceivedPacket raw, TunnelPacket tunnel) { if (Core.InvokeRequired) // called from lookup core's thread { Core.RunInCoreAsync(delegate() { ReceiveTunnelPacket(raw, tunnel); }); return; } Debug.Assert(!IsLookup); if (IsLookup) return; // decrypt public packet if (Core.Sim == null || Core.Sim.Internet.TestEncryption) // turn off encryption during simulation { if (tunnel.Payload.Length < 16) throw new Exception("Not enough data received for IV"); tunnel.Payload = Utilities.DecryptBytes(tunnel.Payload, tunnel.Payload.Length, LocalAugmentedKey); } G2ReceivedPacket opPacket = new G2ReceivedPacket(); opPacket.Root = new G2Header(tunnel.Payload); // set source information if (G2Protocol.ReadPacket(opPacket.Root)) { opPacket.Source = new DhtAddress(); // used to add direct op contact if source firewall is open // or re-routing through same lookup proxy opPacket.Source.IP = raw.Source.IP; opPacket.Source.UdpPort = raw.Source.UdpPort; // op user/client set by net/comm processing opPacket.Source.TunnelClient = tunnel.Source; opPacket.Source.TunnelServer = tunnel.SourceServer; PacketLogEntry logEntry = new PacketLogEntry(Core.TimeNow, TransportProtocol.Tunnel, DirectionType.In, opPacket.Source, opPacket.Root.Data); LogPacket(logEntry); IncomingPacket(opPacket); } }
// nodes in lookup proxy mode are psuedo-open, instead of udp they send tunneled packets // tunnel packets include routing information to the lookup target as well as // the encrytped operation packet embedded in the payload public int SendTunnelPacket(DhtAddress contact, G2Packet embed) { Debug.Assert(contact.TunnelClient != null && contact.TunnelServer != null); Debug.Assert(Core.Context.Lookup != null); Debug.Assert(!IsLookup); Debug.Assert(Core.User.Settings.OpAccess != AccessType.Secret); if (IsLookup || Core.Context.Lookup == null || Core.User.Settings.OpAccess == AccessType.Secret) return 0; OpCore lookup = Core.Context.Lookup; // tunnel packet through lookup network byte[] encoded = embed.Encode(Protocol); PacketLogEntry logEntry = new PacketLogEntry(Core.TimeNow, TransportProtocol.Tunnel, DirectionType.Out, contact, encoded); LogPacket(logEntry); TunnelPacket packet = new TunnelPacket(); // encrypt, turn off encryption during simulation if (Core.Sim == null || Core.Sim.Internet.TestEncryption) packet.Payload = Utilities.EncryptBytes(encoded, GetAugmentedKey(contact.UserID)); else packet.Payload = encoded; packet.Source = new TunnelAddress(lookup.Network.Local, Core.TunnelID); packet.Target = contact.TunnelClient; int bytesSent = 0; // if we are the tunnel server (our lookup net is open, but op is blocked) if (lookup.Network.Local.Equals(contact.TunnelServer)) // use dhtclient compare { lookup.RunInCoreAsync(delegate() { TcpConnect direct = lookup.Network.TcpControl.GetProxy(packet.Target); if (direct != null) { packet.SourceServer = new DhtAddress(Core.LocalIP, lookup.Network.GetLocalSource()); bytesSent = direct.SendPacket(packet); } }); return bytesSent; } // if not open send proxied through local lookup proxy // NAT as well because receiver would need to send all responses through same local lookup proxy // for NATd host to get replies if (Core.Firewall != FirewallType.Open) { packet.TargetServer = contact.TunnelServer; lookup.RunInCoreAsync(delegate() { TcpConnect server = lookup.Network.TcpControl.GetProxy(packet.TargetServer) ?? // direct path lookup.Network.TcpControl.GetProxyServer(contact.IP) ?? // reRoute through same server lookup.Network.TcpControl.GetRandomProxy(); // random proxy if (server != null) { packet.SourceServer = new DhtAddress(server.RemoteIP, server); bytesSent = server.SendPacket(packet); } }); } // else we are open, send op ip address in the souce server else { packet.SourceServer = new DhtAddress(Core.LocalIP, lookup.Network.GetLocalSource()); lookup.RunInCoreAsync(delegate() { bytesSent = lookup.Network.UdpControl.SendTo(contact.TunnelServer, packet); }); } return bytesSent; }
public void ReceivePacket(G2ReceivedPacket packet) { // Network packet if (packet.Root.Name == RootPacket.Network) { NetworkPacket netPacket = NetworkPacket.Decode(packet.Root); G2ReceivedPacket embedded = new G2ReceivedPacket(); embedded.Tcp = packet.Tcp; embedded.Source = packet.Source; embedded.Source.UserID = netPacket.SourceID; embedded.Source.ClientID = netPacket.ClientID; embedded.Root = new G2Header(netPacket.InternalData); // from - received from proxy server if (netPacket.FromAddress != null) { if (packet.ReceivedUdp) throw new Exception("From tag set on packet received udp"); if (packet.Tcp.Proxy != ProxyType.Server) throw new Exception("From tag (" + netPacket.FromAddress.ToString() + ") set on packet not received from server (" + packet.Tcp.ToString() + ")"); embedded.Source = new DhtContact(netPacket.FromAddress); } // to - received from proxied node, and not for us if (netPacket.ToAddress != null && !(netPacket.ToAddress.UserID == Local.UserID && netPacket.ToAddress.ClientID == Local.ClientID)) { if (packet.ReceivedUdp) throw new Exception("To tag set on packet received udp"); if (packet.Tcp.Proxy == ProxyType.Server || packet.Tcp.Proxy == ProxyType.Unset) throw new Exception("To tag set on packet received from server"); DhtAddress address = netPacket.ToAddress; netPacket.ToAddress = null; TcpConnect direct = TcpControl.GetProxy(address); if (direct != null) direct.SendPacket(netPacket); else UdpControl.SendTo(address, netPacket); return; } // process if (G2Protocol.ReadPacket(embedded.Root)) ReceiveNetworkPacket(embedded); } // Tunnel Packet else if (packet.Root.Name == RootPacket.Tunnel) { // can only tunnel over lookup network if (!IsLookup) return; PacketLogEntry logEntry = new PacketLogEntry(Core.TimeNow, TransportProtocol.Tunnel, DirectionType.In, packet.Source, packet.Root.Data); LogPacket(logEntry); TunnelPacket tunnel = TunnelPacket.Decode(packet.Root); // handle locally if (tunnel.Target.Equals(Local)) { Core.Context.Cores.LockReading(delegate() { foreach (OpCore core in Core.Context.Cores) if (core.TunnelID == tunnel.Target.TunnelID) core.Network.ReceiveTunnelPacket(packet, tunnel); }); } else if (tunnel.TargetServer != null) { TcpConnect direct = TcpControl.GetProxy(tunnel.Target); // if directly connected add from and forwared if (direct != null) direct.SendPacket(tunnel); // only forward udp if received over tcp from a proxied host else if (tunnel.TargetServer != null && packet.ReceivedTcp && packet.Tcp.Proxy != ProxyType.Server) UdpControl.SendTo(tunnel.TargetServer, tunnel); } } // Communication Packet else if (packet.Root.Name == RootPacket.Comm) { RudpPacket commPacket = RudpPacket.Decode(packet); // received direct packet.Source.UserID = commPacket.SenderID; packet.Source.ClientID = commPacket.SenderClient; // remote node is proxied if (commPacket.RemoteProxy != null) packet.Source = new DhtContact(commPacket.RemoteProxy); // For local host if (commPacket.TargetID == Local.UserID && commPacket.TargetClient == Local.ClientID) { ReceiveCommPacket(packet, commPacket); return; } // Also Forward to appropriate node TcpConnect socket = TcpControl.GetProxy(commPacket.TargetID, commPacket.TargetClient); if (socket != null) { // forward to proxied node - strip TO flag, add from address commPacket.ToAddress = null; commPacket.RemoteProxy = packet.Source; // if remote proxy is null, then we are setting this to the packet's original source socket.SendPacket(commPacket); return; } // received from a proxied node, forward udp if (packet.ReceivedTcp && commPacket.ToAddress != null) { DhtAddress target = commPacket.ToAddress; commPacket.ToAddress = null; // strip TO flag commPacket.RemoteProxy = new DhtAddress(Core.LocalIP, GetLocalSource()); UdpControl.SendTo(target, commPacket); } } }
public void LogPacket(PacketLogEntry logEntry) { if (Core.Sim != null && !Core.Sim.Internet.Logging) return; if (Core.PauseLog) return; lock (LoggedPackets) { LoggedPackets.Enqueue(logEntry); while (LoggedPackets.Count > 50) LoggedPackets.Dequeue(); } Core.RunInGuiThread(UpdatePacketLog, logEntry); }
public void SendTo(G2Packet packet) { if (Core.InvokeRequired) Debug.Assert(false); if (packet is NetworkPacket) { ((NetworkPacket)packet).SourceID = Network.Local.UserID; ((NetworkPacket)packet).ClientID = Network.Local.ClientID; } byte[] encoded = packet.Encode(Network.Protocol); PacketLogEntry logEntry = new PacketLogEntry(Core.TimeNow, TransportProtocol.LAN, DirectionType.Out, null, encoded); Network.LogPacket(logEntry); byte[] final = null; // encrypt, turn off encryption during simulation if (Core.Sim == null || Core.Sim.Internet.TestEncryption) { final = Utilities.EncryptBytes(encoded, Network.OpCrypt.Key); } else final = encoded; // send try { if (Core.Sim != null) { //Core.Sim.Internet.SendPacket(SimPacketType.Udp, Network, final, address.ToEndPoint(), null); return; } if (LanSocket == null) return; if (encoded.Length> MAX_UDP_SIZE) throw new Exception("Packet larger than " + MAX_UDP_SIZE.ToString() + " bytes"); EndPoint tempSender = (EndPoint)new IPEndPoint(IPAddress.Broadcast, ListenPort); LanSocket.BeginSendTo(final, 0, final.Length, SocketFlags.None, tempSender, new AsyncCallback(UdpSocket_SendTo), LanSocket); } catch(Exception ex) { Network.UpdateLog("Exception", "LanHandler::SendTo: " + ex.Message); } }
void ParsePacket(byte[] buff, int length, IPEndPoint sender, bool copied) { G2ReceivedPacket packet = new G2ReceivedPacket(); packet.Root = new G2Header(buff); if(G2Protocol.ReadPacket(packet.Root)) { packet.Source = new DhtContact(0, 0, sender.Address, 0, 0); byte[] packetData = copied ? buff : Utilities.ExtractBytes(packet.Root.Data, packet.Root.PacketPos, packet.Root.PacketSize); PacketLogEntry logEntry = new PacketLogEntry(Core.TimeNow, TransportProtocol.LAN, DirectionType.In, packet.Source, packetData); Network.LogPacket(logEntry); Network.IncomingPacket(packet); } }
public int SendTo(DhtAddress address, G2Packet packet) { if (Core.InvokeRequired) Debug.Assert(false); Debug.Assert(address.UdpPort != 0); if (packet is NetworkPacket) { ((NetworkPacket)packet).SourceID = Network.Local.UserID; ((NetworkPacket)packet).ClientID = Network.Local.ClientID; } byte[] encoded = packet.Encode(Network.Protocol); PacketLogEntry logEntry = new PacketLogEntry(Core.TimeNow, TransportProtocol.Udp, DirectionType.Out, address, encoded); Network.LogPacket(logEntry); byte[] final = null; // encrypt, turn off encryption during simulation if (Core.Sim == null || Core.Sim.Internet.TestEncryption) final = Utilities.EncryptBytes(encoded, Network.GetAugmentedKey(address.UserID)); else final = encoded; // send try { if (Core.Sim != null) { Core.Sim.Internet.SendPacket(SimPacketType.Udp, Network, final, address.ToEndPoint(), null); } else { if (UdpSocket == null) return 0; if (encoded.Length > MAX_UDP_SIZE) throw new Exception("Packet larger than " + MAX_UDP_SIZE.ToString() + " bytes"); UdpSocket.BeginSendTo(final, 0, final.Length, SocketFlags.None, address.ToEndPoint(), new AsyncCallback(UdpSocket_SendTo), UdpSocket); } // record bandwidth Bandwidth.OutPerSec += final.Length; return final.Length; } catch(Exception ex) { Network.UpdateLog("Exception", "UdpHandler::SendTo: " + ex.Message); } return 0; }