New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sf::Ftp::getDirectoryListing() stuck if there are no files/directories #1025

Closed
StDH opened this Issue Dec 27, 2015 · 5 comments

Comments

Projects
None yet
4 participants
@StDH

StDH commented Dec 27, 2015

I did some testing and when i added file/directory it worked immediately.

Client: SFML 2.3.2
Server: FileZilla FTP Server (latest)

Permissions were given all and it was hosted on localhost

@eXpl0it3r

This comment has been minimized.

Show comment
Hide comment
@eXpl0it3r

eXpl0it3r Dec 27, 2015

Member

You should provide a problem description. What does "stuck" mean exactly? When does it happen? etc.

You might also want to take a look at the contribution guidelines in the future.

Member

eXpl0it3r commented Dec 27, 2015

You should provide a problem description. What does "stuck" mean exactly? When does it happen? etc.

You might also want to take a look at the contribution guidelines in the future.

@StDH

This comment has been minimized.

Show comment
Hide comment
@StDH

StDH Dec 27, 2015

This is my first time, and i was expecting someone complaining about my "problem description" /^^\

So then,
Imagine ideal state of the connection and ftp (no problems)

util::log(util::INFO, "Requesting list... ");
sf::Ftp::ListingResponse list_status = m_ftp.getDirectoryListing();

getDirectoryListing() gets stuck once there are no files/directories to list from the server, server showed success of sending NLST to the client but client was literally stuck on that function, just as when you are waiting for the socket to complete operation.

example:
(000002)27.12.2015 23:57:16 - user(127.0.0.1)> NLST
(000002)27.12.2015 23:57:16 - user (127.0.0.1)> 150 Opening data channel for directory listing of "/"
(000002)27.12.2015 23:57:16 - user (127.0.0.1)> 226 Successfully transferred "/"

and then the client is stuck on getDirectoryListing(); , looks like waiting for some operation to complete

StDH commented Dec 27, 2015

This is my first time, and i was expecting someone complaining about my "problem description" /^^\

So then,
Imagine ideal state of the connection and ftp (no problems)

util::log(util::INFO, "Requesting list... ");
sf::Ftp::ListingResponse list_status = m_ftp.getDirectoryListing();

getDirectoryListing() gets stuck once there are no files/directories to list from the server, server showed success of sending NLST to the client but client was literally stuck on that function, just as when you are waiting for the socket to complete operation.

example:
(000002)27.12.2015 23:57:16 - user(127.0.0.1)> NLST
(000002)27.12.2015 23:57:16 - user (127.0.0.1)> 150 Opening data channel for directory listing of "/"
(000002)27.12.2015 23:57:16 - user (127.0.0.1)> 226 Successfully transferred "/"

and then the client is stuck on getDirectoryListing(); , looks like waiting for some operation to complete

@jcowgill

This comment has been minimized.

Show comment
Hide comment
@jcowgill

jcowgill Dec 28, 2015

Contributor

I can reproduce this if I add an call to sleep(1) above this line in Ftp.cpp.

The client hangs here:

(gdb) bt
#0  0x00007ffff6e645cd in __libc_recv (fd=3, buf=buf@entry=0x7fffffffd560, n=n@entry=1024, flags=flags@entry=16384)
    at ../sysdeps/unix/sysv/linux/x86_64/recv.c:29
#1  0x00007ffff7bd47d0 in recv (__flags=16384, __n=1024, __buf=0x7fffffffd560, __fd=<optimized out>)
    at /usr/include/x86_64-linux-gnu/bits/socket2.h:44
#2  sf::TcpSocket::receive (this=this@entry=0x7fffffffdd48, data=data@entry=0x7fffffffd560, size=size@entry=1024, received=@0x7fffffffd0d8: 0)
    at /home/james/deb-pkg/libsfml/libsfml/src/SFML/Network/TcpSocket.cpp:278
