Skip to content

Commit

Permalink
Resources starting with '/@/' never match resources not starting with…
Browse files Browse the repository at this point in the history
… '/@/'
  • Loading branch information
OlivierHecart committed Oct 29, 2020
1 parent abe9216 commit ae414e4
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 25 deletions.
11 changes: 11 additions & 0 deletions zenoh-protocol/src/core/rname.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,14 @@ DEFINE_INTERSECT!(res_intersect, end, wild, next, chunk_intersect);
pub fn intersect(s1: &str, s2: &str) -> bool {
res_intersect(s1, s2)
}

pub const ADMIN_PREFIX: &str = "/@/";

#[inline(always)]
pub fn matches(s1: &str, s2: &str) -> bool {
if s1.starts_with(ADMIN_PREFIX) == s2.starts_with(ADMIN_PREFIX) {
intersect(s1, s2)
} else {
false
}
}
4 changes: 1 addition & 3 deletions zenoh-router/src/routing/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,7 @@ async fn route_query_to_map(
src_qid: qid,
});
let mut faces = HashMap::new();
for res in
Resource::get_matches(&tables, &[&prefix.name(), suffix].concat())
{
for res in Resource::get_matches(&tables, &[&prefix.name(), suffix].concat()) {
unsafe {
let mut res = res.upgrade().unwrap();
for (sid, context) in &mut Arc::get_mut_unchecked(&mut res).contexts {
Expand Down
34 changes: 23 additions & 11 deletions zenoh-router/src/routing/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::routing::broker::Tables;
use crate::routing::face::FaceState;
use async_std::sync::{Arc, Weak};
use std::collections::HashMap;
use zenoh_protocol::core::rname::intersect;
use zenoh_protocol::core::rname;
use zenoh_protocol::core::{SubInfo, ZInt};
use zenoh_protocol::io::RBuf;
use zenoh_protocol::proto::DataInfo;
Expand Down Expand Up @@ -270,40 +270,52 @@ impl Resource {
}

pub fn get_matches(tables: &Tables, rname: &str) -> Vec<Weak<Resource>> {
fn get_matches_from(rname: &str, from: &Arc<Resource>) -> Vec<Weak<Resource>> {
fn get_matches_from(
rname: &str,
is_admin: bool,
from: &Arc<Resource>,
) -> Vec<Weak<Resource>> {
let mut matches = Vec::new();
if from.parent.is_none() {
for child in from.childs.values() {
matches.append(&mut get_matches_from(rname, child));
matches.append(&mut get_matches_from(rname, is_admin, child));
}
return matches;
}
if rname.is_empty() {
if from.suffix == "/**" || from.suffix == "/" {
matches.push(Arc::downgrade(from));
if is_admin == from.name().starts_with(rname::ADMIN_PREFIX) {
matches.push(Arc::downgrade(from));
}
for child in from.childs.values() {
matches.append(&mut get_matches_from(rname, child));
matches.append(&mut get_matches_from(rname, is_admin, child));
}
}
return matches;
}
let (chunk, rest) = Resource::fst_chunk(rname);
if intersect(chunk, &from.suffix) {
if rname::intersect(chunk, &from.suffix) {
if rest.is_empty() || rest == "/" || rest == "/**" {
matches.push(Arc::downgrade(from));
if is_admin == from.name().starts_with(rname::ADMIN_PREFIX) {
matches.push(Arc::downgrade(from));
}
} else if chunk == "/**" || from.suffix == "/**" {
matches.append(&mut get_matches_from(rest, from));
matches.append(&mut get_matches_from(rest, is_admin, from));
}
for child in from.childs.values() {
matches.append(&mut get_matches_from(rest, child));
matches.append(&mut get_matches_from(rest, is_admin, child));
if chunk == "/**" || from.suffix == "/**" {
matches.append(&mut get_matches_from(rname, child));
matches.append(&mut get_matches_from(rname, is_admin, child));
}
}
}
matches
};
get_matches_from(rname, &tables.root_res)
get_matches_from(
rname,
rname.starts_with(rname::ADMIN_PREFIX),
&tables.root_res,
)
}

pub fn match_resource(tables: &Tables, res: &mut Arc<Resource>) {
Expand Down
22 changes: 11 additions & 11 deletions zenoh/src/net/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,12 +338,12 @@ impl Session {
let resname = state.localkey_to_resname(resource)?;
let mut res = Resource::new(resname.clone());
for sub in state.subscribers.values() {
if rname::intersect(&resname, &sub.resname) {
if rname::matches(&resname, &sub.resname) {
res.subscribers.push(sub.clone());
}
}
for cb_sub in state.callback_subscribers.values() {
if rname::intersect(&resname, &cb_sub.resname) {
if rname::matches(&resname, &cb_sub.resname) {
res.callback_subscribers.push(cb_sub.clone());
}
}
Expand Down Expand Up @@ -489,12 +489,12 @@ impl Session {
});
state.subscribers.insert(id, sub_state.clone());
for res in state.local_resources.values_mut() {
if rname::intersect(&resname, &res.name) {
if rname::matches(&resname, &res.name) {
res.subscribers.push(sub_state.clone());
}
}
for res in state.remote_resources.values_mut() {
if rname::intersect(&resname, &res.name) {
if rname::matches(&resname, &res.name) {
res.subscribers.push(sub_state.clone());
}
}
Expand Down Expand Up @@ -587,12 +587,12 @@ impl Session {
});
state.callback_subscribers.insert(id, sub_state.clone());
for res in state.local_resources.values_mut() {
if rname::intersect(&resname, &res.name) {
if rname::matches(&resname, &res.name) {
res.callback_subscribers.push(sub_state.clone());
}
}
for res in state.remote_resources.values_mut() {
if rname::intersect(&resname, &res.name) {
if rname::matches(&resname, &res.name) {
res.callback_subscribers.push(sub_state.clone());
}
}
Expand Down Expand Up @@ -842,7 +842,7 @@ impl Session {
Ok(resname) => {
// Call matching callback_subscribers
for sub in state.callback_subscribers.values() {
if rname::intersect(&sub.resname, &resname) {
if rname::matches(&sub.resname, &resname) {
let handler = &mut *sub.dhandler.write().await;
handler(Sample {
res_name: resname.clone(),
Expand All @@ -855,7 +855,7 @@ impl Session {
let subs = state
.subscribers
.values()
.filter(|sub| rname::intersect(&sub.resname, &resname))
.filter(|sub| rname::matches(&sub.resname, &resname))
.map(|sub| sub.sender.clone())
.collect::<Vec<Sender<Sample>>>();
(resname, subs)
Expand Down Expand Up @@ -984,7 +984,7 @@ impl Session {
.filter(
|queryable| match state.localkey_to_resname(&queryable.reskey) {
Ok(qablname) => {
rname::intersect(&qablname, &resname)
rname::matches(&qablname, &resname)
&& ((queryable.kind == queryable::ALL_KINDS
|| target.kind == queryable::ALL_KINDS)
|| (queryable.kind & target.kind != 0))
Expand Down Expand Up @@ -1063,12 +1063,12 @@ impl Primitives for Session {
Ok(resname) => {
let mut res = Resource::new(resname.clone());
for sub in state.subscribers.values() {
if rname::intersect(&resname, &sub.resname) {
if rname::matches(&resname, &sub.resname) {
res.subscribers.push(sub.clone());
}
}
for cb_sub in state.callback_subscribers.values() {
if rname::intersect(&resname, &cb_sub.resname) {
if rname::matches(&resname, &cb_sub.resname) {
res.callback_subscribers.push(cb_sub.clone());
}
}
Expand Down

0 comments on commit ae414e4

Please sign in to comment.