new: add mptp packet verify functions

This commit is contained in:
ngn 2024-06-22 07:03:17 +03:00
parent 19c98b763d
commit c8e45097fe
12 changed files with 275 additions and 110 deletions

View File

@ -1,5 +1,4 @@
#include "../../include/error.h" #include "../../include/all.h"
#include "../../include/mptp.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <strings.h> #include <strings.h>
@ -7,46 +6,28 @@
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
int ret = EXIT_FAILURE; int ret = EXIT_FAILURE;
if (argc != 3) { if (argc != 2) {
printf("usage: %s <host> <port>\n", argv[0]); printf("usage: %s <host>\n", argv[0]);
return ret; return ret;
} }
int porti = atoi(argv[2]); lm_ctx_t ctx;
if (porti <= 0 || porti > UINT16_MAX) { lm_ctx_init(&ctx);
printf("bad port number\n");
return ret; ctx.debug = true;
if (!lm_ctx_pool_add(&ctx, "test", NULL)) {
printf("failed to add pool: %s (%d)\n", lm_strerror(), lm_error());
goto end;
} }
int sock = lm_mptp_server_listen(argv[1], porti); if(!lm_ctx_pool_serve(&ctx, argv[1])) {
if (sock < 0) { printf("failed to serve the pools: %s (%d)\n", lm_strerror(), lm_error());
printf("failed to start the server: %s\n", lm_strerror()); goto end;
return ret;
}
lm_mptp_t packet;
struct sockaddr addr;
while (lm_mptp_server_recv(sock, &packet, &addr)) {
switch (MPTP_FLAGS_TYPE(&packet)) {
case MPTP_C2S_PING:
bzero(&packet, sizeof(packet));
lm_mptp_packet_init(&packet, false, MPTP_S2C_PONG, true);
lm_mptp_server_send(sock, &packet, &addr);
break;
default:
bzero(&packet, sizeof(packet));
lm_mptp_packet_init(&packet, false, MPTP_S2C_WHAT, true);
lm_mptp_server_send(sock, &packet, &addr);
break;
}
} }
ret = EXIT_SUCCESS; ret = EXIT_SUCCESS;
end: end:
lm_mptp_close(sock); lm_ctx_free(&ctx);
return ret; return ret;
} }

View File

