Всем привет. Подскажите кто чем может.
У меня есть сервер, там 2 и более ip адресов. Где можно найти информацию, что бы переключится между этими ip адересами.
Пример: У меня есть программа, которая работает с API, надо что то на подобии прокси, только тут я моментально мог переключатся между своими ip, и опрашивать сервер.
Можно ли такое вообще реализовать, и где про это можно почитать поподробнее? Приложение на C#
Можно добавлять route
-ы, указывая, по какому интерфейсу должно происходить соединение на конкретный IP адрес. Вот мой рабочий пример с комментариями.
static class Program
{
private const int ForwardTableSize = 100;
public enum Error : uint
{
ERROR_ACCESS_DENIED = 5,
ERROR_NOT_SUPPORTED = 50,
ERROR_INVALID_PARAMETER = 87,
ERROR_BAD_ARGUMENTS = 160
}
public enum MIB_IPFORWARD_TYPE : uint
{
MIB_IPROUTE_TYPE_OTHER = 1,
MIB_IPROUTE_TYPE_INVALID = 2,
MIB_IPROUTE_TYPE_DIRECT = 3,
MIB_IPROUTE_TYPE_INDIRECT = 4
}
public enum MIB_IPFORWARD_PROTO : uint
{
MIB_IPPROTO_OTHER = 1,
MIB_IPPROTO_LOCAL = 2,
MIB_IPPROTO_NETMGMT = 3,
MIB_IPPROTO_ICMP = 4,
MIB_IPPROTO_EGP = 5,
MIB_IPPROTO_GGP = 6,
MIB_IPPROTO_HELLO = 7,
MIB_IPPROTO_RIP = 8,
MIB_IPPROTO_IS_IS = 9,
MIB_IPPROTO_ES_IS = 10,
MIB_IPPROTO_CISCO = 11,
MIB_IPPROTO_BBN = 12,
MIB_IPPROTO_OSPF = 13,
MIB_IPPROTO_BGP = 14,
MIB_IPPROTO_NT_AUTOSTATIC = 10002,
MIB_IPPROTO_NT_STATIC = 10006,
MIB_IPPROTO_NT_STATIC_NON_DOD = 10007
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_IPFORWARDROW
{
public uint dwForwardDest;
public uint dwForwardMask;
public uint dwForwardPolicy;
public uint dwForwardNextHop;
public uint dwForwardIfIndex;
public MIB_IPFORWARD_TYPE ForwardType;
public MIB_IPFORWARD_PROTO ForwardProto;
public uint dwForwardAge;
public uint dwForwardNextHopAS;
public uint dwForwardMetric1;
public uint dwForwardMetric2;
public uint dwForwardMetric3;
public uint dwForwardMetric4;
public uint dwForwardMetric5;
}
[DllImport("Iphlpapi", CallingConvention = CallingConvention.Winapi)]
public static extern uint GetIpForwardTable(IntPtr pIpForwardTable, ref uint pdwSize, bool bOrder);
[DllImport("Iphlpapi", CallingConvention = CallingConvention.Winapi)]
public static extern uint CreateIpForwardEntry(ref MIB_IPFORWARDROW pRoute);
[DllImport("Iphlpapi", CallingConvention = CallingConvention.Winapi)]
public static extern uint DeleteIpForwardEntry(ref MIB_IPFORWARDROW pRoute);
// высокоуровневый переходник на нативную функцию, с которой очень сложно работать напрямую
public static MIB_IPFORWARDROW[] GetIpForwardTable()
{
const int tableSize = 100;
int bufLength = 4 + tableSize * Marshal.SizeOf(typeof(MIB_IPFORWARDROW));
IntPtr addr = Marshal.AllocHGlobal(bufLength);
try
{
Marshal.WriteInt32(addr, tableSize);
uint size = (uint)bufLength;
if (GetIpForwardTable(addr, ref size, true) != 0)
throw new InvalidOperationException();
if (size != bufLength)
{
// buffer too small
}
int length = Marshal.PtrToStructure<int>(addr);
var result = new MIB_IPFORWARDROW[length];
for (int i = 0; i < length; i++)
result[i] = Marshal.PtrToStructure<MIB_IPFORWARDROW>(addr + 4 + i * Marshal.SizeOf(typeof(MIB_IPFORWARDROW)));
return result;
}
finally
{
Marshal.FreeHGlobal(addr);
}
}
static uint IPToUInt32(IPAddress addr)
{
var bytes = addr.GetAddressBytes();
if (bytes.Length != 4)
throw new NotImplementedException();
return (uint)((bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0]);
}
// ищет запись в таблице с нашим айпи и удаляет ёё
static void Clear(MIB_IPFORWARDROW[] table, IPAddress addr)
{
foreach (var row in table)
{
if (row.dwForwardDest == IPToUInt32(addr))
{
var proute = row;
uint result = DeleteIpForwardEntry(ref proute);
if (result != 0)
throw new InvalidOperationException(((Error)result).ToString());
Console.WriteLine("IP forward entry removed");
}
}
}
static void AddForEthernet(IPAddress destIP, IPAddress destMask)
{
// 10 - номер сетевого интерфейса Ethernet
// в моем случае не работает если указать 0.0.0.0
// указал IP адрес роутера, можете посмотреть адреса через "ipconfig -all"
AddForInterface(10, destIP, destMask, IPAddress.Parse("192.168.1.1"));
}
static void AddForVPN(IPAddress destIP, IPAddress destMask)
{
// 35 - номер сетевого интерфейса подключенного VPN
AddForInterface(35, destIP, destMask, IPAddress.Parse("0.0.0.0"));
}
static void AddForInterface(uint ifIndex, IPAddress destIP, IPAddress destMask, IPAddress nextHop)
{
var route = new MIB_IPFORWARDROW
{
dwForwardDest = IPToUInt32(destIP),
dwForwardMask = IPToUInt32(destMask),
dwForwardPolicy = 0,
dwForwardNextHop = IPToUInt32(nextHop),
dwForwardIfIndex = ifIndex,
dwForwardMetric1 = 500, // не знаю, что это, с 500 в меня работает нормально
dwForwardMetric2 = 0,
dwForwardMetric3 = 0,
dwForwardMetric4 = 0,
dwForwardMetric5 = 0,
ForwardProto = MIB_IPFORWARD_PROTO.MIB_IPPROTO_NETMGMT,
ForwardType = MIB_IPFORWARD_TYPE.MIB_IPROUTE_TYPE_DIRECT
};
uint result = CreateIpForwardEntry(ref route);
if (result != 0)
throw new InvalidOperationException(((Error)result).ToString());
Console.WriteLine("IP forward entry added");
}
static void DoRequest(IPAddress ip)
{
// для надежности я соединяюсь по IP, и указываю хост вручную
var req = (HttpWebRequest)WebRequest.Create($"https://{ip}/?format=json");
req.Host = "api.ipify.org";
req.KeepAlive = false; // обязательно отключаем KeepAlive
using (var resp = req.GetResponse())
{
var stream = resp.GetResponseStream();
using (var sr = new StreamReader(stream))
{
Console.WriteLine(sr.ReadToEnd());
}
}
}
static void Main(string[] args)
{
// ищем IPv4 адрес
var destIP = Dns.GetHostAddresses("api.ipify.org").First(ip => ip.AddressFamily == AddressFamily.InterNetwork);
// маска указывает, что мы добавляем роут только для 1 адреса
var destMask = IPAddress.Parse("255.255.255.255");
var table = GetIpForwardTable();
Clear(table, destIP); // удаляем предыдущий роут, если вдруг остался от прошлого запуска программы
AddForVPN(destIP, destMask); // добавляем роут через интерфейс VPN подключения
try
{
DoRequest(destIP);
}
finally
{
table = GetIpForwardTable();
Clear(table, destIP); // очищаем таблицу
}
AddForEthernet(destIP, destMask); // добавляем роут через Ethernet
try
{
DoRequest(destIP);
}
finally
{
table = GetIpForwardTable();
Clear(table, destIP); // очищаем таблицу
}
}
}
Узнать номера интерфейсов можно командой route print
:
C:\Windows\system32>route print
===========================================================================
Interface List
35...........................VPN
10...xx xx xx xx xx xx ......Ethernet Connection
17...xx xx xx xx xx xx ......xxx
18...xx xx xx xx xx xx ......xxx
...
===========================================================================
Вывод программы:
IP forward entry added
{"ip":"xx.xx.xx.xx"} // VPN IP
IP forward entry removed
IP forward entry added
{"ip":"xx.xx.xx.xx"} // Ethernet IP
IP forward entry removed
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Делаю учебную задачу, у меня есть удаленное хранилище ключей,, само апи это три запроса, гет , пост и делит, для создание api использую, Nancy, Aspnetcore,...
Как сделать вот такой запрос от одного php скрипта к другому на моём хостинге?