Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Go1.18から導入されるnetip package/netip-package

sonata
February 18, 2022

Go1.18から導入されるnetip package/netip-package

sonata

February 18, 2022
Tweet

More Decks by sonata

Other Decks in Programming

Transcript

  1. 1
    (P͔Βಋೖ͞ΕΔOFUOFUJQQBDLBHF
    (PϦϦʔεύʔςΟ
    !TPOBUBSEͦͳଠ

    View Slide

  2. Appify Technologies
    CTO
    ͦͳଠ
    @sonatard

    View Slide

  3. 3
    "QQJGZ
    w 4IPQJGZɺ#"4&ͷJ04ɺ"OESPJEͷΞϓϦΛ/P$PEFͰϦϦʔε͢ΔαʔϏε
    w όοΫΤϯυ͸(PͰ͢
    w ࠾༻
    w IUUQTBQQJGZJODDPNKPC

    View Slide

  4. OFUOFUJQQBDLBHF

    View Slide

  5. 5
    OFUOFUJQQBDLBHFͱ͸
    w (P͔ΒOFU*1ܕʹ୅ΘΔOFUJQ"EESܕΛఏڙ͢Δ
    w ಛ௃
    w লϝϞϦ
    w ϝϞϦΞϩέʔγϣϯ͕ͳ͍
    w ෆม
    w ͰൺֱՄೳ
    w NBQͷ,FZʹ࢖͑Δ
    package net
    type IP []byte
    package netip
    type Addr struct {
    addr uint128
    z *intern.Value
    }

    View Slide

  6. 6
    OFUOFUJQQBDLBHFͱ͸
    w ͳͥվળ͕ඞཁʹͳ͔ͬͨʁ
    w ݩ(PνʔϜɺݱࡏUBJMTDBMFࣾͷCSBE
    fi
    U[ࢯ͔ΒͷఏҊ
    w 5BJMTDBMFࣾ͸ωοτϫʔΫΞϓϦέʔγϣϯͰ͋ΔͨΊ*1ΞυϨεͷૢ࡞͕ଟ͍
    w (PͰ͸6%1ύέοτͷड৴Ͱར༻͢ΔϝιουͰ*1Λฦͨ͢ΊɺͦͷͨͼʹϝϞϦΞϩ
    έʔγϣϯ͕ൃੜ͢Δͱ஗͘ͳͬͯ͠·͏
    w ۙ೥6%1Λར༻͢Δϓϩτίϧ͕ଟ͍
    w 26*$ɺ8JSF(VBSE

    View Slide

  7. 7
    OFUOFUJQQBDLBHFͱ͸
    w ༨ஊύοέʔδ໊෇ܾఆ·Ͱͷٞ࿦
    w ࠷ॳͷఏҊOFUBEES*1
    w *1ܕͷ໊લΛOFUQBDLBHFͱಉ͡ʹ͠Α͏ͱͨ͠
    w BEES*1ͱ͍͏ͷ͕গ͠ҧ࿨ײ
    w OFUQBDLBHF͔Β෼͔Ε͍ͯΔͷ͸ྑ͍ɻOFUQBDLBHFେ͖͗͢ΔCZSTD
    w ࣍ͷఏҊJQ"EES
    w ͖ͬ͢Γ͍ͯͯ͠ྑͦ͞͏
    w ͨͩ͠ύοέʔδ໊͕JQͩͱɺม਺໊JQͱিಥͦ͠͏
    w ܾఆ
    w OFUJQ"EES

    View Slide

  8. 8
    OFUOFUJQQBDLBHFͱ͸
    w (P͔ΒOFU*1ܕʹ୅ΘΔOFUJQ"EESܕΛఏڙ͢Δ
    w ಛ௃
    w লϝϞϦ
    w ϝϞϦΞϩέʔγϣϯ͕ͳ͍
    w ෆม
    w ͰൺֱՄೳ
    w NBQͷ,FZʹ࢖͑Δ
    package net
    type IP []byte
    package netip
    type Addr struct {
    addr uint128
    z *intern.Value
    }

    View Slide

  9. 9
    OFUOFUJQQBDLBHFͱ͸
    w লϝϞϦ package net
    type IP []byte
    package netip
    type Addr struct {
    addr uint128
    z *intern.Value
    }
    ip := make(net.IP, net.IPv6len)
    ipSize := len([net.IPv6len]net.IP{})
    fmt.Printf("net.IP([%v]byte) Size = %vbyte\n”,
    net.IPv6len, int(unsafe.Sizeof(ip))+ipSize)
    var addr netip.Addr
    fmt.Printf("netip.Addr Size = %vbyte\n", unsafe.Sizeof(addr))
    // https://gotipplay.golang.org/p/xrkMg5Nw67g
    // net.IP([16]byte) Size = 40byte
    // netip.Addr Size = 24byte
    w 4MJDF)FBEFSCZUF
    w *1WCZUFΑΓେ͖͍ʜ
    type SliceHeader struct {
    Data uintptr
    Len int
    Cap int
    }

    View Slide

  10. 10
    OFUOFUJQQBDLBHFͱ͸
    w ϝϞϦΞϩέʔγϣϯ͕ͳ͍
    w εϥΠεͰ͸ͳ͘ߏ଄ମͰ࣮ମͱͯ͠ѻ͍ͬͯ͘
    w ώʔϓͷ֬อΛ͢Δ͜ͱ͕ͳ͍ͷͰ଎͘ͳΔ
    package netip
    type Addr struct {
    addr uint128
    z *intern.Value
    }

    View Slide

  11. 11
    OFUOFUJQQBDLBHFͱ͸
    w ෆม
    w *1ܕ͸εϥΠεͳͷͰෆมΛ࣮ݱͰ͖ͳ͔ͬͨ
    package net
    type IP []byte
    package netip
    type Addr struct {
    addr uint128
    z *intern.Value
    }

    View Slide

  12. 12
    OFUOFUJQQBDLBHFͱ͸
    w ͰൺֱՄೳ
    w *1ܕ͸εϥΠεͳͷͰɺϙΠϯλͷൺֱʹͳͬͯ͠·͍ൺֱͰ͖ͳ͔ͬͨ
    addr := netip.MustParseAddr("192.168.1.1")
    addr2 := netip.MustParseAddr("192.168.1.1")
    fmt.Printf("%v\n", addr == addr2) // true
    addr3 := netip.MustParseAddr("192.168.1.2")
    fmt.Printf("%v\n", addr == addr3) // false
    package netip
    type Addr struct {
    addr uint128
    z *intern.Value
    }

    View Slide

  13. 13
    OFUOFUJQQBDLBHFͱ͸
    w NBQͷ,FZʹ࢖͑Δ
    addr := netip.MustParseAddr("192.168.1.1")
    addrKeyMap := map[netip.Addr]string{addr: "IPv4ΞυϨε"}
    fmt.Printf("%v\n", addrKeyMap)
    package netip
    type Addr struct {
    addr uint128
    z *intern.Value
    }

    View Slide

  14. 14
    OFUOFUJQQBDLBHFͱ͸
    w BEESVJOU CZUF

    w
    w OFUJQQBDLBHFʹఆٛ͞Εͨܕ
    w BEESIJͱBEESMPͰ*1WΞυϨεΛ෼ׂͯ͠දݱ
    w *1Wͷͱ͖͸ɺ*1WNBQQFE*1WBEESFTTʹม׵ͯ֨͠ೲ
    w
    ffff

    w ͳͥ<>CZUFͰ͸ͳ͍ʁ
    w *1ͷૢ࡞͸CJUϨδελ্Ͱͷࢉज़ԋࢉͱϏοτԋࢉͰߦΘΕΔ͜ͱ͕ଟ͘ɺόΠ
    τ୯ҐͰॲཧ͢ΔΑΓ଎͍ͨΊ
    w
    package netip
    type Addr struct {
    addr uint128
    z *intern.Value
    }
    type uint128 struct {
    hi uint64
    lo uint64
    }
    // For example, 0011:2233:4455:6677:8899:aabb:ccdd:eeff is stored as:
    // addr.hi = 0x0011223344556677
    // addr.lo = 0x8899aabbccddeeff

    View Slide

  15. 15
    OFUOFUJQQBDLBHFͱ͸
    w [JOUFSO7BMVF
    w *1WPS*1WΛද͢
    w ;͕*1WΞυϨε
    w [OP[͸*1WΞυϨεͷκʔϯΠϯσοΫε͕ͳ͍΋ͷ
    w κʔϯΠϯσοΫε͕͋Δ৔߹͸ɺκʔϯ͕[ʹೖΔ
    w ͜ͷͱ͖͸ඞͣ*1W
    w ྫ
    GFFUI
    w ΠϯλʔϑΣʔεΛࢦఆͯ͠ύέοτΛૹ৴Ͱ͖Δ
    w OFU*1ܕͷͱ͖͸ɺκʔϯΛ࣋ͯͳ͍ͷͰผ్
    OFU*1BEESܕΛ༻ҙ͍͕ͯͨ͠ɺOFUJQ"EESܕ͸ͭʹ
    ఆٛͰ͖ͨ
    var (
    z0 = (*intern.Value)(nil)
    z4 = new(intern.Value)
    z6noz = new(intern.Value)
    )
    func (ip Addr) BitLen() int {
    switch ip.z {
    case z0:
    return 0
    case z4:
    return 32
    }
    return 128
    }
    package netip
    type Addr struct {
    addr uint128
    z *intern.Value
    }

    View Slide

  16. 16
    OFUOFUJQQBDLBHFͱ͸
    w ͳͥTUSJOHͰ͸ͳ͘[JOUFSO7BMVF
    w αΠζΛCZUFʹ཈͔͑ͨͬͨ
    w TUSJOH͸ϙΠϯλͱMFOΛ࣋ͭͷͰCZUF
    w ϙΠϯτͰ͸஋ൺֱʹར༻Ͱ͖ͳ͍ͷͰ͸ʁ
    w JOUFSO7BMVF͸ಛघͳܕͰಉ͡஋͸ಉ͡ϙΠϯλΞυϨεʹͳΔ
    w ʮΞυϨε͕ಉ͡஋͕ಉ͡ʯͳͷͰɺOFUJQ"EESܕ͸ߏ଄ମͷൺֱͰಉ͡஋ͱ൑அ͢Δ
    ͜ͱ͕Մೳ
    w JOUFSO7BMVFܕ͸খ͘͞ͳ͍͕ɺOFUJQ"EESܕͱͯ͠ίϐʔ͞ΕΔ[ϑΟʔϧυ͸ϙΠϯλͳ
    ͷͰCZUFͱখ͘͞ͳΔɻ
    w JOUFSO7BMVFܕ͸ɺTUSJOHͷΑ͏ʹ஋ൺֱՄೳͳCZUFͷϙΠϯλΛ࣮ݱ͢Δ
    w ൚༻తͳύοέʔδ͕༻ҙ͞Ε͍ͯΔɻ
    w IUUQTQLHHPEFWHPPSHJOUFSO
    w ஋ͱϙΠϯλͷϚοϐϯάςʔϒϧͷ࣮૷͕௝͍ͨ͠ΊࢀߟʹͳΔɻ

    View Slide

  17. OFUOFUJQQBDLBHFͷޓ׵ੑ

    View Slide

  18. 18
    OFUOFUJQQBDLBHFͷޓ׵ੑ
    w *1ܕΛར༻͍ͯͨ͠Օॴ͸Ͳ͏ͳΔʁ
    w OFUQBDLBHF͸ͦͷ··ͳͷͰɺ͍ͭ΋௨ΓԼҐޓ׵ੑ͕͋Δ

    View Slide

  19. 19
    OFUOFUJQQBDLBHFͷޓ׵ੑ
    w OFU*1ܕͱOFUJQ"EESܕͷػೳͷࠩ
    w ࠓ·ͰOFU*1ܕपลͷ*1ΞυϨεʹؔ͢Δૢ࡞ͷϝιου͸ɺOFUJQ"EESܕʹ΋ఏڙ
    ͞Ε͍ͯΔ
    func (ip Addr) IsPrivate() bool {
    // Match the stdlib's IsPrivate logic.
    if ip.Is4() {
    // RFC 1918 allocates 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16 as
    // private IPv4 address subnets.
    return ip.v4(0) == 10 ||
    (ip.v4(0) == 172 && ip.v4(1)&0xf0 == 16) ||
    (ip.v4(0) == 192 && ip.v4(1) == 168)
    }
    if ip.Is6() {
    // RFC 4193 allocates fc00::/7 as the unique local unicast IPv6 address
    // subnet.
    return ip.v6(0)&0xfe == 0xfc
    }
    return false // zero value
    }

    View Slide

  20. 20
    OFUOFUJQQBDLBHFͷޓ׵ੑ
    w ඪ४ϥΠϒϥϦ͸*1ܕΛར༻͠ͳ͘ͳΔʁ
    w কདྷతʹ͸ɺաڈͷ"1*͸಺෦Ͱ͸OFUJQ"EESܕΛ࢖͍ೖग़ྗ͚ͩOFU*1ܕʹม׵ͯ͠
    ฦ͍ͨ͢͠໛༷
    w (PͰ͸ɺ͜ͷมߋ͸ೖ͍ͬͯͳ͍
    w OFUQBDLBHFOFUJQQBDLBHF΁ͷґଘ͸͋Δ͕ɺٯ͸ͳ͍

    View Slide

  21. 21
    OFUOFUJQQBDLBHFͷޓ׵ੑ
    w ࠓ·ͰOFU*1ܕΛར༻͍ͯͨ͠ػೳͷ͢΂͕ͯOFUJQ"EESܕͰఏڙ͞Ε͍ͯΔΘ͚Ͱ͸ͳ͍
    w OFUJQ"EESܕʹม׵͢Δϝιου͕௥Ճ͞Ε͍ͯΔ͜ͱ΋͋Δ
    w 5$1"EES"EES1PSUɺ-PPLVQ/FU*1ͳͲ
    func (r *Resolver) LookupNetIP(ctx context.Context, network, host string) ([]netip.Addr, error) {
    // TODO(bradfitz): make this efficient, making the internal net package
    // type throughout be netip.Addr and only converting to the net.IP slice
    // version at the edge. But for now (2021-10-20), this is a wrapper around
    // the old way.
    ips, err := r.LookupIP(ctx, network, host)
    if err != nil {
    return nil, err
    }
    ret := make([]netip.Addr, 0, len(ips))
    for _, ip := range ips {
    if a, ok := netip.AddrFromSlice(ip); ok {
    ret = append(ret, a)
    }
    }
    return ret, nil
    }

    View Slide

  22. 22
    OFUOFUJQQBDLBHFͷޓ׵ੑ
    w ໨తͰ͋ͬͨ6%1ͷߴ଎ԽͷͨΊ͍͔ͭ͘ͷϝιου͕௥Ճ͞Ε͍ͯΔ
    w 6%1$POO3FBE'SPN6%1"EES1PSU 6%1$POO3FBE.TH6%1"EES1PSU
    6%1$POO8SJUF5P6%1"EES1PSU 6%1$POO8SJUF.TH6%1"EES1PSU
    w OFUJQ"EESܕΛฦ͢͜ͱͰߴ଎Խ͍ͯ͠Δ

    View Slide

  23. 23
    OFUOFUJQQBDLBHFͷޓ׵ੑ
    w ࣗ෼ͰίʔυΛॻ͘৔߹͸ʁ
    w OFU*1ܕΛར༻͢Δ
    w PS
    w OFUJQ"EESܕΛར༻͢ΔɺඞཁʹԠͯ͡OFU*1ܕʹม׵
    # net.IP -> netip.Addr
    ip := net.ParseIP("192.168.1.1")
    if addr, ok := netip.AddrFromSlice(ip); ok {
    fmt.Printf("%v\n", addr)
    }
    # netip.Addr -> net.IP
    addr := netip.MustParseAddr("192.168.1.1")
    ip := net.IP(addr.AsSlice())
    fmt.Printf("ip: %v\n", ip)

    View Slide

  24. 24
    w ࢀߟ
    w OFUOFUJQBEEOFX*1BEESFTTQBDLBHF VTFJOOFUCZCSBE
    fi
    U[
    w IUUQTHJUIVCDPNHPMBOHHPJTTVFT

    View Slide