Search in sources :

Example 6 with VersionedDataInputStream

use of org.apache.geode.internal.VersionedDataInputStream in project geode by apache.

the class JGroupsMessenger method readJGMessage.

/**
   * deserialize a jgroups payload. If it's a DistributionMessage find the ID of the sender and
   * establish it as the message's sender
   */
Object readJGMessage(Message jgmsg) {
    Object result = null;
    int messageLength = jgmsg.getLength();
    if (logger.isTraceEnabled()) {
        logger.trace("deserializing a message of length " + messageLength);
    }
    if (messageLength == 0) {
        // jgroups messages with no payload are used for protocol interchange, such
        // as STABLE_GOSSIP
        logger.trace("message length is zero - ignoring");
        return null;
    }
    Exception problem = null;
    byte[] buf = jgmsg.getRawBuffer();
    try {
        long start = services.getStatistics().startMsgDeserialization();
        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(buf, jgmsg.getOffset(), jgmsg.getLength()));
        short ordinal = Version.readOrdinal(dis);
        if (ordinal < Version.CURRENT_ORDINAL) {
            dis = new VersionedDataInputStream(dis, Version.fromOrdinalNoThrow(ordinal, true));
        }
        // read
        boolean isEncrypted = dis.readBoolean();
        if (isEncrypted && encrypt == null) {
            throw new GemFireConfigException("Got remote message as encrypted");
        }
        if (isEncrypted) {
            result = readEncryptedMessage(dis, ordinal, encrypt);
        } else {
            result = deserializeMessage(dis, ordinal);
        }
        services.getStatistics().endMsgDeserialization(start);
    } catch (ClassNotFoundException | IOException | RuntimeException e) {
        problem = e;
    } catch (Exception e) {
        problem = e;
    }
    if (problem != null) {
        logger.error(LocalizedMessage.create(LocalizedStrings.GroupMembershipService_EXCEPTION_DESERIALIZING_MESSAGE_PAYLOAD_0, jgmsg), problem);
        return null;
    }
    return result;
}
Also used : GemFireIOException(org.apache.geode.GemFireIOException) IOException(java.io.IOException) VersionedDataInputStream(org.apache.geode.internal.VersionedDataInputStream) DataInputStream(java.io.DataInputStream) MemberShunnedException(org.apache.geode.internal.tcp.MemberShunnedException) DistributedSystemDisconnectedException(org.apache.geode.distributed.DistributedSystemDisconnectedException) InvocationTargetException(java.lang.reflect.InvocationTargetException) ForcedDisconnectException(org.apache.geode.ForcedDisconnectException) GemFireIOException(org.apache.geode.GemFireIOException) SystemConnectException(org.apache.geode.SystemConnectException) GemFireConfigException(org.apache.geode.GemFireConfigException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) ByteArrayInputStream(java.io.ByteArrayInputStream) GemFireConfigException(org.apache.geode.GemFireConfigException) VersionedDataInputStream(org.apache.geode.internal.VersionedDataInputStream)

Example 7 with VersionedDataInputStream

use of org.apache.geode.internal.VersionedDataInputStream in project geode by apache.

the class JGroupsMessenger method readEncryptedMessage.

