Compare commits

..

10 Commits

Author SHA1 Message Date
老九
7765bc0862
Update README.md 2022-12-07 08:24:48 +08:00
xljiulang
65b5f8aa35 优化代理请求解析 2022-12-06 21:38:09 +08:00
xljiulang
849058bd9f 更新 WindivertDotnet 2022-12-03 13:20:01 +08:00
xljiulang
9f9cbce624 简化packet修改 2022-10-28 21:41:01 +08:00
陈国伟
7c203971c1 使用Writer写入数据 2022-10-20 10:45:46 +08:00
xljiulang
1d177f6aba 使用CalcOutboundFlag 2022-10-17 20:25:54 +08:00
xljiulang
81c6ebd583 应用cancellationToken 2022-10-16 18:47:26 +08:00
陈国伟
c7384ac5ef update WindivertDotnet 2022-10-14 16:29:54 +08:00
陈国伟
d5b0809e0c WindivertDotnet1.0 2022-10-13 17:00:42 +08:00
陈国伟
aa99fdafac WindivertDotnet异步 2022-10-13 12:28:18 +08:00
5 changed files with 75 additions and 106 deletions

View File

@ -26,56 +26,77 @@ namespace FastGithub.HttpServer.TcpMiddlewares
/// <returns></returns>
public async Task InvokeAsync(ConnectionDelegate next, ConnectionContext context)
{
var result = await context.Transport.Input.ReadAsync();
var httpRequest = this.GetHttpRequestHandler(result, out var consumed);
var input = context.Transport.Input;
var output = context.Transport.Output;
var request = new HttpRequestHandler();
// 协议错误
if (consumed == 0L)
while (context.ConnectionClosed.IsCancellationRequested == false)
{
await context.Transport.Output.WriteAsync(this.http400, context.ConnectionClosed);
}
else
{
// 隧道代理连接请求
if (httpRequest.ProxyProtocol == ProxyProtocol.TunnelProxy)
var result = await input.ReadAsync();
if (result.IsCanceled)
{
var position = result.Buffer.GetPosition(consumed);
context.Transport.Input.AdvanceTo(position);
await context.Transport.Output.WriteAsync(this.http200, context.ConnectionClosed);
}
else
{
var position = result.Buffer.Start;
context.Transport.Input.AdvanceTo(position);
break;
}
context.Features.Set<IHttpProxyFeature>(httpRequest);
await next(context);
try
{
if (this.ParseRequest(result, request, out var consumed))
{
if (request.ProxyProtocol == ProxyProtocol.TunnelProxy)
{
input.AdvanceTo(consumed);
await output.WriteAsync(this.http200, context.ConnectionClosed);
}
else
{
input.AdvanceTo(result.Buffer.Start);
}
context.Features.Set<IHttpProxyFeature>(request);
await next(context);
break;
}
else
{
input.AdvanceTo(result.Buffer.Start, result.Buffer.End);
}
if (result.IsCompleted)
{
break;
}
}
catch (Exception)
{
await output.WriteAsync(this.http400, context.ConnectionClosed);
break;
}
}
}
/// <summary>
/// 获取http请求处理者
/// 解析http请求
/// </summary>
/// <param name="result"></param>
/// <param name="requestHandler"></param>
/// <param name="consumed"></param>
/// <returns></returns>
private HttpRequestHandler GetHttpRequestHandler(ReadResult result, out long consumed)
private bool ParseRequest(ReadResult result, HttpRequestHandler request, out SequencePosition consumed)
{
var handler = new HttpRequestHandler();
var reader = new SequenceReader<byte>(result.Buffer);
if (this.httpParser.ParseRequestLine(handler, ref reader) &&
this.httpParser.ParseHeaders(handler, ref reader))
if (this.httpParser.ParseRequestLine(request, ref reader) &&
this.httpParser.ParseHeaders(request, ref reader))
{
consumed = reader.Consumed;
consumed = reader.Position;
return true;
}
else
{
consumed = 0L;
consumed = default;
return false;
}
return handler;
}

