use of im.actor.core.network.mtp.entity.ProtoStruct in project actor-platform by actorapp.
the class AuthKeyActor method onMessage.
private void onMessage(int connectionId, byte[] data, int offset, int len) {
if (connectionId != this.connectionId) {
Log.d(TAG, "Too old: ignoring");
return;
}
ProtoStruct protoStruct;
try {
DataInput dataInput = new DataInput(data, offset, len);
ProtoPackage protoPackage = new ProtoPackage(dataInput);
if (protoPackage.getAuthId() != 0) {
throw new IOException("AuthId != 0");
}
if (protoPackage.getSessionId() != 0) {
throw new IOException("Session != 0");
}
if (protoPackage.getPayload().getMessageId() != 0) {
throw new IOException("MessageId != 0");
}
protoStruct = ProtoSerializer.readMessagePayload(protoPackage.getPayload().getPayload());
} catch (IOException e) {
e.printStackTrace();
crashConnection();
return;
}
try {
if (currentState == null) {
throw new IOException();
}
currentState.onMessage(protoStruct);
} catch (Exception e) {
e.printStackTrace();
crashConnection();
}
}
use of im.actor.core.network.mtp.entity.ProtoStruct in project actor-platform by actorapp.
the class AuthKeyActor method gotoDHState.
private void gotoDHState(final long keyId, final byte[] key, final byte[] serverNonce) {
final byte[] clientNonce = new byte[32];
Crypto.nextBytes(clientNonce);
byte[] keyMaterial = new byte[32];
Crypto.nextBytes(keyMaterial);
final Curve25519KeyPair clientKeyPair = Curve25519.keyGen(keyMaterial);
goToState(new ActorState() {
@Override
public ProtoStruct sendStartMessage() throws IOException {
Log.d(TAG, "Sending RequestDH");
return new RequestDH(randomId, keyId, clientNonce, clientKeyPair.getPublicKey());
}
@Override
public void onMessage(ProtoStruct struct) throws IOException {
if (struct instanceof ResponseDoDH) {
Log.d(TAG, "Received ResponseDoDH");
ResponseDoDH r = (ResponseDoDH) struct;
if (r.getRandomId() != randomId) {
throw new IOException("Incorrect RandomId");
}
PRF combinedPrf = Cryptos.PRF_SHA_STREEBOG_256();
byte[] nonce = ByteStrings.merge(clientNonce, serverNonce);
byte[] pre_master_secret = Curve25519.calculateAgreement(clientKeyPair.getPrivateKey(), key);
byte[] master_secret = combinedPrf.calculate(pre_master_secret, "master secret", nonce, 256);
byte[] verify = combinedPrf.calculate(master_secret, "client finished", nonce, 256);
if (!Curve25519.verifySignature(key, verify, r.getVerifySign())) {
throw new IOException("Incorrect Signature");
}
Digest sha256 = Crypto.createSHA256();
sha256.update(master_secret, 0, master_secret.length);
byte[] authIdHash = new byte[32];
sha256.doFinal(authIdHash, 0);
long authId = ByteStrings.bytesToLong(authIdHash);
Log.d(TAG, "Key successfully created #" + authId);
gotoSuccess(master_secret, authId);
} else {
throw new IOException("Expected: ResponseGetServerKey, got: " + struct.getClass().getName());
}
}
});
}
use of im.actor.core.network.mtp.entity.ProtoStruct in project actor-platform by actorapp.
the class ReceiverActor method onReceive.
private void onReceive(ProtoMessage message) {
sender.send(new PusherActor.ReadPackageFromConnection());
boolean disableConfirm = false;
try {
if (receivedMessages.size() >= MAX_RECEIVED_BUFFER) {
receivedMessages.remove(0);
}
receivedMessages.add(message.getMessageId());
ProtoStruct obj;
try {
obj = ProtoSerializer.readMessagePayload(message.getPayload());
} catch (IOException e) {
Log.w(TAG, "Unable to parse message: ignoring");
e.printStackTrace();
return;
}
if (obj instanceof NewSessionCreated) {
NewSessionCreated newSessionCreated = (NewSessionCreated) obj;
sender.send(new PusherActor.NewSession(newSessionCreated.getMessageId()));
proto.getCallback().onSessionCreated();
} else if (obj instanceof Container) {
Container container = (Container) obj;
for (ProtoMessage m : container.getMessages()) {
self().send(m, sender());
}
} else if (obj instanceof SessionLost) {
sender.send(new PusherActor.SessionLost());
} else if (obj instanceof MTRpcResponse) {
MTRpcResponse responseBox = (MTRpcResponse) obj;
// Forget messages
sender.send(new PusherActor.ForgetMessage(responseBox.getMessageId(), true));
proto.getCallback().onRpcResponse(responseBox.getMessageId(), responseBox.getPayload());
} else if (obj instanceof MessageAck) {
MessageAck ack = (MessageAck) obj;
for (long ackMsgId : ack.messagesIds) {
sender.send(new PusherActor.ForgetMessage(ackMsgId, false));
}
} else if (obj instanceof MTPush) {
MTPush box = (MTPush) obj;
proto.getCallback().onUpdate(box.getPayload());
} else if (obj instanceof UnsentResponse) {
UnsentResponse unsent = (UnsentResponse) obj;
if (!receivedMessages.contains(unsent.getResponseMessageId())) {
disableConfirm = true;
sender.send(new PusherActor.SendMessage(MTUids.nextId(), new RequestResend(unsent.getMessageId()).toByteArray(), true));
}
} else if (obj instanceof UnsentMessage) {
UnsentMessage unsent = (UnsentMessage) obj;
if (!receivedMessages.contains(unsent.getMessageId())) {
disableConfirm = true;
sender.send(new PusherActor.SendMessage(MTUids.nextId(), new RequestResend(unsent.getMessageId()).toByteArray(), false));
}
} else if (obj instanceof AuthIdInvalid) {
proto.getCallback().onAuthKeyInvalidated(proto.getAuthId());
proto.stopProto();
} else {
Log.w(TAG, "Unsupported package " + obj);
}
} catch (Exception e) {
Log.w(TAG, "Parsing error");
} finally {
if (!disableConfirm) {
sender.send(new PusherActor.ConfirmMessage(message.getMessageId()));
}
}
}
use of im.actor.core.network.mtp.entity.ProtoStruct in project actor-platform by actorapp.
the class ApiBroker method processUpdate.
private void processUpdate(long authId, byte[] content) {
if (authId != currentAuthId) {
return;
}
ProtoStruct protoStruct;
try {
protoStruct = ProtoSerializer.readUpdate(content);
} catch (IOException e) {
e.printStackTrace();
Log.w(TAG, "Broken mt update");
return;
}
int type = ((Push) protoStruct).updateType;
byte[] body = ((Push) protoStruct).body;
RpcScope updateBox;
try {
updateBox = parserConfig.parseRpc(type, body);
} catch (IOException e) {
e.printStackTrace();
Log.w(TAG, "Broken update box");
return;
}
// Log.w(TAG, "Box: " + updateBox + "");
callback.onUpdateReceived(updateBox);
}
use of im.actor.core.network.mtp.entity.ProtoStruct in project actor-platform by actorapp.
the class ApiBroker method processResponse.
private void processResponse(long authId, long mid, byte[] content) {
if (authId != currentAuthId) {
return;
}
ProtoStruct protoStruct;
try {
protoStruct = ProtoSerializer.readRpcResponsePayload(content);
} catch (IOException e) {
e.printStackTrace();
Log.w(TAG, "Broken response mid#" + mid);
return;
}
// Log.w(TAG, protoStruct + " mid#" + mid);
long rid;
if (idMap.containsKey(mid)) {
rid = idMap.get(mid);
} else {
return;
}
CommonTimer timer = timeouts.get(rid);
if (timer != null) {
timer.cancel();
timeouts.remove(rid);
}
RequestHolder holder;
if (requests.containsKey(rid)) {
holder = requests.get(rid);
} else {
return;
}
if (protoStruct instanceof RpcOk) {
RpcOk ok = (RpcOk) protoStruct;
requests.remove(rid);
if (holder.protoId != 0) {
idMap.remove(holder.protoId);
}
Response response;
try {
response = (Response) parserConfig.parseRpc(ok.responseType, ok.payload);
} catch (IOException e) {
e.printStackTrace();
requests.remove(rid);
if (holder.protoId != 0) {
idMap.remove(holder.protoId);
}
holder.callback.onError(new RpcInternalException());
return;
}
Log.d(TAG, "<- response#" + holder.publicId + ": " + response + " in " + (Runtime.getCurrentTime() - holder.requestTime) + " ms");
holder.callback.onResult(response);
} else if (protoStruct instanceof RpcError) {
RpcError e = (RpcError) protoStruct;
requests.remove(rid);
if (holder.protoId != 0) {
idMap.remove(holder.protoId);
}
Log.w(TAG, "<- error#" + holder.publicId + ": " + e.errorTag + " " + e.errorCode + " " + e.userMessage + " in " + (Runtime.getCurrentTime() - holder.requestTime) + " ms");
holder.callback.onError(new RpcException(e.errorTag, e.errorCode, e.userMessage, e.canTryAgain, e.relatedData));
} else if (protoStruct instanceof RpcInternalError) {
RpcInternalError e = ((RpcInternalError) protoStruct);
Log.d(TAG, "<- internal_error#" + holder.publicId + " " + e.getTryAgainDelay() + " sec" + " in " + (Runtime.getCurrentTime() - holder.requestTime) + " ms");
if (e.isCanTryAgain()) {
schedule(new ForceResend(rid), e.getTryAgainDelay() * 1000L);
} else {
requests.remove(rid);
if (holder.protoId != 0) {
idMap.remove(holder.protoId);
}
holder.callback.onError(new RpcInternalException());
}
} else if (protoStruct instanceof RpcFloodWait) {
RpcFloodWait f = (RpcFloodWait) protoStruct;
Log.d(TAG, "<- flood_wait#" + holder.publicId + " " + f.getDelay() + " sec" + " in " + (Runtime.getCurrentTime() - holder.requestTime) + " ms");
schedule(new ForceResend(rid), f.getDelay() * 1000L);
} else {
Log.d(TAG, "<- unknown_package#" + holder.publicId + " in " + (Runtime.getCurrentTime() - holder.requestTime) + " ms");
}
}
Aggregations