public void InjectSelf() { _Original = this.InjectFunctionPointer<SendToDelegate>(AddressHelper.CodeOffset("gso", 0x1C274), 24); }
public LocalMulticast(int port, Action <TMessage> handler = null, string name = null) { _handler = handler; _name = name ?? String.Empty; var msgSize = TypeHelper <TMessage> .FixedSize; if (msgSize <= 0) { throw new ArgumentException($"Type {typeof(TMessage).Name} must be a blittable struct"); } _bufferLength = msgSize; _sendArgsPool = new ObjectPool <SocketAsyncEventArgs>(SendArgsFactory, 4); var multicastAddress = IPAddress.Parse("239.199.99.9"); _mcEndPoint = new CachedEndPoint(new IPEndPoint(multicastAddress, port)); _inEndPoint = new CachedEndPoint(new IPEndPoint(IPAddress.Loopback, port)); _socket = new Socket(_inEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp); _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); _socket.SetSocketOption(SocketOptionLevel.Udp, SocketOptionName.NoChecksum, 1); _socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 2); _socket.ExclusiveAddressUse = false; _socket.Blocking = true; _socket.EnableBroadcast = true; // Maybe a fluke, bit perf drops and definitely not improves with this: _socket.UseOnlyOverlappedIO = true; _socket.Bind(_inEndPoint); // If you are using a connectionless protocol such as UDP, // you do not have to call Connect before sending and // receiving data. You can use SendTo and ReceiveFrom to // synchronously communicate with a remote host. // If you do call Connect, any datagrams that arrive from // an address other than the specified default will be discarded. // _socket.Connect(_mcEndPoint); _socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, true); // join on loopback interface var mcastOption = new MulticastOption(multicastAddress, NetworkInterface.LoopbackInterfaceIndex); _socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, mcastOption); _socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, #pragma warning disable 618 (int)IPAddress.Loopback.Address); #pragma warning restore 618 // see https://github.com/dotnet/corefx/issues/25699 if there are issues on non-Windows // IPAddress.HostToNetworkOrder(NetworkInterface.LoopbackInterfaceIndex)); // Another option to limit source to loopback //byte[] membershipAddresses = new byte[12]; // 3 IPs * 4 bytes (IPv4) //Buffer.BlockCopy(multicastAddress.GetAddressBytes(), 0, membershipAddresses, 0, 4); //Buffer.BlockCopy(IPAddress.Loopback.GetAddressBytes(), 0, membershipAddresses, 4, 4); //Buffer.BlockCopy(IPAddress.Loopback.GetAddressBytes(), 0, membershipAddresses, 8, 4); //_socket.SetSocketOption(SocketOptionLevel.IP, // SocketOptionName.AddSourceMembership, // membershipAddresses); StartReceive(); #if NETCOREAPP3_0 try { _handle = _socket.SafeHandle; var address = _mcEndPoint.Serialize(); _mcAddressSize = address.Size; _mcAddressBuffer = new byte[_mcAddressSize]; for (int i = 0; i < _mcAddressSize; i++) { _mcAddressBuffer[i] = address[i]; } var assembly = typeof(Socket).Assembly; var socketPalType = assembly.GetTypes().FirstOrDefault(x => x.Name == "SocketPal"); var method = socketPalType?.GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public) .FirstOrDefault(m => m.Name == "SendTo"); _sendToDelegate = Delegate.CreateDelegate(typeof(SendToDelegate), method) as SendToDelegate; } catch { Trace.TraceInformation("Cannot get SocketPal.SendTo method"); } #endif }