@SuppressWarnings("resource")
DistributionMessage readEncryptedMessage(DataInputStream dis, short ordinal, GMSEncrypt encryptLocal) throws Exception {
    int dfsid = InternalDataSerializer.readDSFIDHeader(dis);
    int requestId = dis.readInt();
    long start = services.getStatistics().startUDPMsgDecryption();
    try {
        logger.debug("readEncryptedMessage Reading Request id " + dfsid + " and requestid is " + requestId + " myid " + this.localAddress);
        InternalDistributedMember pkMbr = null;
        boolean readPK = false;
        switch(dfsid) {
            case FIND_COORDINATOR_REQ:
            case JOIN_REQUEST:
                readPK = true;
                break;
            case FIND_COORDINATOR_RESP:
            case JOIN_RESPONSE:
                // this will have requestId to know the PK
                pkMbr = getRequestedMember(requestId);
                break;
        }
        byte[] data;
        byte[] pk = null;
        if (readPK) {
            // need to read PK
            pk = InternalDataSerializer.readByteArray(dis);
            // encrypt.setPublicKey(publickey, mbr);
            data = InternalDataSerializer.readByteArray(dis);
            // using prefixed pk from sender
            data = encryptLocal.decryptData(data, pk);
        } else {
            data = InternalDataSerializer.readByteArray(dis);
            // from cluster key
            if (pkMbr != null) {
                // using member public key
                data = encryptLocal.decryptData(data, pkMbr);
            } else {
                // from cluster key
                data = encryptLocal.decryptData(data);
            }
        }
        {
            DataInputStream in = new DataInputStream(new ByteArrayInputStream(data));
            if (ordinal < Version.CURRENT_ORDINAL) {
                in = new VersionedDataInputStream(in, Version.fromOrdinalNoThrow(ordinal, true));
            }
            DistributionMessage result = deserializeMessage(in, ordinal);
            if (pk != null) {
                logger.info("Setting public key for " + result.getSender() + " len " + pk.length);
                setPublicKey(pk, result.getSender());
            }
            return result;
        }
    } catch (Exception e) {
        throw new Exception("Message id is " + dfsid, e);
    } finally {
        services.getStatistics().endUDPMsgDecryption(start);
    }
}
Also used : InternalDistributedMember(org.apache.geode.distributed.internal.membership.InternalDistributedMember) ByteArrayInputStream(java.io.ByteArrayInputStream) DistributionMessage(org.apache.geode.distributed.internal.DistributionMessage) HighPriorityDistributionMessage(org.apache.geode.distributed.internal.HighPriorityDistributionMessage) VersionedDataInputStream(org.apache.geode.internal.VersionedDataInputStream) DataInputStream(java.io.DataInputStream) VersionedDataInputStream(org.apache.geode.internal.VersionedDataInputStream) MemberShunnedException(org.apache.geode.internal.tcp.MemberShunnedException) DistributedSystemDisconnectedException(org.apache.geode.distributed.DistributedSystemDisconnectedException) InvocationTargetException(java.lang.reflect.InvocationTargetException) ForcedDisconnectException(org.apache.geode.ForcedDisconnectException) GemFireIOException(org.apache.geode.GemFireIOException) SystemConnectException(org.apache.geode.SystemConnectException) GemFireConfigException(org.apache.geode.GemFireConfigException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException)

Example 8 with VersionedDataInputStream

use of org.apache.geode.internal.VersionedDataInputStream in project geode by apache.

the class TcpClient method requestToServer.

/**
   * Send a request to a Locator
   * 
   * @param ipAddr The locator's inet socket address
   * @param request The request message
   * @param timeout Timeout for sending the message and receiving a reply
   * @param replyExpected Whether to wait for a reply
   *
   * @return The reply, or null if no reply is expected
   *
   * @throws IOException
   * @throws ClassNotFoundException
   */
