Skip to content

Commit

Permalink
Fix NetBIOS lookup when multiple addresses are returned (#258)
Browse files Browse the repository at this point in the history
Also adds a bunch of new resolver diagnostics, some refactoring.
  • Loading branch information
mbechler committed Dec 20, 2020
1 parent b95e1e6 commit c27b8f5
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 16 deletions.
5 changes: 4 additions & 1 deletion src/main/java/jcifs/netbios/NameQueryResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
package jcifs.netbios;


import java.util.Arrays;

import jcifs.Configuration;


Expand Down Expand Up @@ -70,6 +72,7 @@ int readRDataWireFormat ( byte[] src, int srcIndex ) {

@Override
public String toString () {
return new String("NameQueryResponse[" + super.toString() + ",addrEntry=" + this.addrEntry + "]");
return new String(
"NameQueryResponse[" + super.toString() + ",addrEntry=" + ( this.addrEntry != null ? Arrays.toString(this.addrEntry) : "" ) + "]");
}
}
65 changes: 50 additions & 15 deletions src/main/java/jcifs/netbios/NameServiceClientImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -510,6 +511,13 @@ NbtAddress[] getAllByName ( Name name, InetAddress addr ) throws UnknownHostExce
try {
send(request, response, config.getNetbiosRetryTimeout());
}
catch ( InterruptedIOException ioe ) {
// second query thread to finish gets interrupted so this is expected
if ( log.isTraceEnabled() ) {
log.trace("Failed to send nameservice request for " + name.name, ioe);
}
throw new UnknownHostException(name.name);
}
catch ( IOException ioe ) {
log.info("Failed to send nameservice request for " + name.name, ioe);
throw new UnknownHostException(name.name);
Expand Down Expand Up @@ -813,7 +821,7 @@ static class QueryThread extends Thread {
private Sem sem;
private String host, scope;
private int type;
private NetbiosAddress ans = null;
private NetbiosAddress[] ans = null;
private InetAddress svr;
private UnknownHostException uhe;
private CIFSContext tc;
Expand All @@ -833,7 +841,7 @@ static class QueryThread extends Thread {
@Override
public void run () {
try {
this.ans = this.tc.getNameServiceClient().getNbtByName(this.host, this.type, this.scope, this.svr);
this.ans = this.tc.getNameServiceClient().getNbtAllByName(this.host, this.type, this.scope, this.svr);
}
catch ( UnknownHostException ex ) {
this.uhe = ex;
Expand All @@ -853,7 +861,7 @@ public void run () {
/**
* @return the ans
*/
public NetbiosAddress getAnswer () {
public NetbiosAddress[] getAnswer () {
return this.ans;
}

Expand All @@ -868,7 +876,7 @@ public UnknownHostException getException () {
}


NetbiosAddress lookupServerOrWorkgroup ( String name, InetAddress svr ) throws UnknownHostException {
NetbiosAddress[] lookupServerOrWorkgroup ( String name, InetAddress svr ) throws UnknownHostException {
Sem sem = new Sem(2);
int type = isWINS(svr) ? 0x1b : 0x1d;

Expand Down Expand Up @@ -954,7 +962,6 @@ public UniAddress getByName ( String hostname, boolean possibleNTDomainOrWorkgro

@Override
public UniAddress[] getAllByName ( String hostname, boolean possibleNTDomainOrWorkgroup ) throws UnknownHostException {
Object addr;
if ( hostname == null || hostname.length() == 0 ) {
throw new UnknownHostException();
}
Expand All @@ -970,12 +977,17 @@ public UniAddress[] getAllByName ( String hostname, boolean possibleNTDomainOrWo
}

for ( ResolverType resolver : this.transportContext.getConfig().getResolveOrder() ) {
NetbiosAddress[] addr = null;
try {
switch ( resolver ) {
case RESOLVER_LMHOSTS:
if ( ( addr = getLmhosts().getByName(hostname, this.transportContext) ) == null ) {
NbtAddress lmaddr;
if ( ( lmaddr = getLmhosts().getByName(hostname, this.transportContext) ) == null ) {
continue;
}
addr = new NetbiosAddress[] {
lmaddr
};
break;
case RESOLVER_WINS:
if ( hostname.equals(NbtAddress.MASTER_BROWSER_NAME) || hostname.length() > 15 ) {
Expand All @@ -986,7 +998,7 @@ public UniAddress[] getAllByName ( String hostname, boolean possibleNTDomainOrWo
addr = lookupServerOrWorkgroup(hostname, getWINSAddress());
}
else {
addr = getNbtByName(hostname, 0x20, null, getWINSAddress());
addr = getNbtAllByName(hostname, 0x20, null, getWINSAddress());
}
break;
case RESOLVER_BCAST:
Expand All @@ -998,34 +1010,57 @@ public UniAddress[] getAllByName ( String hostname, boolean possibleNTDomainOrWo
addr = lookupServerOrWorkgroup(hostname, this.transportContext.getConfig().getBroadcastAddress());
}
else {
addr = getNbtByName(hostname, 0x20, null, this.transportContext.getConfig().getBroadcastAddress());
addr = getNbtAllByName(hostname, 0x20, null, this.transportContext.getConfig().getBroadcastAddress());
}
break;
case RESOLVER_DNS:
if ( isAllDigits(hostname) ) {
throw new UnknownHostException(hostname);
}
InetAddress[] iaddrs = InetAddress.getAllByName(hostname);
UniAddress[] addrs = new UniAddress[iaddrs.length];
for ( int ii = 0; ii < iaddrs.length; ii++ ) {
addrs[ ii ] = new UniAddress(iaddrs[ ii ]);
UniAddress[] addrs = wrapInetAddresses(InetAddress.getAllByName(hostname));
if ( log.isDebugEnabled() ) {
log.debug("Resolved '{}' to {} using DNS", hostname, Arrays.toString(addrs));
}
return addrs; // Success
default:
throw new UnknownHostException(hostname);
}
UniAddress[] addrs = new UniAddress[1];
addrs[ 0 ] = new UniAddress(addr);
return addrs; // Success

if ( addr != null ) { // Success
if ( log.isDebugEnabled() ) {
log.debug("Resolved '{}' to addrs {} via {}", hostname, Arrays.toString(addr), resolver);
}
return wrapNetbiosAddresses(addr);
}
}
catch ( IOException ioe ) {
// Failure
log.trace("Resolving {} via {} failed:", hostname, resolver);
log.trace("Exception is", ioe);
}
}
throw new UnknownHostException(hostname);
}


private static UniAddress[] wrapInetAddresses ( InetAddress[] iaddrs ) {
UniAddress[] addrs = new UniAddress[iaddrs.length];
for ( int ii = 0; ii < iaddrs.length; ii++ ) {
addrs[ ii ] = new UniAddress(iaddrs[ ii ]);
}
return addrs;
}


private static UniAddress[] wrapNetbiosAddresses ( NetbiosAddress[] addr ) {
UniAddress[] addrs = new UniAddress[addr.length];
for ( int i = 0; i < addr.length; i++ ) {
addrs[ i ] = new UniAddress(addr[ i ]);
}
return addrs;
}


/**
* {@inheritDoc}
*
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/jcifs/smb/SmbTransportPoolImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ public int compare ( Address o1, Address o2 ) {

IOException ex = null;
for ( Address addr : addrs ) {
if ( log.isDebugEnabled() ) {
log.debug("Trying address {}", addr);
}
try ( SmbTransportImpl trans = getSmbTransport(tf, addr, port, exclusive, forceSigning).unwrap(SmbTransportImpl.class) ) {
try {
trans.ensureConnected();
Expand Down

0 comments on commit c27b8f5

Please sign in to comment.