mirror of https://github.com/oxen-io/lokinet
Merge pull request #67 from majestrate/dev
various fixes to make the network stop spamming itselfpull/68/head
commit
3ef2b5c8ad
@ -1,76 +1,76 @@
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
"files.associations": {
|
||||
"array": "cpp",
|
||||
"limits": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"atomic": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"bitset": "cpp",
|
||||
"chrono": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"deque": "cpp",
|
||||
"list": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"exception": "cpp",
|
||||
"filesystem": "cpp",
|
||||
"string_view": "cpp",
|
||||
"fstream": "cpp",
|
||||
"functional": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"memory": "cpp",
|
||||
"mutex": "cpp",
|
||||
"optional": "cpp",
|
||||
"ostream": "cpp",
|
||||
"ratio": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"system_error": "cpp",
|
||||
"thread": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"tuple": "cpp",
|
||||
"typeindex": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"utility": "cpp",
|
||||
"__config": "cpp",
|
||||
"__nullptr": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"io": "cpp",
|
||||
"strstream": "cpp",
|
||||
"numeric": "cpp",
|
||||
"valarray": "cpp",
|
||||
"*.ipp": "cpp",
|
||||
"csignal": "cpp",
|
||||
"future": "cpp",
|
||||
"map": "cpp",
|
||||
"vector": "cpp",
|
||||
"new": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"complex": "cpp",
|
||||
"variant": "cpp",
|
||||
"any": "cpp",
|
||||
"tuntap.h": "c",
|
||||
"hashtable": "cpp",
|
||||
"__mutex_base": "cpp",
|
||||
"iterator": "cpp"
|
||||
}
|
||||
"editor.formatOnSave": true,
|
||||
"files.associations": {
|
||||
"array": "cpp",
|
||||
"limits": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"atomic": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"bitset": "cpp",
|
||||
"chrono": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"deque": "cpp",
|
||||
"list": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"exception": "cpp",
|
||||
"filesystem": "cpp",
|
||||
"string_view": "cpp",
|
||||
"fstream": "cpp",
|
||||
"functional": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"memory": "cpp",
|
||||
"mutex": "cpp",
|
||||
"optional": "cpp",
|
||||
"ostream": "cpp",
|
||||
"ratio": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"system_error": "cpp",
|
||||
"thread": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"tuple": "cpp",
|
||||
"typeindex": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"utility": "cpp",
|
||||
"__config": "cpp",
|
||||
"__nullptr": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"io": "cpp",
|
||||
"strstream": "cpp",
|
||||
"numeric": "cpp",
|
||||
"valarray": "cpp",
|
||||
"*.ipp": "cpp",
|
||||
"csignal": "cpp",
|
||||
"future": "cpp",
|
||||
"map": "cpp",
|
||||
"vector": "cpp",
|
||||
"new": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"complex": "cpp",
|
||||
"variant": "cpp",
|
||||
"any": "cpp",
|
||||
"tuntap.h": "c",
|
||||
"hashtable": "cpp",
|
||||
"__mutex_base": "cpp",
|
||||
"iterator": "cpp"
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,113 @@
|
||||
#include <llarp/exit/session.hpp>
|
||||
#include "router.hpp"
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace exit
|
||||
{
|
||||
}
|
||||
BaseSession::BaseSession(const llarp::RouterID& router,
|
||||
std::function< bool(llarp_buffer_t) > writepkt,
|
||||
llarp_router* r, size_t numpaths, size_t hoplen)
|
||||
: llarp::path::Builder(r, r->dht, numpaths, hoplen)
|
||||
, m_ExitRouter(router)
|
||||
, m_WritePacket(writepkt)
|
||||
{
|
||||
r->crypto.identity_keygen(m_ExitIdentity);
|
||||
}
|
||||
|
||||
BaseSession::~BaseSession()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
BaseSession::ShouldBuildMore(llarp_time_t now) const
|
||||
{
|
||||
return AvailablePaths(llarp::path::ePathRoleExit) == 0
|
||||
|| path::Builder::ShouldBuildMore(now);
|
||||
}
|
||||
|
||||
bool
|
||||
BaseSession::SelectHop(llarp_nodedb* db, const RouterContact& prev,
|
||||
RouterContact& cur, size_t hop,
|
||||
llarp::path::PathRole roles)
|
||||
{
|
||||
if(hop == numHops - 1)
|
||||
return llarp_nodedb_get_rc(db, m_ExitRouter, cur);
|
||||
else
|
||||
return path::Builder::SelectHop(db, prev, cur, hop, roles);
|
||||
}
|
||||
|
||||
void
|
||||
BaseSession::HandlePathBuilt(llarp::path::Path* p)
|
||||
{
|
||||
p->SetDropHandler(std::bind(&BaseSession::HandleTrafficDrop, this,
|
||||
std::placeholders::_1, std::placeholders::_2,
|
||||
std::placeholders::_3));
|
||||
p->SetExitTrafficHandler(std::bind(&BaseSession::HandleTraffic, this,
|
||||
std::placeholders::_1,
|
||||
std::placeholders::_2));
|
||||
p->AddObtainExitHandler(std::bind(&BaseSession::HandleGotExit, this,
|
||||
std::placeholders::_1,
|
||||
std::placeholders::_2));
|
||||
llarp::routing::ObtainExitMessage obtain;
|
||||
obtain.S = p->NextSeqNo();
|
||||
obtain.T = llarp_randint();
|
||||
obtain.X = 0;
|
||||
obtain.E = 1;
|
||||
if(!obtain.Sign(&router->crypto, m_ExitIdentity))
|
||||
{
|
||||
llarp::LogError("Failed to sign exit request");
|
||||
return;
|
||||
}
|
||||
if(p->SendExitRequest(&obtain, router))
|
||||
llarp::LogInfo("asking ", m_ExitRouter, " for exit");
|
||||
else
|
||||
llarp::LogError("faild to send exit request");
|
||||
}
|
||||
|
||||
bool
|
||||
BaseSession::HandleGotExit(llarp::path::Path* p, llarp_time_t b)
|
||||
{
|
||||
if(b == 0)
|
||||
{
|
||||
llarp::LogInfo("obtained an exit via ", p->Endpoint());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BaseSession::HandleTraffic(llarp::path::Path* p, llarp_buffer_t pkt)
|
||||
{
|
||||
(void)p;
|
||||
if(m_WritePacket)
|
||||
return m_WritePacket(pkt);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
BaseSession::HandleTrafficDrop(llarp::path::Path* p, const PathID_t& path,
|
||||
uint64_t s)
|
||||
{
|
||||
(void)p;
|
||||
llarp::LogError("dropped traffic on exit ", m_ExitRouter, " S=", s,
|
||||
" P=", path);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BaseSession::SendUpstreamTraffic(llarp::net::IPv4Packet pkt)
|
||||
{
|
||||
auto path = PickRandomEstablishedPath(llarp::path::ePathRoleExit);
|
||||
if(!path)
|
||||
return false;
|
||||
llarp::routing::TransferTrafficMessage transfer;
|
||||
transfer.S = path->NextSeqNo();
|
||||
transfer.X.resize(pkt.sz);
|
||||
memcpy(transfer.X.data(), pkt.buf, pkt.sz);
|
||||
if(!transfer.Sign(&router->crypto, m_ExitIdentity))
|
||||
return false;
|
||||
return path->SendRoutingMessage(&transfer, router);
|
||||
}
|
||||
|
||||
} // namespace exit
|
||||
} // namespace llarp
|
@ -1,315 +0,0 @@
|
||||
#if defined(__MINGW32__) && !defined(_WIN64)
|
||||
/*
|
||||
* Contains routines missing from WS2_32.DLL until 2006, if yer using
|
||||
* Microsoft C/C++, then this code is irrelevant, as the official
|
||||
* Platform SDK already links against these routines in the correct
|
||||
* libraries.
|
||||
*
|
||||
* -despair86 30/07/18
|
||||
*/
|
||||
|
||||
// these need to be in a specific order
|
||||
#include <assert.h>
|
||||
#include <llarp/net.h>
|
||||
#include <windows.h>
|
||||
#include <iphlpapi.h>
|
||||
#if WINNT_CROSS_COMPILE && !NTSTATUS
|
||||
typedef LONG NTSTATUS;
|
||||
#endif
|
||||
#include "win32_intrnl.h"
|
||||
|
||||
const char *
|
||||
inet_ntop(int af, const void *src, char *dst, size_t size)
|
||||
{
|
||||
int address_length;
|
||||
DWORD string_length = size;
|
||||
struct sockaddr_storage sa;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
switch(af)
|
||||
{
|
||||
case AF_INET:
|
||||
address_length = sizeof(struct sockaddr_in);
|
||||
sin->sin_family = af;
|
||||
memcpy(&sin->sin_addr, src, sizeof(struct in_addr));
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
address_length = sizeof(struct sockaddr_in6);
|
||||
sin6->sin6_family = af;
|
||||
memcpy(&sin6->sin6_addr, src, sizeof(struct in6_addr));
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(WSAAddressToString((LPSOCKADDR)&sa, address_length, NULL, dst,
|
||||
&string_length)
|
||||
== 0)
|
||||
{
|
||||
return dst;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
inet_pton(int af, const char *src, void *dst)
|
||||
{
|
||||
int address_length;
|
||||
struct sockaddr_storage sa;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
|
||||
|
||||
switch(af)
|
||||
{
|
||||
case AF_INET:
|
||||
address_length = sizeof(struct sockaddr_in);
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
address_length = sizeof(struct sockaddr_in6);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(WSAStringToAddress((LPTSTR)src, af, NULL, (LPSOCKADDR)&sa, &address_length)
|
||||
== 0)
|
||||
{
|
||||
switch(af)
|
||||
{
|
||||
case AF_INET:
|
||||
memcpy(dst, &sin->sin_addr, sizeof(struct in_addr));
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
memcpy(dst, &sin6->sin6_addr, sizeof(struct in6_addr));
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct _InterfaceIndexTable
|
||||
{
|
||||
DWORD numIndexes;
|
||||
IF_INDEX indexes[1];
|
||||
} InterfaceIndexTable;
|
||||
|
||||
// windows 2000
|
||||
// todo(despair86): implement IPv6 detection using
|
||||
// the ipv6 preview stack/adv net pack from 1999/2001
|
||||
DWORD FAR PASCAL
|
||||
_GetAdaptersAddresses(ULONG Family, ULONG Flags, PVOID Reserved,
|
||||
PIP_ADAPTER_ADDRESSES pAdapterAddresses,
|
||||
PULONG pOutBufLen)
|
||||
{
|
||||
InterfaceIndexTable *indexTable;
|
||||
IFInfo ifInfo;
|
||||
int i;
|
||||
ULONG ret, requiredSize = 0;
|
||||
PIP_ADAPTER_ADDRESSES currentAddress;
|
||||
PUCHAR currentLocation;
|
||||
HANDLE tcpFile;
|
||||
|
||||
(void)(Family);
|
||||
if(!pOutBufLen)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
if(Reserved)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
indexTable = getInterfaceIndexTable();
|
||||
if(!indexTable)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
ret = openTcpFile(&tcpFile, FILE_READ_DATA);
|
||||
if(!NT_SUCCESS(ret))
|
||||
return ERROR_NO_DATA;
|
||||
|
||||
for(i = indexTable->numIndexes; i >= 0; i--)
|
||||
{
|
||||
if(NT_SUCCESS(
|
||||
getIPAddrEntryForIf(tcpFile, NULL, indexTable->indexes[i], &ifInfo)))
|
||||
{
|
||||
/* The whole struct */
|
||||
requiredSize += sizeof(IP_ADAPTER_ADDRESSES);
|
||||
|
||||
/* Friendly name */
|
||||
if(!(Flags & GAA_FLAG_SKIP_FRIENDLY_NAME))
|
||||
requiredSize +=
|
||||
strlen((char *)ifInfo.if_info.ent.if_descr) + 1; // FIXME
|
||||
|
||||
/* Adapter name */
|
||||
requiredSize += strlen((char *)ifInfo.if_info.ent.if_descr) + 1;
|
||||
|
||||
/* Unicast address */
|
||||
if(!(Flags & GAA_FLAG_SKIP_UNICAST))
|
||||
requiredSize += sizeof(IP_ADAPTER_UNICAST_ADDRESS);
|
||||
|
||||
/* FIXME: Implement multicast, anycast, and dns server stuff */
|
||||
|
||||
/* FIXME: Implement dns suffix and description */
|
||||
requiredSize += 2 * sizeof(WCHAR);
|
||||
|
||||
/* We're only going to implement what's required for XP SP0 */
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "size: %ld, requiredSize: %ld\n", *pOutBufLen, requiredSize);
|
||||
#endif
|
||||
if(!pAdapterAddresses || *pOutBufLen < requiredSize)
|
||||
{
|
||||
*pOutBufLen = requiredSize;
|
||||
closeTcpFile(tcpFile);
|
||||
free(indexTable);
|
||||
return ERROR_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
RtlZeroMemory(pAdapterAddresses, requiredSize);
|
||||
|
||||
/* Let's set up the pointers */
|
||||
currentAddress = pAdapterAddresses;
|
||||
for(i = indexTable->numIndexes; i >= 0; i--)
|
||||
{
|
||||
if(NT_SUCCESS(
|
||||
getIPAddrEntryForIf(tcpFile, NULL, indexTable->indexes[i], &ifInfo)))
|
||||
{
|
||||
currentLocation =
|
||||
(PUCHAR)currentAddress + (ULONG_PTR)sizeof(IP_ADAPTER_ADDRESSES);
|
||||
|
||||
/* FIXME: Friendly name */
|
||||
if(!(Flags & GAA_FLAG_SKIP_FRIENDLY_NAME))
|
||||
{
|
||||
currentAddress->FriendlyName = (PVOID)currentLocation;
|
||||
currentLocation += sizeof(WCHAR);
|
||||
}
|
||||
|
||||
/* Adapter name */
|
||||
currentAddress->AdapterName = (PVOID)currentLocation;
|
||||
currentLocation += strlen((char *)ifInfo.if_info.ent.if_descr) + 1;
|
||||
|
||||
/* Unicast address */
|
||||
if(!(Flags & GAA_FLAG_SKIP_UNICAST))
|
||||
{
|
||||
currentAddress->FirstUnicastAddress = (PVOID)currentLocation;
|
||||
currentLocation += sizeof(IP_ADAPTER_UNICAST_ADDRESS);
|
||||
currentAddress->FirstUnicastAddress->Address.lpSockaddr =
|
||||
(PVOID)currentLocation;
|
||||
currentLocation += sizeof(struct sockaddr);
|
||||
}
|
||||
|
||||
/* FIXME: Implement multicast, anycast, and dns server stuff */
|
||||
|
||||
/* FIXME: Implement dns suffix and description */
|
||||
currentAddress->DnsSuffix = (PVOID)currentLocation;
|
||||
currentLocation += sizeof(WCHAR);
|
||||
|
||||
currentAddress->Description = (PVOID)currentLocation;
|
||||
currentLocation += sizeof(WCHAR);
|
||||
|
||||
currentAddress->Next = (PVOID)currentLocation;
|
||||
/* Terminate the last address correctly */
|
||||
if(i == 0)
|
||||
currentAddress->Next = NULL;
|
||||
|
||||
/* We're only going to implement what's required for XP SP0 */
|
||||
|
||||
currentAddress = currentAddress->Next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now again, for real this time */
|
||||
|
||||
currentAddress = pAdapterAddresses;
|
||||
for(i = indexTable->numIndexes; i >= 0; i--)
|
||||
{
|
||||
if(NT_SUCCESS(
|
||||
getIPAddrEntryForIf(tcpFile, NULL, indexTable->indexes[i], &ifInfo)))
|
||||
{
|
||||
/* Make sure we're not looping more than we hoped for */
|
||||
assert(currentAddress);
|
||||
|
||||
/* Alignment information */
|
||||
currentAddress->Length = sizeof(IP_ADAPTER_ADDRESSES);
|
||||
currentAddress->IfIndex = indexTable->indexes[i];
|
||||
|
||||
/* Adapter name */
|
||||
strcpy(currentAddress->AdapterName, (char *)ifInfo.if_info.ent.if_descr);
|
||||
|
||||
if(!(Flags & GAA_FLAG_SKIP_UNICAST))
|
||||
{
|
||||
currentAddress->FirstUnicastAddress->Length =
|
||||
sizeof(IP_ADAPTER_UNICAST_ADDRESS);
|
||||
currentAddress->FirstUnicastAddress->Flags = 0; // FIXME
|
||||
currentAddress->FirstUnicastAddress->Next =
|
||||
NULL; // FIXME: Support more than one address per adapter
|
||||
currentAddress->FirstUnicastAddress->Address.lpSockaddr->sa_family =
|
||||
AF_INET;
|
||||
memcpy(currentAddress->FirstUnicastAddress->Address.lpSockaddr->sa_data,
|
||||
&ifInfo.ip_addr.iae_addr, sizeof(ifInfo.ip_addr.iae_addr));
|
||||
currentAddress->FirstUnicastAddress->Address.iSockaddrLength =
|
||||
sizeof(ifInfo.ip_addr.iae_addr) + sizeof(USHORT);
|
||||
currentAddress->FirstUnicastAddress->PrefixOrigin =
|
||||
IpPrefixOriginOther; // FIXME
|
||||
currentAddress->FirstUnicastAddress->SuffixOrigin =
|
||||
IpSuffixOriginOther; // FIXME
|
||||
currentAddress->FirstUnicastAddress->DadState =
|
||||
IpDadStatePreferred; // FIXME
|
||||
currentAddress->FirstUnicastAddress->ValidLifetime =
|
||||
0xFFFFFFFF; // FIXME
|
||||
currentAddress->FirstUnicastAddress->PreferredLifetime =
|
||||
0xFFFFFFFF; // FIXME
|
||||
currentAddress->FirstUnicastAddress->LeaseLifetime =
|
||||
0xFFFFFFFF; // FIXME
|
||||
}
|
||||
|
||||
/* FIXME: Implement multicast, anycast, and dns server stuff */
|
||||
currentAddress->FirstAnycastAddress = NULL;
|
||||
currentAddress->FirstMulticastAddress = NULL;
|
||||
currentAddress->FirstDnsServerAddress = NULL;
|
||||
|
||||
/* FIXME: Implement dns suffix, description, and friendly name */
|
||||
currentAddress->DnsSuffix[0] = UNICODE_NULL;
|
||||
currentAddress->Description[0] = UNICODE_NULL;
|
||||
currentAddress->FriendlyName[0] = UNICODE_NULL;
|
||||
|
||||
/* Physical Address */
|
||||
memcpy(currentAddress->PhysicalAddress, ifInfo.if_info.ent.if_physaddr,
|
||||
ifInfo.if_info.ent.if_physaddrlen);
|
||||
currentAddress->PhysicalAddressLength = ifInfo.if_info.ent.if_physaddrlen;
|
||||
|
||||
/* Flags */
|
||||
currentAddress->Flags = 0; // FIXME
|
||||
|
||||
/* MTU */
|
||||
currentAddress->Mtu = ifInfo.if_info.ent.if_mtu;
|
||||
|
||||
/* Interface type */
|
||||
currentAddress->IfType = ifInfo.if_info.ent.if_type;
|
||||
|
||||
/* Operational status */
|
||||
if(ifInfo.if_info.ent.if_operstatus >= IF_OPER_STATUS_CONNECTING)
|
||||
currentAddress->OperStatus = IfOperStatusUp;
|
||||
else
|
||||
currentAddress->OperStatus = IfOperStatusDown;
|
||||
|
||||
/* We're only going to implement what's required for XP SP0 */
|
||||
|
||||
/* Move to the next address */
|
||||
currentAddress = currentAddress->Next;
|
||||
}
|
||||
}
|
||||
|
||||
closeTcpFile(tcpFile);
|
||||
free(indexTable);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
#endif
|
@ -1,572 +0,0 @@
|
||||
#if defined(__MINGW32__) && !defined(_WIN64)
|
||||
/*
|
||||
* All the user-mode scaffolding necessary to backport GetAdaptersAddresses(2))
|
||||
* to the NT 5.x series. See further comments for any limitations.
|
||||
* NOTE: this is dead code, i haven't had time to debug it yet due to illness.
|
||||
* For now, downlevel platforms use GetAdaptersInfo(2) which is inet4 only.
|
||||
* -despair86 20/08/18
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// apparently mingw-w64 loses its shit over this
|
||||
// but only for 32-bit builds, naturally
|
||||
#ifdef WIN32_LEAN_AND_MEAN
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
// these need to be in a specific order
|
||||
#include <windows.h>
|
||||
#include <winternl.h>
|
||||
#include <tdi.h>
|
||||
#include "win32_intrnl.h"
|
||||
|
||||
const PWCHAR TcpFileName = L"\\Device\\Tcp";
|
||||
|
||||
// from ntdll.dll
|
||||
typedef void(FAR PASCAL *pRtlInitUString)(UNICODE_STRING *, const WCHAR *);
|
||||
typedef NTSTATUS(FAR PASCAL *pNTOpenFile)(HANDLE *, ACCESS_MASK,
|
||||
OBJECT_ATTRIBUTES *,
|
||||
IO_STATUS_BLOCK *, ULONG, ULONG);
|
||||
typedef NTSTATUS(FAR PASCAL *pNTClose)(HANDLE);
|
||||
|
||||
#define FSCTL_TCP_BASE FILE_DEVICE_NETWORK
|
||||
|
||||
#define _TCP_CTL_CODE(Function, Method, Access) \
|
||||
CTL_CODE(FSCTL_TCP_BASE, Function, Method, Access)
|
||||
|
||||
#define IOCTL_TCP_QUERY_INFORMATION_EX \
|
||||
_TCP_CTL_CODE(0, METHOD_NEITHER, FILE_ANY_ACCESS)
|
||||
|
||||
typedef struct _InterfaceIndexTable
|
||||
{
|
||||
DWORD numIndexes;
|
||||
DWORD numAllocated;
|
||||
DWORD indexes[1];
|
||||
} InterfaceIndexTable;
|
||||
|
||||
NTSTATUS
|
||||
tdiGetMibForIfEntity(HANDLE tcpFile, TDIEntityID *ent,
|
||||
IFEntrySafelySized *entry)
|
||||
{
|
||||
TCP_REQUEST_QUERY_INFORMATION_EX req;
|
||||
NTSTATUS status = 0;
|
||||
DWORD returnSize;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "TdiGetMibForIfEntity(tcpFile %x,entityId %x)\n",
|
||||
(int)tcpFile, (int)ent->tei_instance);
|
||||
#endif
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.ID.toi_class = INFO_CLASS_PROTOCOL;
|
||||
req.ID.toi_type = INFO_TYPE_PROVIDER;
|
||||
req.ID.toi_id = 1;
|
||||
req.ID.toi_entity = *ent;
|
||||
|
||||
status =
|
||||
DeviceIoControl(tcpFile, IOCTL_TCP_QUERY_INFORMATION_EX, &req,
|
||||
sizeof(req), entry, sizeof(*entry), &returnSize, NULL);
|
||||
|
||||
if(!status)
|
||||
{
|
||||
perror("IOCTL Failed\n");
|
||||
return 0xc0000001;
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"TdiGetMibForIfEntity() => {\n"
|
||||
" if_index ....................... %lx\n"
|
||||
" if_type ........................ %lx\n"
|
||||
" if_mtu ......................... %ld\n"
|
||||
" if_speed ....................... %lx\n"
|
||||
" if_physaddrlen ................. %ld\n",
|
||||
entry->ent.if_index, entry->ent.if_type, entry->ent.if_mtu,
|
||||
entry->ent.if_speed, entry->ent.if_physaddrlen);
|
||||
fprintf(stderr,
|
||||
" if_physaddr .................... %02x:%02x:%02x:%02x:%02x:%02x\n"
|
||||
" if_descr ....................... %s\n",
|
||||
entry->ent.if_physaddr[0] & 0xff, entry->ent.if_physaddr[1] & 0xff,
|
||||
entry->ent.if_physaddr[2] & 0xff, entry->ent.if_physaddr[3] & 0xff,
|
||||
entry->ent.if_physaddr[4] & 0xff, entry->ent.if_physaddr[5] & 0xff,
|
||||
entry->ent.if_descr);
|
||||
fprintf(stderr, "} status %08lx\n", status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
tdiGetSetOfThings(HANDLE tcpFile, DWORD toiClass, DWORD toiType, DWORD toiId,
|
||||
DWORD teiEntity, DWORD teiInstance, DWORD fixedPart,
|
||||
DWORD entrySize, PVOID *tdiEntitySet, PDWORD numEntries)
|
||||
{
|
||||
TCP_REQUEST_QUERY_INFORMATION_EX req;
|
||||
PVOID entitySet = 0;
|
||||
NTSTATUS status = 0;
|
||||
DWORD allocationSizeForEntityArray = entrySize * MAX_TDI_ENTITIES,
|
||||
arraySize = entrySize * MAX_TDI_ENTITIES;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.ID.toi_class = toiClass;
|
||||
req.ID.toi_type = toiType;
|
||||
req.ID.toi_id = toiId;
|
||||
req.ID.toi_entity.tei_entity = teiEntity;
|
||||
req.ID.toi_entity.tei_instance = teiInstance;
|
||||
|
||||
/* There's a subtle problem here...
|
||||
* If an interface is added at this exact instant, (as if by a PCMCIA
|
||||
* card insertion), the array will still not have enough entries after
|
||||
* have allocated it after the first DeviceIoControl call.
|
||||
*
|
||||
* We'll get around this by repeating until the number of interfaces
|
||||
* stabilizes.
|
||||
*/
|
||||
do
|
||||
{
|
||||
status =
|
||||
DeviceIoControl(tcpFile, IOCTL_TCP_QUERY_INFORMATION_EX, &req,
|
||||
sizeof(req), 0, 0, &allocationSizeForEntityArray, NULL);
|
||||
|
||||
if(!status)
|
||||
return 0xc0000001;
|
||||
|
||||
arraySize = allocationSizeForEntityArray;
|
||||
entitySet = HeapAlloc(GetProcessHeap(), 0, arraySize);
|
||||
|
||||
if(!entitySet)
|
||||
{
|
||||
status = ((NTSTATUS)0xC000009A);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = DeviceIoControl(tcpFile, IOCTL_TCP_QUERY_INFORMATION_EX, &req,
|
||||
sizeof(req), entitySet, arraySize,
|
||||
&allocationSizeForEntityArray, NULL);
|
||||
|
||||
/* This is why we have the loop -- we might have added an adapter */
|
||||
if(arraySize == allocationSizeForEntityArray)
|
||||
break;
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, entitySet);
|
||||
entitySet = 0;
|
||||
|
||||
if(!status)
|
||||
return 0xc0000001;
|
||||
} while(TRUE); /* We break if the array we received was the size we
|
||||
* expected. Therefore, we got here because it wasn't */
|
||||
|
||||
*numEntries = (arraySize - fixedPart) / entrySize;
|
||||
*tdiEntitySet = entitySet;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
tdiGetEntityIDSet(HANDLE tcpFile, TDIEntityID **entitySet, PDWORD numEntities)
|
||||
{
|
||||
NTSTATUS status =
|
||||
tdiGetSetOfThings(tcpFile, INFO_CLASS_GENERIC, INFO_TYPE_PROVIDER,
|
||||
ENTITY_LIST_ID, GENERIC_ENTITY, 0, 0,
|
||||
sizeof(TDIEntityID), (PVOID *)entitySet, numEntities);
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
tdiGetIpAddrsForIpEntity(HANDLE tcpFile, TDIEntityID *ent, IPAddrEntry **addrs,
|
||||
PDWORD numAddrs)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "TdiGetIpAddrsForIpEntity(tcpFile 0x%p, entityId 0x%lx)\n",
|
||||
tcpFile, ent->tei_instance);
|
||||
#endif
|
||||
|
||||
status = tdiGetSetOfThings(tcpFile, INFO_CLASS_PROTOCOL, INFO_TYPE_PROVIDER,
|
||||
0x102, CL_NL_ENTITY, ent->tei_instance, 0,
|
||||
sizeof(IPAddrEntry), (PVOID *)addrs, numAddrs);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static VOID
|
||||
tdiFreeThingSet(PVOID things)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, things);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
openTcpFile(PHANDLE tcpFile, ACCESS_MASK DesiredAccess)
|
||||
{
|
||||
UNICODE_STRING fileName;
|
||||
OBJECT_ATTRIBUTES objectAttributes;
|
||||
IO_STATUS_BLOCK ioStatusBlock;
|
||||
NTSTATUS status;
|
||||
pRtlInitUString _RtlInitUnicodeString;
|
||||
pNTOpenFile _NTOpenFile;
|
||||
HANDLE ntdll;
|
||||
|
||||
ntdll = GetModuleHandle("ntdll.dll");
|
||||
_RtlInitUnicodeString =
|
||||
(pRtlInitUString)GetProcAddress(ntdll, "RtlInitUnicodeString");
|
||||
_NTOpenFile = (pNTOpenFile)GetProcAddress(ntdll, "NtOpenFile");
|
||||
_RtlInitUnicodeString(&fileName, TcpFileName);
|
||||
InitializeObjectAttributes(&objectAttributes, &fileName, OBJ_CASE_INSENSITIVE,
|
||||
NULL, NULL);
|
||||
status = _NTOpenFile(tcpFile, DesiredAccess | SYNCHRONIZE, &objectAttributes,
|
||||
&ioStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT);
|
||||
/* String does not need to be freed: it points to the constant
|
||||
* string we provided */
|
||||
if(!NT_SUCCESS(status))
|
||||
*tcpFile = INVALID_HANDLE_VALUE;
|
||||
return status;
|
||||
}
|
||||
VOID
|
||||
closeTcpFile(HANDLE h)
|
||||
{
|
||||
pNTClose _NTClose;
|
||||
HANDLE ntdll = GetModuleHandle("ntdll.dll");
|
||||
_NTClose = (pNTClose)GetProcAddress(ntdll, "NtClose");
|
||||
assert(h != INVALID_HANDLE_VALUE);
|
||||
_NTClose(h);
|
||||
}
|
||||
|
||||
BOOL
|
||||
isLoopback(HANDLE tcpFile, TDIEntityID *loop_maybe)
|
||||
{
|
||||
IFEntrySafelySized entryInfo;
|
||||
NTSTATUS status;
|
||||
|
||||
status = tdiGetMibForIfEntity(tcpFile, loop_maybe, &entryInfo);
|
||||
|
||||
return NT_SUCCESS(status)
|
||||
&& (entryInfo.ent.if_type == IFENT_SOFTWARE_LOOPBACK);
|
||||
}
|
||||
|
||||
BOOL
|
||||
isIpEntity(HANDLE tcpFile, TDIEntityID *ent)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(tcpFile);
|
||||
return (ent->tei_entity == CL_NL_ENTITY || ent->tei_entity == CO_NL_ENTITY);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
getNthIpEntity(HANDLE tcpFile, DWORD index, TDIEntityID *ent)
|
||||
{
|
||||
DWORD numEntities = 0;
|
||||
DWORD numRoutes = 0;
|
||||
TDIEntityID *entitySet = 0;
|
||||
NTSTATUS status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities);
|
||||
unsigned i;
|
||||
|
||||
if(!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
for(i = 0; i < numEntities; i++)
|
||||
{
|
||||
if(isIpEntity(tcpFile, &entitySet[i]))
|
||||
{
|
||||
fprintf(stderr, "Entity %d is an IP Entity\n", i);
|
||||
if(numRoutes == index)
|
||||
break;
|
||||
else
|
||||
numRoutes++;
|
||||
}
|
||||
}
|
||||
|
||||
if(numRoutes == index && i < numEntities)
|
||||
{
|
||||
fprintf(stderr, "Index %lu is entity #%d - %04lx:%08lx\n", index, i,
|
||||
entitySet[i].tei_entity, entitySet[i].tei_instance);
|
||||
memcpy(ent, &entitySet[i], sizeof(*ent));
|
||||
tdiFreeThingSet(entitySet);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tdiFreeThingSet(entitySet);
|
||||
return 0xc000001;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL
|
||||
isInterface(TDIEntityID *if_maybe)
|
||||
{
|
||||
return if_maybe->tei_entity == IF_ENTITY;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
getInterfaceInfoSet(HANDLE tcpFile, IFInfo **infoSet, PDWORD numInterfaces)
|
||||
{
|
||||
DWORD numEntities;
|
||||
TDIEntityID *entIDSet = NULL;
|
||||
NTSTATUS status = tdiGetEntityIDSet(tcpFile, &entIDSet, &numEntities);
|
||||
IFInfo *infoSetInt = 0;
|
||||
int curInterf = 0;
|
||||
unsigned i;
|
||||
|
||||
if(!NT_SUCCESS(status))
|
||||
{
|
||||
fprintf(stderr, "getInterfaceInfoSet: tdiGetEntityIDSet() failed: 0x%lx\n",
|
||||
status);
|
||||
return status;
|
||||
}
|
||||
|
||||
infoSetInt = HeapAlloc(GetProcessHeap(), 0, sizeof(IFInfo) * numEntities);
|
||||
|
||||
if(infoSetInt)
|
||||
{
|
||||
for(i = 0; i < numEntities; i++)
|
||||
{
|
||||
if(isInterface(&entIDSet[i]))
|
||||
{
|
||||
infoSetInt[curInterf].entity_id = entIDSet[i];
|
||||
status = tdiGetMibForIfEntity(tcpFile, &entIDSet[i],
|
||||
&infoSetInt[curInterf].if_info);
|
||||
fprintf(stderr, "tdiGetMibForIfEntity: %08lx\n", status);
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
DWORD numAddrs;
|
||||
IPAddrEntry *addrs;
|
||||
TDIEntityID ip_ent;
|
||||
unsigned j;
|
||||
|
||||
status = getNthIpEntity(tcpFile, curInterf, &ip_ent);
|
||||
if(NT_SUCCESS(status))
|
||||
status =
|
||||
tdiGetIpAddrsForIpEntity(tcpFile, &ip_ent, &addrs, &numAddrs);
|
||||
for(j = 0; NT_SUCCESS(status) && j < numAddrs; j++)
|
||||
{
|
||||
fprintf(stderr, "ADDR %d: index %ld (target %ld)\n", j,
|
||||
addrs[j].iae_index,
|
||||
infoSetInt[curInterf].if_info.ent.if_index);
|
||||
if(addrs[j].iae_index == infoSetInt[curInterf].if_info.ent.if_index)
|
||||
{
|
||||
memcpy(&infoSetInt[curInterf].ip_addr, &addrs[j],
|
||||
sizeof(addrs[j]));
|
||||
curInterf++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(NT_SUCCESS(status))
|
||||
tdiFreeThingSet(addrs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tdiFreeThingSet(entIDSet);
|
||||
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
*infoSet = infoSetInt;
|
||||
*numInterfaces = curInterf;
|
||||
}
|
||||
else
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, infoSetInt);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
tdiFreeThingSet(entIDSet);
|
||||
return ((NTSTATUS)0xC000009A);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
getInterfaceInfoByName(HANDLE tcpFile, char *name, IFInfo *info)
|
||||
{
|
||||
IFInfo *ifInfo;
|
||||
DWORD numInterfaces;
|
||||
unsigned i;
|
||||
NTSTATUS status = getInterfaceInfoSet(tcpFile, &ifInfo, &numInterfaces);
|
||||
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
for(i = 0; i < numInterfaces; i++)
|
||||
{
|
||||
if(!strcmp((PCHAR)ifInfo[i].if_info.ent.if_descr, name))
|
||||
{
|
||||
memcpy(info, &ifInfo[i], sizeof(*info));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, ifInfo);
|
||||
|
||||
return i < numInterfaces ? 0 : 0xc0000001;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
getInterfaceInfoByIndex(HANDLE tcpFile, DWORD index, IFInfo *info)
|
||||
{
|
||||
IFInfo *ifInfo;
|
||||
DWORD numInterfaces;
|
||||
NTSTATUS status = getInterfaceInfoSet(tcpFile, &ifInfo, &numInterfaces);
|
||||
unsigned i;
|
||||
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
for(i = 0; i < numInterfaces; i++)
|
||||
{
|
||||
if(ifInfo[i].if_info.ent.if_index == index)
|
||||
{
|
||||
memcpy(info, &ifInfo[i], sizeof(*info));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, ifInfo);
|
||||
|
||||
return i < numInterfaces ? 0 : 0xc0000001;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
getIPAddrEntryForIf(HANDLE tcpFile, char *name, DWORD index, IFInfo *ifInfo)
|
||||
{
|
||||
NTSTATUS status = name ? getInterfaceInfoByName(tcpFile, name, ifInfo)
|
||||
: getInterfaceInfoByIndex(tcpFile, index, ifInfo);
|
||||
|
||||
if(!NT_SUCCESS(status))
|
||||
{
|
||||
fprintf(stderr, "getIPAddrEntryForIf returning %lx\n", status);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
InterfaceIndexTable *
|
||||
getInterfaceIndexTableInt(BOOL nonLoopbackOnly)
|
||||
{
|
||||
DWORD numInterfaces, curInterface = 0;
|
||||
unsigned i;
|
||||
IFInfo *ifInfo;
|
||||
InterfaceIndexTable *ret = 0;
|
||||
HANDLE tcpFile;
|
||||
NTSTATUS status = openTcpFile(&tcpFile, FILE_READ_DATA);
|
||||
|
||||
ifInfo = NULL;
|
||||
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
status = getInterfaceInfoSet(tcpFile, &ifInfo, &numInterfaces);
|
||||
|
||||
fprintf(stderr, "InterfaceInfoSet: %08lx, %04lx:%08lx\n", status,
|
||||
ifInfo->entity_id.tei_entity, ifInfo->entity_id.tei_instance);
|
||||
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
ret = (InterfaceIndexTable *)calloc(
|
||||
1, sizeof(InterfaceIndexTable) + (numInterfaces - 1) * sizeof(DWORD));
|
||||
|
||||
if(ret)
|
||||
{
|
||||
ret->numAllocated = numInterfaces;
|
||||
fprintf(stderr, "NumInterfaces = %ld\n", numInterfaces);
|
||||
|
||||
for(i = 0; i < numInterfaces; i++)
|
||||
{
|
||||
fprintf(stderr, "Examining interface %d\n", i);
|
||||
if(!nonLoopbackOnly || !isLoopback(tcpFile, &ifInfo[i].entity_id))
|
||||
{
|
||||
fprintf(stderr, "Interface %d matches (%ld)\n", i, curInterface);
|
||||
ret->indexes[curInterface++] = ifInfo[i].if_info.ent.if_index;
|
||||
}
|
||||
}
|
||||
|
||||
ret->numIndexes = curInterface;
|
||||
}
|
||||
|
||||
tdiFreeThingSet(ifInfo);
|
||||
}
|
||||
closeTcpFile(tcpFile);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
InterfaceIndexTable *
|
||||
getInterfaceIndexTable(void)
|
||||
{
|
||||
return getInterfaceIndexTableInt(FALSE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// there's probably an use case for a _newer_ implementation
|
||||
// of pthread_setname_np(3), in fact, I may just merge _this_
|
||||
// upstream...
|
||||
#if 0
|
||||
#include <windows.h>
|
||||
|
||||
typedef HRESULT(FAR PASCAL *p_SetThreadDescription)(void *, const wchar_t *);
|
||||
#define EXCEPTION_SET_THREAD_NAME ((DWORD)0x406D1388)
|
||||
|
||||
typedef struct _THREADNAME_INFO
|
||||
{
|
||||
DWORD dwType; /* must be 0x1000 */
|
||||
LPCSTR szName; /* pointer to name (in user addr space) */
|
||||
DWORD dwThreadID; /* thread ID (-1=caller thread) */
|
||||
DWORD dwFlags; /* reserved for future use, must be zero */
|
||||
} THREADNAME_INFO;
|
||||
|
||||
void
|
||||
SetThreadName(DWORD dwThreadID, LPCSTR szThreadName)
|
||||
{
|
||||
THREADNAME_INFO info;
|
||||
DWORD infosize;
|
||||
HANDLE hThread;
|
||||
/* because loonix is SHIT and limits thread names to 16 bytes */
|
||||
wchar_t thr_name_w[16];
|
||||
p_SetThreadDescription _SetThreadDescription;
|
||||
|
||||
/* current win10 flights now have a new named-thread API, let's try to use
|
||||
* that first! */
|
||||
/* first, dlsym(2) the new call from system library */
|
||||
hThread = NULL;
|
||||
_SetThreadDescription = (p_SetThreadDescription)GetProcAddress(
|
||||
GetModuleHandle("kernel32"), "SetThreadDescription");
|
||||
if(_SetThreadDescription)
|
||||
{
|
||||
/* grab another reference to the thread */
|
||||
hThread = OpenThread(THREAD_SET_LIMITED_INFORMATION, FALSE, dwThreadID);
|
||||
/* windows takes unicode, our input is utf-8 or plain ascii */
|
||||
MultiByteToWideChar(CP_ACP, 0, szThreadName, -1, thr_name_w, 16);
|
||||
if(hThread)
|
||||
_SetThreadDescription(hThread, thr_name_w);
|
||||
else
|
||||
goto old; /* for whatever reason, we couldn't get a handle to the thread.
|
||||
Just use the old method. */
|
||||
}
|
||||
else
|
||||
{
|
||||
old:
|
||||
info.dwType = 0x1000;
|
||||
info.szName = szThreadName;
|
||||
info.dwThreadID = dwThreadID;
|
||||
info.dwFlags = 0;
|
||||
|
||||
infosize = sizeof(info) / sizeof(DWORD);
|
||||
|
||||
__try
|
||||
{
|
||||
RaiseException(EXCEPTION_SET_THREAD_NAME, 0, infosize, (DWORD *)&info);
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
}
|
||||
}
|
||||
/* clean up */
|
||||
if(hThread)
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
#endif
|
@ -1,111 +0,0 @@
|
||||
#ifndef WIN32_INTRNL_H
|
||||
#define WIN32_INTRNL_H
|
||||
/* if yer using Microsoft C++, then downlevel platforms are irrelevant to you */
|
||||
#if defined(__MINGW32__) && !defined(_WIN64)
|
||||
#ifndef NT_SUCCESS
|
||||
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
||||
#endif
|
||||
#include <tdiinfo.h>
|
||||
|
||||
typedef unsigned long ulong;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned int uint;
|
||||
|
||||
/* forward declare, each module has their own idea of what this is */
|
||||
typedef struct _InterfaceIndexTable InterfaceIndexTable;
|
||||
|
||||
typedef struct IFEntry
|
||||
{
|
||||
ulong if_index;
|
||||
ulong if_type;
|
||||
ulong if_mtu;
|
||||
ulong if_speed;
|
||||
ulong if_physaddrlen;
|
||||
uchar if_physaddr[8];
|
||||
ulong if_adminstatus;
|
||||
ulong if_operstatus;
|
||||
ulong if_lastchange;
|
||||
ulong if_inoctets;
|
||||
ulong if_inucastpkts;
|
||||
ulong if_innucastpkts;
|
||||
ulong if_indiscards;
|
||||
ulong if_inerrors;
|
||||
ulong if_inunknownprotos;
|
||||
ulong if_outoctets;
|
||||
ulong if_outucastpkts;
|
||||
ulong if_outnucastpkts;
|
||||
ulong if_outdiscards;
|
||||
ulong if_outerrors;
|
||||
ulong if_outqlen;
|
||||
ulong if_descrlen;
|
||||
uchar if_descr[1];
|
||||
} IFEntry;
|
||||
|
||||
typedef struct IPAddrEntry
|
||||
{
|
||||
ulong iae_addr;
|
||||
ulong iae_index;
|
||||
ulong iae_mask;
|
||||
ulong iae_bcastaddr;
|
||||
ulong iae_reasmsize;
|
||||
ushort iae_context;
|
||||
ushort iae_pad;
|
||||
} IPAddrEntry;
|
||||
|
||||
typedef union _IFEntrySafelySized {
|
||||
CHAR MaxSize[sizeof(DWORD) + sizeof(IFEntry) + 128 + 1];
|
||||
IFEntry ent;
|
||||
} IFEntrySafelySized;
|
||||
|
||||
#ifndef IFENT_SOFTWARE_LOOPBACK
|
||||
#define IFENT_SOFTWARE_LOOPBACK 24 /* This is an SNMP constant from rfc1213 */
|
||||
#endif /*IFENT_SOFTWARE_LOOPBACK*/
|
||||
|
||||
/* Encapsulates information about an interface */
|
||||
typedef struct _IFInfo
|
||||
{
|
||||
TDIEntityID entity_id;
|
||||
IFEntrySafelySized if_info;
|
||||
IPAddrEntry ip_addr;
|
||||
} IFInfo;
|
||||
|
||||
/* functions */
|
||||
NTSTATUS
|
||||
openTcpFile(PHANDLE tcpFile, ACCESS_MASK DesiredAccess);
|
||||
|
||||
VOID
|
||||
closeTcpFile(HANDLE h);
|
||||
|
||||
BOOL
|
||||
isLoopback(HANDLE tcpFile, TDIEntityID* loop_maybe);
|
||||
|
||||
BOOL
|
||||
isIpEntity(HANDLE tcpFile, TDIEntityID* ent);
|
||||
|
||||
NTSTATUS
|
||||
getNthIpEntity(HANDLE tcpFile, DWORD index, TDIEntityID* ent);
|
||||
|
||||
BOOL
|
||||
isInterface(TDIEntityID* if_maybe);
|
||||
|
||||
NTSTATUS
|
||||
getInterfaceInfoSet(HANDLE tcpFile, IFInfo** infoSet, PDWORD numInterfaces);
|
||||
|
||||
NTSTATUS
|
||||
getInterfaceInfoByName(HANDLE tcpFile, char* name, IFInfo* info);
|
||||
|
||||
NTSTATUS
|
||||
getInterfaceInfoByIndex(HANDLE tcpFile, DWORD index, IFInfo* info);
|
||||
|
||||
NTSTATUS
|
||||
getIPAddrEntryForIf(HANDLE tcpFile, char* name, DWORD index, IFInfo* ifInfo);
|
||||
|
||||
InterfaceIndexTable*
|
||||
getInterfaceIndexTableInt(BOOL nonLoopbackOnly);
|
||||
|
||||
InterfaceIndexTable*
|
||||
getInterfaceIndexTable(void);
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,8 +1,7 @@
|
||||
#!/usr/bin/env sh
|
||||
#
|
||||
#!/usr/bin/env bash
|
||||
# this shell script will be replaced by a proper program in the future (probably)
|
||||
#
|
||||
|
||||
if [ "X$1" = "X" ] ; then url="https://i2p.rocks/i2procks.signed" ; else url="$1" ; fi
|
||||
echo "downloading $url"
|
||||
wget -O $HOME/.lokinet/bootstrap.signed "$url" || echo "failed to download bootstrap from $url"
|
||||
wget -O $HOME/.lokinet/bootstrap.signed "$url" || echo "failed to download bootstrap from $url"
|
@ -0,0 +1,33 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <llarp/aligned.hpp>
|
||||
|
||||
using Buffer_t = llarp::AlignedBuffer< 32 >;
|
||||
using Map_t = std::unordered_map< Buffer_t, int, Buffer_t::Hash >;
|
||||
|
||||
struct AlignedBufferTest : public ::testing::Test
|
||||
{
|
||||
AlignedBufferTest()
|
||||
{
|
||||
llarp_crypto_init(&crypto);
|
||||
}
|
||||
|
||||
llarp_crypto crypto;
|
||||
};
|
||||
|
||||
TEST_F(AlignedBufferTest, TestHash)
|
||||
{
|
||||
Buffer_t k, other_k;
|
||||
k.Randomize();
|
||||
other_k.Randomize();
|
||||
Map_t m;
|
||||
ASSERT_TRUE(m.empty());
|
||||
ASSERT_TRUE(m.emplace(k, 1).second);
|
||||
ASSERT_TRUE(m.find(k) != m.end());
|
||||
ASSERT_TRUE(m[k] == 1);
|
||||
ASSERT_FALSE(m.find(other_k) != m.end());
|
||||
ASSERT_TRUE(m.size() == 1);
|
||||
Buffer_t k_copy = k;
|
||||
ASSERT_FALSE(m.emplace(k_copy, 2).second);
|
||||
ASSERT_FALSE(m[k_copy] == 2);
|
||||
ASSERT_TRUE(m[k_copy] == 1);
|
||||
};
|
@ -0,0 +1,30 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <llarp/exit.hpp>
|
||||
#include "router.hpp"
|
||||
|
||||
struct ExitTest : public ::testing::Test
|
||||
{
|
||||
ExitTest()
|
||||
{
|
||||
llarp_crypto_init(&r.crypto);
|
||||
}
|
||||
llarp_router r;
|
||||
};
|
||||
|
||||
TEST_F(ExitTest, AddMultipleIP)
|
||||
{
|
||||
llarp::PubKey pk;
|
||||
pk.Randomize();
|
||||
llarp::PathID_t firstPath, secondPath;
|
||||
firstPath.Randomize();
|
||||
secondPath.Randomize();
|
||||
llarp::exit::Context::Config_t conf;
|
||||
conf.emplace("exit", "true");
|
||||
conf.emplace("type", "null");
|
||||
conf.emplace("ifaddr", "10.0.0.1/24");
|
||||
ASSERT_TRUE(r.exitContext.AddExitEndpoint("test-exit", conf));
|
||||
ASSERT_TRUE(r.exitContext.ObtainNewExit(pk, firstPath, true));
|
||||
ASSERT_TRUE(r.exitContext.ObtainNewExit(pk, secondPath, true));
|
||||
ASSERT_TRUE(r.exitContext.FindEndpointForPath(firstPath)->LocalIP()
|
||||
== r.exitContext.FindEndpointForPath(secondPath)->LocalIP());
|
||||
};
|
Loading…
Reference in New Issue