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; ...@@ -15,9 +15,16 @@ using Titanium.Web.Proxy.Tcp;
namespace Titanium.Web.Proxy.Helpers namespace Titanium.Web.Proxy.Helpers
{ {
internal enum IpVersion
{
Ipv4 = 1,
Ipv6 = 2,
}
internal partial class NativeMethods internal partial class NativeMethods
{ {
internal const int AfInet = 2; internal const int AfInet = 2;
internal const int AfInet6 = 23;
internal enum TcpTableType internal enum TcpTableType
{ {
...@@ -75,19 +82,21 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -75,19 +82,21 @@ namespace Titanium.Web.Proxy.Helpers
/// Gets the extended TCP table. /// Gets the extended TCP table.
/// </summary> /// </summary>
/// <returns>Collection of <see cref="TcpRow"/>.</returns> /// <returns>Collection of <see cref="TcpRow"/>.</returns>
internal static TcpTable GetExtendedTcpTable() internal static TcpTable GetExtendedTcpTable(IpVersion ipVersion)
{ {
List<TcpRow> tcpRows = new List<TcpRow>(); List<TcpRow> tcpRows = new List<TcpRow>();
IntPtr tcpTable = IntPtr.Zero; IntPtr tcpTable = IntPtr.Zero;
int tcpTableLength = 0; 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 try
{ {
tcpTable = Marshal.AllocHGlobal(tcpTableLength); 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)); NativeMethods.TcpTable table = (NativeMethods.TcpTable)Marshal.PtrToStructure(tcpTable, typeof(NativeMethods.TcpTable));
......
...@@ -20,6 +20,10 @@ namespace Titanium.Web.Proxy.Models ...@@ -20,6 +20,10 @@ namespace Titanium.Web.Proxy.Models
public int Port { get; internal set; } public int Port { get; internal set; }
public bool EnableSsl { 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; } internal TcpListener listener { get; set; }
} }
......
...@@ -16,7 +16,6 @@ using Titanium.Web.Proxy.Shared; ...@@ -16,7 +16,6 @@ using Titanium.Web.Proxy.Shared;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using System.Text;
namespace Titanium.Web.Proxy namespace Titanium.Web.Proxy
{ {
...@@ -25,15 +24,31 @@ namespace Titanium.Web.Proxy ...@@ -25,15 +24,31 @@ namespace Titanium.Web.Proxy
/// </summary> /// </summary>
partial class ProxyServer 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 //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 //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) private async Task HandleClient(ExplicitProxyEndPoint endPoint, TcpClient tcpClient)
{ {
var tcpRow = TcpHelper.GetExtendedTcpTable().FirstOrDefault( var processId = GetProcessIdFromPort(((IPEndPoint)tcpClient.Client.RemoteEndPoint).Port, endPoint.IpV6Enabled);
row => row.LocalEndPoint.Port == ((IPEndPoint) tcpClient.Client.RemoteEndPoint).Port);
var processId = tcpRow?.ProcessId ?? 0;
Stream clientStream = tcpClient.GetStream(); Stream clientStream = tcpClient.GetStream();
...@@ -175,10 +190,7 @@ namespace Titanium.Web.Proxy ...@@ -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 //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) private async Task HandleClient(TransparentProxyEndPoint endPoint, TcpClient tcpClient)
{ {
var tcpRow = TcpHelper.GetExtendedTcpTable().FirstOrDefault( var processId = GetProcessIdFromPort(((IPEndPoint)tcpClient.Client.RemoteEndPoint).Port, endPoint.IpV6Enabled);
row => row.LocalEndPoint.Port == ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Port);
var processId = tcpRow?.ProcessId ?? 0;
Stream clientStream = tcpClient.GetStream(); Stream clientStream = tcpClient.GetStream();
...@@ -230,7 +242,6 @@ namespace Titanium.Web.Proxy ...@@ -230,7 +242,6 @@ namespace Titanium.Web.Proxy
endPoint.EnableSsl ? endPoint.GenericCertificateName : null, null); endPoint.EnableSsl ? endPoint.GenericCertificateName : null, null);
} }
private async Task HandleHttpSessionRequestInternal(TcpConnection connection, SessionEventArgs args, ExternalProxy customUpStreamHttpProxy, ExternalProxy customUpStreamHttpsProxy, bool CloseConnection) private async Task HandleHttpSessionRequestInternal(TcpConnection connection, SessionEventArgs args, ExternalProxy customUpStreamHttpProxy, ExternalProxy customUpStreamHttpsProxy, bool CloseConnection)
{ {
try try
...@@ -357,6 +368,7 @@ namespace Titanium.Web.Proxy ...@@ -357,6 +368,7 @@ namespace Titanium.Web.Proxy
connection.Dispose(); connection.Dispose();
} }
} }
/// <summary> /// <summary>
/// This is the core request handler method for a particular connection from client /// This is the core request handler method for a particular connection from client
/// </summary> /// </summary>
...@@ -568,7 +580,6 @@ namespace Titanium.Web.Proxy ...@@ -568,7 +580,6 @@ namespace Titanium.Web.Proxy
webRequest.Request.RequestHeaders = requestHeaders; webRequest.Request.RequestHeaders = requestHeaders;
} }
/// <summary> /// <summary>
/// This is called when the request is PUT/POST to read the body /// This is called when the request is PUT/POST to read the body
/// </summary> /// </summary>
...@@ -590,9 +601,7 @@ namespace Titanium.Web.Proxy ...@@ -590,9 +601,7 @@ namespace Titanium.Web.Proxy
else if (args.WebSession.Request.IsChunked) else if (args.WebSession.Request.IsChunked)
{ {
await args.ProxyClient.ClientStreamReader.CopyBytesToStreamChunked(BUFFER_SIZE, postStream); 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