com.limegroup.gnutella
Class ConnectionManager

java.lang.Object
  extended bycom.limegroup.gnutella.ConnectionManager

public class ConnectionManager
extends java.lang.Object

The list of all ManagedConnection's. Provides a factory method for creating user-requested outgoing connections, accepts incoming connections, and fetches "automatic" outgoing connections as needed. Creates threads for handling these connections when appropriate. Use the setKeepAlive(int) method control the number of connections; modifying the KEEP_ALIVE property of SettingsManager does not automatically affect this.

Because this is the only list of all connections, it plays an important role in message broadcasting. For this reason, the code is highly tuned to avoid locking in the getInitializedConnections() methods. Adding and removing connections is a slower operation.

ConnectionManager has methods to get up and downstream bandwidth, but it doesn't quite fit the BandwidthTracker interface.


Field Summary
static int ALLOWED_BAD_LEAF_CONNECTIONS
          Similar to RESERVED_GOOD_CONNECTIONS, but measures the number of slots allowed for bad leaf connections.
static int PREFERRED_CONNECTIONS_FOR_LEAF
          The number of connections leaves should maintain to Ultrapeers.
static int RESERVED_GOOD_LEAF_CONNECTIONS
          The number of leaf connections reserved for "good" clients.
static int ULTRAPEER_CONNECTIONS
          The number of Ultrapeer connections to ideally maintain as an Ultrapeer.
 
Constructor Summary
ConnectionManager(Authenticator authenticator)
          Constructs a ConnectionManager.
 
