/** * Creates {@link Packet} of type {@link PacketTypes#DATA} and sends it to network, initiates retransmission. * It is normal data sending procedure when {@link Session} with remote node is already established. * @param session {@link Session} with remote node * @param payload data to send */ private void sendPayload(Session session, byte[] payload) { byte[] dataToSend = preparePayloadForSession(session.sessionKey, payload); Packet packet = new Packet(getNextPacketId(), myNodeInfo.getNumber(), session.remoteNodeInfo.getNumber(), PacketTypes.DATA, dataToSend); sendPacket(session.remoteNodeInfo, packet); session.addPacketToRetransmitMap(packet.packetId, packet, payload); }
/** * We have sent {@link PacketTypes#HELLO} typed {@link Packet}, * and have got {@link PacketTypes#WELCOME} typed {@link Packet} - it means we can continue handshake and send * request for session's keys. KEY_REQ's payload is more than 512 bytes, so used two parts here. * @param session is {@link Session} in which sending is. * @param payloadPart1 is prepared in {@link SocketListenThread#onReceiveWelcome(Packet)} * @param payloadPart2 is prepared in {@link SocketListenThread#onReceiveWelcome(Packet)} */ private void sendKeyReq(Session session, byte[] payloadPart1, byte[] payloadPart2) throws EncryptionError { report(logLabel, ()->"send key_req to "+session.remoteNodeInfo.getNumber(), VerboseLevel.BASE); Packet packet1 = new Packet(getNextPacketId(), myNodeInfo.getNumber(), session.remoteNodeInfo.getNumber(), PacketTypes.KEY_REQ_PART1, payloadPart1); Packet packet2 = new Packet(getNextPacketId(), myNodeInfo.getNumber(), session.remoteNodeInfo.getNumber(), PacketTypes.KEY_REQ_PART2, payloadPart2); sendPacket(session.remoteNodeInfo, packet1); sendPacket(session.remoteNodeInfo, packet2); session.addPacketToRetransmitMap(packet1.packetId, packet1, payloadPart1); session.addPacketToRetransmitMap(packet2.packetId, packet2, payloadPart2); }
/** * Someone who sent {@link PacketTypes#HELLO} typed {@link Packet}, * send us new KEY_REQ typed {@link Packet} - if all is ok we send session keys to. * SESSION's payload is more than 512 bytes, so used two parts here. * From now we ready to data exchange. * @param sessionReader is {@link SessionReader} in which sending is. */ private void sendSessionKey(SessionReader sessionReader) throws EncryptionError { report(logLabel, ()->"send session_key to "+sessionReader.remoteNodeInfo.getNumber(), VerboseLevel.BASE); List data = Arrays.asList(sessionReader.sessionKey.getKey(), sessionReader.remoteNonce); byte[] packed = Boss.pack(data); byte[] encrypted = new PublicKey(sessionReader.remoteNodeInfo.getPublicKey().pack()).encrypt(packed); byte[] sign = new PrivateKey(ownPrivateKey.pack()).sign(encrypted, HashType.SHA512); Packet packet1 = new Packet(getNextPacketId(), myNodeInfo.getNumber(), sessionReader.remoteNodeInfo.getNumber(), PacketTypes.SESSION_PART1, encrypted); Packet packet2 = new Packet(getNextPacketId(), myNodeInfo.getNumber(), sessionReader.remoteNodeInfo.getNumber(), PacketTypes.SESSION_PART2, sign); sendPacket(sessionReader.remoteNodeInfo, packet1); sendPacket(sessionReader.remoteNodeInfo, packet2); sessionReader.addPacketToRetransmitMap(packet1.packetId, packet1, encrypted); sessionReader.addPacketToRetransmitMap(packet2.packetId, packet2, sign); }
/** * When someone send us {@link PacketTypes#HELLO} typed {@link UDPAdapter.Packet}, * we should respond with {@link PacketTypes#WELCOME}. * @param sessionReader is {@link UDPAdapter.SessionReader} in which sending is. */ private void sendWelcome(SessionReader sessionReader) { try { report(logLabel, () -> "send welcome to " + sessionReader.remoteNodeInfo.getNumber(), VerboseLevel.BASE); byte[] data = sessionReader.localNonce; byte[] sign = new PrivateKey(ownPrivateKey.pack()).sign(data, HashType.SHA512); byte[] payload = Boss.dumpToArray(Arrays.asList(data, sign)); Packet packet = new Packet(getNextPacketId(), myNodeInfo.getNumber(), sessionReader.remoteNodeInfo.getNumber(), PacketTypes.WELCOME, payload); sendPacket(sessionReader.remoteNodeInfo, packet); sessionReader.removeHandshakePacketsFromRetransmitMap(); sessionReader.addPacketToRetransmitMap(packet.packetId, packet, sessionReader.localNonce); } catch (EncryptionError e) { callErrorCallbacks("(sendWelcome) EncryptionError: " + e); } }
/** * This is first step of creation and installation of the session. * @param session is {@link Session} in which sending is. */ private void sendHello(Session session) { try { report(logLabel, () -> "send hello to " + session.remoteNodeInfo.getNumber(), VerboseLevel.BASE); byte[] helloNonce = Do.randomBytes(64); Packet packet = new Packet(getNextPacketId(), myNodeInfo.getNumber(), session.remoteNodeInfo.getNumber(), PacketTypes.HELLO, new PublicKey(session.remoteNodeInfo.getPublicKey().pack()).encrypt(helloNonce)); sendPacket(session.remoteNodeInfo, packet); session.addPacketToRetransmitMap(packet.packetId, packet, helloNonce); } catch (EncryptionError e) { callErrorCallbacks("(sendHello) EncryptionError: " + e); } }