Start doing TCP networking
This commit is contained in:
10
TODO.txt
10
TODO.txt
@@ -1,11 +1,15 @@
|
|||||||
Move to a GPU algo. RandomX is a good candidate, but CPU mining is not that attractive to anyone but people who actually want to support the project.
|
TODO:
|
||||||
It won't incentivize people who want to profit, which let's be fair, is the majority of miners.
|
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
Make transactions private. A bit more work, but it's a challenge worth taking on.
|
Make transactions private. A bit more work, but it's a challenge worth taking on.
|
||||||
I want to make an "optional privacy" system, where the TX can be public or private. Of course private TXs need more bytes, so the fees (although low) will be higher for them.
|
I want to make an "optional privacy" system, where the TX can be public or private. Of course private TXs need more bytes, so the fees (although low) will be higher for them.
|
||||||
I need to figure out a way to make the privacy work without a UTXO system, and instead, with a "Balance Sheet" approach.
|
I need to figure out a way to make the privacy work without a UTXO system, and instead, with a "Balance Sheet" approach.
|
||||||
|
|
||||||
|
Move the Networking Code to support win32 as well, as I'm just doing POSIX right now
|
||||||
|
|
||||||
|
DONE:
|
||||||
I want to move away from the Monero emission. I want to do something a bit radical for cryptocurrency, but I feel like it's necessary to make it more like money:
|
I want to move away from the Monero emission. I want to do something a bit radical for cryptocurrency, but I feel like it's necessary to make it more like money:
|
||||||
a constant inflation rate of 1.5% per year. It's lower than fiat (USD is ~2.8% per year), and it additionally doesn't fluctuate during crisis. It's constant.
|
a constant inflation rate of 1.5% per year. It's lower than fiat (USD is ~2.8% per year), and it additionally doesn't fluctuate during crisis. It's constant.
|
||||||
|
|
||||||
|
Move to a GPU algo. RandomX is a good candidate, but CPU mining is not that attractive to anyone but people who actually want to support the project.
|
||||||
|
Sadly, CPUs won't incentivize people who want to profit, which let's be fair, is the majority of miners.
|
||||||
@@ -7,6 +7,11 @@
|
|||||||
#include <block/chain.h>
|
#include <block/chain.h>
|
||||||
#include <block/block.h>
|
#include <block/block.h>
|
||||||
|
|
||||||
|
// Nets
|
||||||
|
#define MAX_CONS 32 // Some baseline for now
|
||||||
|
#define LISTEN_PORT 9393
|
||||||
|
|
||||||
|
// Economics
|
||||||
#define DECIMALS 1000000000000ULL
|
#define DECIMALS 1000000000000ULL
|
||||||
#define DIFFICULTY_ADJUSTMENT_INTERVAL 3840 // Every 3840 blocks (roughly every 4 days with a 90 second block time)
|
#define DIFFICULTY_ADJUSTMENT_INTERVAL 3840 // Every 3840 blocks (roughly every 4 days with a 90 second block time)
|
||||||
// Max adjustment per is x2. So if blocks are coming in too fast, the difficulty will at most double every 24 hours, and vice versa if they're coming in too slow.
|
// Max adjustment per is x2. So if blocks are coming in too fast, the difficulty will at most double every 24 hours, and vice versa if they're coming in too slow.
|
||||||
|
|||||||
29
include/nets/net_node.h
Normal file
29
include/nets/net_node.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef NET_NODE_H
|
||||||
|
#define NET_NODE_H
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
// POSIX
|
||||||
|
#include <tcpd/tcpconnection.h>
|
||||||
|
#include <tcpd/tcpserver.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <dynarr.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <constants.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
tcp_server_t* server;
|
||||||
|
// TODO: Add the list of clients as well
|
||||||
|
} net_node_t;
|
||||||
|
|
||||||
|
net_node_t* Node_Create();
|
||||||
|
void Node_Destroy(net_node_t* node);
|
||||||
|
|
||||||
|
// Callback logic
|
||||||
|
void Node_Server_OnConnect(tcp_connection_t* client);
|
||||||
|
void Node_Server_OnData(tcp_connection_t* client);
|
||||||
|
void Node_Server_OnDisconnect(tcp_connection_t* client);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -11,19 +11,19 @@
|
|||||||
|
|
||||||
#define MTU 1500
|
#define MTU 1500
|
||||||
|
|
||||||
struct TcpClient {
|
struct tcp_connection_t {
|
||||||
int clientFd;
|
int clientFd;
|
||||||
struct sockaddr_in clientAddr;
|
struct sockaddr_in clientAddr;
|
||||||
uint32_t clientId;
|
uint32_t clientId;
|
||||||
|
|
||||||
unsigned char dataBuf[MTU];
|
unsigned char dataBuf[MTU];
|
||||||
ssize_t dataBufLen;
|
ssize_t dataBufLen;
|
||||||
void (*on_data)(struct TcpClient* client);
|
void (*on_data)(struct tcp_connection_t* client);
|
||||||
void (*on_disconnect)(struct TcpClient* client);
|
void (*on_disconnect)(struct tcp_connection_t* client);
|
||||||
|
|
||||||
pthread_t clientThread;
|
pthread_t clientThread;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct TcpClient TcpClient;
|
typedef struct tcp_connection_t tcp_connection_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <tcpd/tcpclient.h>
|
#include <tcpd/tcpconnection.h>
|
||||||
#include <numgen.h>
|
#include <numgen.h>
|
||||||
#include <dynarr.h>
|
#include <dynarr.h>
|
||||||
|
|
||||||
@@ -20,37 +20,37 @@ typedef struct {
|
|||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
// Called before the client thread runs
|
// Called before the client thread runs
|
||||||
void (*on_connect)(TcpClient* client);
|
void (*on_connect)(tcp_connection_t* client);
|
||||||
// Called when data is received
|
// Called when data is received
|
||||||
void (*on_data)(TcpClient* client);
|
void (*on_data)(tcp_connection_t* client);
|
||||||
// Called before the socket and client thread are killed; Do NOT free client manually
|
// Called before the socket and client thread are killed; Do NOT free client manually
|
||||||
void (*on_disconnect)(TcpClient* client);
|
void (*on_disconnect)(tcp_connection_t* client);
|
||||||
|
|
||||||
// max clients
|
// max clients
|
||||||
size_t clients;
|
size_t clients;
|
||||||
TcpClient** clientsArrPtr;
|
tcp_connection_t** clientsArrPtr;
|
||||||
|
|
||||||
pthread_t svrThread;
|
pthread_t svrThread;
|
||||||
} TcpServer;
|
} tcp_server_t;
|
||||||
|
|
||||||
struct tcpclient_thread_args {
|
struct tcpclient_thread_args {
|
||||||
TcpClient* clientPtr;
|
tcp_connection_t* clientPtr;
|
||||||
TcpServer* serverPtr;
|
tcp_server_t* serverPtr;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct tcpclient_thread_args tcpclient_thread_args;
|
typedef struct tcpclient_thread_args tcpclient_thread_args;
|
||||||
|
|
||||||
TcpServer* TcpServer_Create();
|
tcp_server_t* TcpServer_Create();
|
||||||
void TcpServer_Destroy(TcpServer* ptr);
|
void TcpServer_Destroy(tcp_server_t* ptr);
|
||||||
|
|
||||||
void TcpServer_Init(TcpServer* ptr, unsigned short port, const char* addr);
|
void TcpServer_Init(tcp_server_t* ptr, unsigned short port, const char* addr);
|
||||||
void TcpServer_Start(TcpServer* ptr, int maxcons);
|
void TcpServer_Start(tcp_server_t* ptr, int maxcons);
|
||||||
void TcpServer_Stop(TcpServer* ptr);
|
void TcpServer_Stop(tcp_server_t* ptr);
|
||||||
void TcpServer_Send(TcpServer* ptr, TcpClient* cli, void* data, size_t len);
|
void TcpServer_Send(tcp_server_t* ptr, tcp_connection_t* cli, void* data, size_t len);
|
||||||
void Generic_SendSocket(int sock, void* data, size_t len);
|
void Generic_SendSocket(int sock, void* data, size_t len);
|
||||||
void TcpServer_Disconnect(TcpServer* ptr, TcpClient* cli);
|
void TcpServer_Disconnect(tcp_server_t* ptr, tcp_connection_t* cli);
|
||||||
void TcpServer_KillClient(TcpServer* ptr, TcpClient* cli);
|
void TcpServer_KillClient(tcp_server_t* ptr, tcp_connection_t* cli);
|
||||||
|
|
||||||
size_t Generic_FindClientInArrayByPtr(TcpClient** arr, TcpClient* ptr, size_t len);
|
size_t Generic_FindClientInArrayByPtr(tcp_connection_t** arr, tcp_connection_t* ptr, size_t len);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -455,15 +455,43 @@ bool Chain_LoadFromFile(blockchain_t* chain, const char* dirpath, uint256_t* out
|
|||||||
FILE* chainFile = fopen(chainPath, "rb+");
|
FILE* chainFile = fopen(chainPath, "rb+");
|
||||||
FILE* tableFile = fopen(tablePath, "rb+");
|
FILE* tableFile = fopen(tablePath, "rb+");
|
||||||
if (!metaFile || !chainFile || !tableFile) {
|
if (!metaFile || !chainFile || !tableFile) {
|
||||||
|
if (metaFile) fclose(metaFile);
|
||||||
|
if (chainFile) fclose(chainFile);
|
||||||
|
if (tableFile) fclose(tableFile);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t savedSize = 0;
|
size_t savedSize = 0;
|
||||||
if (fread(&savedSize, sizeof(size_t), 1, metaFile) != 1) return false;
|
if (fread(&savedSize, sizeof(size_t), 1, metaFile) != 1) {
|
||||||
if (fread(outLastSavedHash, sizeof(uint8_t), 32, metaFile) != 32) return false;
|
fclose(metaFile);
|
||||||
if (fread(outCurrentSupply, sizeof(uint256_t), 1, metaFile) != 1) return false;
|
fclose(chainFile);
|
||||||
if (fread(outDifficultyTarget, sizeof(uint32_t), 1, metaFile) != 1) return false;
|
fclose(tableFile);
|
||||||
if (fread(outCurrentReward, sizeof(uint64_t), 1, metaFile) != 1) return false;
|
return false;
|
||||||
|
}
|
||||||
|
if (fread(outLastSavedHash, sizeof(uint8_t), 32, metaFile) != 32) {
|
||||||
|
fclose(metaFile);
|
||||||
|
fclose(chainFile);
|
||||||
|
fclose(tableFile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (fread(outCurrentSupply, sizeof(uint256_t), 1, metaFile) != 1) {
|
||||||
|
fclose(metaFile);
|
||||||
|
fclose(chainFile);
|
||||||
|
fclose(tableFile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (fread(outDifficultyTarget, sizeof(uint32_t), 1, metaFile) != 1) {
|
||||||
|
fclose(metaFile);
|
||||||
|
fclose(chainFile);
|
||||||
|
fclose(tableFile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (fread(outCurrentReward, sizeof(uint64_t), 1, metaFile) != 1) {
|
||||||
|
fclose(metaFile);
|
||||||
|
fclose(chainFile);
|
||||||
|
fclose(tableFile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
fclose(metaFile);
|
fclose(metaFile);
|
||||||
|
|
||||||
// TODO: Might add a flag to allow reading from a point onward, but just rewrite for now
|
// TODO: Might add a flag to allow reading from a point onward, but just rewrite for now
|
||||||
@@ -481,6 +509,8 @@ bool Chain_LoadFromFile(blockchain_t* chain, const char* dirpath, uint256_t* out
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (loc.blockNumber != i) {
|
if (loc.blockNumber != i) {
|
||||||
|
fclose(chainFile);
|
||||||
|
fclose(tableFile);
|
||||||
return false; // Mismatch
|
return false; // Mismatch
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -491,24 +521,30 @@ bool Chain_LoadFromFile(blockchain_t* chain, const char* dirpath, uint256_t* out
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
block_t* blk = Block_Create();
|
// Header-only load path: do not allocate per-block transaction arrays.
|
||||||
|
block_t* blk = (block_t*)calloc(1, sizeof(block_t));
|
||||||
if (!blk) {
|
if (!blk) {
|
||||||
|
fclose(chainFile);
|
||||||
|
fclose(tableFile);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read block header and transactions
|
// Read block header and transactions
|
||||||
if (fread(&blk->header, sizeof(block_header_t), 1, chainFile) != 1) {
|
if (fread(&blk->header, sizeof(block_header_t), 1, chainFile) != 1) {
|
||||||
fclose(chainFile);
|
fclose(chainFile);
|
||||||
Block_Destroy(blk);
|
fclose(tableFile);
|
||||||
|
free(blk);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t txSize = 0;
|
size_t txSize = 0;
|
||||||
if (fread(&txSize, sizeof(size_t), 1, chainFile) != 1) {
|
if (fread(&txSize, sizeof(size_t), 1, chainFile) != 1) {
|
||||||
fclose(chainFile);
|
fclose(chainFile);
|
||||||
Block_Destroy(blk);
|
fclose(tableFile);
|
||||||
|
free(blk);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
(void)txSize;
|
||||||
|
|
||||||
/*for (size_t j = 0; j < txSize; j++) {
|
/*for (size_t j = 0; j < txSize; j++) {
|
||||||
signed_transaction_t tx;
|
signed_transaction_t tx;
|
||||||
@@ -526,7 +562,7 @@ bool Chain_LoadFromFile(blockchain_t* chain, const char* dirpath, uint256_t* out
|
|||||||
if (!DynArr_push_back(chain->blocks, blk)) {
|
if (!DynArr_push_back(chain->blocks, blk)) {
|
||||||
fclose(chainFile);
|
fclose(chainFile);
|
||||||
fclose(tableFile);
|
fclose(tableFile);
|
||||||
Block_Destroy(blk);
|
free(blk);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
chain->size++;
|
chain->size++;
|
||||||
@@ -537,6 +573,8 @@ bool Chain_LoadFromFile(blockchain_t* chain, const char* dirpath, uint256_t* out
|
|||||||
}
|
}
|
||||||
|
|
||||||
chain->size = savedSize;
|
chain->size = savedSize;
|
||||||
|
fclose(chainFile);
|
||||||
|
fclose(tableFile);
|
||||||
|
|
||||||
// After read, you SHOULD verify chain validity. We're not doing it here since returning false is a bit unclear if the read failed or if the chain is invalid.
|
// After read, you SHOULD verify chain validity. We're not doing it here since returning false is a bit unclear if the read failed or if the chain is invalid.
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ void Transaction_Sign(signed_transaction_t* tx, const uint8_t* privateKey) {
|
|||||||
Transaction_CalculateHash(tx, txHash);
|
Transaction_CalculateHash(tx, txHash);
|
||||||
Crypto_SignData(
|
Crypto_SignData(
|
||||||
txHash,
|
txHash,
|
||||||
sizeof(transaction_t),
|
32,
|
||||||
privateKey,
|
privateKey,
|
||||||
tx->signature.signature
|
tx->signature.signature
|
||||||
);
|
);
|
||||||
|
|||||||
11
src/main.c
11
src/main.c
@@ -15,6 +15,8 @@
|
|||||||
#include <autolykos2/autolykos2.h>
|
#include <autolykos2/autolykos2.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <nets/net_node.h>
|
||||||
|
|
||||||
#ifndef CHAIN_DATA_DIR
|
#ifndef CHAIN_DATA_DIR
|
||||||
#define CHAIN_DATA_DIR "chain_data"
|
#define CHAIN_DATA_DIR "chain_data"
|
||||||
#endif
|
#endif
|
||||||
@@ -169,6 +171,12 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
uint256_t currentSupply = uint256_from_u64(0);
|
uint256_t currentSupply = uint256_from_u64(0);
|
||||||
|
|
||||||
|
net_node_t* node = Node_Create();
|
||||||
|
if (!node) {
|
||||||
|
BalanceSheet_Destroy();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
blockchain_t* chain = Chain_Create();
|
blockchain_t* chain = Chain_Create();
|
||||||
if (!chain) {
|
if (!chain) {
|
||||||
fprintf(stderr, "failed to create chain\n");
|
fprintf(stderr, "failed to create chain\n");
|
||||||
@@ -479,5 +487,8 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
Chain_Destroy(chain);
|
Chain_Destroy(chain);
|
||||||
Block_ShutdownPowContext();
|
Block_ShutdownPowContext();
|
||||||
|
|
||||||
|
Node_Destroy(node);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
43
src/nets/net_node.c
Normal file
43
src/nets/net_node.c
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#include <nets/net_node.h>
|
||||||
|
|
||||||
|
net_node_t* Node_Create() {
|
||||||
|
net_node_t* node = (net_node_t*)malloc(sizeof(net_node_t));
|
||||||
|
if (!node) { return NULL; }
|
||||||
|
|
||||||
|
node->server = TcpServer_Create();
|
||||||
|
if (!node->server) {
|
||||||
|
free(node);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
TcpServer_Init(node->server, LISTEN_PORT, "0.0.0.0"); // All interfaces
|
||||||
|
|
||||||
|
// Register callbacks before starting the server
|
||||||
|
node->server->on_connect = Node_Server_OnConnect;
|
||||||
|
node->server->on_data = Node_Server_OnData;
|
||||||
|
node->server->on_disconnect = Node_Server_OnDisconnect;
|
||||||
|
|
||||||
|
TcpServer_Start(node->server, MAX_CONS);
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node_Destroy(net_node_t* node) {
|
||||||
|
if (!node || !node->server) { return; }
|
||||||
|
TcpServer_Stop(node->server);
|
||||||
|
TcpServer_Destroy(node->server);
|
||||||
|
|
||||||
|
free(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node_Server_OnConnect(tcp_connection_t* client) {
|
||||||
|
printf("A node connected!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node_Server_OnData(tcp_connection_t* client) {
|
||||||
|
printf("A node sent data!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node_Server_OnDisconnect(tcp_connection_t* client) {
|
||||||
|
printf("A node disconnected!\n");
|
||||||
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
|
#ifndef _WIN32
|
||||||
|
|
||||||
#include <tcpd/tcpserver.h>
|
#include <tcpd/tcpserver.h>
|
||||||
|
|
||||||
TcpServer* TcpServer_Create() {
|
tcp_server_t* TcpServer_Create() {
|
||||||
TcpServer* svr = (TcpServer*)malloc(sizeof(TcpServer));
|
tcp_server_t* svr = (tcp_server_t*)malloc(sizeof(tcp_server_t));
|
||||||
|
|
||||||
if (!svr) {
|
if (!svr) {
|
||||||
perror("tcpserver - creation failure");
|
perror("tcpserver - creation failure");
|
||||||
@@ -20,7 +22,7 @@ TcpServer* TcpServer_Create() {
|
|||||||
return svr;
|
return svr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcpServer_Destroy(TcpServer* ptr) {
|
void TcpServer_Destroy(tcp_server_t* ptr) {
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
if (ptr->clientsArrPtr) {
|
if (ptr->clientsArrPtr) {
|
||||||
for (size_t i = 0; i < ptr->clients; i++) {
|
for (size_t i = 0; i < ptr->clients; i++) {
|
||||||
@@ -37,7 +39,7 @@ void TcpServer_Destroy(TcpServer* ptr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcpServer_Init(TcpServer* ptr, unsigned short port, const char* addr) {
|
void TcpServer_Init(tcp_server_t* ptr, unsigned short port, const char* addr) {
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
// Create socket
|
// Create socket
|
||||||
ptr->sockFd = socket(AF_INET, SOCK_STREAM, 0);
|
ptr->sockFd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
@@ -74,8 +76,8 @@ void* TcpServer_clientthreadprocess(void* ptr) {
|
|||||||
|
|
||||||
tcpclient_thread_args* args = (tcpclient_thread_args*)ptr;
|
tcpclient_thread_args* args = (tcpclient_thread_args*)ptr;
|
||||||
|
|
||||||
TcpClient* cli = args->clientPtr;
|
tcp_connection_t* cli = args->clientPtr;
|
||||||
TcpServer* svr = args->serverPtr;
|
tcp_server_t* svr = args->serverPtr;
|
||||||
|
|
||||||
if (args) {
|
if (args) {
|
||||||
free(args);
|
free(args);
|
||||||
@@ -97,13 +99,15 @@ void* TcpServer_clientthreadprocess(void* ptr) {
|
|||||||
pthread_testcancel(); // Check for thread death
|
pthread_testcancel(); // Check for thread death
|
||||||
}
|
}
|
||||||
|
|
||||||
cli->on_disconnect(cli);
|
if (cli->on_disconnect) {
|
||||||
|
cli->on_disconnect(cli);
|
||||||
|
}
|
||||||
|
|
||||||
// Close on exit
|
// Close on exit
|
||||||
close(cli->clientFd);
|
close(cli->clientFd);
|
||||||
|
|
||||||
// Destroy
|
// Destroy
|
||||||
TcpClient** arr = svr->clientsArrPtr;
|
tcp_connection_t** arr = svr->clientsArrPtr;
|
||||||
size_t idx = Generic_FindClientInArrayByPtr(arr, cli, svr->clients);
|
size_t idx = Generic_FindClientInArrayByPtr(arr, cli, svr->clients);
|
||||||
if (idx != SIZE_MAX) {
|
if (idx != SIZE_MAX) {
|
||||||
if (arr[idx]) {
|
if (arr[idx]) {
|
||||||
@@ -126,9 +130,9 @@ void* TcpServer_threadprocess(void* ptr) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
TcpServer* svr = (TcpServer*)ptr;
|
tcp_server_t* svr = (tcp_server_t*)ptr;
|
||||||
while (1) {
|
while (1) {
|
||||||
TcpClient tempclient;
|
tcp_connection_t tempclient;
|
||||||
socklen_t clientsize = sizeof(tempclient.clientAddr);
|
socklen_t clientsize = sizeof(tempclient.clientAddr);
|
||||||
int client = accept(svr->sockFd, (struct sockaddr*)&tempclient.clientAddr, &clientsize);
|
int client = accept(svr->sockFd, (struct sockaddr*)&tempclient.clientAddr, &clientsize);
|
||||||
if (client >= 0) {
|
if (client >= 0) {
|
||||||
@@ -137,7 +141,7 @@ void* TcpServer_threadprocess(void* ptr) {
|
|||||||
tempclient.on_disconnect = svr->on_disconnect;
|
tempclient.on_disconnect = svr->on_disconnect;
|
||||||
|
|
||||||
// I'm lazy, so I'm just copying the data for now (I should probably make this a better way)
|
// I'm lazy, so I'm just copying the data for now (I should probably make this a better way)
|
||||||
TcpClient* heapCli = (TcpClient*)malloc(sizeof(TcpClient));
|
tcp_connection_t* heapCli = (tcp_connection_t*)malloc(sizeof(tcp_connection_t));
|
||||||
if (!heapCli) {
|
if (!heapCli) {
|
||||||
perror("tcpserver - client failed to allocate");
|
perror("tcpserver - client failed to allocate");
|
||||||
exit(EXIT_FAILURE); // Wtf just happened???
|
exit(EXIT_FAILURE); // Wtf just happened???
|
||||||
@@ -193,7 +197,7 @@ void* TcpServer_threadprocess(void* ptr) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcpServer_Start(TcpServer* ptr, int maxcons) {
|
void TcpServer_Start(tcp_server_t* ptr, int maxcons) {
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
if (listen(ptr->sockFd, maxcons) < 0) {
|
if (listen(ptr->sockFd, maxcons) < 0) {
|
||||||
perror("tcpserver - listen");
|
perror("tcpserver - listen");
|
||||||
@@ -202,7 +206,7 @@ void TcpServer_Start(TcpServer* ptr, int maxcons) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ptr->clients = maxcons;
|
ptr->clients = maxcons;
|
||||||
ptr->clientsArrPtr = (TcpClient**)malloc(sizeof(TcpClient*) * maxcons);
|
ptr->clientsArrPtr = (tcp_connection_t**)malloc(sizeof(tcp_connection_t*) * maxcons);
|
||||||
|
|
||||||
if (!ptr->clientsArrPtr) {
|
if (!ptr->clientsArrPtr) {
|
||||||
perror("tcpserver - allocation of client space fatally errored");
|
perror("tcpserver - allocation of client space fatally errored");
|
||||||
@@ -219,7 +223,7 @@ void TcpServer_Start(TcpServer* ptr, int maxcons) {
|
|||||||
pthread_create(&ptr->svrThread, NULL, TcpServer_threadprocess, ptr);
|
pthread_create(&ptr->svrThread, NULL, TcpServer_threadprocess, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcpServer_Stop(TcpServer* ptr) {
|
void TcpServer_Stop(tcp_server_t* ptr) {
|
||||||
if (ptr && ptr->svrThread != 0) {
|
if (ptr && ptr->svrThread != 0) {
|
||||||
// Stop server
|
// Stop server
|
||||||
pthread_cancel(ptr->svrThread);
|
pthread_cancel(ptr->svrThread);
|
||||||
@@ -227,7 +231,7 @@ void TcpServer_Stop(TcpServer* ptr) {
|
|||||||
|
|
||||||
// Disconnect clients
|
// Disconnect clients
|
||||||
for (size_t i = 0; i < ptr->clients; i++) {
|
for (size_t i = 0; i < ptr->clients; i++) {
|
||||||
TcpClient* cliPtr = ptr->clientsArrPtr[i];
|
tcp_connection_t* cliPtr = ptr->clientsArrPtr[i];
|
||||||
if (cliPtr) {
|
if (cliPtr) {
|
||||||
close(cliPtr->clientFd);
|
close(cliPtr->clientFd);
|
||||||
pthread_cancel(cliPtr->clientThread);
|
pthread_cancel(cliPtr->clientThread);
|
||||||
@@ -238,7 +242,7 @@ void TcpServer_Stop(TcpServer* ptr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcpServer_Send(TcpServer* ptr, TcpClient* cli, void* data, size_t len) {
|
void TcpServer_Send(tcp_server_t* ptr, tcp_connection_t* cli, void* data, size_t len) {
|
||||||
if (ptr && cli && data && len > 0) {
|
if (ptr && cli && data && len > 0) {
|
||||||
size_t sent = 0;
|
size_t sent = 0;
|
||||||
while (sent < len) {
|
while (sent < len) {
|
||||||
@@ -267,7 +271,7 @@ void Generic_SendSocket(int sock, void* data, size_t len) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcpServer_Disconnect(TcpServer* ptr, TcpClient* cli) {
|
void TcpServer_Disconnect(tcp_server_t* ptr, tcp_connection_t* cli) {
|
||||||
if (ptr && cli) {
|
if (ptr && cli) {
|
||||||
close(cli->clientFd);
|
close(cli->clientFd);
|
||||||
pthread_cancel(cli->clientThread);
|
pthread_cancel(cli->clientThread);
|
||||||
@@ -284,7 +288,7 @@ void TcpServer_Disconnect(TcpServer* ptr, TcpClient* cli) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcpServer_KillClient(TcpServer* ptr, TcpClient* cli) {
|
void TcpServer_KillClient(tcp_server_t* ptr, tcp_connection_t* cli) {
|
||||||
if (ptr && cli) {
|
if (ptr && cli) {
|
||||||
// RST the connection
|
// RST the connection
|
||||||
struct linger so_linger;
|
struct linger so_linger;
|
||||||
@@ -306,7 +310,7 @@ void TcpServer_KillClient(TcpServer* ptr, TcpClient* cli) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Generic_FindClientInArrayByPtr(TcpClient** arr, TcpClient* ptr, size_t len) {
|
size_t Generic_FindClientInArrayByPtr(tcp_connection_t** arr, tcp_connection_t* ptr, size_t len) {
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
if (arr[i] == ptr) {
|
if (arr[i] == ptr) {
|
||||||
return i;
|
return i;
|
||||||
@@ -315,3 +319,5 @@ size_t Generic_FindClientInArrayByPtr(TcpClient** arr, TcpClient* ptr, size_t le
|
|||||||
|
|
||||||
return SIZE_MAX; // Returns max unsigned, likely improbable to be correct
|
return SIZE_MAX; // Returns max unsigned, likely improbable to be correct
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user