1
0
mirror of https://github.com/CPunch/Laika.git synced 2025-09-26 20:00:08 +00:00

Inital commit

lib/ is just [FoxNet](https://git.openpunk.com/CPunch/FoxNet) ported to C99
This commit is contained in:
2022-01-23 21:28:16 -06:00
commit 8133a8d3cb
24 changed files with 1939 additions and 0 deletions

54
lib/include/hashmap.h Normal file
View File

@@ -0,0 +1,54 @@
// Copyright 2020 Joshua J Baker. All rights reserved.
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.
#ifndef HASHMAP_H
#define HASHMAP_H
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
struct hashmap;
struct hashmap *hashmap_new(size_t elsize, size_t cap,
uint64_t seed0, uint64_t seed1,
uint64_t (*hash)(const void *item,
uint64_t seed0, uint64_t seed1),
int (*compare)(const void *a, const void *b,
void *udata),
void (*elfree)(void *item),
void *udata);
struct hashmap *hashmap_new_with_allocator(
void *(*malloc)(size_t),
void *(*realloc)(void *, size_t),
void (*free)(void*),
size_t elsize, size_t cap,
uint64_t seed0, uint64_t seed1,
uint64_t (*hash)(const void *item,
uint64_t seed0, uint64_t seed1),
int (*compare)(const void *a, const void *b,
void *udata),
void (*elfree)(void *item),
void *udata);
void hashmap_free(struct hashmap *map);
void hashmap_clear(struct hashmap *map, bool update_cap);
size_t hashmap_count(struct hashmap *map);
bool hashmap_oom(struct hashmap *map);
void *hashmap_get(struct hashmap *map, const void *item);
void *hashmap_set(struct hashmap *map, void *item);
void *hashmap_delete(struct hashmap *map, void *item);
void *hashmap_probe(struct hashmap *map, uint64_t position);
bool hashmap_scan(struct hashmap *map,
bool (*iter)(const void *item, void *udata), void *udata);
uint64_t hashmap_sip(const void *data, size_t len,
uint64_t seed0, uint64_t seed1);
uint64_t hashmap_murmur(const void *data, size_t len,
uint64_t seed0, uint64_t seed1);
// DEPRECATED: use `hashmap_new_with_allocator`
void hashmap_set_allocator(void *(*malloc)(size_t), void (*free)(void*));
#endif

13
lib/include/laika.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef LAIKA_LAIKA_H
#define LAIKA_LAIKA_H
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#define ARRAY_START 4
#endif

47
lib/include/lerror.h Normal file
View File

@@ -0,0 +1,47 @@
#ifndef LAIKA_ERROR_H
#define LAIKA_ERROR_H
#include <stdio.h>
#include <setjmp.h>
/* defines errorstack size */
#define LAIKA_MAXERRORS 32
/* DO NOT RETURN/GOTO/BREAK or otherwise skip LAIKA_TRYEND */
#define LAIKA_TRY if (setjmp(eLaika_errStack[++eLaika_errIndx]) == 0) {
#define LAIKA_CATCH } else {
#define LAIKA_TRYEND } --eLaika_errIndx;
/* if eLaika_errIndx is >= 0, we have a safe spot to jump too if an error is thrown */
#define LAIKA_ISPROTECTED (eLaika_errIndx >= 0)
/* CERROR(printf args):
if called after a LAIKA_TRY block will jump to the previous LAIKA_CATCH/LAIKA_TRYEND block,
otherwise program is exit()'d. if DEBUG is defined printf is called with passed args, else
arguments are ignored.
*/
#ifndef DEBUG
#define CERROR(...) { \
if (LAIKA_ISPROTECTED) \
longjmp(eLaika_errStack[eLaika_errIndx], 1); \
else \
exit(1); \
}
#define CWARN(...)
#else
#define CERROR(...) { \
printf("[ERROR] : " __VA_ARGS__); \
if (LAIKA_ISPROTECTED) \
longjmp(eLaika_errStack[eLaika_errIndx], 1); \
else \
exit(1); \
}
#define CWARN(...) \
printf("[WARN] : " __VA_ARGS__);
#endif
extern int eLaika_errIndx;
extern jmp_buf eLaika_errStack[LAIKA_MAXERRORS];
#endif

26
lib/include/lmem.h Normal file
View File

@@ -0,0 +1,26 @@
#ifndef LAIKA_MEM_H
#define LAIKA_MEM_H
#include "laika.h"
#define GROW_FACTOR 2
#define laikaM_malloc(sz) laikaM_realloc(NULL, sz)
#define laikaM_free(buf) laikaM_realloc(buf, 0)
#define laikaM_free(buf) laikaM_realloc(buf, 0)
#define laikaM_growarray(type, buf, count, capacity) \
if (count >= capacity || buf == NULL) { \
capacity *= GROW_FACTOR; \
buf = (type*)cosmoM_realloc(buf, sizeof(type)*capacity); \
}
/* moves array elements above indx down by numElem, removing numElem elements at indx */
#define laikaM_rmvarray(type, buf, count, indx, numElem) { \
memmove(&buf[indx], &buf[indx+numElem], ((count-indx)-numElem)*sizeof(type)); \
count -= numElem; \
}
void *laikaM_realloc(void *buf, size_t sz);
#endif

10
lib/include/lpacket.h Normal file
View File

@@ -0,0 +1,10 @@
#ifndef LAIKA_PACKET_H
#define LAIKA_PACKET_H
typedef enum {
LAIKAPKT_HANDSHAKE_REQ,
LAIKAPKT_HANDSHAKE_RES,
LAIKAPKT_MAXNONE
} LAIKAPKT_ID;
#endif

25
lib/include/lpeer.h Normal file
View File

