mirror of
https://github.com/moonlight-stream/Internet-Hosting-Tool.git
synced 2025-07-01 23:35:27 +00:00
Remove IPv6 UPnP code from MISS
This commit is contained in:
parent
23ef57c20f
commit
c6837c95f1
223
miss/miss.cpp
223
miss/miss.cpp
@ -55,27 +55,6 @@ static struct port_entry {
|
|||||||
|
|
||||||
static const int k_WolPorts[] = { 9 };
|
static const int k_WolPorts[] = { 9 };
|
||||||
|
|
||||||
void UPnPCreatePinholeForPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const char* myAddr, int port)
|
|
||||||
{
|
|
||||||
char uniqueId[8];
|
|
||||||
char protoStr[3];
|
|
||||||
char portStr[6];
|
|
||||||
|
|
||||||
snprintf(portStr, sizeof(portStr), "%d", port);
|
|
||||||
snprintf(protoStr, sizeof(protoStr), "%d", proto);
|
|
||||||
|
|
||||||
printf("Creating UPnP IPv6 pinhole for %s %s -> %s...", protoStr, portStr, myAddr);
|
|
||||||
|
|
||||||
// Lease time is in seconds - 7200 = 2 hours
|
|
||||||
int err = UPNP_AddPinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, "empty", portStr, myAddr, portStr, protoStr, "7200", uniqueId);
|
|
||||||
if (err == UPNPCOMMAND_SUCCESS) {
|
|
||||||
printf("OK" NL);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
printf("ERROR %d (%s)" NL, err, strupnperror(err));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UPnPMapPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const char* myAddr, int port, bool enable, bool indefinite)
|
bool UPnPMapPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const char* myAddr, int port, bool enable, bool indefinite)
|
||||||
{
|
{
|
||||||
char intClient[16];
|
char intClient[16];
|
||||||
@ -196,93 +175,6 @@ bool UPnPMapPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResolveStableIP6Address(char* tmpAddr)
|
|
||||||
{
|
|
||||||
union {
|
|
||||||
IP_ADAPTER_ADDRESSES addresses;
|
|
||||||
char buffer[8192];
|
|
||||||
};
|
|
||||||
ULONG error;
|
|
||||||
ULONG length;
|
|
||||||
PIP_ADAPTER_ADDRESSES currentAdapter;
|
|
||||||
PIP_ADAPTER_UNICAST_ADDRESS currentAddress;
|
|
||||||
in6_addr targetAddress;
|
|
||||||
|
|
||||||
inet_pton(AF_INET6, tmpAddr, &targetAddress);
|
|
||||||
|
|
||||||
// Get a list of all interfaces with IPv6 addresses on the system
|
|
||||||
length = sizeof(buffer);
|
|
||||||
error = GetAdaptersAddresses(AF_INET6,
|
|
||||||
GAA_FLAG_SKIP_ANYCAST |
|
|
||||||
GAA_FLAG_SKIP_MULTICAST |
|
|
||||||
GAA_FLAG_SKIP_DNS_SERVER |
|
|
||||||
GAA_FLAG_SKIP_FRIENDLY_NAME,
|
|
||||||
NULL,
|
|
||||||
&addresses,
|
|
||||||
&length);
|
|
||||||
if (error != ERROR_SUCCESS) {
|
|
||||||
printf("GetAdaptersAddresses() failed: %d" NL, error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentAdapter = &addresses;
|
|
||||||
currentAddress = nullptr;
|
|
||||||
while (currentAdapter != nullptr) {
|
|
||||||
// First, search for the adapter
|
|
||||||
currentAddress = currentAdapter->FirstUnicastAddress;
|
|
||||||
while (currentAddress != nullptr) {
|
|
||||||
assert(currentAddress->Address.lpSockaddr->sa_family == AF_INET6);
|
|
||||||
|
|
||||||
PSOCKADDR_IN6 currentAddrV6 = (PSOCKADDR_IN6)currentAddress->Address.lpSockaddr;
|
|
||||||
|
|
||||||
if (RtlEqualMemory(¤tAddrV6->sin6_addr, &targetAddress, sizeof(targetAddress))) {
|
|
||||||
// Found interface with matching address
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentAddress = currentAddress->Next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentAddress != nullptr) {
|
|
||||||
// Get out of the loop if we found the matching address
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentAdapter = currentAdapter->Next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentAdapter == nullptr) {
|
|
||||||
printf("No adapter found with IPv6 address: %s" NL, tmpAddr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now currentAdapter is the adapter we reached the IGD with. Find a suitable
|
|
||||||
// public address that we can use to create the pinhole.
|
|
||||||
currentAddress = currentAdapter->FirstUnicastAddress;
|
|
||||||
while (currentAddress != nullptr) {
|
|
||||||
assert(currentAddress->Address.lpSockaddr->sa_family == AF_INET6);
|
|
||||||
|
|
||||||
PSOCKADDR_IN6 currentAddrV6 = (PSOCKADDR_IN6)currentAddress->Address.lpSockaddr;
|
|
||||||
|
|
||||||
// Exclude temporary addresses and link-local addresses
|
|
||||||
if (currentAddress->SuffixOrigin != IpSuffixOriginRandom && currentAddrV6->sin6_scope_id == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentAddress = currentAddress->Next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentAddress == nullptr) {
|
|
||||||
printf("No suitable alternate address found for %s" NL, tmpAddr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PSOCKADDR_IN6 currentAddrV6 = (PSOCKADDR_IN6)currentAddress->Address.lpSockaddr;
|
|
||||||
inet_ntop(AF_INET6, ¤tAddrV6->sin6_addr, tmpAddr, 128);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetIP4OnLinkPrefixLength(char* lanAddressString, int* prefixLength)
|
bool GetIP4OnLinkPrefixLength(char* lanAddressString, int* prefixLength)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
@ -336,7 +228,7 @@ bool GetIP4OnLinkPrefixLength(char* lanAddressString, int* prefixLength)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UPnPHandleDeviceList(struct UPNPDev* list, bool ipv6, bool enable, char* lanAddrOverride, char* wanAddr)
|
bool UPnPHandleDeviceList(struct UPNPDev* list, bool enable, char* lanAddrOverride, char* wanAddr)
|
||||||
{
|
{
|
||||||
struct UPNPUrls urls;
|
struct UPNPUrls urls;
|
||||||
struct IGDdatas data;
|
struct IGDdatas data;
|
||||||
@ -369,40 +261,13 @@ bool UPnPHandleDeviceList(struct UPNPDev* list, bool ipv6, bool enable, char* la
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ipv6) {
|
ret = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, wanAddr);
|
||||||
// Convert what is likely a IPv6 temporary address into
|
if (ret == UPNPCOMMAND_SUCCESS) {
|
||||||
// the stable IPv6 address for the same interface.
|
printf("UPnP IGD WAN address is: %s" NL, wanAddr);
|
||||||
if (ResolveStableIP6Address(localAddress)) {
|
|
||||||
printf("Stable global IPv6 address is: %s" NL, localAddress);
|
|
||||||
|
|
||||||
// Don't try IPv6FC without a control URL
|
|
||||||
if (data.IPv6FC.controlurl[0] != 0) {
|
|
||||||
int firewallEnabled;
|
|
||||||
ret = UPNP_GetFirewallStatus(urls.controlURL_6FC, data.IPv6FC.servicetype, &firewallEnabled, &pinholeAllowed);
|
|
||||||
if (ret == UPNPCOMMAND_SUCCESS) {
|
|
||||||
printf("UPnP IPv6 firewall control available. Firewall is %s, pinhole is %s" NL,
|
|
||||||
firewallEnabled ? "enabled" : "disabled",
|
|
||||||
pinholeAllowed ? "allowed" : "disallowed");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
printf("UPnP IPv6 firewall control is unavailable with error %d (%s)" NL, ret, strupnperror(ret));
|
|
||||||
pinholeAllowed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
printf("IPv6 firewall control not supported by UPnP IGD!" NL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ret = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, wanAddr);
|
// Empty string
|
||||||
if (ret == UPNPCOMMAND_SUCCESS) {
|
*wanAddr = 0;
|
||||||
printf("UPnP IGD WAN address is: %s" NL, wanAddr);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Empty string
|
|
||||||
*wanAddr = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We may be mapping on behalf of another device
|
// We may be mapping on behalf of another device
|
||||||
@ -414,44 +279,37 @@ bool UPnPHandleDeviceList(struct UPNPDev* list, bool ipv6, bool enable, char* la
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < ARRAYSIZE(k_Ports); i++) {
|
for (int i = 0; i < ARRAYSIZE(k_Ports); i++) {
|
||||||
if (!ipv6) {
|
if (!UPnPMapPort(&urls, &data, k_Ports[i].proto, portMappingInternalAddress, k_Ports[i].port, enable, false)) {
|
||||||
if (!UPnPMapPort(&urls, &data, k_Ports[i].proto, portMappingInternalAddress, k_Ports[i].port, enable, false)) {
|
success = false;
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pinholeAllowed) {
|
|
||||||
UPnPCreatePinholeForPort(&urls, &data, k_Ports[i].proto, portMappingInternalAddress, k_Ports[i].port);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do a best-effort for IPv4 Wake-on-LAN broadcast mappings
|
// Do a best-effort for IPv4 Wake-on-LAN broadcast mappings
|
||||||
if (!ipv6) {
|
for (int i = 0; i < ARRAYSIZE(k_WolPorts); i++) {
|
||||||
for (int i = 0; i < ARRAYSIZE(k_WolPorts); i++) {
|
if (lanAddrOverride == nullptr) {
|
||||||
if (lanAddrOverride == nullptr) {
|
// Map the port to the broadcast address (may not work on all routers). This
|
||||||
// Map the port to the broadcast address (may not work on all routers). This
|
// ensures delivery even after the ARP entry for this PC times out on the router.
|
||||||
// ensures delivery even after the ARP entry for this PC times out on the router.
|
int onLinkPrefixLen;
|
||||||
int onLinkPrefixLen;
|
if (GetIP4OnLinkPrefixLength(localAddress, &onLinkPrefixLen)) {
|
||||||
if (GetIP4OnLinkPrefixLength(localAddress, &onLinkPrefixLen)) {
|
int netmask = 0;
|
||||||
int netmask = 0;
|
for (int j = 0; j < onLinkPrefixLen; j++) {
|
||||||
for (int j = 0; j < onLinkPrefixLen; j++) {
|
netmask |= (1 << j);
|
||||||
netmask |= (1 << j);
|
|
||||||
}
|
|
||||||
|
|
||||||
in_addr broadcastAddr;
|
|
||||||
broadcastAddr.S_un.S_addr = inet_addr(localAddress);
|
|
||||||
broadcastAddr.S_un.S_addr |= ~netmask;
|
|
||||||
|
|
||||||
char broadcastAddrStr[128];
|
|
||||||
inet_ntop(AF_INET, &broadcastAddr, broadcastAddrStr, sizeof(broadcastAddrStr));
|
|
||||||
|
|
||||||
UPnPMapPort(&urls, &data, IPPROTO_UDP, broadcastAddrStr, k_WolPorts[i], enable, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
in_addr broadcastAddr;
|
||||||
|
broadcastAddr.S_un.S_addr = inet_addr(localAddress);
|
||||||
|
broadcastAddr.S_un.S_addr |= ~netmask;
|
||||||
|
|
||||||
|
char broadcastAddrStr[128];
|
||||||
|
inet_ntop(AF_INET, &broadcastAddr, broadcastAddrStr, sizeof(broadcastAddrStr));
|
||||||
|
|
||||||
|
UPnPMapPort(&urls, &data, IPPROTO_UDP, broadcastAddrStr, k_WolPorts[i], enable, true);
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
// When we're mapping the WOL ports upstream of our router, we map directly to
|
else {
|
||||||
// the port on the upstream address (likely our router's WAN interface).
|
// When we're mapping the WOL ports upstream of our router, we map directly to
|
||||||
UPnPMapPort(&urls, &data, IPPROTO_UDP, lanAddrOverride, k_WolPorts[i], enable, true);
|
// the port on the upstream address (likely our router's WAN interface).
|
||||||
}
|
UPnPMapPort(&urls, &data, IPPROTO_UDP, lanAddrOverride, k_WolPorts[i], enable, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,7 +525,7 @@ void UpdatePortMappingsForTarget(bool enable, char* targetAddressIP4, char* inte
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Don't try NAT-PMP if UPnP succeeds
|
// Don't try NAT-PMP if UPnP succeeds
|
||||||
if (UPnPHandleDeviceList(ipv4Devs, false, enable, internalAddressIP4, upstreamAddrUPnP)) {
|
if (UPnPHandleDeviceList(ipv4Devs, enable, internalAddressIP4, upstreamAddrUPnP)) {
|
||||||
printf("UPnP IPv4 port mapping successful" NL);
|
printf("UPnP IPv4 port mapping successful" NL);
|
||||||
if (enable) {
|
if (enable) {
|
||||||
// We still want to try NAT-PMP if we're removing
|
// We still want to try NAT-PMP if we're removing
|
||||||
@ -682,23 +540,6 @@ void UpdatePortMappingsForTarget(bool enable, char* targetAddressIP4, char* inte
|
|||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
// Only run IPv6 UPnP discovery on the first hop
|
|
||||||
if (targetAddressIP4 == nullptr) {
|
|
||||||
int upnpErr;
|
|
||||||
struct UPNPDev* ipv6Devs = upnpDiscoverAll(UPNP_DISCOVERY_DELAY_MS, nullptr, nullptr, UPNP_LOCAL_PORT_ANY, 1, 2, &upnpErr);
|
|
||||||
char ipv6WanAddr[128] = {};
|
|
||||||
|
|
||||||
printf("UPnP IPv6 IGD discovery completed with error code: %d" NL, upnpErr);
|
|
||||||
|
|
||||||
// Ignore whether IPv6 succeeded when decided to use NAT-PMP
|
|
||||||
|
|
||||||
UPnPHandleDeviceList(ipv6Devs, true, enable, nullptr, ipv6WanAddr);
|
|
||||||
|
|
||||||
freeUPNPDevlist(ipv6Devs);
|
|
||||||
}
|
|
||||||
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
if (natPmpErr == 0) {
|
if (natPmpErr == 0) {
|
||||||
// NAT-PMP has no description field or other token that we can use to determine
|
// NAT-PMP has no description field or other token that we can use to determine
|
||||||
// if we created the rules we'd be deleting. Since we don't have that, we can't
|
// if we created the rules we'd be deleting. Since we don't have that, we can't
|
||||||
|
Loading…
x
Reference in New Issue
Block a user