View File

@ -60,25 +60,19 @@ namespace FastGithub.PacketIntercept.Dns
/// <returns></returns>
public async Task InterceptAsync(CancellationToken cancellationToken)
{
await Task.Yield();
using var divert = new WinDivert(filter, WinDivertLayer.Network);
cancellationToken.Register(d =>
{
((WinDivert)d!).Dispose();
DnsFlushResolverCache();
}, divert);
var addr = new WinDivertAddress();
using var packet = new WinDivertPacket();
using var addr = new WinDivertAddress();
DnsFlushResolverCache();
cancellationToken.Register(DnsFlushResolverCache);
while (cancellationToken.IsCancellationRequested == false)
{
divert.Recv(packet, ref addr);
await divert.RecvAsync(packet, addr, cancellationToken);
try
{
this.ModifyDnsPacket(packet, ref addr);
this.ModifyDnsPacket(packet, addr);
}
catch (Exception ex)
{
@ -86,7 +80,7 @@ namespace FastGithub.PacketIntercept.Dns
}
finally
{
divert.Send(packet, ref addr);
await divert.SendAsync(packet, addr, cancellationToken);
}
}
}
@ -96,7 +90,7 @@ namespace FastGithub.PacketIntercept.Dns
/// </summary>
/// <param name="packet"></param>
/// <param name="addr"></param>
unsafe private void ModifyDnsPacket(WinDivertPacket packet, ref WinDivertAddress addr)
unsafe private void ModifyDnsPacket(WinDivertPacket packet, WinDivertAddress addr)
{
var result = packet.GetParseResult();
var requestPayload = result.DataSpan.ToArray();
@ -125,46 +119,17 @@ namespace FastGithub.PacketIntercept.Dns
var loopback = question.Type == RecordType.A ? IPAddress.Loopback : IPAddress.IPv6Loopback;
var record = new IPAddressResourceRecord(domain, loopback, this.ttl);
response.AnswerRecords.Add(record);
var responsePayload = response.ToArray();
// 修改payload和包长
responsePayload.CopyTo(new Span<byte>(result.Data, responsePayload.Length));
packet.Length = packet.Length + responsePayload.Length - requestPayload.Length;
// 修改payload
var writer = packet.GetWriter(packet.Length - result.DataLength);
writer.Write(response.ToArray());
// 修改ip包
IPAddress destAddress;
if (result.IPV4Header != null)
{
destAddress = result.IPV4Header->DstAddr;
result.IPV4Header->DstAddr = result.IPV4Header->SrcAddr;
result.IPV4Header->SrcAddr = destAddress;
result.IPV4Header->Length = (ushort)packet.Length;
}
else
{
destAddress = result.IPV6Header->DstAddr;
result.IPV6Header->DstAddr = result.IPV6Header->SrcAddr;
result.IPV6Header->SrcAddr = destAddress;
result.IPV6Header->Length = (ushort)(packet.Length - sizeof(IPV6Header));
}
// 修改udp包
var destPort = result.UdpHeader->DstPort;
result.UdpHeader->DstPort = result.UdpHeader->SrcPort;
result.UdpHeader->SrcPort = destPort;
result.UdpHeader->Length = (ushort)(sizeof(UdpHeader) + responsePayload.Length);
packet.ReverseEndPoint();
packet.ApplyLengthToHeaders();
packet.CalcChecksums(addr);
packet.CalcOutboundFlag(addr);
addr.Flags |= WinDivertAddressFlag.Impostor;
if (addr.Flags.HasFlag(WinDivertAddressFlag.Loopback))
{
addr.Flags |= WinDivertAddressFlag.Outbound;
}
else
{
addr.Flags ^= WinDivertAddressFlag.Outbound;
}
packet.CalcChecksums(ref addr);
this.logger.LogInformation($"{domain}->{loopback}");
}

