Nand2Tetris(ã³ã³ãã¥ã¼ã¿ã·ã¹ãã ã®çè«ã¨å®è£ )ã§CPUããOSã¾ã§ä¸æ°é貫ã§ä½ãã®ãæé«ã«æ¥½ããã£ã話
ã©ãããããããã§ãã
å»å¹´ããããããã¼ã¬ã¤ã¤ã¼å¨ãã®ç¥èãå å®ããããã¨æãã ä½ã¬ã¤ã¤ãç¥ããã人ã®ããã®Cã³ã³ãã¤ã©ä½æå ¥é ãèªãã§Cã³ã³ãã¤ã©ãæ¸ãã¦ã¿ããx86_64ã®åå¼·ãããããã¦ãã¾ããã
ä»å¹´ã«å ¥ã£ã¦ããããããã¼ãªã¬ã¤ã¤ã¼ãå ·ä½çã«ã¯ãã¼ãã¦ã§ã¢ãOSã«ã¤ãã¦ããå°ãç¥ãããã¨æãå§ããæé ãªæ¸ç±ãæ¢ãã¦ãã¾ããã CPUãªã©ã®ãã¼ãã¦ã§ã¢å¨ãã«ã¤ãã¦ã¯æ¦è¦ããç¥ããªãã¦æãåããããã¨ããªãã®ã§ãå®éã«ä½ãä½ããªããå¦ã¹ããã®ã¨ãã¦ã O'Reilly Japan - ã³ã³ãã¥ã¼ã¿ã·ã¹ãã ã®çè«ã¨å®è£ ã«ææ¦ãããã¨ã«ãã¾ããã
O'Reilly Japan - ã³ã³ãã¥ã¼ã¿ã·ã¹ãã ã®çè«ã¨å®è£
ææç©ã¯ä»¥ä¸ã®ãªãã¸ããªã«ç½®ãã¦ããã¾ãã
çµè«ããè¨ãã¨ããã£ã¦ã¿ã¦å¤§å¤æ¥½ããã¾ããï¼
ç¹ã«ãã¼ãã¦ã§ã¢å¨ãã¯ä»ã¾ã§ææ¦ãããã¨ã®ãªãåéã§ãåè·¯ã®è¨è¨ãã¨ã¦ãæ°é®®ã§æ¥½ããã§åãçµãã¾ããã ã¡ããã¡ããéã空ãããããã®ã§ãå ¨é¨å®èµ°ããã¾ã§10ã¶æã¡ãã£ã¨ãããã¾ãããâ¦â¦ã
ã³ã³ãã¤ã©ãVMã®ä½æã¯ãCã³ã³ãã¤ã©æ¸ãã¦ã¿ããããçµé¨ããã£ãã®ã§ãããªãã§ãã¾ããããå®è£ è¨èªã«Rustãæ¡ç¨ãããã¨ã§Rustã®ç¿çã«ãå½¹ç«ã¡ã¾ããã (ã¨ãããããã£ãã®ã¯ä¸»ã«Rustã®å¦ç¿ã§ã使ãæ £ããè¨èªã ã£ããããããããã«å®è£ ã§ããã¯ãã§ãâ¦â¦)
OSã«é¢ãã¦ã¯ããªãç©è¶³ããªãã£ãã®ã§ããã¡ãã¯å¥ãªææã§æ¹ãã¦å¦ã³ããã¨æãã¾ãã
Nand2Tetrisã£ã¦ãªã«?
ãã³ã³ãã¥ã¼ã¿ã·ã¹ãã ã®çè«ã¨å®è£ ã(é称Nand2Tetris: NANDãããããªã¹ã¸)ã¯ãã³ã³ãã¥ã¼ã¿ã¼ã®åºæ¬çãªæ§æè¦ç´ ã§ããCPUãã¡ã¢ãªããå§ãã¦ããã®ã¢ã¼ããã¯ãã£åãã®æ©æ¢°èªãçæããã³ã³ãã¤ã©ãã¢ããªã±ã¼ã·ã§ã³ã¨ãã¼ãã¦ã§ã¢ã®æ©æ¸¡ããããOSã¾ã§ã é ã追ã£ã¦ä½æãããã¨ã§ãåºæ¬çãªã³ã³ãã¥ã¼ã¿ã¼ã·ã¹ãã ã®åä½åçãç解ã§ãããããªæ§æã«ãªã£ã¦ãã¾ãã
Courseraã«ã³ã¼ã¹ããã£ã¦ãèè ã®Shimon Schockenææã¨Noam Nisanææãã¤ã³ã¹ãã©ã¯ã¿ã¼ã¨ãã¦ãªã³ã©ã¤ã³ã§åè¬ãããã¨ãã§ãã¾ãã
åã¯ãã¿ã¬ãªã®ã§åè¬ã¯ããã«ç¬å¦ãã¾ããããæ°åå ¥ãã¦åãçµãã¤ãããªãåè¬ããã®ãããã§ã¯ãªãã§ããããã
Nand2Tetrisã§ã¯ãHackã¨ããæ¬æ¸ç¬èªã®ã¢ã¼ããã¯ãã£ç¨ã®CPUãã¡ã¢ãªãªã©ãNandåè·¯ããå§ãã¦ä½æããJackã¨ããæ¬æ¸ç¬èªã®ããã°ã©ãã³ã°è¨èªã®Hackã¢ã¼ããã¯ãã£åãã³ã³ãã¤ã©ãå®è£ ãããã®Jackè¨èªãç¨ãã¦OSãæ¸ããã¨ã§ããã¼ãã¦ã§ã¢ããOSãã¢ããªã±ã¼ã·ã§ã³ã¾ã§ãã¹ã¦ãèªåã§ä½ã£ã¦ããã¾ãã ã¨ã¯ãããHackã¢ã¼ããã¯ãã£ã§ä½æããCPUã¯16bitã§ãã¼ã¿ã¬ã¸ã¹ã¿ã¨ã¢ãã¬ã¹ã¬ã¸ã¹ã¿ãããããã²ã¨ã¤ãããªãåç´ãªCPU(ä¹é¤ç®ããã§ãã¾ããï¼)ã§ãããJackè¨èªã¯ãªãã¸ã§ã¯ãæåè¨èªã§ããJavaãããªãåç´åããè¨èªä»æ§ã§ãã ã¾ããOSã¯ããã»ã¹ç®¡çããã¡ã¤ã«ç®¡çããããã¯ã¼ã¯ãªã©ã¯ãµãã¼ããããåç´ã«ãã¼ãã¼ããã¹ã¯ãªã¼ã³ãªã©ã¡ã¢ãªããããããããã¼ãã¦ã§ã¢ãæä½ããããã®ä¾¿å©ã©ã¤ãã©ãªã®ãããªä½ç½®ã¥ãã§ãã
ããã§ããé çªã«å®è£ ãã¦ããã¨(ã·ãã¥ã¬ã¼ã¿ã¼ä¸ã¨ã¯ãã)ãã®ãããªã²ã¼ã (ã¢ããªã±ã¼ã·ã§ã³)ãåä½ããããã¨ãã§ãã¾ã!
çµãã£ããNand2TetrisãJackè¨èªã³ã³ãã¤ã©ã®ã³ã¼ãçæã®å®è£ ãã
— 極éçå½ä½ããããNA (@yuroyoro) November 13, 2020
CPUãã¢ã»ã³ãã©ãã¹ã¿ãã¯ãã·ã³VMãã³ã³ãã¤ã©ã¨ä½ã£ã¦ãã¦ãããããã¢ããªã±ã¼ã·ã§ã³ãã¨ãã¥ã¬ã¼ã¿ä¸ã§åãããã«ãªã£ããォâ¦â¦ï¼ï¼ pic.twitter.com/KmojKek9wT
ãããªã¹ã¡ãããããï¼ï¼
ãã¦æ¬ã®æ§æã§ãããããã¾ãã«ãã¼ãã¦ã§ã¢ãã³ã³ãã¤ã©ãOSã®3ã¤ã®ãã¼ãã«åãããã¦ãããåãã¼ãã¯ããã¤ãã®ç« ã§æ§æããã¾ãã ç« ãã¨ã«æ¼ç¿åé¡ãç¨æããã¦ãããå®éã«ãã®åé¡ã§ä½ã£ããã¼ãã次ã®ç« ã§å©ç¨ãããä»æãã«ãªã£ã¦ãã¾ãã ä¾ãã°ãåè·¯è¨è¨ã§ã¯æåã®1ç« ã§ANDãORã²ã¼ããä½ãã次ã®2ç« ã§ã¯ããããçµã¿åããã¦å ç®å¨ãä½ããã¨ãã£ãå ·åã§ãã
æ¬æ¸ã¯ãã¹ãããããã®åè·¯ã·ãã¥ã¬ã¼ã¿ã¼ãCPUã·ãã¥ã¬ã¼ã¿ã¼ããã§ã«ç¨æããã¦ãããã¾ãç« ãã¨ã®èª²é¡ããã¹ãã±ã¼ã¹ãç¨æããã¦ãã¾ãã 課é¡ã®å 容ã«ãããã£ã¦HDLãæ¸ãããããã°ã©ã ãä½æãã¦ãã·ãã¥ã¬ã¼ã¿ã¼ä¸ã§ç¨æããã¦ãããã¹ãããã¹ããã°ãã®ç« ã¯ã¯ãªã¢ã§ãã
ãã®ã·ãã¥ã¬ã¼ã¿ã¼ããã¹ããç¨æããã¦ããã®ãé常ã«åãçµã¿ãããããã¹ãããã¹ãããã¨ãç®æ¨ã¨ãã¦å®è£ ããã°ããã®ã§è¿·ããªãã¦ããã®ãããã£ãã§ãã ãããã¦ãã¹ãããã¹ããããã«ç« ãã¨ã®èª²é¡ãããªãã¦ããã°ãã¤ã®ã¾ã«ãã³ã³ãã¥ã¼ã¿ã¼ã·ã¹ãã ãå®æãã¦ããã®ã§ãã
1ç« ãã5ç« : ãã¼ãã¦ã§ã¢
ã¾ããæåã¯Nandã²ã¼ããçµã¿åããã¦è«çã²ã¼ããä½ãããããã®ãã¼ããçµã¿åããã¦å ç®å¨ãã¡ã¢ãªãALUãªã©ãå®è£ ãã¾ãã ä½ã£ãALUããã¼ã¹ã«CPUãè¨è¨ãå®è£ ããã¨ããã¾ã§ãããã¼ãã¦ã§ã¢ã®ãã¼ãã§ãããã¨ã§ãã
- 1ç« ããã¼ã«è«ç : Nandã²ã¼ããçµã¿ããã¦AND, ORãªã©ã®è«çã²ã¼ããä½æãã¾ãã
- 2ç« ããã¼ã«ç®è¡ : AND, ORãªã©ã®ãã¼ãããã¨ã«å ç®å¨ãALU(ç®è¡è«çæ¼ç®å¨)ãä½ãã¾ã
- 3ç« ãé åºåè·¯ : ããªãããããããç¨ãã¦1bitã¬ã¸ã¹ã¿ããå§ãã¦16KBã¡ã¢ãª, ããã°ã©ã ã«ã¦ã³ã¿ãä½ãã¾ã
- 4ç« ãæ©æ¢°èª : æ©æ¢°èªã«ã¤ãã¦Hackã¢ã¼ããã¯ãã£åãã®ã¢ã»ã³ãã©ãæ¸ãã¦å¦ã³ã¾ã
- 5ç« ãã³ã³ãã¥ã¼ã¿ã¢ã¼ããã¯ã㣠: ããã¾ã§ä½ã£ã¦ããã«ã¦ã³ã¿ãALUãçµã¿åããã¦ã4ç« ã§å¦ãã Hackã¢ã¼ããã¯ãã£ã®æ©æ¢°èªãå®è¡ã§ããCPUãä½ããã¡ã¢ãªãå ¥åºåã¨çµã¿åããã¾ã
åè·¯è¨è¨ã§ãããHDLãæ¸ãã¦ã·ãã¥ã¬ã¼ã¿ã¼ä¸ã§ãã¹ãããªããé²ãã¦ããã¾ãã æ¬æ¸ã®ãµãã¼ããµã¤ããããã¦ã³ãã¼ãã§ãããã¼ã«ãã§ã¤ã³ã«ãã¼ããã¦ã§ã¢ã·ãã¥ã¬ã¼ã¿ããããå®è£ ããHDLããã®ã·ãã¥ã¬ã¼ã¿ã¼ä¸ã§ãã¹ããã¾ãã HDLã¯æ¸ãããã¨ããªãã£ãã®ã§ãããæ¬æ¸ã§æ±ããã®ã¯é常ã«åç´ãªã«ã¼ã«ãªã®ã§ããã«è¦ãããã¨ãã§ãã¾ããã
ãããªæãã§ãã£ã¦ããã¾ãã
é§ãåºãã¨ã³ã¸ãã¢ãªã®ã§è«çã²ã¼ãã®å®è£ ã®åå¼·ããã¦ãã¾ã pic.twitter.com/bdMv0B0wzM
— 極éçå½ä½ããããNA (@yuroyoro) February 6, 2020
åè·¯è¨è¨ã«æ©ããããã§ã
Nand2Tetrisãä»æ¥ã¯ããã°ã©ã ã«ã¦ã³ã¿ã¼ã®å®è£ ã¾ã§ãããããããªã£ãã®ã§åè·¯å³æ¸ããã⦠pic.twitter.com/PkQZtmPl5l
— 極éçå½ä½ããããNA (@yuroyoro) May 6, 2020
CPUã®å®è£ ã§ãã®ãã¼ã¸ãåºã¦ããã¨ãã¯ãã£ã¡ããã³ã·ã§ã³ãããã¾ãããï¼
ãã®ããããããã pic.twitter.com/iHPZJmWqQB
— 極éçå½ä½ããããNA (@yuroyoro) May 13, 2020
ã·ãã¥ã¬ã¼ã¿ã¼ä¸ã§ãèªåãHDLæ¸ããCPUãHackæ©æ¢°èªãå®è¡ã§ããããã«ãªã£ãã¨ãã®æ§åã§ãããããã£ãæãã£ãã
CPUã¨Memoryãå®è£ ããã®ã§çµã¿åããã¦ãã·ãã¥ã¬ã¼ã¿ã¼ä¸ã§æ©æ¢°èªãåãããã«ãªã£ãソï¾ï½«â¦â¦
— 極éçå½ä½ããããNA (@yuroyoro) May 15, 2020
HWã¯ããã§ä¸æ®µè½ #nand2tetris pic.twitter.com/Vx8hfZRowL
6ç« ãã11ç« : ã³ã³ãã¤ã©
6ç« ããã¯ã³ã³ãã¤ã©ã®å®è£ ã§ãã æ¬æ¸ç¬èªã®Jackè¨èªã®ã³ã³ãã¤ã©ãå®è£ ãã¦ãJackè¨èªã½ã¼ã¹ã³ã¼ãããHackæ©æ¢°èªãçæã§ããããã«ãªãã¾ã§ãç®æ¨ã§ãã
- 6ç« ãã¢ã»ã³ãã© : Hackæ©æ¢°èªãçæããã¢ã»ã³ãã©ãå®è£ ãã¾ã
- 7ç« ããã¼ãã£ã«ãã·ã³#1ï¼ã¹ã¿ãã¯æä½ : ã¹ã¿ãã¯ãã¼ã¹ã®VMãå®è£ ãã¾ããVMã½ã¼ã¹ã³ã¼ããã6ç« ã§ä½ã£ãã¢ã»ã³ããªãçæã§ããããã«ãã¾ãã
- 8ç« ããã¼ãã£ã«ãã·ã³#2ï¼ããã°ã©ã å¶å¾¡ : VMå®è£ ã®ç¶ãã§ä¸»ã«é¢æ°å¼ã³åºããå®è£ ãã¾ãã
- 9ç« ãé«æ°´æºè¨èª : Jackè¨èªã®è¨èªä»æ§ã«ã¤ãã¦ã®èª¬æã§ããå®éã«ããããä½ãJackè¨èªãæ¸ãã¦ã¿ã¾ãã
- 10ç« ãã³ã³ãã¤ã©#1ï¼æ§æ解æ : Jackè¨èªã³ã³ãã¤ã©ã®ããã³ãã¨ã³ãé¨åã®å®è£ ã§ããåèµ·ä¸éãã¼ãµã¼ãæ¸ãã¦ASTçæã¾ã§å®è£ ãã¾ãã
- 11ç« ãã³ã³ãã¤ã©#2ï¼ã³ã¼ãçæ : Jackè¨èªã³ã³ãã¤ã©ã®ããã¯ã¨ã³ãå®è£ ã§ããASTããVMåãã®ã³ã¼ãçæãè¡ãã¾ãã
ã³ã³ãã¤ã©ã®ç« ã¯å¤§ããåãã¦3é¨æ§æã§ãã¢ã»ã³ãã©ããã¼ãã£ã«ãã·ã³ãJackè¨èªã³ã³ãã¤ã©ã«åãããã¾ãã ããããã®ãã¼ãã§å®éã«ã¢ã»ã³ãã©ãã³ã³ãã¤ã©ãå®è£ ããããã§ãããè¨èªä»æ§ãæºããå®è£ ãã§ããã®ã§ããã°ä½¿ç¨ããããã°ã©ãã³ã°è¨èªã¯ä½ãç¨ãã¦ãæ§ãã¾ããã
ããã£ããã ãã俺ã¯ãã®Rustã¨ããè¨èªããé¸ã¶ãã
ã¢ã»ã³ãã©ãVMã®å®è£ ã§ã¯ãçæãããæ©æ¢°èªãã¢ã»ã³ãã©ãCPUã·ãã¥ã¬ã¼ã¿ã¼ä¸ã§åä½ãããã確èªãã¾ãã ãã¼ãã¦ã§ã¢ã§ã¯HDLä¸ã§åè·¯ããã¹ããã¾ããããã³ã³ãã¤ã©ã¯çæããã³ã¼ããã·ãã¥ã¬ã¼ã¿ã¼ã§ãã¹ããã¾ãã ãã¹ãã±ã¼ã¹ã¨ãã¦å ¥åã¨ãªãã½ã¼ã¹ã³ã¼ãã¨ãã®æå¾ ããåä½ããã¹ãããããã®ã¹ã¯ãªãããç¨æããã¦ããã®ã§ããã¹ãããã¹ãããããªæ©æ¢°èª/ã¢ã»ã³ããª/VMã³ã¼ããçæã§ãããã ã«é å¼µãã ãã§ãã
ã¢ã»ã³ãã©ã®å®è£ ã¯asmãã¡ã¤ã«ãè¡ãã¨ã«èªãã§ãã¼ã¹ãã¦æ©æ¢°èªã«å¤æããã ããªã®ã§æ©ã¿ã¯ãªãã£ãã§ãããã®é ã¯ä¸»ã«Rustã«ã¤ãã¦æ©ãã§ãã
Nand2TetrisãããããRustã§ã®ã¢ã»ã³ãã©å®è£ ãçµãã£ã¦VMã®å®è£ ã«å ¥ã£ãã
— 極éçå½ä½ããããNA (@yuroyoro) September 8, 2020
VMä½ãã®ãã®ãã
ãã®ãã
Nand2Tetrisã®ã¢ã»ã³ãã©ãGoã¨ãRubyã¨ãjsã¨ãææ £ããè¨èªã§æ¸ãããå¤å2, 3æéã§å®è£ ã§ããã¨æããã©ããã£ããRustãåå¼·ããªããæ¸ãã¦ã¿ããå®è³ª2é±éãããããã£ã¦å¦ç¿å¹çãããªãã£ãã§ããé¢ç½ãã£ããã©
— 極éçå½ä½ããããNA (@yuroyoro) September 8, 2020
ã¹ã¿ãã¯ãã·ã³ã¯Cã³ã³ãã¤ã©ä½æå ¥éã§ä¸åº¦å®è£ ãããã¨ããã£ãã®ã§ãé¢æ°å¼ã³åºãæã®ã¹ã¿ãã¯ã¨ããªã¿ã¼ã³ã¢ãã¬ã¹ã¨ããã®ãããã¯ç解ãã¦ããã®ã§ãããHackã¯ã¬ã¸ã¹ã¿2åãããªãã¦å®è£ ããã©ãã£ãã§ãã
é åã®nçªç®ã¸ã®æ¸ãè¾¼ã¿ã«nåã®å½ä»¤ãå¿ è¦ãªã¢ã»ã³ããªåãã¦ãã¿ã¾ããâ¦â¦ã¬ã¸ã¹ã¿ã足ããªã
— 極éçå½ä½ããããNA (@yuroyoro) September 18, 2020
ãªãã»ããã¬ã¸ã¹ã¿ã®æãé£ãã身ãæã£ã¦ä½æãã¦ããï¾
ã¬ã¸ã¹ã¿2åããç¡ãã®ã§ã¬ã¸ã¹ã¿å²ä»ã¨ãå®è£ ããªãã¦ããã¦æ¥½ã§ããð
— 極éçå½ä½ããããNA (@yuroyoro) September 18, 2020
æ±ç¨ãã¼ã¿ã¬ã¸ã¹ã¿ã¨ã¢ãã¬ã¹ã¬ã¸ã¹ã¿ãä¸ã¤ã¥ã¤ããç¡ãHackã¢ã¼ããã¯ãã£ã§åç´ã¨ã¯è¨ãã¹ã¿ãã¯ãã·ã³å®è£ ããã®ã¯ãã«ãã£ãããã¼ã«ãã§ã¤ã³ã«CPU Emulatorããã£ã¦å©ãã£ã
— 極éçå½ä½ããããNA (@yuroyoro) September 28, 2020
asmçæã§æåã¯jmpå½ä»¤ãé§ä½¿ãã¦ãµãã«ã¼ãã³åããasmãåãã¦ããããã©ããå½ä»¤æ°å¤ãããªã(ã©ãããjmpã®åå¢ãã)ã®ã§ã¤ã³ã©ã¤ã³å±éãããã¨ã«ããã
— 極éçå½ä½ããããNA (@yuroyoro) September 17, 2020
ã³ã³ãã¤ã©ã«æè¬ããæ§åã§ã
ã¢ã»ã³ããªæ¸ãã®ãã«ãããã®ã§ãé«æ°´æºè¨èªããã¢ã»ã³ããªãå®è¡å¯è½ãªæ©æ¢°èªãçæãã¦ãããã³ã³ãã¤ã©ã¯æé«ã¨ããæ°æã¡é«ã¾ã£ã¦ãã¾ã
— 極éçå½ä½ããããNA (@yuroyoro) September 24, 2020
ã³ã³ãã¤ã©ãé å¼µã£ã¦jumpå½ä»¤åãã¦ããããããã§GOTOããæ¸ããªãã¦ããããã ãã³ã³ãã¤ã©ã«æè¬ãã¦ï¼
— 極éçå½ä½ããããNA (@yuroyoro) September 28, 2020
Rustã¸ã®ç解ãæ·±ã¾ã£ã¦ããæ§åã§ã
Rustãææ権ã¨åç¨ã«ã¤ãã¦ã¯ãªãã¦ãããã©ãLIfetime修飾åã ãã¯ä½¿ãããªããæ°ãããªãã§ã
— 極éçå½ä½ããããNA (@yuroyoro) September 24, 2020
è¿·ã£ãããã³ãã¼ã§ãã? (ç¥è½)
Rustãæ§é ä½ã¡ã³ãã«åç §ããããã¨LIfetime修飾åã§æ»ã¬ãã©ãstd::rc::Rcã§åç §ã«ã¦ã³ãã§æããããLifetimeèããªãã¦ãåç §ã«ã¦ã³ãã§åæã«ç®¡çãã¦ãããã®ã§è§£æ±ºã§ã¯ï¼ï¼
— 極éçå½ä½ããããNA (@yuroyoro) October 27, 2020
(ãªãåç §ãªã¼ã¯ã«ã¤ãã¦ã¯èããªãäºã¨ããð)
Rustãããããªãã«ãæãããããããªãã³ãã¼ã®ã³ã¹ããããæã£ããããã¨ããèªæã¨æ¦ãããã°ã©ãã³ã°è¨èªã ã¨ããå®æã§ã
— 極éçå½ä½ããããNA (@yuroyoro) October 31, 2020
Rustã®macroã便å©ð
— 極éçå½ä½ããããNA (@yuroyoro) November 4, 2020
Rustæ¸ãã¦ãåã§ã pic.twitter.com/cmdQHAOBi1
— 極éçå½ä½ããããNA (@yuroyoro) September 14, 2020
ç¾ç¶ã§ã pic.twitter.com/Q70KBkJEyO
— 極éçå½ä½ããããNA (@yuroyoro) September 30, 2020
VMå®è£ çµãã£ãã¨ã
Nand2TetrisãRustã§Jack VMã®å®è£ ã¾ã§çµãã£ããhttps://t.co/v18qXGtFZy
— 極éçå½ä½ããããNA (@yuroyoro) September 28, 2020
Jackè¨èªã³ã³ãã¤ã©ã«é¢ãã¦ã¯åèµ·ä¸éãã¼ãµã¼ãæ¸ãããã¨ãããã®ã§å®è£ é¢ã§æ©ããã¨ã¯ãªãã£ãã§ã
å帰ä¸éãã¼ãµã¼ã好ãâ¡
— 極éçå½ä½ããããNA (@yuroyoro) October 14, 2020
Rustã§å帰ä¸éãã¼ãµã¼æ¸ãã¦ããã©ãæå³ããã«streamãæ¶è²»ãããããªãã°ãèµ·ãã«ããã®ã§ããæãã§ã
— 極éçå½ä½ããããNA (@yuroyoro) October 29, 2020
ãã ãã³ã³ãã¤ã«éãã¾ã§ãå³ãã
Rustã§æ½è±¡æ§ææ¨ã®ãããªå帰çãªæ§é ãå®ç¾©ããã¨ã©ããã¦ãBoxã«å ¥ããããå¾ãªãã¦ãrustcã¯ã©ããã£ã¦ããè¦ã¦ã¿ãããã£ã±ãBoxã«å ¥ãã¦ãã®ã§ééã£ã¦ãªãã£ã
— 極éçå½ä½ããããNA (@yuroyoro) November 4, 2020
Rustã§parserããã¿ã§æ¸ãã¦ã¿ããã©ãã³ã³ãã¤ã«ã¨ã©ã¼ã«ãã¹ãç®æãã¡ããã¨åãã§ãã«ã§ç¶²ç¾ ã§ããã®ã§ããã£ãã§ã á( á )á
— 極éçå½ä½ããããNA (@yuroyoro) November 8, 2020
ã§ãããNand2Tetris 10ç« ã®Jackè¨èªã³ã³ãã¤ã©ã®ããã³ãã¨ã³ãé¨åã®Rustå®è£ ããhttps://t.co/zXeqwuf4tN
— 極éçå½ä½ããããNA (@yuroyoro) November 8, 2020
12ç« : ãªãã¬ã¼ãã£ã³ã°ã·ã¹ãã
æ£ç´ããããã¯ãã¾ãã§ããJackè¨èªã§OSãæ¸ãã®ã§ããããã®OSã¯ä¸ã§è¿°ã¹ãã¨ãããã¼ãã¦ã§ã¢ã¨ã®ããã¨ããããããã®ã¡ã¢ãªã¢ã¯ã»ã¹ã便å©ã«ãã¦ãããã©ã¤ãã©ãªã¿ãããªãã®ã§ãã Jackè¨èªãéåãªè¨èªãªã®ã§æ¸ãã®ã¯ãã«ãã£ãã§ãã ãã ãèªä½ããã³ã³ãã¤ã©ãã¡ããã¨ã·ã³ã¿ãã¯ã¹ã¨ã©ã¼ãæ¤åºãã¦ãããã¨ãã¯ã¡ãã£ã¨ãããããã¿ã湧ãä¸ããã¾ããã?
èªä½ã³ã³ãã¤ã©ãã¡ããã¨ã³ã³ãã¤ã«ã¨ã©ã¼æ¤åºãã¦ããã¦ããã
— 極éçå½ä½ããããNA (@yuroyoro) November 16, 2020
ãã¨ãã°ãç»é¢ã«æåãåºåããã®ã«DMAãããç»é¢ã®ãã¯ã»ã«ã«å¯¾å¿ããã¡ã¢ãªã®ãããããã©ã³ãã«ãããã£ã¦ç«ã¦ãå¦çã¨ãæ¸ãã®ãã«ãã£ãã§ãã
ç»é¢ã«æåãåºåããã®ãã¸ã§ãã«ãã£ãã pic.twitter.com/vqEok7c89y
— 極éçå½ä½ããããNA (@yuroyoro) November 23, 2020
ãã¨ãç»é¢ã«âãæç»ããéã®é«éãªã¢ã«ã´ãªãºã ã¨ãåå¼·ã«ãªãã¾ãããå¤åãã使ããã¨ãªãã ãããã©
- Midpoint circle algorithm - Wikipedia
- ä¼èª¬ã®ãè¶ã®é No007-09(1) åã®æç»(1) Michenerã¨Bresenham
- QuickDrawã¯ã©ã®ããã«ç´ æ©ãåãæãã¦ããã®ãï¼ - ã¶ãªã¬ããè¦ã¦ãã...ã
ã¨ã¯ãããèªåã§æ¸ããOS(ã£ã½ãã©ã¤ãã©ãª)ã§ã²ã¼ã ãåããã¨ãã¯éææããã¾ãããã
Nand2Tetris ãã³ã³ãã¥ã¼ã¿ã·ã¹ãã ã®çè«ã¨å®è£ ããå®èµ°ãã¾ãã
— 極éçå½ä½ããããNA (@yuroyoro) November 23, 2020
CPUããOSã¾ã§ä¸æ°é貫ã§ä½ãã®ã¯æ¥½ããã£ãã§ãhttps://t.co/m223NjRcdS
ã¾ã¨ã
O'Reilly Japan - ã³ã³ãã¥ã¼ã¿ã·ã¹ãã ã®çè«ã¨å®è£ ã楽ããã®ã§ã¿ããªããã¨ããã§ãã?
ã¨ãã«ãã³ã³ãã¥ã¼ã¿ã¼ãµã¤ã¨ã³ã¹ã«è¦ææèãããã¨ããã¼ã¬ã¤ã¤ã¼æãã¨ãã®äººã«ããããã§ãããã£ã¦ã¿ãã¨ãã¨ã¦ãã·ã³ãã«ãªä»çµã¿ã®ç©ã¿éãã§ã³ã³ãã¥ã¼ã¿ã¼ãåä½ãã¦ãããã¨ãå®ä½é¨ã¨ãã¦ç解ã§ãã¾ãã ããã¦ãç¾ä»£ã®CPUãOSãã©ãã ãé²æ©ãã¦ããããâ¦â¦
åãä»åå¼·ã§ä½ã£ã¦ãã¬ã¸ã¹ã¿2åãããªãä¹é¤ç®ããã§ããªã16bitCPUã«æ¯ã¹ãã¨ããã«ãã³ã¢ã§L1,L2ãã£ãã·ã¥ãæã¡ãã¤ãã©ã¤ã³åããã¦åå²äºæ¸¬ããªãªã¼ãã¼ãè¡ããæµ®åå°æ°ç¹æ¼ç®ã©ãããSIMDã¨ãSHAè¨ç®ã¾ã§ãµãã¼ãããç¾ä»£ã®CPUã¯è¶ ææãæ®ãããªã¼ãã¼ãã«ããè¦ããªãã§ã
— 極éçå½ä½ããããNA (@yuroyoro) November 20, 2020
æ¬æ¸ã§åãæ±ãããããã®ãããã¯ã¯æ¦è¦ã¬ãã«ã§ãã®ã§ãä¾ãã°ã³ã³ãã¤ã©ã«ã¤ãã¦ãã£ã¨å¦ã³ããã¨ãOSã詳ããç¥ãããã¨ãããã¼ãºã«ã¯é©ãã¦ã¯ãã¾ããããå ¨ä½ã俯ç°ããå ¥ãå£ã¨ãã¦ã¯æé©ã ã¨æãã¾ãã
ããã¦ãç解ãæ·±ããã«ã¯ãã®ãããåç´ã§ãããããèªåã§ä½ã£ã¦ã¿ãã¦ã£ã¨ãæ©ãã®ã§ãããæ¬æ¸ã¯ãããæå©ããã¦ãããç´ æ´ãããå 容ã§ããã ä»å¾ã¯ãèªä½ãã©ã¦ã¶ã¨ãèªä½TCP/IPãããã³ã«ã»ã¹ã¿ãã¯ã¨ãèªä½RDBMSã¨ããææ¦ãã¦ã¿ãããã®ãå±±ç©ã¿ã§ãã
ã§æ¬¡ã§ãããNand2Tetrisã§ã¯OSé¨åãèãã¦ç©è¶³ããªããã£ãã®ã§ãOSãä½ã£ã¦ã¿ããã¨ã«ãã¾ããã
è²·ãã¾ãããï¼
— 極éçå½ä½ããããNA (@yuroyoro) November 17, 2020
30æ¥ã§ã§ãã! OSèªä½å ¥éãå§è¨ã - é人åºçä¼ https://t.co/WfHOtXQSS6
12æã¯å¿ãç®ãªã®ã§ãå¹´æ«å¹´å§ããã¾ãè °ãæ®ãã¦åãçµã¿ããã¨æãã¾ãã
ãã¨ãRustå®å ¨ã«ãã¹ã¿ã¼ãã¾ãã(å ãæ¾ã¡ãªããæ¶æ» )
ã©ãºãã¤ã¨WebRTCã§åç©ã®æ»æ´»ç£è¦ãã§ããããã«ãã話
ããã«ã¡ããããããã§ãã
ä»ã¯å¤ä¼ã¿ã§å¥¥ããã¨åã©ããã¡ã帰çãã¦ããã®ã§ãåç©ã¨2人ã§æ®ããã¦ãã¾ãã
ã§ãå¤åºããã¨åç©ã ãã家ã«æ®ãã¦ãããã¨ã«ãªãã¾ãã ãããã¢ãã¿ã¼ã¨ãå¸è²©ã§ããããã§ããããã£ãããªã®ã§ã å¤ä¼ã¿ã®èªç±ç 究ã¨ãã¦ãã©ãºãã¤+ã«ã¡ã©ã¢ã¸ã¥ã¼ã«ã¨WebRTCã使ã£ã¦ãå¤åºå ããã§ãåç©ã®ç¶æ ã確èªã§ãããã¤ãä½ã£ã¦ã¿ã¾ããã
â æ»æ´»ç£è¦ãããåç©ã®æ§åã§ã
ç¨æãããã®
- Pi3 B+ ã¹ã¿ã¼ã¿ã¼ããã V3 16GB ç½
- Piã«ã¡ã© Official V2 for 3/2/1/0
- Manfrotto ããä¸è PIXI ãã©ã㯠MTPIXI-B ã«ã¡ã©ç¨
- Manfrotto ã¹ãã¼ããã©ã³ç¨ä¸èã¢ããã¿ã¼ MCLAMP
- HAKUBA èªç±é²å° BH-1
ã©ãºãã¤3ã¨ã±ã¼ã¹ã®ã»ããã¨ã«ã¡ã©ã¢ã¸ã¥ã¼ã«ã¯ Raspberry Pi Shop by KSY ã§è³¼å ¥ãæééå®ã»ã¼ã«ã§ã¡ãã£ã¨å®ãã£ãã§ãã ãã®ã»ããã«ã¤ãã¦ãã±ã¼ã¹ã¯ãã©ãºãã¤ã®ãã¼ã¯ã®ç©´ã«ã«ã¡ã©ã¢ã¸ã¥ã¼ã«ãåºå®ãããã¨ãã§ãã¦ä¾¿å©ã æé¨å ã®momoã ã¨ãRaspberry Pi ã® GPU ã®H.264 ãã¼ãã¦ã§ã¢ã¨ã³ã³ã¼ãã¼æ©è½ãå©ç¨ã§ãããããã®ã§ãã©ãºãã¤zeroã§ãè¡ãããããã§ãã
ã§ãã©ãºãã¤ãä¸èã¨ã¹ããç¨ã¢ããã¿ã§åºå®ãã¾ãããããªæãã«ãªãã
ã©ãºãã¤ã®åæè¨å®
ã¾ãã¯ã©ãºãã¤ã®åæè¨å®ã§OSã¤ã³ã¹ãã¼ã«ãè³¼å ¥ãããããã®SDã«ã¼ãã«ãã§ã«OSãç¨æããã¦ããã®ã§ãé»æºå ¥ãã¦ç»é¢ã®éãã«ã»ããã¢ããããã°çµäºã
Raspberry Pi 3 Model B+ã®ååã»ããã¢ããï¼è³¼å ¥ããèµ·åã¾ã§ï¼ - Qiita
ãã¨ã¯ãsshã¨ã«ã¡ã©ã¢ã¸ã¥ã¼ã«ãconfigããæå¹ã«ãã¦ããã
Raspberry Piã«ã¡ã©ã®ã»ããã¢ããæ¹æ³
æå¾ã«ãmDNSã¨sshå¨ãã®è¨å®ãè¡ã£ã¦ãGUIããªãã«ãã¦å®äºãããã§æå ã®macbookããsshã§æ¥ç¶ãã¦ä½æ¥ã§ããããã«ãªã£ãã
ææã¡ã®RaspberryPiããµã¯ãã¨mDNSã«å¯¾å¿ããã - Qiita
WebRTC Native Client Momo
æé¨å ã® WebRTC Native Client Momo ã使ãã¾ãããã£ããæ¥ç¶ã§ãã¦æé«ã§ããã
Githubã®ãªãªã¼ã¹ãã¼ã¸ ããææ°ã®ãã¤ããªãtarã§é å¸ããã¦ããã®ã§ããã¦ã³ãã¼ããã¦è§£åããã ãã§ãã
å¿ è¦ãªã©ã¤ãã©ãªãå ¥ãã¦ã
$ sudo apt-get install libnspr4 libnss3
ãã¨ã¯ãã¤ããªãå®è¡ããã ãã§ãã©ãºãã¤ã®ã«ã¡ã©ã¢ã¸ã¥ã¼ã«ãå©ç¨ããã¹ããªã¼ãã³ã°ãå¯è½ã«ãªãã¾ãã
$ ./momo --no-audio ayame wss://ayame-lite.shiguredo.jp/signaling <your-github-id>@<your-room-name> --signaling-key <your-signaling-key>
èµ·åæã®ãªãã·ã§ã³ã¯ãã·ã°ããªã³ã°ãµã¼ãã¼ã«Ayameã¨ãã®URLãããã¦ã«ã¼ã IDãæå®ãã¾ããã¾ãã次ã§èª¬æããã·ã°ããªã³ã°ãã¼ããããã¾ãã
æé¨å WebRTC ã·ã°ããªã³ã°ãµã¼ãã¹ Ayame Lite
WebRTCã«ããã¦NATè¶ ãã§éä¿¡ãè¡ãã«ããã£ã¦ãã·ã°ããªã³ã°ãµã¼ããä»ãã¦ããããã®ãã¢ã®æ¥ç¶ã®èª¿æ´ãè¡ãå¿ è¦ãããã æé¨å ãWebRTC ã® P2P å©ç¨åãã«ç¡æã§å©ç¨ã§ããã·ã°ããªã³ã°ãµã¼ãã¹ãæä¾ãã¦ããã¦ããã®ã§ãããããã使ããã¦ããã ãã¾ãã
WebRTC ã·ã°ããªã³ã°ãµã¼ãã¹ Ayame Lite éçºãã°
P2Pã§æ¥ç¶ã§ããå ´åã«ã¯ãç¹ã«ç»é²ãå¿ è¦ãªã使ãã¾ãã4Gåç·ã®å ´åãªã©TURNãµã¼ãã¼ãçµç±ããå¿ è¦ãããå ´åã¯ããã¼ã¿ãã¹ãä¸ã®ã·ã°ããªã³ã°ãã¼ãå©ç¨ãã¦TURNãµã¼ãã¼ã®æãåºãããã¦ãããå¿ è¦ãããã¾ãã Githubã¢ã«ã¦ã³ãã§ãµã¤ã³ã¢ããããã¨ãã·ã°ããªã³ã°ãã¼ãçºè¡ããã¦TURN ãµã¼ãã®å©ç¨ãå¯è½ã«ãªãã¾ãã
STUN/TURNã«ã¤ãã¦ã¯ãã®ãããåç §
- WebRTCã®è£å´
- å£ãè¶ããï¼WebRTCã§NAT/Firewallãè¶ãã¦éä¿¡ããã | HTML5Experts.jp
4Gã§ã¤ãªãããªãã¨twitterã§åã£ã¦ããã¨ããã @voluntas ã«ãã¼ã¿ç使ã£ã¦ã¿ã? ã¨ãèªããåããã®ã§ãããããã使ããã¦ãããã¾ããã ã¡ããã©ãªã¼ãã³ãã¼ã¿ãå§ã¾ã£ãã¨ããã§ããã
Ayame Lite ãªã¼ãã³ãã¼ã¿ãã¹ãéå§ãã¾ãã - shiguredo - Medium
ãã¡ãããGithubã¢ã«ã¦ã³ãã§ãµã¤ã³ã¢ããã§ãã¾ãã
æé¨å æé«ã§ã¯?
ã¯ã©ã¤ã¢ã³ãå´ã®å®è£
ãã¨ã¯ãã¯ã©ã¤ã¢ã³ããæºåãã¦æ¥ç¶ã§ããæã£åãæ©ã試ãã¦ã¿ãã®ã«ã OpenAyame/ayame-react-sample: Ayame React ãµã³ãã« ãå©ç¨ãã¾ããã
ä¸è¨ã®ãªãã¸ããªã git clone
ãããã¨ã yarn install
ã㦠yarn serve
ããã¨ãlocalhostã§åä½ç¢ºèªãã§ãã¾ãã
ãããªæãã§ãAyameã®URLã¨ãèªåã§æå®ããã«ã¼ã IDãã·ã°ããªã³ã°ãã¼ãå ¥åãã¦æ¥ç¶ãæ¼ãã¨ãã¹ããªã¼ãã³ã°ã§ã©ãºãã¤å´ã®ã«ã¡ã©ããé ä¿¡ããã¦ãããã¨ã確èªã§ãã¾ãã
iOS Safariã®å ´åã¯åçãã¿ã³ãæ¼ãå¿
è¦ãããã¨ã®ãã¨ã§ãvideo
ã¿ã°ã« controls
ã追å ãã¦å¯¾å¿ãã¾ããã
<Videos> <RemoteVideo ref={remoteVideoRef} muted autoPlay controls/> </Videos>
ãã®ä»èª¿æ´
ã¾ããã¯ã©ã¤ã¢ã³ãã®ã¢ã»ããä¸å¼ãé©å½ãªå ´æããé
ä¿¡ã§ããããã«ãã¾ãã yarn build
ãã¦ã§ããææç©ããããVPSã«nginxãç«ã¦ã¦ï¾ï½¯ï¾ãï½´ï¾ï½¸ï¾ï¾ï¾ï¾ãã¦httpsã§é
ä¿¡ã§ããããã«ãã¾ããã
httpsã§é
ä¿¡ã§ããå ´æãªããcloudfrontã¨ãNetlifyã¨ãã§ãããã¨æãã¾ãã
ãã¨ã¯ãã©ãºãã¤å´ã®momoãsystemdã®ãµã¼ãã¹ã¨ãã¦è¨å®ãã¦èµ·åæã«èµ·ããããã«ããã°çµããã§ãã
Raspberry Pi 㧠systemd ã使ã£ã¦ããã°ã©ã ãèªåå®è¡ãã - Qiita
ã¾ã¨ã
ã©ãºãã¤ã§WebRTCããã«ããã£ã¦ãå½å㯠NTTã³ã ããã®æä¾ãã Skyway ã¨ãã®sdkã試ãã¦ã¿ãã®ã§ãããã©ãããã¢ãä¸æãåä½ãã¾ããã§ããã æé¨å ã®momoã¨OpenAyameã使ã£ã¦ã¿ãã¨ããããã¤ããªãè½ã¨ãã¦ãã¦ããã¥ã¡ã³ãã®æé éãã«é²ããã ãã§ãã£ããæ¥ç¶ã§ãã¦ãã¾ãã¾ããã
ããã§å¤åºæã§ãåç©ã®æ§åãæ»æ´»ç£è¦ãã§ãã¦æãã
æé¨å æé«ã§ã¯?
async/awaitã¨promise使ãã°ã¢ããç³è¡£æ§æã£ã½ãã®æ¸ãããã ããã£ã¦æã£ã¦æ¸ãã¦ã¿ããã©ãasync () => {} ã§wrapããªãã¨ãããªããã¾ããããªã«ãããã«æ¸ããªãã£ãã£ã¦è©±
ã¿ã¤ãã«ã§å ¨é¨è¨ãåã£ã¦ã¾ãã
// Optional container like maybe monad class Option { constructor(value){ this.value = value } async promise() { return new Promise((resolve, reject) => { if (this.value) { resolve(this.value); } else { reject(undefined); } }); } }
ãããªMaybe ã¨ãOptionalã£ã½ããã¤ãç¨æãã¾ãã promise()
㧠Promiseãçæãã¦è¿ãããã«ãã¾ãããã£ã¦ãå¤ã«å¿ã㦠resolve
(JustãSome)ããã reject
(Nothing)ããããã¾ãã
const o1 = new Option("foo"); const o2 = new Option("bar"); const o3 = new Option(null); (async () => { try { const v1 = await o1.promise(); const v2 = await o2.promise(); console.log(v1, v2); } catch {} })(); // => foo bar (async () => { try { const v1 = await o1.promise(); const v2 = await o2.promise(); const v3 = await o3.promise(); console.log(v1, v2, v3); } catch {} })(); // do nothing // introduce doM emulates do-like syntax sugar async function doM(f1, f2) { try { return f1(); } catch { if (f2) { return f2(); } } } // => foo bar
asyncã®ä¸ã§ã promise()
ã awaitã§å¼ã³åºããã¨ã§ã doè¨æ³ã£ã½ãããâ¦â¦ã«è¦ããªãããªããªãã³ã¼ãã«ãªãã¾ãããã§ã失æç³»å¦çããªãå ´åã§ã catch
æ¸ãå¿
è¦ããã®ãã«ãã§ããï¼
try..catch
ãå¤ããã«ãã£ã¦ããããã«ãã¼ãå°å
¥ãã¾ããã
// introduce doM emulates do-like syntax sugar async function doM(f1, f2) { try { return f1(); } catch { if (f2) { return f2(); } } }
ãã® doM
ã« asyncãªç¡åé¢æ°ã渡ãã¨ããã®ä¸ã§doè¨æ³ã£ã½ãããâ¦â¦ã«è¦ããªãããªããªãã³ã¼ããæ¸ãã¾ãã
doM(async () => { const v1 = await o1.promise(); const v2 = await o2.promise(); console.log(v1, v2); }); // => foo bar doM(async () => { const v1 = await o1.promise(); const v2 = await o2.promise(); const v3 = await o3.promise(); console.log(v1, v2, v3); }); // do nothing
ã ããã©ãããã£ã¦è©±ã§ããããããããªã¢ãããä½ã£ã¦åæãã¦æ±ãå ´åã«ä¾¿å©ãããããªãã§ããããããã¢ããã¨ãJavaScriptã§ä½ããªã以ä¸
é¢æ°ã®è©±
ããã«ã¡ã¯ãããããã§ãã
ææã§é¢æ°åããã°ã©ãã³ã°ã¨ã¯ãªã¹ãå¦çã®ãã¨ãªã®ããã¨çãã¦ããã®ãè¦ã¦ãé¢æ°åããã°ã©ãã³ã°ã¨ã¯ä½ããã¨ãããã¨ãèªåãªãã®èããè¿°ã¹ããã¨æãã¾ãããæ¥ãªã®ã§ã
ãã®è³æã¯2å¹´ã»ã©åã«Supershipã®ç¤¾å åå¼·ä¼ã§ä½¿ã£ããã®ã§ããããã®ä¸ã§é¢æ°ã¨ãªãã¸ã§ã¯ãã対æ¯ãã¦ããç®æãããã¾ãã é¢æ°ããªãã¸ã§ã¯ãããå¤æ°ãé¢æ°ã®å¼æ°æ»ãå¤ã¨ãã¦æ±ãã第1ç´ã®å¤ã§ãããç¶æ ãæã¡(ã¡ã³ãã¼å¤æ°/ã¯ãã¼ã¸ã£)ãçµã¿åãããå¯è½(delegate, composition/é¢æ°åæ)ãã§ãããã¨ã
ã§ã¯ãªãã¸ã§ã¯ãæåã¨é¢æ°åããã°ã©ãã³ã°ã§ä½ã決å®çã«ç°ãªããã¨ããã¨ãè¨è¨ã»å®è£ ã®ã¢ããã¼ãã«ä½ãä¸å¿ã«æ®ããããã¨ãããã¨ã ã¨æãã¾ãã
ãªãã¸ã§ã¯ãæåã§ã¯ãã¯ã©ã¹ã»ãªãã¸ã§ã¯ããã¢ããªã³ã°ããå種ã®ãªãã¸ã§ã¯ãæåçãã¶ã¤ã³ãã¿ã¼ã³ãç¨ãã¦ãªãã¸ã§ã¯ãå士ãçµã¿åãããªããè¨è¨ã»å®è£ ãè¡ãã¾ãã é¢æ°åããã°ã©ãã³ã°ã§ã¯ãé¢æ°ãç´°ããªçµã¿åããå¯è½ãªåä½ã«å解ããé¢æ°åæãå帰ãã¯ãã¼ã¸ã£ãªã©ãé§ä½¿ããªããçµã¿åããããã¨ã§è¨è¨ã»å®è£ ãã¾ãã
ããæ¸ãã¦ã¿ãã¨å½ããåã®ãã¨ã§ãããã³ã¼ãã®è¨è¿°ã¹ã¿ã¤ã«ã ãè°è«ãã¦ãæå³ããªãã¦ããã®ãããªè¨è¿°ã¯ããã°ã©ã å ¨ä½ã貫ãææ³ã®ãªãã§ã©ã®ãããªä½ç½®ã¥ãã«ããã®ãã®ã³ã³ããã¹ããéè¦ãªã®ã§ã¯ãªãã§ããããã ä¾ãã°ãGoã§ã¯ç¡çãã¦ç¡åé¢æ°ãç¨ãããªã¹ãå¦çãæ¸ããããforã§æ¸ãã»ããã¯ããã«èªç¶ã§ãããã JavaScriptã§ã¯â¦â¦ã©ãã§ãããããè²ã ãªã¹ã¿ã¤ã«ã§æ¸ããã®ã§è°è«ãç´ç³¾ããã®ããã
map/reduceã使ã£ããªã¹ãå¦çãé¢æ°åããã°ã©ãã³ã°ã®å ¨ã¦ãã¨ããã¨ããã§ã¯ãªããããã¾ã§é¢æ°ãä¸å¿ã«æ®ããèããæ¹ã®ä¸ã¤ã¨ãã¦ãé 延è©ä¾¡ + é«éé¢æ°/ã¯ãã¼ã¸ã£ã®çµã¿åããã«ããã¹ããªã¼ã ã©ã¤ã¯ãªå®è£ ããããã¨ãããã¨ã ã¨æãã¾ãã é¢æ°ãä¸å¿ã«æ®ããã¨ããä½ããã£ã«ã¿ã¼ãããããè¦ç´ ãã©ã®ããã«å¤æããããã¨ããå¦çã®åä½ãé¢æ°ã¨ãã¦æ½åºããããã®çµã¿åããæ¹æ³ã¨ãã¦é 延è©ä¾¡ãªã¹ãã¨é«éé¢æ°ãç¨ããæ¹æ³ããããã¨ããã ãã§ãã çµæãé¢æ°ãä¸å¿ã«ãããã¢ããã¼ãã§ã¯map/reduceã使ãè¨è¿°ãèªç¶ã¨å°ããã¾ãã ã¨ã¯ããã ãªã¹ãå¦çã®å®è£ ã¨ãã¦ã¯å帰ã使ãæ¹æ³ãããã®ã§ãããã¾ã§é¢æ°åããã°ã©ãã³ã°ã«ãããªã¹ãå¦çã®1ã¢ããã¼ãã«ããã¾ããã
ã©ã¡ãã®ã¹ã¿ã¤ã«ã§æ¸ãã®ãããããã¨ããã®ã«çµ¶å¯¾çãªæ£è§£ã¯ãªãã¨æãã¾ãããé¢æ°ãä¸å¿ã¨ããã¢ããã¼ããç¥ã£ã¦ããã¨ãæç¶ãåã®ããã°ã©ã ãæ¸ãã¦ãã¦ãæãã¬å ´é¢ã§å½¹ã«ç«ã¤ãã¨ãããã¾ãã ã¡ããã©æè¿å½¹ã«ãã£ãå®ä½é¨ã®ã²ã¨ã¤ã§ã ãã rspecã®ããã©ã¼ãã³ã¹ãã¥ã¼ãã³ã°ã®éã«é 延è©ä¾¡ãå½¹ã«ãã£ããã¨ãããã¾ãã
error_msg = generate_error_message(actual_value, expected_value) expect(actula_value).to have_content(expected_value), error_msg
ãããªæãã®rspecã®ã³ã¼ãã§ã assertã®ã¨ã©ã¼æã«è¡¨ç¤ºãã error_msg
ãçæãã generate_error_message
ãé常ã«ã³ã¹ãã®æããå¦çã§ããã
é常ã¯assertã«å¤±æããå ´åã®æ¹ãç¨ãªã®ã§ãå¿
è¦ã«ãªãã¾ã§(assertã«å¤±æããã¾ã§) ãã®å¦çã®å¼ã³åºããé
延ããããã¨ã§æ§è½ãæ¹åãããã§ãã
rspecã® expect
ã¯ã¨ã©ã¼ã¡ãã»ã¼ã¸ã®ä»£ããã« Proc
ã渡ããã¨ãå¯è½ã§ãã
ããã§ãã¨ã©ã¼ã¡ãã»ã¼ã¸ãçæããå¦çãã¯ãã¼ã¸ã£ã¨ãã¦æ½åºãã expect
ã«æ¸¡ããã¨ã§é
延è©ä¾¡ããããã¨ãã§ãã¾ãã
error_msg_generator = ->() { generate_error_message(actual_value, expected_value) } expect(actula_value).to have_content(expected_value), error_msg_generator
é¢æ°åããã°ã©ãã³ã°ã®ç¥èãããã¨ã expect
ã®å¼æ°ã Proc
ãåããã¨ããã·ã°ããã£ãããé
延è©ä¾¡ã«ããæ§è½æ¹åã«å©ç¨ããçºæ³ãå°ããã¾ãã
ãã®ããã«ãé¢æ°åããã°ã©ãã³ã°ã¯é常ã®æç¶ãåããã°ã©ãã³ã°ã§ããããã«å½¹ç«ã¡ã¾ãã®ã§ãåæ¹ããããã®ææ³ãå¦ãã§ããã¨ããã°ã©ãã³ã°ã®è£¾éãåºããã¾ã
ããããã¼ããé¢æ°åããã°ã©ãã³ã°ãå¦ã¶ãã¨ããªã¹ã¹ã¡ããçç±ã§ãã
ã¾ã¨ã
- é¢æ°åããã°ã©ãã³ã°ã¨ã¯ãé¢æ°ãä¸å¿ã¨ããã¢ããã¼ãã
- ãªã¹ãå¦çã¯é¢æ°åããã°ã©ãã³ã°ã®ä¸å´é¢
- ã©ã£ã¡ããããã¯ã±ã¼ã¹ãã¤ã±ã¼ã¹
- é¢æ°åããã°ã©ãã³ã°ãç¥ã£ã¦ããã¨ããã°ã©ãã³ã°ã®è£¾éãåºããã
ããããããããã§ãã
ä½ã£ã¦å¦ã¶ ãHttps Man in The Middle Proxyã in Go
á( á )á ããã«ã¡ããããããã§ãã
webã®httpsåãæ¨é²ãããæ¨ä»ã§ãã?
httpséä¿¡ã¯çµè·¯ä¸ã§ã®éä¿¡å
容ãçè´ã»æ¹ç«ãããã®ãé²ããã¨ãã§ãã¾ãããéçºç¨éã§httpséä¿¡ã®å
容ã確èªãããå ´åãç¨ã«ããã¾ãã
ãã®ãããªå ´å㯠mitmproxy ãªã©ãå°å
¥ããã°ããã®ã§ããããã£ãããªã®ã§å®éã«ãã®ãããªProxyãGoã§å®è£
ãã¦ã¿ã¦ã ä¸éè
æ»æ(Man-in-The-Middle Attack)ãã©ã®ãããªææ³ã§httpséä¿¡ãçè´ã»æ¹ç«ããã®ã確ããã¦ã¿ã¾ããã
å®éã«æ¸ããProxyã®ã³ã¼ãã¯ãã¡ãã§ã
https proxy 㨠HTTP CONNECT tunneling
ã¾ããé常ã®https Proxyã®åä½ã確èªãã¦ã¿ã¾ãããã
httpsã§ã¯ãProxyã¯ã¯ã©ã¤ã¢ã³ãããã®CONNECTã¡ã½ãããåä¿¡ããã¨ãã¯ã©ã¤ã¢ã³ãã«ä»£ãã£ã¦å¯¾è±¡ãã¹ãã¨ã®TCPã³ãã¯ã·ã§ã³ã確ç«ãã以éã¯ã¯ã©ã¤ã¢ã³ãã¨å¯¾è±¡ãã¹ãã®TCPéä¿¡ã転éãã¾ããã¯ã©ã¤ã¢ã³ã-ãã¹ãéã®TLSæ¥ç¶ã®handshakeãproxyãçµç±ãã¦è¡ãã¾ãã
ãã®æ¹å¼ã«ãããProxyãçµç±ãã¤ã¤ã¯ã©ã¤ã¢ã³ã-ãã¹ãéã§TLSã»ãã·ã§ã³ã確ç«ãããProxyãçµç±ãã¤ã¤ãçµè·¯ä¸ã§ã¯æå·åãããéä¿¡ãå¯è½ã¨ãªãã¾ãã
å³ã«ããã¨ãããªæãã§ã
å®è£
ã§ã¯å
·ä½çãªå®è£
ãè¦ã¦ã¾ãããã
ã¾ãã¯ããªãã¿ ServeHTTP
ã§ããã¯ã©ã¤ã¢ã³ããã CONNECT
ã¡ã½ãããéä¿¡ãããããéä¿¡ã転éãã relayHTTPSRequest
ãå¼ã³åºãã¾ã
https://github.com/yuroyoro/mitm_proxy_sample/blob/master/main.go#L34
func (proxy *MiTMProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { // CONNECT ã¡ã½ãããæ¥ãã if r.Method == http.MethodConnect { if proxy.mitm { proxy.mitmRequest(w, r) // Man in The Middleãã } else { proxy.relayHTTPSRequest(w, r) // Tunnelingã§éä¿¡ã転éãã } return } proxy.transportHTTPRequest(w, r) }
å®éã«éä¿¡ã転éãã¦ããã³ã¼ãã¯ä»¥ä¸ã®ã¨ããã§ããå¦çã®æµãã¯ã³ã¡ã³ããèªãã§ãããã°ãããã¨æãã¾ããããã£ã¦ãããã¨ã¯åç´ã§ãã
CONNECT
ã¡ã½ããã§æå®ããããã¹ãã«TCPæ¥ç¶ãå¼µã£ã¦ãã¯ã©ã¤ã¢ã³ãããã®éä¿¡ããã®ã¾ã¾æµãè¾¼ãã ãã§ã
https://github.com/yuroyoro/mitm_proxy_sample/blob/master/https.go#L12
func (proxy *MiTMProxy) relayHTTPSRequest(w http.ResponseWriter, r *http.Request) { proxy.info("relayHTTPSRequest : %s %s", r.Method, r.URL.String()) // CONNECTå ã®Hostã¸TCPã³ãã¯ã·ã§ã³ãå¼µã dest, err := net.Dial("tcp", r.Host) if err != nil { http.Error(w, err.Error(), http.StatusServiceUnavailable) return } // http.Hicjacker ãå©ç¨ãã¦ã¯ã©ã¤ã¢ã³ãã¨ã®çã®TCPã³ãã¯ã·ã§ã³ãåãåºã conn := hijackConnect(w) // ã¯ã©ã¤ã¢ã³ãã«ã¯200 OKãè¿ããããã§ã¯ã©ã¤ã¢ã³ãã¯ãã®TCPæ¥ç¶ã«HTTPãªã¯ã¨ã¹ããéã£ã¦ãã conn.Write([]byte("HTTP/1.0 200 OK\r\n\r\n")) proxy.info("relayHTTPSRequest : start relaying tcp packets %s %s", r.Method, r.URL.String()) // ã¯ã©ã¤ã¢ã³ã-対象Hostéã®TCPéä¿¡ããã®ã¾ã¾ä¸ç¶ãã go transfer(dest, conn) go transfer(conn, dest) } func transfer(dest io.WriteCloser, source io.ReadCloser) { defer dest.Close() defer source.Close() io.Copy(dest, source) }
Goã«ã¯ http.Hijacker ã¨ãã便å©ãªã¤ã³ã¿ã¼ãã§ã¼ã¹ãããã http.ResponseWriter
ããçã®ã¯ã©ã¤ã¢ã³ãã¨ã®TCPæ¥ç¶ãåãåºããã¨ãã§ãã¾ãã
ãããå©ç¨ãã¦ãTCPéä¿¡ã®è»¢éãè¡ã£ã¦ãã¾ã
func hijackConnect(w http.ResponseWriter) net.Conn { hj, ok := w.(http.Hijacker) if !ok { panic("httpserver does not support hijacking") } conn, _, err := hj.Hijack() if err != nil { panic("Cannot hijack connection " + err.Error()) } return conn }
å®éã¯timeoutãªã©ãèæ ®ããå®è£ ããã¹ããªã®ã§ãããããã ãã§ãåãã¾ãã
Man in The Middel Proxyã®ä»çµã¿
ã§ã¯ãæ¬é¡ã®ä¸éè æ»æãè¡ãProxyã«ã¤ãã¦ã§ãã
é常ã®https proxyã§ã¯ãã¯ã©ã¤ã¢ã³ãããã® CONNECT
ã¡ã½ãããå¥æ©ã«ã対象Hostã¨ã®TCPéä¿¡ãä¸ç¶ãã¦ãã¾ããã
Proxyãæµããéä¿¡å
容ã¯TLSã«ãã£ã¦æå·åããã¦ãããå
容ãçè´ã»æ¹ç«ãããã¨ã¯ã§ãã¾ããã
ãããã対象Hostã¨ã¯ã©ã¤ã¢ã³ãéã®TLS handshakeãProxyãçµç±ããã®ã§ããã®æ®µéã§ã¯ã©ã¤ã¢ã³ãããã®TLS handshakeãã対象ãã¹ãã«ãªããã¾ãã¦Proxyãè¡ãã¨ã©ããªãã§ããããï¼
ã¤ã¾ããProxyã¯å¯¾è±¡ãã¹ãã®ãµã¼ãã¼è¨¼ææ¸ããã®å ´ã§çæãã¦ç½²åããã¯ã©ã¤ã¢ã³ãã«æ示ãã¾ãã
ãã¡ãããProxyãç½²åãããµã¼ãã¼è¨¼ææ¸ã¯ä¿¡é ¼ã§ããªãCAã®ãã®ã¨ãã¦ãã©ã¦ã¶ã«ã¯è¦åãåºã¾ããããã®ã¾ã¾ã¦ã¼ã¶ã¼ãç¶è¡ãããã¨ã§TLS handshakeãæåãã¾ãã
ã¯ã©ã¤ã¢ã³ãã¯ç¢ºç«ããTLSæ¥ç¶ã対象ãã¹ãã¨ã®ãã®ã ã¨æãããã§ãProxyãã¯ã©ã¤ã¢ã³ãã«éãè¾¼ãã ãã»ã®ãµã¼ãã¼è¨¼ææ¸ã®å
¬ééµã§éä¿¡ãæå·åããã®ã§ãProxyã¯ãã®å
容ã復å·ãããã¨ãã§ãã¾ãã
ãã¨ã¯ã復å·ãããªã¯ã¨ã¹ãããã®ã¾ã¾å¯¾è±¡ã®ãã¹ãã«è»¢éããã°ãhttpsã«ãé¢ãããProxyã¯éä¿¡å
容ãææ¡ãã¤ã¤ã対象ãã¹ãã¨ã®éä¿¡ãåãæã¤ãã¨ãã§ãã¦ãã¾ãã¾ãã
ããã§ä¸éè
æ»æãæç«ãã¾ãÊã ï¾ç¿ï¾ Ê ã
å³ã«ããã¨ä»¥ä¸ã®æµãã¨ãªãã¾ã
é常ããã®ãããªæ»æã¯ãã©ã¦ã¶ãè¦åãåºãããã«æç«ãã¾ããã
ã¾ããã¦ã¼ã¶ã¼ãæ示çã«ãã©ã¦ã¶ã«Proxyãæå®ããå¿
è¦ãããã¾ãã(port forwardãå©ç¨ããééProxyã¯ãã®éãã§ã¯ãªã)ãProxyãç½²åã«ä½¿ç¨ããã«ã¼ã証ææ¸(ã¾ãã¯ä¸é証ææ¸)ãTrust Chainã«ãªãããã§ãã
éã«è¨ãã°ãä¿¡é ¼ã§ããªãã«ã¼ã証ææ¸ãã·ã¹ãã ã«ã¤ã³ã¹ãã¼ã«ãã¦ãã¾ãã¨ããã®ãããªæ»æãæç«ããä½å°ãçã¾ãã¦ãã¾ãã¾ãã
å®éã«ãä¸é¨ã®ã»ãã¥ãªãã£ã¢ãã©ã¤ã¢ã³ã¹ãã¢ã³ãã¦ã£ã«ã¹ã½ããã¦ã§ã¢ã¯ããã®ãããªææ³ã§httpséä¿¡ã®å
容ããã§ãã¯ãã¦ãã¾ãã
Avastãå
¥ããç¶æ
ã§ãã©ã¦ã¶ã§è¨¼ææ¸ãã§ã¼ã³ã確èªããã¨ã ãAvast trusted CAãã¨ããè¬ã®èªè¨¼å±ãåºç¾ããã®ã¯ãã®ããã§ã( ;ï¾ç¿ï¾)ï¾ï½¼Î£ ï¾ï½¨ï¾ï½·ï¾ï½¨ï½¨ï½°ï½°ï½¯!!!
以åãLenovoã®PCã«ããªã¤ã³ã¹ãã¼ã«ãããã¢ãã¦ã§ã¢ãSuperfishããã«ã¼ã証ææ¸ãã·ã¹ãã ã«ã¤ã³ã¹ãã¼ã«ããä¸ã«ãå
¨PCã§å
±éã®CAç§å¯éµã使ã£ã¦ãããã¨ã§å¤§åé¡ã«ãªãã¾ãããã
Dellã§ãä¼¼ããããªãã¨ããã£ãã¿ããã§ã( êªâêª)
Lenovoã®PCå ¨æ©ç¨®ã«ãã¬ãã¼ãããã¦ããã¢ãã¦ã§ã¢ãå®ã¯æããããã«ã¦ã§ã¢ã ã£ãï¼ | TechCrunch Japan Dellã®PCã«ä¸å¯©ãªã«ã¼ã証ææ¸ãLenovoã®Superfishã¨åãåé¡ã - ITmedia ã¨ã³ã¿ã¼ãã©ã¤ãº
å®è£
ããã§ã¯å ·ä½çãªå®è£ ã®è§£èª¬ãè¡ãã¾ããå¦çã®æµãã¯ä»¥ä¸ã®ã¨ããã§ãã
- CONNECTã¡ã½ããã®ãªã¯ã¨ã¹ããããhttp.Hijackerã使ã£ã¦çã®TCPã³ãã¯ã·ã§ã³ãåãåºã
- ã¯ã©ã¤ã¢ã³ãã«ã¯200 okãè¿ã
- æ¥ç¶å ãã¹ãã®è¨¼ææ¸ããäºãç¨æãã¦ããroot証ææ¸ã§ãµã¤ã³ãã¦çæãã
- çæãã証ææ¸ã§ã¯ã©ã¤ã¢ã³ãã¨tlsæ¥ç¶ã確ç«ãã (root証ææ¸ãç»é²ããã¦ããªãã¨ãã©ã¦ã¶ã§è¦åãåºã)
- goroutineèµ·ããã¦ãã¯ã©ã¤ã¢ã³ãã¨ã®tlsæ¥ç¶ããhttp requestãèªã¿è¾¼ã
- åããhttp requestããã®ã¾ã¾æ¥ç¶å hostã«éä¿¡ãã
- æ¥ç¶å hostããã®http responseããã¯ã©ã¤ã¢ã³ãtlsæ¥ç¶ã«æ¸ãè¾¼ã
- EOFãæ¥ãã¾ã§ 5-7ç¹°ãè¿ã
https://github.com/yuroyoro/mitm_proxy_sample/blob/master/https.go#L57
func (proxy *MiTMProxy) mitmRequest(w http.ResponseWriter, r *http.Request) { // http.Hicjacker ãå©ç¨ãã¦ã¯ã©ã¤ã¢ã³ãã¨ã®çã®TCPã³ãã¯ã·ã§ã³ãåãåºã conn := hijackConnect(w) // ã¯ã©ã¤ã¢ã³ãã«200 OKãè¿ãã¦ãã conn.Write([]byte("HTTP/1.0 200 OK\r\n\r\n")) // 以éã®å¦çã¯goroutineä¸ã§è¡ã go proxy.transportHTTPSRequest(w, r, conn) } func (proxy *MiTMProxy) transportHTTPSRequest(w http.ResponseWriter, r *http.Request, conn net.Conn) { proxy.info("transportHTTPSRequest : %s %s", r.Method, r.URL.String()) // 対象ãã¹ãã®ãã»ã®ãµã¼ãã¼è¨¼ææ¸ãçæãã¦ç½²åãã host := r.Host tlsConfig, err := proxy.generateTLSConfig(host) if err != nil { if _, err := conn.Write([]byte("HTTP/1.0 500 Internal Server Error\r\n\r\n")); err != nil { proxy.error("Failed to write response : %v", err) } conn.Close() } // ã¯ã©ã¤ã¢ã³ãã¨ã®TCPæ¥ç¶ä¸ã§ããã»ã®ãµã¼ãã¼è¨¼ææ¸ãå©ç¨ãã¦TLSæ¥ç¶ãå¾ ã¡åãã tlsConn := tls.Server(conn, tlsConfig) if err := tlsConn.Handshake(); err != nil { proxy.error("Cannot handshake client %v %v", r.Host, err) return } defer tlsConn.Close() proxy.info("transportHTTPSRequest : established tls connection") // ãã»ã®è¨¼ææ¸ã§ç¢ºç«ããTLSæ¥ç¶ä¸ã§ã¯ã©ã¤ã¢ã³ãããã®ãªã¯ã¨ã¹ããèªã¿è¾¼ã tlsIn := bufio.NewReader(tlsConn) for !isEOF(tlsIn) { req, err := http.ReadRequest(tlsIn) // http.Requestãªãã¸ã§ã¯ãã¨ãã¦éä¿¡ãèªã¿è¾¼ã if err != nil { if err == io.EOF { proxy.error("EOF detected when read request from client: %v %v", r.Host, err) } else { proxy.error("Cannot read request from client: %v %v", r.Host, err) } return } proxy.info("transportHTTPSRequest : read request : %s %s", req.Method, req.URL.String()) // 転éç¨ã«URLããããã¼ãªã©ãè¨å® req.URL.Scheme = "https" req.URL.Host = r.Host req.RequestURI = req.URL.String() req.RemoteAddr = r.RemoteAddr dumpRequest(req) removeProxyHeaders(req) // http.RoundTripper ã§åä¿¡ãããªã¯ã¨ã¹ãã対象ãã¹ãã«è»¢éããã¬ã¹ãã³ã¹ãåãåã resp, err := proxy.transport.RoundTrip(req) if err != nil { proxy.error("error read response %v %v", r.URL.Host, err.Error()) if resp == nil { http.Error(w, err.Error(), 500) return } } proxy.info("transportHTTPSRequest : transport request: %s", resp.Status) dumpResponse(resp) // ã¬ã¹ãã³ã¹ãã¯ã©ã¤ã³ãã¸ã®TLSæ¥ç¶ã«æ¸ãè¾¼ã resp.Write(tlsConn) } proxy.info("transportHTTPSRequest : finished ") }
ãã¤ã³ãã¯ã ãªã¯ã¨ã¹ããåããã¨ãã»ã®ãµã¼ãã¼è¨¼ææ¸ããã®å ´ã§çæãã¦ããã®è¨¼ææ¸ã¨ http.Hijacker
ã§åãåºããã¯ã©ã¤ã³ãã®TCP㧠tls.Server
ãç¨ãã¦TLSæ¥ç¶ããªããã¾ããã¨ã§ã(çæãã証ææ¸ã¯ãã£ãã·ã¥ãã¾ã)ã
証ææ¸ã®çæã¯é·ããªãã®ã§ããã«ã¯è¼ãã¾ãããã ãã¡ã ãè¦ã¦ãããã°ã¨æãã¾ãã
ã¯ã©ã¤ã³ãã¨ã®TLSæ¥ç¶ãä¹ã£åãã°ããã¨ã¯ãã®æ¥ç¶ä¸ã§Httpãªã¯ã¨ã¹ããèªã¿è¾¼ã¿ã対象ãã¹ãã«è»¢éããã°OKã§ããGoã§ã¯ã http.RoundTripper
ãå©ç¨ããã° http.Request
ããã®ã¾ã¾è»¢éã§ããã®ã§ä¾¿å©ã§ãããã®éã«ããªã¯ã¨ã¹ãã»ã¬ã¹ãã³ã¹ã®å
容ãdumpãã¦ãã¾ãã
æªæãããã°ããã®æ®µéã§æ¹ç«ãå¯è½ã§ãããã
ã¾ã¨ã
以ä¸ããMan-in-The-Middle Attackãè¡ãç°¡åãªProxyã®å®è£ ã§ãããã®æ»æãæåããæ¡ä»¶ã¨ãã¦ã¯ã
- çµè·¯ä¸ã«ãã®ãããªProxyãåå¨ãã (httpséä¿¡ãport forwardããã¦ããå ´åããã)
- Proxyãç½²åã«ä½¿ãã«ã¼ã証ææ¸ãTrust Chainã«åå¨ãã
ã®2ç¹ã§ããç¹ã«2ç¹ç®ã¯TLSã®æ ¹å¹¹ããªãé¨åã§ãããããã«ã«ã¼ã証ææ¸ã®ç®¡çã¯å³æ ¼ã«è¡ãå¿ è¦ããããGoogleã¯Symantecã®è¨¼ææ¸ãç¡å¹ã«ããLenoveãDellã¯è²¬ããããã¹ããªã®ã§ããAvastãã¡ãã£ã¨ã©ããã¨æãã¾ãã
å®éã«æãåããã¦å®è£ ãã¦ã¿ãã¨ãProxyã®å®è£ ã§æ³¨æã¹ã¹ãç¹ããTLSã¨èªè¨¼å±ã®ä»çµã¿ã¨ãè²ã ã¨å¦ã³ããããããã£ãã¨ãããã¾ãã( êªâêª)
go tool traceã§goroutineã®å®è¡ç¶æ³ãå¯è¦åãã
ããã«ã¡ããããããã§ããä»æ¥ã¯goroutineã®å®è¡ç¶æ³ããããããã«å¯è¦åãããã¼ã«ã®è©±ã§ãã
goã®ãããã¡ã¤ãªã³ã°ãã¼ã«ã¨è¨ãã°ã runtime/pprof
ã net/http/pprof
ã§ãããããããã®ä½¿ãæ¹ã¯ã°ã°ãã°ããã«åºã¦ããã®ã§ããã 詳細ãªtraceãåå¾ãã¦å¯è¦åã§ãã runtime/trace
ã«ã¤ãã¦ã¯ãæ¥æ¬èªã®æ
å ±ãæ®ã©ç¡ãã®ã§æ¸ãã¦ã¿ã¾ããããã
runtime/trace
ã¯goroutineã®å®è¡ç¶æ³ãsystem callã®ã¤ãã³ããHeapãnetworkã®ç¶æ³ããããªæãã«å¯è¦åãã¦ãããã®ã§ä¾¿å©ã§ãã
ããã¯èªä½ã®ã¯ãã¼ã©ã¼ãåããã¦ããéã®traceãå¯è¦åãããã®ã§ã横軸ãã¿ã¤ã ã©ã¤ã³ã«ãªã£ã¦ãããä¸æ®µã« Heapã®ä½¿ç¨ç¶æ³ãgoroutineã¨os threadã®æ°ã, ä¸æ®µã¯networkãProccesor(GOMAXPROCSã§æå®ããgoroutineã®å®è¡ç°å¢)æ¯ã«ã©ã®ã³ã¼ããå®è¡ããã¦ããããã表示ããã¾ãã
Heapãgoroutinesæ°ã®å¢æ¸ã¨å¦çã®é¢é£ãæç³»åã§è¿½ããã®ã§ã大ã¾ããªããã«ããã¯ã®ç¹å®ã«ä¾¿å©ã§ããã¾ããågoroutineæ¯ã®éå§/çµäºã¨system callãunblockã¤ãã³ã(goroutineã®åãæ¿ã)ãç´°ãã追ããã®ã§ãgoroutineãåºãã£ã¦ããç®æã®ç¹å®ã«ãå½¹ç«ã¡ã¾ã
å³å´ã®boxã®âã¢ã¤ã³ã³ãã¯ãªãã¯ããä¸ã§ãã°ã©ãä¸ã§ãã©ãã°ããã¨zoomin/outã§ãã¾ããã¾ããView Options 㧠Flow Eventsããã§ãã¯ããã¨ç¢å°ãæç»ããã¾ã
ããã«ãå®éã«åããããµã³ãã«ãç½®ãã¦ããã¾ãã
ããã¯ã¨ããèªä½Proxyã®traceã®ä¸é¨ã§ãProc3ã§å®è¡ããã¦ããçããããªãã¿ã® net/http.(*conn).serve
ããªã¯ã¨ã¹ããåãã¦ã go æ§æã§æ°ããªgoroutineãèµ·åãã¦Proc2ã§å®è¡ãããæ§åã§ãããã®ããã«ãã©ã®ã¿ã¤ãã³ã°ã§ã©ã®goroutineãåããã®ããä¸ç®çç¶ã§ãã
ããã¯GCãå®è¡ããã¦ããæ§åã§ããã»ã¨ãã©ã®Procã§GCé¢é£ã®å¦çãåããå¾ã«ãä¸æ®µã®Heapã®allocatedãæ¸ã£ã¦ããæ§åãè¦ã¦ã¨ãã¾ãã
ã§ããã®traceã®å¯è¦åã®æ¹æ³ã§ããã æã£åãæ©ãã®ã¯ runtime/trace
ããã±ã¼ã¸ãimportãã¦ã trace.Start(w io.Writer)
㨠trace.Stop()
ãå¼ã³åºãæ¹æ³ã§ã
https://golang.org/pkg/runtime/trace/
package main import ( "log" "os" "runtime" "runtime/trace" ) func main() { f, err := os.Create("trace.out") if err != nil { log.Fatal(err) } defer f.Close() trace.Start(f) defer trace.Stop() // do something ... }
ãã®ããã«ãtraceãåå¾ãããå¦çã®åå¾ã§ trace.Start
ãå¼ã³åºãã¨ãçµæããã¡ã¤ã«ã«åºåããã¾ãã ãã®ãã¡ã¤ã«ã go tool trace
ã³ãã³ãã®å¼æ°ã«æ¸¡ãã¨ããã©ã¦ã¶ã§åå¾ããtraceãåæã§ããããã«ãªãã¾ãã
net/http/pprof
ããã±ã¼ã¸ã使ã£ã¦ããã¦ã§ãã¢ããªã±ã¼ã·ã§ã³ã§ããç°¡åã«traceãåå¾ãããã¨ãã§ãã¾ãã
pprofãlistenãã¦ãããªãã /debug/pprof/trace?seconds=5
ã«ãªã¯ã¨ã¹ããéãã¨ã5ç§éã®traceãåå¾ãã¦çµæããã¦ã³ãã¼ãã§ãã¾ããå¾ããããã¡ã¤ã«ã go tool trace
ã«æ¸¡ãã°ãåæ§ã«ãã©ã¦ã¶ä¸ã§åæã§ãã¾ãã
詳細ãªããã«ããã¯ã®åæã¯ã pprofãgo-torchã§ã®flamegraphã®åæãæåã§ããã go tool trace
ã§ã¯æç³»åã«å¯¾å¿ãã¦ã®åæãå¯è½ãªã®ã§ãããããç¶æ³ã«åããã¦ä½¿ãåããã¨è¯ãã®ã§ã¯ãªããã¨æãã¾ããããã
F.Y.I.
ãã£ã¹ã¯ä½¿ç¨éãFlameGraphã§å¯è¦åãã
ããã«ã¡ããããããã§ããä»æ¥ã¯ãã£ã¹ã¯ä½¿ç¨éãFlameGraphã«ãããã¼ã«ã®è©±ã§ãã
FlameGraphã«ã¤ãã¦ã¯ã Flame Graphs ã GolangでFlame Graphを描く | SOTA ãèªãã§ãããã®ãæã£åãæ©ãã®ã§ãããããã¯ãããã¡ã¤ã«çµæãå¯è¦åããæ¹æ³ã§ãã縦軸ãå¼ã³åºãã®é層ã«ã横軸ããµã³ãã«æ°ãå®è¡æéãªã©ã«å¯¾å¿ãã¦ãããã©ã®é¢æ°ãæ¯é çããç´æçã«è¦ããã¨ãã§ããåªããã°ã©ãã§ããã
ã§ããã®FlameGraphãå¥ã«ãããã¡ã¤ã«çµæã ãã§ã¯ãªããããªã¼æ§é ã§åãã¼ããéãæã¤å ´åã«ãææ¯ã®ç´¯ç©éãå¯è¦åããã®ã«å©ç¨ã§ãã¾ãããããã¡ã¤ã«ä»¥å¤ã«ãããªã¼æ§é ã§ãã¼ããéãæã¤ä¾ã¨ãã¦ããã£ã¬ã¯ããªé層æ¯ã®ãã£ã¹ã¯ä½¿ç¨éãèãããã¾ãã
ã¨ããããã§ãæå®ãã£ã¬ã¯ããªä»¥ä¸ã®ãã£ã¹ã¯ä½¿ç¨éãFlameGraphåãããã¼ã«ãæ¸ãã¾ããã
GitHub - yuroyoro/du-flamegraph: visualize disk usage as flamegraph
ãããªæãã®ã°ã©ããåºåããã¾ã
goã§æ¸ããã¦ããã使ãæ¹ã¯ã `go get -u yuroyoro/du-flamegraph` ã§ã¤ã³ã¹ãã¼ã«ã§ãã¾ãã
ãã®ãã¼ã«ã¯ã FlameGraphã®æç»ã« `flamegraph.pl` ã¨ããã¹ã¯ãªãããå¿
è¦ã§ããããã㯠GitHub - brendangregg/FlameGraph: Stack trace visualizer ã«ããã¾ãã
ããã git cloneãªã©ã§æå
ã«å
¥ãã¦ã $PATHã«è¿½å ãããã `--flamegraph-script` ã§ä½ç½®ãæå®ããããã¦ããã°ãFlameGraph ãsvgã¨ãã¦åºåããã¾ãã
NAME: du-flamegraph - visualize disk usage as flamegraph USAGE: du-flamegraph [global options] [FILE] VERSION: 0.0.0 GLOBAL OPTIONS: --width value, -w value width of image (default 1200) (default: 1200) --height value, -h value height of each frame (default 16) (default: 16) --flamegraph-script value path of flamegraph.pl. if not given, find the script from $PATH --out value distination path of grenerated flamegraph. default is ./du-flamegraph.svg (default: "./du-flamegraph.svg") --verbose show verbose log --version, -v print the version
FlameGraphãè²ã ã¨å¿ç¨ãããããã§ããã