Exemple #1
0
        public void Receive_ProxyRequest(G2ReceivedPacket packet)
        {
            ProxyReq request = ProxyReq.Decode(packet);

            ProxyAck ack = new ProxyAck();

            ack.Source = GetLocalSource();

            // check if there is space for type required
            if (Core.Firewall == FirewallType.Open && TcpControl.AcceptProxy(request.Type, ack.Source.UserID))
            {
                ack.Accept = true;
            }
            else if (packet.ReceivedTcp)
            {
                packet.Tcp.CleanClose("Couldn't accept proxy request");
                return;
            }



            // always send some contacts along so node can find closer proxy
            ack.ContactList = Routing.Find(request.SenderID, 8);


            // received request tcp
            if (packet.ReceivedUdp)
            {
                UdpControl.SendTo(packet.Source, ack);
            }

            // received request tcp
            else
            {
                packet.Tcp.Proxy = request.Type;
                packet.Tcp.SendPacket(ack);

                TcpControl.AddProxy(packet.Tcp);

                // check if a proxy needs to be disconnected now because overflow
                TcpControl.CheckProxies();
            }
        }
Exemple #2
0
        public void FirewallChangedtoNAT()
        {
            if (Core.InvokeRequired)
            {
                Core.RunInCoreAsync(delegate() { FirewallChangedtoNAT(); });
                return;
            }

            //update proxy connects
            lock (TcpControl.SocketList)
                foreach (TcpConnect connection in TcpControl.SocketList)
                {
                    if (connection.Proxy == ProxyType.Server)
                    {
                        ProxyReq request = new ProxyReq();
                        request.SenderID = Local.UserID;
                        request.Type     = ProxyType.ClientNAT;
                        connection.SendPacket(request);
                    }
                }
        }
Exemple #3
0
        void ConnectProxy()
        {
            // Get cloest contacts and sort by distance to us
            DhtContact attempt = null;

            // no Dht contacts, use ip cache will be used to connect tcp/udp in DoBootstrap

            // find if any contacts in list are worth trying (will be skipped if set already)
            // get closest contact that is not already connected
            foreach (DhtContact contact in Network.Routing.NearXor.Contacts)
            {
                // if havent tried in 10 minutes
                if (Core.TimeNow > contact.NextTryProxy && contact.TunnelClient == null)
                {
                    bool connected = false;

                    lock (SocketList)
                        foreach (TcpConnect socket in SocketList)
                        {
                            if (contact.UserID == socket.UserID && contact.ClientID == socket.ClientID)
                            {
                                connected = true;
                                break;
                            }
                        }

                    if (connected)
                    {
                        continue;
                    }

                    if (attempt == null || (contact.UserID ^ Network.Local.UserID) < (attempt.UserID ^ Network.Local.UserID))
                    {
                        attempt = contact;
                    }
                }
            }


            if (attempt != null)
            {
                // take into account when making proxy request, disconnct furthest
                if (Core.Firewall == FirewallType.Blocked)
                {
                    // continue attempted to test nat with pings which are small
                    Network.Send_Ping(attempt);
                    MakeOutbound(attempt, attempt.TcpPort, "try proxy");
                }

                // if natted do udp proxy request first before connect
                else if (Core.Firewall == FirewallType.NAT)
                {
                    ProxyReq request = new ProxyReq();
                    request.SenderID = Network.Local.UserID;
                    request.Type     = ProxyType.ClientNAT;
                    Network.UdpControl.SendTo(attempt, request);
                }

                attempt.NextTryProxy = Core.TimeNow.AddMinutes(10);
            }
        }
Exemple #4
0
        public void FirewallChangedtoNAT()
        {
            if (Core.InvokeRequired)
            {
                Core.RunInCoreAsync(delegate() { FirewallChangedtoNAT(); });
                return;
            }

            //update proxy connects
            lock (TcpControl.SocketList)
                foreach (TcpConnect connection in TcpControl.SocketList)
                    if (connection.Proxy == ProxyType.Server)
                    {
                        ProxyReq request = new ProxyReq();
                        request.SenderID = Local.UserID;
                        request.Type = ProxyType.ClientNAT;
                        connection.SendPacket(request);
                    }
        }
