Fixed a few problems:
- some bugs that creeped in when I moved security into its own adapter - improved some DB code as it doesn't work in Android anyway - all entities should be serializable (very useful in Android)
This commit is contained in:
@ -29,6 +29,7 @@ import org.slf4j.LoggerFactory;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.sql.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
@ -97,16 +98,16 @@ public class JdbcAddressRepository extends JdbcHelper implements AddressReposito
|
||||
while (rs.next()) {
|
||||
BitmessageAddress address;
|
||||
|
||||
byte[] privateKeyBytes = rs.getBytes("private_key");
|
||||
if (privateKeyBytes != null) {
|
||||
PrivateKey privateKey = PrivateKey.read(new ByteArrayInputStream(privateKeyBytes));
|
||||
InputStream privateKeyStream = rs.getBinaryStream("private_key");
|
||||
if (privateKeyStream != null) {
|
||||
PrivateKey privateKey = PrivateKey.read(privateKeyStream);
|
||||
address = new BitmessageAddress(privateKey);
|
||||
} else {
|
||||
address = new BitmessageAddress(rs.getString("address"));
|
||||
byte[] publicKeyBytes = rs.getBytes("public_key");
|
||||
if (publicKeyBytes != null) {
|
||||
Blob publicKeyBlob = rs.getBlob("public_key");
|
||||
if (publicKeyBlob != null) {
|
||||
Pubkey pubkey = Factory.readPubkey(address.getVersion(), address.getStream(),
|
||||
new ByteArrayInputStream(publicKeyBytes), publicKeyBytes.length, false);
|
||||
publicKeyBlob.getBinaryStream(), (int) publicKeyBlob.length(), false);
|
||||
if (address.getVersion() == 4 && pubkey instanceof V3Pubkey) {
|
||||
pubkey = new V4Pubkey((V3Pubkey) pubkey);
|
||||
}
|
||||
@ -182,7 +183,7 @@ public class JdbcAddressRepository extends JdbcHelper implements AddressReposito
|
||||
data.writeUnencrypted(out);
|
||||
ps.setBytes(parameterIndex, out.toByteArray());
|
||||
} else {
|
||||
ps.setBlob(parameterIndex, (Blob) null);
|
||||
ps.setBytes(parameterIndex, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,8 @@ import ch.dissem.bitmessage.entity.payload.ObjectType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.Blob;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
@ -84,7 +82,7 @@ abstract class JdbcHelper {
|
||||
data.write(os);
|
||||
ps.setBytes(parameterIndex, os.toByteArray());
|
||||
} else {
|
||||
ps.setBlob(parameterIndex, (Blob) null);
|
||||
ps.setBytes(parameterIndex, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ public class JdbcInventory extends JdbcHelper implements Inventory {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<InventoryVector> getFullInventory(long... streams) {
|
||||
List<InventoryVector> result = new LinkedList<>();
|
||||
try (Connection connection = config.getConnection()) {
|
||||
@ -79,8 +80,8 @@ public class JdbcInventory extends JdbcHelper implements Inventory {
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT data, version FROM Inventory WHERE hash = X'" + vector + "'");
|
||||
if (rs.next()) {
|
||||
byte[] data = rs.getBytes("data");
|
||||
return Factory.getObjectMessage(rs.getInt("version"), new ByteArrayInputStream(data), data.length);
|
||||
Blob data = rs.getBlob("data");
|
||||
return Factory.getObjectMessage(rs.getInt("version"), data.getBinaryStream(), (int) data.length());
|
||||
} else {
|
||||
LOG.info("Object requested that we don't have. IV: " + vector);
|
||||
return null;
|
||||
@ -108,8 +109,8 @@ public class JdbcInventory extends JdbcHelper implements Inventory {
|
||||
ResultSet rs = stmt.executeQuery(query.toString());
|
||||
List<ObjectMessage> result = new LinkedList<>();
|
||||
while (rs.next()) {
|
||||
byte[] data = rs.getBytes("data");
|
||||
result.add(Factory.getObjectMessage(rs.getInt("version"), new ByteArrayInputStream(data), data.length));
|
||||
Blob data = rs.getBlob("data");
|
||||
result.add(Factory.getObjectMessage(rs.getInt("version"), data.getBinaryStream(), (int) data.length()));
|
||||
}
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
|
@ -27,6 +27,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@ -107,9 +108,9 @@ public class JdbcMessageRepository extends JdbcHelper implements MessageReposito
|
||||
ResultSet rs = stmt.executeQuery("SELECT id, iv, type, sender, recipient, data, sent, received, status FROM Message WHERE " + where);
|
||||
while (rs.next()) {
|
||||
byte[] iv = rs.getBytes("iv");
|
||||
byte[] data = rs.getBytes("data");
|
||||
InputStream data = rs.getBinaryStream("data");
|
||||
Plaintext.Type type = Plaintext.Type.valueOf(rs.getString("type"));
|
||||
Plaintext.Builder builder = Plaintext.readWithoutSignature(type, new ByteArrayInputStream(data));
|
||||
Plaintext.Builder builder = Plaintext.readWithoutSignature(type, data);
|
||||
long id = rs.getLong("id");
|
||||
builder.id(id);
|
||||
builder.IV(new InventoryVector(iv));
|
||||
@ -191,7 +192,8 @@ public class JdbcMessageRepository extends JdbcHelper implements MessageReposito
|
||||
|
||||
private void insert(Connection connection, Plaintext message) throws SQLException, IOException {
|
||||
PreparedStatement ps = connection.prepareStatement(
|
||||
"INSERT INTO Message (iv, type, sender, recipient, data, sent, received, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);
|
||||
"INSERT INTO Message (iv, type, sender, recipient, data, sent, received, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
Statement.RETURN_GENERATED_KEYS);
|
||||
ps.setBytes(1, message.getInventoryVector() != null ? message.getInventoryVector().getHash() : null);
|
||||
ps.setString(2, message.getType().name());
|
||||
ps.setString(3, message.getFrom().getAddress());
|
||||
|
@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015 Christian Basler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ch.dissem.bitmessage.repository;
|
||||
|
||||
import ch.dissem.bitmessage.entity.valueobject.NetworkAddress;
|
||||
import ch.dissem.bitmessage.ports.NodeRegistry;
|
||||
import ch.dissem.bitmessage.utils.UnixTime;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static ch.dissem.bitmessage.utils.Collections.selectRandom;
|
||||
import static ch.dissem.bitmessage.utils.UnixTime.HOUR;
|
||||
import static java.util.Collections.newSetFromMap;
|
||||
|
||||
public class MemoryNodeRegistry implements NodeRegistry {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MemoryNodeRegistry.class);
|
||||
|
||||
private final Map<Long, Set<NetworkAddress>> stableNodes = new HashMap<>();
|
||||
private final Map<Long, Set<NetworkAddress>> knownNodes = new ConcurrentHashMap<>();
|
||||
|
||||
public MemoryNodeRegistry() {
|
||||
try (InputStream in = getClass().getClassLoader().getResourceAsStream("nodes.txt")) {
|
||||
Scanner scanner = new Scanner(in);
|
||||
long stream = 0;
|
||||
Set<NetworkAddress> streamSet = null;
|
||||
while (scanner.hasNext()) {
|
||||
try {
|
||||
String line = scanner.nextLine().trim();
|
||||
if (line.startsWith("#") || line.isEmpty()) {
|
||||
// Ignore
|
||||
continue;
|
||||
}
|
||||
if (line.startsWith("[stream")) {
|
||||
stream = Long.parseLong(line.substring(8, line.lastIndexOf(']')));
|
||||
streamSet = new HashSet<>();
|
||||
stableNodes.put(stream, streamSet);
|
||||
} else if (streamSet != null) {
|
||||
int portIndex = line.lastIndexOf(':');
|
||||
InetAddress inetAddress = InetAddress.getByName(line.substring(0, portIndex));
|
||||
int port = Integer.valueOf(line.substring(portIndex + 1));
|
||||
streamSet.add(new NetworkAddress.Builder().ip(inetAddress).port(port).stream(stream).build());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.warn(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NetworkAddress> getKnownAddresses(int limit, long... streams) {
|
||||
List<NetworkAddress> result = new LinkedList<>();
|
||||
for (long stream : streams) {
|
||||
Set<NetworkAddress> known = knownNodes.get(stream);
|
||||
if (known != null && !known.isEmpty()) {
|
||||
for (NetworkAddress node : known) {
|
||||
if (node.getTime() > UnixTime.now(-3 * HOUR)) {
|
||||
result.add(node);
|
||||
} else {
|
||||
known.remove(node);
|
||||
}
|
||||
}
|
||||
} else if (stableNodes.containsKey(stream)) {
|
||||
// To reduce load on stable nodes, only return one
|
||||
result.add(selectRandom(stableNodes.get(stream)));
|
||||
}
|
||||
}
|
||||
return selectRandom(limit, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void offerAddresses(List<NetworkAddress> addresses) {
|
||||
for (NetworkAddress node : addresses) {
|
||||
if (node.getTime() <= UnixTime.now()) {
|
||||
if (!knownNodes.containsKey(node.getStream())) {
|
||||
synchronized (knownNodes) {
|
||||
if (!knownNodes.containsKey(node.getStream())) {
|
||||
knownNodes.put(
|
||||
node.getStream(),
|
||||
newSetFromMap(new ConcurrentHashMap<NetworkAddress, Boolean>())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node.getTime() <= UnixTime.now()) {
|
||||
// TODO: This isn't quite correct
|
||||
// If the node is already known, the one with the more recent time should be used
|
||||
knownNodes.get(node.getStream()).add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
[stream 1]
|
||||
|
||||
[2604:2000:1380:9f:82e:148b:2746:d0c7]:8080
|
||||
5.45.99.75:8444
|
||||
75.167.159.54:8444
|
||||
95.165.168.168:8444
|
||||
85.180.139.241:8444
|
||||
158.222.211.81:8080
|
||||
178.62.12.187:8448
|
||||
24.188.198.204:8111
|
||||
109.147.204.113:1195
|
||||
178.11.46.221:8444
|
||||
|
||||
[stream 2]
|
||||
# none yet
|
@ -17,6 +17,7 @@
|
||||
package ch.dissem.bitmessage.repository;
|
||||
|
||||
import ch.dissem.bitmessage.entity.valueobject.NetworkAddress;
|
||||
import ch.dissem.bitmessage.ports.MemoryNodeRegistry;
|
||||
import ch.dissem.bitmessage.ports.NodeRegistry;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
Reference in New Issue
Block a user