mirror of
https://github.com/CPunch/Laika.git
synced 2024-11-21 20:40:05 +00:00
Lib: minor refactoring, more lcontent.c boilerplate
This commit is contained in:
parent
b02f48c006
commit
83002faa62
@ -22,4 +22,20 @@
|
|||||||
# define LAIKA_FORCEINLINE __forceinline
|
# define LAIKA_FORCEINLINE __forceinline
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MIN(a, b) \
|
||||||
|
({ __typeof__ (a) _a = (a); \
|
||||||
|
__typeof__ (b) _b = (b); \
|
||||||
|
_a < _b ? _a : _b; })
|
||||||
|
|
||||||
|
#define MAX(a, b) \
|
||||||
|
({ __typeof__ (a) _a = (a); \
|
||||||
|
__typeof__ (b) _b = (b); \
|
||||||
|
_a > _b ? _a : _b; })
|
||||||
|
|
||||||
|
struct sLaika_peer;
|
||||||
|
struct sLaika_socket;
|
||||||
|
struct sLaika_pollList;
|
||||||
|
struct sLaika_task;
|
||||||
|
struct sLaika_taskService;
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -1,7 +1,8 @@
|
|||||||
#ifndef LAIKA_CONTENT_H
|
#ifndef LAIKA_CONTENT_H
|
||||||
#define LAIKA_CONTENT_H
|
#define LAIKA_CONTENT_H
|
||||||
|
|
||||||
#include "lpeer.h"
|
#include "laika.h"
|
||||||
|
#include "lpacket.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@ -18,29 +19,31 @@ enum {
|
|||||||
|
|
||||||
typedef uint8_t CONTENT_TYPE;
|
typedef uint8_t CONTENT_TYPE;
|
||||||
typedef uint8_t CONTENT_ERRCODE;
|
typedef uint8_t CONTENT_ERRCODE;
|
||||||
|
typedef uint16_t CONTENT_ID;
|
||||||
|
|
||||||
struct sLaika_content {
|
struct sLaika_content {
|
||||||
|
struct sLaika_content *next;
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
uint32_t sz; /* content size */
|
uint32_t sz; /* content size */
|
||||||
uint32_t processed;
|
uint32_t processed;
|
||||||
uint16_t id;
|
CONTENT_ID id;
|
||||||
CONTENT_TYPE type;
|
CONTENT_TYPE type;
|
||||||
struct sLaika_content *next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sLaika_contentContext {
|
struct sLaika_contentContext {
|
||||||
struct sLaika_peer *peer;
|
|
||||||
struct sLaika_content *headIn; /* receiving from peer */
|
struct sLaika_content *headIn; /* receiving from peer */
|
||||||
struct sLaika_content *headOut; /* sending to peer */
|
struct sLaika_content *headOut; /* sending to peer */
|
||||||
uint16_t nextID;
|
CONTENT_ID nextID;
|
||||||
};
|
};
|
||||||
|
|
||||||
void laikaF_initContext(struct sLaika_contentContext *context, struct sLaika_peer *peer);
|
void laikaF_initContext(struct sLaika_contentContext *context);
|
||||||
void laikaF_cleanContext(struct sLaika_contentContext *context);
|
void laikaF_cleanContext(struct sLaika_contentContext *context);
|
||||||
|
|
||||||
int laikaF_newOutContent(struct sLaika_contentContext *context, FILE *fd, CONTENT_TYPE type);
|
int laikaF_newOutContent(struct sLaika_peer *peer, FILE *fd, CONTENT_TYPE type);
|
||||||
void laikaF_newInContent(struct sLaika_contentContext *context, uint16_t id, uint32_t sz, CONTENT_TYPE type);
|
void laikaF_newInContent(struct sLaika_peer *peer, CONTENT_ID id, uint32_t sz, CONTENT_TYPE type);
|
||||||
|
|
||||||
void laikaF_poll(struct sLaika_contentContext *context);
|
void laikaF_pollContent(struct sLaika_peer *peer);
|
||||||
|
|
||||||
|
void laikaF_handleContentChunk(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -6,6 +6,7 @@
|
|||||||
#include "lpacket.h"
|
#include "lpacket.h"
|
||||||
#include "lpolllist.h"
|
#include "lpolllist.h"
|
||||||
#include "lsodium.h"
|
#include "lsodium.h"
|
||||||
|
#include "lcontent.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PEER_UNKNWN,
|
PEER_UNKNWN,
|
||||||
@ -30,7 +31,6 @@ typedef enum {
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct sLaika_peer;
|
|
||||||
typedef void (*PeerPktHandler)(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData);
|
typedef void (*PeerPktHandler)(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData);
|
||||||
|
|
||||||
struct sLaika_peerPacketInfo {
|
struct sLaika_peerPacketInfo {
|
||||||
@ -43,6 +43,7 @@ struct sLaika_peerPacketInfo {
|
|||||||
|
|
||||||
struct sLaika_peer {
|
struct sLaika_peer {
|
||||||
struct sLaika_socket sock; /* DO NOT MOVE THIS. this member HAS TO BE FIRST so that typecasting sLaika_peer* to sLaika_sock* works as intended */
|
struct sLaika_socket sock; /* DO NOT MOVE THIS. this member HAS TO BE FIRST so that typecasting sLaika_peer* to sLaika_sock* works as intended */
|
||||||
|
struct sLaika_contentContext context;
|
||||||
uint8_t peerPub[crypto_kx_PUBLICKEYBYTES]; /* connected peer's public key */
|
uint8_t peerPub[crypto_kx_PUBLICKEYBYTES]; /* connected peer's public key */
|
||||||
uint8_t inKey[crypto_kx_SESSIONKEYBYTES], outKey[crypto_kx_SESSIONKEYBYTES];
|
uint8_t inKey[crypto_kx_SESSIONKEYBYTES], outKey[crypto_kx_SESSIONKEYBYTES];
|
||||||
char hostname[LAIKA_HOSTNAME_LEN], inet[LAIKA_INET_LEN], ipv4[LAIKA_IPV4_LEN];
|
char hostname[LAIKA_HOSTNAME_LEN], inet[LAIKA_INET_LEN], ipv4[LAIKA_IPV4_LEN];
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "laika.h"
|
||||||
#include "lsodium.h"
|
#include "lsodium.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -60,7 +61,6 @@ typedef enum {
|
|||||||
RAWSOCK_POLL
|
RAWSOCK_POLL
|
||||||
} RAWSOCKCODE;
|
} RAWSOCKCODE;
|
||||||
|
|
||||||
struct sLaika_socket;
|
|
||||||
typedef bool (*pollEvent)(struct sLaika_socket *sock);
|
typedef bool (*pollEvent)(struct sLaika_socket *sock);
|
||||||
typedef void (*pollFailEvent)(struct sLaika_socket *sock, void *uData);
|
typedef void (*pollFailEvent)(struct sLaika_socket *sock, void *uData);
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
struct sLaika_task;
|
#include "laika.h"
|
||||||
struct sLaika_taskService;
|
|
||||||
typedef void (*taskCallback)(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick, void *uData);
|
typedef void (*taskCallback)(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick, void *uData);
|
||||||
|
|
||||||
struct sLaika_task {
|
struct sLaika_task {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "laika.h"
|
||||||
#include "lcontent.h"
|
#include "lcontent.h"
|
||||||
#include "lmem.h"
|
#include "lmem.h"
|
||||||
#include "lerror.h"
|
#include "lerror.h"
|
||||||
@ -5,6 +6,8 @@
|
|||||||
#include "lsocket.h"
|
#include "lsocket.h"
|
||||||
#include "lpeer.h"
|
#include "lpeer.h"
|
||||||
|
|
||||||
|
#define CONTENTCHUNK_MAX_BODY (LAIKA_MAX_PKTSIZE-sizeof(CONTENT_ID))
|
||||||
|
|
||||||
size_t getSize(FILE *fd) {
|
size_t getSize(FILE *fd) {
|
||||||
size_t sz;
|
size_t sz;
|
||||||
fseek(fd, 0L, SEEK_END);
|
fseek(fd, 0L, SEEK_END);
|
||||||
@ -13,17 +16,17 @@ size_t getSize(FILE *fd) {
|
|||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isValidID(struct sLaika_contentContext *context, uint16_t id) {
|
struct sLaika_content* getContentByID(struct sLaika_contentContext *context, CONTENT_ID id) {
|
||||||
struct sLaika_content *curr = context->headIn;
|
struct sLaika_content *curr = context->headIn;
|
||||||
|
|
||||||
while (curr) {
|
while (curr) {
|
||||||
if (curr->id == id)
|
if (curr->id == id)
|
||||||
return true;
|
return curr;
|
||||||
|
|
||||||
curr = curr->next;
|
curr = curr->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeContent(struct sLaika_content *content) {
|
void freeContent(struct sLaika_content *content) {
|
||||||
@ -51,15 +54,34 @@ void rmvFromOut(struct sLaika_contentContext *context, struct sLaika_content *co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendContentError(struct sLaika_peer *peer, uint16_t id, CONTENT_ERRCODE err) {
|
void rmvFromIn(struct sLaika_contentContext *context, struct sLaika_content *content) {
|
||||||
|
struct sLaika_content *last = NULL, *curr = context->headIn;
|
||||||
|
|
||||||
|
while (curr) {
|
||||||
|
/* if found, remove it! */
|
||||||
|
if (curr == content) {
|
||||||
|
if (last)
|
||||||
|
last->next = curr->next;
|
||||||
|
else
|
||||||
|
context->headIn = curr->next;
|
||||||
|
|
||||||
|
freeContent(curr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
last = curr;
|
||||||
|
curr = curr->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendContentError(struct sLaika_peer *peer, CONTENT_ID id, CONTENT_ERRCODE err) {
|
||||||
laikaS_startOutPacket(peer, LAIKAPKT_CONTENT_ERROR);
|
laikaS_startOutPacket(peer, LAIKAPKT_CONTENT_ERROR);
|
||||||
laikaS_writeInt(&peer->sock, &id, sizeof(uint16_t));
|
laikaS_writeInt(&peer->sock, &id, sizeof(CONTENT_ID));
|
||||||
laikaS_writeByte(&peer->sock, err);
|
laikaS_writeByte(&peer->sock, err);
|
||||||
laikaS_endOutPacket(peer);
|
laikaS_endOutPacket(peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void laikaF_initContext(struct sLaika_contentContext *context, struct sLaika_peer *peer) {
|
void laikaF_initContext(struct sLaika_contentContext *context) {
|
||||||
context->peer = peer;
|
|
||||||
context->headIn = NULL;
|
context->headIn = NULL;
|
||||||
context->headOut = NULL;
|
context->headOut = NULL;
|
||||||
context->nextID = 0;
|
context->nextID = 0;
|
||||||
@ -85,9 +107,9 @@ void laikaF_cleanContext(struct sLaika_contentContext *context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int laikaF_newOutContent(struct sLaika_contentContext *context, FILE *fd, CONTENT_TYPE type) {
|
int laikaF_newOutContent(struct sLaika_peer *peer, FILE *fd, CONTENT_TYPE type) {
|
||||||
struct sLaika_content *content = (struct sLaika_content*)laikaM_malloc(sizeof(struct sLaika_content));
|
struct sLaika_content *content = (struct sLaika_content*)laikaM_malloc(sizeof(struct sLaika_content));
|
||||||
struct sLaika_peer *peer = context->peer;
|
struct sLaika_contentContext *context = &peer->context;
|
||||||
|
|
||||||
/* init content struct */
|
/* init content struct */
|
||||||
content->fd = fd;
|
content->fd = fd;
|
||||||
@ -102,17 +124,19 @@ int laikaF_newOutContent(struct sLaika_contentContext *context, FILE *fd, CONTEN
|
|||||||
|
|
||||||
/* let the peer know we're sending them some content */
|
/* let the peer know we're sending them some content */
|
||||||
laikaS_startOutPacket(peer, LAIKAPKT_CONTENT_NEW);
|
laikaS_startOutPacket(peer, LAIKAPKT_CONTENT_NEW);
|
||||||
laikaS_writeInt(&peer->sock, &content->id, sizeof(uint16_t));
|
laikaS_writeInt(&peer->sock, &content->id, sizeof(CONTENT_ID));
|
||||||
laikaS_writeInt(&peer->sock, &content->sz, sizeof(uint32_t));
|
laikaS_writeInt(&peer->sock, &content->sz, sizeof(uint32_t));
|
||||||
laikaS_writeByte(&peer->sock, type);
|
laikaS_writeByte(&peer->sock, type);
|
||||||
laikaS_endOutPacket(peer);
|
laikaS_endOutPacket(peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void laikaF_newInContent(struct sLaika_contentContext *context, uint16_t id, uint32_t sz, CONTENT_TYPE type) {
|
/* new content we're recieving from a peer */
|
||||||
|
void laikaF_newInContent(struct sLaika_peer *peer, CONTENT_ID id, uint32_t sz, CONTENT_TYPE type) {
|
||||||
struct sLaika_content *content = (struct sLaika_content*)laikaM_malloc(sizeof(struct sLaika_content));
|
struct sLaika_content *content = (struct sLaika_content*)laikaM_malloc(sizeof(struct sLaika_content));
|
||||||
|
struct sLaika_contentContext *context = &peer->context;
|
||||||
|
|
||||||
if (isValidID(context, id)) {
|
if (getContentByID(context, id)) {
|
||||||
sendContentError(context->peer, id, CONTENT_ERR_ID_IN_USE);
|
sendContentError(peer, id, CONTENT_ERR_ID_IN_USE);
|
||||||
LAIKA_ERROR("ID [%d] is in use!\n", id);
|
LAIKA_ERROR("ID [%d] is in use!\n", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,27 +151,56 @@ void laikaF_newInContent(struct sLaika_contentContext *context, uint16_t id, uin
|
|||||||
context->headIn = content;
|
context->headIn = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
void laikaF_poll(struct sLaika_contentContext *context) {
|
void laikaF_pollContent(struct sLaika_peer *peer) {
|
||||||
uint8_t buff[LAIKA_MAX_PKTSIZE-sizeof(uint16_t)];
|
uint8_t buff[CONTENTCHUNK_MAX_BODY];
|
||||||
struct sLaika_peer *peer = context->peer;
|
struct sLaika_contentContext *context = &peer->context;
|
||||||
struct sLaika_content *tmp, *curr = context->headOut;
|
struct sLaika_content *tmp, *curr = context->headOut;
|
||||||
int rd;
|
int rd;
|
||||||
|
|
||||||
/* traverse our out content, sending each chunk */
|
/* traverse our out content, sending each chunk */
|
||||||
while (curr) {
|
while (curr) {
|
||||||
/* if we've reached the end of the file stream, remove it! */
|
/* if we've reached the end of the file stream, remove it! */
|
||||||
if (rd = fread(buff, sizeof(uint8_t), (curr->sz - curr->processed > (LAIKA_MAX_PKTSIZE-sizeof(uint16_t)) ? LAIKA_MAX_PKTSIZE-sizeof(uint16_t) : curr->sz - curr->processed), curr->fd) == 0) {
|
if (rd = fread(buff, sizeof(uint8_t), MIN(curr->sz - curr->processed, CONTENTCHUNK_MAX_BODY), curr->fd) == 0) {
|
||||||
tmp = curr->next;
|
tmp = curr->next;
|
||||||
rmvFromOut(context, curr);
|
rmvFromOut(context, curr);
|
||||||
curr = tmp;
|
curr = tmp;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* send chunk */
|
||||||
laikaS_startVarPacket(peer, LAIKAPKT_CONTENT_CHUNK);
|
laikaS_startVarPacket(peer, LAIKAPKT_CONTENT_CHUNK);
|
||||||
laikaS_writeInt(&peer->sock, &curr->id, sizeof(uint16_t));
|
laikaS_writeInt(&peer->sock, &curr->id, sizeof(CONTENT_ID));
|
||||||
laikaS_write(&peer->sock, buff, rd);
|
laikaS_write(&peer->sock, buff, rd);
|
||||||
laikaS_endVarPacket(peer);
|
laikaS_endVarPacket(peer);
|
||||||
|
|
||||||
|
curr->processed += rd;
|
||||||
curr = curr->next;
|
curr = curr->next;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================[[ Packet Handlers ]]============================================= */
|
||||||
|
|
||||||
|
void laikaF_handleContentChunk(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) {
|
||||||
|
uint8_t buff[CONTENTCHUNK_MAX_BODY];
|
||||||
|
struct sLaika_contentContext *context = &peer->context;
|
||||||
|
struct sLaika_content *content;
|
||||||
|
CONTENT_ID id;
|
||||||
|
size_t bodySz = sz-sizeof(CONTENT_ID);
|
||||||
|
|
||||||
|
if (sz <= sizeof(CONTENT_ID))
|
||||||
|
LAIKA_ERROR("malformed chunk packet!\n");
|
||||||
|
|
||||||
|
/* read and sanity check id */
|
||||||
|
laikaS_readInt(&peer->sock, &id, sizeof(CONTENT_ID));
|
||||||
|
if ((content = getContentByID(context, id)) == NULL)
|
||||||
|
LAIKA_ERROR("chunk recieved with invalid id! [%d]\n", id);
|
||||||
|
|
||||||
|
/* read data & write to file */
|
||||||
|
laikaS_read(&peer->sock, buff, bodySz);
|
||||||
|
if (fwrite(buff, sizeof(uint8_t), bodySz, content->fd) != bodySz) {
|
||||||
|
rmvFromIn(context, content);
|
||||||
|
} else {
|
||||||
|
/* TODO: if content->processed == content->sz then handle full file received event */
|
||||||
|
content->processed += bodySz;
|
||||||
|
}
|
||||||
}
|
}
|
@ -27,10 +27,14 @@ struct sLaika_peer *laikaS_newPeer(struct sLaika_peerPacketInfo *pktTbl, struct
|
|||||||
memset(peer->hostname, 0, LAIKA_HOSTNAME_LEN);
|
memset(peer->hostname, 0, LAIKA_HOSTNAME_LEN);
|
||||||
memset(peer->inet, 0, LAIKA_INET_LEN);
|
memset(peer->inet, 0, LAIKA_INET_LEN);
|
||||||
memset(peer->ipv4, 0, LAIKA_IPV4_LEN);
|
memset(peer->ipv4, 0, LAIKA_IPV4_LEN);
|
||||||
|
|
||||||
|
/* init content context */
|
||||||
|
laikaF_initContext(&peer->context);
|
||||||
return peer;
|
return peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void laikaS_freePeer(struct sLaika_peer *peer) {
|
void laikaS_freePeer(struct sLaika_peer *peer) {
|
||||||
|
laikaF_cleanContext(&peer->context);
|
||||||
laikaS_cleanSocket(&peer->sock);
|
laikaS_cleanSocket(&peer->sock);
|
||||||
laikaM_free(peer);
|
laikaM_free(peer);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user