Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1ca6a71f0 | ||
|
|
ac92212464 | ||
|
|
dbf43ac7a1 | ||
|
|
893aa76c9c | ||
|
|
21d8c71a2c | ||
|
|
41ef072c9b | ||
|
|
53246bd4c5 | ||
|
|
ac850e79d8 | ||
|
|
944c8993e8 | ||
|
|
b6508d9024 |
@@ -80,6 +80,43 @@
|
|||||||
Name="Moonlight Internet Streaming Tester"/>
|
Name="Moonlight Internet Streaming Tester"/>
|
||||||
</File>
|
</File>
|
||||||
</Component>
|
</Component>
|
||||||
|
<Component Id="GameStreamFirewallRules" Guid="{16CA2511-B533-46F8-8882-F8AEEFDFD7DF}" KeyPath="yes">
|
||||||
|
<fire:FirewallException Id="HttpsFwException"
|
||||||
|
Scope="any"
|
||||||
|
Port="47984"
|
||||||
|
Protocol="tcp"
|
||||||
|
Name="Moonlight - HTTPS"/>
|
||||||
|
<fire:FirewallException Id="HttpFwException"
|
||||||
|
Scope="any"
|
||||||
|
Port="47989"
|
||||||
|
Protocol="tcp"
|
||||||
|
Name="Moonlight - HTTP"/>
|
||||||
|
<fire:FirewallException Id="RtspFwException"
|
||||||
|
Scope="any"
|
||||||
|
Port="48010"
|
||||||
|
Protocol="tcp"
|
||||||
|
Name="Moonlight - RTSP"/>
|
||||||
|
<fire:FirewallException Id="VideoFwException"
|
||||||
|
Scope="any"
|
||||||
|
Port="47998"
|
||||||
|
Protocol="udp"
|
||||||
|
Name="Moonlight - Video"/>
|
||||||
|
<fire:FirewallException Id="ControlFwException"
|
||||||
|
Scope="any"
|
||||||
|
Port="47999"
|
||||||
|
Protocol="udp"
|
||||||
|
Name="Moonlight - Control"/>
|
||||||
|
<fire:FirewallException Id="AudioFwException"
|
||||||
|
Scope="any"
|
||||||
|
Port="48000"
|
||||||
|
Protocol="udp"
|
||||||
|
Name="Moonlight - Audio"/>
|
||||||
|
<fire:FirewallException Id="RtspuFwException"
|
||||||
|
Scope="any"
|
||||||
|
Port="48010"
|
||||||
|
Protocol="udp"
|
||||||
|
Name="Moonlight - RTSPU"/>
|
||||||
|
</Component>
|
||||||
<Component Id="Shortcuts" Guid="*">
|
<Component Id="Shortcuts" Guid="*">
|
||||||
<Shortcut Id="StartMenuShortcut"
|
<Shortcut Id="StartMenuShortcut"
|
||||||
Name="Moonlight Internet Streaming Tester"
|
Name="Moonlight Internet Streaming Tester"
|
||||||
|
|||||||
+30
-23
@@ -116,7 +116,7 @@ bool UPnPMapPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const
|
|||||||
// Some routers change the description, so we can't check that here
|
// Some routers change the description, so we can't check that here
|
||||||
if (!strcmp(intClient, myAddr)) {
|
if (!strcmp(intClient, myAddr)) {
|
||||||
if (atoi(leaseDuration) == 0) {
|
if (atoi(leaseDuration) == 0) {
|
||||||
printf("OK (Static)" NL);
|
printf("OK (Static, Internal port: %s)" NL, intPort);
|
||||||
|
|
||||||
// If we have an existing permanent mapping, we can just leave it alone.
|
// If we have an existing permanent mapping, we can just leave it alone.
|
||||||
if (enable) {
|
if (enable) {
|
||||||
@@ -124,7 +124,7 @@ bool UPnPMapPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printf("OK (%s seconds remaining)" NL, leaseDuration);
|
printf("OK (%s seconds remaining, Internal port: %s)" NL, leaseDuration, intPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're just validating, we found an entry, so we're done.
|
// If we're just validating, we found an entry, so we're done.
|
||||||
@@ -206,7 +206,7 @@ bool UPnPMapPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const
|
|||||||
else if (indefinite) {
|
else if (indefinite) {
|
||||||
printf("STATIC ");
|
printf("STATIC ");
|
||||||
}
|
}
|
||||||
if (err == 718 && proto == IPPROTO_UDP) { // ConflictInMappingEntry
|
if (err == 718 && proto == IPPROTO_UDP && port >= 47000) { // ConflictInMappingEntry
|
||||||
// Some UPnP implementations incorrectly deduplicate on the internal port instead
|
// Some UPnP implementations incorrectly deduplicate on the internal port instead
|
||||||
// of the external port, in violation of the UPnP IGD specification. Since GFE creates
|
// of the external port, in violation of the UPnP IGD specification. Since GFE creates
|
||||||
// mappings on the same internal port as us, those routers break our mappings. To
|
// mappings on the same internal port as us, those routers break our mappings. To
|
||||||
@@ -415,7 +415,7 @@ bool NATPMPMapPort(natpmp_t* natpmp, int proto, int port, bool enable, bool inde
|
|||||||
lifetime = 604800; // 1 week
|
lifetime = 604800; // 1 week
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lifetime = 3600;
|
lifetime = PORT_MAPPING_DURATION_SEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Updating NAT-PMP port mapping for %s %d...", proto == IPPROTO_TCP ? "TCP" : "UDP", port);
|
printf("Updating NAT-PMP port mapping for %s %d...", proto == IPPROTO_TCP ? "TCP" : "UDP", port);
|
||||||
@@ -805,25 +805,28 @@ void NETIOAPI_API_ IpInterfaceChangeNotificationCallback(PVOID context, PMIB_IPI
|
|||||||
SetEvent((HANDLE)context);
|
SetEvent((HANDLE)context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResetLogFile()
|
void ResetLogFile(bool standaloneExe)
|
||||||
{
|
{
|
||||||
char oldLogFilePath[MAX_PATH + 1];
|
|
||||||
char currentLogFilePath[MAX_PATH + 1];
|
|
||||||
char timeString[MAX_PATH + 1] = {};
|
char timeString[MAX_PATH + 1] = {};
|
||||||
SYSTEMTIME time;
|
SYSTEMTIME time;
|
||||||
|
|
||||||
ExpandEnvironmentStringsA("%ProgramData%\\MISS\\miss-old.log", oldLogFilePath, sizeof(oldLogFilePath));
|
if (!standaloneExe) {
|
||||||
ExpandEnvironmentStringsA("%ProgramData%\\MISS\\miss-current.log", currentLogFilePath, sizeof(currentLogFilePath));
|
char oldLogFilePath[MAX_PATH + 1];
|
||||||
|
char currentLogFilePath[MAX_PATH + 1];
|
||||||
|
|
||||||
// Close the existing stdout handle. This is important because otherwise
|
ExpandEnvironmentStringsA("%ProgramData%\\MISS\\miss-old.log", oldLogFilePath, sizeof(oldLogFilePath));
|
||||||
// it may still be open as stdout when we try to MoveFileEx below.
|
ExpandEnvironmentStringsA("%ProgramData%\\MISS\\miss-current.log", currentLogFilePath, sizeof(currentLogFilePath));
|
||||||
fclose(stdout);
|
|
||||||
|
|
||||||
// Rotate the current to the old log file
|
// Close the existing stdout handle. This is important because otherwise
|
||||||
MoveFileExA(currentLogFilePath, oldLogFilePath, MOVEFILE_REPLACE_EXISTING);
|
// it may still be open as stdout when we try to MoveFileEx below.
|
||||||
|
fclose(stdout);
|
||||||
|
|
||||||
// Redirect stdout to this new file
|
// Rotate the current to the old log file
|
||||||
freopen(currentLogFilePath, "w", stdout);
|
MoveFileExA(currentLogFilePath, oldLogFilePath, MOVEFILE_REPLACE_EXISTING);
|
||||||
|
|
||||||
|
// Redirect stdout to this new file
|
||||||
|
freopen(currentLogFilePath, "w", stdout);
|
||||||
|
}
|
||||||
|
|
||||||
// Print a log header
|
// Print a log header
|
||||||
printf("Moonlight Internet Streaming Service v" VER_VERSION_STR NL);
|
printf("Moonlight Internet Streaming Service v" VER_VERSION_STR NL);
|
||||||
@@ -860,13 +863,17 @@ DWORD WINAPI GameStreamStateChangeThread(PVOID Context)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Run()
|
int Run(bool standaloneExe)
|
||||||
{
|
{
|
||||||
HANDLE ifaceChangeEvent = CreateEvent(nullptr, true, false, nullptr);
|
HANDLE ifaceChangeEvent = CreateEvent(nullptr, true, false, nullptr);
|
||||||
HANDLE gsChangeEvent = CreateEvent(nullptr, true, false, nullptr);
|
HANDLE gsChangeEvent = CreateEvent(nullptr, true, false, nullptr);
|
||||||
HANDLE events[2] = { ifaceChangeEvent, gsChangeEvent };
|
HANDLE events[2] = { ifaceChangeEvent, gsChangeEvent };
|
||||||
|
|
||||||
ResetLogFile();
|
ResetLogFile(standaloneExe);
|
||||||
|
|
||||||
|
// Bump the process priority class to above normal. The UDP relay threads will
|
||||||
|
// further raise their own thread priorities to avoid preemption by other activity.
|
||||||
|
SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS);
|
||||||
|
|
||||||
// Create the UDP alternate port relays
|
// Create the UDP alternate port relays
|
||||||
for (int i = 0; i < ARRAYSIZE(k_Ports); i++) {
|
for (int i = 0; i < ARRAYSIZE(k_Ports); i++) {
|
||||||
@@ -895,7 +902,7 @@ int Run()
|
|||||||
ULONGLONG beforeSleepTime = GetTickCount64();
|
ULONGLONG beforeSleepTime = GetTickCount64();
|
||||||
DWORD ret = WaitForMultipleObjects(ARRAYSIZE(events), events, false, POLLING_DELAY_SEC * 1000);
|
DWORD ret = WaitForMultipleObjects(ARRAYSIZE(events), events, false, POLLING_DELAY_SEC * 1000);
|
||||||
if (ret == WAIT_OBJECT_0) {
|
if (ret == WAIT_OBJECT_0) {
|
||||||
ResetLogFile();
|
ResetLogFile(standaloneExe);
|
||||||
|
|
||||||
printf("Woke up for interface change notification after %lld seconds" NL,
|
printf("Woke up for interface change notification after %lld seconds" NL,
|
||||||
(GetTickCount64() - beforeSleepTime) / 1000);
|
(GetTickCount64() - beforeSleepTime) / 1000);
|
||||||
@@ -904,13 +911,13 @@ int Run()
|
|||||||
Sleep(10000);
|
Sleep(10000);
|
||||||
}
|
}
|
||||||
else if (ret == WAIT_OBJECT_0 + 1) {
|
else if (ret == WAIT_OBJECT_0 + 1) {
|
||||||
ResetLogFile();
|
ResetLogFile(standaloneExe);
|
||||||
|
|
||||||
printf("Woke up for GameStream state change notification after %lld seconds" NL,
|
printf("Woke up for GameStream state change notification after %lld seconds" NL,
|
||||||
(GetTickCount64() - beforeSleepTime) / 1000);
|
(GetTickCount64() - beforeSleepTime) / 1000);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ResetLogFile();
|
ResetLogFile(standaloneExe);
|
||||||
|
|
||||||
printf("Woke up for periodic refresh" NL);
|
printf("Woke up for periodic refresh" NL);
|
||||||
}
|
}
|
||||||
@@ -971,7 +978,7 @@ ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
|
|||||||
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
||||||
|
|
||||||
// Start the service
|
// Start the service
|
||||||
err = Run();
|
err = Run(false);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
|
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
|
||||||
ServiceStatus.dwWin32ExitCode = err;
|
ServiceStatus.dwWin32ExitCode = err;
|
||||||
@@ -994,7 +1001,7 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (argc == 2 && !strcmp(argv[1], "exe")) {
|
if (argc == 2 && !strcmp(argv[1], "exe")) {
|
||||||
Run();
|
Run(true);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-16
@@ -19,34 +19,28 @@ WINAPI
|
|||||||
UdpRelayThreadProc(LPVOID Context)
|
UdpRelayThreadProc(LPVOID Context)
|
||||||
{
|
{
|
||||||
PUDP_TUPLE tuple = (PUDP_TUPLE)Context;
|
PUDP_TUPLE tuple = (PUDP_TUPLE)Context;
|
||||||
fd_set fds;
|
USHORT nboPort = htons(tuple->port);
|
||||||
int err;
|
|
||||||
SOCKADDR_IN lastRemoteAddr;
|
SOCKADDR_IN lastRemoteAddr;
|
||||||
|
|
||||||
|
// Ensure the relay threads aren't preempted by games or other CPU intensive activity
|
||||||
|
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
|
||||||
|
|
||||||
RtlZeroMemory(&lastRemoteAddr, sizeof(lastRemoteAddr));
|
RtlZeroMemory(&lastRemoteAddr, sizeof(lastRemoteAddr));
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
char buffer[4096];
|
char buffer[4096];
|
||||||
SOCKADDR_IN sourceAddr;
|
SOCKADDR_IN sourceAddr;
|
||||||
int sourceAddrLen;
|
int sourceAddrLen;
|
||||||
|
int recvLen;
|
||||||
FD_ZERO(&fds);
|
|
||||||
|
|
||||||
FD_SET(tuple->socket, &fds);
|
|
||||||
|
|
||||||
err = select(0, &fds, NULL, NULL, NULL);
|
|
||||||
if (err <= 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceAddrLen = sizeof(sourceAddr);
|
sourceAddrLen = sizeof(sourceAddr);
|
||||||
err = recvfrom(tuple->socket, buffer, sizeof(buffer), 0, (PSOCKADDR)&sourceAddr, &sourceAddrLen);
|
recvLen = recvfrom(tuple->socket, buffer, sizeof(buffer), 0, (PSOCKADDR)&sourceAddr, &sourceAddrLen);
|
||||||
if (err == SOCKET_ERROR) {
|
if (recvLen == SOCKET_ERROR) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOCKADDR_IN destinationAddr;
|
SOCKADDR_IN destinationAddr;
|
||||||
if (RtlEqualMemory(&sourceAddr.sin_addr, &in4addr_loopback, sizeof(sourceAddr.sin_addr))) {
|
if (RtlEqualMemory(&sourceAddr.sin_addr, &in4addr_loopback, sizeof(sourceAddr.sin_addr)) && sourceAddr.sin_port == nboPort) {
|
||||||
// Traffic incoming from loopback interface - send it to the last remote address
|
// Traffic incoming from loopback interface - send it to the last remote address
|
||||||
destinationAddr = lastRemoteAddr;
|
destinationAddr = lastRemoteAddr;
|
||||||
}
|
}
|
||||||
@@ -57,10 +51,10 @@ UdpRelayThreadProc(LPVOID Context)
|
|||||||
// Send it to the normal port via the loopback adapter
|
// Send it to the normal port via the loopback adapter
|
||||||
destinationAddr = sourceAddr;
|
destinationAddr = sourceAddr;
|
||||||
destinationAddr.sin_addr = in4addr_loopback;
|
destinationAddr.sin_addr = in4addr_loopback;
|
||||||
destinationAddr.sin_port = htons(tuple->port);
|
destinationAddr.sin_port = nboPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendto(tuple->socket, buffer, err, 0, (PSOCKADDR)&destinationAddr, sizeof(destinationAddr));
|
sendto(tuple->socket, buffer, recvLen, 0, (PSOCKADDR)&destinationAddr, sizeof(destinationAddr));
|
||||||
}
|
}
|
||||||
|
|
||||||
closesocket(tuple->socket);
|
closesocket(tuple->socket);
|
||||||
|
|||||||
+1
-1
@@ -1002,7 +1002,7 @@ UPnPPortStatus UPnPCheckPort(struct UPNPUrls* urls, struct IGDdatas* data, int p
|
|||||||
}
|
}
|
||||||
else if (err == UPNPCOMMAND_SUCCESS) {
|
else if (err == UPNPCOMMAND_SUCCESS) {
|
||||||
if (!strcmp(myAddr, intClient)) {
|
if (!strcmp(myAddr, intClient)) {
|
||||||
fprintf(LOG_OUT, "OK\n");
|
fprintf(LOG_OUT, "OK (Internal port: %s)\n", intPort);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define VER_VERSION 5,2,0,0
|
#define VER_VERSION 5,3,0,0
|
||||||
#define VER_VERSION_STR "5.2.0.0"
|
#define VER_VERSION_STR "5.3.0.0"
|
||||||
|
|
||||||
#define VER_COMPANYNAME_STR "Moonlight Game Streaming Project"
|
#define VER_COMPANYNAME_STR "Moonlight Game Streaming Project"
|
||||||
#define VER_PRODUCTNAME_STR "Moonlight Internet Hosting Tool"
|
#define VER_PRODUCTNAME_STR "Moonlight Internet Hosting Tool"
|
||||||
|
|||||||
Reference in New Issue
Block a user