package com.limegroup.gnutella; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.Properties; import org.limewire.core.settings.ConnectionSettings; import org.limewire.core.settings.FilterSettings; import org.limewire.core.settings.NetworkSettings; import org.limewire.core.settings.SearchSettings; import org.limewire.core.settings.UltrapeerSettings; import org.limewire.io.GUID; import org.limewire.net.SocketsManager.ConnectType; import org.limewire.util.PrivilegedAccessor; import com.google.inject.Injector; import com.google.inject.Stage; import com.limegroup.gnutella.connection.BlockingConnection; import com.limegroup.gnutella.connection.BlockingConnectionFactory; import com.limegroup.gnutella.handshaking.HandshakeResponder; import com.limegroup.gnutella.handshaking.HandshakeResponse; import com.limegroup.gnutella.handshaking.HeaderNames; import com.limegroup.gnutella.handshaking.HeadersFactory; import com.limegroup.gnutella.messages.Message; import com.limegroup.gnutella.messages.PingReply; import com.limegroup.gnutella.messages.PingReplyFactory; import com.limegroup.gnutella.messages.PingRequest; import com.limegroup.gnutella.util.LimeTestCase; /** * Allows a testcase to easily interact with a fully running LimeWire. */ public abstract class PeerTestCase extends LimeTestCase { public static final int SERVER_PORT = 6669; protected static int TIMEOUT=500; private static final byte[] ultrapeerIP= new byte[] {(byte)18, (byte)239, (byte)0, (byte)144}; private static final byte[] oldIP= new byte[] {(byte)111, (byte)22, (byte)33, (byte)44}; protected Injector injector; protected LifecycleManager lifecycleManager; protected ConnectionServices connectionServices; protected BlockingConnectionFactory blockingConnectionFactory; protected PingReplyFactory pingReplyFactory; protected HeadersFactory headersFactory; public PeerTestCase(String name) { super(name); } @SuppressWarnings({ "unused", "deprecation" }) private static void doSettings() throws Exception { String localIP = InetAddress.getLocalHost().getHostAddress(); FilterSettings.BLACK_LISTED_IP_ADDRESSES.setValue( new String[] {"*.*.*.*"}); FilterSettings.WHITE_LISTED_IP_ADDRESSES.setValue( new String[] {"127.*.*.*", "192.168.*.*", "10.254.*.*", localIP}); NetworkSettings.PORT.setValue(SERVER_PORT); ConnectionSettings.CONNECT_ON_STARTUP.setValue(false); UltrapeerSettings.EVER_ULTRAPEER_CAPABLE.setValue(false); UltrapeerSettings.DISABLE_ULTRAPEER_MODE.setValue(true); UltrapeerSettings.FORCE_ULTRAPEER_MODE.setValue(false); ConnectionSettings.NUM_CONNECTIONS.setValue(0); ConnectionSettings.LOCAL_IS_PRIVATE.setValue(false); ConnectionSettings.WATCHDOG_ACTIVE.setValue(false); SearchSettings.MINIMUM_SEARCH_QUALITY.setValue(-2); } protected ActivityCallback getActivityCallback() { return injector.getInstance(ActivityCallback.class); } @Override protected void setUp() throws Exception { setUp(LimeTestUtils.createInjector(Stage.PRODUCTION)); } @Override protected void tearDown() throws Exception { if (connectionServices != null) connectionServices.disconnect(); if (lifecycleManager != null) lifecycleManager.shutdown(); } protected void setUp(Injector injector) throws Exception { // calls all doSettings() for me and my parents PrivilegedAccessor.invokeAllStaticMethods(this.getClass(), "doSettings", null); this.injector = injector; // calls all doSettings() for me and my children // rs=new RouterService(callback); assertEquals("unexpected port", SERVER_PORT, NetworkSettings.PORT.getValue()); lifecycleManager = injector.getInstance(LifecycleManager.class); connectionServices = injector.getInstance(ConnectionServices.class); blockingConnectionFactory = injector.getInstance(BlockingConnectionFactory.class); pingReplyFactory = injector.getInstance(PingReplyFactory.class); headersFactory = injector.getInstance(HeadersFactory.class); lifecycleManager.start(); connectionServices.connect(); Thread.sleep(2000); assertEquals("unexpected port", SERVER_PORT, NetworkSettings.PORT.getValue()); } protected BlockingConnection connect(boolean ultrapeer) throws Exception { ServerSocket ss=new ServerSocket(); ss.setReuseAddress(true); ss.bind(new InetSocketAddress(0)); connectionServices.connectToHostAsynchronously("127.0.0.1", ss.getLocalPort(), ConnectType.PLAIN); Socket socket = ss.accept(); ss.close(); socket.setSoTimeout(3000); InputStream in=socket.getInputStream(); String word=readWord(in); if (! word.equals("GNUTELLA")) throw new IOException("Bad word: "+word); HandshakeResponder responder; if (ultrapeer) { responder = new UltrapeerResponder(); } else { responder = new OldResponder(); } BlockingConnection con = blockingConnectionFactory.createConnection(socket); con.initialize(null, responder, 1000); replyToPing(con, ultrapeer); return con; } /** * Acceptor.readWord * * @modifies sock * @effects Returns the first word (i.e., no whitespace) of less * than 8 characters read from sock, or throws IOException if none * found. */ private static String readWord(InputStream sock) throws IOException { final int N=9; //number of characters to look at char[] buf=new char[N]; for (int i=0 ; i<N ; i++) { int got=sock.read(); if (got==-1) //EOF throw new IOException(); if ((char)got==' ') { //got word. Exclude space. return new String(buf,0,i); } buf[i]=(char)got; } throw new IOException(); } /** * Note that this function will _EAT_ messages until it finds a ping to respond to. */ private void replyToPing(BlockingConnection c, boolean ultrapeer) throws Exception { // respond to a ping iff one is given. Message m = null; byte[] guid; try { while (!(m instanceof PingRequest)) { m = c.receive(500); } guid = ((PingRequest)m).getGUID(); } catch(InterruptedIOException iioe) { //nothing's coming, send a fake pong anyway. guid = new GUID().bytes(); } Socket socket = c.getSocket(); PingReply reply = pingReplyFactory.createExternal(guid, (byte)7, socket.getLocalPort(), ultrapeer ? ultrapeerIP : oldIP, ultrapeer); reply.hop(); c.send(reply); c.flush(); } private class UltrapeerResponder implements HandshakeResponder { public HandshakeResponse respond(HandshakeResponse response, boolean outgoing) { Properties props = headersFactory.createUltrapeerHeaders("127.0.0.1"); props.put(HeaderNames.X_DEGREE, "42"); return HandshakeResponse.createResponse(props); } public void setLocalePreferencing(boolean b) {} } private static class OldResponder implements HandshakeResponder { public HandshakeResponse respond(HandshakeResponse response, boolean outgoing) { Properties props=new Properties(); return HandshakeResponse.createResponse(props); } public void setLocalePreferencing(boolean b) {} } }