From b3b49bd5479ffd8f9ec8deb582ba2325d396d2ad Mon Sep 17 00:00:00 2001 From: "Robin C. Ladiges" Date: Sun, 10 Jul 2022 08:13:28 +0200 Subject: [PATCH 1/3] on invalid IPv4 addresses, assume it's a hostname and do a DNS lookup Enable the full keyboard to enter non-numbers and increase max length from 15 to 50 for longer hostnames. I know FQDNs can be longer than 50 characters, but that's less common (and painful to type on the Switch). --- include/Keyboard.hpp | 5 ++-- include/nn/socket.h | 11 +++++++++ include/server/Client.hpp | 4 ++-- include/server/SocketClient.hpp | 9 +++++++- include/types.h | 4 ++++ source/server/Client.cpp | 7 +++--- source/server/SocketClient.cpp | 41 +++++++++++++++++++++++++-------- 7 files changed, 61 insertions(+), 20 deletions(-) diff --git a/include/Keyboard.hpp b/include/Keyboard.hpp index f4c5349..4553645 100644 --- a/include/Keyboard.hpp +++ b/include/Keyboard.hpp @@ -7,7 +7,6 @@ #include "nn/swkbd/swkbd.h" #include "logger.hpp" -#include "sead/prim/seadSafeString.h" typedef void (*KeyboardSetup)(nn::swkbd::KeyboardConfig&); @@ -37,7 +36,7 @@ class Keyboard { al::AsyncFunctorThread* mThread; nn::swkbd::String mResultString; - sead::FixedSafeString<0x10> mInitialText; + hostname mInitialText; KeyboardSetup mSetupFunc; const char16_t *mHeaderText = u"Enter Server IP Here!"; @@ -51,4 +50,4 @@ class Keyboard { int mTextCheckSize; char* mCustomizeDicBuf; int mCustomizeDicSize; -}; \ No newline at end of file +}; diff --git a/include/nn/socket.h b/include/nn/socket.h index b308e33..3e8290b 100644 --- a/include/nn/socket.h +++ b/include/nn/socket.h @@ -17,6 +17,15 @@ struct sockaddr u8 _8[8]; // 8 }; +struct hostent +{ + char* h_name; + char** h_aliases; + int h_addrtype; + int h_length; + char** h_addr_list; +}; + namespace nn { namespace socket { @@ -34,6 +43,8 @@ s32 Recv(s32 socket, void* out, ulong outLen, s32 flags); u16 InetHtons(u16 val); s32 InetAton(const char* addressStr, in_addr* addressOut); +struct hostent* GetHostByName(const char* name); + u32 GetLastErrno(); } } diff --git a/include/server/Client.hpp b/include/server/Client.hpp index 7682263..a01749d 100644 --- a/include/server/Client.hpp +++ b/include/server/Client.hpp @@ -259,7 +259,7 @@ class Client { Keyboard* mKeyboard = nullptr; // keyboard for setting server IP - sead::FixedSafeString<0x10> mServerIP; + hostname mServerIP; int mServerPort = 0; @@ -314,4 +314,4 @@ class Client { PuppetHolder *mPuppetHolder = nullptr; PuppetInfo mDebugPuppetInfo; -}; \ No newline at end of file +}; diff --git a/include/server/SocketClient.hpp b/include/server/SocketClient.hpp index 128af87..42dad30 100644 --- a/include/server/SocketClient.hpp +++ b/include/server/SocketClient.hpp @@ -33,4 +33,11 @@ class SocketClient : public SocketBase { private: int maxBufSize = 100; -}; \ No newline at end of file + + /** + * @param str a string containing an IPv4 address or a hostname that can be resolved via DNS + * @param out IPv4 address + * @return if this function was successfull and out contains a valid IP address + */ + bool stringToIPAddress(const char* str, in_addr* out); +}; diff --git a/include/types.h b/include/types.h index 397a50c..e571b4d 100644 --- a/include/types.h +++ b/include/types.h @@ -5,6 +5,7 @@ #include #include #include +#include "sead/prim/seadSafeString.h" typedef unsigned char u8; typedef unsigned short u16; @@ -41,6 +42,9 @@ typedef unsigned int undefined3; typedef unsigned int undefined4; typedef unsigned long undefined8; +const u8 MAX_HOSTNAME_LENGTH = 50; +typedef sead::FixedSafeString hostname; + enum SocketLogState { SOCKET_LOG_UNINITIALIZED = 0, SOCKET_LOG_CONNECTED = 1, diff --git a/source/server/Client.cpp b/source/server/Client.cpp index 6059bc1..9a339ef 100644 --- a/source/server/Client.cpp +++ b/source/server/Client.cpp @@ -30,7 +30,6 @@ #include "packets/PlayerConnect.h" #include "packets/PlayerDC.h" #include "packets/TagInf.h" -#include "prim/seadSafeString.h" #include "puppets/PuppetInfo.h" #include "sead/basis/seadRawPrint.h" #include "sead/math/seadQuat.h" @@ -300,13 +299,13 @@ bool Client::openKeyboardIP() { sInstance->mServerIP.cstr(), [](nn::swkbd::KeyboardConfig& config) { config.keyboardMode = nn::swkbd::KeyboardMode::ModeNumeric; config.leftOptionalSymbolKey = '.'; - config.textMaxLength = 15; + config.textMaxLength = MAX_HOSTNAME_LENGTH; config.textMinLength = 1; config.isUseUtf8 = true; config.inputFormMode = nn::swkbd::InputFormMode::OneLine; }); - sead::FixedSafeString<0x10> prevIp = sInstance->mServerIP; + hostname prevIp = sInstance->mServerIP; while (true) { if (sInstance->mKeyboard->isThreadDone()) { @@ -1573,4 +1572,4 @@ void Client::hideConnect() { return; sInstance->mConnectionWait->tryEnd(); -} \ No newline at end of file +} diff --git a/source/server/SocketClient.cpp b/source/server/SocketClient.cpp index 9dd5d97..1d06879 100644 --- a/source/server/SocketClient.cpp +++ b/source/server/SocketClient.cpp @@ -11,11 +11,10 @@ nn::Result SocketClient::init(const char* ip, u16 port) { - sock_ip = ip; - - this->port = port; + this->sock_ip = ip; + this->port = port; - in_addr hostAddress = { 0 }; + in_addr hostAddress = { 0 }; sockaddr serverAddress = { 0 }; Logger::log("SocketClient::init: %s:%d sock %s\n", ip, port, getStateChar()); @@ -34,18 +33,20 @@ nn::Result SocketClient::init(const char* ip, u16 port) { return -1; } #endif - + if ((this->socket_log_socket = nn::socket::Socket(2, 1, 6)) < 0) { - Logger::log("Socket Unavailable.\n"); - this->socket_errno = nn::socket::GetLastErrno(); this->socket_log_state = SOCKET_LOG_UNAVAILABLE; return -1; } - - nn::socket::InetAton(this->sock_ip, &hostAddress); + if (! this->stringToIPAddress(this->sock_ip, &hostAddress)) { + Logger::log("IP address is invalid or hostname not resolveable.\n"); + this->socket_errno = nn::socket::GetLastErrno(); + this->socket_log_state = SOCKET_LOG_UNAVAILABLE; + return -1; + } serverAddress.address = hostAddress; serverAddress.port = nn::socket::InetHtons(this->port); @@ -205,4 +206,24 @@ bool SocketClient::closeSocket() { } return result; -} \ No newline at end of file +} + +bool SocketClient::stringToIPAddress(const char* str, in_addr* out) { + // string to IPv4 + if (nn::socket::InetAton(str, out)) { + return true; + } + + // get IPs via DNS + struct hostent *he = nn::socket::GetHostByName(str); + if (! he) { return false; } + + // might give us multiple IP addresses, so pick the first one + struct in_addr **addr_list = (struct in_addr **) he->h_addr_list; + for (int i = 0 ; addr_list[i] != NULL ; i++) { + *out = *addr_list[i]; + return true; + } + + return false; +} From dd4f3202ae85b31eb79ddcc9a5d9a15bbb7618d9 Mon Sep 17 00:00:00 2001 From: "Robin C. Ladiges" Date: Mon, 18 Jul 2022 03:30:14 +0200 Subject: [PATCH 2/3] change default IP This might otherwise cause confusion with the server.json setting, which should stay at 0.0.0.0. 127.0.0.1 might at least work with emulators running on the same PC out of the box. Whereas 0.0.0.0 should be invalid (except on some systems that map it to localhost). --- source/hooks.cpp | 4 ++-- source/server/Client.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/hooks.cpp b/source/hooks.cpp index 3fc0fad..da9adf0 100644 --- a/source/hooks.cpp +++ b/source/hooks.cpp @@ -44,7 +44,7 @@ void saveWriteHook(al::ByamlWriter* saveByml) { if (serverIP) { saveByml->addString("ServerIP", serverIP); } else { - saveByml->addString("ServerIP", "0.0.0.0"); + saveByml->addString("ServerIP", "127.0.0.1"); } if (serverPort) { @@ -168,4 +168,4 @@ bool borderPullBackHook(WorldEndBorderKeeper* thisPtr) { } return isFirstStep; -} \ No newline at end of file +} diff --git a/source/server/Client.cpp b/source/server/Client.cpp index 9a339ef..3a72bf1 100644 --- a/source/server/Client.cpp +++ b/source/server/Client.cpp @@ -230,7 +230,7 @@ bool Client::startConnection() { if (mServerIP.isEmpty() || isOverride) { mKeyboard->setHeaderText(u"Save File does not contain an IP!"); mKeyboard->setSubText(u"Please set a Server IP Below."); - mServerIP = "0.0.0.0"; + mServerIP = "127.0.0.1"; Client::openKeyboardIP(); isNeedSave = true; } From ce5b799593082a0eab5fd7482d49dfb042ef9aac Mon Sep 17 00:00:00 2001 From: "Robin C. Ladiges" Date: Mon, 18 Jul 2022 03:31:02 +0200 Subject: [PATCH 3/3] change KeyboardMode from Numeric to ASCII --- source/server/Client.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/server/Client.cpp b/source/server/Client.cpp index 3a72bf1..41881cc 100644 --- a/source/server/Client.cpp +++ b/source/server/Client.cpp @@ -297,8 +297,7 @@ bool Client::openKeyboardIP() { // opens swkbd with the initial text set to the last saved IP sInstance->mKeyboard->openKeyboard( sInstance->mServerIP.cstr(), [](nn::swkbd::KeyboardConfig& config) { - config.keyboardMode = nn::swkbd::KeyboardMode::ModeNumeric; - config.leftOptionalSymbolKey = '.'; + config.keyboardMode = nn::swkbd::KeyboardMode::ModeASCII; config.textMaxLength = MAX_HOSTNAME_LENGTH; config.textMinLength = 1; config.isUseUtf8 = true;