Пример #1
0
        public PacketListViewItem(PacketLogEntry logEntry, string[] subItems, bool incoming)
            : base(subItems)
        {
            LogEntry = logEntry;

            ForeColor = incoming ? Color.DarkBlue : Color.DarkRed;
        }
Пример #2
0
 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));
 }
Пример #3
0
        public void AsyncUpdateLog(PacketLogEntry logEntry)
        {
            if(menuItemPause.Checked)
                return;

            AddListItem(logEntry);

            if (!ListViewPackets.Focused && ListViewPackets.Items.Count > 0)
                ListViewPackets.EnsureVisible(ListViewPackets.Items.Count - 1);
        }
Пример #4
0
        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 );
        }
Пример #5
0
        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;
        }
Пример #6
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");
            }
        }
Пример #7
0
        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);
            }
        }
Пример #8
0
        // 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;
        }
Пример #9
0
        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);
                }
            }
        }
Пример #10
0
        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);
        }
Пример #11
0
        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);
            }
        }
Пример #12
0
        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);
            }
        }
Пример #13
0
        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;
        }