package com.limegroup.gnutella.connection; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import org.limewire.io.Connectable; import org.limewire.io.IpPort; import com.limegroup.gnutella.messages.Message; import com.limegroup.gnutella.messages.vendor.SimppVM; import com.limegroup.gnutella.messages.vendor.VendorMessage; /** * Defines an interface by which two parties can communicate using the Gnutella * protocol over a {@link Socket}. Any capabilities or bandwidth statistics * about the connection are retrievable using the * {@link #getConnectionCapabilities()} or * {@link #getConnectionBandwidthStatistics()} methods. * <p> * <code>Connection</code> exposes no methods for reading or 'starting', as it * is possible for two implementations to use very different methods for * processing incoming connections. For example, a blocking implementation would * allow the caller to process messages on a case-by-case basis, reading one at * a time. An asynchronous implementation (such as implementations of * {@link RoutedConnection}) would have a <code>start</code> method that would funnel * received messages to a third party.<p> */ public interface Connection extends IpPort, Connectable { public ConnectionCapabilities getConnectionCapabilities(); public ConnectionBandwidthStatistics getConnectionBandwidthStatistics(); /** * Call this method when you want to handle us to handle a VM. We may.... */ public void handleVendorMessage(VendorMessage vm); /** * Call this method when the Connection has been initialized and accepted as * 'long-lived'. */ public void sendPostInitializeMessages(); /** * Call this method if you want to send your neighbours a message with your * updated capabilities. */ public void sendUpdatedCapabilities(); /** * Sets the port where the connected node listens at, not the one got from * socket. */ void setListeningPort(int port); /** * Returns the time this connection was established, in milliseconds since * January 1, 1970. * * @return the time this connection was established */ public long getConnectionTime(); /** * Used to determine whether the connection is incoming or outgoing. */ public boolean isOutgoing(); /** * Sends a message. The message may be buffered, so call flush() to * guarantee that the message is sent synchronously. This method is NOT * thread-safe. Behavior is undefined if two threads are in a send call at * the same time for a given connection. * * @requires this is fully initialized * @modifies the network underlying this * @effects send m on the network. Throws IOException if problems arise. */ public void send(Message m) throws IOException; /** * Returns the IP address of the remote host as a string. * * @return the IP address of the remote host as a string */ public String getAddress(); /** * Accessor for the port number this connection is listening on. Note that * this is NOT the port of the socket itself. For incoming connections, the * getPort method of the java.net.Socket class returns the ephemeral port * that the host connected with. This port, however, is the port the remote * host is listening on for new connections, which we set using Gnutella * connection headers in the case of incoming connections. For outgoing * connections, this is the port we used to connect to them -- their * listening port. * * @return the listening port for the remote host */ public int getPort(); /** * Gets the port that this connection is listening on. If this is an * outgoing connection, it will return the port to which the socket * connected. Otherwise, if it is an incoming connection, it will return the * port that the remote side had in the Listen-IP header. If there was no * port describe, it will return -1. */ public int getListeningPort(); /** * Returns the InetSocketAddress of the foreign host this is connected to. * This is a combination of the getInetAddress() & getPort() methods, it is * not the remote socket address (as the listening port may have been * updated by connection headers). * * @throws IllegalStateException if this is not initialized */ public InetSocketAddress getInetSocketAddress() throws IllegalStateException; /** * Returns the address of the foreign host this is connected to. * * @exception IllegalStateException this is not initialized */ public InetAddress getInetAddress() throws IllegalStateException; /** * Accessor for the <tt>Socket</tt> for this connection. * * @return the <tt>Socket</tt> for this connection * @throws IllegalStateException if this connection is not yet initialized */ public Socket getSocket() throws IllegalStateException; /** * Checks whether this connection is considered a stable connection, meaning * it has been up for enough time to be considered stable. * * @return <tt>true</tt> if the connection is considered stable, otherwise * <tt>false</tt> */ public boolean isStable(); /** * Checks whether this connection is considered a stable connection, by * comparing the time it was established with the <tt>millis</tt> * argument. * * @return <tt>true</tt> if the connection is considered stable, otherwise * <tt>false</tt> */ public boolean isStable(long millis); /** * Returns the value of the given outgoing (written) connection property, or * null if no such property. For example, getProperty("X-Supernode") tells * whether I am a supernode or a leaf node. If I wrote a property multiple * time during connection, returns the latest. */ public String getPropertyWritten(String name); /** * @return true until close() is called on this Connection */ public boolean isOpen(); /** * Closes the Connection's socket and thus the connection itself. */ public void close(); /** * Returns true if the outgoing stream is deflated. * * @return true if the outgoing stream is deflated. */ public boolean isWriteDeflated(); /** * Returns true if the incoming stream is deflated. * * @return true if the incoming stream is deflated. */ public boolean isReadDeflated(); /** * Returns true if no capabilites VM is received and the connection is TLS * encoded, or if a capabilites VM is received and it advertises support for * TLS. Otherwise, returns false. */ public boolean isTLSCapable(); /** Returns true if the connection is currently over TLS. */ public boolean isTLSEncoded(); /** * Returns whether or not we should allow new pings on this connection. If * we have recently received a ping, we will likely not allow the second * ping to go through to avoid flooding the network with ping traffic. * * @return <tt>true</tt> if new pings are allowed along this connection, * otherwise <tt>false</tt> */ public boolean allowNewPings(); /** * Returns whether or not we should allow new pongs on this connection. If * we have recently received a pong, we will likely not allow the second * pong to go through to avoid flooding the network with pong traffic. In * practice, this is only used to limit pongs sent to leaves. * * @return <tt>true</tt> if new pongs are allowed along this connection, * otherwise <tt>false</tt> */ public boolean allowNewPongs(); /** * Sends the SimppVM down the connection. */ public void handleSimppVM(SimppVM simppVM) throws IOException; /** * Access the locale preference of the connected servent. */ public String getLocalePref(); }