Network address types

Related tags

Network netaddr
Overview

netaddr Test Status Go Reference

What

This is a package containing a new IP address type for Go.

See its docs: https://pkg.go.dev/inet.af/netaddr

Motivation

See https://tailscale.com/blog/netaddr-new-ip-type-for-go/ for a long blog post about why we made a new IP address package.

Other links:

Maturity

This package is mature, optimized, and used heavily in production at Tailscale. However, API stability is not yet guaranteed.

Testing

In addition to regular Go tests, netaddr uses fuzzing. The corpus is stored separately, in a submodule, to minimize the impact on everyone else.

To use:

$ git submodule update --init
$ go get -u github.com/dvyukov/go-fuzz/go-fuzz github.com/dvyukov/go-fuzz/go-fuzz-build
$ go-fuzz-build && go-fuzz
Issues
  • Change representation of IP?

    Change representation of IP?

    I think there's still some general unhappiness that our IP type requires an allocation to box the [4]byte or [16]byte into an interface.

    I've previously pushed back against any change to the IP type's representation because we have 4 conflicting requirements that I never saw the way out of:

    1. must be comparable
    2. must support IPv6 zones
    3. must be able to distinguish IPv4 and IPv4-mapped IPv6 addresses (that is, 1.2.3.4 and ::ffff::1.2.3.4 should be different)
    4. shouldn't be bigger than a slice (24 bytes: three 8-byte pointers), which is my upper bound for tolerable value types

    We also discussed the solution to requirement (3) as needing "a bool", but because an IPv4 address can't have a zone, we can re-use a sentinel zone value as meaning "actually an IPv4 address".

    Which means we have:

        type IP struct {
            addr [16]byte
            zone ZT
        }
    

    The question then is: what type is the zone, ZT? If the goal is 24 bytes, we only have 8 bytes to work with, so the natural choice of string (at 16 bytes: a pointer and int) is out. That would bump it up to 32 bytes. (If we were cool with 32-byte IP addresses, that's an answer, but I'm not particularly happy about that.)

    But if we used an integer for the zone, we could be smaller, though.

    On Windows, a network adapter's local ID (LUID) is a ULONG64 (uint64): https://docs.microsoft.com/en-us/windows/win32/api/ifdef/ns-ifdef-net_luid_lh

    Maybe that's sufficient? We'd need to find a sentinel zone uint64 number to use for "actually an IPv4 address".

    It does mean that we wouldn't be able to map an arbitrary https://golang.org/pkg/net/#IPAddr Zone string,

    type IPAddr struct {
        IP   IP
        Zone string // IPv6 scoped addressing zone; added in Go 1.1
    }
    

    ... into our IP type if the Zone was not the name of a local interface. Maybe that's okay?

    The Go standard library maintains a cache mapping between integers and strings internally:

    https://github.com/golang/go/blob/go1.16beta1/src/net/interface.go#L178

    We could too.

    Thoughts, @crawshaw @danderson @mdlayher?

    opened by bradfitz 35
  • runtime: marked free object in span ...

    runtime: marked free object in span ...

    Ran the netaddr benchmarks to test a change, with go test -bench=. -count=5. Partway through, the benchmark crashed and reported a pointer to a freed object:

    runtime: marked free object in span 0x7fc17c424910, elemsize=32 freeindex=0 (bad use of unsafe.Pointer? try -d=checkptr)
    0xc000136000 alloc marked  
    0xc000136020 free  unmarked
    0xc000136040 alloc marked  
    0xc000136060 alloc marked  
    0xc000136080 free  marked   zombie
    000000c000136080:  0000000000582bc0  000000c00043a000 
    000000c000136090:  00000000000c5eb0  0000000000000000 
    0xc0001360a0 free  unmarked
    0xc0001360c0 free  unmarked
    0xc0001360e0 free  unmarked
    0xc000136100 free  unmarked
    0xc000136120 free  unmarked
    0xc000136140 free  unmarked
    0xc000136160 free  unmarked
    0xc000136180 free  unmarked
    0xc0001361a0 free  unmarked
    0xc0001361c0 free  unmarked
    0xc0001361e0 free  unmarked
    0xc000136200 free  unmarked
    0xc000136220 alloc marked  
    0xc000136240 free  unmarked
    0xc000136260 free  unmarked
    0xc000136280 free  unmarked
    0xc0001362a0 free  unmarked
    0xc0001362c0 free  unmarked
    0xc0001362e0 free  unmarked
    0xc000136300 free  unmarked
    0xc000136320 free  unmarked
    0xc000136340 free  unmarked
    0xc000136360 free  unmarked
    0xc000136380 free  unmarked
    0xc0001363a0 free  unmarked
    0xc0001363c0 free  unmarked
    0xc0001363e0 free  unmarked
    0xc000136400 free  unmarked
    0xc000136420 free  unmarked
    0xc000136440 free  unmarked
    0xc000136460 free  unmarked
    0xc000136480 free  unmarked
    0xc0001364a0 free  unmarked
    0xc0001364c0 free  unmarked
    0xc0001364e0 free  unmarked
    0xc000136500 free  unmarked
    0xc000136520 free  unmarked
    0xc000136540 free  unmarked
    0xc000136560 free  unmarked
    0xc000136580 free  unmarked
    0xc0001365a0 free  unmarked
    0xc0001365c0 free  unmarked
    0xc0001365e0 free  unmarked
    0xc000136600 free  unmarked
    0xc000136620 free  unmarked
    0xc000136640 free  unmarked
    0xc000136660 free  unmarked
    0xc000136680 free  unmarked
    0xc0001366a0 free  unmarked
    0xc0001366c0 free  unmarked
    0xc0001366e0 free  unmarked
    0xc000136700 free  unmarked
    0xc000136720 free  unmarked
    0xc000136740 free  unmarked
    0xc000136760 free  unmarked
    0xc000136780 free  unmarked
    0xc0001367a0 free  unmarked
    0xc0001367c0 free  unmarked
    0xc0001367e0 free  unmarked
    0xc000136800 free  unmarked
    0xc000136820 free  unmarked
    0xc000136840 free  unmarked
    0xc000136860 free  unmarked
    0xc000136880 free  unmarked
    0xc0001368a0 free  unmarked
    0xc0001368c0 free  unmarked
    0xc0001368e0 free  unmarked
    0xc000136900 free  unmarked
    0xc000136920 free  unmarked
    0xc000136940 free  unmarked
    0xc000136960 free  unmarked
    0xc000136980 free  unmarked
    0xc0001369a0 free  unmarked
    0xc0001369c0 free  unmarked
    0xc0001369e0 free  unmarked
    0xc000136a00 free  unmarked
    0xc000136a20 free  unmarked
    0xc000136a40 free  unmarked
    0xc000136a60 free  unmarked
    0xc000136a80 free  unmarked
    0xc000136aa0 free  unmarked
    0xc000136ac0 free  unmarked
    0xc000136ae0 free  unmarked
    0xc000136b00 free  unmarked
    0xc000136b20 free  unmarked
    0xc000136b40 free  unmarked
    0xc000136b60 free  unmarked
    0xc000136b80 free  unmarked
    0xc000136ba0 free  unmarked
    0xc000136bc0 free  unmarked
    0xc000136be0 free  unmarked
    0xc000136c00 free  unmarked
    0xc000136c20 free  unmarked
    0xc000136c40 free  unmarked
    0xc000136c60 free  unmarked
    0xc000136c80 free  unmarked
    0xc000136ca0 free  unmarked
    0xc000136cc0 free  unmarked
    0xc000136ce0 free  unmarked
    0xc000136d00 free  unmarked
    0xc000136d20 free  unmarked
    0xc000136d40 free  unmarked
    0xc000136d60 free  unmarked
    0xc000136d80 free  unmarked
    0xc000136da0 free  unmarked
    0xc000136dc0 free  unmarked
    0xc000136de0 free  unmarked
    0xc000136e00 free  unmarked
    0xc000136e20 free  unmarked
    0xc000136e40 free  unmarked
    0xc000136e60 free  unmarked
    0xc000136e80 free  unmarked
    0xc000136ea0 free  unmarked
    0xc000136ec0 free  unmarked
    0xc000136ee0 free  unmarked
    0xc000136f00 free  unmarked
    0xc000136f20 free  unmarked
    0xc000136f40 free  unmarked
    0xc000136f60 free  unmarked
    0xc000136f80 free  unmarked
    0xc000136fa0 free  unmarked
    0xc000136fc0 free  unmarked
    0xc000136fe0 free  unmarked
    0xc000137000 free  unmarked
    0xc000137020 free  unmarked
    0xc000137040 free  unmarked
    0xc000137060 free  unmarked
    0xc000137080 free  unmarked
    0xc0001370a0 free  unmarked
    0xc0001370c0 free  unmarked
    0xc0001370e0 alloc marked  
    0xc000137100 free  unmarked
    0xc000137120 free  unmarked
    0xc000137140 free  unmarked
    0xc000137160 free  unmarked
    0xc000137180 free  unmarked
    0xc0001371a0 free  unmarked
    0xc0001371c0 free  unmarked
    0xc0001371e0 free  unmarked
    0xc000137200 free  unmarked
    0xc000137220 free  unmarked
    0xc000137240 free  unmarked
    0xc000137260 free  unmarked
    0xc000137280 free  unmarked
    0xc0001372a0 free  unmarked
    0xc0001372c0 free  unmarked
    0xc0001372e0 free  unmarked
    0xc000137300 free  unmarked
    0xc000137320 free  unmarked
    0xc000137340 free  unmarked
    0xc000137360 free  unmarked
    0xc000137380 free  unmarked
    0xc0001373a0 free  unmarked
    0xc0001373c0 free  unmarked
    0xc0001373e0 free  unmarked
    0xc000137400 free  unmarked
    0xc000137420 free  unmarked
    0xc000137440 free  unmarked
    0xc000137460 free  unmarked
    0xc000137480 free  unmarked
    0xc0001374a0 free  unmarked
    0xc0001374c0 free  unmarked
    0xc0001374e0 free  unmarked
    0xc000137500 free  unmarked
    0xc000137520 free  unmarked
    0xc000137540 free  unmarked
    0xc000137560 free  unmarked
    0xc000137580 free  unmarked
    0xc0001375a0 free  unmarked
    0xc0001375c0 free  unmarked
    0xc0001375e0 free  unmarked
    0xc000137600 free  unmarked
    0xc000137620 free  unmarked
    0xc000137640 free  unmarked
    0xc000137660 free  unmarked
    0xc000137680 free  unmarked
    0xc0001376a0 free  unmarked
    0xc0001376c0 free  unmarked
    0xc0001376e0 free  unmarked
    0xc000137700 free  unmarked
    0xc000137720 free  unmarked
    0xc000137740 free  unmarked
    0xc000137760 free  unmarked
    0xc000137780 free  unmarked
    0xc0001377a0 free  unmarked
    0xc0001377c0 free  unmarked
    0xc0001377e0 free  unmarked
    0xc000137800 free  unmarked
    0xc000137820 free  unmarked
    0xc000137840 free  unmarked
    0xc000137860 free  unmarked
    0xc000137880 free  unmarked
    0xc0001378a0 free  unmarked
    0xc0001378c0 free  unmarked
    0xc0001378e0 free  unmarked
    0xc000137900 free  unmarked
    0xc000137920 free  unmarked
    0xc000137940 free  unmarked
    0xc000137960 free  unmarked
    0xc000137980 free  unmarked
    0xc0001379a0 free  unmarked
    0xc0001379c0 free  unmarked
    0xc0001379e0 free  unmarked
    0xc000137a00 free  unmarked
    0xc000137a20 free  unmarked
    0xc000137a40 free  unmarked
    0xc000137a60 free  unmarked
    0xc000137a80 free  unmarked
    0xc000137aa0 free  unmarked
    0xc000137ac0 free  unmarked
    0xc000137ae0 free  unmarked
    0xc000137b00 free  unmarked
    0xc000137b20 free  unmarked
    0xc000137b40 free  unmarked
    0xc000137b60 free  unmarked
    0xc000137b80 free  unmarked
    0xc000137ba0 free  unmarked
    0xc000137bc0 free  unmarked
    0xc000137be0 free  unmarked
    0xc000137c00 free  unmarked
    0xc000137c20 free  unmarked
    0xc000137c40 free  unmarked
    0xc000137c60 free  unmarked
    0xc000137c80 free  unmarked
    0xc000137ca0 free  unmarked
    0xc000137cc0 free  unmarked
    0xc000137ce0 free  unmarked
    0xc000137d00 free  unmarked
    0xc000137d20 free  unmarked
    0xc000137d40 free  unmarked
    0xc000137d60 free  unmarked
    0xc000137d80 free  unmarked
    0xc000137da0 free  unmarked
    0xc000137dc0 free  unmarked
    0xc000137de0 free  unmarked
    0xc000137e00 free  unmarked
    0xc000137e20 free  unmarked
    0xc000137e40 free  unmarked
    0xc000137e60 free  unmarked
    0xc000137e80 free  unmarked
    0xc000137ea0 free  unmarked
    0xc000137ec0 free  unmarked
    0xc000137ee0 free  unmarked
    0xc000137f00 free  unmarked
    0xc000137f20 free  unmarked
    0xc000137f40 free  unmarked
    0xc000137f60 free  unmarked
    0xc000137f80 free  unmarked
    0xc000137fa0 free  unmarked
    0xc000137fc0 free  unmarked
    0xc000137fe0 free  unmarked
    fatal error: found pointer to free object
    
    runtime stack:
    runtime.SetFinalizer.func1()
    	/nix/store/whf767pjnhyllfk1jkma1rg4np2dizcc-go-1.15.5/share/go/src/runtime/mfinal.go:369 +0x2e
    
    goroutine 960 [running]:
    runtime.systemstack_switch()
    	/nix/store/whf767pjnhyllfk1jkma1rg4np2dizcc-go-1.15.5/share/go/src/runtime/asm_amd64.s:330 fp=0xc000069c00 sp=0xc000069bf8 pc=0x46a700
    runtime.SetFinalizer(0x589b20, 0xc000136080, 0x0, 0x0)
    	/nix/store/whf767pjnhyllfk1jkma1rg4np2dizcc-go-1.15.5/share/go/src/runtime/mfinal.go:368 +0x465 fp=0xc000069ce8 sp=0xc000069c00 pc=0x419da5
    go4.org/intern.Get(0x582bc0, 0xc0005ac050, 0x0)
    	/home/dave/.local/go.path/pkg/mod/go4.org/[email protected]/intern.go:69 +0x185 fp=0xc000069d60 sp=0xc000069ce8 pc=0x52a025
    inet.af/netaddr.IP.WithZone(0x80fe, 0xe1c29f118c3ec01c, 0xc000136060, 0x5bee97, 0x5, 0x0, 0x0, 0x0)
    	/home/dave/hack/netaddr/netaddr.go:356 +0xce fp=0xc000069da0 sp=0xc000069d60 pc=0x5459ae
    inet.af/netaddr.ParseIP(0x5bee7d, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0)
    	/home/dave/hack/netaddr/netaddr.go:190 +0x1fb fp=0xc000069e98 sp=0xc000069da0 pc=0x54483b
    inet.af/netaddr.BenchmarkParseIPv6(0xc0000aa480)
    	/home/dave/hack/netaddr/netaddr_test.go:1225 +0x4b fp=0xc000069ee8 sp=0xc000069e98 pc=0x556e8b
    testing.(*B).runN(0xc0000aa480, 0x1be7ac)
    	/nix/store/whf767pjnhyllfk1jkma1rg4np2dizcc-go-1.15.5/share/go/src/testing/benchmark.go:191 +0xeb fp=0xc000069f58 sp=0xc000069ee8 pc=0x4da7eb
    testing.(*B).launch(0xc0000aa480)
    	/nix/store/whf767pjnhyllfk1jkma1rg4np2dizcc-go-1.15.5/share/go/src/testing/benchmark.go:321 +0xea fp=0xc000069fd8 sp=0xc000069f58 pc=0x4daeaa
    runtime.goexit()
    	/nix/store/whf767pjnhyllfk1jkma1rg4np2dizcc-go-1.15.5/share/go/src/runtime/asm_amd64.s:1374 +0x1 fp=0xc000069fe0 sp=0xc000069fd8 pc=0x46c4e1
    created by testing.(*B).doBench
    	/nix/store/whf767pjnhyllfk1jkma1rg4np2dizcc-go-1.15.5/share/go/src/testing/benchmark.go:276 +0x55
    
    goroutine 1 [chan receive]:
    testing.(*B).doBench(0xc0000aa480, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    	/nix/store/whf767pjnhyllfk1jkma1rg4np2dizcc-go-1.15.5/share/go/src/testing/benchmark.go:277 +0x73
    testing.(*benchContext).processBench(0xc0000e8040, 0xc0000aa480)
    	/nix/store/whf767pjnhyllfk1jkma1rg4np2dizcc-go-1.15.5/share/go/src/testing/benchmark.go:572 +0x226
    testing.(*B).run(0xc0000aa480)
    	/nix/store/whf767pjnhyllfk1jkma1rg4np2dizcc-go-1.15.5/share/go/src/testing/benchmark.go:268 +0x65
    testing.(*B).Run(0xc0000aa240, 0x5baeb2, 0x12, 0x5c4308, 0x4da400)
    	/nix/store/whf767pjnhyllfk1jkma1rg4np2dizcc-go-1.15.5/share/go/src/testing/benchmark.go:657 +0x42f
    testing.runBenchmarks.func1(0xc0000aa240)
    	/nix/store/whf767pjnhyllfk1jkma1rg4np2dizcc-go-1.15.5/share/go/src/testing/benchmark.go:533 +0x78
    testing.(*B).runN(0xc0000aa240, 0x1)
    	/nix/store/whf767pjnhyllfk1jkma1rg4np2dizcc-go-1.15.5/share/go/src/testing/benchmark.go:191 +0xeb
    testing.runBenchmarks(0x5ba1b6, 0xf, 0xc0000e8020, 0x6d3b40, 0xc, 0xc, 0x6d7d20)
    	/nix/store/whf767pjnhyllfk1jkma1rg4np2dizcc-go-1.15.5/share/go/src/testing/benchmark.go:542 +0x3d1
    testing.(*M).Run(0xc000154000, 0x0)
    	/nix/store/whf767pjnhyllfk1jkma1rg4np2dizcc-go-1.15.5/share/go/src/testing/testing.go:1351 +0x51d
    main.main()
    	_testmain.go:137 +0x138
    

    cc @bradfitz @josharian, looks like there's a race/bug in the implementation of intern?

    opened by danderson 12
  • proposal: add additional methods to support IPv6 expansion

    proposal: add additional methods to support IPv6 expansion

    Hi There,

    I saw this package and thought that it overlapped with some work that I have been doing recently. With IPv6 the addresses are usually shortened, have you thought about adding a feature where you can print out the expanded IPv6 format?

    Example

    ip, _ := netaddr.ParseIP("2404:6800:4006:809::200e")
    ip.As16ExpandedShort() // 2404:6800:4006:0809:0:0:0:200e
    ip.As16ExpandedLong() // 2.4.0.4.6.8.0.0.4.0.0.6.0.8.0.9.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.e
    

    The use case for this is the automatic creation of DNS IPv6 PTR records however I am sure that there are other use cases. Is this something that you have thought about as an addition to this package or do you see it as out of scope?

    If it is in scope I am happy to do the work and provide you with a PR, I just wanted to check if its aligned with where you want to take your package.

    opened by jimmystewpot 10
  • Decide which forms of IP addresses to support

    Decide which forms of IP addresses to support

    While digging into implementing ParseIP without relying on the stdlib, I found the following representations of IPs that various parsers consider valid:

    192.168.140.255 (classic dotted quad) 192.168.36095 ("class B" notation, final number encodes 16 bits of the IP) 192.11046143 ("class A" notation, final number encodes 24 bits of the IP) 3232271615 (entire IP as a uint32, which I'm facetiously going to call "Class Omega") 0xc0.0xa8.0x8c.0xff (dotted quad, with hex numbers) 0300.0250.0214.0377 (dotted quad, with octal numbers) 001.002.003.004 (dotted quad, each field is exactly 3 decimal digits, leading zeros not omitted) 00000001.00000002.00000003.000000004 (same as above, but unlimited leading zeros)

    1111:2222:3333:4444:5555:6666:7777:8888 (fully expanded canonical colon-hex notation) 1111::8888 (1 or more 16-bit blocks of zeros elided) 1111::1.2.3.4 (final 32 bits of IPv6 written as IPv4 dotted quad - only a subset of the above nonsense is permitted in the IPv6 notation) 00000001::00000008 (unlimited number of leading zeros - technically not compliant with RFC grammar, but allegedly accepted fairly widely)

    Which of these should we support in netaddr? RFCs don't help us much here. The textual form of IPv6 is somewhat specified, and the "final dotted-quad" format specifies a subset of the above as acceptable, but there is no formal specification of the IPv4 textual form, so it comes down to "what do people use" and "what do parsers understand" - with most of the whackier things seemingly introduced by 4.2BSD and copied around from there, rather than based on some principled belief about the value of those representations.

    My opinions:

    Obvious yes:

    • IPv4 dotted quad, including the form with leading zeros up to 3 digits total.
    • IPv6 colon-hex, with ::

    Leaning yes:

    • IPv4 dotted quad with unlimited number of leading zeros.
    • IPv6 colon-hex with unlimited number of leading zeros (unless RFC explicitly forbids it)

    Leaning no:

    • IPv6 with trailing IPv4 dotted quad. Was useful back when transition mechanisms threatened to make ::1.2.3.4 common, but that time no longer exists.
    • IPv4 as a single uint32. This seems to be used accidentally more often than intentionally.

    Strong no:

    • Class A/B notation. I've only ever seen them used as curiosities, or by malware to surprise unsuspecting software.
    • Octal dotted-quad notation. Clashes with sensible support of leading zeros, and extremely surprising to unsuspecting users - especially given that windows formats some IPs in 000.000.000.000 form and intends that to be decimal.
    • Hex dotted-quad notation. Slightly less offensive than octal, but I just can't think of a good reason to encourage that sort of nonsense.

    /cc @bradfitz @mdlayher @josharian thoughts? Should our parser aim to parse "anything that anyone has ever used to represent IPs" ? Or should we exercise editorial privilege and cut out options we don't think the world should be using?

    Will follow up with a survey of what of the above the stdlib accepts.

    opened by danderson 9
  • FromStdIP has surprising behavior with a v4 net.IP represented at 16 bytes

    FromStdIP has surprising behavior with a v4 net.IP represented at 16 bytes

    Just encountered this in Tailscale, converting from net.IP into netaddr.IP for one of our libraries.

    If you give FromStdIP an IPv4 address that currently happens to be in its 16-byte internal representation, FromStdIP will create a v6 mapped v4 netaddr.IP. Because of net.IP's whacky treatment of pure v4 vs. mapped v4, this requires a fairly clunky pattern to use FromStdIP when you want the intuitive behavior:

    stdip := getAv4NetIPFromSomewhere()
    if stdip4 := stdip.To4(); stdip4 != nil {
        stdip = stdip4
    }
    return netaddr.FromStdIP(stdip)
    

    Maybe FromStdIP should canonicalize the net.IP before converting it? That would prevent people from deliberately creating a v6 mapped v4 netaddr.IP from a net.IP, but that seems like a bit of a corner case - and one we could address with helpers like netaddr.To4in6(), for cases where you deliberately want a v6 address representing a v4 IP.

    cc @mdlayher @bradfitz thoughts?

    opened by danderson 9
  • Change the representation of IP to a pair of uint64s.

    Change the representation of IP to a pair of uint64s.

    This allows IP manipulation operations to operate on IPs as two registers, which empirically leads to significant speedups, in particular on OOO superscalars where the two halves can be processed in parallel.

    name                              old time/op    new time/op    delta
    StdIPv4-8                            146ns ± 2%     141ns ± 2%    -3.42%  (p=0.016 n=5+5)
    IPv4-8                               120ns ± 1%     107ns ± 2%   -10.65%  (p=0.008 n=5+5)
    IPv4_inline-8                        120ns ± 0%     118ns ± 1%    -1.67%  (p=0.016 n=4+5)
    StdIPv6-8                            211ns ± 2%     215ns ± 1%    +2.18%  (p=0.008 n=5+5)
    IPv6-8                               281ns ± 1%     252ns ± 1%   -10.19%  (p=0.008 n=5+5)
    IPv4Contains-8                      11.8ns ± 4%     4.7ns ± 2%   -60.00%  (p=0.008 n=5+5)
    ParseIPv4-8                         68.1ns ± 4%    78.8ns ± 1%   +15.74%  (p=0.008 n=5+5)
    ParseIPv6-8                          419ns ± 1%     409ns ± 0%    -2.40%  (p=0.016 n=4+5)
    StdParseIPv4-8                      73.7ns ± 1%    88.8ns ± 2%   +20.50%  (p=0.008 n=5+5)
    StdParseIPv6-8                       132ns ± 2%     134ns ± 1%      ~     (p=0.079 n=5+5)
    IPPrefixMasking/IPv4_/32-8          36.3ns ± 3%     4.8ns ± 4%   -86.72%  (p=0.008 n=5+5)
    IPPrefixMasking/IPv4_/17-8          39.0ns ± 0%     4.8ns ± 3%   -87.78%  (p=0.008 n=5+5)
    IPPrefixMasking/IPv4_/0-8           36.9ns ± 2%     4.8ns ± 4%   -87.07%  (p=0.008 n=5+5)
    IPPrefixMasking/IPv6_/128-8         32.7ns ± 1%     4.7ns ± 2%   -85.47%  (p=0.008 n=5+5)
    IPPrefixMasking/IPv6_/65-8          39.8ns ± 1%     4.7ns ± 1%   -88.13%  (p=0.008 n=5+5)
    IPPrefixMasking/IPv6_/0-8           40.7ns ± 1%     4.7ns ± 2%   -88.41%  (p=0.008 n=5+5)
    IPPrefixMasking/IPv6_zone_/128-8     136ns ± 3%       5ns ± 2%   -96.53%  (p=0.008 n=5+5)
    IPPrefixMasking/IPv6_zone_/65-8      142ns ± 2%       5ns ± 1%   -96.65%  (p=0.008 n=5+5)
    IPPrefixMasking/IPv6_zone_/0-8       143ns ± 2%       5ns ± 3%   -96.67%  (p=0.008 n=5+5)
    IPSetFuzz-8                         22.7µs ± 2%    16.4µs ± 2%   -27.84%  (p=0.008 n=5+5)
    
    name                              old alloc/op   new alloc/op   delta
    StdIPv4-8                            16.0B ± 0%     16.0B ± 0%      ~     (all equal)
    IPv4-8                               0.00B          0.00B           ~     (all equal)
    IPv4_inline-8                        0.00B          0.00B           ~     (all equal)
    StdIPv6-8                            16.0B ± 0%     16.0B ± 0%      ~     (all equal)
    IPv6-8                               16.0B ± 0%     16.0B ± 0%      ~     (all equal)
    IPv4Contains-8                       0.00B          0.00B           ~     (all equal)
    ParseIPv4-8                          0.00B          0.00B           ~     (all equal)
    ParseIPv6-8                          48.0B ± 0%     48.0B ± 0%      ~     (all equal)
    StdParseIPv4-8                       16.0B ± 0%     16.0B ± 0%      ~     (all equal)
    StdParseIPv6-8                       16.0B ± 0%     16.0B ± 0%      ~     (all equal)
    IPPrefixMasking/IPv4_/32-8           0.00B          0.00B           ~     (all equal)
    IPPrefixMasking/IPv4_/17-8           0.00B          0.00B           ~     (all equal)
    IPPrefixMasking/IPv4_/0-8            0.00B          0.00B           ~     (all equal)
    IPPrefixMasking/IPv6_/128-8          0.00B          0.00B           ~     (all equal)
    IPPrefixMasking/IPv6_/65-8           0.00B          0.00B           ~     (all equal)
    IPPrefixMasking/IPv6_/0-8            0.00B          0.00B           ~     (all equal)
    IPPrefixMasking/IPv6_zone_/128-8     16.0B ± 0%      0.0B       -100.00%  (p=0.008 n=5+5)
    IPPrefixMasking/IPv6_zone_/65-8      16.0B ± 0%      0.0B       -100.00%  (p=0.008 n=5+5)
    IPPrefixMasking/IPv6_zone_/0-8       16.0B ± 0%      0.0B       -100.00%  (p=0.008 n=5+5)
    IPSetFuzz-8                         2.60kB ± 0%    2.60kB ± 0%      ~     (p=1.000 n=5+5)
    
    name                              old allocs/op  new allocs/op  delta
    StdIPv4-8                             1.00 ± 0%      1.00 ± 0%      ~     (all equal)
    IPv4-8                                0.00           0.00           ~     (all equal)
    IPv4_inline-8                         0.00           0.00           ~     (all equal)
    StdIPv6-8                             1.00 ± 0%      1.00 ± 0%      ~     (all equal)
    IPv6-8                                1.00 ± 0%      1.00 ± 0%      ~     (all equal)
    IPv4Contains-8                        0.00           0.00           ~     (all equal)
    ParseIPv4-8                           0.00           0.00           ~     (all equal)
    ParseIPv6-8                           3.00 ± 0%      3.00 ± 0%      ~     (all equal)
    StdParseIPv4-8                        1.00 ± 0%      1.00 ± 0%      ~     (all equal)
    StdParseIPv6-8                        1.00 ± 0%      1.00 ± 0%      ~     (all equal)
    IPPrefixMasking/IPv4_/32-8            0.00           0.00           ~     (all equal)
    IPPrefixMasking/IPv4_/17-8            0.00           0.00           ~     (all equal)
    IPPrefixMasking/IPv4_/0-8             0.00           0.00           ~     (all equal)
    IPPrefixMasking/IPv6_/128-8           0.00           0.00           ~     (all equal)
    IPPrefixMasking/IPv6_/65-8            0.00           0.00           ~     (all equal)
    IPPrefixMasking/IPv6_/0-8             0.00           0.00           ~     (all equal)
    IPPrefixMasking/IPv6_zone_/128-8      1.00 ± 0%      0.00       -100.00%  (p=0.008 n=5+5)
    IPPrefixMasking/IPv6_zone_/65-8       1.00 ± 0%      0.00       -100.00%  (p=0.008 n=5+5)
    IPPrefixMasking/IPv6_zone_/0-8        1.00 ± 0%      0.00       -100.00%  (p=0.008 n=5+5)
    IPSetFuzz-8                           33.0 ± 0%      33.0 ± 0%      ~     (all equal)
    

    Signed-off-by: David Anderson [email protected]

    opened by danderson 8
  • Add extractPrefix to IPPrefix and IPSet

    Add extractPrefix to IPPrefix and IPSet

    Hi,

    Thanks for this library, i enjoy using it as a more convenient api compared to the stdlib variant. I have a use case where i need to extract a prefix with given bit length from a existing larger prefix/set.

    If you find this addition useful, please consider it.

    opened by majst01 8
  • Why do IPPrefixFrom and IPRangeFrom permit constructing invalid values?

    Why do IPPrefixFrom and IPRangeFrom permit constructing invalid values?

    IPPrefix and IPRange have a Valid method. This was very necessary when the types were transparent, since you could put whatever you wanted in them.

    Now that the types are opaque, should their constructors return errors? Then we can guarantee that a particular IPPrefix/IPRange is always valid or zero, rather than have to deal with the possibility of invalid inputs into other functions.

    If yes, should we also add Must* helpers that panic on error?

    I'm intrigued by the idea of making invalid values unrepresentable, but also worried that it makes the API unwieldy to manipulate. thoughts?

    opened by danderson 7
  • netaddr: add IP.StringExpanded to expand IPv6 address strings

    netaddr: add IP.StringExpanded to expand IPv6 address strings

    Signed-off-by: Matt Layher [email protected]

    Fixes #51. There's a bit of duplication between IP.string6 and IP.StringExpanded but I was able to remove some logic regarding adding :: compression so it seemed worth duplicating.

    opened by mdlayher 7
  • IPPrefix from Mask

    IPPrefix from Mask

    Right now there are four ways to construct an IPPrefix:

    1. Parsing an string with an IP represented in CIDR notation: netaddr.ParseIPPrefix("127.0.0.1/8")
    2. Providing the significant bits to an IP struct: netaddr.IPv4(127, 0, 0, 1).Prefix(8)
    3. Working with IPRange: netaddr.ParseRange("127.0.0.0-127.0.0.255").Prefix() (ignoring error returns)
    4. Working with IPSet: ipset.Prefixes()

    I'm working with a kernel API that returns the IP mask itself[^1]. I can turn this into an IPPrefix by first using net.IPMask and calling Size.

    func main() {
    	var mask [4]byte
    	netmask := make(net.IPMask, net.IPv4len)
    
    	mask = getKernelMask()
    	copy(netmask, mask[:])
    
    	bits, _ := netmask.Size()
    	ip, _ := netaddr.IPv4(127, 0, 0, 1).Prefix(uint8(bits))
    
    	fmt.Printf("IPPrefix: %s\n", ip)
    }
    

    Would there be any interest in allowing an IPPrefix to be constructed either directly from a netmask representation, or alternatively from a net.IPMask?

    [^1]: The kernel API returns the netmask for IPv4. For IPv6 they switched to returning the significant bits instead.

    opened by terinjokes 7
  • uint128 commit caused across-the-board performance regression

    uint128 commit caused across-the-board performance regression

    It's particularly noticeable in IPPrefix.Contains, which doubled in execution time.

    The problem is that the compiler doesn't SSA arrays, so we generate a whole bunch of useless register moves.

    The fix is probably to make the uint128 type a struct with lo and hi members.

    cc @bradfitz @danderson

    opened by josharian 7
  • proposal: add Count() or Len() methods

    proposal: add Count() or Len() methods

    Hello,

    I think it would be useful to be able to get the number of IP addresses in ranges, prefixes and sets. That could take the form of Count() or Len() methods, I think.

    For prefixes, the number of IP addresses would include all of them, including the min and max ones even if they could be a network and a broadcast address, as:

    • they are valid IP addresses,
    • tt is easy for the user to remove them from the count if needed,
    • including them makes it easier to add counts of multiple prefixes.

    Right now, I think that, in order to count IP addresses in a range, I would have to convert its bounds into net.IPAddr and do arithmetics from there.

    Regards,

    -- Tanguy Ortolo

    opened by ortolot 0
  • netaddr: plans for API changes after Go 1.18 net/netip

    netaddr: plans for API changes after Go 1.18 net/netip

    @terinjokes brought up a good point today on my Twitch stream (hi chat!):

    Will package netaddr be updated to use type aliases for net/netip as of Go 1.18? Perhaps we use build tags or similar to ease transition for folks who are stuck on 1.17 or older?

    I don't have strong feelings at the moment but it seems like a good idea to start thinking about at least. I know there is some functionality in this package such as IP sets and ranges that did not make it into the stdlib as of yet. It seems like it would make sense to keep those around here, perhaps backed by type aliases into stdlib.

    /cc @bradfitz @danderson @josharian

    opened by mdlayher 3
  • proposal: Implement Scanner & Valuer interfaces

    proposal: Implement Scanner & Valuer interfaces

    I'm using PostgreSQL to store IP address information and would like to be able to use these types with database/sql.

    Would you be open to implementing the Scanner and Valuer interfaces for IP and IPPrefix types? Alternatively, would you be open to PR which did this?

    opened by ccakes 7
  • Access to uint64 pair?

    Access to uint64 pair?

    We serialize a lot of IP addresses, and rather than converting the internal uint64 pair to byte arrays and then back to uint64s, it would be great if we could get access to the uint64 pair values directly to use them for serialization. Also, the ability to construct a netaddr.IP from a uint64 pair would be useful for de-serialization.

    opened by brycekahle 5
  • Make IPSet a fmt.Stringer?

    Make IPSet a fmt.Stringer?

    @Xe requested that IPSet be a fmt.Stringer. It's not obvious what a good representation would be, but having something to look at would be better than nothing. One option might be something like:

    IPSet(127.0.0.0-127.0.0.255,192.168.1.5-192.168.1.5 without 127.0.0.1-127.0.0.2)

    Other ideas welcomed.

    opened by josharian 3
Owner
inet.af
inet.af
A small tool used to correspond to the IP address according to the name, id, and network alias of the docker container, which can be run as a DNS server

A small tool used to correspond to the IP address according to the name, id, and network alias of the docker container, which can be run as a DNS server

Swift 5 Apr 4, 2022
Project helps to identify the network, broadcast address and no of possible hosts

network_identifier Project helps to identify the network, broadcast address and no of possible hosts for Ipv4 address To use it directly as a go file

Vedant Pareek 0 Dec 3, 2021
Go built-in package network address wrapper.

osnet Go built-in package network address wrapper. Installation go get -u github.com/coolstina/osnet functions IsIP: Check whether the IP address is r

coolstina 0 Jan 10, 2022
Curtis Milo 2 May 8, 2022
Package socket provides a low-level network connection type which integrates with Go's runtime network poller to provide asynchronous I/O and deadline support. MIT Licensed.

socket Package socket provides a low-level network connection type which integrates with Go's runtime network poller to provide asynchronous I/O and d

Matt Layher 42 Jul 3, 2022
Magma is an open-source software platform that gives network operators an open, flexible and extendable mobile core network solution.

Connecting the Next Billion People Magma is an open-source software platform that gives network operators an open, flexible and extendable mobile core

Magma 1.3k Jul 31, 2022
Optimize Windows's network/NIC driver settings for NewTek's NDI(Network-Device-Interface).

windows-ndi-optimizer[WIP] Optimize Windows's network/NIC driver settings for NewTek's NDI(Network-Device-Interface). How it works This is batchfile d

Nil Hiiragi 3 Apr 15, 2022
A simple network analyzer that capture http network traffic

httpcap A simple network analyzer that captures http network traffic. support Windows/MacOS/Linux/OpenWrt(x64) https only capture clienthello colorful

null 1 Nov 24, 2021
Zero Trust Network Communication Sentinel provides peer-to-peer, multi-protocol, automatic networking, cross-CDN and other features for network communication.

Thank you for your interest in ZASentinel ZASentinel helps organizations improve information security by providing a better and simpler way to protect

ZTALAB 6 Jul 30, 2022
Go pkg for returning your public facing IP address.

#publicip This package returns the public facing IP address of the calling client (a la https://icanhazip.com, but from Go!) Author James Polera james

James Polera 25 Jan 23, 2022
A simple tool for retrieving a request's IP address on the server.

reqip A simple tool for retrieving a request's IP address on the server. Inspired from request-ip Installation Via go get go get github.com/mo7zayed/r

Mohamed Zayed 15 Jul 10, 2022
An Yggdrasil address miner in Go

SimpleYggGen-Go This program reimplements SimpleYggGen in Go, importing the original Yggdrasil code for generating keys and utilizing multiple CPU thr

Timur Demin 4 Apr 21, 2022
Serverless Lightning Address server

Addressless Put a Lightning Address "server" on a serverless host like Vercel. The code is heavily borrowed from satdress, minus the federated part. T

Paul Miller 11 Jan 28, 2022
⚡ 🖥️ 👾 Host your own Lightning Address on LND

⚡ ??️ ?? Host your own Lightning Address on LND Lighting Wallets like BlueWallet, Blixt and many more allow us to send sats to Lighting Addresses like

Heebs 8 Jun 12, 2022
Take an IP address and quickly get the reverse PTR

FlipIP Just a little quick app to take an IP (or set of IPs), and convert them to reverse IP pointers Example: $ flipip 1.2.3.4 4.3.2.1.in-addr.arpa.

Drew Stinnett 2 Feb 27, 2022
Shrek is a vanity .onion address generator written in Go.

Shrek Shrek is a vanity .onion address generator written in Go. Usage (CLI) Shrek compiles to a single binary that can be used on the CLI. To build an

null 10 Jun 1, 2022
checkip is a CLI tool and library that checks an IP address using various public services.

checkip is a CLI tool and library that checks an IP address using various public services.

Jozef Reisinger 171 Jul 27, 2022
A small library to detect if an IP address is close to yours

go-geofence A small library to detect if an IP address is close to yours or another of your choosing using https://ipstack.com/ Usage First you will n

Caleb Lemoine 17 Mar 31, 2022
Gopi - Simple API for get geo information about your IP Address, Build by go-fiber

gopi Simple API to get information from your IP Address Idea This idea come from IP zxq and literaly i clone it How to download GeoIP2 ? Remember to c

I Made Ocy Darma Putra 3 May 27, 2022