public bool SendPacket(G2Packet packet) { if (Core.InvokeRequired) { Debug.Assert(false); } byte[] final = packet.Encode(Network.Protocol); if (Comm.State != RudpState.Connected) { return(false); } PacketLogEntry logEntry = new PacketLogEntry(Core.TimeNow, TransportProtocol.Rudp, DirectionType.Out, Comm.PrimaryAddress.Address, final); Core.Network.LogPacket(logEntry); // dont worry about buffers, cause initial comm buffer is large enough to fit all negotiating packets if (SendEncryptor == null) { int length = final.Length; Comm.Send(final, ref length); return(true); } // goal - dont fill encrypt buffer because it will block stuff like pings during transfers // use as temp, return failed if no room if (SendBuffer == null) { SendBuffer = new byte[BUFF_SIZE]; } if (EncryptBuffer == null) { EncryptBuffer = new byte[BUFF_SIZE]; } LastSends.Enqueue(new Tuple <int, int>(EncryptBuffSize, final.Length)); if (LastSends.Count > 100) { LastSends.Dequeue(); } // ensure enough space in encrypt buff for packet and expedite packets if (BUFF_SIZE - EncryptBuffSize < final.Length + 128) { throw new Exception("Packet Dropped"); } // encode put into send buff lock (SendBuffer) { final.CopyTo(SendBuffer, SendBuffSize); SendBuffSize += final.Length; } return(FlushSend()); // return true if room in comm buffer }
public void SendTo(G2Packet packet) { if (Core.InvokeRequired) { Debug.Assert(false); } if (packet is NetworkPacket) { ((NetworkPacket)packet).SourceID = Network.Local.UserID; ((NetworkPacket)packet).ClientID = Network.Local.ClientID; } byte[] encoded = packet.Encode(Network.Protocol); PacketLogEntry logEntry = new PacketLogEntry(Core.TimeNow, TransportProtocol.LAN, DirectionType.Out, null, encoded); Network.LogPacket(logEntry); byte[] final = null; // encrypt, turn off encryption during simulation if (Core.Sim == null || Core.Sim.Internet.TestEncryption) { final = Utilities.EncryptBytes(encoded, Network.OpCrypt.Key); } else { final = encoded; } // send try { if (Core.Sim != null) { //Core.Sim.Internet.SendPacket(SimPacketType.Udp, Network, final, address.ToEndPoint(), null); return; } if (LanSocket == null) { return; } if (encoded.Length > MAX_UDP_SIZE) { throw new Exception("Packet larger than " + MAX_UDP_SIZE.ToString() + " bytes"); } EndPoint tempSender = (EndPoint) new IPEndPoint(IPAddress.Broadcast, ListenPort); LanSocket.BeginSendTo(final, 0, final.Length, SocketFlags.None, tempSender, new AsyncCallback(UdpSocket_SendTo), LanSocket); } catch (Exception ex) { Network.UpdateLog("Exception", "LanHandler::SendTo: " + ex.Message); } }
public bool SendData(uint service, uint datatype, G2Packet packet) { CommData data = new CommData(service, datatype, packet.Encode(Network.Protocol)); Core.ServiceBandwidth[service].OutPerSec += data.Data.Length; return(SendPacket(data)); }
RudpPacket CreateRudpPacket(DhtClient client, uint service, int type, G2Packet packet, bool reliable) { RudpPacket comm = new RudpPacket(); comm.SenderID = Network.Local.UserID; comm.SenderClient = Network.Local.ClientID; comm.TargetID = client.UserID; comm.TargetClient = client.ClientID; comm.PacketType = RudpPacketType.Light; comm.Payload = RudpLight.Encode(service, type, packet.Encode(Network.Protocol)); if (reliable) { comm.PeerID = (ushort)Core.RndGen.Next(ushort.MaxValue); // used to ack comm.Sequence = 1; } return(comm); }
public void SendUnreliable(uint service, uint type, G2Packet packet) { // fast, secure, out-of-band method of sending data // useful for things like VOIP during a file transfer with host // data has got to go out asap, no matter what // check rudp socket is connected if (Status != SessionStatus.Active) { return; } // add to special rudp packet RudpPacket rudp = new RudpPacket(); rudp.SenderID = Network.Local.UserID; rudp.SenderClient = Network.Local.ClientID; rudp.TargetID = UserID; rudp.TargetClient = ClientID; rudp.PeerID = Comm.RemotePeerID; rudp.PacketType = RudpPacketType.Unreliable; CommData data = new CommData(service, type, packet.Encode(Network.Protocol)); rudp.Payload = Utilities.EncryptBytes(data.Encode(Network.Protocol), OutboundEnc.Key); // send Comm.SendPacket(rudp, Comm.PrimaryAddress); // stats Core.ServiceBandwidth[service].OutPerSec += data.Data.Length; PacketLogEntry logEntry = new PacketLogEntry(Core.TimeNow, TransportProtocol.Rudp, DirectionType.Out, Comm.PrimaryAddress.Address, rudp.Payload); Core.Network.LogPacket(logEntry); }
public int SendTo(DhtAddress address, G2Packet packet) { if (Core.InvokeRequired) { Debug.Assert(false); } Debug.Assert(address.UdpPort != 0); if (packet is NetworkPacket) { ((NetworkPacket)packet).SourceID = Network.Local.UserID; ((NetworkPacket)packet).ClientID = Network.Local.ClientID; } byte[] encoded = packet.Encode(Network.Protocol); PacketLogEntry logEntry = new PacketLogEntry(Core.TimeNow, TransportProtocol.Udp, DirectionType.Out, address, encoded); Network.LogPacket(logEntry); byte[] final = null; // encrypt, turn off encryption during simulation if (Core.Sim == null || Core.Sim.Internet.TestEncryption) { final = Utilities.EncryptBytes(encoded, Network.GetAugmentedKey(address.UserID)); } else { final = encoded; } // send try { if (Core.Sim != null) { Core.Sim.Internet.SendPacket(SimPacketType.Udp, Network, final, address.ToEndPoint(), null); } else { if (UdpSocket == null) { return(0); } if (encoded.Length > MAX_UDP_SIZE) { throw new Exception("Packet larger than " + MAX_UDP_SIZE.ToString() + " bytes"); } UdpSocket.BeginSendTo(final, 0, final.Length, SocketFlags.None, address.ToEndPoint(), new AsyncCallback(UdpSocket_SendTo), UdpSocket); } // record bandwidth Bandwidth.OutPerSec += final.Length; return(final.Length); } catch (Exception ex) { Network.UpdateLog("Exception", "UdpHandler::SendTo: " + ex.Message); } return(0); }
public int SendPacket(G2Packet packet) { if (Core.InvokeRequired) { Debug.Assert(false); } if (State != TcpState.Connected) { return(0); } // usually when an inbound connection (dont know remote userId) is determined to be a loopback, we close the connection // even before the userId is set, if the userId is not set then the encryptor cant be init'd to send the 'close' packet if (UserID == 0) { return(0); } if (Core.Sim == null || Core.Sim.Internet.TestEncryption) { if (Encryptor == null) { CreateEncryptor(); } } try { if (packet is NetworkPacket) { ((NetworkPacket)packet).SourceID = Network.Local.UserID; ((NetworkPacket)packet).ClientID = Network.Local.ClientID; } byte[] encoded = packet.Encode(Network.Protocol); PacketLogEntry logEntry = new PacketLogEntry(Core.TimeNow, TransportProtocol.Tcp, DirectionType.Out, new DhtAddress(RemoteIP, this), encoded); Network.LogPacket(logEntry); lock (FinalSendBuffer) { // fill up final buffer, keep encrypt buffer clear if (BUFF_SIZE - FinalSendBuffSize < encoded.Length + 128) { throw new Exception("SendBuff Full"); //crit check packet log } // encrypt, turn off encryption during simulation if (Core.Sim == null || Core.Sim.Internet.TestEncryption) { encoded.CopyTo(SendBuffer, SendBuffSize); SendBuffSize += encoded.Length; int remainder = SendBuffSize % Encryptor.InputBlockSize; if (remainder > 0) { CryptPadding padding = new CryptPadding(); int fillerNeeded = Encryptor.InputBlockSize - remainder; if (fillerNeeded > 2) { padding.Filler = new byte[fillerNeeded - 2]; } encoded = padding.Encode(Network.Protocol); encoded.CopyTo(SendBuffer, SendBuffSize); SendBuffSize += encoded.Length; } int tryTransform = SendBuffSize - (SendBuffSize % Encryptor.InputBlockSize); if (tryTransform == 0) { return(0); } int tranformed = Encryptor.TransformBlock(SendBuffer, 0, tryTransform, FinalSendBuffer, FinalSendBuffSize); if (tranformed == 0) { return(0); } FinalSendBuffSize += tranformed; SendBuffSize -= tranformed; Buffer.BlockCopy(SendBuffer, tranformed, SendBuffer, 0, SendBuffSize); } else { encoded.CopyTo(FinalSendBuffer, FinalSendBuffSize); FinalSendBuffSize += encoded.Length; } } TrySend(); // record bandwidth return(encoded.Length); } catch (Exception ex) { LogException("SendPacket", ex.Message); } return(0); }
public SignedData(G2Protocol protocol, RSACryptoServiceProvider key, G2Packet packet) { Data = packet.Encode(protocol); Signature = key.SignData(Data, new SHA1CryptoServiceProvider()); }
public static byte[] Encode(G2Protocol protocol, RSACryptoServiceProvider key, G2Packet packet) { byte[] data = packet.Encode(protocol); return(Encode(protocol, key, data)); }
// 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); }