Make wii-network async.
* accept still needs to be made async.
This commit is contained in:
parent
d0d162e6ad
commit
124fe24f4c
|
@ -335,6 +335,7 @@
|
||||||
<ClCompile Include="Src\IPC_HLE\WII_IPC_HLE_Device_usb.cpp" />
|
<ClCompile Include="Src\IPC_HLE\WII_IPC_HLE_Device_usb.cpp" />
|
||||||
<ClCompile Include="Src\IPC_HLE\WII_IPC_HLE_Device_usb_kbd.cpp" />
|
<ClCompile Include="Src\IPC_HLE\WII_IPC_HLE_Device_usb_kbd.cpp" />
|
||||||
<ClCompile Include="Src\IPC_HLE\WII_IPC_HLE_WiiMote.cpp" />
|
<ClCompile Include="Src\IPC_HLE\WII_IPC_HLE_WiiMote.cpp" />
|
||||||
|
<ClCompile Include="Src\IPC_HLE\WII_Socket.cpp" />
|
||||||
<ClCompile Include="Src\x64MemTools.cpp" />
|
<ClCompile Include="Src\x64MemTools.cpp" />
|
||||||
<ClCompile Include="Src\Movie.cpp" />
|
<ClCompile Include="Src\Movie.cpp" />
|
||||||
<ClCompile Include="Src\NetPlay.cpp" />
|
<ClCompile Include="Src\NetPlay.cpp" />
|
||||||
|
@ -546,6 +547,7 @@
|
||||||
<ClInclude Include="Src\IPC_HLE\WII_IPC_HLE_Device_usb.h" />
|
<ClInclude Include="Src\IPC_HLE\WII_IPC_HLE_Device_usb.h" />
|
||||||
<ClInclude Include="Src\IPC_HLE\WII_IPC_HLE_Device_usb_kbd.h" />
|
<ClInclude Include="Src\IPC_HLE\WII_IPC_HLE_Device_usb_kbd.h" />
|
||||||
<ClInclude Include="Src\IPC_HLE\WII_IPC_HLE_WiiMote.h" />
|
<ClInclude Include="Src\IPC_HLE\WII_IPC_HLE_WiiMote.h" />
|
||||||
|
<ClInclude Include="Src\IPC_HLE\WII_Socket.h" />
|
||||||
<ClInclude Include="Src\MemTools.h" />
|
<ClInclude Include="Src\MemTools.h" />
|
||||||
<ClInclude Include="Src\Movie.h" />
|
<ClInclude Include="Src\Movie.h" />
|
||||||
<ClInclude Include="Src\NetPlay.h" />
|
<ClInclude Include="Src\NetPlay.h" />
|
||||||
|
|
|
@ -574,6 +574,9 @@
|
||||||
<Filter>IPC HLE %28IOS/Starlet%29\USB</Filter>
|
<Filter>IPC HLE %28IOS/Starlet%29\USB</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Src\ec_wii.cpp" />
|
<ClCompile Include="Src\ec_wii.cpp" />
|
||||||
|
<ClCompile Include="Src\IPC_HLE\WII_Socket.cpp">
|
||||||
|
<Filter>IPC HLE %28IOS/Starlet%29\Net</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Src\ConfigManager.h" />
|
<ClInclude Include="Src\ConfigManager.h" />
|
||||||
|
@ -1069,6 +1072,9 @@
|
||||||
<Filter>IPC HLE %28IOS/Starlet%29\USB</Filter>
|
<Filter>IPC HLE %28IOS/Starlet%29\USB</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Src\ec_wii.h" />
|
<ClInclude Include="Src\ec_wii.h" />
|
||||||
|
<ClInclude Include="Src\IPC_HLE\WII_Socket.h">
|
||||||
|
<Filter>IPC HLE %28IOS/Starlet%29\Net</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="CMakeLists.txt" />
|
<None Include="CMakeLists.txt" />
|
||||||
|
|
|
@ -525,14 +525,15 @@ void ExecuteCommand(u32 _Address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (CmdSuccess)
|
||||||
|
{
|
||||||
// It seems that the original hardware overwrites the command after it has been
|
// It seems that the original hardware overwrites the command after it has been
|
||||||
// executed. We write 8 which is not any valid command, and what IOS does
|
// executed. We write 8 which is not any valid command, and what IOS does
|
||||||
Memory::Write_U32(8, _Address);
|
Memory::Write_U32(8, _Address);
|
||||||
// IOS seems to write back the command that was responded to
|
// IOS seems to write back the command that was responded to
|
||||||
Memory::Write_U32(Command, _Address + 8);
|
Memory::Write_U32(Command, _Address + 8);
|
||||||
|
|
||||||
if (CmdSuccess)
|
|
||||||
{
|
|
||||||
// Ensure replies happen in order, fairly ugly
|
// Ensure replies happen in order, fairly ugly
|
||||||
// Without this, tons of games fail now that DI commands have different reply delays
|
// Without this, tons of games fail now that DI commands have different reply delays
|
||||||
int reply_delay = pDevice ? pDevice->GetCmdDelay(_Address) : 0;
|
int reply_delay = pDevice ? pDevice->GetCmdDelay(_Address) : 0;
|
||||||
|
|
|
@ -36,6 +36,61 @@
|
||||||
//#define FS_EFATAL (u32)-119 // Fatal error not used by IOS as fatal ERROR
|
//#define FS_EFATAL (u32)-119 // Fatal error not used by IOS as fatal ERROR
|
||||||
#define FS_EESEXHAUSTED (u32)-1016 // Max of 2 ES handles at a time
|
#define FS_EESEXHAUSTED (u32)-1016 // Max of 2 ES handles at a time
|
||||||
|
|
||||||
|
// A struct for IOS ioctlv calls
|
||||||
|
struct SIOCtlVBuffer
|
||||||
|
{
|
||||||
|
SIOCtlVBuffer(u32 _Address) : m_Address(_Address)
|
||||||
|
{
|
||||||
|
// These are the Ioctlv parameters in the IOS communication. The BufferVector
|
||||||
|
// is a memory address offset at where the in and out buffer addresses are
|
||||||
|
// stored.
|
||||||
|
Parameter = Memory::Read_U32(m_Address + 0x0C); // command 3, arg0
|
||||||
|
NumberInBuffer = Memory::Read_U32(m_Address + 0x10); // 4, arg1
|
||||||
|
NumberPayloadBuffer = Memory::Read_U32(m_Address + 0x14); // 5, arg2
|
||||||
|
BufferVector = Memory::Read_U32(m_Address + 0x18); // 6, arg3
|
||||||
|
|
||||||
|
// The start of the out buffer
|
||||||
|
u32 BufferVectorOffset = BufferVector;
|
||||||
|
|
||||||
|
// Write the address and size for all in messages
|
||||||
|
for (u32 i = 0; i < NumberInBuffer; i++)
|
||||||
|
{
|
||||||
|
SBuffer Buffer;
|
||||||
|
Buffer.m_Address = Memory::Read_U32(BufferVectorOffset);
|
||||||
|
BufferVectorOffset += 4;
|
||||||
|
Buffer.m_Size = Memory::Read_U32(BufferVectorOffset);
|
||||||
|
BufferVectorOffset += 4;
|
||||||
|
InBuffer.push_back(Buffer);
|
||||||
|
DEBUG_LOG(WII_IPC_HLE, "SIOCtlVBuffer in%i: 0x%08x, 0x%x",
|
||||||
|
i, Buffer.m_Address, Buffer.m_Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the address and size for all out or in-out messages
|
||||||
|
for (u32 i = 0; i < NumberPayloadBuffer; i++)
|
||||||
|
{
|
||||||
|
SBuffer Buffer;
|
||||||
|
Buffer.m_Address = Memory::Read_U32(BufferVectorOffset);
|
||||||
|
BufferVectorOffset += 4;
|
||||||
|
Buffer.m_Size = Memory::Read_U32(BufferVectorOffset);
|
||||||
|
BufferVectorOffset += 4;
|
||||||
|
PayloadBuffer.push_back(Buffer);
|
||||||
|
DEBUG_LOG(WII_IPC_HLE, "SIOCtlVBuffer io%i: 0x%08x, 0x%x",
|
||||||
|
i, Buffer.m_Address, Buffer.m_Size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const u32 m_Address;
|
||||||
|
|
||||||
|
u32 Parameter;
|
||||||
|
u32 NumberInBuffer;
|
||||||
|
u32 NumberPayloadBuffer;
|
||||||
|
u32 BufferVector;
|
||||||
|
|
||||||
|
struct SBuffer { u32 m_Address, m_Size; };
|
||||||
|
std::vector<SBuffer> InBuffer;
|
||||||
|
std::vector<SBuffer> PayloadBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
class IWII_IPC_HLE_Device
|
class IWII_IPC_HLE_Device
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -104,61 +159,6 @@ protected:
|
||||||
bool m_Hardware;
|
bool m_Hardware;
|
||||||
bool m_Active;
|
bool m_Active;
|
||||||
|
|
||||||
// A struct for IOS ioctlv calls
|
|
||||||
struct SIOCtlVBuffer
|
|
||||||
{
|
|
||||||
SIOCtlVBuffer(u32 _Address) : m_Address(_Address)
|
|
||||||
{
|
|
||||||
// These are the Ioctlv parameters in the IOS communication. The BufferVector
|
|
||||||
// is a memory address offset at where the in and out buffer addresses are
|
|
||||||
// stored.
|
|
||||||
Parameter = Memory::Read_U32(m_Address + 0x0C); // command 3, arg0
|
|
||||||
NumberInBuffer = Memory::Read_U32(m_Address + 0x10); // 4, arg1
|
|
||||||
NumberPayloadBuffer = Memory::Read_U32(m_Address + 0x14); // 5, arg2
|
|
||||||
BufferVector = Memory::Read_U32(m_Address + 0x18); // 6, arg3
|
|
||||||
|
|
||||||
// The start of the out buffer
|
|
||||||
u32 BufferVectorOffset = BufferVector;
|
|
||||||
|
|
||||||
// Write the address and size for all in messages
|
|
||||||
for (u32 i = 0; i < NumberInBuffer; i++)
|
|
||||||
{
|
|
||||||
SBuffer Buffer;
|
|
||||||
Buffer.m_Address = Memory::Read_U32(BufferVectorOffset);
|
|
||||||
BufferVectorOffset += 4;
|
|
||||||
Buffer.m_Size = Memory::Read_U32(BufferVectorOffset);
|
|
||||||
BufferVectorOffset += 4;
|
|
||||||
InBuffer.push_back(Buffer);
|
|
||||||
DEBUG_LOG(WII_IPC_HLE, "SIOCtlVBuffer in%i: 0x%08x, 0x%x",
|
|
||||||
i, Buffer.m_Address, Buffer.m_Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the address and size for all out or in-out messages
|
|
||||||
for (u32 i = 0; i < NumberPayloadBuffer; i++)
|
|
||||||
{
|
|
||||||
SBuffer Buffer;
|
|
||||||
Buffer.m_Address = Memory::Read_U32(BufferVectorOffset);
|
|
||||||
BufferVectorOffset += 4;
|
|
||||||
Buffer.m_Size = Memory::Read_U32(BufferVectorOffset);
|
|
||||||
BufferVectorOffset += 4;
|
|
||||||
PayloadBuffer.push_back(Buffer);
|
|
||||||
DEBUG_LOG(WII_IPC_HLE, "SIOCtlVBuffer io%i: 0x%08x, 0x%x",
|
|
||||||
i, Buffer.m_Address, Buffer.m_Size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const u32 m_Address;
|
|
||||||
|
|
||||||
u32 Parameter;
|
|
||||||
u32 NumberInBuffer;
|
|
||||||
u32 NumberPayloadBuffer;
|
|
||||||
u32 BufferVector;
|
|
||||||
|
|
||||||
struct SBuffer { u32 m_Address, m_Size; };
|
|
||||||
std::vector<SBuffer> InBuffer;
|
|
||||||
std::vector<SBuffer> PayloadBuffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Write out the IPC struct from _CommandAddress to _NumberOfCommands numbers
|
// Write out the IPC struct from _CommandAddress to _NumberOfCommands numbers
|
||||||
// of 4 byte commands.
|
// of 4 byte commands.
|
||||||
void DumpCommands(u32 _CommandAddress, size_t _NumberOfCommands = 8,
|
void DumpCommands(u32 _CommandAddress, size_t _NumberOfCommands = 8,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -441,6 +441,7 @@ private:
|
||||||
NWC24Config config;
|
NWC24Config config;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
class CWII_IPC_HLE_Device_net_kd_time : public IWII_IPC_HLE_Device
|
class CWII_IPC_HLE_Device_net_kd_time : public IWII_IPC_HLE_Device
|
||||||
{
|
{
|
||||||
|
@ -550,26 +551,38 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
class CWII_IPC_HLE_Device_net_ip_top : public IWII_IPC_HLE_Device
|
struct bind_params
|
||||||
{
|
{
|
||||||
public:
|
u32 socket;
|
||||||
CWII_IPC_HLE_Device_net_ip_top(u32 _DeviceID, const std::string& _rDeviceName);
|
u32 has_name;
|
||||||
|
u8 name[28];
|
||||||
|
};
|
||||||
|
|
||||||
virtual ~CWII_IPC_HLE_Device_net_ip_top();
|
struct GC_sockaddr
|
||||||
|
{
|
||||||
|
u8 sa_len;
|
||||||
|
u8 sa_family;
|
||||||
|
s8 sa_data[14];
|
||||||
|
};
|
||||||
|
|
||||||
virtual bool Open(u32 _CommandAddress, u32 _Mode);
|
struct GC_in_addr
|
||||||
virtual bool Close(u32 _CommandAddress, bool _bForce);
|
{
|
||||||
virtual bool IOCtl(u32 _CommandAddress);
|
// this cannot be named s_addr under windows - collides with some crazy define.
|
||||||
virtual bool IOCtlV(u32 _CommandAddress);
|
u32 s_addr_;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
struct GC_sockaddr_in
|
||||||
#ifdef _WIN32
|
{
|
||||||
WSADATA InitData;
|
u8 sin_len;
|
||||||
#endif
|
u8 sin_family;
|
||||||
|
u16 sin_port;
|
||||||
|
struct GC_in_addr sin_addr;
|
||||||
|
s8 sin_zero[8];
|
||||||
|
};
|
||||||
|
|
||||||
enum
|
enum NET_IOCTL
|
||||||
{
|
{
|
||||||
IOCTL_SO_ACCEPT = 1,
|
IOCTL_SO_ACCEPT = 1,
|
||||||
IOCTL_SO_BIND,
|
IOCTL_SO_BIND,
|
||||||
IOCTL_SO_CLOSE,
|
IOCTL_SO_CLOSE,
|
||||||
|
@ -605,8 +618,27 @@ private:
|
||||||
IOCTLV_SO_ICMPPING,
|
IOCTLV_SO_ICMPPING,
|
||||||
IOCTL_SO_ICMPCANCEL,
|
IOCTL_SO_ICMPCANCEL,
|
||||||
IOCTL_SO_ICMPCLOSE
|
IOCTL_SO_ICMPCLOSE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
class CWII_IPC_HLE_Device_net_ip_top : public IWII_IPC_HLE_Device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CWII_IPC_HLE_Device_net_ip_top(u32 _DeviceID, const std::string& _rDeviceName);
|
||||||
|
|
||||||
|
virtual ~CWII_IPC_HLE_Device_net_ip_top();
|
||||||
|
|
||||||
|
virtual bool Open(u32 _CommandAddress, u32 _Mode);
|
||||||
|
virtual bool Close(u32 _CommandAddress, bool _bForce);
|
||||||
|
virtual bool IOCtl(u32 _CommandAddress);
|
||||||
|
virtual bool IOCtlV(u32 _CommandAddress);
|
||||||
|
|
||||||
|
virtual u32 Update();
|
||||||
|
|
||||||
|
private:
|
||||||
|
#ifdef _WIN32
|
||||||
|
WSADATA InitData;
|
||||||
|
#endif
|
||||||
u32 ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize);
|
u32 ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize);
|
||||||
u32 ExecuteCommandV(SIOCtlVBuffer& CommandBuffer);
|
u32 ExecuteCommandV(SIOCtlVBuffer& CommandBuffer);
|
||||||
};
|
};
|
||||||
|
@ -687,7 +719,7 @@ private:
|
||||||
SCAN_PASSIVE
|
SCAN_PASSIVE
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct ScanInfo
|
struct ScanInfo
|
||||||
{
|
{
|
||||||
u16 channel_bitmap;
|
u16 channel_bitmap;
|
||||||
|
@ -731,7 +763,7 @@ private:
|
||||||
char wlversion[0x50];
|
char wlversion[0x50];
|
||||||
u8 unk[0x30];
|
u8 unk[0x30];
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,14 +17,17 @@
|
||||||
|
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
#include "WII_IPC_HLE_Device_net_ssl.h"
|
#include "WII_IPC_HLE_Device_net_ssl.h"
|
||||||
|
#include "WII_Socket.h"
|
||||||
#include "../Debugger/Debugger_SymbolMap.h"
|
#include "../Debugger/Debugger_SymbolMap.h"
|
||||||
|
|
||||||
|
WII_SSL CWII_IPC_HLE_Device_net_ssl::_SSL[NET_SSL_MAXINSTANCES];
|
||||||
|
|
||||||
CWII_IPC_HLE_Device_net_ssl::CWII_IPC_HLE_Device_net_ssl(u32 _DeviceID, const std::string& _rDeviceName)
|
CWII_IPC_HLE_Device_net_ssl::CWII_IPC_HLE_Device_net_ssl(u32 _DeviceID, const std::string& _rDeviceName)
|
||||||
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
|
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NET_SSL_MAXINSTANCES; ++i)
|
for (int i = 0; i < NET_SSL_MAXINSTANCES; ++i)
|
||||||
{
|
{
|
||||||
memset(&_SSL[i], 0, sizeof(struct _SSL));
|
memset(&_SSL[i], 0, sizeof(WII_SSL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +48,7 @@ CWII_IPC_HLE_Device_net_ssl::~CWII_IPC_HLE_Device_net_ssl()
|
||||||
memset(&_SSL[i].ctx, 0, sizeof(ssl_context));
|
memset(&_SSL[i].ctx, 0, sizeof(ssl_context));
|
||||||
memset(&_SSL[i].session, 0, sizeof(ssl_session));
|
memset(&_SSL[i].session, 0, sizeof(ssl_session));
|
||||||
memset(&_SSL[i].hs, 0, sizeof(havege_state));
|
memset(&_SSL[i].hs, 0, sizeof(havege_state));
|
||||||
memset(_SSL[i].hostname, 0, MAX_HOSTNAME_LEN);
|
memset(_SSL[i].hostname, 0, NET_SSL_MAX_HOSTNAME_LEN);
|
||||||
|
|
||||||
_SSL[i].active = false;
|
_SSL[i].active = false;
|
||||||
}
|
}
|
||||||
|
@ -94,16 +97,7 @@ bool CWII_IPC_HLE_Device_net_ssl::IOCtl(u32 _CommandAddress)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress)
|
|
||||||
{
|
|
||||||
u32 ReturnValue = 0;
|
|
||||||
SIOCtlVBuffer CommandBuffer(_CommandAddress);
|
|
||||||
|
|
||||||
ReturnValue = ExecuteCommandV(CommandBuffer.Parameter, CommandBuffer);
|
|
||||||
|
|
||||||
Memory::Write_U32(ReturnValue, _CommandAddress+4);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_verify_certificate_callback (void *data, x509_cert *crt, int depth, int *flags)
|
_verify_certificate_callback (void *data, x509_cert *crt, int depth, int *flags)
|
||||||
|
@ -145,14 +139,17 @@ _verify_certificate_callback (void *data, x509_cert *crt, int depth, int *flags)
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer CommandBuffer)
|
bool CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress)
|
||||||
{
|
{
|
||||||
|
u32 ReturnValue = 0;
|
||||||
|
SIOCtlVBuffer CommandBuffer(_CommandAddress);
|
||||||
|
|
||||||
s32 returnValue = 0;
|
s32 returnValue = 0;
|
||||||
|
|
||||||
u32 _BufferIn = 0, _BufferIn2 = 0, _BufferIn3 = 0;
|
u32 _BufferIn = 0, _BufferIn2 = 0, _BufferIn3 = 0;
|
||||||
u32 BufferInSize = 0, BufferInSize2 = 0, BufferInSize3 = 0;
|
u32 BufferInSize = 0, BufferInSize2 = 0, BufferInSize3 = 0;
|
||||||
|
|
||||||
u32 _BufferOut = 0, _BufferOut2 = 0, _BufferOut3 = 0;
|
u32 BufferOut = 0, BufferOut2 = 0, BufferOut3 = 0;
|
||||||
u32 BufferOutSize = 0, BufferOutSize2 = 0, BufferOutSize3 = 0;
|
u32 BufferOutSize = 0, BufferOutSize2 = 0, BufferOutSize3 = 0;
|
||||||
|
|
||||||
if (CommandBuffer.InBuffer.size() > 0)
|
if (CommandBuffer.InBuffer.size() > 0)
|
||||||
|
@ -173,26 +170,26 @@ u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer C
|
||||||
|
|
||||||
if (CommandBuffer.PayloadBuffer.size() > 0)
|
if (CommandBuffer.PayloadBuffer.size() > 0)
|
||||||
{
|
{
|
||||||
_BufferOut = CommandBuffer.PayloadBuffer.at(0).m_Address;
|
BufferOut = CommandBuffer.PayloadBuffer.at(0).m_Address;
|
||||||
BufferOutSize = CommandBuffer.PayloadBuffer.at(0).m_Size;
|
BufferOutSize = CommandBuffer.PayloadBuffer.at(0).m_Size;
|
||||||
}
|
}
|
||||||
if (CommandBuffer.PayloadBuffer.size() > 1)
|
if (CommandBuffer.PayloadBuffer.size() > 1)
|
||||||
{
|
{
|
||||||
_BufferOut2 = CommandBuffer.PayloadBuffer.at(1).m_Address;
|
BufferOut2 = CommandBuffer.PayloadBuffer.at(1).m_Address;
|
||||||
BufferOutSize2 = CommandBuffer.PayloadBuffer.at(1).m_Size;
|
BufferOutSize2 = CommandBuffer.PayloadBuffer.at(1).m_Size;
|
||||||
}
|
}
|
||||||
if (CommandBuffer.PayloadBuffer.size() > 2)
|
if (CommandBuffer.PayloadBuffer.size() > 2)
|
||||||
{
|
{
|
||||||
_BufferOut3 = CommandBuffer.PayloadBuffer.at(2).m_Address;
|
BufferOut3 = CommandBuffer.PayloadBuffer.at(2).m_Address;
|
||||||
BufferOutSize3 = CommandBuffer.PayloadBuffer.at(2).m_Size;
|
BufferOutSize3 = CommandBuffer.PayloadBuffer.at(2).m_Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (_Parameter)
|
switch (CommandBuffer.Parameter)
|
||||||
{
|
{
|
||||||
case IOCTLV_NET_SSL_NEW:
|
case IOCTLV_NET_SSL_NEW:
|
||||||
{
|
{
|
||||||
int verifyOption = Memory::Read_U32(_BufferOut);
|
int verifyOption = Memory::Read_U32(BufferOut);
|
||||||
const char * hostname = (const char*) Memory::GetPointer(_BufferOut2);
|
const char * hostname = (const char*) Memory::GetPointer(BufferOut2);
|
||||||
|
|
||||||
int freeSSL = this->getSSLFreeID();
|
int freeSSL = this->getSSLFreeID();
|
||||||
if (freeSSL)
|
if (freeSSL)
|
||||||
|
@ -221,8 +218,8 @@ u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer C
|
||||||
ssl_set_authmode(&_SSL[sslID].ctx, SSL_VERIFY_OPTIONAL);
|
ssl_set_authmode(&_SSL[sslID].ctx, SSL_VERIFY_OPTIONAL);
|
||||||
ssl_set_renegotiation(&_SSL[sslID].ctx, SSL_RENEGOTIATION_ENABLED);
|
ssl_set_renegotiation(&_SSL[sslID].ctx, SSL_RENEGOTIATION_ENABLED);
|
||||||
|
|
||||||
memcpy(_SSL[sslID].hostname, hostname, min((int)BufferOutSize2, MAX_HOSTNAME_LEN));
|
memcpy(_SSL[sslID].hostname, hostname, min((int)BufferOutSize2, NET_SSL_MAX_HOSTNAME_LEN));
|
||||||
_SSL[sslID].hostname[MAX_HOSTNAME_LEN-1] = '\0';
|
_SSL[sslID].hostname[NET_SSL_MAX_HOSTNAME_LEN-1] = '\0';
|
||||||
ssl_set_hostname(&_SSL[sslID].ctx, _SSL[sslID].hostname);
|
ssl_set_hostname(&_SSL[sslID].ctx, _SSL[sslID].hostname);
|
||||||
|
|
||||||
_SSL[sslID].active = true;
|
_SSL[sslID].active = true;
|
||||||
|
@ -240,13 +237,13 @@ _SSL_NEW_ERROR:
|
||||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||||
verifyOption, hostname,
|
verifyOption, hostname,
|
||||||
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
||||||
_BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
|
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
|
||||||
_BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
|
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTLV_NET_SSL_SHUTDOWN:
|
case IOCTLV_NET_SSL_SHUTDOWN:
|
||||||
{
|
{
|
||||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (SSLID_VALID(sslID))
|
||||||
{
|
{
|
||||||
ssl_close_notify(&_SSL[sslID].ctx);
|
ssl_close_notify(&_SSL[sslID].ctx);
|
||||||
|
@ -259,7 +256,7 @@ _SSL_NEW_ERROR:
|
||||||
memset(&_SSL[sslID].ctx, 0, sizeof(ssl_context));
|
memset(&_SSL[sslID].ctx, 0, sizeof(ssl_context));
|
||||||
memset(&_SSL[sslID].session, 0, sizeof(ssl_session));
|
memset(&_SSL[sslID].session, 0, sizeof(ssl_session));
|
||||||
memset(&_SSL[sslID].hs, 0, sizeof(havege_state));
|
memset(&_SSL[sslID].hs, 0, sizeof(havege_state));
|
||||||
memset(_SSL[sslID].hostname, 0, MAX_HOSTNAME_LEN);
|
memset(_SSL[sslID].hostname, 0, NET_SSL_MAX_HOSTNAME_LEN);
|
||||||
|
|
||||||
_SSL[sslID].active = false;
|
_SSL[sslID].active = false;
|
||||||
|
|
||||||
|
@ -274,8 +271,8 @@ _SSL_NEW_ERROR:
|
||||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||||
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
||||||
_BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
|
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
|
||||||
_BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
|
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTLV_NET_SSL_SETROOTCA:
|
case IOCTLV_NET_SSL_SETROOTCA:
|
||||||
|
@ -285,16 +282,16 @@ _SSL_NEW_ERROR:
|
||||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||||
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
||||||
_BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
|
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
|
||||||
_BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
|
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
||||||
|
|
||||||
|
|
||||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (SSLID_VALID(sslID))
|
||||||
{
|
{
|
||||||
int ret = x509parse_crt_der(
|
int ret = x509parse_crt_der(
|
||||||
&_SSL[sslID].cacert,
|
&_SSL[sslID].cacert,
|
||||||
Memory::GetPointer(_BufferOut2),
|
Memory::GetPointer(BufferOut2),
|
||||||
BufferOutSize2);
|
BufferOutSize2);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -322,10 +319,10 @@ _SSL_NEW_ERROR:
|
||||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||||
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
||||||
_BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
|
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
|
||||||
_BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
|
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
||||||
|
|
||||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (SSLID_VALID(sslID))
|
||||||
{
|
{
|
||||||
std::string cert_base_path(File::GetUserPath(D_WIIUSER_IDX));
|
std::string cert_base_path(File::GetUserPath(D_WIIUSER_IDX));
|
||||||
|
@ -361,10 +358,10 @@ _SSL_NEW_ERROR:
|
||||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||||
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
||||||
_BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
|
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
|
||||||
_BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
|
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
||||||
|
|
||||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (SSLID_VALID(sslID))
|
||||||
{
|
{
|
||||||
x509_free(&_SSL[sslID].clicert);
|
x509_free(&_SSL[sslID].clicert);
|
||||||
|
@ -384,7 +381,7 @@ _SSL_NEW_ERROR:
|
||||||
}
|
}
|
||||||
case IOCTLV_NET_SSL_SETBUILTINROOTCA:
|
case IOCTLV_NET_SSL_SETBUILTINROOTCA:
|
||||||
{
|
{
|
||||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (SSLID_VALID(sslID))
|
||||||
{
|
{
|
||||||
std::string cert_base_path(File::GetUserPath(D_WIIUSER_IDX));
|
std::string cert_base_path(File::GetUserPath(D_WIIUSER_IDX));
|
||||||
|
@ -411,16 +408,16 @@ _SSL_NEW_ERROR:
|
||||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||||
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
||||||
_BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
|
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
|
||||||
_BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
|
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTLV_NET_SSL_CONNECT:
|
case IOCTLV_NET_SSL_CONNECT:
|
||||||
{
|
{
|
||||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (SSLID_VALID(sslID))
|
||||||
{
|
{
|
||||||
_SSL[sslID].sockfd = Memory::Read_U32(_BufferOut2);
|
_SSL[sslID].sockfd = Memory::Read_U32(BufferOut2);
|
||||||
WARN_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_CONNECT socket = %d", _SSL[sslID].sockfd);
|
WARN_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_CONNECT socket = %d", _SSL[sslID].sockfd);
|
||||||
ssl_set_bio(&_SSL[sslID].ctx, net_recv, &_SSL[sslID].sockfd, net_send, &_SSL[sslID].sockfd);
|
ssl_set_bio(&_SSL[sslID].ctx, net_recv, &_SSL[sslID].sockfd, net_send, &_SSL[sslID].sockfd);
|
||||||
Memory::Write_U32(SSL_OK, _BufferIn);
|
Memory::Write_U32(SSL_OK, _BufferIn);
|
||||||
|
@ -434,77 +431,33 @@ _SSL_NEW_ERROR:
|
||||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||||
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
||||||
_BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
|
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
|
||||||
_BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
|
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTLV_NET_SSL_DOHANDSHAKE:
|
case IOCTLV_NET_SSL_DOHANDSHAKE:
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
|
||||||
if (SSLID_VALID(sslID))
|
if (SSLID_VALID(sslID))
|
||||||
{
|
{
|
||||||
ret = ssl_handshake(&_SSL[sslID].ctx);
|
WiiSockMan &sm = WiiSockMan::getInstance();
|
||||||
switch (ret)
|
sm.doSock(_SSL[sslID].sockfd, _CommandAddress, IOCTLV_NET_SSL_DOHANDSHAKE);
|
||||||
{
|
return false;
|
||||||
case 0:
|
|
||||||
Memory::Write_U32(SSL_OK, _BufferIn);
|
|
||||||
break;
|
|
||||||
case POLARSSL_ERR_NET_WANT_READ:
|
|
||||||
Memory::Write_U32(SSL_ERR_RAGAIN, _BufferIn);
|
|
||||||
break;
|
|
||||||
case POLARSSL_ERR_NET_WANT_WRITE:
|
|
||||||
Memory::Write_U32(SSL_ERR_WAGAIN, _BufferIn);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Memory::Write_U32(SSL_ERR_FAILED, _BufferIn);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Memory::Write_U32(SSL_ERR_ID, _BufferIn);
|
Memory::Write_U32(SSL_ERR_ID, _BufferIn);
|
||||||
}
|
}
|
||||||
WARN_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_DOHANDSHAKE = (%d) "
|
|
||||||
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
|
|
||||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
|
||||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
|
||||||
ret,
|
|
||||||
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
|
||||||
_BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
|
|
||||||
_BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTLV_NET_SSL_WRITE:
|
case IOCTLV_NET_SSL_WRITE:
|
||||||
{
|
{
|
||||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (SSLID_VALID(sslID))
|
||||||
{
|
{
|
||||||
int ret = ssl_write( &_SSL[sslID].ctx, Memory::GetPointer(_BufferOut2), BufferOutSize2);
|
WiiSockMan &sm = WiiSockMan::getInstance();
|
||||||
|
sm.doSock(_SSL[sslID].sockfd, _CommandAddress, IOCTLV_NET_SSL_WRITE);
|
||||||
#ifdef DEBUG_SSL
|
return false;
|
||||||
File::IOFile("ssl_write.bin", "ab").WriteBytes(Memory::GetPointer(_BufferOut2), BufferOutSize2);
|
|
||||||
#endif
|
|
||||||
if (ret >= 0)
|
|
||||||
{
|
|
||||||
// Return bytes written or SSL_ERR_ZERO if none
|
|
||||||
Memory::Write_U32((ret == 0) ? SSL_ERR_ZERO : ret, _BufferIn);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (ret)
|
|
||||||
{
|
|
||||||
case POLARSSL_ERR_NET_WANT_READ:
|
|
||||||
Memory::Write_U32(SSL_ERR_RAGAIN, _BufferIn);
|
|
||||||
break;
|
|
||||||
case POLARSSL_ERR_NET_WANT_WRITE:
|
|
||||||
Memory::Write_U32(SSL_ERR_WAGAIN, _BufferIn);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Memory::Write_U32(SSL_ERR_FAILED, _BufferIn);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -515,45 +468,21 @@ _SSL_NEW_ERROR:
|
||||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||||
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
||||||
_BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
|
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
|
||||||
_BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
|
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
||||||
WARN_LOG(WII_IPC_SSL, "%s", Memory::GetPointer(_BufferOut2));
|
WARN_LOG(WII_IPC_SSL, "%s", Memory::GetPointer(BufferOut2));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTLV_NET_SSL_READ:
|
case IOCTLV_NET_SSL_READ:
|
||||||
{
|
{
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (SSLID_VALID(sslID))
|
||||||
{
|
{
|
||||||
ret = ssl_read( &_SSL[sslID].ctx, Memory::GetPointer(_BufferIn2), BufferInSize2);
|
WiiSockMan &sm = WiiSockMan::getInstance();
|
||||||
#ifdef DEBUG_SSL
|
sm.doSock(_SSL[sslID].sockfd, _CommandAddress, IOCTLV_NET_SSL_READ);
|
||||||
if (ret > 0)
|
return false;
|
||||||
{
|
|
||||||
File::IOFile("ssl_read.bin", "ab").WriteBytes(Memory::GetPointer(_BufferIn2), ret);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (ret >= 0)
|
|
||||||
{
|
|
||||||
// Return bytes read or SSL_ERR_ZERO if none
|
|
||||||
Memory::Write_U32((ret == 0) ? SSL_ERR_ZERO : ret, _BufferIn);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (ret)
|
|
||||||
{
|
|
||||||
case POLARSSL_ERR_NET_WANT_READ:
|
|
||||||
Memory::Write_U32(SSL_ERR_RAGAIN, _BufferIn);
|
|
||||||
break;
|
|
||||||
case POLARSSL_ERR_NET_WANT_WRITE:
|
|
||||||
Memory::Write_U32(SSL_ERR_WAGAIN, _BufferIn);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Memory::Write_U32(SSL_ERR_FAILED, _BufferIn);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -566,13 +495,13 @@ _SSL_NEW_ERROR:
|
||||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||||
ret,
|
ret,
|
||||||
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
||||||
_BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
|
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
|
||||||
_BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
|
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTLV_NET_SSL_SETROOTCADEFAULT:
|
case IOCTLV_NET_SSL_SETROOTCADEFAULT:
|
||||||
{
|
{
|
||||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (SSLID_VALID(sslID))
|
||||||
{
|
{
|
||||||
Memory::Write_U32(SSL_OK, _BufferIn);
|
Memory::Write_U32(SSL_OK, _BufferIn);
|
||||||
|
@ -586,8 +515,8 @@ _SSL_NEW_ERROR:
|
||||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||||
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
||||||
_BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
|
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
|
||||||
_BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
|
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTLV_NET_SSL_SETCLIENTCERTDEFAULT:
|
case IOCTLV_NET_SSL_SETCLIENTCERTDEFAULT:
|
||||||
|
@ -597,10 +526,10 @@ _SSL_NEW_ERROR:
|
||||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||||
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
||||||
_BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
|
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
|
||||||
_BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
|
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
||||||
|
|
||||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
if (SSLID_VALID(sslID))
|
if (SSLID_VALID(sslID))
|
||||||
{
|
{
|
||||||
Memory::Write_U32(SSL_OK, _BufferIn);
|
Memory::Write_U32(SSL_OK, _BufferIn);
|
||||||
|
@ -616,22 +545,24 @@ _SSL_NEW_ERROR:
|
||||||
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
|
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
|
||||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||||
_Parameter,
|
CommandBuffer.Parameter,
|
||||||
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
||||||
_BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
|
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
|
||||||
_BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
|
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return returnValue;
|
|
||||||
|
Memory::Write_U32(ReturnValue, _CommandAddress+4);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommand(u32 _Command,
|
u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommand(u32 _Command,
|
||||||
u32 _BufferIn, u32 BufferInSize,
|
u32 _BufferIn, u32 BufferInSize,
|
||||||
u32 _BufferOut, u32 BufferOutSize)
|
u32 BufferOut, u32 BufferOutSize)
|
||||||
{
|
{
|
||||||
WARN_LOG(WII_IPC_SSL, "%s unknown %i "
|
WARN_LOG(WII_IPC_SSL, "%s unknown %i "
|
||||||
"(BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
|
"(BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
|
||||||
GetDeviceName().c_str(), _Command,
|
GetDeviceName().c_str(), _Command,
|
||||||
_BufferIn, BufferInSize, _BufferOut, BufferOutSize);
|
_BufferIn, BufferInSize, BufferOut, BufferOutSize);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,43 +24,30 @@
|
||||||
#include <polarssl/ssl.h>
|
#include <polarssl/ssl.h>
|
||||||
#include <polarssl/havege.h>
|
#include <polarssl/havege.h>
|
||||||
|
|
||||||
#define MAX_HOSTNAME_LEN 256
|
#define NET_SSL_MAX_HOSTNAME_LEN 256
|
||||||
#define NET_SSL_MAXINSTANCES 4
|
#define NET_SSL_MAXINSTANCES 4
|
||||||
|
|
||||||
#define SSLID_VALID(x) (x >= 0 && x < NET_SSL_MAXINSTANCES && _SSL[x].active)
|
#define SSLID_VALID(x) (x >= 0 && x < NET_SSL_MAXINSTANCES && CWII_IPC_HLE_Device_net_ssl::_SSL[x].active)
|
||||||
|
|
||||||
class CWII_IPC_HLE_Device_net_ssl : public IWII_IPC_HLE_Device
|
enum ssl_err_t
|
||||||
{
|
{
|
||||||
public:
|
SSL_OK = 0,
|
||||||
|
SSL_ERR_FAILED = -1,
|
||||||
|
SSL_ERR_RAGAIN = -2,
|
||||||
|
SSL_ERR_WAGAIN = -3,
|
||||||
|
SSL_ERR_SYSCALL = -5,
|
||||||
|
SSL_ERR_ZERO = -6, // read or write returned 0
|
||||||
|
SSL_ERR_CAGAIN = -7, // BIO not connected
|
||||||
|
SSL_ERR_ID = -8, // invalid SSL id
|
||||||
|
SSL_ERR_VCOMMONNAME = -9, // verify failed: common name
|
||||||
|
SSL_ERR_VROOTCA = -10, // verify failed: root ca
|
||||||
|
SSL_ERR_VCHAIN = -11, // verify failed: certificate chain
|
||||||
|
SSL_ERR_VDATE = -12, // verify failed: date invalid
|
||||||
|
SSL_ERR_SERVER_CERT = -13, // certificate cert invalid
|
||||||
|
};
|
||||||
|
|
||||||
CWII_IPC_HLE_Device_net_ssl(u32 _DeviceID, const std::string& _rDeviceName);
|
enum SSL_IOCTL
|
||||||
|
{
|
||||||
virtual ~CWII_IPC_HLE_Device_net_ssl();
|
|
||||||
|
|
||||||
virtual bool Open(u32 _CommandAddress, u32 _Mode);
|
|
||||||
|
|
||||||
virtual bool Close(u32 _CommandAddress, bool _bForce);
|
|
||||||
|
|
||||||
virtual bool IOCtl(u32 _CommandAddress);
|
|
||||||
virtual bool IOCtlV(u32 _CommandAddress);
|
|
||||||
int getSSLFreeID();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
struct _SSL{
|
|
||||||
ssl_context ctx;
|
|
||||||
ssl_session session;
|
|
||||||
havege_state hs;
|
|
||||||
x509_cert cacert;
|
|
||||||
x509_cert clicert;
|
|
||||||
rsa_context rsa;
|
|
||||||
int sockfd;
|
|
||||||
char hostname[MAX_HOSTNAME_LEN];
|
|
||||||
bool active;
|
|
||||||
} _SSL[NET_SSL_MAXINSTANCES];
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
IOCTLV_NET_SSL_NEW = 0x01,
|
IOCTLV_NET_SSL_NEW = 0x01,
|
||||||
IOCTLV_NET_SSL_CONNECT = 0x02,
|
IOCTLV_NET_SSL_CONNECT = 0x02,
|
||||||
IOCTLV_NET_SSL_DOHANDSHAKE = 0x03,
|
IOCTLV_NET_SSL_DOHANDSHAKE = 0x03,
|
||||||
|
@ -78,24 +65,40 @@ private:
|
||||||
IOCTLV_NET_SSL_DISABLEVERIFYOPTIONFORDEBUG = 0x0F,
|
IOCTLV_NET_SSL_DISABLEVERIFYOPTIONFORDEBUG = 0x0F,
|
||||||
IOCTLV_NET_SSL_DEBUGGETVERSION = 0x14,
|
IOCTLV_NET_SSL_DEBUGGETVERSION = 0x14,
|
||||||
IOCTLV_NET_SSL_DEBUGGETTIME = 0x15,
|
IOCTLV_NET_SSL_DEBUGGETTIME = 0x15,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ssl_context ctx;
|
||||||
|
ssl_session session;
|
||||||
|
havege_state hs;
|
||||||
|
x509_cert cacert;
|
||||||
|
x509_cert clicert;
|
||||||
|
rsa_context rsa;
|
||||||
|
int sockfd;
|
||||||
|
char hostname[NET_SSL_MAX_HOSTNAME_LEN];
|
||||||
|
bool active;
|
||||||
|
} WII_SSL;
|
||||||
|
|
||||||
|
class CWII_IPC_HLE_Device_net_ssl : public IWII_IPC_HLE_Device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CWII_IPC_HLE_Device_net_ssl(u32 _DeviceID, const std::string& _rDeviceName);
|
||||||
|
|
||||||
|
virtual ~CWII_IPC_HLE_Device_net_ssl();
|
||||||
|
|
||||||
|
virtual bool Open(u32 _CommandAddress, u32 _Mode);
|
||||||
|
|
||||||
|
virtual bool Close(u32 _CommandAddress, bool _bForce);
|
||||||
|
|
||||||
|
virtual bool IOCtl(u32 _CommandAddress);
|
||||||
|
virtual bool IOCtlV(u32 _CommandAddress);
|
||||||
|
int getSSLFreeID();
|
||||||
|
|
||||||
|
static WII_SSL _SSL[NET_SSL_MAXINSTANCES];
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
enum ssl_err_t
|
|
||||||
{
|
|
||||||
SSL_OK = 0,
|
|
||||||
SSL_ERR_FAILED = -1,
|
|
||||||
SSL_ERR_RAGAIN = -2,
|
|
||||||
SSL_ERR_WAGAIN = -3,
|
|
||||||
SSL_ERR_SYSCALL = -5,
|
|
||||||
SSL_ERR_ZERO = -6, // read or write returned 0
|
|
||||||
SSL_ERR_CAGAIN = -7, // BIO not connected
|
|
||||||
SSL_ERR_ID = -8, // invalid SSL id
|
|
||||||
SSL_ERR_VCOMMONNAME = -9, // verify failed: common name
|
|
||||||
SSL_ERR_VROOTCA = -10, // verify failed: root ca
|
|
||||||
SSL_ERR_VCHAIN = -11, // verify failed: certificate chain
|
|
||||||
SSL_ERR_VDATE = -12, // verify failed: date invalid
|
|
||||||
SSL_ERR_SERVER_CERT = -13, // certificate cert invalid
|
|
||||||
};
|
|
||||||
|
|
||||||
u32 ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize);
|
u32 ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize);
|
||||||
u32 ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer CommandBuffer);
|
u32 ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer CommandBuffer);
|
||||||
|
|
|
@ -0,0 +1,615 @@
|
||||||
|
// Copyright 2013 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "WII_Socket.h"
|
||||||
|
#include "WII_IPC_HLE.h"
|
||||||
|
#include "WII_IPC_HLE_Device.h"
|
||||||
|
|
||||||
|
using WII_IPC_HLE_Interface::ECommandType;
|
||||||
|
using WII_IPC_HLE_Interface::COMMAND_IOCTL;
|
||||||
|
using WII_IPC_HLE_Interface::COMMAND_IOCTLV;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define ERRORCODE(name) WSA ## name
|
||||||
|
#define EITHER(win32, posix) win32
|
||||||
|
#else
|
||||||
|
#define ERRORCODE(name) name
|
||||||
|
#define EITHER(win32, posix) posix
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char* WiiSockMan::DecodeError(s32 ErrorCode)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
static char Message[1024];
|
||||||
|
// If this program was multi-threaded, we'd want to use FORMAT_MESSAGE_ALLOCATE_BUFFER
|
||||||
|
// instead of a static buffer here.
|
||||||
|
// (And of course, free the buffer when we were done with it)
|
||||||
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
|
||||||
|
FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, ErrorCode,
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)Message, 1024, NULL);
|
||||||
|
return Message;
|
||||||
|
#else
|
||||||
|
return strerror(ErrorCode);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
s32 WiiSockMan::getNetErrorCode(s32 ret, std::string caller, bool isRW)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
s32 errorCode = WSAGetLastError();
|
||||||
|
#else
|
||||||
|
s32 errorCode = errno;
|
||||||
|
#endif
|
||||||
|
if (ret >= 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
WARN_LOG(WII_IPC_NET, "%s failed with error %d: %s, ret= %d",
|
||||||
|
caller.c_str(), errorCode, DecodeError(errorCode), ret);
|
||||||
|
|
||||||
|
switch (errorCode)
|
||||||
|
{
|
||||||
|
case ERRORCODE(EMSGSIZE):
|
||||||
|
ERROR_LOG(WII_IPC_NET, "Find out why this happened, looks like PEEK failure?");
|
||||||
|
return -1; // Should be -SO_EMSGSIZE
|
||||||
|
case EITHER(WSAENOTSOCK, EBADF):
|
||||||
|
return -SO_EBADF;
|
||||||
|
case ERRORCODE(EADDRINUSE):
|
||||||
|
return -SO_EADDRINUSE;
|
||||||
|
case ERRORCODE(ECONNRESET):
|
||||||
|
return -SO_ECONNRESET;
|
||||||
|
case ERRORCODE(EISCONN):
|
||||||
|
return -SO_EISCONN;
|
||||||
|
case ERRORCODE(ENOTCONN):
|
||||||
|
return -SO_EAGAIN; // After proper blocking SO_EAGAIN shouldn't be needed...
|
||||||
|
case ERRORCODE(EINPROGRESS):
|
||||||
|
return -SO_EINPROGRESS;
|
||||||
|
case ERRORCODE(EALREADY):
|
||||||
|
return -SO_EALREADY;
|
||||||
|
case ERRORCODE(EACCES):
|
||||||
|
return -SO_EACCES;
|
||||||
|
case EITHER(WSAEWOULDBLOCK, EAGAIN):
|
||||||
|
if(isRW){
|
||||||
|
return -SO_EAGAIN; // EAGAIN
|
||||||
|
}else{
|
||||||
|
return -SO_EINPROGRESS; // EINPROGRESS
|
||||||
|
}
|
||||||
|
// TODO: remove as this should no longer be a problem once blocking is supported.
|
||||||
|
case EITHER(WSA_INVALID_HANDLE, EBADF):
|
||||||
|
return -SO_EINPROGRESS; // EINPROGRESS
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
WiiSocket::~WiiSocket()
|
||||||
|
{
|
||||||
|
if (fd >= 0)
|
||||||
|
{
|
||||||
|
(void)closeFd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiiSocket::setFd(s32 s)
|
||||||
|
{
|
||||||
|
if (fd >= 0)
|
||||||
|
(void)closeFd();
|
||||||
|
|
||||||
|
nonBlock = false;
|
||||||
|
fd = s;
|
||||||
|
|
||||||
|
// TODO: Remove on completion of async
|
||||||
|
#ifdef _WIN32
|
||||||
|
u_long iMode = 1;
|
||||||
|
int ioctlret = ioctlsocket(fd, FIONBIO, &iMode);
|
||||||
|
u32 millis = 3000;
|
||||||
|
#else
|
||||||
|
int flags;
|
||||||
|
if (-1 == (flags = fcntl(fd, F_GETFL, 0)))
|
||||||
|
flags = 0;
|
||||||
|
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
||||||
|
|
||||||
|
struct timeval millis;
|
||||||
|
millis.tv_sec = 3;
|
||||||
|
millis.tv_usec = 0;
|
||||||
|
#endif
|
||||||
|
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&millis,sizeof(millis));
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 WiiSocket::closeFd()
|
||||||
|
{
|
||||||
|
s32 ReturnValue = 0;
|
||||||
|
if (fd >= 0)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
s32 ret = closesocket(fd);
|
||||||
|
#else
|
||||||
|
s32 ret = close(sock);
|
||||||
|
#endif
|
||||||
|
ReturnValue = WiiSockMan::getNetErrorCode(ret, "delSocket", false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ReturnValue = WiiSockMan::getNetErrorCode(EITHER(WSAENOTSOCK, EBADF), "delSocket", false);
|
||||||
|
}
|
||||||
|
fd = -1;
|
||||||
|
return ReturnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 WiiSocket::_connect(sockaddr_in* name, s32 namelen)
|
||||||
|
{
|
||||||
|
int ret = connect(fd, (sockaddr*)name, namelen);
|
||||||
|
ret = WiiSockMan::getNetErrorCode(ret, "SO_CONNECT", false);
|
||||||
|
|
||||||
|
WARN_LOG(WII_IPC_NET,"IOCTL_SO_CONNECT (%08x, %s:%d)",
|
||||||
|
fd, inet_ntoa(name->sin_addr), Common::swap16(name->sin_port));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 WiiSocket::_bind(sockaddr_in* name, s32 namelen)
|
||||||
|
{
|
||||||
|
int ret = bind(fd, (sockaddr*)name, namelen);
|
||||||
|
ret = WiiSockMan::getNetErrorCode(ret, "SO_BIND", false);
|
||||||
|
|
||||||
|
WARN_LOG(WII_IPC_NET, "IOCTL_SO_BIND (%08X %s:%d) = %d ", fd,
|
||||||
|
inet_ntoa(name->sin_addr), Common::swap16(name->sin_port), ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 WiiSocket::_fcntl(u32 cmd, u32 arg)
|
||||||
|
{
|
||||||
|
#define F_GETFL 3
|
||||||
|
#define F_SETFL 4
|
||||||
|
#define F_NONBLOCK 4
|
||||||
|
s32 ret = 0;
|
||||||
|
if (cmd == F_GETFL)
|
||||||
|
{
|
||||||
|
ret = nonBlock ? F_NONBLOCK : 0;
|
||||||
|
}
|
||||||
|
else if (cmd == F_SETFL)
|
||||||
|
{
|
||||||
|
nonBlock = (arg & F_NONBLOCK) == F_NONBLOCK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ERROR_LOG(WII_IPC_NET, "SO_FCNTL unknown command");
|
||||||
|
}
|
||||||
|
|
||||||
|
WARN_LOG(WII_IPC_NET, "IOCTL_SO_FCNTL(%08x, %08X, %08X)",
|
||||||
|
fd, cmd, arg);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiiSocket::update(bool read, bool write, bool except)
|
||||||
|
{
|
||||||
|
auto it = pending_sockops.begin();
|
||||||
|
while (it != pending_sockops.end())
|
||||||
|
{
|
||||||
|
s32 ReturnValue = 0;
|
||||||
|
bool forceNonBlock = false;
|
||||||
|
ECommandType ct = static_cast<ECommandType>(Memory::Read_U32(it->_CommandAddress));
|
||||||
|
if (!it->is_ssl && ct == COMMAND_IOCTL)
|
||||||
|
{
|
||||||
|
u32 BufferIn = Memory::Read_U32(it->_CommandAddress + 0x10);
|
||||||
|
switch(it->net_type)
|
||||||
|
{
|
||||||
|
case IOCTL_SO_FCNTL:
|
||||||
|
{
|
||||||
|
u32 cmd = Memory::Read_U32(BufferIn + 4);
|
||||||
|
u32 arg = Memory::Read_U32(BufferIn + 8);
|
||||||
|
ReturnValue = _fcntl(cmd, arg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IOCTL_SO_BIND:
|
||||||
|
{
|
||||||
|
//TODO: tidy
|
||||||
|
bind_params *addr = (bind_params*)Memory::GetPointer(BufferIn);
|
||||||
|
GC_sockaddr_in addrPC;
|
||||||
|
memcpy(&addrPC, addr->name, sizeof(GC_sockaddr_in));
|
||||||
|
sockaddr_in address;
|
||||||
|
address.sin_family = addrPC.sin_family;
|
||||||
|
address.sin_addr.s_addr = addrPC.sin_addr.s_addr_;
|
||||||
|
address.sin_port = addrPC.sin_port;
|
||||||
|
ReturnValue = _bind(&address, sizeof(address));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IOCTL_SO_CONNECT:
|
||||||
|
{
|
||||||
|
|
||||||
|
//struct sockaddr_in echoServAddr;
|
||||||
|
u32 has_addr = Memory::Read_U32(BufferIn + 0x04);
|
||||||
|
sockaddr_in serverAddr;
|
||||||
|
|
||||||
|
u8 addr[28];
|
||||||
|
Memory::ReadBigEData(addr, BufferIn + 0x08, sizeof(addr));
|
||||||
|
|
||||||
|
if (has_addr != 1)
|
||||||
|
{
|
||||||
|
ReturnValue = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&serverAddr, 0, sizeof(serverAddr));
|
||||||
|
memcpy(&serverAddr, addr, addr[0]);
|
||||||
|
// GC/Wii sockets have a length param as well, we dont really care :)
|
||||||
|
serverAddr.sin_family = serverAddr.sin_family >> 8;
|
||||||
|
|
||||||
|
ReturnValue = _connect(&serverAddr, sizeof(serverAddr));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix blocking error codes
|
||||||
|
if (!nonBlock)
|
||||||
|
{
|
||||||
|
if (it->net_type == IOCTL_SO_CONNECT
|
||||||
|
&& ReturnValue == -SO_EISCONN)
|
||||||
|
{
|
||||||
|
ReturnValue = SO_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ct == COMMAND_IOCTLV)
|
||||||
|
{
|
||||||
|
SIOCtlVBuffer CommandBuffer(it->_CommandAddress);
|
||||||
|
u32 BufferIn = 0, BufferIn2 = 0;
|
||||||
|
u32 BufferInSize = 0, BufferInSize2 = 0;
|
||||||
|
u32 BufferOut = 0, BufferOut2 = 0;
|
||||||
|
u32 BufferOutSize = 0, BufferOutSize2 = 0;
|
||||||
|
|
||||||
|
if (CommandBuffer.InBuffer.size() > 0)
|
||||||
|
{
|
||||||
|
BufferIn = CommandBuffer.InBuffer.at(0).m_Address;
|
||||||
|
BufferInSize = CommandBuffer.InBuffer.at(0).m_Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CommandBuffer.PayloadBuffer.size() > 0)
|
||||||
|
{
|
||||||
|
BufferOut = CommandBuffer.PayloadBuffer.at(0).m_Address;
|
||||||
|
BufferOutSize = CommandBuffer.PayloadBuffer.at(0).m_Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CommandBuffer.PayloadBuffer.size() > 1)
|
||||||
|
{
|
||||||
|
BufferOut2 = CommandBuffer.PayloadBuffer.at(1).m_Address;
|
||||||
|
BufferOutSize2 = CommandBuffer.PayloadBuffer.at(1).m_Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CommandBuffer.InBuffer.size() > 1)
|
||||||
|
{
|
||||||
|
BufferIn2 = CommandBuffer.InBuffer.at(1).m_Address;
|
||||||
|
BufferInSize2 = CommandBuffer.InBuffer.at(1).m_Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (it->is_ssl)
|
||||||
|
{
|
||||||
|
int sslID = Memory::Read_U32(BufferOut) - 1;
|
||||||
|
if (SSLID_VALID(sslID))
|
||||||
|
{
|
||||||
|
switch(it->ssl_type)
|
||||||
|
{
|
||||||
|
case IOCTLV_NET_SSL_DOHANDSHAKE:
|
||||||
|
{
|
||||||
|
|
||||||
|
int ret = ssl_handshake(&CWII_IPC_HLE_Device_net_ssl::_SSL[sslID].ctx);
|
||||||
|
switch (ret)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
Memory::Write_U32(SSL_OK, BufferIn);
|
||||||
|
break;
|
||||||
|
case POLARSSL_ERR_NET_WANT_READ:
|
||||||
|
Memory::Write_U32(SSL_ERR_RAGAIN, BufferIn);
|
||||||
|
if (!nonBlock)
|
||||||
|
ReturnValue = SSL_ERR_RAGAIN;
|
||||||
|
break;
|
||||||
|
case POLARSSL_ERR_NET_WANT_WRITE:
|
||||||
|
Memory::Write_U32(SSL_ERR_WAGAIN, BufferIn);
|
||||||
|
if (!nonBlock)
|
||||||
|
ReturnValue = SSL_ERR_WAGAIN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Memory::Write_U32(SSL_ERR_FAILED, BufferIn);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
WARN_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_DOHANDSHAKE = (%d) "
|
||||||
|
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
|
||||||
|
"BufferOut: (%08x, %i), BufferOut2: (%08x, %i)",
|
||||||
|
ret,
|
||||||
|
BufferIn, BufferInSize, BufferIn2, BufferInSize2,
|
||||||
|
BufferOut, BufferOutSize, BufferOut2, BufferOutSize2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IOCTLV_NET_SSL_WRITE:
|
||||||
|
{
|
||||||
|
int ret = ssl_write(&CWII_IPC_HLE_Device_net_ssl::_SSL[sslID].ctx, Memory::GetPointer(BufferOut2), BufferOutSize2);
|
||||||
|
|
||||||
|
#ifdef DEBUG_SSL
|
||||||
|
File::IOFile("ssl_write.bin", "ab").WriteBytes(Memory::GetPointer(BufferOut2), BufferOutSize2);
|
||||||
|
#endif
|
||||||
|
if (ret >= 0)
|
||||||
|
{
|
||||||
|
// Return bytes written or SSL_ERR_ZERO if none
|
||||||
|
Memory::Write_U32((ret == 0) ? SSL_ERR_ZERO : ret, BufferIn);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (ret)
|
||||||
|
{
|
||||||
|
case POLARSSL_ERR_NET_WANT_READ:
|
||||||
|
Memory::Write_U32(SSL_ERR_RAGAIN, BufferIn);
|
||||||
|
if (!nonBlock)
|
||||||
|
ReturnValue = SSL_ERR_RAGAIN;
|
||||||
|
break;
|
||||||
|
case POLARSSL_ERR_NET_WANT_WRITE:
|
||||||
|
Memory::Write_U32(SSL_ERR_WAGAIN, BufferIn);
|
||||||
|
if (!nonBlock)
|
||||||
|
ReturnValue = SSL_ERR_WAGAIN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Memory::Write_U32(SSL_ERR_FAILED, BufferIn);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IOCTLV_NET_SSL_READ:
|
||||||
|
{
|
||||||
|
int ret = ssl_read(&CWII_IPC_HLE_Device_net_ssl::_SSL[sslID].ctx, Memory::GetPointer(BufferIn2), BufferInSize2);
|
||||||
|
#ifdef DEBUG_SSL
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
File::IOFile("ssl_read.bin", "ab").WriteBytes(Memory::GetPointer(_BufferIn2), ret);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (ret >= 0)
|
||||||
|
{
|
||||||
|
// Return bytes read or SSL_ERR_ZERO if none
|
||||||
|
Memory::Write_U32((ret == 0) ? SSL_ERR_ZERO : ret, BufferIn);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (ret)
|
||||||
|
{
|
||||||
|
case POLARSSL_ERR_NET_WANT_READ:
|
||||||
|
Memory::Write_U32(SSL_ERR_RAGAIN, BufferIn);
|
||||||
|
if (!nonBlock)
|
||||||
|
ReturnValue = SSL_ERR_RAGAIN;
|
||||||
|
break;
|
||||||
|
case POLARSSL_ERR_NET_WANT_WRITE:
|
||||||
|
Memory::Write_U32(SSL_ERR_WAGAIN, BufferIn);
|
||||||
|
if (!nonBlock)
|
||||||
|
ReturnValue = SSL_ERR_WAGAIN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Memory::Write_U32(SSL_ERR_FAILED, BufferIn);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Memory::Write_U32(SSL_ERR_ID, BufferIn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (it->net_type)
|
||||||
|
{
|
||||||
|
case IOCTLV_SO_SENDTO:
|
||||||
|
{
|
||||||
|
|
||||||
|
char * data = (char*)Memory::GetPointer(BufferIn);
|
||||||
|
u32 flags = Common::swap32(BufferIn2 + 0x04);
|
||||||
|
u32 has_destaddr = Common::swap32(BufferIn2 + 0x08);
|
||||||
|
// Act as non blocking when SO_MSG_NONBLOCK is specified
|
||||||
|
forceNonBlock = ((flags & SO_MSG_NONBLOCK) == SO_MSG_NONBLOCK);
|
||||||
|
|
||||||
|
// send/sendto only handles PEEK
|
||||||
|
flags &= SO_MSG_PEEK | SO_MSG_OOB;
|
||||||
|
|
||||||
|
u8 destaddr[28];
|
||||||
|
struct sockaddr_in* addr = (struct sockaddr_in*)&destaddr;
|
||||||
|
if (has_destaddr)
|
||||||
|
{
|
||||||
|
Memory::ReadBigEData((u8*)&destaddr, BufferIn2 + 0x0C, BufferInSize2 - 0x0C);
|
||||||
|
addr->sin_family = addr->sin_family >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = sendto(fd, data, BufferInSize, flags,
|
||||||
|
has_destaddr ? (struct sockaddr*)addr : NULL,
|
||||||
|
has_destaddr ? sizeof(sockaddr) : 0);
|
||||||
|
ReturnValue = WiiSockMan::getNetErrorCode(ret, "SO_SENDTO", true);
|
||||||
|
|
||||||
|
WARN_LOG(WII_IPC_NET,
|
||||||
|
"%s = %d Socket: %08x, BufferIn: (%08x, %i), BufferIn2: (%08x, %i), %u.%u.%u.%u",
|
||||||
|
has_destaddr ? "IOCTLV_SO_SENDTO " : "IOCTLV_SO_SEND ",
|
||||||
|
ReturnValue, fd, BufferIn, BufferInSize,
|
||||||
|
BufferIn2, BufferInSize2,
|
||||||
|
addr->sin_addr.s_addr & 0xFF,
|
||||||
|
(addr->sin_addr.s_addr >> 8) & 0xFF,
|
||||||
|
(addr->sin_addr.s_addr >> 16) & 0xFF,
|
||||||
|
(addr->sin_addr.s_addr >> 24) & 0xFF
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IOCTLV_SO_RECVFROM:
|
||||||
|
{
|
||||||
|
u32 sock = Memory::Read_U32(BufferIn);
|
||||||
|
u32 flags = Memory::Read_U32(BufferIn + 4);
|
||||||
|
|
||||||
|
char *buf = (char *)Memory::GetPointer(BufferOut);
|
||||||
|
int len = BufferOutSize;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
memset(&addr, 0, sizeof(sockaddr_in));
|
||||||
|
socklen_t fromlen = 0;
|
||||||
|
|
||||||
|
if (BufferOutSize2 != 0)
|
||||||
|
{
|
||||||
|
fromlen = BufferOutSize2 >= sizeof(struct sockaddr) ? BufferOutSize2 : sizeof(struct sockaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Act as non blocking when SO_MSG_NONBLOCK is specified
|
||||||
|
forceNonBlock = ((flags & SO_MSG_NONBLOCK) == SO_MSG_NONBLOCK);
|
||||||
|
|
||||||
|
// recv/recvfrom only handles PEEK
|
||||||
|
flags &= SO_MSG_PEEK | SO_MSG_OOB;
|
||||||
|
#ifdef _WIN32
|
||||||
|
if(flags & MSG_PEEK){
|
||||||
|
unsigned long totallen = 0;
|
||||||
|
ioctlsocket(sock, FIONREAD, &totallen);
|
||||||
|
ReturnValue = totallen;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
int ret = recvfrom(sock, buf, len, flags,
|
||||||
|
fromlen ? (struct sockaddr*) &addr : NULL,
|
||||||
|
fromlen ? &fromlen : 0);
|
||||||
|
ReturnValue = WiiSockMan::getNetErrorCode(ret, fromlen ? "SO_RECVFROM" : "SO_RECV", true);
|
||||||
|
|
||||||
|
|
||||||
|
WARN_LOG(WII_IPC_NET, "%s(%d, %p) Socket: %08X, Flags: %08X, "
|
||||||
|
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
|
||||||
|
"BufferOut: (%08x, %i), BufferOut2: (%08x, %i)",
|
||||||
|
fromlen ? "IOCTLV_SO_RECVFROM " : "IOCTLV_SO_RECV ",
|
||||||
|
ReturnValue, buf, sock, flags,
|
||||||
|
BufferIn, BufferInSize, BufferIn2, BufferInSize2,
|
||||||
|
BufferOut, BufferOutSize, BufferOut2, BufferOutSize2);
|
||||||
|
|
||||||
|
if (BufferOutSize2 != 0)
|
||||||
|
{
|
||||||
|
addr.sin_family = (addr.sin_family << 8) | (BufferOutSize2&0xFF);
|
||||||
|
Memory::WriteBigEData((u8*)&addr, BufferOut2, BufferOutSize2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( nonBlock || forceNonBlock
|
||||||
|
|| (!it->is_ssl && ReturnValue != -SO_EAGAIN && ReturnValue != -SO_EINPROGRESS && ReturnValue != -SO_EALREADY)
|
||||||
|
|| (it->is_ssl && ReturnValue != SSL_ERR_WAGAIN && ReturnValue != SSL_ERR_RAGAIN))
|
||||||
|
{
|
||||||
|
WARN_LOG(WII_IPC_NET, "IOCTL(V) Sock: %d ioctl/v: %d returned: %d nonBlock: %d forceNonBlock: %d",
|
||||||
|
fd, it->is_ssl ? it->ssl_type : it->net_type, ReturnValue, nonBlock, forceNonBlock);
|
||||||
|
WiiSockMan::EnqueueReply(it->_CommandAddress, ReturnValue);
|
||||||
|
it = pending_sockops.erase(it);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiiSocket::doSock(u32 _CommandAddress, NET_IOCTL type)
|
||||||
|
{
|
||||||
|
sockop so = {_CommandAddress, false};
|
||||||
|
so.net_type = type;
|
||||||
|
pending_sockops.push_back(so);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiiSocket::doSock(u32 _CommandAddress, SSL_IOCTL type)
|
||||||
|
{
|
||||||
|
sockop so = {_CommandAddress, true};
|
||||||
|
so.ssl_type = type;
|
||||||
|
pending_sockops.push_back(so);
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 WiiSockMan::newSocket(s32 af, s32 type, s32 protocol)
|
||||||
|
{
|
||||||
|
s32 s = (s32)socket(af, type, protocol);
|
||||||
|
s32 ret = getNetErrorCode(s, "newSocket", false);
|
||||||
|
if (ret >= 0)
|
||||||
|
{
|
||||||
|
WiiSocket& sock = WiiSockets[ret];
|
||||||
|
sock.setFd(ret);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 WiiSockMan::delSocket(s32 s)
|
||||||
|
{
|
||||||
|
s32 ReturnValue = WiiSockets[s].closeFd();
|
||||||
|
WiiSockets.erase(s);
|
||||||
|
return ReturnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiiSockMan::Update()
|
||||||
|
{
|
||||||
|
s32 nfds = 0;
|
||||||
|
fd_set read_fds, write_fds, except_fds;
|
||||||
|
struct timeval t = {0,0};
|
||||||
|
FD_ZERO(&read_fds);
|
||||||
|
FD_ZERO(&write_fds);
|
||||||
|
FD_ZERO(&except_fds);
|
||||||
|
for (auto it = WiiSockets.begin(); it != WiiSockets.end(); ++it)
|
||||||
|
{
|
||||||
|
WiiSocket& sock = it->second;
|
||||||
|
if (sock.valid())
|
||||||
|
{
|
||||||
|
FD_SET(sock.fd, &read_fds);
|
||||||
|
FD_SET(sock.fd, &write_fds);
|
||||||
|
FD_SET(sock.fd, &except_fds);
|
||||||
|
nfds = max(nfds, sock.fd+1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Good time to clean up invalid sockets.
|
||||||
|
WiiSockets.erase(sock.fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s32 ret = select(nfds, &read_fds, &write_fds, &except_fds, &t);
|
||||||
|
|
||||||
|
if(ret >= 0)
|
||||||
|
{
|
||||||
|
for (auto it = WiiSockets.begin(); it != WiiSockets.end(); ++it)
|
||||||
|
{
|
||||||
|
WiiSocket& sock = it->second;
|
||||||
|
sock.update(
|
||||||
|
FD_ISSET(sock.fd, &read_fds) != 0,
|
||||||
|
FD_ISSET(sock.fd, &write_fds) != 0,
|
||||||
|
FD_ISSET(sock.fd, &except_fds) != 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto it = WiiSockets.begin(); it != WiiSockets.end(); ++it)
|
||||||
|
{
|
||||||
|
it->second.update(false, false, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WiiSockMan::EnqueueReply(u32 CommandAddress, s32 ReturnValue)
|
||||||
|
{
|
||||||
|
Memory::Write_U32(8, CommandAddress);
|
||||||
|
// IOS seems to write back the command that was responded to
|
||||||
|
Memory::Write_U32(Memory::Read_U32(CommandAddress), CommandAddress + 8);
|
||||||
|
|
||||||
|
// Return value
|
||||||
|
Memory::Write_U32(ReturnValue, CommandAddress + 4);
|
||||||
|
|
||||||
|
WII_IPC_HLE_Interface::EnqReply(CommandAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#undef ERRORCODE
|
||||||
|
#undef EITHER
|
|
@ -0,0 +1,214 @@
|
||||||
|
// Copyright 2013 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#ifndef _WII_SOCKET_H_
|
||||||
|
#define _WII_SOCKET_H_
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#include <iphlpapi.h>
|
||||||
|
#include <iphlpapi.h>
|
||||||
|
|
||||||
|
#include "fakepoll.h"
|
||||||
|
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
|
||||||
|
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
|
||||||
|
|
||||||
|
#elif defined(__linux__) or defined(__APPLE__)
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/fcntl.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef struct pollfd pollfd_t;
|
||||||
|
#else
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/fcntl.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <algorithm> // std::for_each
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
#include "FileUtil.h"
|
||||||
|
#include "WII_IPC_HLE.h"
|
||||||
|
#include "WII_IPC_HLE_Device_net.h"
|
||||||
|
#include "WII_IPC_HLE_Device_net_ssl.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SO_MSG_OOB = 0x01,
|
||||||
|
SO_MSG_PEEK = 0x02,
|
||||||
|
SO_MSG_NONBLOCK = 0x04,
|
||||||
|
};
|
||||||
|
enum {
|
||||||
|
SO_SUCCESS,
|
||||||
|
SO_E2BIG = 1,
|
||||||
|
SO_EACCES,
|
||||||
|
SO_EADDRINUSE,
|
||||||
|
SO_EADDRNOTAVAIL,
|
||||||
|
SO_EAFNOSUPPORT,
|
||||||
|
SO_EAGAIN,
|
||||||
|
SO_EALREADY,
|
||||||
|
SO_EBADF,
|
||||||
|
SO_EBADMSG,
|
||||||
|
SO_EBUSY,
|
||||||
|
SO_ECANCELED,
|
||||||
|
SO_ECHILD,
|
||||||
|
SO_ECONNABORTED,
|
||||||
|
SO_ECONNREFUSED,
|
||||||
|
SO_ECONNRESET,
|
||||||
|
SO_EDEADLK,
|
||||||
|
SO_EDESTADDRREQ,
|
||||||
|
SO_EDOM,
|
||||||
|
SO_EDQUOT,
|
||||||
|
SO_EEXIST,
|
||||||
|
SO_EFAULT,
|
||||||
|
SO_EFBIG,
|
||||||
|
SO_EHOSTUNREACH,
|
||||||
|
SO_EIDRM,
|
||||||
|
SO_EILSEQ,
|
||||||
|
SO_EINPROGRESS,
|
||||||
|
SO_EINTR,
|
||||||
|
SO_EINVAL,
|
||||||
|
SO_EIO,
|
||||||
|
SO_EISCONN,
|
||||||
|
SO_EISDIR,
|
||||||
|
SO_ELOOP,
|
||||||
|
SO_EMFILE,
|
||||||
|
SO_EMLINK,
|
||||||
|
SO_EMSGSIZE,
|
||||||
|
SO_EMULTIHOP,
|
||||||
|
SO_ENAMETOOLONG,
|
||||||
|
SO_ENETDOWN,
|
||||||
|
SO_ENETRESET,
|
||||||
|
SO_ENETUNREACH,
|
||||||
|
SO_ENFILE,
|
||||||
|
SO_ENOBUFS,
|
||||||
|
SO_ENODATA,
|
||||||
|
SO_ENODEV,
|
||||||
|
SO_ENOENT,
|
||||||
|
SO_ENOEXEC,
|
||||||
|
SO_ENOLCK,
|
||||||
|
SO_ENOLINK,
|
||||||
|
SO_ENOMEM,
|
||||||
|
SO_ENOMSG,
|
||||||
|
SO_ENOPROTOOPT,
|
||||||
|
SO_ENOSPC,
|
||||||
|
SO_ENOSR,
|
||||||
|
SO_ENOSTR,
|
||||||
|
SO_ENOSYS,
|
||||||
|
SO_ENOTCONN,
|
||||||
|
SO_ENOTDIR,
|
||||||
|
SO_ENOTEMPTY,
|
||||||
|
SO_ENOTSOCK,
|
||||||
|
SO_ENOTSUP,
|
||||||
|
SO_ENOTTY,
|
||||||
|
SO_ENXIO,
|
||||||
|
SO_EOPNOTSUPP,
|
||||||
|
SO_EOVERFLOW,
|
||||||
|
SO_EPERM,
|
||||||
|
SO_EPIPE,
|
||||||
|
SO_EPROTO,
|
||||||
|
SO_EPROTONOSUPPORT,
|
||||||
|
SO_EPROTOTYPE,
|
||||||
|
SO_ERANGE,
|
||||||
|
SO_EROFS,
|
||||||
|
SO_ESPIPE,
|
||||||
|
SO_ESRCH,
|
||||||
|
SO_ESTALE,
|
||||||
|
SO_ETIME,
|
||||||
|
SO_ETIMEDOUT,
|
||||||
|
SO_ETXTBSY,
|
||||||
|
SO_EXDEV
|
||||||
|
};
|
||||||
|
|
||||||
|
class WiiSocket
|
||||||
|
{
|
||||||
|
struct sockop{
|
||||||
|
u32 _CommandAddress;
|
||||||
|
bool is_ssl;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
NET_IOCTL net_type;
|
||||||
|
SSL_IOCTL ssl_type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
s32 fd;
|
||||||
|
bool nonBlock;
|
||||||
|
std::list<sockop> pending_sockops;
|
||||||
|
|
||||||
|
friend class WiiSockMan;
|
||||||
|
void setFd(s32 s);
|
||||||
|
s32 closeFd();
|
||||||
|
s32 _fcntl(u32 cmd, u32 arg);
|
||||||
|
s32 _bind(sockaddr_in* name, s32 namelen);
|
||||||
|
s32 _connect(sockaddr_in* name, s32 namelen);
|
||||||
|
|
||||||
|
void doSock(u32 _CommandAddress, NET_IOCTL type);
|
||||||
|
void doSock(u32 _CommandAddress, SSL_IOCTL type);
|
||||||
|
void update(bool read, bool write, bool except);
|
||||||
|
bool valid() {return fd >= 0;}
|
||||||
|
public:
|
||||||
|
WiiSocket() : fd(-1), nonBlock(false) {}
|
||||||
|
~WiiSocket();
|
||||||
|
void operator=(WiiSocket const&); // Don't implement
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class WiiSockMan
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static s32 getNetErrorCode(s32 ret, std::string caller, bool isRW);
|
||||||
|
static char* DecodeError(s32 ErrorCode);
|
||||||
|
|
||||||
|
static WiiSockMan& getInstance()
|
||||||
|
{
|
||||||
|
static WiiSockMan instance; // Guaranteed to be destroyed.
|
||||||
|
return instance; // Instantiated on first use.
|
||||||
|
}
|
||||||
|
void Update();
|
||||||
|
static void EnqueueReply(u32 CommandAddress, s32 ReturnValue);
|
||||||
|
|
||||||
|
// NON-BLOCKING FUNCTIONS
|
||||||
|
s32 newSocket(s32 af, s32 type, s32 protocol);
|
||||||
|
s32 delSocket(s32 s);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void doSock(s32 sock, u32 CommandAddress, T type)
|
||||||
|
{
|
||||||
|
if (WiiSockets.find(sock) == WiiSockets.end())
|
||||||
|
{
|
||||||
|
ERROR_LOG(WII_IPC_NET,
|
||||||
|
"doSock: Error, fd not found (%08x, %08X, %08X)",
|
||||||
|
sock, CommandAddress, type);
|
||||||
|
EnqueueReply(CommandAddress, -SO_EBADF);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WiiSockets[sock].doSock(CommandAddress, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
WiiSockMan() {}; // Constructor? (the {} brackets) are needed here.
|
||||||
|
WiiSockMan(WiiSockMan const&); // Don't Implement
|
||||||
|
void operator=(WiiSockMan const&); // Don't implement
|
||||||
|
|
||||||
|
std::unordered_map<s32, WiiSocket> WiiSockets;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue