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