public Object requestToServer(InetSocketAddress ipAddr, Object request, int timeout, boolean replyExpected) throws IOException, ClassNotFoundException {
    /*
     * InetSocketAddress ipAddr; if (addr == null) { ipAddr = new InetSocketAddress(port); } else {
     * ipAddr = new InetSocketAddress(addr, port); // fix for bug 30810 }
     */
    long giveupTime = System.currentTimeMillis() + timeout;
    // Get the GemFire version of the TcpServer first, before sending any other request.
    short serverVersion = getServerVersion(ipAddr, timeout).shortValue();
    if (serverVersion > Version.CURRENT_ORDINAL) {
        serverVersion = Version.CURRENT_ORDINAL;
    }
    // establish the old GossipVersion for the server
    int gossipVersion = TcpServer.getCurrentGossipVersion();
    if (Version.GFE_71.compareTo(serverVersion) > 0) {
        gossipVersion = TcpServer.getOldGossipVersion();
    }
    long newTimeout = giveupTime - System.currentTimeMillis();
    if (newTimeout <= 0) {
        return null;
    }
    logger.debug("TcpClient sending {} to {}", request, ipAddr);
    Socket sock = socketCreator.connect(ipAddr.getAddress(), ipAddr.getPort(), (int) newTimeout, null, false);
    sock.setSoTimeout((int) newTimeout);
    DataOutputStream out = null;
    try {
        out = new DataOutputStream(sock.getOutputStream());
        if (serverVersion < Version.CURRENT_ORDINAL) {
            out = new VersionedDataOutputStream(out, Version.fromOrdinalNoThrow(serverVersion, false));
        }
        out.writeInt(gossipVersion);
        if (gossipVersion > TcpServer.getOldGossipVersion()) {
            out.writeShort(serverVersion);
        }
        DataSerializer.writeObject(request, out);
        out.flush();
        if (replyExpected) {
            DataInputStream in = new DataInputStream(sock.getInputStream());
            in = new VersionedDataInputStream(in, Version.fromOrdinal(serverVersion, false));
            try {
                Object response = DataSerializer.readObject(in);
                logger.debug("received response: {}", response);
                return response;
            } catch (EOFException ex) {
                EOFException eof = new EOFException("Locator at " + ipAddr + " did not respond. This is normal if the locator was shutdown. If it wasn't check its log for exceptions.");
                eof.initCause(ex);
                throw eof;
            }
        } else {
            return null;
        }
    } catch (UnsupportedVersionException ex) {
        if (logger.isDebugEnabled()) {
            logger.debug("Remote TcpServer version: " + serverVersion + " is higher than local version: " + Version.CURRENT_ORDINAL + ". This is never expected as remoteVersion");
        }
        return null;
    } finally {
        try {
            if (replyExpected) {
                // the locator's machine.
                if (!sock.isClosed() && !socketCreator.useSSL()) {
                    sock.setSoLinger(true, 0);
                }
            }
            sock.close();
        } catch (Exception e) {
            logger.error("Error closing socket ", e);
        }
        if (out != null) {
            out.close();
        }
    }
}
Also used : DataOutputStream(java.io.DataOutputStream) VersionedDataOutputStream(org.apache.geode.internal.VersionedDataOutputStream) VersionedDataOutputStream(org.apache.geode.internal.VersionedDataOutputStream) EOFException(java.io.EOFException) DataInputStream(java.io.DataInputStream) VersionedDataInputStream(org.apache.geode.internal.VersionedDataInputStream) Socket(java.net.Socket) VersionedDataInputStream(org.apache.geode.internal.VersionedDataInputStream) SSLHandshakeException(javax.net.ssl.SSLHandshakeException) IOException(java.io.IOException) EOFException(java.io.EOFException) SSLException(javax.net.ssl.SSLException) UnsupportedVersionException(org.apache.geode.cache.UnsupportedVersionException) UnsupportedVersionException(org.apache.geode.cache.UnsupportedVersionException)

Example 9 with VersionedDataInputStream

use of org.apache.geode.internal.VersionedDataInputStream in project geode by apache.

the class TcpServer method processRequest.

/**
   * fix for bug 33711 - client requests are spun off to another thread for processing. Requests are
   * synchronized in processGossip.
   */