@ -8,24 +8,30 @@ typedef enum lm_error {
LM_ERR_URLHostLarge = 4, LM_ERR_URLHostLarge = 4,
LM_ERR_URLPathLarge = 5, LM_ERR_URLPathLarge = 5,
LM_ERR_URLBadHost = 6, LM_ERR_URLBadHost = 6,
LM_ERR_URLBadPath = 7, LM_ERR_URLBadPort = 7,
LM_ERR_URLPortUnknown = 8, LM_ERR_URLBadPath = 8,
LM_ERR_URLBadPort = 9, LM_ERR_URLPortUnknown = 9,
LM_ERR_PoolNoSupport = 10, LM_ERR_BadPort = 10,
LM_ERR_URLEnd = 11, LM_ERR_BadHost = 11,
LM_ERR_MPTPBadVersion = 12, LM_ERR_PoolNoSupport = 12,
LM_ERR_MPTPBadCode = 13, LM_ERR_URLEnd = 13,
LM_ERR_MPTPBadUrl = 14, LM_ERR_MPTPBadVersion = 14,
LM_ERR_MPTPHostFail = 15, LM_ERR_MPTPBadCode = 15,
LM_ERR_MPTPSocketFail = 16, LM_ERR_MPTPBadUrl = 16,
LM_ERR_MPTPConnectFail = 17, LM_ERR_MPTPHostFail = 17,
LM_ERR_MPTPRecvFail = 18, LM_ERR_MPTPSocketFail = 18,
LM_ERR_MPTPSendFail = 19, LM_ERR_MPTPConnectFail = 19,
LM_ERR_MPTPBadChunk = 29, LM_ERR_MPTPRecvFail = 20,
LM_ERR_MPTPSetsockopt = 30, LM_ERR_MPTPSendFail = 21,
LM_ERR_MPTPTimeout = 31, LM_ERR_MPTPBadChunk = 22,
LM_ERR_MPTPBindFail = 32, LM_ERR_MPTPSetsockopt = 23,
LM_ERR_ArgNULL = 33, 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_error_t; } lm_error_t;
typedef struct lm_error_desc { typedef struct lm_error_desc {

View File

@ -69,8 +69,7 @@
// clang-format on // clang-format on
#define MPTP_VERSION_SUPPORTED 0 #define MPTP_VERSION_SUPPORTED 0
#define MPTP_VERSION_MAX 15 // 4 bits #define MPTP_CODE_MAX 3 // 2 bits
#define MPTP_CODE_MAX 4 // 2 bits
#define MPTP_CHUNK_MAX 256 #define MPTP_CHUNK_MAX 256
#define MPTP_TIMEOUT 10 #define MPTP_TIMEOUT 10
@ -101,24 +100,25 @@ typedef struct lm_mptp {
char data[MPTP_CHUNK_MAX]; char data[MPTP_CHUNK_MAX];
} lm_mptp_t; } lm_mptp_t;
#define MPTP_FLAGS_VERSION(m) ((m)->header.flags & 0xFF00) >> 8 #define MPTP_FLAGS_VERSION(m) (((m)->header.flags & 0xFF00) >> 8)
#define MPTP_FLAGS_REQUEST(m) ((m)->header.flags & 0x0080) >> 1 #define MPTP_FLAGS_TYPE(m) (((m)->header.flags & 0x0080) >> 1)
#define MPTP_FLAGS_TYPE(m) ((m)->header.flags & 0x0070) >> 4 #define MPTP_FLAGS_CODE(m) (((m)->header.flags & 0x0070) >> 4)
#define MPTP_FLAGS_LAST(m) ((m)->header.flags & 0x0008) >> 3 #define MPTP_FLAGS_LAST(m) (((m)->header.flags & 0x0008) >> 3)
#define MPTP_IS_REQUEST(m) MPTP_FLAGS_REQUEST(m) == 0 #define MPTP_IS_REQUEST(m) (MPTP_FLAGS_TYPE(m) == 0)
#define MPTP_IS_LAST(m) MPTP_FLAGS_LAST(m) == 1 #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_packet_init(lm_mptp_t *packet, bool is_request, uint8_t code, bool is_last);
int lm_mptp_socket(char *addr, uint16_t port, struct sockaddr *saddr); 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); void lm_mptp_close(int sock);
int lm_mptp_client_connect(char *addr, uint16_t port); int lm_mptp_client_connect(char *addr, uint16_t port);
bool lm_mptp_client_verify(int sock, lm_mptp_t *packet); // not implemented bool lm_mptp_client_verify(lm_mptp_t *packet);
bool lm_mptp_client_send(int sock, lm_mptp_t *packet); bool lm_mptp_client_send(int sock, lm_mptp_t *packet);
bool lm_mptp_client_recv(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_listen(char *addr, uint16_t port);
bool lm_mptp_server_verify(int sock, lm_mptp_t *packet, struct sockaddr *addr); // not implemented 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_recv(int sock, lm_mptp_t *packet, struct sockaddr *addr);
bool lm_mptp_server_send(int sock, lm_mptp_t *packet, struct sockaddr *adrr); bool lm_mptp_server_send(int sock, lm_mptp_t *packet, struct sockaddr *adrr);

View File

@ -6,3 +6,4 @@ bool lm_ctx_pool_add(lm_ctx_t *ctx, char *name, char *url);
bool lm_ctx_pool_del(lm_ctx_t *ctx, char *name); bool lm_ctx_pool_del(lm_ctx_t *ctx, char *name);
void lm_ctx_pool_clear(lm_ctx_t *ctx); void lm_ctx_pool_clear(lm_ctx_t *ctx);
void lm_ctx_pool_test(lm_ctx_t *ctx); void lm_ctx_pool_test(lm_ctx_t *ctx);
bool lm_ctx_pool_serve(lm_ctx_t *ctx, char *addr);

View File

@ -11,7 +11,8 @@ typedef struct lm_url {
char protocol[URL_PROTOCOL_MAX + 1]; char protocol[URL_PROTOCOL_MAX + 1];
char *host; char *host;
char *path; char *path;
bool empty;
} lm_url_t; } lm_url_t;
bool lm_url_parse(lm_url_t *url, char *str); bool lm_url_init(lm_url_t *url, char *str);
void lm_url_free(lm_url_t *url); void lm_url_free(lm_url_t *url);

