mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2025-07-02 07:46:14 +00:00
Add platform support for the 3DS
Prevent wildcard port binding on the 3DS Add 3DS threading logic Add 3DS socket logic Bump the connection timeout to 60s for the 3DS
This commit is contained in:
parent
2597b5e779
commit
c104a97fa0
@ -362,7 +362,7 @@ void destroyControlStream(void) {
|
|||||||
|
|
||||||
static void queueFrameInvalidationTuple(uint32_t startFrame, uint32_t endFrame) {
|
static void queueFrameInvalidationTuple(uint32_t startFrame, uint32_t endFrame) {
|
||||||
LC_ASSERT(startFrame <= endFrame);
|
LC_ASSERT(startFrame <= endFrame);
|
||||||
|
|
||||||
if (isReferenceFrameInvalidationEnabled()) {
|
if (isReferenceFrameInvalidationEnabled()) {
|
||||||
PQUEUED_FRAME_INVALIDATION_TUPLE qfit;
|
PQUEUED_FRAME_INVALIDATION_TUPLE qfit;
|
||||||
qfit = malloc(sizeof(*qfit));
|
qfit = malloc(sizeof(*qfit));
|
||||||
@ -411,7 +411,7 @@ void connectionSendFrameFecStatus(PSS_FRAME_FEC_STATUS fecStatus) {
|
|||||||
if (!IS_SUNSHINE()) {
|
if (!IS_SUNSHINE()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Queue a frame FEC status message. This is best-effort only.
|
// Queue a frame FEC status message. This is best-effort only.
|
||||||
PQUEUED_FRAME_FEC_STATUS queuedFecStatus = malloc(sizeof(*queuedFecStatus));
|
PQUEUED_FRAME_FEC_STATUS queuedFecStatus = malloc(sizeof(*queuedFecStatus));
|
||||||
if (queuedFecStatus != NULL) {
|
if (queuedFecStatus != NULL) {
|
||||||
@ -1334,7 +1334,7 @@ static void lossStatsThreadFunc(void* context) {
|
|||||||
free(queuedFrameStatus);
|
free(queuedFrameStatus);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(queuedFrameStatus);
|
free(queuedFrameStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1362,7 +1362,7 @@ static void lossStatsThreadFunc(void* context) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char* lossStatsPayload;
|
char* lossStatsPayload;
|
||||||
|
|
||||||
// Sunshine should use the newer codepath above
|
// Sunshine should use the newer codepath above
|
||||||
LC_ASSERT(!IS_SUNSHINE());
|
LC_ASSERT(!IS_SUNSHINE());
|
||||||
|
|
||||||
@ -1538,7 +1538,7 @@ int stopControlStream(void) {
|
|||||||
if (ctlSock != INVALID_SOCKET) {
|
if (ctlSock != INVALID_SOCKET) {
|
||||||
shutdownTcpSocket(ctlSock);
|
shutdownTcpSocket(ctlSock);
|
||||||
}
|
}
|
||||||
|
|
||||||
PltInterruptThread(&lossStatsThread);
|
PltInterruptThread(&lossStatsThread);
|
||||||
PltInterruptThread(&requestIdrFrameThread);
|
PltInterruptThread(&requestIdrFrameThread);
|
||||||
PltInterruptThread(&controlReceiveThread);
|
PltInterruptThread(&controlReceiveThread);
|
||||||
@ -1571,7 +1571,7 @@ int stopControlStream(void) {
|
|||||||
enet_host_destroy(client);
|
enet_host_destroy(client);
|
||||||
client = NULL;
|
client = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctlSock != INVALID_SOCKET) {
|
if (ctlSock != INVALID_SOCKET) {
|
||||||
closeSocket(ctlSock);
|
closeSocket(ctlSock);
|
||||||
ctlSock = INVALID_SOCKET;
|
ctlSock = INVALID_SOCKET;
|
||||||
@ -1642,11 +1642,16 @@ int startControlStream(void) {
|
|||||||
if (AppVersionQuad[0] >= 5) {
|
if (AppVersionQuad[0] >= 5) {
|
||||||
ENetAddress remoteAddress, localAddress;
|
ENetAddress remoteAddress, localAddress;
|
||||||
ENetEvent event;
|
ENetEvent event;
|
||||||
|
|
||||||
LC_ASSERT(ControlPortNumber != 0);
|
LC_ASSERT(ControlPortNumber != 0);
|
||||||
|
|
||||||
enet_address_set_address(&localAddress, (struct sockaddr *)&LocalAddr, AddrLen);
|
enet_address_set_address(&localAddress, (struct sockaddr *)&LocalAddr, AddrLen);
|
||||||
|
#ifdef __3DS__
|
||||||
|
// binding to wildcard port is broken on the 3DS, so we need to define a port manually
|
||||||
|
enet_address_set_port(&localAddress, htons(n3ds_udp_port++));
|
||||||
|
#else
|
||||||
enet_address_set_port(&localAddress, 0); // Wildcard port
|
enet_address_set_port(&localAddress, 0); // Wildcard port
|
||||||
|
#endif
|
||||||
|
|
||||||
enet_address_set_address(&remoteAddress, (struct sockaddr *)&RemoteAddr, AddrLen);
|
enet_address_set_address(&remoteAddress, (struct sockaddr *)&RemoteAddr, AddrLen);
|
||||||
enet_address_set_port(&remoteAddress, ControlPortNumber);
|
enet_address_set_port(&remoteAddress, ControlPortNumber);
|
||||||
@ -1711,9 +1716,15 @@ int startControlStream(void) {
|
|||||||
|
|
||||||
// Ensure the connect verify ACK is sent immediately
|
// Ensure the connect verify ACK is sent immediately
|
||||||
enet_host_flush(client);
|
enet_host_flush(client);
|
||||||
|
|
||||||
|
#ifdef __3DS__
|
||||||
|
// Set the peer timeout to 1 minute and limit backoff to 2x RTT
|
||||||
|
// The 3DS can take a bit longer to set up when starting fresh
|
||||||
|
enet_peer_timeout(peer, 2, 60000, 60000);
|
||||||
|
#else
|
||||||
// Set the peer timeout to 10 seconds and limit backoff to 2x RTT
|
// Set the peer timeout to 10 seconds and limit backoff to 2x RTT
|
||||||
enet_peer_timeout(peer, 2, 10000, 10000);
|
enet_peer_timeout(peer, 2, 10000, 10000);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// NB: Do NOT use ControlPortNumber here. 47995 is correct for these old versions.
|
// NB: Do NOT use ControlPortNumber here. 47995 is correct for these old versions.
|
||||||
|
@ -93,7 +93,7 @@ void* ThreadProc(void* context) {
|
|||||||
free(ctx);
|
free(ctx);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(LC_WINDOWS) || defined(__vita__) || defined(__WIIU__)
|
#if defined(LC_WINDOWS) || defined(__vita__) || defined(__WIIU__) || defined(__3DS__)
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -105,6 +105,9 @@ void PltSleepMs(int ms) {
|
|||||||
SleepEx(ms, FALSE);
|
SleepEx(ms, FALSE);
|
||||||
#elif defined(__vita__)
|
#elif defined(__vita__)
|
||||||
sceKernelDelayThread(ms * 1000);
|
sceKernelDelayThread(ms * 1000);
|
||||||
|
#elif defined(__3DS__)
|
||||||
|
s64 nsecs = ms * 1000000;
|
||||||
|
svcSleepThread(nsecs);
|
||||||
#else
|
#else
|
||||||
useconds_t usecs = ms * 1000;
|
useconds_t usecs = ms * 1000;
|
||||||
usleep(usecs);
|
usleep(usecs);
|
||||||
@ -129,6 +132,8 @@ int PltCreateMutex(PLT_MUTEX* mutex) {
|
|||||||
}
|
}
|
||||||
#elif defined(__WIIU__)
|
#elif defined(__WIIU__)
|
||||||
OSFastMutex_Init(mutex, "");
|
OSFastMutex_Init(mutex, "");
|
||||||
|
#elif defined(__3DS__)
|
||||||
|
LightLock_Init(mutex);
|
||||||
#else
|
#else
|
||||||
int err = pthread_mutex_init(mutex, NULL);
|
int err = pthread_mutex_init(mutex, NULL);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
@ -145,7 +150,7 @@ void PltDeleteMutex(PLT_MUTEX* mutex) {
|
|||||||
// No-op to destroy a SRWLOCK
|
// No-op to destroy a SRWLOCK
|
||||||
#elif defined(__vita__)
|
#elif defined(__vita__)
|
||||||
sceKernelDeleteMutex(*mutex);
|
sceKernelDeleteMutex(*mutex);
|
||||||
#elif defined(__WIIU__)
|
#elif defined(__WIIU__) || defined(__3DS__)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
pthread_mutex_destroy(mutex);
|
pthread_mutex_destroy(mutex);
|
||||||
@ -159,6 +164,8 @@ void PltLockMutex(PLT_MUTEX* mutex) {
|
|||||||
sceKernelLockMutex(*mutex, 1, NULL);
|
sceKernelLockMutex(*mutex, 1, NULL);
|
||||||
#elif defined(__WIIU__)
|
#elif defined(__WIIU__)
|
||||||
OSFastMutex_Lock(mutex);
|
OSFastMutex_Lock(mutex);
|
||||||
|
#elif defined(__3DS__)
|
||||||
|
LightLock_Lock(mutex);
|
||||||
#else
|
#else
|
||||||
pthread_mutex_lock(mutex);
|
pthread_mutex_lock(mutex);
|
||||||
#endif
|
#endif
|
||||||
@ -171,6 +178,8 @@ void PltUnlockMutex(PLT_MUTEX* mutex) {
|
|||||||
sceKernelUnlockMutex(*mutex, 1);
|
sceKernelUnlockMutex(*mutex, 1);
|
||||||
#elif defined(__WIIU__)
|
#elif defined(__WIIU__)
|
||||||
OSFastMutex_Unlock(mutex);
|
OSFastMutex_Unlock(mutex);
|
||||||
|
#elif defined(__3DS__)
|
||||||
|
LightLock_Unlock(mutex);
|
||||||
#else
|
#else
|
||||||
pthread_mutex_unlock(mutex);
|
pthread_mutex_unlock(mutex);
|
||||||
#endif
|
#endif
|
||||||
@ -187,6 +196,9 @@ void PltJoinThread(PLT_THREAD* thread) {
|
|||||||
free(thread->context);
|
free(thread->context);
|
||||||
#elif defined(__WIIU__)
|
#elif defined(__WIIU__)
|
||||||
OSJoinThread(&thread->thread, NULL);
|
OSJoinThread(&thread->thread, NULL);
|
||||||
|
#elif defined(__3DS__)
|
||||||
|
threadJoin(thread->thread, U64_MAX);
|
||||||
|
threadFree(thread->thread);
|
||||||
#else
|
#else
|
||||||
pthread_join(thread->thread, NULL);
|
pthread_join(thread->thread, NULL);
|
||||||
#endif
|
#endif
|
||||||
@ -226,7 +238,7 @@ int PltCreateThread(const char* name, ThreadEntry entry, void* context, PLT_THRE
|
|||||||
ctx->entry = entry;
|
ctx->entry = entry;
|
||||||
ctx->context = context;
|
ctx->context = context;
|
||||||
ctx->name = name;
|
ctx->name = name;
|
||||||
|
|
||||||
thread->cancelled = false;
|
thread->cancelled = false;
|
||||||
|
|
||||||
#if defined(LC_WINDOWS)
|
#if defined(LC_WINDOWS)
|
||||||
@ -265,6 +277,22 @@ int PltCreateThread(const char* name, ThreadEntry entry, void* context, PLT_THRE
|
|||||||
|
|
||||||
OSSetThreadDeallocator(&thread->thread, thread_deallocator);
|
OSSetThreadDeallocator(&thread->thread, thread_deallocator);
|
||||||
OSResumeThread(&thread->thread);
|
OSResumeThread(&thread->thread);
|
||||||
|
#elif defined(__3DS__)
|
||||||
|
{
|
||||||
|
s32 priority = 0x30;
|
||||||
|
size_t stack_size = 1024 * 1024;
|
||||||
|
svcGetThreadPriority(&priority, CUR_THREAD_HANDLE);
|
||||||
|
thread->thread = threadCreate(ThreadProc,
|
||||||
|
ctx,
|
||||||
|
stack_size,
|
||||||
|
priority,
|
||||||
|
-1,
|
||||||
|
false);
|
||||||
|
if (thread->thread == NULL) {
|
||||||
|
free(ctx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
int err = pthread_create(&thread->thread, NULL, ThreadProc, ctx);
|
int err = pthread_create(&thread->thread, NULL, ThreadProc, ctx);
|
||||||
@ -351,6 +379,8 @@ int PltCreateConditionVariable(PLT_COND* cond, PLT_MUTEX* mutex) {
|
|||||||
}
|
}
|
||||||
#elif defined(__WIIU__)
|
#elif defined(__WIIU__)
|
||||||
OSFastCond_Init(cond, "");
|
OSFastCond_Init(cond, "");
|
||||||
|
#elif defined(__3DS__)
|
||||||
|
CondVar_Init(cond);
|
||||||
#else
|
#else
|
||||||
pthread_cond_init(cond, NULL);
|
pthread_cond_init(cond, NULL);
|
||||||
#endif
|
#endif
|
||||||
@ -364,6 +394,8 @@ void PltDeleteConditionVariable(PLT_COND* cond) {
|
|||||||
sceKernelDeleteCond(*cond);
|
sceKernelDeleteCond(*cond);
|
||||||
#elif defined(__WIIU__)
|
#elif defined(__WIIU__)
|
||||||
// No-op to delete an OSFastCondition
|
// No-op to delete an OSFastCondition
|
||||||
|
#elif defined(__3DS__)
|
||||||
|
// No-op to delete CondVar
|
||||||
#else
|
#else
|
||||||
pthread_cond_destroy(cond);
|
pthread_cond_destroy(cond);
|
||||||
#endif
|
#endif
|
||||||
@ -376,6 +408,8 @@ void PltSignalConditionVariable(PLT_COND* cond) {
|
|||||||
sceKernelSignalCond(*cond);
|
sceKernelSignalCond(*cond);
|
||||||
#elif defined(__WIIU__)
|
#elif defined(__WIIU__)
|
||||||
OSFastCond_Signal(cond);
|
OSFastCond_Signal(cond);
|
||||||
|
#elif defined(__3DS__)
|
||||||
|
CondVar_Signal(cond);
|
||||||
#else
|
#else
|
||||||
pthread_cond_signal(cond);
|
pthread_cond_signal(cond);
|
||||||
#endif
|
#endif
|
||||||
@ -388,6 +422,8 @@ void PltWaitForConditionVariable(PLT_COND* cond, PLT_MUTEX* mutex) {
|
|||||||
sceKernelWaitCond(*cond, NULL);
|
sceKernelWaitCond(*cond, NULL);
|
||||||
#elif defined(__WIIU__)
|
#elif defined(__WIIU__)
|
||||||
OSFastCond_Wait(cond, mutex);
|
OSFastCond_Wait(cond, mutex);
|
||||||
|
#elif defined(__3DS__)
|
||||||
|
CondVar_Wait(cond, mutex);
|
||||||
#else
|
#else
|
||||||
pthread_cond_wait(cond, mutex);
|
pthread_cond_wait(cond, mutex);
|
||||||
#endif
|
#endif
|
||||||
@ -452,7 +488,7 @@ int initializePlatform(void) {
|
|||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = enet_initialize();
|
err = enet_initialize();
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
return err;
|
return err;
|
||||||
@ -460,14 +496,14 @@ int initializePlatform(void) {
|
|||||||
|
|
||||||
enterLowLatencyMode();
|
enterLowLatencyMode();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanupPlatform(void) {
|
void cleanupPlatform(void) {
|
||||||
exitLowLatencyMode();
|
exitLowLatencyMode();
|
||||||
|
|
||||||
cleanupPlatformSockets();
|
cleanupPlatformSockets();
|
||||||
|
|
||||||
enet_deinitialize();
|
enet_deinitialize();
|
||||||
|
|
||||||
LC_ASSERT(activeThreads == 0);
|
LC_ASSERT(activeThreads == 0);
|
||||||
|
@ -32,6 +32,9 @@
|
|||||||
#include <coreinit/fastmutex.h>
|
#include <coreinit/fastmutex.h>
|
||||||
#include <coreinit/fastcondition.h>
|
#include <coreinit/fastcondition.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#elif defined(__3DS__)
|
||||||
|
#include <3ds.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#else
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
@ -35,6 +35,10 @@ DWORD (WINAPI *pfnWlanSetInterface)(HANDLE hClientHandle, CONST GUID *pInterface
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __3DS__
|
||||||
|
in_port_t n3ds_udp_port = 47998;
|
||||||
|
#endif
|
||||||
|
|
||||||
void addrToUrlSafeString(struct sockaddr_storage* addr, char* string, size_t stringLength)
|
void addrToUrlSafeString(struct sockaddr_storage* addr, char* string, size_t stringLength)
|
||||||
{
|
{
|
||||||
char addrstr[URLSAFESTRING_LEN];
|
char addrstr[URLSAFESTRING_LEN];
|
||||||
@ -74,8 +78,8 @@ int setNonFatalRecvTimeoutMs(SOCKET s, int timeoutMs) {
|
|||||||
// losing some data in a very rare case is fine, especially because we get to
|
// losing some data in a very rare case is fine, especially because we get to
|
||||||
// halve the number of syscalls per packet by avoiding select().
|
// halve the number of syscalls per packet by avoiding select().
|
||||||
return setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeoutMs, sizeof(timeoutMs));
|
return setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeoutMs, sizeof(timeoutMs));
|
||||||
#elif defined(__WIIU__)
|
#elif defined(__WIIU__) || defined(__3DS__)
|
||||||
// timeouts aren't supported on Wii U
|
// timeouts aren't supported on Wii U or 3DS
|
||||||
return -1;
|
return -1;
|
||||||
#else
|
#else
|
||||||
struct timeval val;
|
struct timeval val;
|
||||||
@ -142,6 +146,15 @@ int pollSockets(struct pollfd* pollFds, int pollFdsCount, int timeoutMs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
#elif defined(__3DS__)
|
||||||
|
int err;
|
||||||
|
for (int i = 0; i < timeoutMs; i++) {
|
||||||
|
err = poll(pollFds, pollFdsCount, 1); // need to do this on 3ds since poll will block even if socket is ready before
|
||||||
|
if (err) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return err;
|
return err;
|
||||||
#else
|
#else
|
||||||
return poll(pollFds, pollFdsCount, timeoutMs);
|
return poll(pollFds, pollFdsCount, timeoutMs);
|
||||||
@ -164,7 +177,7 @@ bool isSocketReadable(SOCKET s) {
|
|||||||
|
|
||||||
int recvUdpSocket(SOCKET s, char* buffer, int size, bool useSelect) {
|
int recvUdpSocket(SOCKET s, char* buffer, int size, bool useSelect) {
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (useSelect) {
|
if (useSelect) {
|
||||||
struct pollfd pfd;
|
struct pollfd pfd;
|
||||||
@ -251,6 +264,11 @@ SOCKET bindUdpSocket(int addressFamily, struct sockaddr_storage* localAddr, SOCK
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __3DS__
|
||||||
|
// binding to wildcard port is broken on the 3DS, so we need to define a port manually
|
||||||
|
struct sockaddr_in *n3ds_addr = &bindAddr;
|
||||||
|
n3ds_addr->sin_port = htons(n3ds_udp_port++);
|
||||||
|
#endif
|
||||||
if (bind(s, (struct sockaddr*) &bindAddr, addrLen) == SOCKET_ERROR) {
|
if (bind(s, (struct sockaddr*) &bindAddr, addrLen) == SOCKET_ERROR) {
|
||||||
err = LastSocketError();
|
err = LastSocketError();
|
||||||
Limelog("bind() failed: %d\n", err);
|
Limelog("bind() failed: %d\n", err);
|
||||||
@ -353,6 +371,9 @@ SOCKET createSocket(int addressFamily, int socketType, int protocol, bool nonBlo
|
|||||||
setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, (char*)&val, sizeof(val));
|
setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, (char*)&val, sizeof(val));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __3DS__
|
||||||
|
SOCU_AddGlobalSocket(s);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (nonBlocking) {
|
if (nonBlocking) {
|
||||||
setSocketNonBlocking(s, true);
|
setSocketNonBlocking(s, true);
|
||||||
@ -426,7 +447,7 @@ SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen,
|
|||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for the connection to complete or the timeout to elapse
|
// Wait for the connection to complete or the timeout to elapse
|
||||||
pfd.fd = s;
|
pfd.fd = s;
|
||||||
pfd.events = POLLOUT;
|
pfd.events = POLLOUT;
|
||||||
@ -446,6 +467,17 @@ SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen,
|
|||||||
SetLastSocketError(ETIMEDOUT);
|
SetLastSocketError(ETIMEDOUT);
|
||||||
return INVALID_SOCKET;
|
return INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
#ifdef __3DS__ //SO_ERROR is unreliable on 3DS
|
||||||
|
else {
|
||||||
|
char test_buffer[1];
|
||||||
|
err = (int)recv(s, test_buffer, 1, MSG_PEEK);
|
||||||
|
if (err < 0 &&
|
||||||
|
(LastSocketError() == EWOULDBLOCK ||
|
||||||
|
LastSocketError() == EAGAIN)) {
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
else {
|
else {
|
||||||
// The socket was signalled
|
// The socket was signalled
|
||||||
SOCKADDR_LEN len = sizeof(err);
|
SOCKADDR_LEN len = sizeof(err);
|
||||||
@ -455,10 +487,11 @@ SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen,
|
|||||||
err = (err != 0) ? err : LastSocketFail();
|
err = (err != 0) ? err : LastSocketFail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Disable non-blocking I/O now that the connection is established
|
// Disable non-blocking I/O now that the connection is established
|
||||||
setSocketNonBlocking(s, false);
|
setSocketNonBlocking(s, false);
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
Limelog("connect() failed: %d\n", err);
|
Limelog("connect() failed: %d\n", err);
|
||||||
@ -521,7 +554,7 @@ int resolveHostName(const char* host, int family, int tcpTestPort, struct sockad
|
|||||||
Limelog("getaddrinfo(%s) returned success without addresses\n", host);
|
Limelog("getaddrinfo(%s) returned success without addresses\n", host);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (currentAddr = res; currentAddr != NULL; currentAddr = currentAddr->ai_next) {
|
for (currentAddr = res; currentAddr != NULL; currentAddr = currentAddr->ai_next) {
|
||||||
// Use the test port to ensure this address is working if:
|
// Use the test port to ensure this address is working if:
|
||||||
// a) We have multiple addresses
|
// a) We have multiple addresses
|
||||||
@ -539,10 +572,10 @@ int resolveHostName(const char* host, int family, int tcpTestPort, struct sockad
|
|||||||
closeSocket(testSocket);
|
closeSocket(testSocket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(addr, currentAddr->ai_addr, currentAddr->ai_addrlen);
|
memcpy(addr, currentAddr->ai_addr, currentAddr->ai_addrlen);
|
||||||
*addrLen = (SOCKADDR_LEN)currentAddr->ai_addrlen;
|
*addrLen = (SOCKADDR_LEN)currentAddr->ai_addrlen;
|
||||||
|
|
||||||
freeaddrinfo(res);
|
freeaddrinfo(res);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -555,14 +588,14 @@ int resolveHostName(const char* host, int family, int tcpTestPort, struct sockad
|
|||||||
#ifdef AF_INET6
|
#ifdef AF_INET6
|
||||||
bool isInSubnetV6(struct sockaddr_in6* sin6, unsigned char* subnet, int prefixLength) {
|
bool isInSubnetV6(struct sockaddr_in6* sin6, unsigned char* subnet, int prefixLength) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < prefixLength; i++) {
|
for (i = 0; i < prefixLength; i++) {
|
||||||
unsigned char mask = 1 << (i % 8);
|
unsigned char mask = 1 << (i % 8);
|
||||||
if ((sin6->sin6_addr.s6_addr[i / 8] & mask) != (subnet[i / 8] & mask)) {
|
if ((sin6->sin6_addr.s6_addr[i / 8] & mask) != (subnet[i / 8] & mask)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -575,7 +608,7 @@ bool isPrivateNetworkAddress(struct sockaddr_storage* address) {
|
|||||||
|
|
||||||
memcpy(&addr, &((struct sockaddr_in*)address)->sin_addr, sizeof(addr));
|
memcpy(&addr, &((struct sockaddr_in*)address)->sin_addr, sizeof(addr));
|
||||||
addr = htonl(addr);
|
addr = htonl(addr);
|
||||||
|
|
||||||
// 10.0.0.0/8
|
// 10.0.0.0/8
|
||||||
if ((addr & 0xFF000000) == 0x0A000000) {
|
if ((addr & 0xFF000000) == 0x0A000000) {
|
||||||
return true;
|
return true;
|
||||||
@ -723,7 +756,7 @@ int initializePlatformSockets(void) {
|
|||||||
#if defined(LC_WINDOWS)
|
#if defined(LC_WINDOWS)
|
||||||
WSADATA data;
|
WSADATA data;
|
||||||
return WSAStartup(MAKEWORD(2, 0), &data);
|
return WSAStartup(MAKEWORD(2, 0), &data);
|
||||||
#elif defined(__vita__) || defined(__WIIU__)
|
#elif defined(__vita__) || defined(__WIIU__) || defined(__3DS__)
|
||||||
return 0; // already initialized
|
return 0; // already initialized
|
||||||
#elif defined(LC_POSIX) && !defined(LC_CHROME)
|
#elif defined(LC_POSIX) && !defined(LC_CHROME)
|
||||||
// Disable SIGPIPE signals to avoid us getting
|
// Disable SIGPIPE signals to avoid us getting
|
||||||
|
@ -2,6 +2,15 @@
|
|||||||
|
|
||||||
#include "Limelight.h"
|
#include "Limelight.h"
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
|
#ifdef __3DS__
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#ifdef AF_INET6
|
||||||
|
#undef AF_INET6
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern in_port_t n3ds_udp_port;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
@ -28,6 +28,13 @@ typedef struct _PLT_THREAD {
|
|||||||
OSThread thread;
|
OSThread thread;
|
||||||
int cancelled;
|
int cancelled;
|
||||||
} PLT_THREAD;
|
} PLT_THREAD;
|
||||||
|
#elif defined(__3DS__)
|
||||||
|
typedef LightLock PLT_MUTEX;
|
||||||
|
typedef CondVar PLT_COND;
|
||||||
|
typedef struct _PLT_THREAD {
|
||||||
|
Thread thread;
|
||||||
|
bool cancelled;
|
||||||
|
} PLT_THREAD;
|
||||||
#elif defined (LC_POSIX)
|
#elif defined (LC_POSIX)
|
||||||
typedef pthread_mutex_t PLT_MUTEX;
|
typedef pthread_mutex_t PLT_MUTEX;
|
||||||
typedef pthread_cond_t PLT_COND;
|
typedef pthread_cond_t PLT_COND;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user