Skip to content
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

Information question about method SmbTreeConnection.send0() #351

Open
l-k-test opened this issue Oct 25, 2023 · 2 comments
Open

Information question about method SmbTreeConnection.send0() #351

l-k-test opened this issue Oct 25, 2023 · 2 comments

Comments

@l-k-test
Copy link

In my tests I see 10 attempts fail (Create request fails with STATUS_PATH_NOT_COVERED).

After that I see a slightly different Ioctl Request FSCTL_DFS_GET_REFERRALS + Tree Connect \APPSDATA$, and then Create request succeeds.

Why the method loops 10 times?

@mbechler
Copy link
Contributor

The loop is meant to handle the STATUS_PATH_NOT_COVERED error by requesting the DFS referral and update the path accordingly. If that fails and the same path is requested over and over, you have hit a bug.

@l-k-test
Copy link
Author

l-k-test commented Oct 27, 2023

Thanks for the answer.

Yes, it fails 10 times with STATUS_PATH_NOT_COVERED for exactly the same path before trying a different path, with success.

Then it fails again 10 times with STATUS_PATH_NOT_COVERED for a path that is different from the previous 10 attempts. And again, the path stays the same for all 10 attempts.

So OK, it is a bug.
It is not a showstopper in my case. I had to increase value of jcifs.smb.client.maxRequestRetries , otherwise it failed with "Loop in DFS referrals" after the second series of 10 attempts.

The thing is: in my tests I have hit quite a number of problems which are showstoppers for me.
I did not report them yet here because, honestly, at the moment they would look like this (for this specific case):

            SmbTreeConnection.send0() tries the same path 10 times in the row and fails.

It is not very useful I think.

I have a better idea. Maybe you find it useful as well.

First, some context: our software uses commons-vfs2 with org.codelib:jcifs dependency.
The tests with windows professional and with some basic samba servers went OK.
The test at a client side, with a real DFS, did not work: authentication failed.

Before I continue, I have a question: what is the real difference between org.codelib:jcifs and jcifs-ng? What I can see here https://github.com/codelibs/jcifs/#this-jcifs-or-jcifs-ng is not really an answer to this question. I mean looking at it I would not be able to decide which of the two are better for my project.

Back to the context: our software did not work. It failed with authentication problems. smbclient worked with the same credentials.

This was a starting point for me: I was asked to look at it. Fortunately I was also given permission to run tcpdump at the client side.

To simplify the investigation I have written a very small test program that connects to a specified url (directory) and lists its contents.

First it started with commons-vfs2, but then I changed it to use jcifs directly.
At some point in time I had even added smbj-based variant in an attempt to find at least something java-based that would work.

Analyzing the first 10 or so tcpdumps of smbclient resulted in questions #350
These tcpdumps helped: after specifying the truncated user name in the credentials I managed to make my test application work with org.codelib:jcifs and with jcifs-ng.

Just for info: smbj based variant still did not work. Authentication was successful then, but it failed on Tree Connect Request after that.

Both jcifs variants worked with the URL of the share, but not for sibdirectories of the share.
The client provided us with url with 5 directories under the share. I was too optimistic and specified this url. My test application hung. In fact it was an endless loop.

I had to start small, directory by directory. It did not work, I looked at debug output and tcpdumps, trying to figure out what was wrong. I patched org.codelib:jcifs according to my understanding of the problem. It was actually very bad. It took a day to get it working for the first subdirectory. It took another day for the next subdirectory. I am not exaggerating.

After that I hit "Loop in DFS referrals" , and after increasing jcifs.smb.client.maxRequestRetries I finally managed to list the contents of the directory the client specified.

So back to my idea:

I had to made quite a number of patches. The problems I "fixed" include:

  • StringIndexOutOfBoundsException in DfsImpl.resolveIntermediates due to incorrect (?) iteration over DfsReferralDataInternal dr parameter
  • Endless loop in this method due to wrong (?) iteration over DfsReferralDataInternal dr parameter
  • DfsImpl.getLinkReferral was invoking stripPathConsumed() only on the first DfsReferralDataInternal. This was also one of the reasons for StringIndexOutOfBoundsException in DfsImpl.resolveIntermediates
  • Another incorrect (?) iteration in DfsImpl.resolveIntermediates, this time over DfsReferralData nextstart = resolve(tf, r.getServer(), r.getShare(), nextPath, depthLimit - 1);
    There is a do/while loop but it always performed just one iteration, never invoked next() method
  • SmbTreeConnection.resolveDfs0() is invoking SmbResourceLocatorImpl.handleDFSReferral() in several places but is still using rfullpath based on the state of SmbResourceLocatorImpl before handleDFSReferral()

I use "fixed" in quotes because I do not know for sure if my fixes are correct. I was just trying to make my test program work.

For the changes I made I can create individual pull requests for jcifs-ng. The changes include also some comments where I explain why I did it or wondered about a particular piece of code. You can then review my changes, maybe accept some of them or just make the fixes yourself. Or maybe you will have some comments about particular changes...

I also hit several problems that did not make my test program fail, but which are in my view signs of bugs:

  • My original question for this issue: 10 attempts failing with STATUS_PATH_NOT_COVERED for the same path.
  • "Path consumed out of range " warnings in SmbResourceLocatorImpl.handleDFSReferral. I am pretty sure I have seen them as well in test runs that were hung.
  • Warnings like "jcifs.smb.SmbTransportImpl - Disconnecting transport while still in use", "jcifs.smb.SmbSessionImpl - Logging off session while still in use" and "jcifs.smb.SmbTreeImpl - Disconnected tree while still in use". How many of them appear depends really on the url. They do not appear for urls that include only the share of first 2 subdirectories. The longer the path after that the more warnings I get.
    I have actually found this one. It is in SmbTreeConnection.disconnect(): the tree is disconnected but not released.

I would like to see them fixed as well. The last one seems very dangerous to me. it smells like resource leak, which is a big problem for a long running program. This is what I will try to investigate next.

If you have any suggestions what to look for to resolve these 3 problems I would like to hear them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants