|
|
|
@ -43,9 +43,7 @@ const trySendP2p = async (pubKey, data64, isPing, messageEventData) => {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
const port = p2pDetails.port ? `:${p2pDetails.port}` : '';
|
|
|
|
|
|
|
|
|
|
await rpc(p2pDetails.address, port, 'store', {
|
|
|
|
|
await rpc(p2pDetails.address, p2pDetails.port, 'store', {
|
|
|
|
|
data: data64,
|
|
|
|
|
});
|
|
|
|
|
lokiP2pAPI.setContactOnline(pubKey);
|
|
|
|
@ -68,9 +66,30 @@ const trySendP2p = async (pubKey, data64, isPing, messageEventData) => {
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const retrieveNextMessages = async (nodeUrl, nodeData, ourKey) => {
|
|
|
|
|
const params = {
|
|
|
|
|
pubKey: ourKey,
|
|
|
|
|
lastHash: nodeData.lastHash || '',
|
|
|
|
|
};
|
|
|
|
|
const options = {
|
|
|
|
|
timeout: 40000,
|
|
|
|
|
headers: {
|
|
|
|
|
[LOKI_LONGPOLL_HEADER]: true,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const result = await rpc(
|
|
|
|
|
`https://${nodeUrl}`,
|
|
|
|
|
nodeData.port,
|
|
|
|
|
'retrieve',
|
|
|
|
|
params,
|
|
|
|
|
options
|
|
|
|
|
);
|
|
|
|
|
return result.messages || [];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class LokiMessageAPI {
|
|
|
|
|
constructor({ snodeServerPort }) {
|
|
|
|
|
this.snodeServerPort = snodeServerPort ? `:${snodeServerPort}` : '';
|
|
|
|
|
constructor() {
|
|
|
|
|
this.jobQueue = new window.JobQueue();
|
|
|
|
|
this.sendingSwarmNodes = {};
|
|
|
|
|
}
|
|
|
|
@ -151,8 +170,13 @@ class LokiMessageAPI {
|
|
|
|
|
|
|
|
|
|
async openSendConnection(params) {
|
|
|
|
|
while (!_.isEmpty(this.sendingSwarmNodes[params.timestamp])) {
|
|
|
|
|
const url = this.sendingSwarmNodes[params.timestamp].shift();
|
|
|
|
|
const successfulSend = await this.sendToNode(url, params);
|
|
|
|
|
const snode = this.sendingSwarmNodes[params.timestamp].shift();
|
|
|
|
|
// TODO: Revert back to using snode address instead of IP
|
|
|
|
|
const successfulSend = await this.sendToNode(
|
|
|
|
|
snode.ip,
|
|
|
|
|
snode.port,
|
|
|
|
|
params
|
|
|
|
|
);
|
|
|
|
|
if (successfulSend) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
@ -160,17 +184,12 @@ class LokiMessageAPI {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async sendToNode(url, params) {
|
|
|
|
|
async sendToNode(address, port, params) {
|
|
|
|
|
let successiveFailures = 0;
|
|
|
|
|
while (successiveFailures < 3) {
|
|
|
|
|
await sleepFor(successiveFailures * 500);
|
|
|
|
|
try {
|
|
|
|
|
const result = await rpc(
|
|
|
|
|
`https://${url}`,
|
|
|
|
|
this.snodeServerPort,
|
|
|
|
|
'store',
|
|
|
|
|
params
|
|
|
|
|
);
|
|
|
|
|
const result = await rpc(`https://${address}`, port, 'store', params);
|
|
|
|
|
|
|
|
|
|
// Make sure we aren't doing too much PoW
|
|
|
|
|
const currentDifficulty = window.storage.get('PoWDifficulty', null);
|
|
|
|
@ -203,51 +222,34 @@ class LokiMessageAPI {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
log.error(`Failed to send to node: ${url}`);
|
|
|
|
|
await lokiSnodeAPI.unreachableNode(params.pubKey, url);
|
|
|
|
|
log.error(`Failed to send to node: ${address}`);
|
|
|
|
|
await lokiSnodeAPI.unreachableNode(params.pubKey, address);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async retrieveNextMessages(nodeUrl, nodeData, ourKey) {
|
|
|
|
|
const params = {
|
|
|
|
|
pubKey: ourKey,
|
|
|
|
|
lastHash: nodeData.lastHash || '',
|
|
|
|
|
};
|
|
|
|
|
const options = {
|
|
|
|
|
timeout: 40000,
|
|
|
|
|
headers: {
|
|
|
|
|
[LOKI_LONGPOLL_HEADER]: true,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const result = await rpc(
|
|
|
|
|
`https://${nodeUrl}`,
|
|
|
|
|
this.snodeServerPort,
|
|
|
|
|
'retrieve',
|
|
|
|
|
params,
|
|
|
|
|
options
|
|
|
|
|
);
|
|
|
|
|
return result.messages || [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async openConnection(callback) {
|
|
|
|
|
const ourKey = window.textsecure.storage.user.getNumber();
|
|
|
|
|
while (!_.isEmpty(this.ourSwarmNodes)) {
|
|
|
|
|
const url = Object.keys(this.ourSwarmNodes)[0];
|
|
|
|
|
const nodeData = this.ourSwarmNodes[url];
|
|
|
|
|
delete this.ourSwarmNodes[url];
|
|
|
|
|
const address = Object.keys(this.ourSwarmNodes)[0];
|
|
|
|
|
const nodeData = this.ourSwarmNodes[address];
|
|
|
|
|
delete this.ourSwarmNodes[address];
|
|
|
|
|
let successiveFailures = 0;
|
|
|
|
|
while (successiveFailures < 3) {
|
|
|
|
|
await sleepFor(successiveFailures * 1000);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
let messages = await this.retrieveNextMessages(url, nodeData, ourKey);
|
|
|
|
|
// TODO: Revert back to using snode address instead of IP
|
|
|
|
|
let messages = await retrieveNextMessages(
|
|
|
|
|
nodeData.ip,
|
|
|
|
|
nodeData,
|
|
|
|
|
ourKey
|
|
|
|
|
);
|
|
|
|
|
successiveFailures = 0;
|
|
|
|
|
if (messages.length) {
|
|
|
|
|
const lastMessage = _.last(messages);
|
|
|
|
|
nodeData.lashHash = lastMessage.hash;
|
|
|
|
|
lokiSnodeAPI.updateLastHash(
|
|
|
|
|
url,
|
|
|
|
|
address,
|
|
|
|
|
lastMessage.hash,
|
|
|
|
|
lastMessage.expiration
|
|
|
|
|
);
|
|
|
|
|