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

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

sonatard
February 18, 2022

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

sonatard

February 18, 2022
Tweet

More Decks by sonatard

Other Decks in Programming

Transcript

  1. 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 }
  2. 6 OFUOFUJQQBDLBHFͱ͸ w ͳͥվળ͕ඞཁʹͳ͔ͬͨʁ w ݩ(PνʔϜɺݱࡏUBJMTDBMFࣾͷCSBE fi U[ࢯ͔ΒͷఏҊ w 5BJMTDBMFࣾ͸ωοτϫʔΫΞϓϦέʔγϣϯͰ͋ΔͨΊ*1ΞυϨεͷૢ࡞͕ଟ͍

    w (PͰ͸6%1ύέοτͷड৴Ͱར༻͢ΔϝιουͰ*1Λฦͨ͢ΊɺͦͷͨͼʹϝϞϦΞϩ έʔγϣϯ͕ൃੜ͢Δͱ஗͘ͳͬͯ͠·͏ w ۙ೥6%1Λར༻͢Δϓϩτίϧ͕ଟ͍ w 26*$ɺ8JSF(VBSE
  3. 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
  4. 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 }
  5. 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 }
  6. 11 OFUOFUJQQBDLBHFͱ͸ w ෆม w *1ܕ͸εϥΠεͳͷͰෆมΛ࣮ݱͰ͖ͳ͔ͬͨ package net type IP

    []byte package netip type Addr struct { addr uint128 z *intern.Value }
  7. 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 }
  8. 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 }
  9. 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
  10. 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 }
  11. 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 ஋ͱϙΠϯλͷϚοϐϯάςʔϒϧͷ࣮૷͕௝͍ͨ͠ΊࢀߟʹͳΔɻ
  12. 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 }
  13. 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 }
  14. 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)