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;
}
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);
}
}
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();
}
}
}
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
}
}
});
}
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());
}
Aggregations