Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

Appify Technologies CTO ͦͳଠ @sonatard

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

OFUOFUJQQBDLBHF

Slide 5

Slide 5 text

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 }

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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 }

Slide 9

Slide 9 text

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 }

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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 }

Slide 13

Slide 13 text

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 }

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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 }

Slide 16

Slide 16 text

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 ஋ͱϙΠϯλͷϚοϐϯάςʔϒϧͷ࣮૷͕௝͍ͨ͠ΊࢀߟʹͳΔɻ

Slide 17

Slide 17 text

OFUOFUJQQBDLBHFͷޓ׵ੑ

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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 }

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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 }

Slide 22

Slide 22 text

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ܕΛฦ͢͜ͱͰߴ଎Խ͍ͯ͠Δ

Slide 23

Slide 23 text

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)

Slide 24

Slide 24 text

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