private synchronized void initSocket(Socket socket) throws IOException { if (!socketInitialized) { if (!socket.isConnected()) { LOG.trace("Trying to connect to node " + node); socket.connect(new InetSocketAddress(node.toInetAddress(), node.getPort()), CONNECT_TIMEOUT); } socket.setSoTimeout(READ_TIMEOUT); in = socket.getInputStream(); out = socket.getOutputStream(); socketInitialized = true; } }
@Override public void write(ByteBuffer buffer) { write(buffer, false); }
private void insert(NetworkAddress node) { try ( Connection connection = config.getConnection(); PreparedStatement ps = connection.prepareStatement( "INSERT INTO Node (stream, address, port, services, time) " + "VALUES (?, ?, ?, ?, ?)") ) { ps.setLong(1, node.getStream()); ps.setBytes(2, node.getIPv6()); ps.setInt(3, node.getPort()); ps.setLong(4, node.getServices()); ps.setLong(5, node.getTime()); ps.executeUpdate(); } catch (SQLException e) { LOG.error(e.getMessage(), e); } }
private NetworkAddress loadExisting(NetworkAddress node) { String query = "SELECT stream, address, port, services, time" + " FROM Node" + " WHERE stream = " + node.getStream() + " AND address = X'" + Strings.hex(node.getIPv6()) + "'" + " AND port = " + node.getPort(); try ( Connection connection = config.getConnection(); Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery(query) ) { if (rs.next()) { return new NetworkAddress.Builder() .stream(rs.getLong("stream")) .ipv6(rs.getBytes("address")) .port(rs.getInt("port")) .services(rs.getLong("services")) .time(rs.getLong("time")) .build(); } else { return null; } } catch (Exception e) { LOG.error(e.getMessage(), e); throw new ApplicationException(e); } }
@Override public String toString() { return "[" + toInetAddress() + "]:" + port; }
public NetworkAddress build() { if (time == 0) { time = UnixTime.now(); } return new NetworkAddress(this); } }
private boolean isConnectedTo(NetworkAddress address) { for (ConnectionInfo c : connections.keySet()) { if (c.getNode().equals(address)) { return true; } } return false; }
@Override public void offerAddresses(List<NetworkAddress> nodes) { cleanUp(); nodes.stream() .filter(node -> node.getTime() < now(+2 * MINUTE) && node.getTime() > now(-28 * DAY)) .forEach(node -> { synchronized (this) { NetworkAddress existing = loadExisting(node); if (existing == null) { insert(node); } else if (node.getTime() > existing.getTime()) { update(node); } } }); }
@Override public String toString() { return "[" + toInetAddress() + "]:" + port; }
public NetworkAddress build() { if (time == 0) { time = UnixTime.now(); } return new NetworkAddress(this); } }
private void update(NetworkAddress node) { try ( Connection connection = config.getConnection(); PreparedStatement ps = connection.prepareStatement( "UPDATE Node SET services=?, time=? WHERE stream=? AND address=? AND port=?") ) { ps.setLong(1, node.getServices()); ps.setLong(2, node.getTime()); ps.setLong(3, node.getStream()); ps.setBytes(4, node.getIPv6()); ps.setInt(5, node.getPort()); ps.executeUpdate(); } catch (SQLException e) { LOG.error(e.getMessage(), e); } } }
@Override public void write(OutputStream stream) throws IOException { write(stream, false); }
@Override public void write(OutputStream stream) throws IOException { write(stream, false); }
@Override public void write(OutputStream out) throws IOException { Encode.varInt(addresses.size(), out); for (NetworkAddress address : addresses) { address.write(out); } }
@Override public void write(ByteBuffer buffer) { Encode.varInt(addresses.size(), buffer); for (NetworkAddress address : addresses) { address.write(buffer); } }
@Override public void write(OutputStream stream) throws IOException { Encode.varInt(addresses.size(), stream); for (NetworkAddress address : addresses) { address.write(stream); } }
@Override public void write(OutputStream stream) throws IOException { Encode.int32(version, stream); Encode.int64(services, stream); Encode.int64(timestamp, stream); addrRecv.write(stream, true); addrFrom.write(stream, true); Encode.int64(nonce, stream); Encode.varString(userAgent, stream); Encode.varIntList(streams, stream); }
@Override public void write(ByteBuffer buffer) { Encode.int32(version, buffer); Encode.int64(services, buffer); Encode.int64(timestamp, buffer); addrRecv.write(buffer, true); addrFrom.write(buffer, true); Encode.int64(nonce, buffer); Encode.varString(userAgent, buffer); Encode.varIntList(streams, buffer); }
@Override public void write(OutputStream stream) throws IOException { Encode.int32(version, stream); Encode.int64(services, stream); Encode.int64(timestamp, stream); addrRecv.write(stream, true); addrFrom.write(stream, true); Encode.int64(nonce, stream); Encode.varString(userAgent, stream); Encode.varIntList(streams, stream); }