Merge pull request #20 from Istador/dns

on invalid IPv4 addresses, assume it's a hostname and do a DNS lookup
This commit is contained in:
CraftyBoss 2022-08-10 15:00:35 -07:00 committed by GitHub
commit d3b1935899
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 65 additions and 25 deletions

View file

@ -7,7 +7,6 @@
#include "nn/swkbd/swkbd.h" #include "nn/swkbd/swkbd.h"
#include "logger.hpp" #include "logger.hpp"
#include "sead/prim/seadSafeString.h"
typedef void (*KeyboardSetup)(nn::swkbd::KeyboardConfig&); typedef void (*KeyboardSetup)(nn::swkbd::KeyboardConfig&);
@ -37,7 +36,7 @@ class Keyboard {
al::AsyncFunctorThread* mThread; al::AsyncFunctorThread* mThread;
nn::swkbd::String mResultString; nn::swkbd::String mResultString;
sead::FixedSafeString<0x10> mInitialText; hostname mInitialText;
KeyboardSetup mSetupFunc; KeyboardSetup mSetupFunc;
const char16_t *mHeaderText = u"Enter Server IP Here!"; const char16_t *mHeaderText = u"Enter Server IP Here!";

View file

@ -17,6 +17,15 @@ struct sockaddr
u8 _8[8]; // 8 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 { namespace nn { namespace socket {
@ -34,6 +43,8 @@ s32 Recv(s32 socket, void* out, ulong outLen, s32 flags);
u16 InetHtons(u16 val); u16 InetHtons(u16 val);
s32 InetAton(const char* addressStr, in_addr* addressOut); s32 InetAton(const char* addressStr, in_addr* addressOut);
struct hostent* GetHostByName(const char* name);
u32 GetLastErrno(); u32 GetLastErrno();
} } } }

View file

