Beispiel #1
0
            public override Task ConnectAsync(EndPoint remoteAddress, EndPoint localAddress)
            {
                NativeChannel ch = this.Channel;

                if (!ch.Open)
                {
                    return(this.CreateClosedChannelExceptionTask());
                }

                ConnectRequest request = null;

                try
                {
                    if (ch.connectPromise != null)
                    {
                        throw new InvalidOperationException("connection attempt already made");
                    }

                    ch.connectPromise = new TaskCompletionSource(remoteAddress);

                    if (localAddress != null)
                    {
                        ch.DoBind(localAddress);
                    }
                    request = new TcpConnect(this, (IPEndPoint)remoteAddress);
                    return(ch.connectPromise.Task);
                }
                catch (Exception ex)
                {
                    request?.Dispose();
                    this.CloseIfClosed();
                    return(TaskEx.FromException(this.AnnotateConnectException(ex, remoteAddress)));
                }
            }
Beispiel #2
0
        public void SendRequest(DhtAddress address, UInt64 targetID, uint searchID, uint service, uint datatype, byte[] parameters)
        {
            SearchReq request = new SearchReq();

            request.Source     = Network.GetLocalSource();
            request.SearchID   = searchID;
            request.TargetID   = targetID;
            request.Service    = service;
            request.DataType   = datatype;
            request.Parameters = parameters;

            int sentBytes = 0;

            TcpConnect direct = Network.TcpControl.GetProxy(address);

            if (direct != null)
            {
                sentBytes = direct.SendPacket(request);
            }
            else
            {
                sentBytes = Network.SendPacket(address, request);
            }

            Core.ServiceBandwidth[request.Service].OutPerSec += sentBytes;
        }
Beispiel #3
0
        private void TbCommand_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode.Equals(Keys.Enter))
            {
                byte[] resvReponse;

                if (tbService.Text.Equals("TCP"))
                {
                    TcpConnect tcpCon = new TcpConnect();
                    resvReponse = null;//tcpCon.SendRequest_Message(tbIP.Text, tbPort.Text, tbCommand.Text);
                }
                else
                {
                    Udp_Client udpClient = new Udp_Client();
                    udpClient.StartAsClient(tbIP.Text, tbPort.Text);
                    resvReponse = udpClient.SendRequest(Encoding.UTF8.GetBytes(tbCommand.Text));
                }

                if (resvReponse != null)
                {
                    string sResponse = Encoding.UTF8.GetString(resvReponse);

                    if (sResponse.Length < 20)
                    {
                        if (sResponse.Equals("SUCCESS"))
                        {
                            //tbResponse.Text = sResponse;

                            if (tbService.Text.Equals("TCP"))
                            {
                                TcpConnect tcpCon = new TcpConnect();
                                resvReponse = null; //tcpCon.SendRequest_Message(tbIP.Text, tbPort.Text, "view machinelist");
                            }
                            else
                            {
                                Udp_Client udpClient = new Udp_Client();
                                resvReponse = udpClient.SendRequest(Encoding.UTF8.GetBytes("view machinelist"));
                            }
                        }
                    }

                    /* MachineList Set GRID*/
                    if (resvReponse.Length > 20)
                    {
                        DataTable dataTable = Fomatter.xmlDataToDataTable(Encoding.UTF8.GetString(resvReponse));

                        if (dataTable.Rows.Count > 0)
                        {
                            dgvMachineList.DataSource = null;
                        }

                        dgvMachineList.DataSource = dataTable;

                        //SetDataGeidView(dataTable);
                    }

                    tbCommand.Text = "";
                }
            }
        }
        public static Tcp ConnectTo(this Tcp tcp,
                                    IPEndPoint remoteEndPoint,
                                    Action <Tcp, Exception> connectedAction,
                                    bool dualStack = false)
        {
            if (tcp is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tcp);
            }
            if (remoteEndPoint is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.remoteEndPoint);
            }
            if (connectedAction is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.connectedAction);
            }

            TcpConnect request = null;

            try
            {
                request = new TcpConnect(tcp, remoteEndPoint, connectedAction);
            }
            catch (Exception)
            {
                request?.Dispose();
                throw;
            }

            return(tcp);
        }