View File

@ -7,7 +7,7 @@
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="DNS" Version="7.0.0" />
<PackageReference Include="WindivertDotnet" Version="1.0.0-beta2" />
<PackageReference Include="WindivertDotnet" Version="1.1.2" />
</ItemGroup>
<ItemGroup>

View File

@ -50,9 +50,10 @@ namespace FastGithub.PacketIntercept.Tcp
return;
}
await Task.Yield();
using var divert = new WinDivert(this.filter, WinDivertLayer.Network);
using var packet = new WinDivertPacket();
using var addr = new WinDivertAddress();
using var divert = new WinDivert(this.filter, WinDivertLayer.Network, 0, WinDivertFlag.None);
if (Socket.OSSupportsIPv4)
{
this.logger.LogInformation($"{IPAddress.Loopback}:{this.oldServerPort} <=> {IPAddress.Loopback}:{this.newServerPort}");
@ -61,18 +62,13 @@ namespace FastGithub.PacketIntercept.Tcp
{
this.logger.LogInformation($"{IPAddress.IPv6Loopback}:{this.oldServerPort} <=> {IPAddress.IPv6Loopback}:{this.newServerPort}");
}
cancellationToken.Register(d => ((WinDivert)d!).Dispose(), divert);
var addr = new WinDivertAddress();
using var packet = new WinDivertPacket();
while (cancellationToken.IsCancellationRequested == false)
{
addr.Clear();
divert.Recv(packet, ref addr);
await divert.RecvAsync(packet, addr, cancellationToken);
try
{
this.ModifyTcpPacket(packet, ref addr);
this.ModifyTcpPacket(packet, addr);
}
catch (Exception ex)
{
@ -80,7 +76,7 @@ namespace FastGithub.PacketIntercept.Tcp
}
finally
{
divert.Send(packet, ref addr);
await divert.SendAsync(packet, addr, cancellationToken);
}
}
}
@ -90,18 +86,9 @@ namespace FastGithub.PacketIntercept.Tcp
/// </summary>
/// <param name="packet"></param>
/// <param name="addr"></param>
unsafe private void ModifyTcpPacket(WinDivertPacket packet, ref WinDivertAddress addr)
unsafe private void ModifyTcpPacket(WinDivertPacket packet, WinDivertAddress addr)
{
var result = packet.GetParseResult();
if (result.IPV4Header != null && result.IPV4Header->SrcAddr.Equals(IPAddress.Loopback) == false)
{
return;
}
if (result.IPV6Header != null && result.IPV6Header->SrcAddr.Equals(IPAddress.IPv6Loopback) == false)
{
return;
}
if (result.TcpHeader->DstPort == oldServerPort)
{
result.TcpHeader->DstPort = this.newServerPort;
@ -111,7 +98,7 @@ namespace FastGithub.PacketIntercept.Tcp
result.TcpHeader->SrcPort = oldServerPort;
}
addr.Flags |= WinDivertAddressFlag.Impostor;
packet.CalcChecksums(ref addr);
packet.CalcChecksums(addr);
}
}
}

View File

@ -1,15 +1,11 @@
# FastGithub
github加速神器解决github打不开、用户头像无法加载、releases无法上传下载、git-clone、git-pull、git-push失败等问题。
### 0 写在前面
### 1 写在前面
* **fastgithub不具备“翻墙”功能,也没有相关的计划**
* **fastgithub不支持Windows7等已被发行方停止支持的操作系统并且也不会主动提供支持**
* **fastgithub不能为您的游戏加速**
* **fastgithub没有主动在github和fastgithub@qq.com之外的任何渠道发布**
### 1 程序下载
* [github-release下载](https://github.com/dotnetcore/fastgithub/releases)
* 发送任意邮件到fastgithub@qq.com
* **fastgithub没有主动在github之外的任何渠道发布**
### 2 部署方式
#### 2.1 windows-x64桌面