[jcifs] Invalid share causes all free connections consumption

Gergan Dimitrov gergan.dimitrov at gmail.com
Wed Mar 2 08:23:39 MST 2011


Hi Michael,

I tested again, and I agree the SmbTransport is reused and no other sockets
are created. The problem seem to be rather with the SmbSession.

The logoff() call I meant is in the SmbSession.send() method, line 268
(version 1.3.15). It is called just in the case when the share name is
incorrect. So, when you do treeConnect(), on line 162 a call is made to
session.send(). Then there is a call to the SmbSession.sessionSetup method.
In this method, line 385, we send some request, which purpose is not very
clear to me. So the first time, we go through those calls, and since the
share name is wrong, we go here (the SmbSession.send()) :

 try {
                transport.send( request, response );
            } catch (SmbException se) {
                if (request instanceof SmbComTreeConnectAndX) {
                    logoff(true);
                }
                request.digest = null;
                throw se;
            }


We go here in the catch, and logoff is called. As a result, the flag
sessionSetup is set to false in the logoff method. On the next time, the
whole cycle repeats, and the check in  the SmbSession.sessionSetup() for the
flag sessionSetup fails and the whole session setup is done again.

So I rarther think this continous session setup for the wrong share causes
the free connections error message, because it is caught just in this
method.

I also attach a very simple testing program - you have one thread, that
connects to a share on a cycle of 1 second and just calls the exists()
method. You can start also a second thread in parallel, which is for the
same credentials, but for correct host. Actually, I managed to get the error
with only a Single, wrongly configured thread. To run the application, just
provide the correct host and user/pass and share name settings in the main
method.

So please, take a look at this issue and please give advise - will it be
correct to logoff the whole session in case of wrong share name?

Regards,
Gergan.



2011/2/25 Michael B Allen <ioplex at gmail.com>

> On Wed, Feb 23, 2011 at 10:10 AM, Gergan Dimitrov
> <gergan.dimitrov at gmail.com> wrote:
> > Hi Michael,
> >
> > unfortunately, I do have other listeners working correctly which connect
> to
> > the same host, with same credentials, but to correctly defined shares. In
> > this case, I have the problem described above - on each retry of the
> wrongly
> > configured one, I get one more connection to the server.
> >
> > I did further investigation and I think I found the problem, but I am not
> > sure.
> >
> > The main issue seems to be in the SmbTree.treeConnect method. We have
> > correct host, and correct user/password. This line succeeds:
> >
> > session.transport.connect();
> >
> > At this point, we have a socket open to the remote host.
>
> Hi Gergan,
>
> If you have other resources open with that transport, the same
> transport will be reused and therefore additional sockets should NOT
> be created. If they are, that is a bug which should be investigated
> and fixed.
>
> Note that the code is organized so that:
>
>  SmbFiles share SmbTrees with the same share name
>  SmbTrees share SmbSessions with the same credentials
>  SmbSessions share SmbTransports with the same network address
>
> > We construct then
> > the request and response and call the session.send( request, response );
> But
> > since the share name is wrong, this fails. As a result, the
> connectionState
> > is never changed to 2 (so, it is considered not connected), and the
> variable
> > 'tid' is not initialized. If we see what happens in the send() call, the
> > transport.send( request, response ); throws exception and we go in the
> catch
> > and call logoff(true).
>
> There is no logoff() call in treeConnect. When the exception is
> caught, it calls treeDisconnect and sets connectionState back to 0. At
> least this is what is supposed to happen.
>
> > Then we go to the the treeDisconnect, the isError is
> > true. But in the treeDisconnect(), we have
> > if (connectionState != 2) // not-connected
> >             return;
> >
> > But here the connectionState is not 2, and we actually do not send a
> > disconnection message to the server.
>
> That is correct. The tree connect never succeeded and therefore no
> disconnect message should be sent.
>
> In CIFS, to get a connection to a file (or share) you must first do a
> "tree connect" which first requires a "session setup" which first
> requires a regular socket. Each socket can have multiple sessions and
> each session can have multiple trees and each tree can have multiple
> files.
>
> > Besides, the isError is also true and
> > tid is 0, and thus none of the conditions to call the disconnect is met.
> > This Tree is practically never disconnected, because since other
> listeners
> > sharing the same SmbTransport still work, we cannot get read timeout
> > exception and the SmbTransport is never removed. This means the SmbTree
> is
> > always reused, and always does the frist connect and opens new sockets,
> that
> > are never closed.
>
> Once the SmbTree object is created, it will remain associated with the
> SmbSession and reused. But when you do a treeConnect and it fails, the
> state should be reset back to 0. Because the existing socket is used,
> there should be no new sockets created and because the connectionState
> should always be reset back to 0 on failure, trying to call
> treeConnect again should go through submitting the
> SmbComTreeConnectAndX message again. At least this is what is supposed
> to happen.
>
> >
> > So Michael, please tell me
> > 1) can you verify this is really the problem. I am still not sure if the
> > upper explains why those connections seem never to close, while there are
> > other running connections to the server.
>
> No. But if you are actually finding that new sockets are being created
> when treeConnect is called on an existing transport that already has
> an open socket, that is an error that should be fixed. But you will
> need to provide evidence that there are multiple sockets being created
> in this scenario.
>
> Create a minimalistic test program that opens a file on a good share
> and then have it try to open a file on a non-existant share 10 times
> (with try / catch inside the loop of course). Then post the code and a
> backtrace to show that multiple threads blocked trying to create
> sockets or whatever it is that is being created that you think JCIFS
> should not be creating.
>
> > 2) what can be the possible solution here. I am not familiar with the
> > purpose of this  SmbComTreeConnectAndX and why it has to be called before
> we
> > set the state to connected? Also, why not try to disconnect if isError is
> > true on this request? What could be the impact if those checks are
> removed
> > from the disconnect method?
>
> I think I answered this above.
>
> Mike
>
> --
> Michael B Allen
> Java Active Directory Integration
> http://www.ioplex.com/
>
>
>
> > 2011/2/23 Mohan Radhakrishnan <mohanr at fss.co.in>
> >>
> >> Hi,
> >>
> >>     Does it mean that we should not use SmbSession.logon even using the
> >> latest JCIFS JAR ?
> >>
> >>
> >> Thanks,
> >> Mohan
> >>
> >> -----Original Message-----
> >> From: jcifs-bounces at lists.samba.org [mailto:
> jcifs-bounces at lists.samba.org]
> >> On Behalf Of Michael B Allen
> >> Sent: Wednesday, February 23, 2011 2:35 AM
> >> To: Gergan Dimitrov
> >> Cc: jcifs at lists.samba.org; s.sourkov at bg.seeburger.com
> >> Subject: Re: [jcifs] Invalid share causes all free connections
> consumption
> >>
> >> Hi Gergan,
> >>
> >> The SmbSession.logon method is flawed and should no longer be used.
> >> Just do something like (new SmbFile(smb://1.2.3.4/IPC$")).exists().
> >>
> >> But if nothing is listening on the other end it will take a while for
> >> the socket to timeout. Lowering the jcifs.smb.client.soTimeout might
> >> help with this but you cannot completely eliminate these waiting
> >> threads. It just takes time for the OS to report the SYN packet has
> >> failed.
> >>
> >> Just add logic to slow down the frequency of your attempts. And you
> >> should only use one thread per server. So have one thread try and if
> >> it times out, wait 30 seconds before trying again. If it fails again,
> >> wait 60 seconds, 120, 240 etc to some maximum like 10 minutes. I think
> >> a SYN packet failure takes at most about 90 seconds to timeout so as
> >> long as you wait more than that you should not have a net surplus of
> >> transport threads waiting.
> >>
> >> Mike
> >>
> >> On Mon, Feb 21, 2011 at 11:08 AM, Gergan Dimitrov
> >> <gergan.dimitrov at gmail.com> wrote:
> >> > Hi All,
> >> >
> >> > I have an windows share listener, which listens for new files on
> Windows
> >> > share on 1 second interval. I first try to connect to the server with
> >> > SmbSession.logon method and then call the SmbFile.exists() method for
> >> > the
> >> > directory to listen, both with same user credentials. But if the share
> >> > name
> >> > is invalid, after a short period I get run out of free connections to
> >> > the
> >> > server. Since the server ip and credentials are correct, the logon
> >> > method
> >> > succeeds. Then the exists() method throws exception. It seems that on
> >> > each
> >> > next logon, more connections are created, while the old are not
> closed.
> >> > Of
> >> > course, I could not use the logon method each time, but even if I call
> >> > it
> >> > from other application for the same credentials, I get the same
> result.
> >> > If I
> >> > skip the logon part, the problem does not appear, but as I said - it
> >> > could
> >> > be called from other application. Please, tell if you have any idea
> why
> >> > the
> >> > wrong share causes such behaviour.
> >> >
> >> > The problem can be very easily simulated, but if you need any stack
> >> > traces
> >> > or thread dumps, please say so. You can see the growing number of IPC$
> >> > connections from the  computer management/ system tools/ shared
> >> > folders/shares tool in Windows. I must add some things:
> >> >
> >> > 1) When the logon succeeds, the SmbTransport created for it is for
> port
> >> > 0,
> >> > while the SmbFile is for port 445, and so at leas two connections are
> >> > firstly created. Port was not provided for the logon method, or the
> smb
> >> > file
> >> > creation. I tried also with setting port 445 for the logon, but the
> >> > result
> >> > was the same
> >> > 2) I could not see more than two SmbTransport objects in the
> CONNECTIONS
> >> > collection.
> >> > 3) when the connection from the SmbFile is successful, but the share
> >> > cannot
> >> > be found, the flag treeConnected on the SmbTree objects remains to
> >> > false.
> >> >
> >> > Thank you in advance,
> >> > Gergan.
> >> >
> >>
> >>
> >>
> >> --
> >> Michael B Allen
> >> Java Active Directory Integration
> >> http://www.ioplex.com/
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.samba.org/pipermail/jcifs/attachments/20110302/2ecbf073/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: WrongShareTest.java
Type: application/octet-stream
Size: 2239 bytes
Desc: not available
URL: <http://lists.samba.org/pipermail/jcifs/attachments/20110302/2ecbf073/attachment-0001.obj>


More information about the jCIFS mailing list