XSocket Implementation
This commit is contained in:
151
src/xenia/kernel/xsocket.h
Normal file
151
src/xenia/kernel/xsocket.h
Normal file
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2015 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_KERNEL_XSOCKET_H_
|
||||
#define XENIA_KERNEL_XSOCKET_H_
|
||||
|
||||
#include <queue>
|
||||
|
||||
#include "xenia/base/byte_order.h"
|
||||
#include "xenia/base/math.h"
|
||||
#include "xenia/kernel/xobject.h"
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
struct XSOCKADDR {
|
||||
xe::be<uint16_t> address_family;
|
||||
char sa_data[14];
|
||||
};
|
||||
|
||||
struct N_XSOCKADDR {
|
||||
N_XSOCKADDR() {}
|
||||
N_XSOCKADDR(const XSOCKADDR* other) { *this = *other; }
|
||||
N_XSOCKADDR& operator=(const XSOCKADDR& other) {
|
||||
address_family = other.address_family;
|
||||
std::memcpy(sa_data, other.sa_data, xe::countof(sa_data));
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint16_t address_family;
|
||||
char sa_data[14];
|
||||
};
|
||||
|
||||
struct XSOCKADDR_IN {
|
||||
xe::be<uint16_t> sin_family;
|
||||
|
||||
// Always big-endian!
|
||||
xe::be<uint16_t> sin_port;
|
||||
xe::be<uint32_t> sin_addr;
|
||||
char sin_zero[8];
|
||||
};
|
||||
|
||||
// Xenia native sockaddr_in
|
||||
struct N_XSOCKADDR_IN {
|
||||
N_XSOCKADDR_IN() {}
|
||||
N_XSOCKADDR_IN(const XSOCKADDR_IN* other) { *this = *other; }
|
||||
N_XSOCKADDR_IN& operator=(const XSOCKADDR_IN& other) {
|
||||
sin_family = other.sin_family;
|
||||
sin_port = other.sin_port;
|
||||
sin_addr = other.sin_addr;
|
||||
std::memset(sin_zero, 0, 8);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint16_t sin_family;
|
||||
xe::be<uint16_t> sin_port;
|
||||
xe::be<uint32_t> sin_addr;
|
||||
char sin_zero[8];
|
||||
};
|
||||
|
||||
class XSocket : public XObject {
|
||||
public:
|
||||
static const Type kType = kTypeSocket;
|
||||
|
||||
enum AddressFamily {
|
||||
AF_INET = 2,
|
||||
};
|
||||
|
||||
enum Type {
|
||||
SOCK_STREAM = 1,
|
||||
SOCK_DGRAM = 2,
|
||||
};
|
||||
|
||||
enum Protocol {
|
||||
IPPROTO_TCP = 6,
|
||||
IPPROTO_UDP = 17,
|
||||
|
||||
// LIVE Voice and Data Protocol
|
||||
// http://blog.csdn.net/baozi3026/article/details/4277227
|
||||
// Format: [cbGameData][GameData(encrypted)][VoiceData(unencrypted)]
|
||||
IPPROTO_VDP = 254,
|
||||
};
|
||||
|
||||
XSocket(KernelState* kernel_state);
|
||||
~XSocket();
|
||||
|
||||
uint64_t native_handle() const { return native_handle_; }
|
||||
uint16_t bound_port() const { return bound_port_; }
|
||||
|
||||
X_STATUS Initialize(AddressFamily af, Type type, Protocol proto);
|
||||
X_STATUS Close();
|
||||
|
||||
X_STATUS SetOption(uint32_t level, uint32_t optname, void* optval_ptr,
|
||||
uint32_t optlen);
|
||||
X_STATUS IOControl(uint32_t cmd, uint8_t* arg_ptr);
|
||||
|
||||
X_STATUS Connect(N_XSOCKADDR* name, int name_len);
|
||||
X_STATUS Bind(N_XSOCKADDR_IN* name, int name_len);
|
||||
X_STATUS Listen(int backlog);
|
||||
object_ref<XSocket> Accept(N_XSOCKADDR* name, int* name_len);
|
||||
|
||||
int Recv(uint8_t* buf, uint32_t buf_len, uint32_t flags);
|
||||
int Send(const uint8_t* buf, uint32_t buf_len, uint32_t flags);
|
||||
|
||||
int RecvFrom(uint8_t* buf, uint32_t buf_len, uint32_t flags,
|
||||
N_XSOCKADDR_IN* from, uint32_t* from_len);
|
||||
int SendTo(uint8_t* buf, uint32_t buf_len, uint32_t flags, N_XSOCKADDR_IN* to,
|
||||
uint32_t to_len);
|
||||
|
||||
struct packet {
|
||||
// These values are in network byte order.
|
||||
xe::be<uint16_t> src_port;
|
||||
xe::be<uint32_t> src_ip;
|
||||
|
||||
uint16_t data_len;
|
||||
uint8_t data[1];
|
||||
};
|
||||
|
||||
// Queue a packet into our internal buffer.
|
||||
bool QueuePacket(uint32_t src_ip, uint16_t src_port, const uint8_t* buf,
|
||||
size_t len);
|
||||
|
||||
private:
|
||||
XSocket(KernelState* kernel_state, uint64_t native_handle);
|
||||
uint64_t native_handle_ = -1;
|
||||
|
||||
AddressFamily af_; // Address family
|
||||
Type type_; // Type (DGRAM/Stream/etc)
|
||||
Protocol proto_; // Protocol (TCP/UDP/etc)
|
||||
bool secure_ = true; // Secure socket (encryption enabled)
|
||||
|
||||
bool bound_ = false; // Explicitly bound to an IP address?
|
||||
uint16_t bound_port_ = 0;
|
||||
|
||||
bool broadcast_socket_ = false;
|
||||
|
||||
std::unique_ptr<xe::threading::Event> event_;
|
||||
std::mutex incoming_packet_mutex_;
|
||||
std::queue<uint8_t*> incoming_packets_;
|
||||
};
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
#endif // XENIA_KERNEL_XSOCKET_H_
|
||||
Reference in New Issue
Block a user