Beispiel #5
0
    bool BaseFlow.Init()
    {
        PlayerDataModule dataModule = ModuleManager.Instance.FindModule <PlayerDataModule>();

        if (GameConfig.GuideSceneID > 0 && !dataModule.IsStageHasPassed(GameConfig.GuideSceneID))
        {
            SceneManager.Instance.RequestEnterScene(GameConfig.GuideSceneID);
        }
        else
        {
            SceneManager.Instance.RequestEnterScene(SceneManager.Instance.GetLastCityResId());
        }

        FightGradeManager.Instance.InitListeners();
        //初始化主流程的部分数据


        //临时放到这里
        PlayerDataEvent evt = new PlayerDataEvent(PlayerDataEvent.PLAYER_DATA_CHANGED);

        EventSystem.Instance.PushEvent(evt);

        //临时
        GuideManager.Instance.OnFistGame();

        string[] strList = Environment.ChatServerAddress.Split(new char[] { ':' });

        //进入聊天服务器
        mTcpConnect = new TcpConnect();
        mTcpConnect.Connect(strList[0], int.Parse(strList[1]));

        SettingManager.Instance.InitPlayer(dataModule.GetName());

        return(false);
    }
Beispiel #6
0
    private void StartNetWork()
    {
        Log.Loggers.net.Debug("StartNetWork");
        _isRunning = true;

        // 初始化连接对象;
        _tc = new TcpConnect();
        _tc.StartConnect(_host, _port);
    }
Beispiel #7
0
 public SimPacket(SimPacketType type, IPEndPoint source, byte[] packet, DhtNetwork dest, TcpConnect tcp, ulong id)
 {
     Type     = type;
     Source   = source;
     Packet   = packet;
     Dest     = dest;
     Tcp      = tcp;
     SenderID = id;
 }
Beispiel #8
0
    // 请求关闭网络;
    // 结束前, 必须显示调用该函数; 否则可能会被阻塞在网络消息接收中, 卡死; (无法放在析构函数中, 结束阻塞后才会执行到析构)
    public void StopNetWork()
    {
        Log.Loggers.net.Debug("StopNetWork");
        _isRunning = false;

        // 断开原有连接;
        if (_tc != null)
        {
            _tc.CloseConnect();
            _tc = null;
        }
    }
Beispiel #9
0
        public bool Activate()
        {
            // bootstrap search from routing
            foreach (DhtContact contact in Network.Routing.Find(TargetID, 8))
            {
                Add(contact);
            }

            List <TcpConnect> sockets = null;

            // if open send search to proxied nodes just for good measure, probably helps on very small networks
            if (Core.Firewall == FirewallType.Open)
            {
                sockets = Network.TcpControl.ProxyClients;
            }

            // if natted send request to proxies for fresh nodes
            if (Core.Firewall == FirewallType.NAT)
            {
                sockets = Network.TcpControl.ProxyServers;
            }

            if (sockets != null)
            {
                foreach (TcpConnect socket in sockets)
                {
                    DhtContact contact = new DhtContact(socket, socket.RemoteIP);
                    Network.Searches.SendRequest(contact, TargetID, SearchID, Service, DataType, Parameters);

                    DhtLookup host = Add(socket.GetContact());
                    if (host != null)
                    {
                        host.Status = LookupStatus.Searching;
                    }
                }
            }

            // if blocked send proxy search request to 1 proxy, record and wait
            if (Core.Firewall == FirewallType.Blocked && !Network.UseLookupProxies)
            {
                // pick random proxy server
                if (Network.TcpControl.ProxyServers.Count == 0)
                {
                    return(false);
                }

                ProxyTcp = Network.TcpControl.ProxyServers[Core.RndGen.Next(Network.TcpControl.ProxyServers.Count)];

                Send_ProxySearchRequest();
            }

            return(true);
        }