@@ -0,0 +1,25 @@
#ifndef LAIKA_PEER_H
#define LAIKA_PEER_H
#include "laika.h"
#include "lsocket.h"
#include "lpacket.h"
#include "lpolllist.h"
struct sLaika_peer {
struct sLaika_socket sock;
struct sLaika_pollList *pList; /* pollList we're active in */
void (*pktHandler)(struct sLaika_peer *peer, LAIKAPKT_ID id);
size_t pktSize; /* current pkt size */
LAIKAPKT_ID pktID; /* current pkt ID */
size_t *pktSizeTable; /* const table to pull pkt size data from */
bool setPollOut; /* if EPOLLOUT/POLLOUT is set on sock's pollfd */
};
struct sLaika_peer *laikaS_newPeer(void (*pktHandler)(struct sLaika_peer *peer, LAIKAPKT_ID id), struct sLaika_pollList *pList, size_t *pktSizeTable);
void laikaS_freePeer(struct sLaika_peer *peer);
bool laikaS_handlePeerIn(struct sLaika_peer *peer);
bool laikaS_handlePeerOut(struct sLaika_peer *peer);
#endif

43
lib/include/lpolllist.h Normal file
View File

@@ -0,0 +1,43 @@
#ifndef LAIKA_POLLLIST_H
#define LAIKA_POLLLIST_H
#include "laika.h"
#include "lsocket.h"
#include "hashmap.h"
/* number of pollFDs or epollFDs we expect to start with */
#define POLLSTARTCAP 8
struct sLaika_pollEvent {
struct sLaika_socket *sock;
bool pollIn;
bool pollOut;
};
struct sLaika_pollList {
struct hashmap *sockets;
struct sLaika_pollEvent *revents;
#ifdef LAIKA_USE_EPOLL
/* epoll */
struct epoll_event ev, ep_events[MAX_EPOLL_EVENTS];
SOCKET epollfd;
#else
/* raw poll descriptor */
PollFD *fds;
int fdCapacity;
int fdCount;
#endif
int reventCapacity;
int reventCount;
};
void laikaP_initPList(struct sLaika_pollList *pList);
void laikaP_cleanPList(struct sLaika_pollList *pList); /* free's all members */
void laikaP_addSock(struct sLaika_pollList *pList, struct sLaika_socket *sock);
void laikaP_rmvSock(struct sLaika_pollList *pList, struct sLaika_socket *sock);
void laikaP_addPollOut(struct sLaika_pollList *pList, struct sLaika_socket *sock);
void laikaP_rmvPollOut(struct sLaika_pollList *pList, struct sLaika_socket *sock);
struct sLaika_pollEvent *laikaP_poll(struct sLaika_pollList *pList, int timeout, int *nevents);
#endif

86
lib/include/lsocket.h Normal file
View File

@@ -0,0 +1,86 @@
/* socket/winsock headers */
#ifdef _WIN32
/* windows */
#ifndef NOMINMAX
#define NOMINMAX
#endif
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#pragma comment(lib, "Ws2_32.lib")
typedef char buffer_t;
#define PollFD WSAPOLLFD
#define poll WSAPoll
#define LN_ERRNO WSAGetLastError()
#define LN_EWOULD WSAEWOULDBLOCK
#define LN_MSG_NOSIGNAL 0
#define SOCKETINVALID(x) (x == INVALID_SOCKET)
#define SOCKETERROR(x) (x == SOCKET_ERROR)
#else
/* posix platform */
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <poll.h>
#ifdef __linux__
#include <sys/epoll.h>
/* max events for epoll() */
#define MAX_EPOLL_EVENTS 128
#define LAIKA_USE_EPOLL
#endif
#include <unistd.h>
#include <errno.h>
typedef int SOCKET;
typedef void buffer_t;
#define PollFD struct pollfd
#define LN_ERRNO errno
#define LN_EWOULD EWOULDBLOCK
#define LN_MSG_NOSIGNAL MSG_NOSIGNAL
#define INVALID_SOCKET -1
#define SOCKETINVALID(x) (x < 0)
#define SOCKETERROR(x) (x == -1)
#endif
#include <fcntl.h>
typedef enum {
RAWSOCK_OK,
RAWSOCK_ERROR,
RAWSOCK_CLOSED,
RAWSOCK_POLL
} RAWSOCKCODE;
struct sLaika_socket {
uint8_t *outBuf; /* raw data to be sent() */
uint8_t *inBuf; /* raw data we recv()'d */
SOCKET sock; /* raw socket fd */
int outCount;
int inCount;
int outCap;
int inCap;
};
#define laikaS_isAlive(sock) (sock->sock != INVALID_SOCKET)
void laikaS_init(void);
void laikaS_cleanUp(void);
void laikaS_initSocket(struct sLaika_socket *sock);
void laikaS_cleanSocket(struct sLaika_socket *sock);
void laikaS_kill(struct sLaika_socket *sock); /* kills a socket */
void laikaS_connect(struct sLaika_socket *sock, char *ip, char *port); /* connect to ip & port */
void laikaS_bind(struct sLaika_socket *sock, uint16_t port); /* bind sock to port */
bool laikaS_setNonBlock(struct sLaika_socket *sock);
void laikaS_read(struct sLaika_socket *sock, void *buf, size_t sz); /* reads from inBuf */
void laikaS_write(struct sLaika_socket *sock, void *buf, size_t sz); /* writes to outBuf */
void laikaS_writeByte(struct sLaika_socket *sock, uint8_t data);
uint8_t laikaS_readByte(struct sLaika_socket *sock);
RAWSOCKCODE laikaS_rawRecv(struct sLaika_socket *sock, size_t sz, int *processed);
RAWSOCKCODE laikaS_rawSend(struct sLaika_socket *sock, size_t sz, int *processed);