Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -24,10 +24,60 @@
#include <polarssl/ssl.h>
#include <polarssl/havege.h>

#define MAX_HOSTNAME_LEN 256
#define NET_SSL_MAX_HOSTNAME_LEN 256
#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)

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
};

enum SSL_IOCTL
{
IOCTLV_NET_SSL_NEW = 0x01,
IOCTLV_NET_SSL_CONNECT = 0x02,
IOCTLV_NET_SSL_DOHANDSHAKE = 0x03,
IOCTLV_NET_SSL_READ = 0x04,
IOCTLV_NET_SSL_WRITE = 0x05,
IOCTLV_NET_SSL_SHUTDOWN = 0x06,
IOCTLV_NET_SSL_SETCLIENTCERT = 0x07,
IOCTLV_NET_SSL_SETCLIENTCERTDEFAULT = 0x08,
IOCTLV_NET_SSL_REMOVECLIENTCERT = 0x09,
IOCTLV_NET_SSL_SETROOTCA = 0x0A,
IOCTLV_NET_SSL_SETROOTCADEFAULT = 0x0B,
IOCTLV_NET_SSL_DOHANDSHAKEEX = 0x0C,
IOCTLV_NET_SSL_SETBUILTINROOTCA = 0x0D,
IOCTLV_NET_SSL_SETBUILTINCLIENTCERT = 0x0E,
IOCTLV_NET_SSL_DISABLEVERIFYOPTIONFORDEBUG = 0x0F,
IOCTLV_NET_SSL_DEBUGGETVERSION = 0x14,
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
{
@@ -44,58 +94,11 @@ class CWII_IPC_HLE_Device_net_ssl : public IWII_IPC_HLE_Device
virtual bool IOCtl(u32 _CommandAddress);
virtual bool IOCtlV(u32 _CommandAddress);
int getSSLFreeID();

static WII_SSL _SSL[NET_SSL_MAXINSTANCES];

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_CONNECT = 0x02,
IOCTLV_NET_SSL_DOHANDSHAKE = 0x03,
IOCTLV_NET_SSL_READ = 0x04,
IOCTLV_NET_SSL_WRITE = 0x05,
IOCTLV_NET_SSL_SHUTDOWN = 0x06,
IOCTLV_NET_SSL_SETCLIENTCERT = 0x07,
IOCTLV_NET_SSL_SETCLIENTCERTDEFAULT = 0x08,
IOCTLV_NET_SSL_REMOVECLIENTCERT = 0x09,
IOCTLV_NET_SSL_SETROOTCA = 0x0A,
IOCTLV_NET_SSL_SETROOTCADEFAULT = 0x0B,
IOCTLV_NET_SSL_DOHANDSHAKEEX = 0x0C,
IOCTLV_NET_SSL_SETBUILTINROOTCA = 0x0D,
IOCTLV_NET_SSL_SETBUILTINCLIENTCERT = 0x0E,
IOCTLV_NET_SSL_DISABLEVERIFYOPTIONFORDEBUG = 0x0F,
IOCTLV_NET_SSL_DEBUGGETVERSION = 0x14,
IOCTLV_NET_SSL_DEBUGGETTIME = 0x15,
};

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 ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer CommandBuffer);

Large diffs are not rendered by default.

@@ -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