update: migrating MPTP to TCP
This commit is contained in:
parent
865141177a
commit
75fa38f1d7
@ -148,6 +148,7 @@ typedef enum lm_error {
|
||||
LM_ERR_ChdirFail = 146,
|
||||
LM_ERR_ExtractRootChdirFail = 147,
|
||||
LM_ERR_ExtractOldChdirFail = 148,
|
||||
LM_ERR_MPTPAcceptFail = 149,
|
||||
} lm_error_t;
|
||||
|
||||
typedef struct lm_error_desc {
|
||||
|
@ -141,9 +141,11 @@ bool lm_mptp_client_send(int sock, lm_mptp_t *packet);
|
||||
bool lm_mptp_client_recv(int sock, lm_mptp_t *packet);
|
||||
|
||||
int lm_mptp_server_listen(char *addr, uint16_t port);
|
||||
int lm_mptp_server_accept(int sock, struct sockaddr *addr);
|
||||
void lm_mptp_server_close(int sock);
|
||||
bool lm_mptp_server_verify(lm_mptp_t *packet);
|
||||
bool lm_mptp_server_recv(int sock, lm_mptp_t *packet, struct sockaddr *addr);
|
||||
bool lm_mptp_server_send(int sock, lm_mptp_t *packet, struct sockaddr *addr);
|
||||
bool lm_mptp_server_recv(int sock, lm_mptp_t *packet);
|
||||
bool lm_mptp_server_send(int sock, lm_mptp_t *packet);
|
||||
|
||||
bool lm_mptp_sendfile(int sock, struct sockaddr *addr, char *path, lm_mptp_transfer_callback_t callback, void *data);
|
||||
bool lm_mptp_sendfile(int sock, char *path, lm_mptp_transfer_callback_t callback, void *data);
|
||||
bool lm_mptp_recvfile(int sock, char *path, lm_mptp_transfer_callback_t callback, void *data);
|
||||
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-08-07 01:28+0300\n"
|
||||
"POT-Creation-Date: 2024-08-07 04:49+0300\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -630,3 +630,8 @@ msgstr ""
|
||||
#: src/error.c:167
|
||||
msgid "failed to change directory back from root during extraction"
|
||||
msgstr ""
|
||||
|
||||
#: src/error.c:168
|
||||
#, c-format
|
||||
msgid "failed to accept the MPTP connection: %s"
|
||||
msgstr ""
|
||||
|
176
src/ctx/serve.c
176
src/ctx/serve.c
@ -12,34 +12,89 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
struct lm_ctx_serve_thread_arg {
|
||||
lm_ctx_serve_callback_t callback;
|
||||
int sock;
|
||||
struct sockaddr addr;
|
||||
lm_mptp_t packet;
|
||||
lm_pool_t *pool;
|
||||
lm_ctx_serve_callback_t callback;
|
||||
lm_ctx_t *ctx;
|
||||
void *data;
|
||||
};
|
||||
|
||||
void __lm_ctx_serve(lm_pool_t *pool, lm_mptp_t *packet, int sock, struct sockaddr *addr) {
|
||||
switch (MPTP_FLAGS_CODE(packet)) {
|
||||
void __lm_ctx_serve_thread(void *_arg) {
|
||||
struct lm_ctx_serve_thread_arg *arg = _arg;
|
||||
bool success = false;
|
||||
lm_mptp_t packet;
|
||||
|
||||
if(!lm_mptp_server_recv(arg->sock, &packet)){
|
||||
pdebug(__func__, "%x: failed to receive packet (%s)", arg->addr, lm_strerror());
|
||||
return lm_mptp_close(arg->sock);
|
||||
}
|
||||
|
||||
if (!lm_mptp_server_verify(&packet)) {
|
||||
pdebug(__func__, "%x: closing connection, failed to verify (%s)", arg->addr, lm_strerror());
|
||||
return lm_mptp_close(arg->sock);
|
||||
}
|
||||
|
||||
char hostname[packet.header.host_size + 1]; // +1 for NULL terminator
|
||||
char path[packet.header.data_size + 1], *ppath = path;
|
||||
|
||||
if (!lm_mptp_get_host(&packet, hostname)) {
|
||||
pdebug(__func__, "%x: closing connection, failed to get hostname (%s)", arg->addr, lm_strerror());
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!lm_mptp_get_data(&packet, path)) {
|
||||
pdebug(__func__, "%x: closing connection, failed to get path (%s)", arg->addr, lm_strerror());
|
||||
goto end;
|
||||
}
|
||||
|
||||
if(MPTP_FLAGS_CODE(&packet) == MPTP_C2S_PULL && (ppath = dirname(path)) == NULL){
|
||||
pdebug(__func__, "%x: closing connection, failed to get dirname (%s)", strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
|
||||
lm_pool_t *pool = lm_ctx_pool_by_url(arg->ctx, hostname, ppath);
|
||||
|
||||
if (NULL == pool) {
|
||||
pdebug(__func__, "%x: unknown pool (%s), closing connection", arg->addr, hostname);
|
||||
lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true);
|
||||
lm_mptp_server_send(arg->sock, &packet);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if(lm_pool_path_is_empty(pool)){
|
||||
pdebug(__func__, "%x: requested pool (%s) have empty paths, closing connection", arg->addr, pool->name);
|
||||
lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true);
|
||||
lm_mptp_server_send(arg->sock, &packet);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if(!pool->loaded){
|
||||
pdebug(__func__, "%x: requested pool (%s) is not loaded, closing connection", arg->addr, pool->name);
|
||||
lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true);
|
||||
lm_mptp_server_send(arg->sock, &packet);
|
||||
goto end;
|
||||
}
|
||||
|
||||
success = true;
|
||||
|
||||
switch (MPTP_FLAGS_CODE(&packet)) {
|
||||
// response PING with PONG
|
||||
case MPTP_C2S_PING:
|
||||
pdebug(__func__, "(%s) PING: returning PONG", pool->name);
|
||||
lm_mptp_init(packet, false, MPTP_S2C_PONG, true);
|
||||
lm_mptp_server_send(sock, packet, addr);
|
||||
pdebug(__func__, "(%x) PING %s: returning PONG", arg->addr, pool->name);
|
||||
lm_mptp_init(&packet, false, MPTP_S2C_PONG, true);
|
||||
lm_mptp_server_send(arg->sock, &packet);
|
||||
break;
|
||||
|
||||
// when INFO file is requested, send the file
|
||||
case MPTP_C2S_INFO:
|
||||
pdebug(__func__, "(%s) INFO: attempting to send info", pool->name);
|
||||
lm_mptp_sendfile(sock, addr, pool->info_file, NULL, NULL);
|
||||
pdebug(__func__, "(%x) INFO %s: attempting to send info", arg->addr, pool->name);
|
||||
lm_mptp_sendfile(arg->sock, pool->info_file, NULL, NULL);
|
||||
break;
|
||||
|
||||
// when LIST file is requested, send the file
|
||||
case MPTP_C2S_LIST:
|
||||
pdebug(__func__, "(%s) LIST: attempting to send list", pool->name);
|
||||
lm_mptp_sendfile(sock, addr, pool->list_file, NULL, NULL);
|
||||
pdebug(__func__, "(%x) LIST %s: attempting to send list", arg->addr, pool->name);
|
||||
lm_mptp_sendfile(arg->sock, pool->list_file, NULL, NULL);
|
||||
break;
|
||||
|
||||
// when the request code is PULL, send the requested package archive and
|
||||
@ -47,25 +102,25 @@ void __lm_ctx_serve(lm_pool_t *pool, lm_mptp_t *packet, int sock, struct sockadd
|
||||
case MPTP_C2S_PULL:
|
||||
// PULL request should contain package path,
|
||||
// if path (stored in the data field) is empty it's an invalid request
|
||||
if(packet->header.data_size <= 0){
|
||||
lm_mptp_init(packet, false, MPTP_S2C_WHAT, true);
|
||||
lm_mptp_server_send(sock, packet, addr);
|
||||
if(packet.header.data_size <= 0){
|
||||
lm_mptp_init(&packet, false, MPTP_S2C_WHAT, true);
|
||||
lm_mptp_server_send(arg->sock, &packet);
|
||||
break;
|
||||
}
|
||||
|
||||
pdebug(__func__, "(%s) PULL: attempting to send package archive and signature", pool->name);
|
||||
char path[packet->header.data_size + 1], *package = path;
|
||||
pdebug(__func__, "(%x) PULL %s: attempting to send package archive and signature", arg->addr, pool->name);
|
||||
char path[packet.header.data_size + 1], *package = path;
|
||||
|
||||
if(!lm_mptp_get_data(packet, path)){
|
||||
if(!lm_mptp_get_data(&packet, path)){
|
||||
// we should never be able to get here, if we do theres definetly a bug
|
||||
pdebug(__func__, "(%s) PULL: skipping, failed to get path: %s", pool->name, lm_strerror());
|
||||
pdebug(__func__, "(%x) PULL %s: skipping, failed to get path: %s", arg->addr, pool->name, lm_strerror());
|
||||
break;
|
||||
}
|
||||
|
||||
// if we can't get the package name, then theres something wrong with the request
|
||||
if((package = basename(path)) == NULL){
|
||||
lm_mptp_init(packet, false, MPTP_S2C_WHAT, true);
|
||||
lm_mptp_server_send(sock, packet, addr);
|
||||
lm_mptp_init(&packet, false, MPTP_S2C_WHAT, true);
|
||||
lm_mptp_server_send(arg->sock, &packet);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -75,30 +130,27 @@ void __lm_ctx_serve(lm_pool_t *pool, lm_mptp_t *packet, int sock, struct sockadd
|
||||
|
||||
// if we can't parse the package name, request is invalid
|
||||
if(!package_parse(package, name, version)){
|
||||
lm_mptp_init(packet, false, MPTP_S2C_WHAT, true);
|
||||
lm_mptp_server_send(sock, packet, addr);
|
||||
lm_mptp_init(&packet, false, MPTP_S2C_WHAT, true);
|
||||
lm_mptp_server_send(arg->sock, &packet);
|
||||
break;
|
||||
}
|
||||
|
||||
// if the package is not found in the pool, tell the client
|
||||
if((pkg = lm_pool_package_find(pool, name, version)) == NULL){
|
||||
lm_mptp_init(packet, false, MPTP_S2C_BRUH, true);
|
||||
lm_mptp_server_send(sock, packet, addr);
|
||||
lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true);
|
||||
lm_mptp_server_send(arg->sock, &packet);
|
||||
break;
|
||||
}
|
||||
|
||||
// send package archive and the signature file
|
||||
lm_mptp_sendfile(sock, addr, pkg->archive, NULL, NULL);
|
||||
lm_mptp_sendfile(sock, addr, pkg->signature, NULL, NULL);
|
||||
lm_mptp_sendfile(arg->sock, pkg->archive, NULL, NULL);
|
||||
lm_mptp_sendfile(arg->sock, pkg->signature, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void __lm_ctx_serve_thread(void *_arg) {
|
||||
struct lm_ctx_serve_thread_arg *arg = _arg;
|
||||
if(NULL != arg->callback && !arg->callback(arg->pool, &arg->packet, &arg->addr, arg->data))
|
||||
return free(arg);
|
||||
__lm_ctx_serve(arg->pool, &arg->packet, arg->sock, &arg->addr);
|
||||
end:
|
||||
if(success && NULL != arg->callback)
|
||||
arg->callback(pool, &packet, &arg->addr, arg->data);
|
||||
free(arg);
|
||||
}
|
||||
|
||||
@ -110,9 +162,8 @@ bool lm_ctx_serve(lm_ctx_t *ctx, char *addr, uint8_t threads, lm_ctx_serve_callb
|
||||
|
||||
char host[strlen(addr)+1];
|
||||
struct sockaddr saddr;
|
||||
lm_mptp_t packet;
|
||||
uint16_t port;
|
||||
int sock;
|
||||
int sock = -1, c = -1;
|
||||
lm_thpool_t tp;
|
||||
|
||||
lm_thpool_init(&tp, threads);
|
||||
@ -128,61 +179,14 @@ bool lm_ctx_serve(lm_ctx_t *ctx, char *addr, uint8_t threads, lm_ctx_serve_callb
|
||||
if ((sock = lm_mptp_server_listen(host, port)) < 0)
|
||||
return false;
|
||||
|
||||
while (lm_mptp_server_recv(sock, &packet, &saddr)) {
|
||||
if (!lm_mptp_server_verify(&packet)) {
|
||||
pdebug(__func__, "skipping packet, failed to verify: %s", lm_strerror());
|
||||
continue;
|
||||
}
|
||||
|
||||
char hostname[packet.header.host_size + 1]; // +1 for NULL terminator
|
||||
char path[packet.header.data_size + 1], *ppath = path;
|
||||
|
||||
if (!lm_mptp_get_host(&packet, hostname)) {
|
||||
pdebug(__func__, "skipping packet, failed to get hostname: %s", lm_strerror());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!lm_mptp_get_data(&packet, path)) {
|
||||
pdebug(__func__, "skipping packet, failed to get path: %s", lm_strerror());
|
||||
continue;
|
||||
}
|
||||
|
||||
if(MPTP_FLAGS_CODE(&packet) == MPTP_C2S_PULL && (ppath = dirname(path)) == NULL){
|
||||
pdebug(__func__, "skipping packet, failed to get dirname: %s", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
lm_pool_t *pool = lm_ctx_pool_by_url(ctx, hostname, ppath);
|
||||
|
||||
if (NULL == pool) {
|
||||
pdebug(__func__, "unknown pool (%s), closing connection", hostname);
|
||||
lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true);
|
||||
lm_mptp_server_send(sock, &packet, &saddr);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(lm_pool_path_is_empty(pool)){
|
||||
pdebug(__func__, "requested pool (%s) have empty paths, closing connection", pool->name);
|
||||
lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true);
|
||||
lm_mptp_server_send(sock, &packet, &saddr);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!pool->loaded){
|
||||
pdebug(__func__, "requested pool (%s) is not loaded, closing connection", pool->name);
|
||||
lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true);
|
||||
lm_mptp_server_send(sock, &packet, &saddr);
|
||||
continue;
|
||||
}
|
||||
|
||||
while ((c = lm_mptp_server_accept(sock, &saddr)) < 0) {
|
||||
struct lm_ctx_serve_thread_arg *arg = malloc(sizeof(struct lm_ctx_serve_thread_arg));
|
||||
|
||||
memcpy(&arg->addr, &saddr, sizeof(struct sockaddr));
|
||||
lm_mptp_copy(&arg->packet, &packet);
|
||||
|
||||
arg->ctx = ctx;
|
||||
arg->callback = callback;
|
||||
arg->data = data;
|
||||
arg->pool = pool;
|
||||
arg->sock = sock;
|
||||
arg->sock = c;
|
||||
|
||||
pdebug(__func__, "adding new connection to the pool");
|
||||
lm_thpool_add(&tp, __lm_ctx_serve_thread, arg);
|
||||
|
@ -165,6 +165,7 @@ void lm_error_set(lm_error_t code, ...) {
|
||||
{.code = LM_ERR_ChdirFail, .desc = _("failed change directory: %s") },
|
||||
{.code = LM_ERR_ExtractRootChdirFail, .desc = _("failed to change directory to root during extraction") },
|
||||
{.code = LM_ERR_ExtractOldChdirFail, .desc = _("failed to change directory back from root during extraction")},
|
||||
{.code = LM_ERR_MPTPAcceptFail, .desc = _("failed to accept the MPTP connection: %s") },
|
||||
};
|
||||
|
||||
char *fmt = NULL;
|
||||
|
@ -108,7 +108,7 @@ int lm_mptp_socket(char *addr, uint16_t port, struct sockaddr *saddr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((sock = socket(family, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
|
||||
if ((sock = socket(family, AF_INET, SOCK_STREAM)) < 0) {
|
||||
lm_error_set(LM_ERR_MPTPSocketFail);
|
||||
return -1;
|
||||
}
|
||||
|
@ -2,8 +2,10 @@
|
||||
#include "../../include/mptp.h"
|
||||
#include "../../include/util.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
int lm_mptp_server_listen(char *addr, uint16_t port) {
|
||||
struct sockaddr saddr;
|
||||
@ -23,6 +25,22 @@ int lm_mptp_server_listen(char *addr, uint16_t port) {
|
||||
return sock;
|
||||
}
|
||||
|
||||
int lm_mptp_server_accept(int sock, struct sockaddr *addr){
|
||||
socklen_t sl = sizeof(struct sockaddr);
|
||||
int s = -1;
|
||||
|
||||
if((s = accept(sock, addr, &sl) < 0)){
|
||||
lm_error_set(LM_ERR_MPTPAcceptFail, strerror(errno));
|
||||
s = -1;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void lm_mptp_server_close(int sock){
|
||||
close(sock); // you didn't see that comming, did you?
|
||||
}
|
||||
|
||||
bool lm_mptp_server_verify(lm_mptp_t *packet) {
|
||||
if (!lm_mptp_verify(packet))
|
||||
return false;
|
||||
@ -45,20 +63,19 @@ bool lm_mptp_server_verify(lm_mptp_t *packet) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lm_mptp_server_recv(int sock, lm_mptp_t *packet, struct sockaddr *addr) {
|
||||
if (NULL == packet || NULL == addr) {
|
||||
bool lm_mptp_server_recv(int sock, lm_mptp_t *packet) {
|
||||
if (NULL == packet) {
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
char buffer[sizeof(packet->header) + MPTP_HOST_MAX + MPTP_DATA_MAX];
|
||||
socklen_t socklen = sizeof(struct sockaddr);
|
||||
ssize_t total = sizeof(buffer), used = 0;
|
||||
|
||||
bzero(buffer, sizeof(buffer));
|
||||
bzero(packet, sizeof(lm_mptp_t));
|
||||
|
||||
if (recvfrom(sock, buffer, sizeof(buffer), 0, addr, &socklen) <= 0) {
|
||||
if (recv(sock, buffer, sizeof(buffer), 0) <= 0) {
|
||||
lm_error_set(LM_ERR_MPTPRecvFail);
|
||||
return false;
|
||||
}
|
||||
@ -77,7 +94,7 @@ bool lm_mptp_server_recv(int sock, lm_mptp_t *packet, struct sockaddr *addr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lm_mptp_server_send(int sock, lm_mptp_t *packet, struct sockaddr *addr) {
|
||||
bool lm_mptp_server_send(int sock, lm_mptp_t *packet) {
|
||||
if (NULL == packet) {
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return false;
|
||||
@ -98,7 +115,6 @@ bool lm_mptp_server_send(int sock, lm_mptp_t *packet, struct sockaddr *addr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
socklen_t addrlen = sizeof(struct sockaddr);
|
||||
char buffer[sizeof(packet->header) + packet->header.host_size + packet->header.data_size];
|
||||
ssize_t total = sizeof(buffer), used = 0;
|
||||
|
||||
@ -108,7 +124,7 @@ bool lm_mptp_server_send(int sock, lm_mptp_t *packet, struct sockaddr *addr) {
|
||||
copy_to_buffer(buffer, packet->host, packet->header.host_size, &total, &used);
|
||||
copy_to_buffer(buffer, packet->data, packet->header.data_size, &total, &used);
|
||||
|
||||
if (sendto(sock, buffer, sizeof(buffer), 0, addr, addrlen) < 0) {
|
||||
if (send(sock, buffer, sizeof(buffer), 0) < 0) {
|
||||
lm_error_set(LM_ERR_MPTPSendFail);
|
||||
return false;
|
||||
}
|
||||
|
@ -9,8 +9,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
bool lm_mptp_sendfile(int sock, struct sockaddr *addr, char *path, lm_mptp_transfer_callback_t callback, void *data){
|
||||
if (NULL == path || NULL == addr){
|
||||
bool lm_mptp_sendfile(int sock, char *path, lm_mptp_transfer_callback_t callback, void *data){
|
||||
if (NULL == path){
|
||||
lm_error_set(LM_ERR_ArgNULL);
|
||||
return false;
|
||||
}
|
||||
@ -49,7 +49,7 @@ bool lm_mptp_sendfile(int sock, struct sockaddr *addr, char *path, lm_mptp_trans
|
||||
}
|
||||
|
||||
packet.header.data_size = size;
|
||||
lm_mptp_server_send(sock, &packet, addr);
|
||||
lm_mptp_server_send(sock, &packet);
|
||||
|
||||
if(NULL != callback)
|
||||
if(!callback(path, current, total, data))
|
||||
@ -60,7 +60,7 @@ bool lm_mptp_sendfile(int sock, struct sockaddr *addr, char *path, lm_mptp_trans
|
||||
|
||||
while ((read = fread(packet.data, 1, MPTP_DATA_MAX, file)) > 0) {
|
||||
packet.header.data_size = read;
|
||||
if(!lm_mptp_server_send(sock, &packet, addr))
|
||||
if(!lm_mptp_server_send(sock, &packet))
|
||||
goto end;
|
||||
|
||||
current += read;
|
||||
@ -85,7 +85,7 @@ bool lm_mptp_sendfile(int sock, struct sockaddr *addr, char *path, lm_mptp_trans
|
||||
end:
|
||||
if(NULL != file)
|
||||
fclose(file);
|
||||
lm_mptp_server_send(sock, &packet, addr);
|
||||
lm_mptp_server_send(sock, &packet);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user