From 88a396d52fbd45016e9ea559b12d5af4bf60133e Mon Sep 17 00:00:00 2001 From: ngn Date: Sun, 23 Jun 2024 01:55:01 +0300 Subject: [PATCH] update: add host info to the MPTP packets --- examples/pool/main.c | 4 +- examples/server/main.c | 4 +- include/error.h | 24 +++--- include/libmp.h | 6 ++ include/mptp.h | 37 ++++++--- include/pool.h | 10 +-- include/types.h | 8 ++ include/url.h | 1 - include/util.h | 3 + locale/tr/LC_MESSAGES/libmp.po | 27 ++++-- src/error.c | 64 +++++++------- src/libmp.c | 132 ++++++++++++++++++++++++++++- src/mptp.c | 135 ++++++++++++++++++++++-------- src/pool.c | 148 +++++++++------------------------ src/url.c | 22 +++-- src/util.c | 36 ++++++-- 16 files changed, 424 insertions(+), 237 deletions(-) diff --git a/examples/pool/main.c b/examples/pool/main.c index 69adfd6..0f31981 100644 --- a/examples/pool/main.c +++ b/examples/pool/main.c @@ -15,12 +15,12 @@ int main(int argc, char *argv[]) { ctx.debug = true; - if (!lm_ctx_pool_add(&ctx, "test", argv[1])) { + if (!lm_ctx_pools_add(&ctx, "test", argv[1])) { printf("failed to add pool: %s (%d)\n", lm_strerror(), lm_error()); goto end; } - lm_ctx_pool_test(&ctx); + lm_ctx_pools_test(&ctx); ret = EXIT_SUCCESS; end: diff --git a/examples/server/main.c b/examples/server/main.c index c3298db..80b0068 100644 --- a/examples/server/main.c +++ b/examples/server/main.c @@ -16,12 +16,12 @@ int main(int argc, char *argv[]) { ctx.debug = true; - if (!lm_ctx_pool_add(&ctx, "test", NULL)) { + if (!lm_ctx_pools_add(&ctx, "test", "mptp://127.0.0.1:5858")) { printf("failed to add pool: %s (%d)\n", lm_strerror(), lm_error()); goto end; } - if(!lm_ctx_pool_serve(&ctx, argv[1])) { + if (!lm_ctx_pools_serve(&ctx, argv[1])) { printf("failed to serve the pools: %s (%d)\n", lm_strerror(), lm_error()); goto end; } diff --git a/include/error.h b/include/error.h index 218f5d3..596a006 100644 --- a/include/error.h +++ b/include/error.h @@ -11,8 +11,8 @@ typedef enum lm_error { LM_ERR_URLBadPort = 7, LM_ERR_URLBadPath = 8, LM_ERR_URLPortUnknown = 9, - LM_ERR_BadPort = 10, - LM_ERR_BadHost = 11, + LM_ERR_BadPort = 10, + LM_ERR_BadHost = 11, LM_ERR_PoolNoSupport = 12, LM_ERR_URLEnd = 13, LM_ERR_MPTPBadVersion = 14, @@ -23,15 +23,17 @@ typedef enum lm_error { LM_ERR_MPTPConnectFail = 19, LM_ERR_MPTPRecvFail = 20, LM_ERR_MPTPSendFail = 21, - LM_ERR_MPTPBadChunk = 22, - LM_ERR_MPTPSetsockopt = 23, - LM_ERR_MPTPTimeout = 24, - LM_ERR_MPTPBindFail = 25, - LM_ERR_ArgNULL = 26, - LM_ERR_MPTPNotResponse = 27, - LM_ERR_MPTPNotRequest = 28, - LM_ERR_MPTPNotLast = 29, - LM_ERR_NoPort = 30, + LM_ERR_MPTPBadData = 22, + LM_ERR_MPTPBadHost = 23, + LM_ERR_MPTPSetsockopt = 24, + LM_ERR_MPTPTimeout = 25, + LM_ERR_MPTPBindFail = 26, + LM_ERR_ArgNULL = 27, + LM_ERR_MPTPNotResponse = 28, + LM_ERR_MPTPNotRequest = 29, + LM_ERR_MPTPNotLast = 30, + LM_ERR_NoPort = 31, + LM_ERR_PoolInfoBad = 32, } lm_error_t; typedef struct lm_error_desc { diff --git a/include/libmp.h b/include/libmp.h index 7fff84e..527237d 100644 --- a/include/libmp.h +++ b/include/libmp.h @@ -3,3 +3,9 @@ void lm_ctx_init(lm_ctx_t *ctx); void lm_ctx_free(lm_ctx_t *ctx); + +lm_pool_t *lm_ctx_pools_add(lm_ctx_t *ctx, char *name, char *url); +bool lm_ctx_pools_del(lm_ctx_t *ctx, char *name); +void lm_ctx_pools_clear(lm_ctx_t *ctx); +void lm_ctx_pools_test(lm_ctx_t *ctx); +bool lm_ctx_pools_serve(lm_ctx_t *ctx, char *addr); diff --git a/include/mptp.h b/include/mptp.h index 647e794..0ebd45d 100644 --- a/include/mptp.h +++ b/include/mptp.h @@ -12,8 +12,9 @@ ##################################### # FLAGS # ##################################### - # SIZE # + # HOST SIZE | DATA SIZE # ##################################### + # HOST # # DATA # #...................................# @@ -51,17 +52,26 @@ --------------------------------------------------------- - [16 bits] SIZE + [8 bits] HOST SIZE ========================================================= - | All bits used for specifying the DATA size, in bytes + | All bits used for specifying HOST size --------------------------------------------------------- + [8 bits] DATA SIZE + ========================================================= + | 8 bits used for specifying DATA size + --------------------------------------------------------- + + [...] HOST + --------------------------------------------------------- + | Plaintext server hostname, max size is 255 octets + | see the SIZE section + --------------------------------------------------------- [...] DATA --------------------------------------------------------- | Plaintext data used for that specific request/response, - | max value for SIZE is 65535, so this section may have - | 65535 bytes total + | max size is 255 octets, see the SIZE section --------------------------------------------------------- */ @@ -69,8 +79,9 @@ // clang-format on #define MPTP_VERSION_SUPPORTED 0 -#define MPTP_CODE_MAX 3 // 2 bits -#define MPTP_CHUNK_MAX 256 +#define MPTP_CODE_MAX 3 +#define MPTP_DATA_MAX UINT8_MAX +#define MPTP_HOST_MAX UINT8_MAX #define MPTP_TIMEOUT 10 #define MPTP_REQUEST 0 @@ -92,12 +103,14 @@ typedef enum lm_mptp_response { typedef struct lm_mptp_header { uint16_t flags; - uint16_t size; + uint8_t host_size; + uint8_t data_size; } lm_mptp_header_t; typedef struct lm_mptp { lm_mptp_header_t header; - char data[MPTP_CHUNK_MAX]; + char host[MPTP_DATA_MAX]; + char data[MPTP_DATA_MAX]; } lm_mptp_t; #define MPTP_FLAGS_VERSION(m) (((m)->header.flags & 0xFF00) >> 8) @@ -108,7 +121,11 @@ typedef struct lm_mptp { #define MPTP_IS_REQUEST(m) (MPTP_FLAGS_TYPE(m) == 0) #define MPTP_IS_LAST(m) (MPTP_FLAGS_LAST(m) == 1) -bool lm_mptp_packet_init(lm_mptp_t *packet, bool is_request, uint8_t code, bool is_last); +bool lm_mptp_init(lm_mptp_t *packet, bool is_request, uint8_t code, bool is_last); +bool lm_mptp_set_data(lm_mptp_t *packet, char *data, size_t size); +bool lm_mptp_set_host(lm_mptp_t *packet, char *host); +bool lm_mptp_get_host(lm_mptp_t *packet, char *host); + int lm_mptp_socket(char *addr, uint16_t port, struct sockaddr *saddr); bool lm_mptp_verify(lm_mptp_t *packet); void lm_mptp_close(int sock); diff --git a/include/pool.h b/include/pool.h index 12a945c..750b169 100644 --- a/include/pool.h +++ b/include/pool.h @@ -2,8 +2,8 @@ #include "types.h" #include -bool lm_ctx_pool_add(lm_ctx_t *ctx, char *name, char *url); -bool lm_ctx_pool_del(lm_ctx_t *ctx, char *name); -void lm_ctx_pool_clear(lm_ctx_t *ctx); -void lm_ctx_pool_test(lm_ctx_t *ctx); -bool lm_ctx_pool_serve(lm_ctx_t *ctx, char *addr); +lm_pool_t *lm_pool_new(char *name, char *url); +void lm_pool_test(lm_pool_t *pool); +bool lm_pool_info_file(lm_pool_t *pool, char *file); +bool lm_pool_info(lm_pool_t *pool, char *info); +void lm_pool_free(lm_pool_t *pool); diff --git a/include/types.h b/include/types.h index b206941..d73fbe0 100644 --- a/include/types.h +++ b/include/types.h @@ -1,9 +1,17 @@ #pragma once #include "url.h" #include +#include + +typedef struct lm_pool_info { + char *maintainer; + char *pubkey; + size_t size; +} lm_pool_info_t; typedef struct lm_pool { struct lm_pool *next; + lm_pool_info_t info; lm_url_t url; bool available; char *name; diff --git a/include/url.h b/include/url.h index fd09ea8..e67655a 100644 --- a/include/url.h +++ b/include/url.h @@ -11,7 +11,6 @@ typedef struct lm_url { char protocol[URL_PROTOCOL_MAX + 1]; char *host; char *path; - bool empty; } lm_url_t; bool lm_url_init(lm_url_t *url, char *str); diff --git a/include/util.h b/include/util.h index 1991209..6dcee32 100644 --- a/include/util.h +++ b/include/util.h @@ -2,6 +2,7 @@ #include "types.h" #include #include +#include #define _(x) gettext(x) @@ -11,3 +12,5 @@ bool contains(char *str, char s); bool eq(char *s1, char *s2); bool is_letter(char c); bool is_digit(char c); +bool copy_to_buffer(void *buffer, void *src, size_t size, ssize_t *total, ssize_t *used); +bool copy_from_buffer(void *dst, void *buffer, size_t size, ssize_t *total, ssize_t *used); diff --git a/locale/tr/LC_MESSAGES/libmp.po b/locale/tr/LC_MESSAGES/libmp.po index 3cbdf0b..1c38edd 100644 --- a/locale/tr/LC_MESSAGES/libmp.po +++ b/locale/tr/LC_MESSAGES/libmp.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-06-22 07:00+0300\n" +"POT-Creation-Date: 2024-06-23 01:52+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -111,37 +111,46 @@ msgstr "" #: src/error.c:35 #, fuzzy -msgid "MPTP data chunk size is invalid" +msgid "MPTP data size is invalid" msgstr "URL path is too large" #: src/error.c:36 +#, fuzzy +msgid "MPTP host size is invalid" +msgstr "URL path is too large" + +#: src/error.c:37 msgid "failed to set MPTP socket options" msgstr "" -#: src/error.c:37 +#: src/error.c:38 msgid "MPTP connection timed out" msgstr "" -#: src/error.c:38 +#: src/error.c:39 msgid "failed to bind MPTP socket" msgstr "" -#: src/error.c:39 +#: src/error.c:40 msgid "required argument is a NULL pointer" msgstr "" -#: src/error.c:40 +#: src/error.c:41 msgid "not a MPTP request" msgstr "" -#: src/error.c:41 +#: src/error.c:42 msgid "not a MPTP response" msgstr "" -#: src/error.c:42 +#: src/error.c:43 msgid "MPTP request last flag is not set" msgstr "" -#: src/error.c:43 +#: src/error.c:44 msgid "host port not specified" msgstr "" + +#: src/error.c:45 +msgid "failed to parse pool info" +msgstr "" diff --git a/src/error.c b/src/error.c index a4c214c..97239b7 100644 --- a/src/error.c +++ b/src/error.c @@ -10,37 +10,39 @@ void lm_error_set(lm_error_t code) { char *lm_strerror() { lm_error_desc_t errors[] = { - {.code = LM_ERR_NoError, .desc = _("no error") }, - {.code = LM_ERR_URLBadChar, .desc = _("URL contains an invalid character") }, - {.code = LM_ERR_URLBadProtocol, .desc = _("URL does not have a valid protocol field") }, - {.code = LM_ERR_URLTooLarge, .desc = _("URL is too large") }, - {.code = LM_ERR_URLHostLarge, .desc = _("URL hostname is too large") }, - {.code = LM_ERR_URLPathLarge, .desc = _("URL path is too large") }, - {.code = LM_ERR_URLBadHost, .desc = _("URL does not have a valid hostname") }, - {.code = LM_ERR_URLBadPort, .desc = _("URL does not have a valid port number") }, - {.code = LM_ERR_URLBadPath, .desc = _("URL does not have a valid path") }, - {.code = LM_ERR_BadPort, .desc = _("hostname does not contain a valid port number")}, - {.code = LM_ERR_BadHost, .desc = _("hostname is not valid")}, - {.code = LM_ERR_URLPortUnknown, .desc = _("URL protocol port number is unknown") }, - {.code = LM_ERR_URLEnd, .desc = _("URL is incomplete") }, - {.code = LM_ERR_PoolNoSupport, .desc = _("pool does not support the specified protocol") }, - {.code = LM_ERR_MPTPBadVersion, .desc = _("unsupported MPTP version") }, - {.code = LM_ERR_MPTPBadCode, .desc = _("invalid MPTP request/response code") }, - {.code = LM_ERR_MPTPBadUrl, .desc = _("invalid MPTP URL") }, - {.code = LM_ERR_MPTPHostFail, .desc = _("failed to resolve hostname for MPTP connection") }, - {.code = LM_ERR_MPTPSocketFail, .desc = _("failed to create a MPTP socket") }, - {.code = LM_ERR_MPTPConnectFail, .desc = _("failed to connect to the MPTP host") }, - {.code = LM_ERR_MPTPRecvFail, .desc = _("failed receive MPTP data from host") }, - {.code = LM_ERR_MPTPSendFail, .desc = _("failed send MPTP data to host") }, - {.code = LM_ERR_MPTPBadChunk, .desc = _("MPTP data chunk size is invalid") }, - {.code = LM_ERR_MPTPSetsockopt, .desc = _("failed to set MPTP socket options") }, - {.code = LM_ERR_MPTPTimeout, .desc = _("MPTP connection timed out") }, - {.code = LM_ERR_MPTPBindFail, .desc = _("failed to bind MPTP socket") }, - {.code = LM_ERR_ArgNULL, .desc = _("required argument is a NULL pointer") }, - {.code = LM_ERR_MPTPNotRequest, .desc = _("not a MPTP request") }, - {.code = LM_ERR_MPTPNotResponse, .desc = _("not a MPTP response") }, - {.code = LM_ERR_MPTPNotLast, .desc = _("MPTP request last flag is not set") }, - {.code = LM_ERR_NoPort, .desc = _("host port not specified") }, + {.code = LM_ERR_NoError, .desc = _("no error") }, + {.code = LM_ERR_URLBadChar, .desc = _("URL contains an invalid character") }, + {.code = LM_ERR_URLBadProtocol, .desc = _("URL does not have a valid protocol field") }, + {.code = LM_ERR_URLTooLarge, .desc = _("URL is too large") }, + {.code = LM_ERR_URLHostLarge, .desc = _("URL hostname is too large") }, + {.code = LM_ERR_URLPathLarge, .desc = _("URL path is too large") }, + {.code = LM_ERR_URLBadHost, .desc = _("URL does not have a valid hostname") }, + {.code = LM_ERR_URLBadPort, .desc = _("URL does not have a valid port number") }, + {.code = LM_ERR_URLBadPath, .desc = _("URL does not have a valid path") }, + {.code = LM_ERR_BadPort, .desc = _("hostname does not contain a valid port number") }, + {.code = LM_ERR_BadHost, .desc = _("hostname is not valid") }, + {.code = LM_ERR_URLPortUnknown, .desc = _("URL protocol port number is unknown") }, + {.code = LM_ERR_URLEnd, .desc = _("URL is incomplete") }, + {.code = LM_ERR_PoolNoSupport, .desc = _("pool does not support the specified protocol") }, + {.code = LM_ERR_MPTPBadVersion, .desc = _("unsupported MPTP version") }, + {.code = LM_ERR_MPTPBadCode, .desc = _("invalid MPTP request/response code") }, + {.code = LM_ERR_MPTPBadUrl, .desc = _("invalid MPTP URL") }, + {.code = LM_ERR_MPTPHostFail, .desc = _("failed to resolve hostname for MPTP connection")}, + {.code = LM_ERR_MPTPSocketFail, .desc = _("failed to create a MPTP socket") }, + {.code = LM_ERR_MPTPConnectFail, .desc = _("failed to connect to the MPTP host") }, + {.code = LM_ERR_MPTPRecvFail, .desc = _("failed receive MPTP data from host") }, + {.code = LM_ERR_MPTPSendFail, .desc = _("failed send MPTP data to host") }, + {.code = LM_ERR_MPTPBadData, .desc = _("MPTP data size is invalid") }, + {.code = LM_ERR_MPTPBadHost, .desc = _("MPTP host size is invalid") }, + {.code = LM_ERR_MPTPSetsockopt, .desc = _("failed to set MPTP socket options") }, + {.code = LM_ERR_MPTPTimeout, .desc = _("MPTP connection timed out") }, + {.code = LM_ERR_MPTPBindFail, .desc = _("failed to bind MPTP socket") }, + {.code = LM_ERR_ArgNULL, .desc = _("required argument is a NULL pointer") }, + {.code = LM_ERR_MPTPNotRequest, .desc = _("not a MPTP request") }, + {.code = LM_ERR_MPTPNotResponse, .desc = _("not a MPTP response") }, + {.code = LM_ERR_MPTPNotLast, .desc = _("MPTP request last flag is not set") }, + {.code = LM_ERR_NoPort, .desc = _("host port not specified") }, + {.code = LM_ERR_PoolInfoBad, .desc = _("failed to parse pool info") }, }; for (int i = 0; i < sizeof(errors) / sizeof(lm_error_desc_t); i++) { diff --git a/src/libmp.c b/src/libmp.c index d3654d3..eb75406 100644 --- a/src/libmp.c +++ b/src/libmp.c @@ -23,10 +23,14 @@ // clang-format on #include "../include/libmp.h" +#include "../include/error.h" +#include "../include/mptp.h" #include "../include/pool.h" +#include "../include/util.h" #include #include #include +#include void lm_ctx_init(lm_ctx_t *ctx) { setlocale(LC_ALL, ""); @@ -39,7 +43,133 @@ void lm_ctx_init(lm_ctx_t *ctx) { ctx->debug = false; } +lm_pool_t *lm_ctx_pools_add(lm_ctx_t *ctx, char *name, char *url) { + lm_pool_t *pool = lm_pool_new(name, url); + if (NULL == pool) + return false; + + pdebug(ctx, __func__, "pool name is %s", pool->name); + pdebug(ctx, __func__, "pool URL is %s://%s:%d%s", pool->url.protocol, pool->url.host, pool->url.port, pool->url.path); + + if (NULL == ctx->pools) { + ctx->pools = pool; + return pool; + } + + lm_pool_t *cur = ctx->pools; + while (NULL != cur) { + if (NULL == cur->next) { + cur->next = pool; + return pool; + } + cur = cur->next; + } + + lm_pool_free(pool); + return NULL; +} + +void lm_ctx_pools_clear(lm_ctx_t *ctx) { + lm_pool_t *cur = ctx->pools, *prev = NULL; + while (NULL != cur) { + prev = cur; + cur = cur->next; + lm_pool_free(prev); + } + + ctx->pools = NULL; +} + +void lm_ctx_pools_test(lm_ctx_t *ctx) { + lm_pool_t *cur = ctx->pools; + while (NULL != cur) { + lm_pool_test(cur); + if (!cur->available) + pdebug(ctx, __func__, "%s is not avaliable: %s", cur->name, lm_strerror()); + cur = cur->next; + } +} + +lm_pool_t *lm_ctx_pools_find(lm_ctx_t *ctx, char *name) { + lm_pool_t *cur = ctx->pools; + while (NULL != cur) { + if (eq(cur->name, name)) + return cur; + cur = cur->next; + } + return NULL; +} + +bool lm_ctx_pools_have_host(lm_ctx_t *ctx, char *host) { + lm_pool_t *cur = ctx->pools; + while (NULL != cur) { + if (eq(cur->url.host, host)) + return true; + cur = cur->next; + } + return false; +} + +bool lm_ctx_pools_serve(lm_ctx_t *ctx, char *addr) { + struct sockaddr saddr; + char *host = NULL; + lm_mptp_t packet; + uint16_t port; + int sock; + + if (!parse_host(addr, host, &port)) + return false; + + if (port == 0) { + lm_error_set(LM_ERR_NoPort); + return false; + } + + if ((sock = lm_mptp_server_listen(addr, port)) < 0) + return false; + + while (lm_mptp_server_recv(sock, &packet, &saddr)) { + if (!lm_mptp_server_verify(&packet)) { + pdebug(ctx, __func__, "skipping packet, failed to verify: %s", lm_strerror()); + continue; + } + + char hostname[packet.header.host_size + 1]; // +1 for NULL terminator + if (!lm_mptp_get_host(&packet, hostname)) { + pdebug(ctx, __func__, "skipping packet, failed to get hostname: %s", lm_strerror()); + continue; + } + + if (!lm_ctx_pools_have_host(ctx, hostname)) { + pdebug(ctx, __func__, "unknown hostname, closing connection: %s", hostname); + lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true); + goto end; + } + + switch (MPTP_FLAGS_CODE(&packet)) { + case MPTP_C2S_PING: + lm_mptp_init(&packet, false, MPTP_S2C_PONG, true); + goto end; + + case MPTP_C2S_INFO: + if (packet.header.data_size <= 0) { + lm_mptp_init(&packet, false, MPTP_S2C_WHAT, true); + goto end; + } + + lm_mptp_init(&packet, false, MPTP_S2C_COOL, true); + // send pool info + } + + end: + lm_mptp_set_host(&packet, hostname); + lm_mptp_server_send(sock, &packet, &saddr); + } + + return true; +} + void lm_ctx_free(lm_ctx_t *ctx) { - lm_ctx_pool_clear(ctx); + lm_ctx_pools_clear(ctx); return; } diff --git a/src/mptp.c b/src/mptp.c index a6705ee..b570cd5 100644 --- a/src/mptp.c +++ b/src/mptp.c @@ -1,6 +1,7 @@ #include "../include/mptp.h" #include "../include/error.h" #include "../include/url.h" +#include "../include/util.h" #include #include #include @@ -12,10 +13,13 @@ #include #include -bool lm_mptp_packet_init(lm_mptp_t *packet, bool is_request, uint8_t code, bool is_last) { - packet->header.flags = 0; - packet->header.size = 0; - bzero(packet->data, MPTP_CHUNK_MAX); +bool lm_mptp_init(lm_mptp_t *packet, bool is_request, uint8_t code, bool is_last) { + packet->header.flags = 0; + packet->header.data_size = 0; + packet->header.host_size = 0; + + bzero(packet->data, MPTP_DATA_MAX); + bzero(packet->host, MPTP_HOST_MAX); if (code > MPTP_CODE_MAX) { lm_error_set(LM_ERR_MPTPBadCode); @@ -39,7 +43,43 @@ bool lm_mptp_packet_init(lm_mptp_t *packet, bool is_request, uint8_t code, bool return true; } -bool lm_mptp_verify(lm_mptp_t *packet){ +bool lm_mptp_set_host(lm_mptp_t *packet, char *host) { + size_t size = strlen(host); + if (size > MPTP_HOST_MAX || size <= 0) { + lm_error_set(LM_ERR_MPTPBadHost); + return false; + } + + // do NOT copy the NULL terminator + packet->header.host_size = size; + memcpy(packet->host, host, size); + return true; +} + +bool lm_mptp_get_host(lm_mptp_t *packet, char *host) { + if (packet->header.host_size > MPTP_HOST_MAX || packet->header.host_size <= 0) { + host = NULL; + lm_error_set(LM_ERR_BadHost); + return false; + } + + memcpy(host, packet->host, packet->header.host_size); + host[packet->header.host_size] = 0; + return true; +} + +bool lm_mptp_set_data(lm_mptp_t *packet, char *data, size_t size) { + if (size > MPTP_DATA_MAX || size < 0) { + lm_error_set(LM_ERR_MPTPBadData); + return false; + } + + packet->header.data_size = size; + mempcpy(packet->data, data, size); + return true; +} + +bool lm_mptp_verify(lm_mptp_t *packet) { if (NULL == packet) { lm_error_set(LM_ERR_ArgNULL); return false; @@ -50,8 +90,13 @@ bool lm_mptp_verify(lm_mptp_t *packet){ return false; } - if (packet->header.size > MPTP_CHUNK_MAX || packet->header.size < 0) { - lm_error_set(LM_ERR_MPTPBadChunk); + if (packet->header.data_size > MPTP_DATA_MAX || packet->header.data_size < 0) { + lm_error_set(LM_ERR_MPTPBadData); + return false; + } + + if (packet->header.host_size > MPTP_HOST_MAX || packet->header.host_size <= 0) { + lm_error_set(LM_ERR_MPTPBadHost); return false; } @@ -176,20 +221,24 @@ bool lm_mptp_client_send(int sock, lm_mptp_t *packet) { return false; } - if (packet->header.size > MPTP_CHUNK_MAX) { - lm_error_set(LM_ERR_MPTPBadChunk); + if (packet->header.data_size > MPTP_DATA_MAX) { + lm_error_set(LM_ERR_MPTPBadData); return false; } - char buffer[sizeof(packet->header) + packet->header.size]; - bzero(buffer, sizeof(buffer)); + if (packet->header.host_size > MPTP_HOST_MAX || packet->header.host_size <= 0) { + lm_error_set(LM_ERR_MPTPBadHost); + return false; + } - if (packet->header.size > 0) - memcpy(buffer + sizeof(packet->header), packet->data, packet->header.size); + char buffer[sizeof(packet->header) + packet->header.host_size + packet->header.data_size]; + ssize_t total = sizeof(buffer), used = 0; packet->header.flags = htons(packet->header.flags); - packet->header.size = htons(packet->header.size); - memcpy(buffer, &packet->header, sizeof(packet->header)); + + copy_to_buffer(buffer, &packet->header, sizeof(packet->header), &total, &used); + 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 (send(sock, buffer, sizeof(buffer), 0) < 0) { lm_error_set(LM_ERR_MPTPSendFail); @@ -205,8 +254,11 @@ bool lm_mptp_client_recv(int sock, lm_mptp_t *packet) { return false; } - char buffer[sizeof(packet->header) + MPTP_CHUNK_MAX]; + char buffer[sizeof(packet->header) + MPTP_HOST_MAX + MPTP_DATA_MAX]; + ssize_t total = sizeof(buffer), used = 0; + bzero(buffer, sizeof(buffer)); + bzero(packet, sizeof(lm_mptp_t)); if (recv(sock, buffer, sizeof(buffer), 0) < 0) { if (ETIMEDOUT == errno || EAGAIN == errno) { @@ -217,14 +269,17 @@ bool lm_mptp_client_recv(int sock, lm_mptp_t *packet) { return false; } - memcpy(&packet->header, buffer, sizeof(packet->header)); + copy_from_buffer(&packet->header, buffer, sizeof(packet->header), &total, &used); packet->header.flags = ntohs(packet->header.flags); - packet->header.size = ntohs(packet->header.size); + // packet->header.host_size = ntohs(packet->header.host_size); + // packet->header.data_size = ntohs(packet->header.data_size); - if (packet->header.size > MPTP_CHUNK_MAX) - return true; + if (packet->header.host_size <= MPTP_HOST_MAX) + copy_from_buffer(&packet->host, buffer, packet->header.host_size, &total, &used); + + if (packet->header.data_size <= MPTP_DATA_MAX) + copy_from_buffer(&packet->data, buffer, packet->header.data_size, &total, &used); - memcpy(packet->data, buffer + sizeof(packet->header), packet->header.size); return true; } @@ -255,7 +310,7 @@ bool lm_mptp_server_verify(lm_mptp_t *packet) { return false; } - if(!MPTP_IS_LAST(packet)){ + if (!MPTP_IS_LAST(packet)) { lm_error_set(LM_ERR_MPTPNotLast); return false; } @@ -269,8 +324,9 @@ bool lm_mptp_server_recv(int sock, lm_mptp_t *packet, struct sockaddr *addr) { return false; } + char buffer[sizeof(packet->header) + MPTP_HOST_MAX + MPTP_DATA_MAX]; socklen_t socklen = sizeof(struct sockaddr); - char buffer[sizeof(packet->header) + MPTP_CHUNK_MAX]; + ssize_t total = sizeof(buffer), used = 0; bzero(buffer, sizeof(buffer)); bzero(packet, sizeof(lm_mptp_t)); @@ -280,14 +336,17 @@ bool lm_mptp_server_recv(int sock, lm_mptp_t *packet, struct sockaddr *addr) { return false; } - memcpy(&packet->header, buffer, sizeof(packet->header)); + copy_from_buffer(&packet->header, buffer, sizeof(packet->header), &total, &used); packet->header.flags = ntohs(packet->header.flags); - packet->header.size = ntohs(packet->header.size); + // packet->header.host_size = ntohs(packet->header.host_size); + // packet->header.data_size = ntohs(packet->header.data_size); - if (packet->header.size > MPTP_CHUNK_MAX) - return true; + if (packet->header.host_size <= MPTP_HOST_MAX) + copy_from_buffer(&packet->host, buffer, packet->header.host_size, &total, &used); + + if (packet->header.data_size <= MPTP_DATA_MAX) + copy_from_buffer(&packet->data, buffer, packet->header.data_size, &total, &used); - memcpy(packet->data, buffer + sizeof(packet->header), sizeof(packet->header)); return true; } @@ -302,21 +361,25 @@ bool lm_mptp_server_send(int sock, lm_mptp_t *packet, struct sockaddr *addr) { return false; } - if (packet->header.size > MPTP_CHUNK_MAX) { - lm_error_set(LM_ERR_MPTPBadChunk); + if (packet->header.data_size > MPTP_DATA_MAX) { + lm_error_set(LM_ERR_MPTPBadData); + return false; + } + + if (packet->header.host_size > MPTP_HOST_MAX || packet->header.host_size <= 0) { + lm_error_set(LM_ERR_MPTPBadHost); return false; } socklen_t addrlen = sizeof(struct sockaddr); - char buffer[sizeof(packet->header.size) + packet->header.size]; - - bzero(buffer, sizeof(buffer)); + char buffer[sizeof(packet->header) + packet->header.host_size + packet->header.data_size]; + ssize_t total = sizeof(buffer), used = 0; packet->header.flags = htons(packet->header.flags); - packet->header.size = htons(packet->header.size); - memcpy(buffer, &packet->header, sizeof(packet->header)); - memcpy(buffer + sizeof(packet->header), packet->data, packet->header.size); + copy_to_buffer(buffer, &packet->header, sizeof(packet->header), &total, &used); + 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) { lm_error_set(LM_ERR_MPTPSendFail); diff --git a/src/pool.c b/src/pool.c index e6330be..20a8705 100644 --- a/src/pool.c +++ b/src/pool.c @@ -2,14 +2,11 @@ #include "../include/error.h" #include "../include/mptp.h" #include "../include/util.h" -#include -#include -#include -void lm_pool_free(lm_pool_t *pool) { - lm_url_free(&pool->url); - free(pool); -} +#include +#include +#include +#include lm_pool_t *lm_pool_new(char *name, char *url) { lm_pool_t *pool = malloc(sizeof(lm_pool_t)); @@ -21,9 +18,6 @@ lm_pool_t *lm_pool_new(char *name, char *url) { return NULL; } - if(pool->url.empty) - return pool; - if (!eq(pool->url.protocol, "mptp")) { lm_error_set(LM_ERR_PoolNoSupport); lm_pool_free(pool); @@ -34,13 +28,9 @@ lm_pool_t *lm_pool_new(char *name, char *url) { } void lm_pool_test(lm_pool_t *pool) { - if(pool->url.empty){ - pool->available = false; - return; - } - lm_mptp_t packet; - lm_mptp_packet_init(&packet, true, MPTP_C2S_PING, true); + lm_mptp_init(&packet, true, MPTP_C2S_PING, true); + lm_mptp_set_host(&packet, pool->url.host); int sock = lm_mptp_client_connect(pool->url.host, pool->url.port); if (sock == -1) { @@ -58,7 +48,7 @@ void lm_pool_test(lm_pool_t *pool) { goto end; } - if (!lm_mptp_client_verify(&packet)){ + if (!lm_mptp_client_verify(&packet)) { pool->available = false; goto end; } @@ -69,106 +59,42 @@ end: return; } -bool lm_ctx_pool_add(lm_ctx_t *ctx, char *name, char *url) { - lm_pool_t *pool = lm_pool_new(name, url); - if (NULL == pool) - return false; +int lm_pool_info_handler(void *data, const char *_section, const char *_key, const char *_value) { + char *section = (char *)_section, *value = (char *)_value, *key = (char *)_key; + lm_pool_t *pool = data; - pdebug(ctx, __func__, "pool name is %s", pool->name); - if(!pool->url.empty) - pdebug(ctx, __func__, "pool URL is %s://%s:%d%s", pool->url.protocol, pool->url.host, pool->url.port, pool->url.path); + if (!eq(pool->name, section)) + return 0; - if (NULL == ctx->pools) { - ctx->pools = pool; - return true; - } + if (eq(key, "size")) + pool->info.size = atol(value); + else if (eq(key, "maintainer")) + pool->info.maintainer = strdup(value); + else if (eq(key, "pubkey")) + pool->info.pubkey = strdup(value); + else + return 0; - lm_pool_t *cur = ctx->pools; - while (NULL != cur) { - if (NULL == cur->next) { - cur->next = pool; - return true; - } - cur = cur->next; - } - - return false; + return 1; } -bool lm_ctx_pool_del(lm_ctx_t *ctx, char *name) { - lm_pool_t *cur = ctx->pools, *prev = NULL; - while (NULL != cur) { - if (!eq(cur->name, name)) { - cur = cur->next; - continue; - } - - if (NULL == prev) { - ctx->pools = cur->next; - lm_pool_free(cur); - return true; - } - - prev->next = cur->next; - lm_pool_free(cur); - return true; - } - - return false; -} - -void lm_ctx_pool_clear(lm_ctx_t *ctx) { - lm_pool_t *cur = ctx->pools, *prev = NULL; - while (NULL != cur) { - prev = cur; - cur = cur->next; - lm_pool_free(prev); - } - - ctx->pools = NULL; -} - -void lm_ctx_pool_test(lm_ctx_t *ctx) { - lm_pool_t *cur = ctx->pools; - while (NULL != cur) { - lm_pool_test(cur); - if (!cur->available) - pdebug(ctx, __func__, "%s is not avaliable: %s", cur->name, lm_strerror()); - cur = cur->next; - } -} - -bool lm_ctx_pool_serve(lm_ctx_t *ctx, char *addr) { - struct sockaddr saddr; - char *host = NULL; - lm_mptp_t packet; - uint16_t port; - int sock; - - if(!parse_host(addr, host, &port)) - return false; - - if(port == 0){ - lm_error_set(LM_ERR_NoPort); +bool lm_pool_info_file(lm_pool_t *pool, char *file) { + if (ini_parse(file, lm_pool_info_handler, pool) < 0) { + lm_error_set(LM_ERR_PoolInfoBad); return false; } - - if((sock = lm_mptp_server_listen(addr, port)) < 0) - return false; - - while(lm_mptp_server_recv(sock, &packet, &saddr)){ - if(!lm_mptp_verify(&packet)){ - pdebug(ctx, __func__, "skipping invalid packet: %s", lm_strerror()); - continue; - } - - switch (MPTP_FLAGS_CODE(&packet)) { - case MPTP_C2S_PING: - lm_mptp_packet_init(&packet, false, MPTP_S2C_PONG, true); - lm_mptp_server_send(sock, &packet, &saddr); - break; - } - } - return true; } + +bool lm_pool_info(lm_pool_t *pool, char *info) { + if (ini_parse_string(info, lm_pool_info_handler, pool) < 0) { + lm_error_set(LM_ERR_PoolInfoBad); + return false; + } + return true; +} + +void lm_pool_free(lm_pool_t *pool) { + lm_url_free(&pool->url); + free(pool); +} diff --git a/src/url.c b/src/url.c index 3f83c2b..8184ce0 100644 --- a/src/url.c +++ b/src/url.c @@ -32,16 +32,14 @@ uint16_t lm_url_default_port(char *protocol) { bool lm_url_init(lm_url_t *url, char *str) { // clear out every variable bzero(url->protocol, sizeof(url->protocol)); - url->empty = true; url->host = NULL; url->path = NULL; url->port = 0; - if(NULL == str) - return true; - - // str is not NULL - url->empty = false; + if (NULL == str) { + lm_error_set(LM_ERR_ArgNULL); + return false; + } // stores the string size size_t strl = 0, index = 0, pos = 0; @@ -55,7 +53,7 @@ bool lm_url_init(lm_url_t *url, char *str) { lm_state_t state = URL_PROTOCOL_0; char buffer[strl + 1]; // temporary buffer, strok_r save pointer - bool ret = false; // return value + bool ret = false; // return value // clear out the temporary buffer bzero(buffer, strl + 1); @@ -190,14 +188,14 @@ bool lm_url_init(lm_url_t *url, char *str) { goto end; } - if(parse_host(url->host, url->host, &url->port)){ - if(url->port != 0){ + if (parse_host(url->host, url->host, &url->port)) { + if (url->port != 0) { ret = true; goto end; } - + url->port = lm_url_default_port(url->protocol); - if(url->port == 0){ + if (url->port == 0) { lm_error_set(LM_ERR_URLPortUnknown); goto end; } @@ -210,7 +208,7 @@ bool lm_url_init(lm_url_t *url, char *str) { case LM_ERR_BadHost: lm_error_set(LM_ERR_URLBadHost); break; - + case LM_ERR_BadPort: lm_error_set(LM_ERR_URLBadPort); break; diff --git a/src/util.c b/src/util.c index 1d47a0d..c0a85d4 100644 --- a/src/util.c +++ b/src/util.c @@ -1,6 +1,6 @@ #include "../include/util.h" -#include "../include/types.h" #include "../include/error.h" +#include "../include/types.h" #include #include #include @@ -46,22 +46,22 @@ bool contains(char *str, char s) { return false; } -bool parse_host(char *addr, char *host, uint16_t *port){ +bool parse_host(char *addr, char *host, uint16_t *port) { char *save = NULL, *portc = NULL; - int portint = 0; + int portint = 0; - if((host = strtok_r(addr, ":", &save)) == NULL){ + if ((host = strtok_r(addr, ":", &save)) == NULL) { lm_error_set(LM_ERR_BadHost); return false; } - if((portc = strtok_r(NULL, ":", &save)) == NULL){ + if ((portc = strtok_r(NULL, ":", &save)) == NULL) { *port = 0; return true; } portint = atoi(portc); - if(portint <= 0 || portint > UINT16_MAX){ + if (portint <= 0 || portint > UINT16_MAX) { lm_error_set(LM_ERR_BadPort); return false; } @@ -69,3 +69,27 @@ bool parse_host(char *addr, char *host, uint16_t *port){ *port = portint; return true; } + +bool copy_to_buffer(void *buffer, void *src, size_t size, ssize_t *total, ssize_t *used) { + if (*used + size > *total) + return false; + + if (*used == 0) + bzero(buffer, *total); + + memcpy(buffer + *used, src, size); + *used += size; + return true; +} + +bool copy_from_buffer(void *dst, void *buffer, size_t size, ssize_t *total, ssize_t *used) { + if (*used + size > *total) + return false; + + if (*used == 0) + bzero(dst, size); + + memcpy(dst, buffer + *used, size); + *used += size; + return true; +}