View File

@ -6,6 +6,7 @@
#define _(x) gettext(x) #define _(x) gettext(x)
void pdebug(lm_ctx_t *ctx, const char *func, const char *fmt, ...); void pdebug(lm_ctx_t *ctx, const char *func, const char *fmt, ...);
bool parse_host(char *addr, char *host, uint16_t *port);
bool contains(char *str, char s); bool contains(char *str, char s);
bool eq(char *s1, char *s2); bool eq(char *s1, char *s2);
bool is_letter(char c); bool is_letter(char c);

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-06-22 04:17+0300\n" "POT-Creation-Date: 2024-06-22 07:00+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -47,74 +47,101 @@ msgid "URL does not have a valid hostname"
msgstr "URL does not have a valid hostname" msgstr "URL does not have a valid hostname"
#: src/error.c:20 #: src/error.c:20
#, fuzzy
msgid "URL does not have a valid port number"
msgstr "URL does not have a valid hostname"
#: src/error.c:21
msgid "URL does not have a valid path" msgid "URL does not have a valid path"
msgstr "URL does not have a valid path" msgstr "URL does not have a valid path"
#: src/error.c:21 #: src/error.c:22
msgid "URL does not contain a hostname with a valid port number" #, fuzzy
msgid "hostname does not contain a valid port number"
msgstr "URL does not contain a hostname with a valid port number" msgstr "URL does not contain a hostname with a valid port number"
#: src/error.c:22 #: src/error.c:23
#, fuzzy
msgid "hostname is not valid"
msgstr "URL hostname is too large"
#: src/error.c:24
msgid "URL protocol port number is unknown" msgid "URL protocol port number is unknown"
msgstr "URL protocol port number is unknown" msgstr "URL protocol port number is unknown"
#: src/error.c:23 #: src/error.c:25
msgid "URL is incomplete" msgid "URL is incomplete"
msgstr "URL tamamlanmamış" msgstr "URL tamamlanmamış"
#: src/error.c:24 #: src/error.c:26
msgid "pool does not support the specified protocol" msgid "pool does not support the specified protocol"
msgstr "pool does not support the specified protocol" msgstr "pool does not support the specified protocol"
#: src/error.c:25 #: src/error.c:27
msgid "unsupported MPTP version" msgid "unsupported MPTP version"
msgstr "" msgstr ""
#: src/error.c:26 #: src/error.c:28
msgid "invalid MPTP request/response code" msgid "invalid MPTP request/response code"
msgstr "" msgstr ""
#: src/error.c:27 #: src/error.c:29
msgid "invalid MPTP URL" msgid "invalid MPTP URL"
msgstr "" msgstr ""
#: src/error.c:28 #: src/error.c:30
msgid "failed to resolve hostname for MPTP connection" msgid "failed to resolve hostname for MPTP connection"
msgstr "" msgstr ""
#: src/error.c:29 #: src/error.c:31
msgid "failed to create a MPTP socket" msgid "failed to create a MPTP socket"
msgstr "" msgstr ""
#: src/error.c:30 #: src/error.c:32
msgid "failed to connect to the MPTP host" msgid "failed to connect to the MPTP host"
msgstr "" msgstr ""
#: src/error.c:31 #: src/error.c:33
msgid "failed receive MPTP data from host" msgid "failed receive MPTP data from host"
msgstr "" msgstr ""
#: src/error.c:32 #: src/error.c:34
msgid "failed send MPTP data to host" msgid "failed send MPTP data to host"
msgstr "" msgstr ""
#: src/error.c:33 #: src/error.c:35
#, fuzzy #, fuzzy
msgid "MPTP data chunk is too large" msgid "MPTP data chunk size is invalid"
msgstr "URL path is too large" msgstr "URL path is too large"
#: src/error.c:34 #: src/error.c:36
msgid "failed to set MPTP socket options" msgid "failed to set MPTP socket options"
msgstr "" msgstr ""
#: src/error.c:35 #: src/error.c:37
msgid "MPTP connection timed out" msgid "MPTP connection timed out"
msgstr "" msgstr ""
#: src/error.c:36 #: src/error.c:38
msgid "failed to bind MPTP socket" msgid "failed to bind MPTP socket"
msgstr "" msgstr ""
#: src/error.c:37 #: src/error.c:39
msgid "required argument is a NULL pointer" msgid "required argument is a NULL pointer"
msgstr "" msgstr ""
#: src/error.c:40
msgid "not a MPTP request"
msgstr ""
#: src/error.c:41
msgid "not a MPTP response"
msgstr ""
#: src/error.c:42
msgid "MPTP request last flag is not set"
msgstr ""
#: src/error.c:43
msgid "host port not specified"
msgstr ""