#3  0x00007ffff7bc98d9 in sf::Ftp::getResponse (this=this@entry=0x7fffffffdd40) at /home/james/deb-pkg/libsfml/libsfml/src/SFML/Network/Ftp.cpp:400
#4  0x00007ffff7bcdbc6 in sf::Ftp::getDirectoryListing (this=0x7fffffffdd40, directory=...)
    at /home/james/deb-pkg/libsfml/libsfml/src/SFML/Network/Ftp.cpp:224
#5  0x0000000000401646 in main () at ftptest.cpp:43

I think this is because in a FTP directory listing, two responses are used to mark the start (150) and end (266) of the directory listing. getResponse is called twice (once through sendCommand) to receive both of these responses, but if both are already in the socket's receive buffer during the first call, the first getResponse will consume both and then the second call will hang with nothing to receive.

Testcase: https://gist.github.com/jcowgill/f33b4b839b57b5e14bf0

Contributor

jcowgill commented Dec 28, 2015

I can reproduce this if I add an call to sleep(1) above this line in Ftp.cpp.

The client hangs here:

(gdb) bt
#0  0x00007ffff6e645cd in __libc_recv (fd=3, buf=buf@entry=0x7fffffffd560, n=n@entry=1024, flags=flags@entry=16384)
    at ../sysdeps/unix/sysv/linux/x86_64/recv.c:29
#1  0x00007ffff7bd47d0 in recv (__flags=16384, __n=1024, __buf=0x7fffffffd560, __fd=<optimized out>)
    at /usr/include/x86_64-linux-gnu/bits/socket2.h:44
#2  sf::TcpSocket::receive (this=this@entry=0x7fffffffdd48, data=data@entry=0x7fffffffd560, size=size@entry=1024, received=@0x7fffffffd0d8: 0)
    at /home/james/deb-pkg/libsfml/libsfml/src/SFML/Network/TcpSocket.cpp:278
#3  0x00007ffff7bc98d9 in sf::Ftp::getResponse (this=this@entry=0x7fffffffdd40) at /home/james/deb-pkg/libsfml/libsfml/src/SFML/Network/Ftp.cpp:400
#4  0x00007ffff7bcdbc6 in sf::Ftp::getDirectoryListing (this=0x7fffffffdd40, directory=...)
    at /home/james/deb-pkg/libsfml/libsfml/src/SFML/Network/Ftp.cpp:224
#5  0x0000000000401646 in main () at ftptest.cpp:43

I think this is because in a FTP directory listing, two responses are used to mark the start (150) and end (266) of the directory listing. getResponse is called twice (once through sendCommand) to receive both of these responses, but if both are already in the socket's receive buffer during the first call, the first getResponse will consume both and then the second call will hang with nothing to receive.

Testcase: https://gist.github.com/jcowgill/f33b4b839b57b5e14bf0

@binary1248 binary1248 added s:accepted and removed s:undecided labels May 8, 2016

@binary1248 binary1248 self-assigned this May 8, 2016

binary1248 added a commit that referenced this issue May 8, 2016

Fixed FTP directory listing blocking forever if both expected respons…
…es are read from the command socket in a single call. (#1025)
@binary1248

This comment has been minimized.

Show comment
Hide comment
@binary1248

binary1248 May 8, 2016

Member

Should be fixed in #1025.

@StDH, @jcowgill care to test?

Member

binary1248 commented May 8, 2016

Should be fixed in #1025.

@StDH, @jcowgill care to test?

@eXpl0it3r eXpl0it3r added this to the 2.4 milestone May 10, 2016

@StDH

This comment has been minimized.

Show comment
Hide comment
@StDH

StDH May 18, 2016

@binary1248 no problem, maybe today or tomorrow for sure

StDH commented May 18, 2016

@binary1248 no problem, maybe today or tomorrow for sure

eXpl0it3r added a commit that referenced this issue Jun 4, 2016

Fixed FTP directory listing blocking forever if both expected respons…
…es are read from the command socket in a single call. (#1025)

iamPHEN added a commit to Bablawn3d5/SFML that referenced this issue Mar 11, 2017

Fixed FTP directory listing blocking forever if both expected respons…
…es are read from the command socket in a single call. (SFML#1025)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment