/** ****************************************************************************** * 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 #include "xenia/base/byte_order.h" #include "xenia/base/math.h" #include "xenia/kernel/xobject.h" namespace xe { namespace kernel { struct XSOCKADDR { xe::be 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 sin_family; // Always big-endian! xe::be sin_port; xe::be 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 sin_port; xe::be 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 // https://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 Accept(N_XSOCKADDR* name, int* name_len); int Shutdown(int how); 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 src_port; xe::be 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 event_; std::mutex incoming_packet_mutex_; std::queue incoming_packets_; }; } // namespace kernel } // namespace xe #endif // XENIA_KERNEL_XSOCKET_H_