diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/DataSerializer.kt b/app/src/main/java/io/github/chronosx88/influence/helpers/DataSerializer.kt index be74217..67a3bd4 100644 --- a/app/src/main/java/io/github/chronosx88/influence/helpers/DataSerializer.kt +++ b/app/src/main/java/io/github/chronosx88/influence/helpers/DataSerializer.kt @@ -5,32 +5,31 @@ import com.sleepycat.bind.EntryBinding import com.sleepycat.je.DatabaseEntry import io.netty.buffer.Unpooled import net.tomp2p.connection.SignatureFactory -import net.tomp2p.storage.AlternativeCompositeByteBuf import net.tomp2p.storage.Data -import org.mapdb.DataInput2 import java.io.* import java.nio.ByteBuffer import java.security.InvalidKeyException import java.security.SignatureException -class DataSerializerEx(private val signatureFactory: SignatureFactory) : EntryBinding, Serializable { - private val LOG_TAG = "DataSerializerEx" + +class DataSerializer(private val signatureFactory: SignatureFactory) : EntryBinding, Serializable { + private val LOG_TAG = "DataSerializer" override fun entryToObject(databaseEntry: DatabaseEntry): Data? { if (databaseEntry.data == null) { return null } - val inputStream = ByteArrayInputStream(databaseEntry.data) + val dataInput = DataInputStream(ByteArrayInputStream(databaseEntry.data)) var buf = Unpooled.buffer() var data: Data? = null while (data == null) { - buf.writeByte(inputStream.read()) + buf.writeByte(dataInput.read()) data = Data.decodeHeader(buf, signatureFactory) } val len = data.length() var me = ByteArray(len) try { - inputStream.read(me) + dataInput.read(me) } catch (e: IOException) { e.printStackTrace() } @@ -40,37 +39,42 @@ class DataSerializerEx(private val signatureFactory: SignatureFactory) : EntryBi if (!retVal) { Log.e(LOG_TAG, "# ERROR: Data could not be deserialized!") } - val dataInput = DataInputStream(inputStream) - me = ByteArray(signatureFactory.signatureSize()) - dataInput.readFully(me) - buf = Unpooled.wrappedBuffer(me) + if (data.isSigned) { + me = ByteArray(signatureFactory.signatureSize()) + dataInput.readFully(me) + buf = Unpooled.wrappedBuffer(me) + } retVal = data.decodeDone(buf, signatureFactory); if(!retVal) { - throw IOException("signature could not be read") + throw IOException("Signature could not be read!") } return data } override fun objectToEntry(data: Data, databaseEntry: DatabaseEntry) { - val out = ByteArrayOutputStream() - val acb = AlternativeCompositeByteBuf.compBuffer(AlternativeCompositeByteBuf.UNPOOLED_HEAP) + val baos = ByteArrayOutputStream() + val out = DataOutputStream(baos) + val acb = Unpooled.buffer() + // store data to disk + // header first + data.encodeHeader(acb, signatureFactory) + writeData(out, acb.nioBuffers()) + acb.skipBytes(acb.writerIndex()) + // next data - no need to copy to another buffer, just take the data + // from memory + writeData(out, data.toByteBuffers()) + // rest try { - // header first - data.encodeHeader(acb, signatureFactory) + data.encodeDone(acb, signatureFactory) writeData(out, acb.nioBuffers()) - acb.skipBytes(acb.writerIndex()) - // next data - no need to copy to another buffer, just take the data - // from memory - writeData(out, data.toByteBuffers()) - } catch (e: SignatureException) { - e.printStackTrace() } catch (e: InvalidKeyException) { - e.printStackTrace() - } catch (e: IOException) { - e.printStackTrace() + throw IOException(e) + } catch (e: SignatureException) { + throw IOException(e) } - - databaseEntry.data = out.toByteArray() + out.flush() + databaseEntry.data = baos.toByteArray() + out.close() } @Throws(IOException::class) diff --git a/app/src/main/java/io/github/chronosx88/influence/logic/MainLogic.java b/app/src/main/java/io/github/chronosx88/influence/logic/MainLogic.java index d7f8b95..91a4532 100644 --- a/app/src/main/java/io/github/chronosx88/influence/logic/MainLogic.java +++ b/app/src/main/java/io/github/chronosx88/influence/logic/MainLogic.java @@ -9,6 +9,8 @@ import com.google.gson.JsonObject; import net.tomp2p.connection.Bindings; import net.tomp2p.connection.ChannelClientConfiguration; +import net.tomp2p.connection.ChannelServerConfiguration; +import net.tomp2p.connection.Ports; import net.tomp2p.connection.RSASignatureFactory; import net.tomp2p.dht.PeerBuilderDHT; import net.tomp2p.dht.PeerDHT; @@ -21,9 +23,7 @@ import net.tomp2p.p2p.PeerBuilder; import net.tomp2p.peers.Number160; import net.tomp2p.peers.PeerAddress; import net.tomp2p.relay.tcp.TCPRelayClientConfig; -import net.tomp2p.replication.AutoReplication; import net.tomp2p.replication.IndirectReplication; -import net.tomp2p.replication.Replication; import net.tomp2p.storage.Data; import java.io.IOException; @@ -89,6 +89,7 @@ public class MainLogic implements CoreContracts.IMainLogicContract { new PeerBuilder(peerID) .ports(7243) .channelClientConfiguration(createChannelClientConfig()) + .channelServerConfiguration(createChannelServerConfig()) .start() ) .storage(storageBerkeleyDB) @@ -257,7 +258,7 @@ public class MainLogic implements CoreContracts.IMainLogicContract { } catch (IOException e) { e.printStackTrace(); } - Log.i(LOG_TAG, P2PUtils.put(AppHelper.getPeerID() + "_profile", null, serializedUserProfile) ? "# Profile successfully published!" : "# Profile publishing failed!"); + Log.i(LOG_TAG, P2PUtils.put(AppHelper.getPeerID() + "_profile", null, serializedUserProfile, mainKeyPair) ? "# Profile successfully published!" : "# Profile publishing failed!"); } private ChannelClientConfiguration createChannelClientConfig() { @@ -273,4 +274,17 @@ public class MainLogic implements CoreContracts.IMainLogicContract { channelClientConfiguration.byteBufPool(false); return channelClientConfiguration; } + + private ChannelServerConfiguration createChannelServerConfig() { + ChannelServerConfiguration channelServerConfiguration = new ChannelServerConfiguration(); + channelServerConfiguration.bindings(new Bindings()); + //these two values may be overwritten in the peer builder + channelServerConfiguration.ports(new Ports(Ports.DEFAULT_PORT, Ports.DEFAULT_PORT)); + channelServerConfiguration.portsForwarding(new Ports(Ports.DEFAULT_PORT, Ports.DEFAULT_PORT)); + channelServerConfiguration.behindFirewall(false); + channelServerConfiguration.pipelineFilter(new PeerBuilder.DefaultPipelineFilter()); + channelServerConfiguration.signatureFactory(new RSASignatureFactory()); + channelServerConfiguration.byteBufPool(false); + return channelServerConfiguration; + } } diff --git a/app/src/main/java/io/github/chronosx88/influence/logic/SettingsLogic.kt b/app/src/main/java/io/github/chronosx88/influence/logic/SettingsLogic.kt index a64a28d..da08ee9 100644 --- a/app/src/main/java/io/github/chronosx88/influence/logic/SettingsLogic.kt +++ b/app/src/main/java/io/github/chronosx88/influence/logic/SettingsLogic.kt @@ -23,24 +23,27 @@ class SettingsLogic : CoreContracts.ISettingsLogic { fun publishUsername(oldUsername: String?, username: String?) { val mainKeyPair = keyPairManager.openMainKeyPair() - if(oldUsername != null || !oldUsername.equals("")) { - P2PUtils.remove(oldUsername, null, mainKeyPair) + oldUsername?.let { + if(!oldUsername.equals("")) { + P2PUtils.remove(oldUsername, null, mainKeyPair) + } } - if (username.equals("") || username == null) { + username?.let { + var data: Data? = null + try { + data = Data(AppHelper.getPeerID()) + } catch (e: IOException) { + e.printStackTrace() + } + + data!!.protectEntry(mainKeyPair) + + val isSuccess = P2PUtils.put(username, null, data, mainKeyPair) + Log.i(LOG_TAG, if (isSuccess) "Username $username is published!" else "Username $username isn't published!") + } ?: run { return } - var data: Data? = null - try { - data = Data(AppHelper.getPeerID()) - } catch (e: IOException) { - e.printStackTrace() - } - - data!!.protectEntry(mainKeyPair) - - val isSuccess = P2PUtils.put(username, null, data, mainKeyPair) - Log.i(LOG_TAG, if (isSuccess) "Username $username is published!" else "Username $username isn't published!") } } } \ No newline at end of file