Beispiel #10
0
        public void Send_StoreReq(DhtAddress address, DhtClient localProxy, DataReq publish)
        {
            if (address == null)
            {
                return;
            }

            StoreReq store = new StoreReq();

            store.Source   = Network.GetLocalSource();
            store.Key      = publish.Target;
            store.Service  = publish.Service;
            store.DataType = publish.DataType;
            store.Data     = publish.Data;

            int sentBytes = 0;

            TcpConnect direct = Network.TcpControl.GetProxy(address);

            if (direct != null)
            {
                sentBytes = direct.SendPacket(store);
            }

            else if (address.TunnelClient != null)
            {
                sentBytes = Network.SendTunnelPacket(address, store);
            }

            // if blocked send tcp with to tag
            else if (Core.Firewall == FirewallType.Blocked)
            {
                store.ToAddress = address;

                TcpConnect proxy = Network.TcpControl.GetProxy(localProxy);

                if (proxy != null)
                {
                    sentBytes = proxy.SendPacket(store);
                }
                else
                {
                    sentBytes = Network.TcpControl.SendRandomProxy(store);
                }
            }
            else
            {
                sentBytes = Network.UdpControl.SendTo(address, store);
            }

            Core.ServiceBandwidth[store.Service].OutPerSec += sentBytes;
        }
Beispiel #11
0
        void DoConnect(EndPoint remoteAddress, EndPoint localAddress)
        {
            ConnectRequest request = null;

            try
            {
                if (localAddress is object)
                {
                    DoBind(localAddress);
                }
                request = new TcpConnect(Unsafe, (IPEndPoint)remoteAddress);
            }
            catch
            {
                request?.Dispose();
                throw;
            }
        }
        void DoConnect(EndPoint remoteAddress, EndPoint localAddress)
        {
            ConnectRequest request = null;

            try
            {
                if (localAddress != null)
                {
                    this.DoBind(localAddress);
                }
                request = new TcpConnect((INativeUnsafe)this.Unsafe, (IPEndPoint)remoteAddress);
            }
            catch
            {
                request?.Dispose();
                throw;
            }
        }
Beispiel #13
0
        public Tcp ConnectTo(IPEndPoint remoteEndPoint, Action <Tcp, Exception> connectedAction)
        {
            Contract.Requires(remoteEndPoint != null);
            Contract.Requires(connectedAction != null);

            TcpConnect request = null;

            try
            {
                request = new TcpConnect(this, remoteEndPoint, connectedAction);
            }
            catch (Exception exception)
            {
                Log.Error($"{this.HandleType} {this.InternalHandle} Failed to connect to {remoteEndPoint}", exception);
                request?.Dispose();
                throw;
            }

            return(this);
        }
Beispiel #14
0
        // sends a direct request, no acks are returned, if  host has what is requested it sends a store request as a reply
        // make sure whatevers calling this handles the resulting store request
        public void SendDirectRequest(DhtAddress dest, ulong target, uint service, uint datatype, byte[] parameters)
        {
            SearchReq request = new SearchReq();

            request.Source     = Network.GetLocalSource();
            request.TargetID   = target;
            request.Service    = service;
            request.DataType   = datatype;
            request.Parameters = parameters;
            request.Nodes      = false;

            int sentBytes = 0;

            TcpConnect socket = Network.TcpControl.GetProxy(dest);

            if (socket != null)
            {
                sentBytes = socket.SendPacket(request);
            }

            else if (dest.TunnelClient != null)
            {
                sentBytes = Network.SendTunnelPacket(dest, request);
            }

            else if (Core.Firewall == FirewallType.Blocked)
            {
                request.ToAddress = dest;
                sentBytes         = Network.TcpControl.SendRandomProxy(request);
            }
            else
            {
                sentBytes = Network.UdpControl.SendTo(dest, request);
            }


            Core.ServiceBandwidth[request.Service].OutPerSec += sentBytes;

            // if remote end has what we need they will send us a store request
        }