private void processRequest(final Socket sock) {
    executor.execute(() -> {
        long startTime = DistributionStats.getStatTime();
        DataInputStream input = null;
        Object request, response;
        try {
            socketCreator.configureServerSSLSocket(sock);
            sock.setSoTimeout(READ_TIMEOUT);
            try {
                input = new DataInputStream(sock.getInputStream());
            } catch (StreamCorruptedException e) {
                // Some garbage can be left on the socket stream
                // if a peer disappears at exactly the wrong moment.
                log.debug("Discarding illegal request from " + (sock.getInetAddress().getHostAddress() + ":" + sock.getPort()), e);
                return;
            }
            int gossipVersion = readGossipVersion(sock, input);
            short versionOrdinal;
            if (gossipVersion <= getCurrentGossipVersion() && GOSSIP_TO_GEMFIRE_VERSION_MAP.containsKey(gossipVersion)) {
                // Create a versioned stream to remember sender's GemFire version
                versionOrdinal = (short) GOSSIP_TO_GEMFIRE_VERSION_MAP.get(gossipVersion);
            } else {
                // Close the socket. We can not accept requests from a newer version
                try {
                    sock.getOutputStream().write("unknown protocol version".getBytes());
                    sock.getOutputStream().flush();
                } catch (IOException e) {
                    log.debug("exception in sending reply to process using unknown protocol " + gossipVersion, e);
                }
                sock.close();
                return;
            }
            if (Version.GFE_71.compareTo(versionOrdinal) <= 0) {
                // Recent versions of TcpClient will send the version ordinal
                versionOrdinal = input.readShort();
            }
            if (log.isDebugEnabled() && versionOrdinal != Version.CURRENT_ORDINAL) {
                log.debug("Locator reading request from " + sock.getInetAddress() + " with version " + Version.fromOrdinal(versionOrdinal, false));
            }
            input = new VersionedDataInputStream(input, Version.fromOrdinal(versionOrdinal, false));
            request = DataSerializer.readObject(input);
            if (log.isDebugEnabled()) {
                log.debug("Locator received request " + request + " from " + sock.getInetAddress());
            }
            if (request instanceof ShutdownRequest) {
                shuttingDown = true;
                // Don't call shutdown from within the worker thread, see java bug #6576792.
                // Closing the socket will cause our acceptor thread to shutdown the executor
                this.serverSocketPortAtClose = srv_sock.getLocalPort();
                srv_sock.close();
                response = new ShutdownResponse();
            } else if (request instanceof InfoRequest) {
                response = handleInfoRequest(request);
            } else if (request instanceof VersionRequest) {
                response = handleVersionRequest(request);
            } else {
                response = handler.processRequest(request);
            }
            handler.endRequest(request, startTime);
            startTime = DistributionStats.getStatTime();
            if (response != null) {
                DataOutputStream output = new DataOutputStream(sock.getOutputStream());
                if (versionOrdinal != Version.CURRENT_ORDINAL) {
                    output = new VersionedDataOutputStream(output, Version.fromOrdinal(versionOrdinal, false));
                }
                DataSerializer.writeObject(response, output);
                output.flush();
            }
            handler.endResponse(request, startTime);
        } catch (EOFException ignore) {
        // client went away - ignore
        } catch (CancelException ignore) {
        // ignore
        } catch (ClassNotFoundException ex) {
            String sender = null;
            if (sock != null) {
                sender = sock.getInetAddress().getHostAddress();
            }
            log.info("Unable to process request from " + sender + " exception=" + ex.getMessage());
        } catch (Exception ex) {
            String sender = null;
            if (sock != null) {
                sender = sock.getInetAddress().getHostAddress();
            }
            if (ex instanceof IOException) {
                // log with severe.
                if (!sock.isClosed()) {
                    log.info("Exception in processing request from " + sender, ex);
                }
            } else {
                log.fatal("Exception in processing request from " + sender, ex);
            }
        } catch (VirtualMachineError err) {
            SystemFailure.initiateFailure(err);
            throw err;
        } catch (Throwable ex) {
            SystemFailure.checkFailure();
            String sender = null;
            if (sock != null) {
                sender = sock.getInetAddress().getHostAddress();
            }
            try {
                log.fatal("Exception in processing request from " + sender, ex);
            } catch (VirtualMachineError err) {
                SystemFailure.initiateFailure(err);
                throw err;
            } catch (Throwable t) {
                SystemFailure.checkFailure();
                t.printStackTrace();
            }
        } finally {
            try {
                sock.close();
            } catch (IOException ignore) {
            // ignore
            }
        }
    });
}
Also used : DataOutputStream(java.io.DataOutputStream) VersionedDataOutputStream(org.apache.geode.internal.VersionedDataOutputStream) IOException(java.io.IOException) DataInputStream(java.io.DataInputStream) VersionedDataInputStream(org.apache.geode.internal.VersionedDataInputStream) CancelException(org.apache.geode.CancelException) StreamCorruptedException(java.io.StreamCorruptedException) IOException(java.io.IOException) EOFException(java.io.EOFException) SSLException(javax.net.ssl.SSLException) VersionedDataOutputStream(org.apache.geode.internal.VersionedDataOutputStream) EOFException(java.io.EOFException) StreamCorruptedException(java.io.StreamCorruptedException) CancelException(org.apache.geode.CancelException) VersionedDataInputStream(org.apache.geode.internal.VersionedDataInputStream)

Example 10 with VersionedDataInputStream

use of org.apache.geode.internal.VersionedDataInputStream in project geode by apache.

the class ClientCacheFactoryJUnitTest method testOldClientIDDeserialization.

@Test
public void testOldClientIDDeserialization() throws Exception {
    // during a HandShake a clientID is read w/o knowing the client's
    // version
    cc = new ClientCacheFactory().create();
    GemFireCacheImpl gfc = (GemFireCacheImpl) cc;
    InternalDistributedMember memberID = (InternalDistributedMember) cc.getDistributedSystem().getDistributedMember();
    GMSMember gmsID = (GMSMember) memberID.getNetMember();
    memberID.setVersionObjectForTest(Version.GFE_82);
    assertEquals(Version.GFE_82, memberID.getVersionObject());
    ClientProxyMembershipID clientID = ClientProxyMembershipID.getClientId(memberID);
    HeapDataOutputStream out = new HeapDataOutputStream(Version.GFE_82);
    DataSerializer.writeObject(clientID, out);
    DataInputStream in = new VersionedDataInputStream(new ByteArrayInputStream(out.toByteArray()), Version.CURRENT);
    ClientProxyMembershipID newID = DataSerializer.readObject(in);
    InternalDistributedMember newMemberID = (InternalDistributedMember) newID.getDistributedMember();
    assertEquals(Version.GFE_82, newMemberID.getVersionObject());
    assertEquals(Version.GFE_82, newID.getClientVersion());
    GMSMember newGmsID = (GMSMember) newMemberID.getNetMember();
    assertEquals(0, newGmsID.getUuidLSBs());
    assertEquals(0, newGmsID.getUuidMSBs());
    gmsID.setUUID(new UUID(1234l, 5678l));
    memberID.setVersionObjectForTest(Version.CURRENT);
    clientID = ClientProxyMembershipID.getClientId(memberID);
    out = new HeapDataOutputStream(Version.CURRENT);
    DataSerializer.writeObject(clientID, out);
    in = new VersionedDataInputStream(new ByteArrayInputStream(out.toByteArray()), Version.CURRENT);
    newID = DataSerializer.readObject(in);
    newMemberID = (InternalDistributedMember) newID.getDistributedMember();
    assertEquals(Version.CURRENT, newMemberID.getVersionObject());
    assertEquals(Version.CURRENT, newID.getClientVersion());
    newGmsID = (GMSMember) newMemberID.getNetMember();
    assertEquals(gmsID.getUuidLSBs(), newGmsID.getUuidLSBs());
    assertEquals(gmsID.getUuidMSBs(), newGmsID.getUuidMSBs());
}
Also used : ClientProxyMembershipID(org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID) InternalDistributedMember(org.apache.geode.distributed.internal.membership.InternalDistributedMember) ByteArrayInputStream(java.io.ByteArrayInputStream) GMSMember(org.apache.geode.distributed.internal.membership.gms.GMSMember) HeapDataOutputStream(org.apache.geode.internal.HeapDataOutputStream) GemFireCacheImpl(org.apache.geode.internal.cache.GemFireCacheImpl) DataInputStream(java.io.DataInputStream) VersionedDataInputStream(org.apache.geode.internal.VersionedDataInputStream) UUID(org.jgroups.util.UUID) VersionedDataInputStream(org.apache.geode.internal.VersionedDataInputStream) ClientServerTest(org.apache.geode.test.junit.categories.ClientServerTest) Test(org.junit.Test) IntegrationTest(org.apache.geode.test.junit.categories.IntegrationTest)

Aggregations

VersionedDataInputStream (org.apache.geode.internal.VersionedDataInputStream)13 DataInputStream (java.io.DataInputStream)12 IOException (java.io.IOException)8 ByteArrayInputStream (java.io.ByteArrayInputStream)7 DataOutputStream (java.io.DataOutputStream)7 VersionedDataOutputStream (org.apache.geode.internal.VersionedDataOutputStream)7 HeapDataOutputStream (org.apache.geode.internal.HeapDataOutputStream)5 EOFException (java.io.EOFException)4 GemFireConfigException (org.apache.geode.GemFireConfigException)4 InternalDistributedMember (org.apache.geode.distributed.internal.membership.InternalDistributedMember)4 InputStream (java.io.InputStream)3 Socket (java.net.Socket)3 SSLException (javax.net.ssl.SSLException)3 UnsupportedVersionException (org.apache.geode.cache.UnsupportedVersionException)3 Version (org.apache.geode.internal.Version)3 AuthenticationRequiredException (org.apache.geode.security.AuthenticationRequiredException)3 Test (org.junit.Test)3 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 UnknownHostException (java.net.UnknownHostException)2 SSLHandshakeException (javax.net.ssl.SSLHandshakeException)2