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

Go で Network Programming するためのよもやま話 / Network P...

Go で Network Programming するためのよもやま話 / Network Programming with Go

GDG DevFest Tokyo 2018 の発表に使ったスライドです。
Goについて以下の話をしました。

- netパッケージの基本的なインタフェース
- netpoll による I/O 多重化の仕組み
- ブロッキング I/O をアンブロックする方法
- TLS対応について
 - Public Key Pinning のやり方など

Tomohiro Takezawa

September 01, 2018
Tweet

More Decks by Tomohiro Takezawa

Other Decks in Programming

Transcript

  1. ࣗݾ঺հ • ஛ᖒ ༑ത • Github: ttakezawa • Twitter: @takezawa

    • גࣜձࣾKyashॴଐ • όοΫΤϯυશൠ • ಛʹ VISA ΍ QUICPay (Google Pay) ͷϓϩηγϯάγεςϜͳͲ
  2. ίωΫγϣϯཱ֬·ͰͷϓϦϛςΟϒ $POO -JTUFO %JBM netύοέʔδʹ͸ϓϩτίϧ͝ͱʹͦΕͧΕͷ࣮૷͕͋Δ net.DialIP(…) net.DialTCP(…) net.DialUDP(…) net.DialUnix(…) net.IPConn

    net.TCPConn net.UDPConn net.UnixConn net.ListenIP(…) net.ListenTCP(…) net.ListenUDP(…) net.ListenUnix(…) net.ListenUnixgram(…)
  3. ίωΫγϣϯཱ֬·ͰͷϓϦϛςΟϒ $POO -JTUFO %JBM netύοέʔδʹ͸ϓϩτίϧ͝ͱʹͦΕͧΕͷ࣮૷͕͋Δ net.DialIP(…) net.DialTCP(…) net.DialUDP(…) net.DialUnix(…) net.IPConn

    net.TCPConn net.UDPConn net.UnixConn net.ListenIP(…) net.ListenTCP(…) net.ListenUDP(…) net.ListenUnix(…) net.ListenUnixgram(…)
  4. ίωΫγϣϯཱ֬·ͰͷϓϦϛςΟϒ $POO -JTUFO %JBM netύοέʔδʹ͸ϓϩτίϧ͝ͱʹͦΕͧΕͷ࣮૷͕͋Δ net.DialIP(…) net.DialTCP(…) net.DialUDP(…) net.DialUnix(…) net.IPConn

    net.TCPConn net.UDPConn net.UnixConn net.ListenIP(…) net.ListenTCP(…) net.ListenUDP(…) net.ListenUnix(…) net.ListenUnixgram(…)
  5. ΠϯλϑΣʔεΛ࢖͏ͱ $POO -JTUFO %JBM net.Listen(…) net.ListenPacket(…) net.Dial(…) net.Conn net.PacketConn •

    Listen • ετϦʔϜܕͷ৔߹: net.Listen() → net.Listener → net.Conn • σʔλάϥϜܕͷ৔߹: net.ListenPacket() → net.PacketConn • Dial͸͍ͣΕͷϓϩτίϧͰ΋ڞ௨ • net.Dial() → net.Conn
  6. ΠϯλϑΣʔεΛ࢖͏ͱ $POO -JTUFO %JBM net.Listen(…) net.ListenPacket(…) net.Dial(…) net.Conn net.PacketConn •

    Listen • ετϦʔϜܕͷ৔߹: net.Listen() → net.Listener → net.Conn • σʔλάϥϜܕͷ৔߹: net.ListenPacket() → net.PacketConn • Dial͸͍ͣΕͷϓϩτίϧͰ΋ڞ௨ • net.Dial() → net.Conn
  7. ΠϯλϑΣʔεΛ࢖͏ͱ $POO -JTUFO %JBM net.Listen(…) net.ListenPacket(…) net.Dial(…) net.Conn net.PacketConn •

    Listen • ετϦʔϜܕͷ৔߹: net.Listen() → net.Listener → net.Conn • σʔλάϥϜܕͷ৔߹: net.ListenPacket() → net.PacketConn • Dial͸͍ͣΕͷϓϩτίϧͰ΋ڞ௨ • net.Dial() → net.Conn
  8. ΠϯλϑΣʔεΛ࢖͏ͱ $POO -JTUFO %JBM net.Listen(…) net.ListenPacket(…) net.Dial(…) net.Conn net.PacketConn •

    Listen • ετϦʔϜܕͷ৔߹: net.Listen() → net.Listener → net.Conn • σʔλάϥϜܕͷ৔߹: net.ListenPacket() → net.PacketConn • Dial͸͍ͣΕͷϓϩτίϧͰ΋ڞ௨ • net.Dial() → net.Conn
  9. ΠϯλϑΣʔεΛ࢖͏ͱ $POO -JTUFO %JBM net.Listen(…) net.ListenPacket(…) net.Dial(…) net.Conn net.PacketConn •

    Listen • ετϦʔϜܕͷ৔߹: net.Listen() → net.Listener → net.Conn • σʔλάϥϜܕͷ৔߹: net.ListenPacket() → net.PacketConn • Dial • ͲͪΒͷ৔߹΋: net.Dial() → net.Conn
  10. ετϦʔϜܕϓϩτίϧͷ৔߹ • αʔό/ΫϥΠΞϯτ͸ڞʹ net.Conn ΠϯλϑΣʔε ͱͯ͠ίωΫγϣϯΛѻ͏ • αʔόଆ • net.Listen()

    Ͱ଴ͪड͚Λ࢝Ίɺฦ͖ͬͯͨListener ΠϯλϑΣʔεͷ Accept() ͰίωΫγϣϯͷ஋Λಘ Δ • ΫϥΠΞϯτଆ
 • net.Dial() Ͱ઀ଓ͢Δ  
  11. ετϦʔϜܕϓϩτίϧͷ৔߹ • αʔό/ΫϥΠΞϯτ͸ͱ΋ʹ net.Conn ΠϯλʔϑΣʔεͰίωΫ γϣϯΛѻ͏ • networkͱͯ͠ "tcp"ɺ"unix"ɺ"unixpacket" ͳͲ͕ࢦఆՄೳ

    OFU-JTUFO αʔόଆ
 net.Listen("tcp", "127.0.0.1:8080")
 net.Listen("unix", "socketfile") ΫϥΠΞϯτଆ
 net.Dial("tcp", "127.0.0.1:8080")
 net.Dial("unix", "socketfile") OFU-JTUFOFS "DDFQU OFU$POO OFU%JBM OFU$POO  
  12. σʔλάϥϜܕϓϩτίϧͷ৔߹ • αʔόଆ • net.PacketConn ΠϯλϑΣʔεͷ஋Λฦ͢ • net.PacketConn ͸௨৴૬ख͕ݶఆ͞Ε͍ͯͳ͍৔߹ʹ ࢖༻͞ΕΔίωΫγϣϯͷΠϯλϑΣʔεͰ͋Γɺ

    net.PacketConn Λ࢖ͬͯૹ৴͢Δͱ͖͸ɺૹ৴ઌΛࢦ ఆ͢Δඞཁ͕͋Δ • ΫϥΠΞϯτଆ • ௨৴૬ख͕ݶఆ͞ΕΔͷͰɺ net.Conn ΠϯλϑΣʔεͷ ஋͕࢖͑Δ  
  13. σʔλάϥϜܕϓϩτίϧͷ৔߹ • UDPͰૹड৴Λ͢Δίʔυͷྫ αʔόଆ ΫϥΠΞϯτଆ • ΫϥΠΞϯτଆ͸ɺΠϯλϑΣʔε্͸ετϦʔϜܕͱมΘΒͳ͍ • αʔόଆ͸௨৴૬ख͕ఆ·Βͳ͍ͷͰɺ net.PacketConn

    ΠϯλϑΣʔεͷΦϒδΣΫτͰ ௨৴͢Δ͜ͱʹͳΔ • PacketConn.ReadFrom ͕௨৴૬खͷΞυϨε΋ฦͯ͘͠ΕΔ • PacketConn.WriteTo Ͱ૬खઌͷΞυϨεΛࢦఆ͢Δඞཁ͕͋Δ
  14. σʔλάϥϜܕϓϩτίϧͷ৔߹ • UDPͰૹड৴Λ͢Δίʔυͷྫ αʔόଆ ΫϥΠΞϯτଆ • ΫϥΠΞϯτଆ͸ɺΠϯλϑΣʔε্͸ετϦʔϜܕͱมΘΒͳ͍ • αʔόଆ͸௨৴૬ख͕ఆ·Βͳ͍ͷͰɺ net.PacketConn

    ΠϯλϑΣʔεͷΦϒδΣΫτͰ ௨৴͢Δ͜ͱʹͳΔ • PacketConn.ReadFrom ͕௨৴૬खͷΞυϨε΋ฦͯ͘͠ΕΔ • PacketConn.WriteTo Ͱ૬खઌͷΞυϨεΛࢦఆ͢Δඞཁ͕͋Δ
  15. σʔλάϥϜܕϓϩτίϧͷ৔߹ • UDPͰૹड৴Λ͢Δίʔυͷྫ αʔόଆ ΫϥΠΞϯτଆ • ΫϥΠΞϯτଆ͸ɺΠϯλϑΣʔε্͸ετϦʔϜܕͱมΘΒͳ͍ • αʔόଆ͸௨৴૬ख͕ఆ·Βͳ͍ͷͰɺ net.PacketConn

    ΠϯλϑΣʔεͷΦϒδΣΫτͰ ௨৴͢Δ͜ͱʹͳΔ • PacketConn.ReadFrom ͕௨৴૬खͷΞυϨε΋ฦͯ͘͠ΕΔ • PacketConn.WriteTo Ͱ૬खઌͷΞυϨεΛࢦఆ͢Δඞཁ͕͋Δ
  16. σʔλάϥϜܕϓϩτίϧͷ৔߹ • UDPͰૹड৴Λ͢Δίʔυͷྫ αʔόଆ ΫϥΠΞϯτଆ • ΫϥΠΞϯτଆ͸ɺΠϯλϑΣʔε্͸ετϦʔϜܕͱมΘΒͳ͍ • αʔόଆ͸௨৴૬ख͕ఆ·Βͳ͍ͷͰɺ net.PacketConn

    ΠϯλϑΣʔεͷΦϒδΣΫτͰ ௨৴͢Δ͜ͱʹͳΔ • PacketConn.ReadFrom ͕௨৴૬खͷΞυϨε΋ฦͯ͘͠ΕΔ • PacketConn.WriteTo Ͱ૬खઌͷΞυϨεΛࢦఆ͢Δඞཁ͕͋Δ
  17. σʔλάϥϜܕϓϩτίϧͷ৔߹ • UDPͰૹड৴Λ͢Δίʔυͷྫ αʔόଆ ΫϥΠΞϯτଆ • ΫϥΠΞϯτଆ͸ɺΠϯλϑΣʔε্͸ετϦʔϜܕͱมΘΒͳ͍ • αʔόଆ͸௨৴૬ख͕ఆ·Βͳ͍ͷͰɺ net.PacketConn

    ΠϯλϑΣʔεͷΦϒδΣΫτͰ ௨৴͢Δ͜ͱʹͳΔ • PacketConn.ReadFrom ͕௨৴૬खͷΞυϨε΋ฦͯ͘͠ΕΔ • PacketConn.WriteTo Ͱ૬खઌͷΞυϨεΛࢦఆ͢Δඞཁ͕͋Δ
  18. σʔλάϥϜܕϓϩτίϧͷ৔߹ • UDPͰૹड৴Λ͢Δίʔυͷྫ αʔόଆ ΫϥΠΞϯτଆ • ΫϥΠΞϯτଆ͸ɺΠϯλϑΣʔε্͸ετϦʔϜܕͱมΘΒͳ͍ • αʔόଆ͸௨৴૬ख͕ఆ·Βͳ͍ͷͰɺ net.PacketConn

    ΠϯλϑΣʔεͷΦϒδΣΫτͰ ௨৴͢Δ͜ͱʹͳΔ • PacketConn.ReadFrom ͕௨৴૬खͷΞυϨε΋ฦͯ͘͠ΕΔ • PacketConn.WriteTo Ͱ૬खઌͷΞυϨεΛࢦఆ͢Δඞཁ͕͋Δ
  19. σʔλάϥϜܕϓϩτίϧͷ৔߹ • UDPͰૹड৴Λ͢Δίʔυͷྫ αʔόଆ ΫϥΠΞϯτଆ • ΫϥΠΞϯτଆ͸ɺΠϯλϑΣʔε্͸ετϦʔϜܕͱมΘΒͳ͍ • αʔόଆ͸௨৴૬ख͕ఆ·Βͳ͍ͷͰɺ net.PacketConn

    ΠϯλϑΣʔεͷΦϒδΣΫτͰ ௨৴͢Δ͜ͱʹͳΔ • PacketConn.ReadFrom ͕௨৴૬खͷΞυϨε΋ฦͯ͘͠ΕΔ • PacketConn.WriteTo Ͱ૬खઌͷΞυϨεΛࢦఆ͢Δඞཁ͕͋Δ
  20. σʔλάϥϜܕϓϩτίϧͷ৔߹ • σʔλάϥϜܕϓϩτίϧͷ৔߹ • αʔόଆ͸ net.ListenPacket() Λ࢖ͬͯ଴ͪड͚Λ։࢝ • αʔόଆ͸ net.PacketConnɺΫϥΠΞϯτଆ͸

    net.Conn ͰίωΫγϣϯΛѻ͏ • networkͱͯ͠ "udp"ɺ"unixgram"ɺ"ip" ͳͲ͕ࢦఆՄೳ OFU-JTUFO1BDLFU  αʔόଆ
 net.ListenPacket("udp", "127.0.0.1:8080")
 net.ListenPacket("unixgram", "socketfile") ΫϥΠΞϯτଆ
 net.Dial("tcp", "127.0.0.1:8080")
 net.Dial("unix", "socketfile") OFU1BDLFU$POO OFU$POO OFU%JBM ΫϥΠΞϯτͱ௨৴Λ։࢝͢Δલ ʹ࡞ΒΕΔίωΫγϣϯͷΠϯλʔ ϑΣʔε
 ௨৴૬ख͕1ͭʹఆ·͍ͬͯͳ͍ ͱ͖ʹ࢖ΘΕΔ ΫϥΠΞϯτ(Dial)ଆ͸ɺ௨৴૬ ख͕ఆ·͓ͬͯΓɺ net.Conn Π ϯλʔϑΣʔεʹ౷Ұ͞Ε͍ͯΔ
  21. I/O ʹؔ͢Δ༻ޠͷઆ໌ • ϒϩοΩϯά I/O • I/O ॲཧ͕׬ྃɺΤϥʔɺλΠϜΞ΢τʹͳΔ͔ɺͳͲ௨஌͕͘Δ·Ͱ ࣮ߦΛઌʹਐ·ͳ͍ॲཧ •

    ϊϯϒϩοΩϯά I/O ͷ৔߹͸ɺ I/O ͕ॲཧதͰ΋࣮ߦΛ͙͢ʹਐΊΔ • I/O ͷଟॏԽ • ෳ਺ͷ I/O ͷ௨஌ΛҰ౓ʹ଴ͯΔΑ͏ʹ͢Δ͜ͱ • ଟॏԽ͍ͯ͠ͳ͍৔߹ʹ͸଴ͪड͚ର৅͝ͱʹγεςϜίʔϧ͕ඞཁ ʹͳΔ • OSʹΑΓɺ selectɺpollɺepoll(Linux)ɺkqueue(BSDܥ) ͳͲͷγες ϜίʔϧͰ࣮ݱ͞ΕΔ • ΠϕϯτۦಈϞσϧͷ࣮૷ʹ͸΄΅ඞਢͳ࢓૊Έ
  22. ϚϧνεϨουϞσϧ • Α͋͘ΔҰൠతͳϓϩάϥϛϯάϞσϧ ͦͷ1 • ϑϩʔۦಈϞσϧ • ฒྻʹॲཧ͍ͨ͠୯ҐͰεϨουΛ࡞ͬͯɺεϨου͝ ͱʹ I/O

    Λߦ͏ • ྫ͑͹ίωΫγϣϯ͝ͱʹεϨου΋͘͠͸ϓϩηε Λੜ੒͠ɺͦΕͧΕͷεϨουͰ I/O Λߦ͏ɺͱ͍͏ Α͏ͳΞϓϩʔνʹͳΔ • ฒྻ౓͕ߴ͍ͱ͖(ίωΫγϣϯ͕ଟ͍ͱ͖)ʹɺͦͷ෼ εϨουΛͨ͘͞Μ࢖͏͜ͱʹͳΔͷͰɺίετ͕େ͖ ͍
  23. ΠϕϯτۦಈϞσϧ • Α͋͘ΔҰൠతͳϓϩάϥϛϯάϞσϧ ͦͷ2 • ΠϕϯτΛ଴ػ͠ɺىͬͨ͜Πϕϯτʹ͍ͭͯΠϕϯτϋϯυϥΛ࣮ߦ͠ଓ͚ Δɺͱ͍͏Ϟσϧ • Node.jsɺRubyͷEventMachineɺPythonͷTwisted ͳͲ

    • I/O ΛଟॏԽͯ͠γϯάϧεϨουͰͨ͘͞Μͷ I/O Λѻ͑Δ • ೉͍͠ɺͱݴΘΕ΍͍͢Ϟσϧ • ओʹγϯάϧεϨουͰಈ࡞͢ΔͷͰɺ • ͕͔͔࣌ؒΔॲཧΛ࣮ߦͯ͠͠·͏ͱଞͷॲཧ͕શ࣮͘ߦ͞Εͳ͘ͳΔ • ෳ਺ίΞͷCPUΛੜ͔ͤͳ͍ • ॲཧͷ࣮ߦ͞ΕΔॱং͕Θ͔Βͳ͍ɺͳͲ
  24. GoͰͷ΍Γํ ϚϧνεϨουͱΠϕϯτۦಈͷϋΠϒϦουͷΑ͏ͳ࢓૊Έ • Go͸εϨουΑΓ΋ܰྔͳgoroutineΛɺεϨου্ʹׂΓ౰ ͯͳ͕Β࣮ߦ͢Δ • goroutine্Ͱ I/O Λ࣮ߦ͢Δͱgoroutine͸ϒϩοΫ͞ΕΔ •

    ϒϩοΫ͍ͨ͠਺͚ͩgoroutine͕ඞཁ • GoͷϥϯλΠϜ͸ I/O ΛଟॏԽͯ͠଴ͪड͚͢Δ • ଴ͪड͚ͷͨΊʹେྔͷεϨουΛඞཁͱ͠ͳ͍ • I/O ଴ͪͷͱ͖goroutine͸εϨουʹׂΓ౰ͯ͞Εͳ͍
  25. ϢʔβͷGoίʔυࢹ఺Ͱ͍͏ͱ • GoͷϓϩάϥϛϯάΠϯλϑΣʔεͱͯ͠͸ I/O ͸ϒ ϩοΩϯά • ྫ͑͹ conn.Read(buffer) ͱ͢ΔͱΠϕϯτ͕͋Δ·

    Ͱɺͦͷgoroutine͸εέδϡʔϥ͔Β֎͞Εͯ଴ͪঢ় ଶ(ϒϩοΩϯά)ʹͳΔ • ͜ͷ I/O ʹ͍ͭͯ௨஌͕͘Δͱɺ conn.Read(buffer) ͕ ฦͬͯ͘Δ
  26. netpollʹΑΔଟॏԽͷྲྀΕ ҎԼͷྲྀΕΛ Linux (epoll) ͷྫͰऔΓ্͛ͯઆ໌͢Δ 1. ιέοτΛ࡞Δͱ͖ʹ४උ͢Δ 2. I/O ॲཧ

    (ReadͳͲ) Λ։࢝͢Δ 3. I/O ϒϩοΩϯά͢Δ goroutine Λεέδϡʔϥ͔Β֎͢ 4. ௨஌Λड͚औͬͨΒɺgoroutineΛ࣮ߦΩϡʔʹ໭͢ 5. εέδϡʔϥ͸࣮ߦ଴ͪͷΩϡʔ͔ΒgoroutineΛऔΓग़ ͠ɺOSεϨουʹׂΓ౰࣮ͯͯߦ͢Δ
  27. 1. ιέοτΛ࡞Δͱ͖ͷ४උ ιέοτΛ࡞ΔλΠϛϯάͰڞ௨ͷinitؔ਺Λ࣮ߦ͍ͯ͠Δ ҎԼɺGoͷιʔείʔυ͔Βൈਮ go1.11/src/net/sock_posix.go go1.11/src/os/file_unix.go • DialɺListenɺListenPacketɺAcceptɺϑΝΠϧΛ։͘ɺͦΕͧΕͷͱ͖ʹڞ௨ͷॳظԽॲཧ͕ߦΘΕΔ • Go

    1.9 ͔ΒωοτϫʔΫ I/O͚ͩͰͳ͘ϑΝΠϧ I/Oʹ͍ͭͯ΋ netpoll ͰଟॏԽ͢Δ࣮૷͕ೖͬͨ • ͱ͸͍͑ɺৗʹ͋ΒΏΔ I/O Λ netpoll ͰଟॏԽ͍ͯ͠Δͱ͍͏Θ͚Ͱ͸ͳ͘ɺos.Open() ΍ os.Pipe() ͳͲݶఆ͞ΕͨϑΝΠϧσΟεΫϦϓλʹ͍ͭͯ netpoll ͰଟॏԽ͞ΕΔ go1.11/src/net/fd_unix.go
  28. 1. ιέοτΛ࡞Δͱ͖ͷ४උ • ڞ௨initؔ਺ : pollDesc.init • ιέοτ΍ϑΝΠϧͷσΟεΫϦϓλॳظԽʹݺͼग़͞ΕΔɻ • epoll

    ͕ॳظԽ͞Ε͍ͯͳ͍৔߹ʹ͸ epoll ͷॳظԽ epoll_create Λ͢Δ • epoll ͷ ؂ࢹ଴ͪʹొ࿥ EPOLL_CTL_ADD ͢Δ go1.11/src/internal/poll/fd_poll_runtime.go • runtime_pollServerInit ʹͯ epoll_create ͕1౓͚ͩ (sync.Once Ͱอূ) ͞ΕΔ • runtime_pollOpen Ͱ؂ࢹ଴ͪʹొ࿥ (EPOLL_CTL_ADD)͢Δ
  29. 1. ιέοτΛ࡞Δͱ͖ͷ४උ go1.11/src/internal/poll/fd_poll_runtime.go • runtime_pollServerInit ʹͯ epoll_create ͕1౓͚ͩ (sync.Once Ͱอূ)

    ͞ΕΔ • runtime_pollOpen Ͱ؂ࢹ଴ͪʹొ࿥ (EPOLL_CTL_ADD)͢Δ • ڞ௨initؔ਺ : pollDesc.init • ιέοτ΍ϑΝΠϧͷσΟεΫϦϓλॳظԽʹݺͼग़͞ΕΔɻ • epoll ͕ॳظԽ͞Ε͍ͯͳ͍৔߹ʹ͸ epoll ͷॳظԽ epoll_create Λ͢Δ • epoll ͷ ؂ࢹ଴ͪʹొ࿥ EPOLL_CTL_ADD ͢Δ
  30. 4. ௨஌Λड͚औͬͨΒgoroutineΛ࣮ߦΩϡʔʹ໭͢ go1.11/src/runtime/proc.go ιέοτΛ؂ࢹͯ͠௨஌Λड͚औͬͨ৔߹ʹ͸ɺ֘౰͢ΔgoroutineΛ࣮ ߦΩϡʔʹೖΕΔ • εέδϡʔϦϯάͰ͙͢ʹ࣮ ߦͰ͖Δgoroutine͕ݟ͔ͭ Βͳ͍৔߹ʹ͸ɺnetpoll() ʹΑΓ

    epoll_pwait Λ࣮ߦ͠ ͯɺI/O ͷ௨஌Λ଴ͭ • netpoll() ͸௨஌͕͋ͬͨ goroutine Λࢦ͢஋gpΛฦ ͢ͷͰɺ injectglist(gp) ʹΑ Γ࣮ߦΩϡʔʹೖΕΔ ͜ͷޙɺεέδϡʔϥ͸࣮ߦ଴ͪͷΩϡʔ͔ΒgoroutineΛऔΓग़͠ɺ࠶౓OS εϨουʹׂΓ౰࣮ͯͯߦ͢Δ
  31. 4. ௨஌Λड͚औͬͨΒgoroutineΛ࣮ߦΩϡʔʹ໭͢ go1.11/src/runtime/proc.go • εέδϡʔϦϯάͰ͙͢ʹ࣮ ߦͰ͖Δgoroutine͕ݟ͔ͭ Βͳ͍৔߹ʹ͸ɺnetpoll() ʹΑΓ epoll_pwait Λ࣮ߦ͠

    ͯɺI/O ͷ௨஌Λ଴ͭ • netpoll() ͸௨஌͕͋ͬͨ goroutine Λࢦ͢஋gpΛฦ ͢ͷͰɺ injectglist(gp) ʹΑ Γ࣮ߦΩϡʔʹೖΕΔ ιέοτΛ؂ࢹͯ͠௨஌Λड͚औͬͨ৔߹ʹ͸ɺ֘౰͢ΔgoroutineΛ࣮ ߦΩϡʔʹೖΕΔ ͜ͷޙɺεέδϡʔϥ͸࣮ߦ଴ͪͷΩϡʔ͔ΒgoroutineΛऔΓग़͠ɺ࠶౓OS εϨουʹׂΓ౰࣮ͯͯߦ͢Δ
  32. 4. ௨஌Λड͚औͬͨΒgoroutineΛ࣮ߦΩϡʔʹ໭͢ go1.11/src/runtime/proc.go • εέδϡʔϦϯάͰ͙͢ʹ࣮ ߦͰ͖Δgoroutine͕ݟ͔ͭ Βͳ͍৔߹ʹ͸ɺnetpoll() ʹΑΓ epoll_pwait Λ࣮ߦ͠

    ͯɺI/O ͷ௨஌Λ଴ͭ • netpoll() ͸௨஌͕͋ͬͨ goroutine Λࢦ͢஋gpΛฦ ͢ͷͰɺ injectglist(gp) ʹΑ Γ࣮ߦΩϡʔʹೖΕΔ ͜ͷޙɺεέδϡʔϥ͸࣮ߦ଴ͪͷΩϡʔ͔ΒgoroutineΛऔΓग़͠ɺ࠶౓OS εϨουʹׂΓ౰࣮ͯͯߦ͢Δ ιέοτΛ؂ࢹͯ͠௨஌Λड͚औͬͨ৔߹ʹ͸ɺ֘౰͢ΔgoroutineΛ࣮ ߦΩϡʔʹೖΕΔ
  33. ϒϩοΩϯά I/O Λ೚ҙͷλΠϛϯάͰऴ͍ྃͤͨ͞৔߹ ೚ҙͷλΠϛϯάͰ I/O Λதஅ͍ͤͨ͜͞ͱ͕͋Δ • ΞϓϦέʔγϣϯΛऴྃ࣌ͷॲཧΛ࡞ΓࠐΉ৔߹ • SetDeadline

    Ͱ͸ରԠͰ͖ͳ͍தஅॲཧΛೖΕ͍ͨ৔߹ ͳͲ • ϒϩοΩϯάૢ࡞ (Read) ͷલʹϑϥάνΣοΫ Λ௥Ճ͢Δ͚ͩͰ͸ɺϒϩοΩϯάૢ࡞͕ղআ ͞ΕΔΘ͚Ͱ͸ͳ͍ • ͜ͷΑ͏ͳ࣮૷Λͯ͠͠·͏ͱɺ goroutine ͷऴྃʹ͸࠷େͰ1෼Ҏ্଴ͬͯ͠·͏ • SetDeadline Λ୹͘͢Δͱɺ଴ͭ࣌ؒ͸୹͘ ͳΔ͕ɺγεςϜίʔϧΛݺͼग़͠·͘Δ͜ ͱʹͳΔͷͰɺίετ͕ߴ͍ ଴ͨ͞Εͯ͠·͏ྫ
  34. contextΛ࢖ͬͯΞϯϒϩοΫͤ͞Δ৔߹ context.Context ʹରԠ͍ͯ͠ΔΠϯλϑΣʔε͕͋Ε͹ɺͦΕΛ࢖͏ • Dial() Ͱ͋Ε͹ net.Dialer ͷ DialContext() ͕࢖͑Δ

    • Listen() ΋ net.ListenConfig Ͱ ΩϟϯηϧରԠ • net.ListenConfig ͸ Go 1.11 Ͱ௥Ճ͞Εͨ࢓૊Έ • ͱ͸͍͑ɺListen()ͰϒϩοΫ͢Δͷ͸ DNS Ͱ໊લղܾ͢Δͱ͜ΖͷΈ
  35. context.Context ʹରԠ͍ͯ͠ΔΠϯλϑΣʔε͕͋Ε͹ɺͦΕΛ࢖͏ • Dial() Ͱ͋Ε͹ net.Dialer ͷ DialContext() ͕࢖͑Δ •

    Listen() ΋ net.ListenConfig Ͱ ΩϟϯηϧରԠ • net.ListenConfig ͸ Go 1.11 Ͱ௥Ճ͞Εͨ࢓૊Έ • ͱ͸͍͑ɺListen()ͰϒϩοΫ͢Δͷ͸ DNS Ͱ໊લղܾ͢Δͱ͜ΖͷΈ contextΛ࢖ͬͯΞϯϒϩοΫͤ͞Δ৔߹
  36. Close() Λ࢖ͬͯΞϯϒϩοΫͤ͞Δ৔߹ contextରԠ͕ͳ͍৔߹ʹ͸ɺClose() ͢Δ • ྫ͑͹ net.Listener ͷ Accept() ͸

    context ΛҾ਺ʹऔΒͳ͍ • Listener ʹ SetDeadline() Λ࢖͏͜ͱͰλΠϜΞ΢τͷઃఆͳΒՄೳ • Listener Λ Close() ͨ͠λΠϛϯάͰAccpet()͕ΞϯϒϩοΫ͞ΕΔ • Close() ͰΞϯϒϩοΫͨ͠ͱ͍͏͜ͱΛ఻͑ΔͨΊʹɺdoneνϟωϧͰ఻͍͑ͯΔ
  37. contextରԠ͕ͳ͍৔߹ʹ͸ɺClose() ͢Δ • net.Listener ͷ Accept() ʹ͸ context ରԠ͕ͳ͍ •

    Listener ʹ SetDeadline() Λ࢖͏͜ͱͰλΠϜΞ΢τͷઃఆͳΒՄೳ • Listener Λ Close() ͨ͠λΠϛϯάͰAccept()͕ΞϯϒϩοΫ͞ΕΔ • Close() ͰΞϯϒϩοΫͨ͠ͱ͍͏͜ͱΛ఻͑ΔͨΊʹɺdoneνϟωϧͰ఻͍͑ͯΔ Close() Λ࢖ͬͯΞϯϒϩοΫͤ͞Δ৔߹
  38. ϒϩοΩϯά I/O Λ೚ҙͷλΠϛϯάͰऴ͍ྃͤͨ͞৔߹ net.Conn ͱ os.File ͷΦϒδΣΫτʹ͍ͭͯ • net.Conn ͷ

    Read ΍ Write ʹ΋ context ͷ࢖͑Δ ݺͼग़͠͸ͳ͍ • Accept() ͱಉ༷ʹ net.Conn ͷ஋Λ Close() ͢Δ ͜ͱʹΑΓ೚ҙͷλΠϛϯάͰΞϯϒϩοΫ • os.File ͷ Read ΍ Write ΋ಉ༷ • os.File Λ Close() ͢Ε͹ΞϯϒϩοΫ͞ΕΔ
  39. TLSରԠ: ΫϥΠΞϯτଆ • net.Dial ͷ୅ΘΓʹ tls.Dial Λ࢖͏ • ࣗݾೝূہΛ࢖͏৔߹ʹ͸ɺূ໌ॻΛࢦ ఆ͢Δඞཁ͕͋Δ

    • αʔόূ໌ॻͷݕূΛεΩοϓ͢ΔΦ ϓγϣϯ΋͋Δ͕ɺӡ༻ͰࣄނΔϦε ΫΛߴΊΔͷͰɺݸਓతʹ͸։ൃ؀ڥ ͩͱͯ͠΋εΩοϓ͸Φεεϝ͠ͳ͍ ΫϥΠΞϯτଆ
  40. TLSରԠ: ΫϥΠΞϯτଆ • net.Dial ͷ୅ΘΓʹ tls.Dial Λ࢖͏ • ࣗݾೝূہΛ࢖͏৔߹ʹ͸ɺূ໌ॻΛࢦ ఆ͢Δඞཁ͕͋Δ

    • αʔόূ໌ॻͷݕূΛεΩοϓ͢ΔΦ ϓγϣϯ΋͋Δ͕ɺӡ༻ͰࣄނΔϦε ΫΛߴΊΔͷͰɺݸਓతʹ͸։ൃ؀ڥ ͩͱͯ͠΋εΩοϓ͸Φεεϝ͠ͳ͍ ΫϥΠΞϯτଆ
  41. TLSରԠ: ΫϥΠΞϯτଆ • net.Dial ͷ୅ΘΓʹ tls.Dial Λ࢖͏ • ࣗݾೝূہΛ࢖͏৔߹ʹ͸ɺূ໌ॻΛࢦ ఆ͢Δඞཁ͕͋Δ

    • αʔόূ໌ॻͷݕূΛεΩοϓ͢ΔΦ ϓγϣϯ΋͋Δ͕ɺӡ༻ͰࣄނΔϦε ΫΛߴΊΔͷͰɺݸਓతʹ͸։ൃ؀ڥ ͩͱͯ͠΋εΩοϓ͸Φεεϝ͠ͳ͍ ΫϥΠΞϯτଆ
  42. TLSͰΑΓηΩϡΞʹ • TLSΛ࢖͏ͱͦΕ͚ͩͰ؆୯ʹ௨৴ͷ҉߸Խ͕Ͱ͖Δ͕ɺߟྀ͓͖ͯͨ͠ ͍໰୊΋͋Δ • ௨৴ઌͷαʔό͸ຊ෺ʁ ͳΓ͢·͠͞Ε͍ͯͳ͍ʁ • SymantecύʔτφʔاۀʹΑΔূ໌ॻͷޡൃߦ໰୊ͳͲ •

    Webϒϥ΢βͳΒ CT (Certificate Transparency) ΍ HPKP (HTTP Public Key Pinning) ͱ͍͏࢓૊Έ͕͋Δ͕ɺࣗલͷTLSΞϓϦέʔγϣ ϯͰ͸Ͳ͏͢Δʁ • ࣗ෼Ͱಉ͡Α͏ͳ࢓૊ΈΛೖΕΑ͏ʂ