Beispiel #15
0
        public static Tcp ConnectTo(this Tcp tcp,
                                    IPEndPoint remoteEndPoint,
                                    Action <Tcp, Exception> connectedAction,
                                    bool dualStack = false)
        {
            Contract.Requires(tcp != null);
            Contract.Requires(remoteEndPoint != null);
            Contract.Requires(connectedAction != null);

            TcpConnect request = null;

            try
            {
                request = new TcpConnect(tcp, remoteEndPoint, connectedAction);
            }
            catch (Exception)
            {
                request?.Dispose();
                throw;
            }

            return(tcp);
        }
Beispiel #16
0
        public void Receive_CrawlRequest(G2ReceivedPacket packet)
        {
            CrawlRequest request = CrawlRequest.Decode(packet);


            if (Local.Equals(request.Target))
            {
                Send_CrawlAck(request, packet);
            }

            // Forward to appropriate node
            else
            {
                TcpConnect client = TcpControl.GetProxy(request.Target);

                if (client != null)
                {
                    request.FromAddress = packet.Source; // add so receiving host knows where to send response too

                    client.SendPacket(request);
                }
            }
        }
Beispiel #17
0
        public int SendPacket(SimPacketType type, DhtNetwork network, byte[] packet, System.Net.IPEndPoint target, TcpConnect tcp)
        {
            if (type == SimPacketType.Tcp)
            {
                if (!TcpEndPoints.ContainsKey(target))
                {
                    //this is what actually happens -> throw new Exception("Disconnected");
                    return(-1);
                }
            }

            if (!UdpEndPoints.ContainsKey(target) ||
                !SimMap.ContainsKey(target.Address) ||
                !SimMap.ContainsKey(network.Core.Sim.RealIP))
            {
                return(0);
            }

            DhtNetwork targetNet = (type == SimPacketType.Tcp) ? TcpEndPoints[target] : UdpEndPoints[target];

            if (network.IsLookup != targetNet.IsLookup)
            {
                Debug.Assert(false);
            }

            IPEndPoint source = new IPEndPoint(network.Core.Sim.RealIP, 0);

            source.Port = (type == SimPacketType.Udp) ? network.UdpControl.ListenPort : network.TcpControl.ListenPort;

            SimInstance sourceInstance = SimMap[source.Address];
            SimInstance destInstance   = SimMap[target.Address];

            if (packet != null)
            {
                sourceInstance.BytesSent += (ulong)packet.Length;
            }

            // tcp connection must be present to send tcp
            if (type == SimPacketType.Tcp)
            {
                if (!TcpSourcetoDest.SafeContainsKey(tcp))
                {
                    //this is what actually happens -> throw new Exception("Disconnected");
                    return(-1);
                }
            }

            // add destination to nat table
            if (type == SimPacketType.Udp && sourceInstance.RealFirewall == FirewallType.NAT)
            {
                sourceInstance.NatTable[target] = true;
            }

            // if destination blocked drop udp / tcp connect requests
            if (destInstance.RealFirewall == FirewallType.Blocked)
            {
                if (type == SimPacketType.Udp || type == SimPacketType.TcpConnect)
                {
                    return(0);
                }
            }

            // if destination natted drop udp (unless in nat table) / tcp connect requests
            else if (destInstance.RealFirewall == FirewallType.NAT)
            {
                if (type == SimPacketType.TcpConnect)
                {
                    return(0);
                }

                if (type == SimPacketType.Udp && !destInstance.NatTable.ContainsKey(source))
                {
                    return(0);
                }
            }

            // randomly test tcp send buffer full
            if (TestTcpFullBuffer)
            {
                if (type == SimPacketType.Tcp && packet.Length > 4 && RndGen.Next(2) == 1)
                {
                    int    newlength = packet.Length / 2;
                    byte[] newpacket = new byte[newlength];
                    Buffer.BlockCopy(packet, 0, newpacket, 0, newlength);
                    packet = newpacket;
                }
            }

            if (packet != null && packet.Length == 0)
            {
                Debug.Assert(false, "Empty Packet");
            }

            int index = destInstance.ThreadIndex;

            lock (OutPackets[index])
                OutPackets[index].Add(new SimPacket(type, source, packet, targetNet, tcp, network.Local.UserID));

            if (packet == null)
            {
                return(0);
            }

            return(packet.Length);
        }
