Compare commits

..
10 Commits
5 changed files with 80 additions and 42 deletions
+37
View File
@@ -80,6 +80,43 @@
Name="Moonlight Internet Streaming Tester"/>
</File>
</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="*">
<Shortcut Id="StartMenuShortcut"
Name="Moonlight Internet Streaming Tester"
+30 -23
View File
@@ -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
if (!strcmp(intClient, myAddr)) {
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 (enable) {
@@ -124,7 +124,7 @@ bool UPnPMapPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const
}
}
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.
@@ -206,7 +206,7 @@ bool UPnPMapPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const
else if (indefinite) {
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
// 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
@@ -415,7 +415,7 @@ bool NATPMPMapPort(natpmp_t* natpmp, int proto, int port, bool enable, bool inde
lifetime = 604800; // 1 week
}
else {
lifetime = 3600;
lifetime = PORT_MAPPING_DURATION_SEC;
}
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);
}
void ResetLogFile()
void ResetLogFile(bool standaloneExe)
{
char oldLogFilePath[MAX_PATH + 1];
char currentLogFilePath[MAX_PATH + 1];
char timeString[MAX_PATH + 1] = {};
SYSTEMTIME time;
ExpandEnvironmentStringsA("%ProgramData%\\MISS\\miss-old.log", oldLogFilePath, sizeof(oldLogFilePath));
ExpandEnvironmentStringsA("%ProgramData%\\MISS\\miss-current.log", currentLogFilePath, sizeof(currentLogFilePath));
if (!standaloneExe) {
char oldLogFilePath[MAX_PATH + 1];
char currentLogFilePath[MAX_PATH + 1];
// Close the existing stdout handle. This is important because otherwise
// it may still be open as stdout when we try to MoveFileEx below.
fclose(stdout);
ExpandEnvironmentStringsA("%ProgramData%\\MISS\\miss-old.log", oldLogFilePath, sizeof(oldLogFilePath));
ExpandEnvironmentStringsA("%ProgramData%\\MISS\\miss-current.log", currentLogFilePath, sizeof(currentLogFilePath));
// Rotate the current to the old log file
MoveFileExA(currentLogFilePath, oldLogFilePath, MOVEFILE_REPLACE_EXISTING);
// Close the existing stdout handle. This is important because otherwise
// it may still be open as stdout when we try to MoveFileEx below.
fclose(stdout);
// Redirect stdout to this new file
freopen(currentLogFilePath, "w", stdout);
// Rotate the current to the old log file
MoveFileExA(currentLogFilePath, oldLogFilePath, MOVEFILE_REPLACE_EXISTING);
// Redirect stdout to this new file
freopen(currentLogFilePath, "w", stdout);
}
// Print a log header
printf("Moonlight Internet Streaming Service v" VER_VERSION_STR NL);
@@ -860,13 +863,17 @@ DWORD WINAPI GameStreamStateChangeThread(PVOID Context)
return err;
}
int Run()
int Run(bool standaloneExe)
{
HANDLE ifaceChangeEvent = CreateEvent(nullptr, true, false, nullptr);
HANDLE gsChangeEvent = CreateEvent(nullptr, true, false, nullptr);
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
for (int i = 0; i < ARRAYSIZE(k_Ports); i++) {
@@ -895,7 +902,7 @@ int Run()
ULONGLONG beforeSleepTime = GetTickCount64();
DWORD ret = WaitForMultipleObjects(ARRAYSIZE(events), events, false, POLLING_DELAY_SEC * 1000);
if (ret == WAIT_OBJECT_0) {
ResetLogFile();
ResetLogFile(standaloneExe);
printf("Woke up for interface change notification after %lld seconds" NL,
(GetTickCount64() - beforeSleepTime) / 1000);
@@ -904,13 +911,13 @@ int Run()
Sleep(10000);
}
else if (ret == WAIT_OBJECT_0 + 1) {
ResetLogFile();
ResetLogFile(standaloneExe);
printf("Woke up for GameStream state change notification after %lld seconds" NL,
(GetTickCount64() - beforeSleepTime) / 1000);
}
else {
ResetLogFile();
ResetLogFile(standaloneExe);
printf("Woke up for periodic refresh" NL);
}
@@ -971,7 +978,7 @@ ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
// Start the service
err = Run();
err = Run(false);
if (err != 0) {
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = err;
@@ -994,7 +1001,7 @@ int main(int argc, char* argv[])
}
if (argc == 2 && !strcmp(argv[1], "exe")) {
Run();
Run(true);
return 0;
}
+10 -16
View File
@@ -19,34 +19,28 @@ WINAPI
UdpRelayThreadProc(LPVOID Context)
{
PUDP_TUPLE tuple = (PUDP_TUPLE)Context;
fd_set fds;
int err;
USHORT nboPort = htons(tuple->port);
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));
for (;;) {
char buffer[4096];
SOCKADDR_IN sourceAddr;
int sourceAddrLen;
FD_ZERO(&fds);
FD_SET(tuple->socket, &fds);
err = select(0, &fds, NULL, NULL, NULL);
if (err <= 0) {
break;
}
int recvLen;
sourceAddrLen = sizeof(sourceAddr);
err = recvfrom(tuple->socket, buffer, sizeof(buffer), 0, (PSOCKADDR)&sourceAddr, &sourceAddrLen);
if (err == SOCKET_ERROR) {
recvLen = recvfrom(tuple->socket, buffer, sizeof(buffer), 0, (PSOCKADDR)&sourceAddr, &sourceAddrLen);
if (recvLen == SOCKET_ERROR) {
continue;
}
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
destinationAddr = lastRemoteAddr;
}
@@ -57,10 +51,10 @@ UdpRelayThreadProc(LPVOID Context)
// Send it to the normal port via the loopback adapter
destinationAddr = sourceAddr;
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);
+1 -1
View File
@@ -1002,7 +1002,7 @@ UPnPPortStatus UPnPCheckPort(struct UPNPUrls* urls, struct IGDdatas* data, int p
}
else if (err == UPNPCOMMAND_SUCCESS) {
if (!strcmp(myAddr, intClient)) {
fprintf(LOG_OUT, "OK\n");
fprintf(LOG_OUT, "OK (Internal port: %s)\n", intPort);
return OK;
}
else {
+2 -2
View File
@@ -1,7 +1,7 @@
#pragma once
#define VER_VERSION 5,2,0,0
#define VER_VERSION_STR "5.2.0.0"
#define VER_VERSION 5,3,0,0
#define VER_VERSION_STR "5.3.0.0"
#define VER_COMPANYNAME_STR "Moonlight Game Streaming Project"
#define VER_PRODUCTNAME_STR "Moonlight Internet Hosting Tool"