X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fprotocol.c;h=fd180f4faafab84fd4c3bfedf0bf465dbf96b13c;hb=b1cae6a2011f704dc4d3b02972def561d5c6bcb9;hp=e0a0dbb29a74cfecb717042bbf74088f33afdd37;hpb=b67296418c51784d39a24c3041e2cb199bee06f2;p=meshlink diff --git a/src/protocol.c b/src/protocol.c index e0a0dbb2..fd180f4f 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -27,6 +27,7 @@ #include "protocol.h" #include "utils.h" #include "xalloc.h" +#include "submesh.h" /* Jumptable for the request handlers */ @@ -65,11 +66,15 @@ bool check_id(const char *id) { /* Generic request routines - takes care of logging and error detection as well */ -bool send_request(meshlink_handle_t *mesh, connection_t *c, const char *format, ...) { +bool send_request(meshlink_handle_t *mesh, connection_t *c, submesh_t *s, const char *format, ...) { va_list args; char request[MAXBUFSIZE]; int len; + if(!c) { + return false; + } + /* Use vsnprintf instead of vxasprintf: faster, no memory fragmentation, cleanup is automatic, and there is a limit on the input buffer anyway */ @@ -88,22 +93,34 @@ bool send_request(meshlink_handle_t *mesh, connection_t *c, const char *format, request[len++] = '\n'; if(c == mesh->everyone) { - broadcast_meta(mesh, NULL, request, len); + + if(s) { + broadcast_submesh_meta(mesh, NULL, s, request, len); + } else { + broadcast_meta(mesh, NULL, request, len); + } + return true; } else { return send_meta(mesh, c, request, len); } } -void forward_request(meshlink_handle_t *mesh, connection_t *from, const char *request) { +void forward_request(meshlink_handle_t *mesh, connection_t *from, submesh_t *s, const char *request) { logger(mesh, MESHLINK_DEBUG, "Forwarding %s from %s: %s", request_name[atoi(request)], from->name, request); // Create a temporary newline-terminated copy of the request int len = strlen(request); char tmp[len + 1]; + memcpy(tmp, request, len); tmp[len] = '\n'; - broadcast_meta(mesh, from, tmp, sizeof(tmp)); + + if(s) { + broadcast_submesh_meta(mesh, from, s, tmp, sizeof(tmp)); + } else { + broadcast_meta(mesh, from, tmp, sizeof(tmp)); + } } bool receive_request(meshlink_handle_t *mesh, connection_t *c, const char *request) { @@ -164,13 +181,15 @@ static void free_past_request(past_request_t *r) { free(r); } +static const int request_timeout = 60; + static void age_past_requests(event_loop_t *loop, void *data) { (void)data; meshlink_handle_t *mesh = loop->data; int left = 0, deleted = 0; for splay_each(past_request_t, p, mesh->past_request_tree) { - if(p->firstseen + mesh->pinginterval <= mesh->loop.now.tv_sec) { + if(p->firstseen + request_timeout <= mesh->loop.now.tv_sec) { splay_delete_node(mesh->past_request_tree, node), deleted++; } else { left++; @@ -188,9 +207,7 @@ static void age_past_requests(event_loop_t *loop, void *data) { } bool seen_request(meshlink_handle_t *mesh, const char *request) { - past_request_t *new, p = {}; - - p.request = request; + past_request_t *new, p = {.request = request}; if(splay_search(mesh->past_request_tree, &p)) { logger(mesh, MESHLINK_DEBUG, "Already seen request");