mirror of
https://github.com/CPunch/Laika.git
synced 2026-01-22 10:00:05 +00:00
Added .clang-format, formatted codebase
This commit is contained in:
214
lib/src/lpeer.c
214
lib/src/lpeer.c
@@ -1,16 +1,16 @@
|
||||
#include "lerror.h"
|
||||
#include "lmem.h"
|
||||
#include "lpeer.h"
|
||||
|
||||
struct sLaika_peer *laikaS_newPeer(struct sLaika_peerPacketInfo *pktTbl, struct sLaika_pollList *pList, pollFailEvent onPollFail, void *onPollFailUData, void *uData) {
|
||||
#include "lerror.h"
|
||||
#include "lmem.h"
|
||||
|
||||
struct sLaika_peer *laikaS_newPeer(struct sLaika_peerPacketInfo *pktTbl,
|
||||
struct sLaika_pollList *pList, pollFailEvent onPollFail,
|
||||
void *onPollFailUData, void *uData)
|
||||
{
|
||||
struct sLaika_peer *peer = laikaM_malloc(sizeof(struct sLaika_peer));
|
||||
|
||||
laikaS_initSocket(&peer->sock,
|
||||
laikaS_handlePeerIn,
|
||||
laikaS_handlePeerOut,
|
||||
onPollFail,
|
||||
onPollFailUData
|
||||
);
|
||||
laikaS_initSocket(&peer->sock, laikaS_handlePeerIn, laikaS_handlePeerOut, onPollFail,
|
||||
onPollFailUData);
|
||||
|
||||
peer->packetTbl = pktTbl;
|
||||
peer->pList = pList;
|
||||
@@ -31,14 +31,16 @@ struct sLaika_peer *laikaS_newPeer(struct sLaika_peerPacketInfo *pktTbl, struct
|
||||
return peer;
|
||||
}
|
||||
|
||||
void laikaS_freePeer(struct sLaika_peer *peer) {
|
||||
void laikaS_freePeer(struct sLaika_peer *peer)
|
||||
{
|
||||
laikaS_cleanSocket(&peer->sock);
|
||||
laikaM_free(peer);
|
||||
}
|
||||
|
||||
/* ===================================[[ Start/End Packets ]]=================================== */
|
||||
|
||||
void laikaS_emptyOutPacket(struct sLaika_peer *peer, LAIKAPKT_ID id) {
|
||||
void laikaS_emptyOutPacket(struct sLaika_peer *peer, LAIKAPKT_ID id)
|
||||
{
|
||||
struct sLaika_socket *sock = &peer->sock;
|
||||
|
||||
laikaS_writeByte(sock, id);
|
||||
@@ -47,7 +49,8 @@ void laikaS_emptyOutPacket(struct sLaika_peer *peer, LAIKAPKT_ID id) {
|
||||
laikaP_pushOutQueue(peer->pList, &peer->sock);
|
||||
}
|
||||
|
||||
void laikaS_startOutPacket(struct sLaika_peer *peer, LAIKAPKT_ID id) {
|
||||
void laikaS_startOutPacket(struct sLaika_peer *peer, LAIKAPKT_ID id)
|
||||
{
|
||||
struct sLaika_socket *sock = &peer->sock;
|
||||
|
||||
if (peer->outStart != -1) /* sanity check */
|
||||
@@ -56,27 +59,31 @@ void laikaS_startOutPacket(struct sLaika_peer *peer, LAIKAPKT_ID id) {
|
||||
laikaS_writeByte(sock, id);
|
||||
|
||||
peer->outStart = sock->outCount;
|
||||
if (peer->useSecure) { /* if we're encrypting this packet, append the nonce right after the packet ID */
|
||||
if (peer->useSecure) { /* if we're encrypting this packet, append the nonce right after the
|
||||
packet ID */
|
||||
uint8_t nonce[crypto_secretbox_NONCEBYTES];
|
||||
randombytes_buf(nonce, crypto_secretbox_NONCEBYTES);
|
||||
laikaS_write(sock, nonce, crypto_secretbox_NONCEBYTES);
|
||||
}
|
||||
}
|
||||
|
||||
int laikaS_endOutPacket(struct sLaika_peer *peer) {
|
||||
int laikaS_endOutPacket(struct sLaika_peer *peer)
|
||||
{
|
||||
struct sLaika_socket *sock = &peer->sock;
|
||||
uint8_t *body;
|
||||
size_t sz;
|
||||
|
||||
if (peer->useSecure) {
|
||||
/* make sure we have enough space */
|
||||
laikaM_growarray(uint8_t, sock->outBuf, crypto_secretbox_MACBYTES, sock->outCount, sock->outCap);
|
||||
laikaM_growarray(uint8_t, sock->outBuf, crypto_secretbox_MACBYTES, sock->outCount,
|
||||
sock->outCap);
|
||||
|
||||
/* packet body starts after the id & nonce */
|
||||
body = &sock->outBuf[peer->outStart + crypto_secretbox_NONCEBYTES];
|
||||
/* encrypt packet body in-place */
|
||||
if (crypto_secretbox_easy(body, body, (sock->outCount - peer->outStart) - crypto_secretbox_NONCEBYTES,
|
||||
&sock->outBuf[peer->outStart], peer->outKey) != 0) {
|
||||
if (crypto_secretbox_easy(body, body,
|
||||
(sock->outCount - peer->outStart) - crypto_secretbox_NONCEBYTES,
|
||||
&sock->outBuf[peer->outStart], peer->outKey) != 0) {
|
||||
LAIKA_ERROR("Failed to encrypt packet!\n");
|
||||
}
|
||||
|
||||
@@ -92,28 +99,33 @@ int laikaS_endOutPacket(struct sLaika_peer *peer) {
|
||||
return sz;
|
||||
}
|
||||
|
||||
void laikaS_startVarPacket(struct sLaika_peer *peer, LAIKAPKT_ID id) {
|
||||
void laikaS_startVarPacket(struct sLaika_peer *peer, LAIKAPKT_ID id)
|
||||
{
|
||||
struct sLaika_socket *sock = &peer->sock;
|
||||
|
||||
if (peer->outStart != -1) /* sanity check */
|
||||
LAIKA_ERROR("unended OUT packet!\n");
|
||||
|
||||
laikaS_writeByte(sock, LAIKAPKT_VARPKT);
|
||||
laikaS_zeroWrite(sock, sizeof(LAIKAPKT_SIZE)); /* allocate space for packet size to patch later */
|
||||
laikaS_zeroWrite(sock,
|
||||
sizeof(LAIKAPKT_SIZE)); /* allocate space for packet size to patch later */
|
||||
laikaS_startOutPacket(peer, id);
|
||||
}
|
||||
|
||||
int laikaS_endVarPacket(struct sLaika_peer *peer) {
|
||||
int laikaS_endVarPacket(struct sLaika_peer *peer)
|
||||
{
|
||||
struct sLaika_socket *sock = &peer->sock;
|
||||
int patchIndx = peer->outStart - (sizeof(LAIKAPKT_SIZE) + sizeof(LAIKAPKT_ID)); /* gets index of packet size */
|
||||
int patchIndx = peer->outStart -
|
||||
(sizeof(LAIKAPKT_SIZE) + sizeof(LAIKAPKT_ID)); /* gets index of packet size */
|
||||
LAIKAPKT_SIZE sz = (LAIKAPKT_SIZE)laikaS_endOutPacket(peer);
|
||||
|
||||
/* patch packet size */
|
||||
memcpy((void*)&sock->outBuf[patchIndx], (void*)&sz, sizeof(LAIKAPKT_SIZE));
|
||||
memcpy((void *)&sock->outBuf[patchIndx], (void *)&sz, sizeof(LAIKAPKT_SIZE));
|
||||
return sz;
|
||||
}
|
||||
|
||||
void laikaS_startInPacket(struct sLaika_peer *peer, bool variadic) {
|
||||
void laikaS_startInPacket(struct sLaika_peer *peer, bool variadic)
|
||||
{
|
||||
struct sLaika_socket *sock = &peer->sock;
|
||||
|
||||
if (peer->inStart != -1) /* sanity check */
|
||||
@@ -126,7 +138,8 @@ void laikaS_startInPacket(struct sLaika_peer *peer, bool variadic) {
|
||||
peer->inStart = sock->inCount;
|
||||
}
|
||||
|
||||
int laikaS_endInPacket(struct sLaika_peer *peer) {
|
||||
int laikaS_endInPacket(struct sLaika_peer *peer)
|
||||
{
|
||||
struct sLaika_socket *sock = &peer->sock;
|
||||
uint8_t *body;
|
||||
size_t sz = sock->inCount - peer->inStart;
|
||||
@@ -135,7 +148,8 @@ int laikaS_endInPacket(struct sLaika_peer *peer) {
|
||||
body = &sock->inBuf[peer->inStart + crypto_secretbox_NONCEBYTES];
|
||||
|
||||
/* decrypt packet body in-place */
|
||||
if (crypto_secretbox_open_easy(body, body, (sock->inCount - peer->inStart) - crypto_secretbox_NONCEBYTES,
|
||||
if (crypto_secretbox_open_easy(
|
||||
body, body, (sock->inCount - peer->inStart) - crypto_secretbox_NONCEBYTES,
|
||||
&sock->inBuf[peer->inStart], peer->inKey) != 0) {
|
||||
LAIKA_ERROR("Failed to decrypt packet!\n");
|
||||
}
|
||||
@@ -153,113 +167,119 @@ int laikaS_endInPacket(struct sLaika_peer *peer) {
|
||||
return sz;
|
||||
}
|
||||
|
||||
void laikaS_setSecure(struct sLaika_peer *peer, bool flag) {
|
||||
void laikaS_setSecure(struct sLaika_peer *peer, bool flag)
|
||||
{
|
||||
peer->useSecure = flag;
|
||||
}
|
||||
|
||||
/* ==================================[[ Handle Poll Events ]]=================================== */
|
||||
|
||||
bool laikaS_handlePeerIn(struct sLaika_socket *sock) {
|
||||
struct sLaika_peer *peer = (struct sLaika_peer*)sock;
|
||||
bool laikaS_handlePeerIn(struct sLaika_socket *sock)
|
||||
{
|
||||
struct sLaika_peer *peer = (struct sLaika_peer *)sock;
|
||||
int recvd;
|
||||
|
||||
switch (peer->pktID) {
|
||||
case LAIKAPKT_MAXNONE:
|
||||
/* try grabbing pktID */
|
||||
if (laikaS_rawRecv(&peer->sock, sizeof(uint8_t), &recvd) != RAWSOCK_OK)
|
||||
return false;
|
||||
case LAIKAPKT_MAXNONE:
|
||||
/* try grabbing pktID */
|
||||
if (laikaS_rawRecv(&peer->sock, sizeof(uint8_t), &recvd) != RAWSOCK_OK)
|
||||
return false;
|
||||
|
||||
/* read packet ID */
|
||||
peer->pktID = laikaS_readByte(&peer->sock);
|
||||
LAIKA_DEBUG("%s\n", laikaD_getPacketName(peer->pktID));
|
||||
/* read packet ID */
|
||||
peer->pktID = laikaS_readByte(&peer->sock);
|
||||
LAIKA_DEBUG("%s\n", laikaD_getPacketName(peer->pktID));
|
||||
|
||||
/* LAIKAPKT_VARPKT's body is unencrypted, and handled by this switch statement. LAIKAPKT_VARPKT is
|
||||
also likely not to be defined in our pktSizeTable. the LAIKAPKT_VARPKT case calls laikaS_startInPacket
|
||||
for itself, so skip all of this */
|
||||
if (peer->pktID == LAIKAPKT_VARPKT)
|
||||
goto _HandlePacketVariadic;
|
||||
/* LAIKAPKT_VARPKT's body is unencrypted, and handled by this switch statement.
|
||||
LAIKAPKT_VARPKT is also likely not to be defined in our pktSizeTable. the LAIKAPKT_VARPKT
|
||||
case calls laikaS_startInPacket for itself, so skip all of this */
|
||||
if (peer->pktID == LAIKAPKT_VARPKT)
|
||||
goto _HandlePacketVariadic;
|
||||
|
||||
/* sanity check pktID, pktID's handler & make sure it's not marked as variadic */
|
||||
if (peer->pktID >= LAIKAPKT_MAXNONE || peer->packetTbl[peer->pktID].handler == NULL || peer->packetTbl[peer->pktID].variadic)
|
||||
LAIKA_ERROR("peer %p doesn't support packet id [%d]!\n", peer, peer->pktID);
|
||||
/* sanity check pktID, pktID's handler & make sure it's not marked as variadic */
|
||||
if (peer->pktID >= LAIKAPKT_MAXNONE || peer->packetTbl[peer->pktID].handler == NULL ||
|
||||
peer->packetTbl[peer->pktID].variadic)
|
||||
LAIKA_ERROR("peer %p doesn't support packet id [%d]!\n", peer, peer->pktID);
|
||||
|
||||
peer->pktSize = peer->packetTbl[peer->pktID].size;
|
||||
peer->pktSize = peer->packetTbl[peer->pktID].size;
|
||||
|
||||
/* if peer->useSecure is true, body is encrypted */
|
||||
laikaS_startInPacket(peer, false);
|
||||
goto _HandlePacketBody;
|
||||
case LAIKAPKT_VARPKT:
|
||||
_HandlePacketVariadic:
|
||||
/* try grabbing pktID & size */
|
||||
if (laikaS_rawRecv(&peer->sock, sizeof(LAIKAPKT_ID) + sizeof(LAIKAPKT_SIZE), &recvd) != RAWSOCK_OK)
|
||||
return false;
|
||||
/* if peer->useSecure is true, body is encrypted */
|
||||
laikaS_startInPacket(peer, false);
|
||||
goto _HandlePacketBody;
|
||||
case LAIKAPKT_VARPKT:
|
||||
_HandlePacketVariadic:
|
||||
/* try grabbing pktID & size */
|
||||
if (laikaS_rawRecv(&peer->sock, sizeof(LAIKAPKT_ID) + sizeof(LAIKAPKT_SIZE), &recvd) !=
|
||||
RAWSOCK_OK)
|
||||
return false;
|
||||
|
||||
/* not worth queuing & setting pollIn for 3 bytes. if the connection is that slow, it was probably sent maliciously anyways */
|
||||
if (recvd != sizeof(LAIKAPKT_ID) + sizeof(LAIKAPKT_SIZE))
|
||||
LAIKA_ERROR("couldn't read whole LAIKAPKT_VARPKT\n");
|
||||
/* not worth queuing & setting pollIn for 3 bytes. if the connection is that slow, it was
|
||||
* probably sent maliciously anyways */
|
||||
if (recvd != sizeof(LAIKAPKT_ID) + sizeof(LAIKAPKT_SIZE))
|
||||
LAIKA_ERROR("couldn't read whole LAIKAPKT_VARPKT\n");
|
||||
|
||||
/* read packet size */
|
||||
laikaS_readInt(&peer->sock, (void*)&peer->pktSize, sizeof(LAIKAPKT_SIZE));
|
||||
/* read packet size */
|
||||
laikaS_readInt(&peer->sock, (void *)&peer->pktSize, sizeof(LAIKAPKT_SIZE));
|
||||
|
||||
if (peer->pktSize > LAIKA_MAX_PKTSIZE)
|
||||
LAIKA_ERROR("variable packet too large!\n");
|
||||
if (peer->pktSize > LAIKA_MAX_PKTSIZE)
|
||||
LAIKA_ERROR("variable packet too large!\n");
|
||||
|
||||
/* read pktID */
|
||||
peer->pktID = laikaS_readByte(&peer->sock);
|
||||
/* read pktID */
|
||||
peer->pktID = laikaS_readByte(&peer->sock);
|
||||
|
||||
/* sanity check pktID, check valid handler & make sure it's marked as variadic */
|
||||
if (peer->pktID >= LAIKAPKT_MAXNONE || peer->packetTbl[peer->pktID].handler == NULL || !peer->packetTbl[peer->pktID].variadic)
|
||||
LAIKA_ERROR("requested packet id [%d] is not variadic!\n", peer->pktID);
|
||||
/* sanity check pktID, check valid handler & make sure it's marked as variadic */
|
||||
if (peer->pktID >= LAIKAPKT_MAXNONE || peer->packetTbl[peer->pktID].handler == NULL ||
|
||||
!peer->packetTbl[peer->pktID].variadic)
|
||||
LAIKA_ERROR("requested packet id [%d] is not variadic!\n", peer->pktID);
|
||||
|
||||
/* if peer->useSecure is true, body is encrypted */
|
||||
laikaS_startInPacket(peer, true);
|
||||
goto _HandlePacketBody;
|
||||
default:
|
||||
_HandlePacketBody:
|
||||
/* try grabbing the rest of the packet */
|
||||
if (laikaS_rawRecv(&peer->sock, peer->pktSize - peer->sock.inCount, &recvd) != RAWSOCK_OK)
|
||||
return false;
|
||||
/* if peer->useSecure is true, body is encrypted */
|
||||
laikaS_startInPacket(peer, true);
|
||||
goto _HandlePacketBody;
|
||||
default:
|
||||
_HandlePacketBody:
|
||||
/* try grabbing the rest of the packet */
|
||||
if (laikaS_rawRecv(&peer->sock, peer->pktSize - peer->sock.inCount, &recvd) != RAWSOCK_OK)
|
||||
return false;
|
||||
|
||||
/* have we received the full packet? */
|
||||
if (peer->pktSize == peer->sock.inCount) {
|
||||
peer->pktSize = laikaS_endInPacket(peer);
|
||||
/* have we received the full packet? */
|
||||
if (peer->pktSize == peer->sock.inCount) {
|
||||
peer->pktSize = laikaS_endInPacket(peer);
|
||||
|
||||
/* dispatch to packet handler */
|
||||
peer->packetTbl[peer->pktID].handler(peer, peer->pktSize, peer->uData);
|
||||
/* dispatch to packet handler */
|
||||
peer->packetTbl[peer->pktID].handler(peer, peer->pktSize, peer->uData);
|
||||
|
||||
/* reset */
|
||||
peer->sock.inCount = 0;
|
||||
peer->pktID = LAIKAPKT_MAXNONE;
|
||||
}
|
||||
/* reset */
|
||||
peer->sock.inCount = 0;
|
||||
peer->pktID = LAIKAPKT_MAXNONE;
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
return laikaS_isAlive((&peer->sock));
|
||||
}
|
||||
|
||||
bool laikaS_handlePeerOut(struct sLaika_socket *sock) {
|
||||
struct sLaika_peer *peer = (struct sLaika_peer*)sock;
|
||||
bool laikaS_handlePeerOut(struct sLaika_socket *sock)
|
||||
{
|
||||
struct sLaika_peer *peer = (struct sLaika_peer *)sock;
|
||||
int sent;
|
||||
|
||||
if (peer->sock.outCount == 0) /* sanity check */
|
||||
return true;
|
||||
|
||||
switch (laikaS_rawSend(&peer->sock, peer->sock.outCount, &sent)) {
|
||||
case RAWSOCK_OK: /* we're ok! */
|
||||
/* if POLLOUT was set, unset it */
|
||||
laikaP_rmvPollOut(peer->pList, &peer->sock);
|
||||
case RAWSOCK_OK: /* we're ok! */
|
||||
/* if POLLOUT was set, unset it */
|
||||
laikaP_rmvPollOut(peer->pList, &peer->sock);
|
||||
|
||||
return true;
|
||||
case RAWSOCK_POLL: /* we've been asked to set the POLLOUT flag */
|
||||
/* if POLLOUT wasn't set, set it so we'll be notified whenever the kernel has room :) */
|
||||
laikaP_addPollOut(peer->pList, &peer->sock);
|
||||
return true;
|
||||
case RAWSOCK_POLL: /* we've been asked to set the POLLOUT flag */
|
||||
/* if POLLOUT wasn't set, set it so we'll be notified whenever the kernel has room :) */
|
||||
laikaP_addPollOut(peer->pList, &peer->sock);
|
||||
|
||||
return true;
|
||||
default: /* panic! */
|
||||
case RAWSOCK_CLOSED:
|
||||
case RAWSOCK_ERROR:
|
||||
return false;
|
||||
return true;
|
||||
default: /* panic! */
|
||||
case RAWSOCK_CLOSED:
|
||||
case RAWSOCK_ERROR:
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user