mirror of
https://github.com/xenia-project/xenia.git
synced 2025-12-06 07:12:03 +01:00
151 lines
4 KiB
C++
151 lines
4 KiB
C++
/**
|
|
******************************************************************************
|
|
* 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_
|