mirror of https://github.com/mgba-emu/mgba.git
Util: Support IPv6
This commit is contained in:
parent
968069ff5e
commit
76bf0427f1
1
CHANGES
1
CHANGES
|
@ -15,6 +15,7 @@ Features:
|
|||
- Remappable shortcuts for keyboard and gamepad
|
||||
- Rewinding of emulation
|
||||
- Implemented BIOS routines SoftReset, RegisterRamReset, Diff8bitUnFilterWram, Diff8bitUnFilterVram, and Diff16bitUnFilter
|
||||
- Support IPv6
|
||||
Bugfixes:
|
||||
- Qt: Fix issue with set frame sizes being the wrong height
|
||||
- Qt: Fix emulator crashing when full screen if a game is not running
|
||||
|
|
|
@ -446,11 +446,10 @@ void GDBStubCreate(struct GDBStub* stub) {
|
|||
stub->d.log = 0;
|
||||
}
|
||||
|
||||
int GDBStubListen(struct GDBStub* stub, int port, uint32_t bindAddress) {
|
||||
int GDBStubListen(struct GDBStub* stub, int port, const struct Address* bindAddress) {
|
||||
if (!SOCKET_FAILED(stub->socket)) {
|
||||
GDBStubShutdown(stub);
|
||||
}
|
||||
// TODO: support IPv6
|
||||
stub->socket = SocketOpenTCP(port, bindAddress);
|
||||
if (SOCKET_FAILED(stub->socket)) {
|
||||
if (stub->d.log) {
|
||||
|
@ -500,7 +499,7 @@ void GDBStubUpdate(struct GDBStub* stub) {
|
|||
return;
|
||||
}
|
||||
if (stub->connection == INVALID_SOCKET) {
|
||||
stub->connection = SocketAccept(stub->socket, 0, 0);
|
||||
stub->connection = SocketAccept(stub->socket, 0);
|
||||
if (!SOCKET_FAILED(stub->connection)) {
|
||||
if (!SocketSetBlocking(stub->connection, 0)) {
|
||||
goto connectionLost;
|
||||
|
|
|
@ -33,7 +33,7 @@ struct GDBStub {
|
|||
};
|
||||
|
||||
void GDBStubCreate(struct GDBStub*);
|
||||
int GDBStubListen(struct GDBStub*, int port, uint32_t bindAddress);
|
||||
int GDBStubListen(struct GDBStub*, int port, const struct Address* bindAddress);
|
||||
|
||||
void GDBStubHangup(struct GDBStub*);
|
||||
void GDBStubShutdown(struct GDBStub*);
|
||||
|
|
|
@ -13,7 +13,7 @@ GDBController::GDBController(GameController* controller, QObject* parent)
|
|||
: QObject(parent)
|
||||
, m_gameController(controller)
|
||||
, m_port(2345)
|
||||
, m_bindAddress(0)
|
||||
, m_bindAddress({ IPV4, 0 })
|
||||
{
|
||||
GDBStubCreate(&m_gdbStub);
|
||||
}
|
||||
|
@ -22,10 +22,6 @@ ushort GDBController::port() {
|
|||
return m_port;
|
||||
}
|
||||
|
||||
uint32_t GDBController::bindAddress() {
|
||||
return m_bindAddress;
|
||||
}
|
||||
|
||||
bool GDBController::isAttached() {
|
||||
return m_gameController->debugger() == &m_gdbStub.d;
|
||||
}
|
||||
|
@ -35,7 +31,8 @@ void GDBController::setPort(ushort port) {
|
|||
}
|
||||
|
||||
void GDBController::setBindAddress(uint32_t bindAddress) {
|
||||
m_bindAddress = bindAddress;
|
||||
m_bindAddress.version = IPV4;
|
||||
m_bindAddress.ipv4 = htonl(bindAddress);
|
||||
}
|
||||
|
||||
void GDBController::attach() {
|
||||
|
@ -62,7 +59,7 @@ void GDBController::listen() {
|
|||
attach();
|
||||
}
|
||||
connect(m_gameController, SIGNAL(frameAvailable(const uint32_t*)), this, SLOT(updateGDB()));
|
||||
GDBStubListen(&m_gdbStub, m_port, m_bindAddress);
|
||||
GDBStubListen(&m_gdbStub, m_port, &m_bindAddress);
|
||||
m_gameController->threadContinue();
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ public:
|
|||
|
||||
public:
|
||||
ushort port();
|
||||
uint32_t bindAddress();
|
||||
bool isAttached();
|
||||
|
||||
public slots:
|
||||
|
@ -44,7 +43,7 @@ private:
|
|||
GameController* m_gameController;
|
||||
|
||||
ushort m_port;
|
||||
uint32_t m_bindAddress;
|
||||
Address m_bindAddress;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,18 @@ typedef SOCKET Socket;
|
|||
typedef int Socket;
|
||||
#endif
|
||||
|
||||
enum IP {
|
||||
IPV4,
|
||||
IPV6
|
||||
};
|
||||
|
||||
struct Address {
|
||||
enum IP version;
|
||||
union {
|
||||
uint32_t ipv4;
|
||||
uint8_t ipv6[16];
|
||||
};
|
||||
};
|
||||
|
||||
static inline void SocketSubsystemInitialize() {
|
||||
#ifdef _WIN32
|
||||
|
@ -44,18 +56,35 @@ static inline ssize_t SocketRecv(Socket socket, void* buffer, size_t size) {
|
|||
return read(socket, buffer, size);
|
||||
}
|
||||
|
||||
static inline Socket SocketOpenTCP(int port, uint32_t bindAddress) {
|
||||
static inline Socket SocketOpenTCP(int port, const struct Address* bindAddress) {
|
||||
Socket sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (SOCKET_FAILED(sock)) {
|
||||
return sock;
|
||||
}
|
||||
|
||||
struct sockaddr_in bindInfo;
|
||||
memset(&bindInfo, 0, sizeof(bindInfo));
|
||||
bindInfo.sin_family = AF_INET;
|
||||
bindInfo.sin_port = htons(port);
|
||||
bindInfo.sin_addr.s_addr = htonl(bindAddress);
|
||||
int err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(struct sockaddr_in));
|
||||
int err;
|
||||
if (!bindAddress) {
|
||||
struct sockaddr_in bindInfo;
|
||||
memset(&bindInfo, 0, sizeof(bindInfo));
|
||||
bindInfo.sin_family = AF_INET;
|
||||
bindInfo.sin_port = htons(port);
|
||||
err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo));
|
||||
} else if (bindAddress->version == IPV4) {
|
||||
struct sockaddr_in bindInfo;
|
||||
memset(&bindInfo, 0, sizeof(bindInfo));
|
||||
bindInfo.sin_family = AF_INET;
|
||||
bindInfo.sin_port = htons(port);
|
||||
bindInfo.sin_addr.s_addr = bindAddress->ipv4;
|
||||
err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo));
|
||||
} else {
|
||||
struct sockaddr_in6 bindInfo;
|
||||
memset(&bindInfo, 0, sizeof(bindInfo));
|
||||
bindInfo.sin6_family = AF_INET6;
|
||||
bindInfo.sin6_port = htons(port);
|
||||
memcpy(bindInfo.sin6_addr.s6_addr, bindAddress->ipv6, sizeof(bindInfo.sin6_addr.s6_addr));
|
||||
err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo));
|
||||
|
||||
}
|
||||
if (err) {
|
||||
close(sock);
|
||||
return -1;
|
||||
|
@ -63,18 +92,35 @@ static inline Socket SocketOpenTCP(int port, uint32_t bindAddress) {
|
|||
return sock;
|
||||
}
|
||||
|
||||
static inline Socket SocketConnectTCP(int port, uint32_t destinationAddress) {
|
||||
static inline Socket SocketConnectTCP(int port, const struct Address* destinationAddress) {
|
||||
Socket sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (SOCKET_FAILED(sock)) {
|
||||
return sock;
|
||||
}
|
||||
|
||||
struct sockaddr_in bindInfo;
|
||||
memset(&bindInfo, 0, sizeof(bindInfo));
|
||||
bindInfo.sin_family = AF_INET;
|
||||
bindInfo.sin_port = htons(port);
|
||||
bindInfo.sin_addr.s_addr = htonl(destinationAddress);
|
||||
int err = connect(sock, (const struct sockaddr*) &bindInfo, sizeof(struct sockaddr_in));
|
||||
int err;
|
||||
if (!destinationAddress) {
|
||||
struct sockaddr_in bindInfo;
|
||||
memset(&bindInfo, 0, sizeof(bindInfo));
|
||||
bindInfo.sin_family = AF_INET;
|
||||
bindInfo.sin_port = htons(port);
|
||||
err = connect(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo));
|
||||
} else if (destinationAddress->version == IPV4) {
|
||||
struct sockaddr_in bindInfo;
|
||||
memset(&bindInfo, 0, sizeof(bindInfo));
|
||||
bindInfo.sin_family = AF_INET;
|
||||
bindInfo.sin_port = htons(port);
|
||||
bindInfo.sin_addr.s_addr = destinationAddress->ipv4;
|
||||
err = connect(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo));
|
||||
} else {
|
||||
struct sockaddr_in6 bindInfo;
|
||||
memset(&bindInfo, 0, sizeof(bindInfo));
|
||||
bindInfo.sin6_family = AF_INET6;
|
||||
bindInfo.sin6_port = htons(port);
|
||||
memcpy(bindInfo.sin6_addr.s6_addr, destinationAddress->ipv6, sizeof(bindInfo.sin6_addr.s6_addr));
|
||||
err = connect(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo));
|
||||
}
|
||||
|
||||
if (err) {
|
||||
close(sock);
|
||||
return -1;
|
||||
|
@ -86,8 +132,25 @@ static inline Socket SocketListen(Socket socket, int queueLength) {
|
|||
return listen(socket, queueLength);
|
||||
}
|
||||
|
||||
static inline Socket SocketAccept(Socket socket, struct sockaddr* restrict address, socklen_t* restrict addressLength) {
|
||||
return accept(socket, address, addressLength);
|
||||
static inline Socket SocketAccept(Socket socket, struct Address* address) {
|
||||
if (!address) {
|
||||
return accept(socket, 0, 0);
|
||||
}
|
||||
if (address->version == IPV4) {
|
||||
struct sockaddr_in addrInfo;
|
||||
memset(&addrInfo, 0, sizeof(addrInfo));
|
||||
addrInfo.sin_family = AF_INET;
|
||||
addrInfo.sin_addr.s_addr = address->ipv4;
|
||||
socklen_t len = sizeof(addrInfo);
|
||||
return accept(socket, (struct sockaddr*) &addrInfo, &len);
|
||||
} else {
|
||||
struct sockaddr_in6 addrInfo;
|
||||
memset(&addrInfo, 0, sizeof(addrInfo));
|
||||
addrInfo.sin6_family = AF_INET6;
|
||||
memcpy(addrInfo.sin6_addr.s6_addr, address->ipv6, sizeof(addrInfo.sin6_addr.s6_addr));
|
||||
socklen_t len = sizeof(addrInfo);
|
||||
return accept(socket, (struct sockaddr*) &addrInfo, &len);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int SocketClose(Socket socket) {
|
||||
|
|
Loading…
Reference in New Issue