View File

@ -17,8 +17,10 @@ char *lm_strerror() {
{.code = LM_ERR_URLHostLarge, .desc = _("URL hostname 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_URLPathLarge, .desc = _("URL path is too large") },
{.code = LM_ERR_URLBadHost, .desc = _("URL does not have a valid hostname") }, {.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_URLBadPath, .desc = _("URL does not have a valid path") },
{.code = LM_ERR_URLBadPort, .desc = _("URL does not contain a hostname with a valid port number")}, {.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_URLPortUnknown, .desc = _("URL protocol port number is unknown") },
{.code = LM_ERR_URLEnd, .desc = _("URL is incomplete") }, {.code = LM_ERR_URLEnd, .desc = _("URL is incomplete") },
{.code = LM_ERR_PoolNoSupport, .desc = _("pool does not support the specified protocol") }, {.code = LM_ERR_PoolNoSupport, .desc = _("pool does not support the specified protocol") },
@ -30,11 +32,15 @@ char *lm_strerror() {
{.code = LM_ERR_MPTPConnectFail, .desc = _("failed to connect to the MPTP host") }, {.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_MPTPRecvFail, .desc = _("failed receive MPTP data from host") },
{.code = LM_ERR_MPTPSendFail, .desc = _("failed send MPTP data to host") }, {.code = LM_ERR_MPTPSendFail, .desc = _("failed send MPTP data to host") },
{.code = LM_ERR_MPTPBadChunk, .desc = _("MPTP data chunk is too large") }, {.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_MPTPSetsockopt, .desc = _("failed to set MPTP socket options") },
{.code = LM_ERR_MPTPTimeout, .desc = _("MPTP connection timed out") }, {.code = LM_ERR_MPTPTimeout, .desc = _("MPTP connection timed out") },
{.code = LM_ERR_MPTPBindFail, .desc = _("failed to bind MPTP socket") }, {.code = LM_ERR_MPTPBindFail, .desc = _("failed to bind MPTP socket") },
{.code = LM_ERR_ArgNULL, .desc = _("required argument is a NULL pointer") }, {.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") },
}; };
for (int i = 0; i < sizeof(errors) / sizeof(lm_error_desc_t); i++) { for (int i = 0; i < sizeof(errors) / sizeof(lm_error_desc_t); i++) {

View File

@ -27,7 +27,7 @@ bool lm_mptp_packet_init(lm_mptp_t *packet, bool is_request, uint8_t code, bool
if (is_request) if (is_request)
packet->header.flags |= (MPTP_REQUEST << 7); packet->header.flags |= (MPTP_REQUEST << 7);
else else
packet->header.flags |= (MPTP_REQUEST << 7); packet->header.flags |= (MPTP_RESPONSE << 7);
packet->header.flags |= (code << 4); packet->header.flags |= (code << 4);
@ -39,6 +39,30 @@ bool lm_mptp_packet_init(lm_mptp_t *packet, bool is_request, uint8_t code, bool
return true; return true;
} }
bool lm_mptp_verify(lm_mptp_t *packet){
if (NULL == packet) {
lm_error_set(LM_ERR_ArgNULL);
return false;
}
if (MPTP_FLAGS_VERSION(packet) != MPTP_VERSION_SUPPORTED) {
lm_error_set(LM_ERR_MPTPBadVersion);
return false;
}
if (packet->header.size > MPTP_CHUNK_MAX || packet->header.size < 0) {
lm_error_set(LM_ERR_MPTPBadChunk);
return false;
}
if (MPTP_FLAGS_CODE(packet) > MPTP_CODE_MAX || MPTP_FLAGS_CODE(packet) < 0) {
lm_error_set(LM_ERR_MPTPBadCode);
return false;
}
return true;
}
int lm_mptp_socket(char *addr, uint16_t port, struct sockaddr *saddr) { int lm_mptp_socket(char *addr, uint16_t port, struct sockaddr *saddr) {
if (NULL == addr || NULL == saddr) { if (NULL == addr || NULL == saddr) {
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
@ -129,6 +153,18 @@ int lm_mptp_client_connect(char *addr, uint16_t port) {
return sock; return sock;
} }
bool lm_mptp_client_verify(lm_mptp_t *packet) {
if (!lm_mptp_verify(packet))
return false;
if (MPTP_IS_REQUEST(packet)) {
lm_error_set(LM_ERR_MPTPNotResponse);
return false;
}
return true;
}
bool lm_mptp_client_send(int sock, lm_mptp_t *packet) { bool lm_mptp_client_send(int sock, lm_mptp_t *packet) {
if (NULL == packet) { if (NULL == packet) {
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);
@ -210,6 +246,23 @@ int lm_mptp_server_listen(char *addr, uint16_t port) {
return sock; return sock;
} }
bool lm_mptp_server_verify(lm_mptp_t *packet) {
if (!lm_mptp_verify(packet))
return false;
if (!MPTP_IS_REQUEST(packet)) {
lm_error_set(LM_ERR_MPTPNotRequest);
return false;
}
if(!MPTP_IS_LAST(packet)){
lm_error_set(LM_ERR_MPTPNotLast);
return false;
}
return true;
}
bool lm_mptp_server_recv(int sock, lm_mptp_t *packet, struct sockaddr *addr) { bool lm_mptp_server_recv(int sock, lm_mptp_t *packet, struct sockaddr *addr) {
if (NULL == packet || NULL == addr) { if (NULL == packet || NULL == addr) {
lm_error_set(LM_ERR_ArgNULL); lm_error_set(LM_ERR_ArgNULL);

View File

@ -2,8 +2,9 @@
#include "../include/error.h" #include "../include/error.h"
#include "../include/mptp.h" #include "../include/mptp.h"
#include "../include/util.h" #include "../include/util.h"
#include <stdio.h> #include <sys/socket.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
void lm_pool_free(lm_pool_t *pool) { void lm_pool_free(lm_pool_t *pool) {
lm_url_free(&pool->url); lm_url_free(&pool->url);
@ -12,23 +13,32 @@ void lm_pool_free(lm_pool_t *pool) {
lm_pool_t *lm_pool_new(char *name, char *url) { lm_pool_t *lm_pool_new(char *name, char *url) {
lm_pool_t *pool = malloc(sizeof(lm_pool_t)); lm_pool_t *pool = malloc(sizeof(lm_pool_t));
if (!lm_url_parse(&pool->url, url)) { pool->available = true;
pool->name = name;
if (!lm_url_init(&pool->url, url)) {
free(pool); free(pool);
return NULL; return NULL;
} }
if(pool->url.empty)
return pool;
if (!eq(pool->url.protocol, "mptp")) { if (!eq(pool->url.protocol, "mptp")) {
lm_error_set(LM_ERR_PoolNoSupport); lm_error_set(LM_ERR_PoolNoSupport);
lm_pool_free(pool); lm_pool_free(pool);
return NULL; return NULL;
} }
pool->available = true;
pool->name = name;
return pool; return pool;
} }
void lm_pool_test(lm_pool_t *pool) { void lm_pool_test(lm_pool_t *pool) {
if(pool->url.empty){
pool->available = false;
return;
}
lm_mptp_t packet; lm_mptp_t packet;
lm_mptp_packet_init(&packet, true, MPTP_C2S_PING, true); lm_mptp_packet_init(&packet, true, MPTP_C2S_PING, true);
@ -48,7 +58,12 @@ void lm_pool_test(lm_pool_t *pool) {
goto end; goto end;
} }
pool->available = MPTP_FLAGS_TYPE(&packet) == MPTP_S2C_PONG; if (!lm_mptp_client_verify(&packet)){
pool->available = false;
goto end;
}
pool->available = MPTP_FLAGS_CODE(&packet) == MPTP_S2C_PONG;
end: end:
lm_mptp_close(sock); lm_mptp_close(sock);
return; return;
@ -60,7 +75,8 @@ bool lm_ctx_pool_add(lm_ctx_t *ctx, char *name, char *url) {
return false; return false;
pdebug(ctx, __func__, "pool name is %s", pool->name); 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(!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 (NULL == ctx->pools) { if (NULL == ctx->pools) {
ctx->pools = pool; ctx->pools = pool;
@ -121,3 +137,38 @@ void lm_ctx_pool_test(lm_ctx_t *ctx) {
cur = cur->next; 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);
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;
}

View File

@ -2,6 +2,7 @@
#include "../include/error.h" #include "../include/error.h"
#include "../include/util.h" #include "../include/util.h"
#include <assert.h> #include <assert.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -14,7 +15,7 @@ typedef enum lm_state {
URL_PATH_3 = 3, URL_PATH_3 = 3,
} lm_state_t; } lm_state_t;
uint16_t lm_url_default(char *protocol) { uint16_t lm_url_default_port(char *protocol) {
if (eq(protocol, "ftp")) if (eq(protocol, "ftp"))
return 21; return 21;
else if (eq(protocol, "ftps")) else if (eq(protocol, "ftps"))
@ -28,13 +29,20 @@ uint16_t lm_url_default(char *protocol) {
return 0; return 0;
} }
bool lm_url_parse(lm_url_t *url, char *str) { bool lm_url_init(lm_url_t *url, char *str) {
// clear out every variable // clear out every variable
bzero(url->protocol, sizeof(url->protocol)); bzero(url->protocol, sizeof(url->protocol));
url->empty = true;
url->host = NULL; url->host = NULL;
url->path = NULL; url->path = NULL;
url->port = 0; url->port = 0;
if(NULL == str)
return true;
// str is not NULL
url->empty = false;
// stores the string size // stores the string size
size_t strl = 0, index = 0, pos = 0; size_t strl = 0, index = 0, pos = 0;
@ -46,7 +54,7 @@ bool lm_url_parse(lm_url_t *url, char *str) {
} }
lm_state_t state = URL_PROTOCOL_0; lm_state_t state = URL_PROTOCOL_0;
char buffer[strl + 1], *save; // temporary buffer, strok_r save pointer 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 // clear out the temporary buffer
@ -182,30 +190,34 @@ bool lm_url_parse(lm_url_t *url, char *str) {
goto end; goto end;
} }
if (strtok_r(url->host, ":", &save) == NULL) { if(parse_host(url->host, url->host, &url->port)){
lm_error_set(LM_ERR_URLBadHost); if(url->port != 0){
goto end; ret = true;
} goto end;
}
char *portc = strtok_r(NULL, ":", &save);
if (NULL == portc) { url->port = lm_url_default_port(url->protocol);
url->port = lm_url_default(url->protocol); if(url->port == 0){
if (url->port == 0) {
lm_error_set(LM_ERR_URLPortUnknown); lm_error_set(LM_ERR_URLPortUnknown);
goto end; goto end;
} }
ret = true; ret = true;
goto end; goto end;
} }
int port = atoi(portc); switch (lm_error()) {
if (port <= 0 || port > UINT16_MAX) { case LM_ERR_BadHost:
lm_error_set(LM_ERR_URLBadHost);
break;
case LM_ERR_BadPort:
lm_error_set(LM_ERR_URLBadPort); lm_error_set(LM_ERR_URLBadPort);
goto end; break;
}
url->port = port; default:
ret = true; break;
}
end: end:
if (!ret && NULL != url->host) if (!ret && NULL != url->host)

View File

@ -1,5 +1,7 @@
#include "../include/util.h" #include "../include/util.h"
#include "../include/types.h" #include "../include/types.h"
#include "../include/error.h"
#include <error.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -43,3 +45,27 @@ bool contains(char *str, char s) {
return true; return true;
return false; return false;
} }
bool parse_host(char *addr, char *host, uint16_t *port){
char *save = NULL, *portc = NULL;
int portint = 0;
if((host = strtok_r(addr, ":", &save)) == NULL){
lm_error_set(LM_ERR_BadHost);
return false;
}
if((portc = strtok_r(NULL, ":", &save)) == NULL){
*port = 0;
return true;
}
portint = atoi(portc);
if(portint <= 0 || portint > UINT16_MAX){
lm_error_set(LM_ERR_BadPort);
return false;
}
*port = portint;
return true;
}