Project

General

Profile

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 
 ```

Back