Beispiel #1
0
 /// <summary>
 /// 将buffer的前3个字节,解析到 TunnelPacket 中
 /// </summary>
 /// <param name="buffer"></param>
 /// <param name="offset"></param>
 /// <param name="packet"></param>
 public static void Deserialize(byte[] buffer, TunnelPacket packet)
 {
     packet.Length  = ((buffer[1] & 0x3f) << 8) | buffer[2];
     packet.Type    = (TunnelPacketType)((buffer[1] >> 6) | (buffer[0] & 1) << 2);
     packet.Version = (0x7 & (buffer[0] >> 1));
     packet.Magic   = buffer[0] >> 4;
 }
Beispiel #2
0
 /// <summary>
 /// 将buffer的前3个字节,解析到 TunnelPacket 中
 /// </summary>
 /// <param name="buffer"></param>
 /// <param name="offset"></param>
 /// <param name="tunnelPacket"></param>
 public static void Deserialize(byte[] buffer, TunnelPacket tunnelPacket)
 {
     ((IPacket)tunnelPacket).Reuse(((buffer[1] & 0x3f) << 8) | buffer[2]);
     tunnelPacket.Type    = (TunnelPacketType)((buffer[1] >> 6) | (buffer[0] & 1) << 2);
     tunnelPacket.Version = (0x7 & (buffer[0] >> 1));
     tunnelPacket.Magic   = buffer[0] >> 4;
 }
Beispiel #3
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);
            }
        }
Beispiel #4
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 #5
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);
            }
        }
Beispiel #6
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 #7
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);
                }
            }
        }