[jcifs] [bug+workaround] When multiple hosts are available, only the first is retried

Michael B Allen ioplex at gmail.com
Fri May 12 19:29:38 UTC 2017

Hi Glen,

Yes, this has been on the TODO list for about 10 years which is to say
I don't know if it will be fixed. Some folks have actually been
disabling SMB1 (there was a bug in Windows no too long ago that
prompted MS to recommend disabling SMB1) so the SMB parts of JCIFS
might be obsolete at some point. Really need SMB2/3 to keep it alive
but that's about 14 plates down in the stack of stuff-to-do.


On Thu, May 4, 2017 at 3:43 AM, Glen Wallace via jCIFS
<jcifs at lists.samba.org> wrote:
> Hi
> When multiple addresses are available for a DNS name and the first one fails JCIFS intends to try the next address, but instead retries the initial failing address multiple times.
> In the case of a DFS share where the DNS name may resolve to a list of domain controllers, an outage of a single domain controller may make the DFS share unavailable to a client using JCIFS.
> Detail
> --------
> In jcifs.smb.SmbFile when there are multiple addresses available for the service, see the getAddress() implementation, the doConnect() method may be called multiple times.  It appears the intention is that the doConnect() method will get called for each available address until it either it succeeds or all addresses have been attempted. The result of getAddress() is incremented by a getNextAddress() call.
> What currently happens (in the 1.3.18 codebase) is when the first address fails the doConnect() method will be called multiple times (equal to the number of available addresses), but the first address will be used on every attempt. This is because the address is only set on transport creation, but if a tree already exists it will be reused rather than a new transport created using the next address.
> Reproducing the Issue
> ----------------------------
> The easiest way to reproduce this issue (short of running a local DNS service with a specifically crafted entry) is to
> a)  temporarily patch the RESOLVER_DNS switch case in jcifs.UniAddress#getAllByName and have it insert a non-existent IP as the first item
> b)  set the system property -Djcifs.resolveOrder=DNS to ensure the above patched code is used
> Something like:
>     if( isAllDigits( hostname )) {
>         throw new UnknownHostException( hostname );
>     }
>     InetAddress[] iaddrs = InetAddress.getAllByName( hostname )
>     UniAddress[] addrs = new UniAddress[iaddrs.length + 1];
>     addrs[0] = new UniAddress(InetAddress.getByName(""));  // bad first address
>     for (int ii = 0; ii < iaddrs.length; ii++) {
>         addrs[ii + 1] = new UniAddress(iaddrs[ii]);
>     }
>     return addrs; // Success
> Workaround
> ------------
> I have implemented a workaround that seems to address the immediate issue we were seeing, however I am not convinced it is correct in all cases.
> A patch is attached or see the following commit:
>     https://github.com/wallaceg-tp/samba-jcifs/commit/386763ec5e9960d508c1dbcddcc7218e86fe949d
> Regards
> Glen
> ---
> www.transpower.co.nz

Michael B Allen
Java Active Directory Integration

More information about the jCIFS mailing list