Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

callback for multiping, #42

Closed
gato-gto opened this issue Dec 1, 2021 · 2 comments
Closed

callback for multiping, #42

gato-gto opened this issue Dec 1, 2021 · 2 comments

Comments

@gato-gto
Copy link

gato-gto commented Dec 1, 2021

I propose to implement a callback for the 'multiping' functions, to perform some functions after receiving a response from the host

Using your library as an example

import asyncio

from datetime import datetime
from icmplib import Host, ICMPLibError, ICMPRequest, AsyncSocket, ICMPv4Socket, ICMPv6Socket
from icmplib.utils import unique_identifier, is_ipv6_address, async_resolve, is_hostname

from test_funcs import getHosts


async def async_ping(address, count=4, interval=1, timeout=2, id=None,
                     source=None, family=None, privileged=True, callback_func=None, **kwargs):
    if is_hostname(address):
        address = (await async_resolve(address, family))[0]

    if is_ipv6_address(address):
        _Socket = ICMPv6Socket
    else:
        _Socket = ICMPv4Socket

    id = id or unique_identifier()
    packets_sent = 0
    rtts = []

    with AsyncSocket(_Socket(source, privileged)) as sock:
        for sequence in range(count):
            if sequence > 0:
                await asyncio.sleep(interval)

            request = ICMPRequest(
                destination=address,
                id=id,
                sequence=sequence,
                **kwargs)

            try:
                sock.send(request)
                packets_sent += 1

                reply = await sock.receive(request, timeout)
                reply.raise_for_status()

                rtt = (reply.time - request.time) * 1000
                rtts.append(rtt)

            except ICMPLibError:
                pass
    if callback_func:
        return await callback_func(Host(address, packets_sent, rtts))

    return Host(address, packets_sent, rtts)


async def async_multiping(addresses, count=2, interval=0.5, timeout=2,
                          concurrent_tasks=50, source=None, family=None, privileged=True,
                          callback_func=None, **kwargs):
    loop = asyncio.get_running_loop()
    tasks = []
    tasks_pending = set()

    for address in addresses:
        if len(tasks_pending) >= concurrent_tasks:
            _, tasks_pending = await asyncio.wait(
                tasks_pending,
                return_when=asyncio.FIRST_COMPLETED)

        task = loop.create_task(
            async_ping(
                address=address,
                count=count,
                interval=interval,
                timeout=timeout,
                source=source,
                family=family,
                privileged=privileged,
                callback_func=callback_func,
                **kwargs)
        )

        tasks.append(task)
        tasks_pending.add(task)

    await asyncio.wait(tasks_pending)

    return [task.result() for task in tasks]


async def callback(host):
    print(host.address)
    # send_me(host) example func
    return host

async def test():
    startTime = datetime.now()

    hosts = await getHosts()

    hostsDown = []
    hostsUp = []

    for result in await async_multiping(
            hosts, count=1, timeout=1, interval=0.4, privileged=False, payload_size=8, callback_func=callback
    ):
        if result.is_alive:
            hostsUp.append(result)
        else:
            hostsDown.append(result)

    exTime = (datetime.now() - startTime).total_seconds()

    print(' -', len(hostsUp), 'hosts up out of', len(hosts))

    print(' -', 'execution speed', exTime, 'secs')


asyncio.run(test())

Output

172.20.3.12
172.20.3.198
172.20.3.97
172.20.4.136
172.20.4.184
 - 1160 hosts up out of 1173
 - execution speed 1.371824 secs
@ValentinBELYN
Copy link
Owner

Hi @gato-gto,

Thank you for the suggestion. The multiping function was not designed for this purpose but the idea is interesting.

I will add it in a next update.

@ValentinBELYN
Copy link
Owner

Sorry, ultimately this won't be implemented in icmplib.

I think it's cleaner to use the sockets provided by icmplib directly to achieve this goal.

@ValentinBELYN ValentinBELYN closed this as not planned Won't fix, can't repro, duplicate, stale Apr 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants