package com.limegroup.gnutella.connection;
import com.limegroup.gnutella.handshaking.HandshakeResponse;
import com.limegroup.gnutella.handshaking.HeaderNames;
import com.limegroup.gnutella.messages.vendor.CapabilitiesVM;
import com.limegroup.gnutella.messages.vendor.MessagesSupportedVendorMessage;
/**
* A {@link ConnectionCapabilities} that delegates to {@link HandshakeResponse}
* objects to keep track of what headers were read or written, and
* {@link CapabilitiesVM} and {@link MessagesSupportedVendorMessage} objects to
* keep track of what vendor messages & capabilities are supported.
*/
public class ConnectionCapabilitiesImpl implements ConnectionCapabilities {
private volatile CapabilitiesVM capabilitiesVendorMessage;
// start with empty responses
private volatile HandshakeResponse headersRead = HandshakeResponse.createEmptyResponse();
private volatile HandshakeResponse headersWritten = HandshakeResponse.createEmptyResponse();
private volatile MessagesSupportedVendorMessage messagesSupportedVendorMessage;
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#getUserAgent()
*/
public String getUserAgent() {
return headersRead.getUserAgent();
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#isLimeWire()
*/
public boolean isLimeWire() {
return headersRead.isLimeWire();
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#isOldLimeWire()
*/
public boolean isOldLimeWire() {
return headersRead.isOldLimeWire();
}
// inherit doc comment
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#isGoodUltrapeer()
*/
public boolean isGoodUltrapeer() {
return headersRead.isGoodUltrapeer();
}
// inherit doc comment
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#isGoodLeaf()
*/
public boolean isGoodLeaf() {
return headersRead.isGoodLeaf();
}
// inherit doc comment
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#supportsPongCaching()
*/
public boolean supportsPongCaching() {
return headersRead.supportsPongCaching();
}
/**
* Returns the number of intra-Ultrapeer connections this node maintains.
*
* @return the number of intra-Ultrapeer connections this node maintains
*/
public int getNumIntraUltrapeerConnections() {
return headersRead.getNumIntraUltrapeerConnections();
}
// implements ReplyHandler interface -- inherit doc comment
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#isHighDegreeConnection()
*/
public boolean isHighDegreeConnection() {
return headersRead.isHighDegreeConnection();
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#isUltrapeerQueryRoutingConnection()
*/
public boolean isUltrapeerQueryRoutingConnection() {
return headersRead.isUltrapeerQueryRoutingConnection();
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#supportsProbeQueries()
*/
public boolean supportsProbeQueries() {
return headersRead.supportsProbeQueries();
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#receivedHeaders()
*/
public boolean receivedHeaders() {
return headersRead != HandshakeResponse.createEmptyResponse();
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#headers()
*/
public HandshakeResponse getHeadersRead() {
return headersRead;
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#getVersion()
*/
public String getVersion() {
return headersRead.getVersion();
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#isLeafConnection()
*/
public boolean isLeafConnection() {
return headersRead.isLeaf();
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#isSupernodeConnection()
*/
public boolean isSupernodeConnection() {
return headersRead.isUltrapeer();
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#isClientSupernodeConnection()
*/
public boolean isClientSupernodeConnection() {
// Is remote host a supernode...
if (!isSupernodeConnection())
return false;
// ...and am I a leaf node?
String value = headersWritten.props().getProperty(HeaderNames.X_ULTRAPEER);
if (value == null)
return false;
else
return !Boolean.valueOf(value).booleanValue();
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#isSupernodeSupernodeConnection()
*/
public boolean isSupernodeSupernodeConnection() {
// Is remote host a supernode...
if (!isSupernodeConnection())
return false;
// ...and am I a leaf node?
String value = headersWritten.props().getProperty(HeaderNames.X_ULTRAPEER);
if (value == null)
return false;
else
return Boolean.valueOf(value).booleanValue();
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#isGUESSUltrapeer()
*/
public boolean isGUESSUltrapeer() {
return headersRead.isGUESSUltrapeer();
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#isSupernodeClientConnection()
*/
public boolean isSupernodeClientConnection() {
// Is remote host a supernode...
if (!isLeafConnection())
return false;
// ...and am I a supernode?
String value = headersWritten.props().getProperty(HeaderNames.X_ULTRAPEER);
if (value == null)
return false;
else if (!Boolean.valueOf(value).booleanValue())
return false;
// ...and do both support QRP?
return isQueryRoutingEnabled();
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#supportsGGEP()
*/
@Deprecated
// used only in tests!
public boolean supportsGGEP() {
return headersRead.supportsGGEP();
}
/**
* True if the remote host supports query routing (QRP). This is only
* meaningful in the context of leaf-ultrapeer relationships.
*/
public boolean isQueryRoutingEnabled() {
return headersRead.isQueryRoutingEnabled();
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#supportsVendorMessage(byte[],
* int)
*/
public int supportsVendorMessage(byte[] vendorID, int selector) {
if (messagesSupportedVendorMessage != null)
return messagesSupportedVendorMessage.supportsMessage(vendorID, selector);
return -1;
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#supportsVMRouting()
*/
public boolean supportsVMRouting() {
if (headersRead != null)
return headersRead.supportsVendorMessages() >= 0.2;
return false;
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#remoteHostSupportsUDPConnectBack()
*/
public int remoteHostSupportsUDPConnectBack() {
if (messagesSupportedVendorMessage != null)
return messagesSupportedVendorMessage.supportsUDPConnectBack();
return -1;
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#remoteHostSupportsTCPConnectBack()
*/
public int remoteHostSupportsTCPConnectBack() {
if (messagesSupportedVendorMessage != null)
return messagesSupportedVendorMessage.supportsTCPConnectBack();
return -1;
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#remoteHostSupportsUDPRedirect()
*/
public int remoteHostSupportsUDPRedirect() {
if (messagesSupportedVendorMessage != null)
return messagesSupportedVendorMessage.supportsUDPConnectBackRedirect();
return -1;
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#remoteHostSupportsTCPRedirect()
*/
public int remoteHostSupportsTCPRedirect() {
if (messagesSupportedVendorMessage != null)
return messagesSupportedVendorMessage.supportsTCPConnectBackRedirect();
return -1;
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#remoteHostSupportsUDPCrawling()
*/
public int remoteHostSupportsUDPCrawling() {
if (messagesSupportedVendorMessage != null)
return messagesSupportedVendorMessage.supportsUDPCrawling();
return -1;
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#remoteHostSupportsHopsFlow()
*/
public int remoteHostSupportsHopsFlow() {
if (messagesSupportedVendorMessage != null)
return messagesSupportedVendorMessage.supportsHopsFlow();
return -1;
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#remoteHostSupportsPushProxy()
*/
public int remoteHostSupportsPushProxy() {
if ((messagesSupportedVendorMessage != null) && isClientSupernodeConnection())
return messagesSupportedVendorMessage.supportsPushProxy();
return -1;
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#remoteHostSupportsLeafGuidance()
*/
public int remoteHostSupportsLeafGuidance() {
if (messagesSupportedVendorMessage != null)
return messagesSupportedVendorMessage.supportsLeafGuidance();
return -1;
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#remoteHostSupportsHeaderUpdate()
*/
public int remoteHostSupportsHeaderUpdate() {
if (messagesSupportedVendorMessage != null)
return messagesSupportedVendorMessage.supportsHeaderUpdate();
return -1;
}
/**
* Returns the peer's supported version of the out-of-band proxying control
* message or -1.
*/
public int getSupportedOOBProxyControlVersion() {
if (messagesSupportedVendorMessage != null)
return messagesSupportedVendorMessage.supportsOOBProxyingControl();
return -1;
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#remoteHostSupportsInspections()
*/
public int remoteHostSupportsInspections() {
if (messagesSupportedVendorMessage != null)
return messagesSupportedVendorMessage.supportsInspectionRequests();
return -1;
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#getRemoteHostSupportsFeatureQueries()
*/
public boolean getRemoteHostSupportsFeatureQueries() {
if (capabilitiesVendorMessage != null)
return capabilitiesVendorMessage.supportsFeatureQueries() > 0;
return false;
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#getRemoteHostFeatureQuerySelector()
*/
public int getRemoteHostFeatureQuerySelector() {
if (capabilitiesVendorMessage != null)
return capabilitiesVendorMessage.supportsFeatureQueries();
return -1;
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#remoteHostSupportsWhatIsNew()
*/
public boolean remoteHostSupportsWhatIsNew() {
if (capabilitiesVendorMessage != null)
return capabilitiesVendorMessage.supportsWhatIsNew();
return false;
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#remostHostIsActiveDHTNode()
*/
public int remostHostIsActiveDHTNode() {
if (capabilitiesVendorMessage != null) {
return capabilitiesVendorMessage.isActiveDHTNode();
}
return -1;
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#remostHostIsPassiveDHTNode()
*/
public int remostHostIsPassiveDHTNode() {
if (capabilitiesVendorMessage != null) {
return capabilitiesVendorMessage.isPassiveDHTNode();
}
return -1;
}
/*
* (non-Javadoc)
*
* @see com.limegroup.gnutella.ConnectionCapabilities#remoteHostIsPassiveLeafNode()
*/
public int remoteHostIsPassiveLeafNode() {
if (capabilitiesVendorMessage != null) {
return capabilitiesVendorMessage.isPassiveLeafNode();
}
return -1;
}
public int getCapability(Capability capability) {
if (capabilitiesVendorMessage != null) {
switch (capability) {
case TLS:
return capabilitiesVendorMessage.supportsTLS();
default:
throw new IllegalArgumentException("unknown capability!");
}
} else {
return -1;
}
}
public HandshakeResponse getHeadersWritten() {
return headersWritten;
}
public boolean isCapabilitiesVmSet() {
return capabilitiesVendorMessage != null;
}
public void setCapabilitiesVendorMessage(CapabilitiesVM vm) {
this.capabilitiesVendorMessage = vm;
}
public void setHeadersRead(HandshakeResponse createResponse) {
this.headersRead = createResponse;
}
public void setHeadersWritten(HandshakeResponse writtenHeaders) {
this.headersWritten = writtenHeaders;
}
public void setMessagesSupportedVendorMessage(MessagesSupportedVendorMessage vm) {
this.messagesSupportedVendorMessage = vm;
}
public boolean canAcceptIncomingTCP() {
if (capabilitiesVendorMessage == null)
return true;
return capabilitiesVendorMessage.canAcceptIncomingTCP();
}
public boolean canDoFWT() {
if (capabilitiesVendorMessage == null)
return true;
return capabilitiesVendorMessage.canDoFWT();
}
}