mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-04-20 22:13:47 +00:00
Merge branch 'main' into rx_delay
# Conflicts: # examples/simple_repeater/main.cpp # examples/simple_room_server/main.cpp
This commit is contained in:
commit
5d4a5dce36
2 changed files with 57 additions and 39 deletions
|
|
@ -106,7 +106,8 @@ struct ClientInfo {
|
|||
mesh::Identity id;
|
||||
uint32_t last_timestamp;
|
||||
uint8_t secret[PUB_KEY_SIZE];
|
||||
int out_path_len;
|
||||
bool is_admin;
|
||||
int8_t out_path_len;
|
||||
uint8_t out_path[MAX_PATH_SIZE];
|
||||
};
|
||||
|
||||
|
|
@ -127,6 +128,7 @@ struct NodePrefs { // persisted to file
|
|||
uint8_t unused;
|
||||
float rx_delay_base;
|
||||
float tx_delay_factor;
|
||||
char guest_password[16];
|
||||
};
|
||||
|
||||
class MyMesh : public mesh::Mesh {
|
||||
|
|
@ -159,14 +161,7 @@ class MyMesh : public mesh::Mesh {
|
|||
memcpy(reply_data, &now, 4); // response packets always prefixed with timestamp
|
||||
|
||||
switch (payload[0]) {
|
||||
case CMD_GET_STATS: {
|
||||
uint32_t max_age_secs;
|
||||
if (payload_len >= 5) {
|
||||
memcpy(&max_age_secs, &payload[1], 4); // first param in request pkt
|
||||
} else {
|
||||
max_age_secs = 12*60*60; // default, 12 hours
|
||||
}
|
||||
|
||||
case CMD_GET_STATS: { // guests can also access this now
|
||||
RepeaterStats stats;
|
||||
stats.batt_milli_volts = board.getBattMilliVolts();
|
||||
stats.curr_tx_queue_len = _mgr->getOutboundCount();
|
||||
|
|
@ -240,38 +235,47 @@ protected:
|
|||
uint32_t timestamp;
|
||||
memcpy(×tamp, data, 4);
|
||||
|
||||
bool is_admin;
|
||||
if (memcmp(&data[4], _prefs.password, strlen(_prefs.password)) == 0) { // check for valid password
|
||||
auto client = putClient(sender); // add to known clients (if not already known)
|
||||
if (client == NULL || timestamp <= client->last_timestamp) {
|
||||
MESH_DEBUG_PRINTLN("Client table full, or replay attack!");
|
||||
return; // FATAL: client table is full -OR- replay attack
|
||||
}
|
||||
is_admin = true;
|
||||
} else if (memcmp(&data[4], _prefs.guest_password, strlen(_prefs.guest_password)) == 0) { // check guest password
|
||||
is_admin = false;
|
||||
} else {
|
||||
#if MESH_DEBUG
|
||||
data[len] = 0; // ensure null terminator
|
||||
MESH_DEBUG_PRINTLN("Invalid password: %s", &data[4]);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
MESH_DEBUG_PRINTLN("Login success!");
|
||||
client->last_timestamp = timestamp;
|
||||
auto client = putClient(sender); // add to known clients (if not already known)
|
||||
if (client == NULL || timestamp <= client->last_timestamp) {
|
||||
MESH_DEBUG_PRINTLN("Client table full, or replay attack!");
|
||||
return; // FATAL: client table is full -OR- replay attack
|
||||
}
|
||||
|
||||
uint32_t now = getRTCClock()->getCurrentTime();
|
||||
memcpy(reply_data, &now, 4); // response packets always prefixed with timestamp
|
||||
memcpy(&reply_data[4], "OK", 2);
|
||||
MESH_DEBUG_PRINTLN("Login success!");
|
||||
client->last_timestamp = timestamp;
|
||||
client->is_admin = is_admin;
|
||||
|
||||
if (packet->isRouteFlood()) {
|
||||
// let this sender know path TO here, so they can use sendDirect(), and ALSO encode the response
|
||||
mesh::Packet* path = createPathReturn(sender, client->secret, packet->path, packet->path_len,
|
||||
PAYLOAD_TYPE_RESPONSE, reply_data, 4 + 2);
|
||||
if (path) sendFlood(path);
|
||||
} else {
|
||||
mesh::Packet* reply = createDatagram(PAYLOAD_TYPE_RESPONSE, sender, client->secret, reply_data, 4 + 2);
|
||||
if (reply) {
|
||||
if (client->out_path_len >= 0) { // we have an out_path, so send DIRECT
|
||||
sendDirect(reply, client->out_path, client->out_path_len);
|
||||
} else {
|
||||
sendFlood(reply);
|
||||
}
|
||||
uint32_t now = getRTCClock()->getCurrentTime();
|
||||
memcpy(reply_data, &now, 4); // response packets always prefixed with timestamp
|
||||
memcpy(&reply_data[4], "OK", 2);
|
||||
|
||||
if (packet->isRouteFlood()) {
|
||||
// let this sender know path TO here, so they can use sendDirect(), and ALSO encode the response
|
||||
mesh::Packet* path = createPathReturn(sender, client->secret, packet->path, packet->path_len,
|
||||
PAYLOAD_TYPE_RESPONSE, reply_data, 4 + 2);
|
||||
if (path) sendFlood(path);
|
||||
} else {
|
||||
mesh::Packet* reply = createDatagram(PAYLOAD_TYPE_RESPONSE, sender, client->secret, reply_data, 4 + 2);
|
||||
if (reply) {
|
||||
if (client->out_path_len >= 0) { // we have an out_path, so send DIRECT
|
||||
sendDirect(reply, client->out_path, client->out_path_len);
|
||||
} else {
|
||||
sendFlood(reply);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
data[4+8] = 0; // ensure null terminator
|
||||
MESH_DEBUG_PRINTLN("Incorrect password: %s", &data[4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -333,7 +337,7 @@ protected:
|
|||
} else {
|
||||
MESH_DEBUG_PRINTLN("onPeerDataRecv: possible replay attack detected");
|
||||
}
|
||||
} else if (type == PAYLOAD_TYPE_TXT_MSG && len > 5) { // a CLI command
|
||||
} else if (type == PAYLOAD_TYPE_TXT_MSG && len > 5 && client->is_admin) { // a CLI command
|
||||
uint32_t sender_timestamp;
|
||||
memcpy(&sender_timestamp, data, 4); // timestamp (by sender's RTC clock - which could be wrong)
|
||||
uint flags = (data[4] >> 2); // message attempt number, and other flags
|
||||
|
|
@ -541,6 +545,11 @@ public:
|
|||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
}
|
||||
} else if (memcmp(config, "guest.password ", 15) == 0) {
|
||||
strncpy(_prefs.guest_password, &config[15], sizeof(_prefs.guest_password)-1);
|
||||
_prefs.guest_password[sizeof(_prefs.guest_password)-1] = 0; // truncate if necessary
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
} else if (memcmp(config, "name ", 5) == 0) {
|
||||
strncpy(_prefs.node_name, &config[5], sizeof(_prefs.node_name)-1);
|
||||
_prefs.node_name[sizeof(_prefs.node_name)-1] = 0; // truncate if nec
|
||||
|
|
|
|||
|
|
@ -144,6 +144,7 @@ struct NodePrefs { // persisted to file
|
|||
uint8_t unused;
|
||||
float rx_delay_base;
|
||||
float tx_delay_factor;
|
||||
char guest_password[16];
|
||||
};
|
||||
|
||||
class MyMesh : public mesh::Mesh {
|
||||
|
|
@ -304,12 +305,11 @@ protected:
|
|||
is_admin = true;
|
||||
} else {
|
||||
is_admin = false;
|
||||
#ifdef ROOM_PASSWORD
|
||||
if (memcmp(&data[8], ROOM_PASSWORD, strlen(ROOM_PASSWORD)) != 0) { // check the room/public password
|
||||
int len = strlen(_prefs.guest_password);
|
||||
if (len > 0 && memcmp(&data[8], _prefs.guest_password, len) != 0) { // check the room/public password
|
||||
MESH_DEBUG_PRINTLN("Incorrect room password");
|
||||
return; // no response. Client will timeout
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
auto client = putClient(sender); // add to known clients (if not already known)
|
||||
|
|
@ -539,6 +539,10 @@ public:
|
|||
_prefs.tx_power_dbm = LORA_TX_POWER;
|
||||
_prefs.disable_fwd = 1;
|
||||
_prefs.advert_interval = 2; // default to 2 minutes for NEW installs
|
||||
#ifdef ROOM_PASSWORD
|
||||
strncpy(_prefs.guest_password, ROOM_PASSWORD, sizeof(_prefs.guest_password)-1);
|
||||
_prefs.guest_password[sizeof(_prefs.guest_password)-1] = 0; // truncate if necessary
|
||||
#endif
|
||||
|
||||
num_clients = 0;
|
||||
next_post_idx = 0;
|
||||
|
|
@ -646,6 +650,11 @@ public:
|
|||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
}
|
||||
} else if (memcmp(config, "guest.password ", 15) == 0) {
|
||||
strncpy(_prefs.guest_password, &config[15], sizeof(_prefs.guest_password)-1);
|
||||
_prefs.guest_password[sizeof(_prefs.guest_password)-1] = 0; // truncate if necessary
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
} else if (memcmp(config, "name ", 5) == 0) {
|
||||
strncpy(_prefs.node_name, &config[5], sizeof(_prefs.node_name)-1);
|
||||
_prefs.node_name[sizeof(_prefs.node_name)-1] = 0; // truncate if nec
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue