package com.limegroup.gnutella; import java.io.IOException; import java.net.InetSocketAddress; import java.util.Set; import org.limewire.io.GUID; import org.limewire.io.IpPort; import org.limewire.lifecycle.Service; import org.limewire.security.SecurityToken; import com.limegroup.gnutella.connection.RoutedConnection; import com.limegroup.gnutella.guess.GUESSEndpoint; import com.limegroup.gnutella.messagehandlers.MessageHandler; import com.limegroup.gnutella.messages.Message; import com.limegroup.gnutella.messages.PingRequest; import com.limegroup.gnutella.messages.PushRequest; import com.limegroup.gnutella.messages.QueryReply; import com.limegroup.gnutella.messages.QueryRequest; import com.limegroup.gnutella.messages.vendor.InspectionRequest; import com.limegroup.gnutella.messages.vendor.ReplyNumberVendorMessage; import com.limegroup.gnutella.routing.QueryRouteTable; public interface MessageRouter extends Service { public static final long CLEAR_TIME = 30 * 1000; // 30 seconds /** * Installs a MessageHandler for "regular" Messages. * * @link #handleMessage(Message, RoutedConnection) * @param clazz The Class of the Message * @param handler The Handler of the Message */ public void setMessageHandler(Class<? extends Message> clazz, MessageHandler handler); /** * Adds the new handler as a handler in addition to other handlers. * * @link #handleMessage(Message, RoutedConnection) * @param clazz The Class of the Message * @param handler The Handler of the Message */ public void addMessageHandler(Class<? extends Message> clazz, MessageHandler handler); /** * Returns a MessageHandler for the specified Message Class * or null if no such MessageHandler exists. */ public MessageHandler getMessageHandler(Class<? extends Message> clazz); /** * Installs a MessageHandler for UDP Messages. * * @link #handleUDPMessage(Message, InetSocketAddress) * @param clazz The Class of the Message * @param handler The Handler of the Message */ public void setUDPMessageHandler(Class<? extends Message> clazz, MessageHandler handler); /** * Adds the new handler as a handler in addition to other handlers for UDP messages. * * @link #handleUDPMessage(Message, InetSocketAddress) * @param clazz The Class of the Message * @param handler The Handler of the Message */ public void addUDPMessageHandler(Class<? extends Message> clazz, MessageHandler handler); /** * Returns a MessageHandler for the specified Message Class * or null if no such MessageHandler exists. */ public MessageHandler getUDPMessageHandler(Class<? extends Message> clazz); /** * Installs a MessageHandler for Multicast Messages. * * @link #handleMulticastMessage(Message, InetSocketAddress) * @param clazz The Class of the Message * @param handler The Handler of the Message */ public void setMulticastMessageHandler(Class<? extends Message> clazz, MessageHandler handler); /** * Adds the new handler as a handler in addition to other handlers for multicast messages. * * @link #handleMulticastMessage(Message, InetSocketAddress) * @param clazz The Class of the Message * @param handler The Handler of the Message */ public void addMulticastMessageHandler(Class<? extends Message> clazz, MessageHandler handler); /** * Returns a MessageHandler for the specified Message Class * or null if no such MessageHandler exists. */ public MessageHandler getMulticastMessageHandler( Class<? extends Message> clazz); /** * Routes a query GUID to yourself. */ public void originateQueryGUID(byte[] guid); /** Call this to inform us that a query has been killed by a user or * whatever. Useful for purging unneeded info.<br> * Callers of this should make sure that they have purged the guid from * their tables. * @throws IllegalArgumentException if the guid is null */ public void queryKilled(GUID guid) throws IllegalArgumentException; /** Call this to inform us that a download is finished or whatever. Useful * for purging unneeded info.<br> * If the caller is a Downloader, please be sure to clear yourself from the * active and waiting lists in DownloadManager. * @throws IllegalArgumentException if the guid is null */ public void downloadFinished(GUID guid) throws IllegalArgumentException; /** @returns a Set with GUESSEndpoints that had matches for the * original query guid. may be empty. * @param guid the guid of the query you want endpoints for. */ public Set<GUESSEndpoint> getQueryLocs(GUID guid); public String getPingRouteTableDump(); public String getQueryRouteTableDump(); public String getPushRouteTableDump(); /** * The handler for all message types. Processes a message based on the * message type. * * @param m the <tt>Message</tt> instance to route appropriately * @param receivingConnection the <tt>ReplyHandler</tt> over which * the message was received */ public void handleMessage(Message msg, ReplyHandler receivingConnection); /** * The handler for all message types. Processes a message based on the * message type. * * @param msg the <tt>Message</tt> received * @param addr the <tt>InetSocketAddress</tt> containing the IP and * port of the client node */ public void handleUDPMessage(Message msg, InetSocketAddress addr); /** * The handler for Multicast messages. Processes a message based on the * message type. * * @param msg the <tt>Message</tt> recieved. * @param addr the <tt>InetSocketAddress</tt> containing the IP and * port of the client node. */ public void handleMulticastMessage(Message msg, InetSocketAddress addr); /** * Adds the address of <code>handler</code> to the {@link BypassedResultsCache} * if it can receive unsolicited udp. * * @return true if successfully added to the bypassed results cache */ public boolean addBypassedSource(ReplyNumberVendorMessage reply, ReplyHandler handler); /** * Adds the address of <code>handler</code> to the {@link BypassedResultsCache} * if it is likely to not be firewalled. */ public boolean addBypassedSource(QueryReply reply, ReplyHandler handler); /** * Returns the number of results to request from source of <code>reply</code>. * * @return -1 if no results are desired */ public int getNumOOBToRequest(ReplyNumberVendorMessage reply); /** * @return true if there is still a route for this reply */ public boolean isQueryAlive(GUID guid); /** * Determines if we've sent a unicast OOB query to * the given host using the given query GUID. */ public boolean isHostUnicastQueried(GUID guid, IpPort host); /** * Sends the ping request to the designated connection, * setting up the proper reply routing. */ public void sendPingRequest(PingRequest request, RoutedConnection connection); /** * Broadcasts the ping request to all initialized connections, * setting up the proper reply routing. */ public void broadcastPingRequest(PingRequest ping); /** * Generates a new dynamic query. This method is used to send a new * dynamic query from this host (the user initiated this query directly, * so it's replies are intended for this node). * * @param query the <tt>QueryRequest</tt> instance that generates * queries for this dynamic query */ public void sendDynamicQuery(QueryRequest query); /** * Forwards the query request to any leaf connections. * * @param request the query to forward * @param handler the <tt>ReplyHandler</tt> that responds to the * request appropriately * @param manager the <tt>ConnectionManager</tt> that provides * access to any leaf connections that we should forward to */ public void forwardQueryRequestToLeaves(QueryRequest query, ReplyHandler handler); /** * Used to send the first request to a specific ultrapeer * when dynamic querying. * * @param request The query to send. * @param mc The RoutedConnection to send the query along * @return false if the query was not sent, true if so */ public boolean sendInitialQuery(QueryRequest query, RoutedConnection mc); /** * The default handler for QueryReplies. This implementation * uses the query route table to route a query reply. If an appropriate * route doesn't exist, records the error statistics. On sucessful routing, * the QueryReply count is incremented.<p> * * Override as desired, but you probably want to call super.handleQueryReply * if you do. This is public for testing purposes. */ public void handleQueryReply(QueryReply queryReply, ReplyHandler handler); /** * Uses the push route table to send a push request to the appropriate * connection. Since this is used for PushRequests orginating here, no * stats are updated. * @throws IOException if no appropriate route exists. */ public void sendPushRequest(PushRequest push) throws IOException; /** * Sends a push request to the multicast network. No lookups are * performed in the push route table, because the message will always * be broadcast to everyone. */ public void sendMulticastPushRequest(PushRequest push); /** * Converts the passed responses to QueryReplies. Each QueryReply can * accomodate atmost 255 responses. Not all the responses may get included * in QueryReplies in case the query request came from a far away host. * <p> * NOTE: This method doesnt have any side effect, * and does not modify the state of this object * @param responses The responses to be converted * @param queryRequest The query request corresponding to which we are * generating query replies. * @return Iterable of QueryReply */ public Iterable<QueryReply> responsesToQueryReplies(Response[] responses, QueryRequest queryRequest); public Iterable<QueryReply> responsesToQueryReplies(Response[] responses, QueryRequest queryRequest, int replyLimit, SecurityToken token); /** * Accessor for the most recently calculated <tt>QueryRouteTable</tt> * for this node. If this node is an Ultrapeer, the table will include * all data for leaf nodes in addition to data for this node's files. * * @return the <tt>QueryRouteTable</tt> for this node */ public QueryRouteTable getQueryRouteTable(); /** * Adds the specified MessageListener for messages with this GUID. * You must manually unregister the listener. * * This works by replacing the necessary maps & lists, so that * notifying doesn't have to hold any locks. */ public void registerMessageListener(byte[] guid, MessageListener ml); /** * Unregisters this MessageListener from listening to the GUID. * * This works by replacing the necessary maps & lists so that * notifying doesn't have to hold any locks. */ public void unregisterMessageListener(byte[] guid, MessageListener ml); /** * Forwards an inspection request to leaf connections that * support it. */ public void forwardInspectionRequestToLeaves(InspectionRequest ir); /** * Time after which an OOB session should be expired. * @return */ public long getOOBExpireTime(); /** * Returns the push handler registered for the <code>guid</code>, could also * be {@link ForMeReplyHandler} or any of the leaves that are push proxied. * * @param guid the client guid * * @return null if no reply handler is registered for the guid */ ReplyHandler getPushHandler(byte[] guid); }