Exemple #5
0
        void Receive_Pong(G2ReceivedPacket packet)
        {
            Core.ServiceBandwidth[Core.DhtServiceID].InPerSec += packet.Root.Data.Length;

            Pong pong = Pong.Decode(packet);

            SetLocalIP(pong.RemoteIP, packet);

            bool lanIP = Utilities.IsLocalIP(packet.Source.IP);
            bool validSource = (!lanIP || LanMode && lanIP);

            // check if remote has a newer version cached
            if (!IsLookup && pong.Version != 0 && Core.Update != null)
                if (Core.Context.SignedUpdate == null ||
                    !Core.Context.SignedUpdate.Loaded ||
                    Core.Context.SignedUpdate.SequentialVersion < pong.Version)
                {
                    // ota update disabled for now
                    //Core.Update.NewVersion(pong.Version, pong.Source.UserID);
                }

            // if received tcp
            if (packet.ReceivedTcp)
            {
                // if regular interval pong
                if (pong.Source == null)
                {
                    // keep routing entry fresh so connect state remains
                    if (validSource && packet.Tcp.Proxy == ProxyType.Server)
                        Routing.Add(new DhtContact(packet.Tcp, packet.Tcp.RemoteIP), true);
                }

                // else connect pong with source info
                else
                {
                    // usually a proxied pong from somewhere else to keep our routing fresh
                    if (validSource && pong.Source.Firewall == FirewallType.Open)
                        Routing.Add(new DhtContact(pong.Source, packet.Source.IP), true);

                    // pong's direct flag ensures that tcp connection info (especially client ID) is not set with
                    //   information from a pong routed through the remote host, but from the host we're directly connected to
                    if (pong.Direct)
                    {
                        packet.Tcp.UserID = pong.Source.UserID;
                        packet.Tcp.ClientID = pong.Source.ClientID;
                        packet.Tcp.TcpPort = pong.Source.TcpPort;
                        packet.Tcp.UdpPort = pong.Source.UdpPort;

                        // if firewalled
                        if (packet.Tcp.Outbound && packet.Tcp.Proxy == ProxyType.Unset)
                        {
                            if (Core.Firewall != FirewallType.Open && TcpControl.AcceptProxy(ProxyType.Server, pong.Source.UserID))
                            {
                                // send proxy request
                                ProxyReq request = new ProxyReq();
                                request.SenderID = Local.UserID;
                                request.Type = (Core.Firewall == FirewallType.Blocked) ? ProxyType.ClientBlocked : ProxyType.ClientNAT;
                                packet.Tcp.SendPacket(request);
                            }

                            // else ping/pong done, end connect
                            else
                                packet.Tcp.CleanClose("Not in need of a proxy");
                        }
                    }
                }
            }

            // pong received udp or tunneled
            else
            {
                if (validSource)
                {
                    if (Core.Firewall == FirewallType.Blocked && !packet.Tunneled)
                        Core.SetFirewallType(FirewallType.NAT);

                    // add to routing
                    // on startup, especially in sim everyone starts blocked so pong source firewall is not set right, but still needs to go into routing
                    Routing.TryAdd(packet, pong.Source, true);
                }

                // send bootstrap request for nodes if network not responsive
                // do tcp connect because if 2 nodes on network then one needs to find out they're open
                if (!Responsive)
                {
                    Searches.SendRequest(packet.Source, Local.UserID, 0, Core.DhtServiceID, 0, null);

                    if (!packet.Tunneled) // ip isnt set correctly on tunneled, and if tunneled then lookup active and host tested anyways
                        TcpControl.MakeOutbound(packet.Source, pong.Source.TcpPort, "pong bootstrap");
                }

                // forward to proxied nodes, so that their routing tables are up to date, so they can publish easily
                if (Core.Firewall == FirewallType.Open)
                {
                    pong.FromAddress = packet.Source;
                    pong.RemoteIP = null;
                    pong.Direct = false;

                    foreach (TcpConnect connection in TcpControl.ProxyClients)
                        connection.SendPacket(pong);
                }
            }
        }
Exemple #6
0
        void ConnectProxy()
        {
            // Get cloest contacts and sort by distance to us
            DhtContact attempt = null;

            // no Dht contacts, use ip cache will be used to connect tcp/udp in DoBootstrap

            // find if any contacts in list are worth trying (will be skipped if set already)
            // get closest contact that is not already connected
            foreach (DhtContact contact in Network.Routing.NearXor.Contacts)
                // if havent tried in 10 minutes
                if (Core.TimeNow > contact.NextTryProxy && contact.TunnelClient == null)
                {
                    bool connected = false;

                    lock (SocketList)
                        foreach (TcpConnect socket in SocketList)
                            if (contact.UserID == socket.UserID && contact.ClientID == socket.ClientID)
                            {
                                connected = true;
                                break;
                            }

                    if(connected)
                        continue;

                    if (attempt == null || (contact.UserID ^ Network.Local.UserID) < (attempt.UserID ^ Network.Local.UserID))
                        attempt = contact;
                }

            if(attempt != null)
            {
                // take into account when making proxy request, disconnct furthest
                if(Core.Firewall == FirewallType.Blocked)
                {
                    // continue attempted to test nat with pings which are small
                    Network.Send_Ping(attempt);
                    MakeOutbound( attempt, attempt.TcpPort, "try proxy");
                }

                // if natted do udp proxy request first before connect
                else if(Core.Firewall == FirewallType.NAT)
                {
                    ProxyReq request = new ProxyReq();
                    request.SenderID = Network.Local.UserID;
                    request.Type     = ProxyType.ClientNAT;
                    Network.UdpControl.SendTo( attempt, request);
                }

                attempt.NextTryProxy = Core.TimeNow.AddMinutes(10);
            }
        }