Beispiel #18
0
        void PumpThread(int index)
        {
            while (true)
            {
                PumpStart[index].WaitOne();

                if (Shutdown)
                {
                    return;
                }


                // send packets
                foreach (SimPacket packet in InPackets[index])
                {
                    switch (packet.Type)
                    {
                    case SimPacketType.Udp:
                        packet.Dest.Core.Sim.BytesRecvd += (ulong)packet.Packet.Length;
                        packet.Dest.UdpControl.OnReceive(packet.Packet, packet.Packet.Length, packet.Source);
                        break;

                    case SimPacketType.TcpConnect:
                        TcpConnect socket = packet.Dest.TcpControl.OnAccept(null, packet.Source);

                        if (socket != null)
                        {
                            TcpSourcetoDest.SafeAdd(packet.Tcp, socket);
                            TcpSourcetoDest.SafeAdd(socket, packet.Tcp);

                            packet.Tcp.OnConnect();
                        }

                        break;

                    case SimPacketType.Tcp:
                        TcpConnect dest;
                        if (TcpSourcetoDest.SafeTryGetValue(packet.Tcp, out dest))
                        {
                            dest.Core.Sim.BytesRecvd += (ulong)packet.Packet.Length;

                            packet.Packet.CopyTo(dest.RecvBuffer, dest.RecvBuffSize);
                            dest.OnReceive(packet.Packet.Length);
                        }
                        break;

                    case SimPacketType.TcpClose:
                        TcpConnect destClose;
                        if (TcpSourcetoDest.SafeTryGetValue(packet.Tcp, out destClose))
                        {
                            destClose.OnReceive(0);

                            TcpSourcetoDest.SafeRemove(packet.Tcp);
                            TcpSourcetoDest.SafeRemove(destClose);
                        }
                        break;
                    }
                }

                // send messages from gui
                if (!TestCoreThread)
                {
                    Instances.SafeForEach(instance =>
                    {
                        if (instance.ThreadIndex != index)
                        {
                            return;
                        }

                        Action <OpCore> runMessages = core =>
                        {
                            // process invoked functions, dequeue quickly to continue processing
                            while (core.CoreMessages.Count > 0)
                            {
                                AsyncCoreFunction function = null;

                                lock (core.CoreMessages)
                                    function = core.CoreMessages.Dequeue();

                                if (function != null)
                                {
                                    function.Result    = function.Method.DynamicInvoke(function.Args);
                                    function.Completed = true;
                                    function.Processed.Set();
                                }
                            }
                        };

                        if (instance.Context.Lookup != null)
                        {
                            runMessages(instance.Context.Lookup);
                        }

                        instance.Context.Cores.SafeForEach(c => runMessages(c));
                    });
                }

                // instance timer
                if (CurrentPump == 0) // stepping would cause second timer to run every 250ms without this
                {
                    Instances.SafeForEach(instance =>
                    {
                        if (instance.ThreadIndex == index)
                        {
                            instance.Context.SecondTimer_Tick(null);
                        }
                    });
                }

                PumpEnd[index].Set();
            }
        }
Beispiel #19
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);
        }
Beispiel #20
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);
                }
            }
        }