Enable TCP_NODELAY and TCP_QUICKACK (#8)

Enable TCP_NODELAY and TCP_QUICKACK
This commit is contained in:
goaaats 2019-11-18 20:33:44 +09:00 committed by GitHub
commit 94d519b994
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 70 additions and 9 deletions

View file

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Target">
<PlatformTarget>AnyCPU</PlatformTarget>
<TargetFramework>net471</TargetFramework>
<LangVersion>7.2</LangVersion>
<TargetFramework>net48</TargetFramework>
<LangVersion>8.0</LangVersion>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<PropertyGroup Label="Build">
@ -26,4 +26,4 @@
<ItemGroup>
<ProjectReference Include="..\Dalamud\Dalamud.csproj" />
</ItemGroup>
</Project>
</Project>

View file

@ -46,6 +46,8 @@ namespace Dalamud {
public readonly DalamudConfiguration Configuration;
internal readonly WinSockHandlers WinSock2;
public Dalamud(DalamudStartInfo info) {
this.StartInfo = info;
this.Configuration = DalamudConfiguration.Load(info.ConfigurationPath);
@ -75,7 +77,9 @@ namespace Dalamud {
this.PluginManager = new PluginManager(this, info.PluginDirectory, info.DefaultPluginDirectory);
this.IconReplacer = new IconReplacer(this, this.sigScanner);
this.WinSock2 = new WinSockHandlers();
try {
this.PluginManager.LoadPlugins();
} catch (Exception ex) {
@ -109,6 +113,8 @@ namespace Dalamud {
this.unloadSignal.Dispose();
this.WinSock2.Dispose();
if (this.Configuration.ComboPresets != CustomComboPreset.None)
this.IconReplacer.Dispose();
}

View file

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Target">
<PlatformTarget>AnyCPU</PlatformTarget>
<TargetFramework>net471</TargetFramework>
<LangVersion>7.3</LangVersion>
<TargetFramework>net48</TargetFramework>
<LangVersion>8.0</LangVersion>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<PropertyGroup Label="Build">
@ -68,4 +68,4 @@
<ItemGroup>
<Folder Include="Configuration\" />
</ItemGroup>
</Project>
</Project>

View file

@ -0,0 +1,55 @@
using Dalamud.Hooking;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Dalamud.Game
{
internal sealed class WinSockHandlers : IDisposable
{
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
private delegate IntPtr SocketDelegate(int af, int type, int protocol);
private Hook<SocketDelegate> ws2SocketHook;
[DllImport("ws2_32.dll", CallingConvention = CallingConvention.Winapi)]
private static extern int setsockopt(IntPtr socket, SocketOptionLevel level, SocketOptionName optName, ref IntPtr optVal, int optLen);
public WinSockHandlers() {
ws2SocketHook = Hook<SocketDelegate>.FromSymbol("ws2_32.dll", "socket", new SocketDelegate(OnSocket));
ws2SocketHook.Enable();
}
private IntPtr OnSocket(int af, int type, int protocol)
{
var socket = ws2SocketHook.Original(af, type, protocol);
// IPPROTO_TCP
if (type == 1)
{
// INVALID_SOCKET
if (socket != new IntPtr(-1))
{
// In case you're not aware of it: (albeit you should)
// https://linux.die.net/man/7/tcp
// https://assets.extrahop.com/whitepapers/TCP-Optimization-Guide-by-ExtraHop.pdf
var value = new IntPtr(1);
setsockopt(socket, SocketOptionLevel.Tcp, SocketOptionName.NoDelay, ref value, 4);
// Enable tcp_quickack option. This option is undocumented in MSDN but it is supported in Windows 7 and onwards.
value = new IntPtr(1);
setsockopt(socket, SocketOptionLevel.Tcp, (SocketOptionName)12, ref value, 4);
}
}
return socket;
}
public void Dispose() {
ws2SocketHook.Dispose();
}
}
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using EasyHook;
@ -9,7 +9,7 @@ namespace Dalamud.Hooking {
/// This class is basically a thin wrapper around the LocalHook type to provide helper functions.
/// </summary>
/// <typeparam name="T">Delegate type to represents a function prototype. This must be the same prototype as original function do.</typeparam>
public sealed class Hook<T> : IDisposable where T : class {
public sealed class Hook<T> : IDisposable where T : Delegate {
private bool isDisposed;
private readonly IntPtr address;