X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fprotocol_auth.c;h=201cac9fe000eef05b17561fd4223ec31805e60b;hb=HEAD;hp=2154faae09cce7cf9a305464561eaf2e9adb507f;hpb=b2d1ccdaf1554f2f34e8acb86f89190cb93b6634;p=meshlink diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 2154faae..0a107e4c 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -44,12 +44,25 @@ extern bool node_write_devclass(meshlink_handle_t *mesh, node_t *n); bool send_id(meshlink_handle_t *mesh, connection_t *c) { - return send_request(mesh, c, NULL, "%d %s %d.%d %s", ID, mesh->self->name, PROT_MAJOR, PROT_MINOR, mesh->appname); + return send_request(mesh, c, NULL, "%d %s %d.%d %s %u", ID, mesh->self->name, PROT_MAJOR, PROT_MINOR, mesh->appname, 0); } static bool commit_invitation(meshlink_handle_t *mesh, connection_t *c, const void *data) { + // Check if the node is known + node_t *n = lookup_node(mesh, c->name); + + if(n) { + if(n->status.blacklisted) { + logger(mesh, MESHLINK_ERROR, "Invitee %s is blacklisted", c->name); + } else { + logger(mesh, MESHLINK_ERROR, "Invitee %s already known", c->name); + } + + return false; + } + // Create a new node - node_t *n = new_node(); + n = new_node(); n->name = xstrdup(c->name); n->devclass = DEV_CLASS_UNKNOWN; n->ecdsa = ecdsa_set_public_key(data); @@ -58,7 +71,7 @@ static bool commit_invitation(meshlink_handle_t *mesh, connection_t *c, const vo // Remember its current address node_add_recent_address(mesh, n, &c->address); - if(!node_write_config(mesh, n) || !config_sync(mesh, "current")) { + if(!node_write_config(mesh, n, true) || !config_sync(mesh, "current")) { logger(mesh, MESHLINK_ERROR, "Error writing configuration file for invited node %s!\n", c->name); free_node(n); return false; @@ -146,6 +159,9 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat connection_t *c = handle; meshlink_handle_t *mesh = c->mesh; + // Extend the time for the invitation exchange upon receiving a valid message + c->last_ping_time = mesh->loop.now.tv_sec; + if(type == SPTPS_HANDSHAKE) { // The peer should send its cookie first. return true; @@ -172,7 +188,7 @@ bool id_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { char name[MAX_STRING_SIZE]; - if(sscanf(request, "%*d " MAX_STRING " %d.%d", name, &c->protocol_major, &c->protocol_minor) < 2) { + if(sscanf(request, "%*d " MAX_STRING " %d.%d %*s %u", name, &c->protocol_major, &c->protocol_minor, &c->flags) < 2) { logger(mesh, MESHLINK_ERROR, "Got bad %s from %s", "ID", c->name); return false; } @@ -207,6 +223,7 @@ bool id_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { c->protocol_minor = 2; c->allow_request = 1; + c->last_ping_time = mesh->loop.now.tv_sec; return sptps_start(&c->sptps, c, false, false, mesh->invitation_key, c->ecdsa, meshlink_invitation_label, sizeof(meshlink_invitation_label), send_meta_sptps, receive_invitation_sptps); } @@ -250,11 +267,6 @@ bool id_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { return false; } - if(n->status.blacklisted) { - logger(mesh, MESHLINK_WARNING, "Peer %s is blacklisted", c->name); - return false; - } - if(!node_read_public_key(mesh, n)) { logger(mesh, MESHLINK_ERROR, "No key known for peer %s", c->name); @@ -275,6 +287,7 @@ bool id_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { } c->allow_request = ACK; + c->last_ping_time = mesh->loop.now.tv_sec; char label[sizeof(meshlink_tcp_label) + strlen(mesh->self->name) + strlen(c->name) + 2]; if(c->outgoing) { @@ -283,14 +296,25 @@ bool id_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { snprintf(label, sizeof(label), "%s %s %s", meshlink_tcp_label, c->name, mesh->self->name); } - char buf1[1024], buf2[1024]; - bin2hex((uint8_t *)mesh->private_key + 64, buf1, 32); - bin2hex((uint8_t *)n->ecdsa + 64, buf2, 32); - logger(mesh, MESHLINK_DEBUG, "Connection to %s mykey %s hiskey %s", c->name, buf1, buf2); + if(mesh->log_level <= MESHLINK_DEBUG) { + char buf1[1024], buf2[1024]; + bin2hex((uint8_t *)mesh->private_key + 64, buf1, 32); + bin2hex((uint8_t *)n->ecdsa + 64, buf2, 32); + logger(mesh, MESHLINK_DEBUG, "Connection to %s mykey %s hiskey %s", c->name, buf1, buf2); + } + return sptps_start(&c->sptps, c, c->outgoing, false, mesh->private_key, n->ecdsa, label, sizeof(label) - 1, send_meta_sptps, receive_meta_sptps); } bool send_ack(meshlink_handle_t *mesh, connection_t *c) { + node_t *n = lookup_node(mesh, c->name); + + if(n && n->status.blacklisted) { + logger(mesh, MESHLINK_WARNING, "Peer %s is blacklisted", c->name); + return send_error(mesh, c, BLACKLISTED, "blacklisted"); + } + + c->last_ping_time = mesh->loop.now.tv_sec; return send_request(mesh, c, NULL, "%d %s %d %x", ACK, mesh->myport, mesh->devclass, OPTION_PMTU_DISCOVERY | (PROT_MINOR << 24)); } @@ -334,7 +358,7 @@ bool ack_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { } else { if(n->connection) { /* Oh dear, we already have a connection to this node. */ - logger(mesh, MESHLINK_DEBUG, "Established a second connection with %s, closing old connection", n->connection->name); + logger(mesh, MESHLINK_INFO, "Established a second connection with %s, closing old connection", n->connection->name); if(n->connection->outgoing) { if(c->outgoing) { @@ -356,10 +380,12 @@ bool ack_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { n->devclass = devclass; n->status.dirty = true; + n->status.tiny = c->flags & PROTOCOL_TINY; n->last_successfull_connection = mesh->loop.now.tv_sec; n->connection = c; + n->nexthop = n; c->node = n; /* Activate this connection */ @@ -374,9 +400,30 @@ bool ack_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { mesh->meta_status_cb(mesh, (meshlink_node_t *)n, true); } + /* Terminate any connections to this node that are not activated yet */ + + for list_each(connection_t, other, mesh->connections) { + if(!other->status.active && !strcmp(other->name, c->name)) { + if(other->outgoing) { + if(c->outgoing) { + logger(mesh, MESHLINK_WARNING, "Two outgoing connections to the same node!"); + } else { + c->outgoing = other->outgoing; + } + + other->outgoing = NULL; + } + + logger(mesh, MESHLINK_DEBUG, "Terminating pending second connection with %s", n->name); + terminate_connection(mesh, other, false); + } + } + /* Send him everything we know */ - send_everything(mesh, c); + if(!(c->flags & PROTOCOL_TINY)) { + send_everything(mesh, c); + } /* Create an edge_t for this connection */ @@ -389,6 +436,7 @@ bool ack_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { c->edge->weight = mesh->dev_class_traits[devclass].edge_weight; c->edge->connection = c; + node_add_recent_address(mesh, n, &c->address); edge_add(mesh, c->edge); /* Notify everyone of the new edge */ @@ -399,5 +447,11 @@ bool ack_h(meshlink_handle_t *mesh, connection_t *c, const char *request) { graph(mesh); + /* Request a session key to jump start UDP traffic */ + + if(c->status.initiator) { + send_req_key(mesh, n); + } + return true; }