Commit a9d1011b authored by Hakan Arıcı's avatar Hakan Arıcı

IPv6 support is added to finding PID from port mechanism.

parent 12814410
......@@ -15,9 +15,16 @@ using Titanium.Web.Proxy.Tcp;
namespace Titanium.Web.Proxy.Helpers
{
internal enum IpVersion
{
Ipv4 = 1,
Ipv6 = 2,
}
internal partial class NativeMethods
{
internal const int AfInet = 2;
internal const int AfInet6 = 23;
internal enum TcpTableType
{
......@@ -75,19 +82,21 @@ namespace Titanium.Web.Proxy.Helpers
/// Gets the extended TCP table.
/// </summary>
/// <returns>Collection of <see cref="TcpRow"/>.</returns>
internal static TcpTable GetExtendedTcpTable()
internal static TcpTable GetExtendedTcpTable(IpVersion ipVersion)
{
List<TcpRow> tcpRows = new List<TcpRow>();
IntPtr tcpTable = IntPtr.Zero;
int tcpTableLength = 0;
if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, false, NativeMethods.AfInet, (int)NativeMethods.TcpTableType.OwnerPidAll, 0) != 0)
var ipVersionValue = ipVersion == IpVersion.Ipv4 ? NativeMethods.AfInet : NativeMethods.AfInet6;
if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, false, ipVersionValue, (int)NativeMethods.TcpTableType.OwnerPidAll, 0) != 0)
{
try
{
tcpTable = Marshal.AllocHGlobal(tcpTableLength);
if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, NativeMethods.AfInet, (int)NativeMethods.TcpTableType.OwnerPidAll, 0) == 0)
if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, ipVersionValue, (int)NativeMethods.TcpTableType.OwnerPidAll, 0) == 0)
{
NativeMethods.TcpTable table = (NativeMethods.TcpTable)Marshal.PtrToStructure(tcpTable, typeof(NativeMethods.TcpTable));
......
......@@ -20,6 +20,10 @@ namespace Titanium.Web.Proxy.Models
public int Port { get; internal set; }
public bool EnableSsl { get; internal set; }
public bool IpV6Enabled => IpAddress == IPAddress.IPv6Any
|| IpAddress == IPAddress.IPv6Loopback
|| IpAddress == IPAddress.IPv6None;
internal TcpListener listener { get; set; }
}
......
......@@ -16,7 +16,6 @@ using Titanium.Web.Proxy.Shared;
using Titanium.Web.Proxy.Http;
using System.Threading.Tasks;
using Titanium.Web.Proxy.Extensions;
using System.Text;
namespace Titanium.Web.Proxy
{
......@@ -25,15 +24,31 @@ namespace Titanium.Web.Proxy
/// </summary>
partial class ProxyServer
{
private int FindProcessIdFromLocalPort(int port, IpVersion ipVersion)
{
var tcpRow = TcpHelper.GetExtendedTcpTable(ipVersion).FirstOrDefault(
row => row.LocalEndPoint.Port == port);
return tcpRow?.ProcessId ?? 0;
}
private int GetProcessIdFromPort(int port, bool ipV6Enabled)
{
var processId = FindProcessIdFromLocalPort(port, IpVersion.Ipv4);
if (processId > 0 && !ipV6Enabled)
{
return processId;
}
return FindProcessIdFromLocalPort(port, IpVersion.Ipv6);
}
//This is called when client is aware of proxy
//So for HTTPS requests client would send CONNECT header to negotiate a secure tcp tunnel via proxy
private async Task HandleClient(ExplicitProxyEndPoint endPoint, TcpClient tcpClient)
{
var tcpRow = TcpHelper.GetExtendedTcpTable().FirstOrDefault(
row => row.LocalEndPoint.Port == ((IPEndPoint) tcpClient.Client.RemoteEndPoint).Port);
var processId = tcpRow?.ProcessId ?? 0;
var processId = GetProcessIdFromPort(((IPEndPoint)tcpClient.Client.RemoteEndPoint).Port, endPoint.IpV6Enabled);
Stream clientStream = tcpClient.GetStream();
......@@ -175,10 +190,7 @@ namespace Titanium.Web.Proxy
//So for HTTPS requests we would start SSL negotiation right away without expecting a CONNECT request from client
private async Task HandleClient(TransparentProxyEndPoint endPoint, TcpClient tcpClient)
{
var tcpRow = TcpHelper.GetExtendedTcpTable().FirstOrDefault(
row => row.LocalEndPoint.Port == ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Port);
var processId = tcpRow?.ProcessId ?? 0;
var processId = GetProcessIdFromPort(((IPEndPoint)tcpClient.Client.RemoteEndPoint).Port, endPoint.IpV6Enabled);
Stream clientStream = tcpClient.GetStream();
......@@ -230,7 +242,6 @@ namespace Titanium.Web.Proxy
endPoint.EnableSsl ? endPoint.GenericCertificateName : null, null);
}
private async Task HandleHttpSessionRequestInternal(TcpConnection connection, SessionEventArgs args, ExternalProxy customUpStreamHttpProxy, ExternalProxy customUpStreamHttpsProxy, bool CloseConnection)
{
try
......@@ -357,6 +368,7 @@ namespace Titanium.Web.Proxy
connection.Dispose();
}
}
/// <summary>
/// This is the core request handler method for a particular connection from client
/// </summary>
......@@ -568,7 +580,6 @@ namespace Titanium.Web.Proxy
webRequest.Request.RequestHeaders = requestHeaders;
}
/// <summary>
/// This is called when the request is PUT/POST to read the body
/// </summary>
......@@ -590,9 +601,7 @@ namespace Titanium.Web.Proxy
else if (args.WebSession.Request.IsChunked)
{
await args.ProxyClient.ClientStreamReader.CopyBytesToStreamChunked(BUFFER_SIZE, postStream);
}
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment