Skip to content

No dial_args() function for converting multiaddrs to socket-ready strings #114

Description

@sumanjeet0012

Go's manet package provides DialArgs(ma) which converts a multiaddr to (network, address) strings suitable for socket.connect(). Python has get_multiaddr_options() in utils.py which returns a dict but doesn't produce socket-ready strings.

Problem

Go's DialArgs():

func DialArgs(m ma.Multiaddr) (string, string, error) {
    // Returns ("tcp4", "1.2.3.4:80") for /ip4/1.2.3.4/tcp/80
    // Returns ("tcp6", "[::1]:80") for /ip6/::1/tcp/80
    // Returns ("udp4", "1.2.3.4:53") for /ip4/1.2.3.4/udp/53
    // Returns ("unix", "/var/run/docker.sock") for /unix/var/run/docker.sock
    // Returns ("tcp4", "example.com:80") for /dns4/example.com/tcp/80
}

Python's get_multiaddr_options():

opts = get_multiaddr_options(Multiaddr("/ip4/1.2.3.4/tcp/80"))
# Returns: {"family": 4, "host": "1.2.3.4", "transport": "tcp", "port": 80}
# User must manually construct: ("tcp4", "1.2.3.4:80")

Proposed Solution

Add dial_args() to utils.py:

def dial_args(ma: Multiaddr) -> tuple[str, str]:
    """Convert a multiaddr to (network, address) for socket.connect().

    >>> dial_args(Multiaddr("/ip4/1.2.3.4/tcp/80"))
    ('tcp4', '1.2.3.4:80')
    >>> dial_args(Multiaddr("/ip6/::1/tcp/80"))
    ('tcp6', '[::1]:80')
    >>> dial_args(Multiaddr("/unix/var/run/docker.sock"))
    ('unix', '/var/run/docker.sock')
    """
    opts = get_multiaddr_options(ma)
    if opts is None:
        # Check for unix
        protos = list(ma.protocols())
        if protos and protos[0].name == "unix":
            return ("unix", ma.value_for_protocol("unix"))
        raise ValueError(f"{ma} is not a 'thin waist' address")

    family_suffix = "4" if opts["family"] == 4 else "6"
    network = f"{opts['transport']}{family_suffix}"

    if opts["family"] == 6:
        address = f"[{opts['host']}]:{opts['port']}"
    else:
        address = f"{opts['host']}:{opts['port']}"

    return (network, address)

Export from __init__.py and add tests.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions