Start IPv6 - Lord help me
This commit is contained in:
3
TODO.txt
3
TODO.txt
@@ -14,6 +14,9 @@ Check if Block FullVerify is actually verifying fully (not missing any condition
|
|||||||
|
|
||||||
A loophole in the reorg penalty system could potentially exist where someone broadcasts blocks one-at-a-time. Determine a solution to this.
|
A loophole in the reorg penalty system could potentially exist where someone broadcasts blocks one-at-a-time. Determine a solution to this.
|
||||||
|
|
||||||
|
IPv6 support for the P2P node. Come on guys, it's 2026. RFC 2460 was in 1998. It's about time.
|
||||||
|
Like if someone is behind NAT, fine, workable. CGNAT? Lmao good luck.
|
||||||
|
|
||||||
TO TEST:
|
TO TEST:
|
||||||
Implement Horizen's "Reorg Penalty" system to make it harder for the young chain to be attacked by a powerful miner.
|
Implement Horizen's "Reorg Penalty" system to make it harder for the young chain to be attacked by a powerful miner.
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,17 @@ typedef enum {
|
|||||||
typedef struct tcp_connection_t tcp_connection_t;
|
typedef struct tcp_connection_t tcp_connection_t;
|
||||||
|
|
||||||
struct tcp_connection_t {
|
struct tcp_connection_t {
|
||||||
|
// TODO: We should make it so only ONE of this needs to be available.
|
||||||
|
// Because of my temporary "I just need something that works" horseshit that I'm about to write, you'll need IPv4 and IPv6 is optional.
|
||||||
|
// Note to self: Don't pull an IETF and some "NAT exists, we're fine" bullshit, because if we end up with our eqvivalent of Teredo or CGNAT, I'm gonna be fucking pissed.
|
||||||
|
// And no, the solution isn't "eh, just bind to 0.0.0.0 and ignore it", because if we do that, we'll inevitably end up with a host that only has IPv6 and then we'll be fucked.
|
||||||
|
// Honestly, I'm proud of whoever runs IPv6-only. Brave soul.
|
||||||
int sockFd;
|
int sockFd;
|
||||||
struct sockaddr_in peerAddr;
|
struct sockaddr_in peerAddr;
|
||||||
|
#ifdef USE_IPV6
|
||||||
|
int sockFd6; // For IPv6 support
|
||||||
|
struct sockaddr_in6 peerAddr6; // For IPv6 support
|
||||||
|
#endif
|
||||||
uint32_t connectionId;
|
uint32_t connectionId;
|
||||||
tcp_connection_role_t role;
|
tcp_connection_role_t role;
|
||||||
|
|
||||||
@@ -54,6 +63,7 @@ int TcpConnection_SetDataBuffer(tcp_connection_t* conn, const unsigned char* dat
|
|||||||
void TcpConnection_ResetFramingState(tcp_connection_t* conn);
|
void TcpConnection_ResetFramingState(tcp_connection_t* conn);
|
||||||
int TcpConnection_FeedFramedData(tcp_connection_t* conn, const unsigned char* input, size_t inputLen);
|
int TcpConnection_FeedFramedData(tcp_connection_t* conn, const unsigned char* input, size_t inputLen);
|
||||||
|
|
||||||
|
// This just takes a socket ID, so it's independent from the v4/v6 stuff. It works for both.
|
||||||
int TcpConnection_SendRaw(int sockFd, const void* data, size_t len);
|
int TcpConnection_SendRaw(int sockFd, const void* data, size_t len);
|
||||||
int TcpConnection_SendFramed(tcp_connection_t* conn, const void* payload, size_t payloadLen);
|
int TcpConnection_SendFramed(tcp_connection_t* conn, const void* payload, size_t payloadLen);
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,12 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
int sockFd;
|
int sockFd;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
|
#ifdef USE_IPV6
|
||||||
|
int sockFd6; // IPv6 support
|
||||||
|
struct sockaddr_in6 addr6; // IPv6 support
|
||||||
|
#endif
|
||||||
int opt;
|
int opt;
|
||||||
|
int opt6; // IPv6 support
|
||||||
int isRunning;
|
int isRunning;
|
||||||
void* owner;
|
void* owner;
|
||||||
|
|
||||||
|
|||||||
@@ -214,10 +214,26 @@ int TcpConnection_SendFramed(tcp_connection_t* conn, const void* payload, size_t
|
|||||||
|
|
||||||
pthread_mutex_lock(&conn->sendLock);
|
pthread_mutex_lock(&conn->sendLock);
|
||||||
|
|
||||||
|
#ifdef USE_IPV6
|
||||||
|
int sock;
|
||||||
|
if (conn->sockFd6 >= 0) {
|
||||||
|
// IPv6 is available, attempt to send on it. If it fails, we'll fall back to IPv4 if available.
|
||||||
|
sock = conn->sockFd6;
|
||||||
|
} else {
|
||||||
|
// IPv4 fallback
|
||||||
|
sock = conn->sockFd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rc = TcpConnection_SendRaw(sock, &beLen, sizeof(beLen));
|
||||||
|
if (rc == 0 && payloadLen > 0) {
|
||||||
|
rc = TcpConnection_SendRaw(sock, payload, payloadLen);
|
||||||
|
}
|
||||||
|
#else
|
||||||
int rc = TcpConnection_SendRaw(conn->sockFd, &beLen, sizeof(beLen));
|
int rc = TcpConnection_SendRaw(conn->sockFd, &beLen, sizeof(beLen));
|
||||||
if (rc == 0 && payloadLen > 0) {
|
if (rc == 0 && payloadLen > 0) {
|
||||||
rc = TcpConnection_SendRaw(conn->sockFd, payload, payloadLen);
|
rc = TcpConnection_SendRaw(conn->sockFd, payload, payloadLen);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
pthread_mutex_unlock(&conn->sendLock);
|
pthread_mutex_unlock(&conn->sendLock);
|
||||||
|
|
||||||
@@ -235,6 +251,11 @@ void TcpConnection_RequestClose(tcp_connection_t* conn) {
|
|||||||
if (conn->sockFd >= 0) {
|
if (conn->sockFd >= 0) {
|
||||||
shutdown(conn->sockFd, SHUT_RDWR);
|
shutdown(conn->sockFd, SHUT_RDWR);
|
||||||
}
|
}
|
||||||
|
#ifdef USE_IPV6
|
||||||
|
if (conn->sockFd6 >= 0) {
|
||||||
|
shutdown(conn->sockFd6, SHUT_RDWR);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&conn->stateLock);
|
pthread_mutex_unlock(&conn->stateLock);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,6 +172,9 @@ tcp_server_t* TcpServer_Create() {
|
|||||||
svr->isRunning = 0;
|
svr->isRunning = 0;
|
||||||
svr->maxClients = 0;
|
svr->maxClients = 0;
|
||||||
svr->clientsArrPtr = NULL;
|
svr->clientsArrPtr = NULL;
|
||||||
|
#ifdef USE_IPV6
|
||||||
|
svr->sockFd6 = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (pthread_mutex_init(&svr->clientsMutex, NULL) != 0) {
|
if (pthread_mutex_init(&svr->clientsMutex, NULL) != 0) {
|
||||||
free(svr);
|
free(svr);
|
||||||
@@ -217,6 +220,28 @@ void TcpServer_Init(tcp_server_t* ptr, unsigned short port, const char* addr) {
|
|||||||
close(ptr->sockFd);
|
close(ptr->sockFd);
|
||||||
ptr->sockFd = -1;
|
ptr->sockFd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_IPV6
|
||||||
|
// IPv6 support
|
||||||
|
ptr->sockFd6 = socket(AF_INET6, SOCK_STREAM, 0);
|
||||||
|
if (ptr->sockFd6 >= 0) {
|
||||||
|
ptr->opt6 = 1;
|
||||||
|
setsockopt(ptr->sockFd6, SOL_SOCKET, SO_REUSEADDR, &ptr->opt6, sizeof(int));
|
||||||
|
memset(&ptr->addr6, 0, sizeof(ptr->addr6));
|
||||||
|
ptr->addr6.sin6_family = AF_INET6;
|
||||||
|
ptr->addr6.sin6_port = htons(port);
|
||||||
|
inet_pton(AF_INET6, addr, &ptr->addr6.sin6_addr);
|
||||||
|
if (bind(ptr->sockFd6, (struct sockaddr*)&ptr->addr6, sizeof(ptr->addr6)) < 0) {
|
||||||
|
close(ptr->sockFd6);
|
||||||
|
ptr->sockFd6 = -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ptr->sockFd6 = -1; // IPv6 is optional, so if it isn't available, we just set it to -1
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// Safety for my future "I forgot the ifdef guard" self
|
||||||
|
ptr->sockFd6 = -1; // IPv6 not supported in this build
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcpServer_Start(tcp_server_t* ptr, int maxcons) {
|
void TcpServer_Start(tcp_server_t* ptr, int maxcons) {
|
||||||
@@ -228,6 +253,15 @@ void TcpServer_Start(tcp_server_t* ptr, int maxcons) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_IPV6
|
||||||
|
if (ptr->sockFd6 >= 0) {
|
||||||
|
if (listen(ptr->sockFd6, maxcons) < 0) {
|
||||||
|
close(ptr->sockFd6);
|
||||||
|
ptr->sockFd6 = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
pthread_mutex_lock(&ptr->clientsMutex);
|
pthread_mutex_lock(&ptr->clientsMutex);
|
||||||
|
|
||||||
ptr->maxClients = (size_t)maxcons;
|
ptr->maxClients = (size_t)maxcons;
|
||||||
@@ -268,6 +302,14 @@ void TcpServer_Stop(tcp_server_t* ptr) {
|
|||||||
ptr->sockFd = -1;
|
ptr->sockFd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_IPV6
|
||||||
|
if (ptr->sockFd6 >= 0) {
|
||||||
|
shutdown(ptr->sockFd6, SHUT_RDWR);
|
||||||
|
close(ptr->sockFd6);
|
||||||
|
ptr->sockFd6 = -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ptr->svrThread != 0 && !pthread_equal(ptr->svrThread, pthread_self())) {
|
if (ptr->svrThread != 0 && !pthread_equal(ptr->svrThread, pthread_self())) {
|
||||||
pthread_join(ptr->svrThread, NULL);
|
pthread_join(ptr->svrThread, NULL);
|
||||||
}
|
}
|
||||||
@@ -339,6 +381,12 @@ void TcpServer_KillClient(tcp_server_t* ptr, tcp_connection_t* cli) {
|
|||||||
so_linger.l_linger = 0;
|
so_linger.l_linger = 0;
|
||||||
setsockopt(cli->sockFd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger));
|
setsockopt(cli->sockFd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger));
|
||||||
|
|
||||||
|
#ifdef USE_IPV6
|
||||||
|
if (cli->sockFd6 >= 0) {
|
||||||
|
setsockopt(cli->sockFd6, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
TcpServer_Disconnect(ptr, cli);
|
TcpServer_Disconnect(ptr, cli);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user