/** * Generates an SSL-enabled socket. * * @return the new socket * @throws GeneralSecurityException on error building the socket * @throws IOException on error loading the KeyStore */ private SSLSocket getSslSocket(RemoteDevice target) throws GeneralSecurityException, IOException { // Build a new key store based on the key store manager. KeyManager[] keyManagers = coreService.getKeyStoreManager().getKeyManagers(); TrustManager[] trustManagers = coreService.getKeyStoreManager().getTrustManagers(); if (keyManagers.length == 0) { throw new IllegalStateException("No key managers"); } // Create a new SSLContext, using the new KeyManagers and TrustManagers // as the sources of keys and trust decisions, respectively. SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(keyManagers, trustManagers, null); // Finally, build a new SSLSocketFactory from the SSLContext, and // then generate a new SSLSocket from it. SSLSocketFactory factory = sslContext.getSocketFactory(); SSLSocket sock = (SSLSocket) factory.createSocket(); sock.setNeedClientAuth(true); sock.setUseClientMode(true); sock.setKeepAlive(true); sock.setTcpNoDelay(true); InetSocketAddress fullAddr = new InetSocketAddress(target.getAddress(), target.getPort()); sock.connect(fullAddr, SOCKET_CREATION_TIMEOUT_MS); sock.startHandshake(); return sock; }
/** * Pings a peer to test if it's still alive, and sends a list of peers that have disconnected. * * @throws IOException In case an unexpected error happens while reading connections */ public void ping(RemoteDevice peer) throws IOException { try { Socket peerSocket = new Socket(); peerSocket.connect(new InetSocketAddress(peer.getIpAddress(), peer.getPort()), 5000); DataInputStream in = new DataInputStream(peerSocket.getInputStream()); DataOutputStream out = new DataOutputStream(peerSocket.getOutputStream()); /* The tracker will use the special ID -2 */ out.writeInt(-2); out.writeInt(serverPort); /* We prepare the list of peers that have been disconnected */ String message = ""; ArrayList<RemoteDevice> disPeersCopy = new ArrayList<RemoteDevice>(disPeers); for (RemoteDevice opeer : disPeersCopy) { message += opeer.getId() + "|"; } if (message.length() > 0) { message = message.substring(0, message.length() - 1); } /* We send the reply */ out.writeInt(0); out.writeUTF("ping"); out.writeUTF("pong" + message); /* We clear the notifying list if everyone has been notified */ notPeers++; if (notPeers >= peers.size()) { disPeers = new ArrayList<RemoteDevice>(); notPeers = 0; } try { peerSocket.close(); } catch (IOException ioe) { System.err.println("IOException while closing peer " + ioe.getMessage()); } /* The peer appears to be disconnected, remove it from the peerlist */ } catch (SocketTimeoutException ste) { System.out.println("Peer " + peer.getId() + " is no longer responding."); peers.remove(peer); disPeers.add(peer); notPeers = 0; } catch (UnknownHostException uhe) { System.err.println("Unknown host: " + peer.getIpAddress()); } catch (IOException ioe) { System.out.println("Peer " + peer.getId() + " is no longer responding."); peers.remove(peer); disPeers.add(peer); notPeers = 0; } }
/** * The listen method for the servicing new peers. * * @throws IOException In case an unexpected error happens while reading connections */ public void listen() throws IOException { int id = 0; ServerSocket listenSocket = new ServerSocket(serverPort); while (true) { Socket clientSocket = listenSocket.accept(); clientSocket.setSoTimeout(5000); DataInputStream in = new DataInputStream(clientSocket.getInputStream()); DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream()); try { String ipAddress = clientSocket.getInetAddress().getHostAddress(); /* Ask peer which port will it use for the P2P communication */ int assignedPort = in.readInt(); /* Assign an id to peer, send it and close connection */ id++; out.writeInt(id); RemoteDevice newClient = new RemoteDevice(id, ipAddress, assignedPort); /* Send the peer list */ ArrayList<RemoteDevice> peersCopy = new ArrayList<RemoteDevice>(peers); for (RemoteDevice peer : peersCopy) { out.writeBoolean(true); out.writeInt(peer.getId()); out.writeUTF(peer.getIpAddress()); out.writeInt(peer.getPort()); } out.writeBoolean(false); /* Add new peer to peer list */ getPeers().add(newClient); } catch (SocketTimeoutException ste) { System.err.println( "Socket timeout from peer: " + clientSocket.getInetAddress().getHostAddress()); } catch (IOException ioe) { System.err.println( "IOE exception while initializing peer: " + clientSocket.getInetAddress().getHostAddress()); } finally { clientSocket.close(); } } }
private void storeRemoteDevice( SharedPreferences.Editor prefEdit, String suffix, RemoteDevice remoteDevice) { prefEdit.putString(DEVICE_NAME_TAG + suffix, remoteDevice.getName()); prefEdit.putString(DEVICE_IP_TAG + suffix, remoteDevice.getAddress().getHostAddress()); prefEdit.putInt(DEVICE_PORT_TAG + suffix, remoteDevice.getPort()); }