Home > OS >  Use nested loops as a stream
Use nested loops as a stream

Time:11-01

I am currently looping over a list of IPs and checking them for stuff:

    if let Ok(lines) = read_lines(scan_file).await {
        let stream = LinesStream::new(lines);
        let client = Client::with_uri_str(mongodb_url.clone())
            .await
            .expect("Could not connect to MongoDB!");
        stream
            .map(|string| async {
                if let Ok(iplong) = string {
                    let clone = iplong.clone();
                    let split: Vec<&str> = clone.split(" ").collect();
                    let ip = split.get(3);
                    if ip.is_some() {
                        check_server(ip.unwrap().to_string(), &client).await;
                    }
                }
            })
            .buffer_unordered(1000)
            .collect::<Vec<_>>()
            .await;
    }

(scan_file contains many IPs a got from another tool, which is kind of inconvenient, because I just want to be able to run my tool without depending on anything else. This should also cut the running time by alot, because I do not have to wait for one tool to finish to start mine.) But now I want to generate my own IPs without using a file or a cache:

fn loop_ips() {
    for i1 in 0..256 {
        for i2 in 0..256 {
            for i3 in 0..256 {
                if is_public(i1, i2, i3) {
                    for i4 in 0..256 {}
                }
            }
        }
    }
}

(is_public just checks if it's a public IP so I don't check private ones) And I want to use those without first generating all and storing them and then streaming over them, but with streams so the nested for-loops are an async stream like shown above. I am trying to do it async because the requests take a little bit of time and that multiplied by the amount of IPs would just take ages, so I want to loop async somehow.

I have not tried anything yet, because I don't know how to do it. I ahve searched for an hour or so and I asked on mutliple Discord servers but I got no answers in any way, so I decided to move here. I really don't know what to explain anymore, but SO wants more non-code text.

CodePudding user response:

You can try the async-stream crate. Something like:

fn loop_ips() -> impl Stream<Item = (u32,u32,u32,u32)>
{
    stream! {
        for i1 in 0..256 {
            for i2 in 0..256 {
                for i3 in 0..256 {
                   if is_public(i1, i2, i3) {
                        for i4 in 0..256 {
                            yield (i4, i3, i2, i1);
                        }
                    }
                }
            }
        }
    }
}

You can also consider rayon instead of an async framework. For these kinds of parallelism it is sometimes easier to work with.

  • Related