summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau2025-05-27 09:39:10 +0000
committerFelix Fietkau2025-05-30 17:42:41 +0000
commit790b41b6b9871b7ff8705100d38fe0deee013ffd (patch)
tree3114f5d0b24ac4e3f10352744806a909769db25a
parent20e4b342aa0844417bbf00aa906a5ec5c9c84d7d (diff)
pex: indicate refused update requests
This is used, in case an unknown peer requests a network update. That way the peer can know that it is not considered to be a part of the network by the remote peer. Signed-off-by: Felix Fietkau <nbd@nbd.name>
-rw-r--r--network.h1
-rw-r--r--pex-msg.c7
-rw-r--r--pex-msg.h1
-rw-r--r--pex.c19
-rw-r--r--ubus.c5
5 files changed, 30 insertions, 3 deletions
diff --git a/network.h b/network.h
index aa45b6b..57450cc 100644
--- a/network.h
+++ b/network.h
@@ -57,6 +57,7 @@ struct network {
size_t net_data_len;
uint64_t net_data_version;
int num_net_queries;
+ unsigned int update_refused;
struct uloop_timeout reload_timer;
diff --git a/pex-msg.c b/pex-msg.c
index fef5505..34b3bb9 100644
--- a/pex-msg.c
+++ b/pex-msg.c
@@ -480,6 +480,8 @@ void *pex_msg_update_response_recv(const void *data, int len, enum pex_opcode op
uint8_t enc_key[CURVE25519_KEY_SIZE];
void *ret;
+ if (timestamp)
+ *timestamp = 0;
*data_len = 0;
if (op == PEX_MSG_UPDATE_RESPONSE) {
const struct pex_update_response *res = data;
@@ -510,7 +512,8 @@ void *pex_msg_update_response_recv(const void *data, int len, enum pex_opcode op
data += sizeof(*res);
len -= sizeof(*res);
- } else if (op == PEX_MSG_UPDATE_RESPONSE_NO_DATA) {
+ } else if (op == PEX_MSG_UPDATE_RESPONSE_NO_DATA ||
+ op == PEX_MSG_UPDATE_RESPONSE_REFUSED) {
const struct pex_update_response_no_data *res = data;
if (len < sizeof(*res) || !res->cur_version)
@@ -520,6 +523,8 @@ void *pex_msg_update_response_recv(const void *data, int len, enum pex_opcode op
if (!ctx)
return NULL;
+ if (timestamp)
+ *timestamp = be64_to_cpu(res->cur_version);
goto error;
} else {
return NULL;
diff --git a/pex-msg.h b/pex-msg.h
index 36aade2..473d7ed 100644
--- a/pex-msg.h
+++ b/pex-msg.h
@@ -26,6 +26,7 @@ enum pex_opcode {
PEX_MSG_ENDPOINT_NOTIFY,
PEX_MSG_ENDPOINT_PORT_NOTIFY,
PEX_MSG_ENROLL,
+ PEX_MSG_UPDATE_RESPONSE_REFUSED,
};
#define PEX_ID_LEN 8
diff --git a/pex.c b/pex.c
index cfd238f..a1c602d 100644
--- a/pex.c
+++ b/pex.c
@@ -572,7 +572,7 @@ network_pex_recv_update_request(struct network *net, struct network_peer *peer,
D("receive update request, local version=%"PRIu64", remote version=%"PRIu64, net->net_data_version, req_version);
- if (req_version && req_version >= net->net_data_version) {
+ if (peer && req_version && req_version >= net->net_data_version) {
struct pex_update_response_no_data *res;
pex_msg_init_ext(net, PEX_MSG_UPDATE_RESPONSE_NO_DATA, !!addr);
@@ -584,6 +584,15 @@ network_pex_recv_update_request(struct network *net, struct network_peer *peer,
if (req_version > net->net_data_version)
network_pex_send_update_request(net, peer, addr);
+ else if (!peer && net->net_data_len) {
+ struct pex_update_response_no_data *res;
+
+ pex_msg_init_ext(net, PEX_MSG_UPDATE_RESPONSE_REFUSED, !!addr);
+ res = pex_msg_append(sizeof(*res));
+ res->req_id = req->req_id;
+ res->cur_version = cpu_to_be64(net->net_data_version);
+ pex_msg_send_ext(net, peer, addr);
+ }
if (!peer || !net->net_data_len)
return;
@@ -628,8 +637,12 @@ network_pex_recv_update_response(struct network *net, const uint8_t *data, size_
return;
net_data = pex_msg_update_response_recv(data, len, op, &net_data_len, &version);
- if (!net_data)
+ if (!net_data) {
+ if (op == PEX_MSG_UPDATE_RESPONSE_REFUSED && net_data_len == -1 &&
+ version > net->net_data_version)
+ net->update_refused++;
return;
+ }
if (version <= net->net_data_version) {
free(net_data);
@@ -684,6 +697,7 @@ network_pex_recv(struct network *net, struct network_peer *peer, struct pex_hdr
case PEX_MSG_UPDATE_RESPONSE:
case PEX_MSG_UPDATE_RESPONSE_DATA:
case PEX_MSG_UPDATE_RESPONSE_NO_DATA:
+ case PEX_MSG_UPDATE_RESPONSE_REFUSED:
network_pex_recv_update_response(net, data, hdr->len,
NULL, hdr->opcode);
break;
@@ -1063,6 +1077,7 @@ global_pex_recv(void *msg, size_t msg_len, struct sockaddr_in6 *addr)
fallthrough;
case PEX_MSG_UPDATE_RESPONSE_DATA:
case PEX_MSG_UPDATE_RESPONSE_NO_DATA:
+ case PEX_MSG_UPDATE_RESPONSE_REFUSED:
network_pex_recv_update_response(net, data, hdr->len, addr, hdr->opcode);
break;
case PEX_MSG_ENDPOINT_PORT_NOTIFY:
diff --git a/ubus.c b/ubus.c
index 47fa743..d1852b5 100644
--- a/ubus.c
+++ b/ubus.c
@@ -71,8 +71,13 @@ __network_dump(struct blob_buf *buf, struct network *net)
str = blobmsg_alloc_string_buffer(buf, "local_address", INET6_ADDRSTRLEN);
inet_ntop(AF_INET6, &local->peer.local_addr.in6, str, INET6_ADDRSTRLEN);
blobmsg_add_string_buffer(buf);
+ } else {
+ if (net->net_data_len)
+ blobmsg_add_u8(buf, "no_local_host", true);
}
+ if (net->update_refused)
+ blobmsg_add_u32(buf, "update_refused", net->update_refused);
c = blobmsg_open_table(buf, "peers");
vlist_for_each_element(&net->peers, peer, node) {