Exemple #7
0
        void Receive_Pong(G2ReceivedPacket packet)
        {
            Core.ServiceBandwidth[Core.DhtServiceID].InPerSec += packet.Root.Data.Length;

            Pong pong = Pong.Decode(packet);

            SetLocalIP(pong.RemoteIP, packet);

            bool lanIP       = Utilities.IsLocalIP(packet.Source.IP);
            bool validSource = (!lanIP || LanMode && lanIP);

            // check if remote has a newer version cached
            if (!IsLookup && pong.Version != 0 && Core.Update != null)
            {
                if (Core.Context.SignedUpdate == null ||
                    !Core.Context.SignedUpdate.Loaded ||
                    Core.Context.SignedUpdate.SequentialVersion < pong.Version)
                {
                    // ota update disabled for now
                    //Core.Update.NewVersion(pong.Version, pong.Source.UserID);
                }
            }

            // if received tcp
            if (packet.ReceivedTcp)
            {
                // if regular interval pong
                if (pong.Source == null)
                {
                    // keep routing entry fresh so connect state remains
                    if (validSource && packet.Tcp.Proxy == ProxyType.Server)
                    {
                        Routing.Add(new DhtContact(packet.Tcp, packet.Tcp.RemoteIP), true);
                    }
                }

                // else connect pong with source info
                else
                {
                    // usually a proxied pong from somewhere else to keep our routing fresh
                    if (validSource && pong.Source.Firewall == FirewallType.Open)
                    {
                        Routing.Add(new DhtContact(pong.Source, packet.Source.IP), true);
                    }

                    // pong's direct flag ensures that tcp connection info (especially client ID) is not set with
                    //   information from a pong routed through the remote host, but from the host we're directly connected to
                    if (pong.Direct)
                    {
                        packet.Tcp.UserID   = pong.Source.UserID;
                        packet.Tcp.ClientID = pong.Source.ClientID;
                        packet.Tcp.TcpPort  = pong.Source.TcpPort;
                        packet.Tcp.UdpPort  = pong.Source.UdpPort;

                        // if firewalled
                        if (packet.Tcp.Outbound && packet.Tcp.Proxy == ProxyType.Unset)
                        {
                            if (Core.Firewall != FirewallType.Open && TcpControl.AcceptProxy(ProxyType.Server, pong.Source.UserID))
                            {
                                // send proxy request
                                ProxyReq request = new ProxyReq();
                                request.SenderID = Local.UserID;
                                request.Type     = (Core.Firewall == FirewallType.Blocked) ? ProxyType.ClientBlocked : ProxyType.ClientNAT;
                                packet.Tcp.SendPacket(request);
                            }

                            // else ping/pong done, end connect
                            else
                            {
                                packet.Tcp.CleanClose("Not in need of a proxy");
                            }
                        }
                    }
                }
            }

            // pong received udp or tunneled
            else
            {
                if (validSource)
                {
                    if (Core.Firewall == FirewallType.Blocked && !packet.Tunneled)
                    {
                        Core.SetFirewallType(FirewallType.NAT);
                    }

                    // add to routing
                    // on startup, especially in sim everyone starts blocked so pong source firewall is not set right, but still needs to go into routing
                    Routing.TryAdd(packet, pong.Source, true);
                }

                // send bootstrap request for nodes if network not responsive
                // do tcp connect because if 2 nodes on network then one needs to find out they're open
                if (!Responsive)
                {
                    Searches.SendRequest(packet.Source, Local.UserID, 0, Core.DhtServiceID, 0, null);

                    if (!packet.Tunneled) // ip isnt set correctly on tunneled, and if tunneled then lookup active and host tested anyways
                    {
                        TcpControl.MakeOutbound(packet.Source, pong.Source.TcpPort, "pong bootstrap");
                    }
                }

                // forward to proxied nodes, so that their routing tables are up to date, so they can publish easily
                if (Core.Firewall == FirewallType.Open)
                {
                    pong.FromAddress = packet.Source;
                    pong.RemoteIP    = null;
                    pong.Direct      = false;

                    foreach (TcpConnect connection in TcpControl.ProxyClients)
                    {
                        connection.SendPacket(pong);
                    }
                }
            }
        }