Method Summary
 boolean allowAnyConnection()
          Checks if there is any available slot of any kind.
 boolean allowConnection(HandshakeResponse hr)
          Checks if the connection received can be accepted, based upon the type of connection (e.g.
 boolean allowConnection(HandshakeResponse hr, boolean leaf)
          Returns true if this has slots for an incoming connection, without accounting for this' ultrapeer capabilities.
 boolean allowConnectionAsLeaf(HandshakeResponse hr)
          Checks if the connection received can be accepted, based upon the type of connection (e.g.
 boolean allowLeafDemotion()
          Returns true if this can safely switch from Ultrapeer to leaf mode.
 void connect()
          Connects to the network.
 void createConnectionAsynchronously(java.lang.String hostname, int portnum)
          Create a new connection, allowing it to initialize and loop for messages on a new thread.
 ManagedConnection createConnectionBlocking(java.lang.String hostname, int portnum)
          Create a new connection, blocking until it's initialized, but launching a new thread to do the message loop.
 void disconnect()
          Disconnects from the network.
 Authenticator getAuthenticator()
          Provides handle to the authenticator instance
 Endpoint getConnectedGUESSUltrapeer()
          Returns the Endpoint for an Ultrapeer connected via TCP, if available.
 java.util.List getConnectedGUESSUltrapeers()
          Returns a List of Ultrapeers connected via TCP that are GUESS enabled.
 java.util.List getConnections()
           
 java.util.List getInitializedClientConnections()
           
 java.util.List getInitializedClientConnections2()
           
 java.util.List getInitializedConnections()
           
 java.util.List getInitializedConnections2()
           
 int getKeepAlive()
          Get the number of connections we are attempting to maintain.
 float getMeasuredDownstreamBandwidth()
          Returns the downstream bandwidth between the last two calls to measureBandwidth.
 float getMeasuredUpstreamBandwidth()
          Returns the upstream bandwidth between the last two calls to measureBandwidth.
 int getNumClientSupernodeConnections()
           
 int getNumConnections()
           
 int getNumInitializedClientConnections()
           
 int getNumInitializedConnections()
           
 int getNumOldConnections()
           
 int getNumUltrapeerConnections()
           
 java.util.Set getPushProxies()
          Accessor for the Set of push proxies for this node.
 java.util.Set getSupernodeEndpoints()
          Returns the endpoints of the best known ultrapeers.
 boolean hasFreeSlots()
          Returns whether or not this node has any available connection slots.
 boolean hasSupernodeClientConnection()
          Returns true if this is a super node with a connection to a leaf.
 void initialize()
          Links the ConnectionManager up with the other back end pieces and launches the ConnectionWatchdog and the initial ConnectionFetchers.
 boolean isConnected()
          Returns whether or not the client has an established connection with another Gnutella client.
 boolean isShieldedLeaf()
          Returns true if this is a leaf node with a connection to a ultrapeer.
 boolean isSupernode()
          Tells whether the node is gonna be an Ultrapeer or not
 void measureBandwidth()
          Takes a snapshot of the upstream and downstream bandwidth since the last call to measureBandwidth.
 void remove(ManagedConnection mc)
          Removes the specified connection from currently active connections, also removing this connection from routing tables and modifying active connection fetchers accordingly.
 void setKeepAlive(int newKeep)
          Reset how many connections you want and start kicking more off if required.
 boolean supernodeNeeded()
          Tells if this node thinks that more ultrapeers are needed on the network.
 void tryToBecomeAnUltrapeer(int demotionLimit)
          Notifies the connection manager that it should attempt to become an Ultrapeer.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

ULTRAPEER_CONNECTIONS

public static final int ULTRAPEER_CONNECTIONS
The number of Ultrapeer connections to ideally maintain as an Ultrapeer.


PREFERRED_CONNECTIONS_FOR_LEAF

public static final int PREFERRED_CONNECTIONS_FOR_LEAF
The number of connections leaves should maintain to Ultrapeers.

See Also:
Constant Field Values

RESERVED_GOOD_LEAF_CONNECTIONS

public static final int RESERVED_GOOD_LEAF_CONNECTIONS
The number of leaf connections reserved for "good" clients. As described above, the definition of good constantly changes with advances in search architecture.


ALLOWED_BAD_LEAF_CONNECTIONS

public static final int ALLOWED_BAD_LEAF_CONNECTIONS
Similar to RESERVED_GOOD_CONNECTIONS, but measures the number of slots allowed for bad leaf connections. A value of zero means that only LimeWire's leaves are allowed.

See Also:
Constant Field Values
Constructor Detail

ConnectionManager

public ConnectionManager(Authenticator authenticator)
Constructs a ConnectionManager. Must call initialize before using.

Parameters:
authenticator - Authenticator instance for authenticating users
Method Detail

initialize

public void initialize()
Links the ConnectionManager up with the other back end pieces and launches the ConnectionWatchdog and the initial ConnectionFetchers.


createConnectionBlocking

public ManagedConnection createConnectionBlocking(java.lang.String hostname,
                                                  int portnum)
                                           throws java.io.IOException
Create a new connection, blocking until it's initialized, but launching a new thread to do the message loop.

Throws:
java.io.IOException

createConnectionAsynchronously

public void createConnectionAsynchronously(java.lang.String hostname,
                                           int portnum)
Create a new connection, allowing it to initialize and loop for messages on a new thread.


remove

public void remove(ManagedConnection mc)
Removes the specified connection from currently active connections, also removing this connection from routing tables and modifying active connection fetchers accordingly.

Parameters:
mc - the ManagedConnection instance to remove

getKeepAlive

public int getKeepAlive()
Get the number of connections we are attempting to maintain.


setKeepAlive

public void setKeepAlive(int newKeep)
Reset how many connections you want and start kicking more off if required. This IS synchronized because we don't want threads adding or removing connections while this is deciding whether to add more threads. Ignores request if a shielded leaf node and newKeep>1 (sic).


isSupernode

public boolean isSupernode()
Tells whether the node is gonna be an Ultrapeer or not

Returns:
true, if Ultrapeer, false otherwise

isShieldedLeaf

public boolean isShieldedLeaf()
Returns true if this is a leaf node with a connection to a ultrapeer. It is not required that the ultrapeer support query routing, though that is generally the case.


hasSupernodeClientConnection

public boolean hasSupernodeClientConnection()
Returns true if this is a super node with a connection to a leaf.


hasFreeSlots

public boolean hasFreeSlots()
Returns whether or not this node has any available connection slots. This is only relevant for Ultrapeers -- leaves will always return false to this call since they do not accept any incoming connections, at least for now.

Returns:
true if this node is an Ultrapeer with free leaf or Ultrapeer connections slots, otherwise false

getNumConnections

public int getNumConnections()
Returns:
the number of connections, which is greater than or equal to the number of initialized connections.

getNumInitializedConnections

public int getNumInitializedConnections()
Returns:
the number of initialized connections, which is less than or equals to the number of connections.

getNumInitializedClientConnections

public int getNumInitializedClientConnections()
Returns:
the number of initializedclient connections, which is less than or equals to the number of connections.

getNumClientSupernodeConnections

public int getNumClientSupernodeConnections()
Returns:
the number of initialized connections for which isClientSupernodeConnection is true.

getNumUltrapeerConnections

public int getNumUltrapeerConnections()
Returns:
the number of ultrapeer -> ultrapeer connections.

getNumOldConnections

public int getNumOldConnections()
Returns:
the number of old unrouted connections.

isConnected

public boolean isConnected()
Returns whether or not the client has an established connection with another Gnutella client.

Returns:
true if the client is currently connected to another Gnutella client, false otherwise

measureBandwidth

public void measureBandwidth()
Takes a snapshot of the upstream and downstream bandwidth since the last call to measureBandwidth.

See Also:
BandwidthTracker.measureBandwidth()

getMeasuredUpstreamBandwidth

public float getMeasuredUpstreamBandwidth()
Returns the upstream bandwidth between the last two calls to measureBandwidth.

See Also:
BandwidthTracker.measureBandwidth()

getMeasuredDownstreamBandwidth

public float getMeasuredDownstreamBandwidth()
Returns the downstream bandwidth between the last two calls to measureBandwidth.

See Also:
BandwidthTracker.measureBandwidth()

allowConnectionAsLeaf

public boolean allowConnectionAsLeaf(HandshakeResponse hr)
Checks if the connection received can be accepted, based upon the type of connection (e.g. client, ultrapeer, temporary etc).

Returns:
true, if we have incoming slot for the connection received, false otherwise

allowConnection

public boolean allowConnection(HandshakeResponse hr)
Checks if the connection received can be accepted, based upon the type of connection (e.g. client, ultrapeer, temporary etc).

Returns:
true, if we have incoming slot for the connection received, false otherwise

allowAnyConnection

public boolean allowAnyConnection()
Checks if there is any available slot of any kind.

Returns:
true, if we have incoming slot of some kind, false otherwise

allowConnection

public boolean allowConnection(HandshakeResponse hr,
                               boolean leaf)
Returns true if this has slots for an incoming connection, without accounting for this' ultrapeer capabilities. More specifically: useragentHeader is used to prefer LimeWire and certain trusted vendors. outgoing is currently unused, but may be used to prefer incoming or outgoing connections in the forward.

Returns:
true if a connection of the given type is allowed

supernodeNeeded

public boolean supernodeNeeded()
Tells if this node thinks that more ultrapeers are needed on the network. This method should be invoked on a ultrapeer only, as only ultrapeer may have required information to make informed decision.

Returns:
true, if more ultrapeers needed, false otherwise

getAuthenticator

public Authenticator getAuthenticator()
Provides handle to the authenticator instance

Returns:
Handle to the authenticator

getInitializedConnections

public java.util.List getInitializedConnections()
Returns:
a clone of this' initialized connections. The iterator yields items in any order. It is permissible to modify this while iterating through the elements of this, but the modifications will not be visible during the iteration.

getInitializedClientConnections

public java.util.List getInitializedClientConnections()
Returns:
a clone of this' initialized connections to shielded-clients. The iterator yields items in any order. It is permissible to modify this while iterating through the elements of this, but the modifications will not be visible during the iteration.

getInitializedConnections2

public java.util.List getInitializedConnections2()

getInitializedClientConnections2

public java.util.List getInitializedClientConnections2()

getConnections

public java.util.List getConnections()
Returns:
a clone of all of this' connections. The iterator yields items in any order. It is permissible to modify this while iterating through the elements of this, but the modifications will not be visible during the iteration.

getPushProxies

public java.util.Set getPushProxies()
Accessor for the Set of push proxies for this node. If there are no push proxies available, or if this node is an Ultrapeer, this will return an empty Set.

Returns:
a Set of push proxies with a maximum size of 4 TODO: should the set of pushproxy UPs be cached and updated as connections are killed and created?

getSupernodeEndpoints

public java.util.Set getSupernodeEndpoints()
Returns the endpoints of the best known ultrapeers. This include both ultrapeers we are connected to and marked ultrapeer pongs.

Returns:
Returns the endpoints it is connected to.

getConnectedGUESSUltrapeer

public Endpoint getConnectedGUESSUltrapeer()
Returns the Endpoint for an Ultrapeer connected via TCP, if available.

Returns:
the Endpoint for an Ultrapeer connected via TCP if there is one, otherwise returns null

getConnectedGUESSUltrapeers

public java.util.List getConnectedGUESSUltrapeers()
Returns a List of Ultrapeers connected via TCP that are GUESS enabled.

Returns:
A non-null List of GUESS enabled, TCP connected Ultrapeers. The are represented as ManagedConnections.

disconnect

public void disconnect()
Disconnects from the network. Closes all connections and sets the number of connections to zero.


connect

public void connect()
Connects to the network. Ensures the number of messaging connections (keep-alive) is non-zero and recontacts the pong server as needed.


allowLeafDemotion

public boolean allowLeafDemotion()
Returns true if this can safely switch from Ultrapeer to leaf mode. Typically this means that we are an Ultrapeer and have no leaf connections.

Returns:
true if we will allow ourselves to become a leaf, otherwise false

tryToBecomeAnUltrapeer

public void tryToBecomeAnUltrapeer(int demotionLimit)
Notifies the connection manager that it should attempt to become an Ultrapeer. If we already are an Ultrapeer, this will be ignored.

Parameters:
demotionLimit - the number of attempts by other Ultrapeers to demote us to a leaf that we should allow before giving up in the attempt to become an Ultrapeer