public static IPEndPoint GetServerUdpListener(CLRScriptBase Script)
{
int CurrentProcessId = Process.GetCurrentProcess().Id;
uint TableSize = 0;
IntPtr Table = IntPtr.Zero;
uint Status = NO_ERROR;
int LocalPort;
//
// If we have cached the data, return it from the cache.
//
// It is important to check the cache if we spin up a secondary
// UDP socket (and that the cache is first set before that is done)
// or else we might return the wrong listener.
//
if ((LocalPort = Script.GetGlobalInt("ACR_SERVERLISTENER_PORT")) != 0)
{
return new IPEndPoint((long)(UInt32)Script.GetGlobalInt("ACR_SERVERLISTENER_ADDRESS"), LocalPort);
}
//
// Find the first UDP listener owned by this process and assume
// that it's the right one.
//
try
{
do
{
if (Table != IntPtr.Zero)
{
Marshal.FreeHGlobal(Table);
Table = IntPtr.Zero;
}
if (TableSize != 0)
{
Table = Marshal.AllocHGlobal((int)TableSize);
}
Status = GetExtendedUdpTable(Table, ref TableSize, 1, AF_INET, UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID, 0);
} while (Status == ERROR_INSUFFICIENT_BUFFER);
if (Status != NO_ERROR)
{
throw new ApplicationException(String.Format("ALFA.SystemInfo.GetServerUdpListener: GetExtendedUdpTable failed, status = {0}", Status));
}
MIB_UDPTABLE_OWNER_PID UdpTable = (MIB_UDPTABLE_OWNER_PID) Marshal.PtrToStructure(Table, typeof(MIB_UDPTABLE_OWNER_PID));
for (uint Row = 0; Row < UdpTable.dwNumEntries; Row += 1)
{
IntPtr TableOffset = Marshal.OffsetOf(typeof(MIB_UDPTABLE_OWNER_PID), "table");
int RowSize = Marshal.SizeOf(typeof(MIB_UDPROW_OWNER_PID));
IntPtr RowOffset = IntPtr.Add(TableOffset, (int)(RowSize * Row));
MIB_UDPROW_OWNER_PID UdpRow = (MIB_UDPROW_OWNER_PID)Marshal.PtrToStructure(IntPtr.Add(Table, (int)RowOffset), typeof(MIB_UDPROW_OWNER_PID));
if (UdpRow.dwOwningPid != (uint)CurrentProcessId)
continue;
LocalPort = IPAddress.NetworkToHostOrder((short)UdpRow.dwLocalPort);
//
// Use loopback (disable deprecation warning) if we have no
// bound address.
//
#pragma warning disable 618
if (UdpRow.dwLocalAddr == 0)
UdpRow.dwLocalAddr = (uint)(ulong)IPAddress.Loopback.Address;
#pragma warning restore 618
//
// Cache the data and return a new endpoint object for the
// address.
//
Script.SetGlobalInt("ACR_SERVERLISTENER_PORT", LocalPort);
Script.SetGlobalInt("ACR_SERVERLISTENER_ADDRESS", (int)UdpRow.dwLocalAddr);
return new IPEndPoint((long)(ulong)UdpRow.dwLocalAddr, LocalPort);
}
}
finally
{
if (Table != IntPtr.Zero)
Marshal.FreeHGlobal(Table);
}
throw new ApplicationException("Endpoint not found.");
}