@ -225,7 +225,7 @@ class Client {
Keyboard* mKeyboard = nullptr; // keyboard for setting server IP Keyboard* mKeyboard = nullptr; // keyboard for setting server IP
sead::FixedSafeString<0x10> mServerIP; hostname mServerIP;
int mServerPort = 0; int mServerPort = 0;

View file

@ -33,4 +33,11 @@ class SocketClient : public SocketBase {
private: private:
int maxBufSize = 100; int maxBufSize = 100;
/**
* @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);
}; };

View file

@ -5,6 +5,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "sead/prim/seadSafeString.h"
typedef unsigned char u8; typedef unsigned char u8;
typedef unsigned short u16; typedef unsigned short u16;
@ -41,6 +42,9 @@ typedef unsigned int undefined3;
typedef unsigned int undefined4; typedef unsigned int undefined4;
typedef unsigned long undefined8; typedef unsigned long undefined8;
const u8 MAX_HOSTNAME_LENGTH = 50;
typedef sead::FixedSafeString<MAX_HOSTNAME_LENGTH + 1> hostname;
enum SocketLogState { enum SocketLogState {
SOCKET_LOG_UNINITIALIZED = 0, SOCKET_LOG_UNINITIALIZED = 0,
SOCKET_LOG_CONNECTED = 1, SOCKET_LOG_CONNECTED = 1,

View file

@ -44,7 +44,7 @@ void saveWriteHook(al::ByamlWriter* saveByml) {
if (serverIP) { if (serverIP) {
saveByml->addString("ServerIP", serverIP); saveByml->addString("ServerIP", serverIP);
} else { } else {
saveByml->addString("ServerIP", "0.0.0.0"); saveByml->addString("ServerIP", "127.0.0.1");
} }
if (serverPort) { if (serverPort) {

View file

@ -31,7 +31,6 @@
#include "packets/PlayerConnect.h" #include "packets/PlayerConnect.h"
#include "packets/PlayerDC.h" #include "packets/PlayerDC.h"
#include "packets/TagInf.h" #include "packets/TagInf.h"
#include "prim/seadSafeString.h"
#include "puppets/PuppetInfo.h" #include "puppets/PuppetInfo.h"
#include "sead/basis/seadRawPrint.h" #include "sead/basis/seadRawPrint.h"
#include "sead/math/seadQuat.h" #include "sead/math/seadQuat.h"
@ -192,7 +191,7 @@ bool Client::startConnection() {
if (mServerIP.isEmpty() || isOverride) { if (mServerIP.isEmpty() || isOverride) {
mKeyboard->setHeaderText(u"Save File does not contain an IP!"); mKeyboard->setHeaderText(u"Save File does not contain an IP!");
mKeyboard->setSubText(u"Please set a Server IP Below."); mKeyboard->setSubText(u"Please set a Server IP Below.");
mServerIP = "0.0.0.0"; mServerIP = "127.0.0.1";
Client::openKeyboardIP(); Client::openKeyboardIP();
isNeedSave = true; isNeedSave = true;
} }
@ -263,15 +262,14 @@ bool Client::openKeyboardIP() {
// opens swkbd with the initial text set to the last saved IP // opens swkbd with the initial text set to the last saved IP
sInstance->mKeyboard->openKeyboard( sInstance->mKeyboard->openKeyboard(
sInstance->mServerIP.cstr(), [](nn::swkbd::KeyboardConfig& config) { sInstance->mServerIP.cstr(), [](nn::swkbd::KeyboardConfig& config) {
config.keyboardMode = nn::swkbd::KeyboardMode::ModeNumeric; config.keyboardMode = nn::swkbd::KeyboardMode::ModeASCII;
config.leftOptionalSymbolKey = '.'; config.textMaxLength = MAX_HOSTNAME_LENGTH;
config.textMaxLength = 15;
config.textMinLength = 1; config.textMinLength = 1;
config.isUseUtf8 = true; config.isUseUtf8 = true;
config.inputFormMode = nn::swkbd::InputFormMode::OneLine; config.inputFormMode = nn::swkbd::InputFormMode::OneLine;
}); });
sead::FixedSafeString<0x10> prevIp = sInstance->mServerIP; hostname prevIp = sInstance->mServerIP;
while (true) { while (true) {
if (sInstance->mKeyboard->isThreadDone()) { if (sInstance->mKeyboard->isThreadDone()) {

View file

@ -11,11 +11,10 @@
nn::Result SocketClient::init(const char* ip, u16 port) { nn::Result SocketClient::init(const char* ip, u16 port) {
sock_ip = ip; this->sock_ip = ip;
this->port = port;
this->port = port; in_addr hostAddress = { 0 };
in_addr hostAddress = { 0 };
sockaddr serverAddress = { 0 }; sockaddr serverAddress = { 0 };
Logger::log("SocketClient::init: %s:%d sock %s\n", ip, port, getStateChar()); Logger::log("SocketClient::init: %s:%d sock %s\n", ip, port, getStateChar());
@ -36,16 +35,18 @@ nn::Result SocketClient::init(const char* ip, u16 port) {
#endif #endif
if ((this->socket_log_socket = nn::socket::Socket(2, 1, 6)) < 0) { if ((this->socket_log_socket = nn::socket::Socket(2, 1, 6)) < 0) {
Logger::log("Socket Unavailable.\n"); Logger::log("Socket Unavailable.\n");
this->socket_errno = nn::socket::GetLastErrno(); this->socket_errno = nn::socket::GetLastErrno();
this->socket_log_state = SOCKET_LOG_UNAVAILABLE; this->socket_log_state = SOCKET_LOG_UNAVAILABLE;
return -1; return -1;
} }
if (! this->stringToIPAddress(this->sock_ip, &hostAddress)) {
nn::socket::InetAton(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.address = hostAddress;
serverAddress.port = nn::socket::InetHtons(this->port); serverAddress.port = nn::socket::InetHtons(this->port);
@ -219,3 +220,23 @@ bool SocketClient::closeSocket() {
return result; return result;
} }
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;
}