Bug #16413
Updated by koshigoe (Masataka SUZUKI) almost 5 years ago
### 疑問 `Net::FTP#storbinary` などをみると、 `conn.write` で例外が発生した際に `conn.close` を呼ばない実装だと思います。 https://github.com/ruby/ruby/blob/7be550d046c726c2a3aa625ceb260d9b2268fb5a/lib/net/ftp.rb#L683-L707 一方で `Net::FTP#retrbinary` では `conn.shutdown` や `conn.close` (`ensure`) をしています。 https://github.com/ruby/ruby/blob/7be550d046c726c2a3aa625ceb260d9b2268fb5a/lib/net/ftp.rb#L629-L648 素人的な質問で恐縮ですが、これは意図的な実装でしょうか? ### 確認内容 適当な FTP サーバを起動。 ``` $ docker run --rm \ -p 20-21:20-21 \ -p 21100-21110:21100-21110 \ -e FTP_USER=user \ -e FTP_PASS=pass \ -e PASV_ADDRESS=localhost \ -e PASV_MIN_PORT=21100 \ -e PASV_MAX_PORT=21110 \ fauria/vsftpd ``` irb で `Net::FTP#put` のエラーを繰り返し発生させる。 ``` require 'net/ftp' def upload $ ruby -v ruby 2.6.4p104 (2019-08-28 revision 67798) [x86_64-darwin18] $ irb -rnet/ftp > ftp = Net::FTP.new > ftp.passive = true > ftp.connect('localhost') > ftp.login('user', 'pass') i = 0 ftp.put(__FILE__, '/uploaded', 1) do |data| i += 1 raise 'Bomb' if i > 3 end ftp.put('/dev/null', '/null') # 正常 rescue => e puts e.message > ftp.put('/dev/null', '/nil/null') # エラー ensure unless ftp.closed? ftp.close puts 'closed.' end ... エラーを繰り返してみる ... end 11.times { upload } puts 'wait' loop {} __END__ Bomb closed. Net::ReadTimeout with #<Socket:fd 11> closed. Net::ReadTimeout with #<Socket:fd 11> closed. Net::ReadTimeout with #<Socket:fd 11> closed. Net::ReadTimeout with #<Socket:fd 11> closed. Net::ReadTimeout with #<Socket:fd 11> closed. Net::ReadTimeout with #<Socket:fd 11> closed. Net::ReadTimeout with #<Socket:fd 11> closed. Net::ReadTimeout with #<Socket:fd 11> closed. Net::ReadTimeout with #<Socket:fd 11> closed. Net::ReadTimeout with #<Socket:fd 11> closed. wait ``` コネクションがたくさん作られる。 エラー時は `CLOSE_WAIT`, `FIN_WAIT2` が増えていく。 ``` $ lsof -i:21100-21110 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME com.docke 1354 koshigoe 17u IPv6 0x370c967258b56c15 0x370c967241f8be15 0t0 TCP *:21110 (LISTEN) com.docke 1354 koshigoe 19u IPv6 0x370c967258b543d5 0x370c967241f8dad5 0t0 TCP *:21109 (LISTEN) com.docke 1354 koshigoe 21u IPv6 0x370c967258b56095 0x370c967241f8f1d5 0t0 TCP *:21108 (LISTEN) com.docke 1354 koshigoe 23u IPv6 0x370c967258b55515 0x370c967241f8cf55 0t0 TCP *:21107 (LISTEN) com.docke 1354 koshigoe 25u IPv6 0x370c967258b53e15 0x370c967241f8e095 0t0 TCP *:21106 (LISTEN) com.docke 1354 koshigoe 29u IPv6 0x370c967258b571d5 0x370c967241f8c3d5 0t0 TCP *:21105 (LISTEN) com.docke 1354 koshigoe 31u IPv6 0x370c967256ed8e15 0x370c967241f8c995 0t0 TCP *:21104 (LISTEN) com.docke 1354 koshigoe 33u IPv6 0x370c967256edb095 0x370c967241f8d515 0t0 TCP *:21103 (LISTEN) com.docke 1354 koshigoe 35u IPv6 0x370c967256edaad5 0x370c967241a28e15 0t0 TCP *:21102 (LISTEN) com.docke 1354 koshigoe 37u IPv6 0x370c967256ed93d5 0x370c967241a28855 0t0 TCP *:21101 (LISTEN) com.docke 1354 koshigoe 39u IPv6 0x370c967256ed9f55 0x370c967241a2a515 0t0 TCP *:21100 (LISTEN) com.docke 1354 koshigoe 45u 44u IPv6 0x370c967256eda515 0x370c9672385ae1d5 0t0 TCP localhost:21105->localhost:61667 (ESTABLISHED) localhost:21110->localhost:53362 (FIN_WAIT_2) com.docke 1354 koshigoe 47u 45u IPv6 0x370c967257775655 0x370c9672385ad655 0t0 TCP localhost:21109->localhost:61669 (ESTABLISHED) localhost:21107->localhost:53363 (FIN_WAIT_2) com.docke 1354 koshigoe 49u 46u IPv6 0x370c967257772855 0x370c9672434e7855 0t0 TCP localhost:21107->localhost:61671 (ESTABLISHED) localhost:21102->localhost:53378 (FIN_WAIT_2) com.docke 1354 koshigoe 51u 48u IPv6 0x370c9672434ea655 0x370c9672434e83d5 0t0 TCP localhost:21104->localhost:61673 (ESTABLISHED) localhost:21100->localhost:53379 (FIN_WAIT_2) com.docke 1354 koshigoe 53u 49u IPv6 0x370c9672434e9515 0x370c9672434eac15 0t0 TCP localhost:21106->localhost:61675 (ESTABLISHED) localhost:21105->localhost:53380 (FIN_WAIT_2) com.docke 1354 koshigoe 55u 50u IPv6 0x370c967241a2b095 0x370c967241f8ec15 0t0 TCP localhost:21110->localhost:61677 (ESTABLISHED) localhost:21108->localhost:53381 (FIN_WAIT_2) com.docke 1354 koshigoe 57u 51u IPv6 0x370c967241a2b655 0x370c967241a29f55 0t0 TCP localhost:21102->localhost:61679 (ESTABLISHED) localhost:21107->localhost:53382 (FIN_WAIT_2) com.docke 1354 koshigoe 59u 52u IPv6 0x370c967241a2c1d5 0x370c9672385aa855 0t0 TCP localhost:21100->localhost:61681 (ESTABLISHED) localhost:21109->localhost:53383 (FIN_WAIT_2) com.docke 1354 koshigoe 61u 53u IPv6 0x370c96725927f995 0x370c967255892f55 0t0 TCP localhost:21101->localhost:61683 (ESTABLISHED) localhost:21109->localhost:53384 (FIN_WAIT_2) com.docke 1354 koshigoe 63u IPv6 0x370c967259281095 0t0 TCP localhost:21103->localhost:61689 (ESTABLISHED) com.docke 1354 koshigoe 65u IPv6 0x370c967258b55ad5 0t0 TCP localhost:21108->localhost:61693 (ESTABLISHED) ruby 75273 66185 koshigoe 13u IPv6 0x370c9672385ae1d5 0t0 TCP localhost:61667->localhost:21105 (ESTABLISHED) ruby 75273 koshigoe 14u IPv6 0x370c967256ed8855 0t0 TCP localhost:61669->localhost:21109 (ESTABLISHED) ruby 75273 koshigoe 15u IPv6 0x370c967257773f55 0x370c9672385adc15 0t0 TCP localhost:61671->localhost:21107 (ESTABLISHED) localhost:53362->localhost:21110 (CLOSE_WAIT) ruby 75273 66185 koshigoe 16u IPv6 0x370c9672434eac15 0x370c9672385ab995 0t0 TCP localhost:61673->localhost:21104 (ESTABLISHED) localhost:53363->localhost:21107 (CLOSE_WAIT) ruby 75273 66185 koshigoe 17u IPv6 0x370c9672434e8f55 0x370c9672434eb1d5 0t0 TCP localhost:61675->localhost:21106 (ESTABLISHED) localhost:53378->localhost:21102 (CLOSE_WAIT) ruby 75273 66185 koshigoe 18u IPv6 0x370c9672434e7855 0x370c9672434ea095 0t0 TCP localhost:61677->localhost:21110 (ESTABLISHED) localhost:53379->localhost:21100 (CLOSE_WAIT) ruby 75273 66185 koshigoe 19u IPv6 0x370c967241a2aad5 0x370c9672434e9515 0t0 TCP localhost:61679->localhost:21102 (ESTABLISHED) localhost:53380->localhost:21105 (CLOSE_WAIT) ruby 75273 66185 koshigoe 20u IPv6 0x370c967241a29995 0x370c967241f8e655 0t0 TCP localhost:61681->localhost:21100 (ESTABLISHED) localhost:53381->localhost:21108 (CLOSE_WAIT) ruby 75273 66185 koshigoe 21u IPv6 0x370c96725927ee15 0x370c967241a2b655 0t0 TCP localhost:61683->localhost:21101 (ESTABLISHED) localhost:53382->localhost:21107 (CLOSE_WAIT) ruby 75273 66185 koshigoe 22u IPv6 0x370c967259281c15 0x370c967241a2c1d5 0t0 TCP localhost:61689->localhost:21103 (ESTABLISHED) localhost:53383->localhost:21109 (CLOSE_WAIT) ruby 75273 66185 koshigoe 23u IPv6 0x370c967258b56655 0x370c9672385abf55 0t0 TCP localhost:61693->localhost:21108 (ESTABLISHED) localhost:53384->localhost:21109 (CLOSE_WAIT) ``` FTP サーバ(vsftpd)のプロセスがたくさん作られる。 ``` sh-4.1# ps aux | grep '[v]sftpd' root 1 0.0 0.0 11368 2440 ? Ss 09:01 0:00 /bin/bash -ex /usr/sbin/run-vsftpd.sh root 13 0.0 0.1 52184 3864 ? S 09:01 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf nobody 3158 0.0 0.1 56584 3564 ? Ss 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf ftp 3160 0.0 0.0 56684 2432 ? S 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf nobody 3161 0.0 0.1 56584 3564 ? Ss 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf ftp 3163 0.0 0.0 56608 2432 ? S 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf nobody 3164 0.0 0.1 56584 3564 ? Ss 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf ftp 3166 0.0 0.0 56608 2432 ? S 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf nobody 3167 0.0 0.1 56584 3564 ? Ss 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf ftp 3169 0.0 0.0 56608 2432 ? S 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf nobody 3170 0.0 0.1 56584 3564 ? Ss 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf ftp 3172 0.0 0.0 56608 2432 ? S 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf nobody 3173 0.0 0.1 56584 3564 ? Ss 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf ftp 3175 0.0 0.0 56608 2432 ? S 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf nobody 3176 0.0 0.1 56584 3564 ? Ss 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf ftp 3178 0.0 0.0 56608 2432 ? S 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf nobody 3179 0.0 0.1 56584 3564 ? Ss 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf ftp 3181 0.0 0.0 56608 2432 ? S 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf nobody 3182 0.0 0.1 56584 3564 ? Ss 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf ftp 3184 0.0 0.0 56608 2432 ? S 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf nobody 3185 0.0 0.1 56584 3564 ? Ss 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf ftp 3187 0.0 0.0 56608 2432 ? S 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf nobody 3188 0.0 0.1 56584 3564 ? Ss 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf ftp 3190 0.0 0.0 56608 2432 ? S 09:30 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf ```