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(); } }
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); } } }
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); } }
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); } }
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); } } }
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); } }
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); } } } }