1

I am trying to write a discovery function in Rust that discovers the device IP in LAN, this function should sends HTTP requests for all possible IPs in the IP space and once receives 200 status return the value and cancels all others requests (by dropping the future in case reqwest used)

async fn discover() -> Result<String, ()> {
    for i in 0..256 {
        tokio::spawn(async move {
            let url = format!("http://192.168.0.{i}:8000/ping");

            reqwest::get(url).await;
        });
    }
}

Edit 1

once receives 200 status return the value and cancels all others requests

We would like to also validate the response content to make sure that this is the correct device and not someone who is trying to spy on the network we will validate the response by verifying the JWT token returning from the /ping endpoint, how can we do this

Murad
  • 13
  • 4

1 Answers1

1

This may be achievable with the futures-crate and select_ok().

You can do the following:

  • convert the range in an Iterator and map each element i into a reqwest request. select_ok needs the Futures in the Vec to implement UnPin; that's why I used .boxed() here.

  • pass the Vec of futures into select_ok

  • the response will contain the first succesful future result

  • we can use the remaining_futures to cancel the remaining requests with drop (I am not sure if that works, you need to test this)

use futures::{future::select_ok, FutureExt};

async fn discover() {
    let futures = (0..256)
        .into_iter()
        .map(|i| {
            let url = format!("http://192.168.0.{i}:8000/ping");

            return reqwest::get(url).boxed();
        })
        .collect::<Vec<_>>();

    let (response, mut remaining_futures) = select_ok(futures).await.unwrap();

    remaining_futures.iter_mut().for_each(|f| drop(f));
}
Tobias S.
  • 21,159
  • 4
  • 27
  • 45
  • Thanks, this works fine, could you please extending this answer to allow validating the response before accepting it as OK, the /ping endpoint will return a JWT token that I need to validate to make sure that this is the real device and not someone else trying to spy on the network – Murad Oct 15 '22 at 11:34
  • @Murad - How would that validation look like? – Tobias S. Oct 15 '22 at 12:25
  • I need to get the response content which is JSON containing a JWT, that I need to verify on my end to make sure that the device I pinged is really the device that I want to connect to cause we share the same SECRET KEY – Murad Oct 15 '22 at 12:27
  • @Murad - You can put that validation in an `.and_then()` like so: `reqwest::get(url).and_then(|res| { /* ... validation here ... /* ).boxed()` – Tobias S. Oct 15 '22 at 12:30