network delete_all force retries if we get a 421

pull/1941/head
Audric Ackermann 4 years ago
parent 6de594b44d
commit fa32e61982
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -59,7 +59,6 @@ module.exports = grunt => {
'libtextsecure/storage.js', 'libtextsecure/storage.js',
'libtextsecure/storage/user.js', 'libtextsecure/storage/user.js',
'libtextsecure/storage/groups.js', 'libtextsecure/storage/groups.js',
'libtextsecure/protobufs.js',
'libtextsecure/helpers.js', 'libtextsecure/helpers.js',
'libtextsecure/stringview.js', 'libtextsecure/stringview.js',
'libtextsecure/event_target.js', 'libtextsecure/event_target.js',

@ -4,24 +4,9 @@
"homepage": "https://github.com/loki-project/session-desktop", "homepage": "https://github.com/loki-project/session-desktop",
"license": "GPLV3", "license": "GPLV3",
"private": true, "private": true,
"dependencies": {
"indexeddb-backbonejs-adapter": "*",
"protobuf": "~3.8.0"
},
"devDependencies": { "devDependencies": {
"mock-socket": "~0.3.2" "mock-socket": "~0.3.2"
}, },
"preen": {
"indexeddb-backbonejs-adapter": [
"backbone-indexeddb.js"
],
"mock-socket": [
"dist/mock-socket.js"
],
"protobuf": [
"dist/ProtoBuf.js"
]
},
"concat": { "concat": {
"app": [ "app": [
"node_modules/jquery/dist/jquery.js", "node_modules/jquery/dist/jquery.js",

File diff suppressed because it is too large Load Diff

@ -1,37 +0,0 @@
/* global window, dcodeIO, textsecure */
// eslint-disable-next-line func-names
(function() {
window.textsecure = window.textsecure || {};
window.textsecure.protobuf = {};
function loadProtoBufs(filename) {
return dcodeIO.ProtoBuf.loadProtoFile(
{ root: window.PROTO_ROOT, file: filename },
(error, result) => {
if (error) {
const text = `Error loading protos from ${filename} (root: ${window.PROTO_ROOT}) ${
error && error.stack ? error.stack : error
}`;
window.log.error(text);
throw error;
}
const protos = result.build('signalservice');
if (!protos) {
const text = `Error loading protos from ${filename} (root: ${window.PROTO_ROOT})`;
window.log.error(text);
throw new Error(text);
}
// eslint-disable-next-line no-restricted-syntax, guard-for-in
for (const protoName in protos) {
textsecure.protobuf[protoName] = protos[protoName];
}
}
);
}
// this is all the Session Protocols
loadProtoBufs('SignalService.proto');
// this is for websocket wrapping of messages
loadProtoBufs('SubProtocol.proto');
})();

@ -13,8 +13,6 @@ const { JobQueue } = require('./js/modules/job_queue');
const { app } = electron.remote; const { app } = electron.remote;
const { clipboard } = electron; const { clipboard } = electron;
window.PROTO_ROOT = 'protos';
const config = require('url').parse(window.location.toString(), true).query; const config = require('url').parse(window.location.toString(), true).query;
let title = config.name; let title = config.name;

@ -1,7 +1,6 @@
import React from 'react'; import React from 'react';
import Electron from 'electron'; import { shell } from 'electron';
const { shell } = Electron;
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';

@ -19,6 +19,7 @@ export const SessionMessagesList = (props: {
scrollToQuoteMessage: (options: QuoteClickOptions) => Promise<void>; scrollToQuoteMessage: (options: QuoteClickOptions) => Promise<void>;
}) => { }) => {
const messagesProps = useSelector(getSortedMessagesTypesOfSelectedConversation); const messagesProps = useSelector(getSortedMessagesTypesOfSelectedConversation);
return ( return (
<> <>
{messagesProps.map(messageProps => { {messagesProps.map(messageProps => {

@ -1,6 +1,5 @@
import Electron from 'electron'; import { ipcRenderer } from 'electron';
const { ipcRenderer } = Electron;
// tslint:disable: no-require-imports no-var-requires one-variable-per-declaration no-void-expression // tslint:disable: no-require-imports no-var-requires one-variable-per-declaration no-void-expression
import _ from 'lodash'; import _ from 'lodash';

@ -610,6 +610,12 @@ export const forceNetworkDeletion = async (): Promise<Array<string> | null> => {
snodeToMakeRequestTo.pubkey_ed25519 snodeToMakeRequestTo.pubkey_ed25519
)} due to error: ${reason}: ${statusCode}` )} due to error: ${reason}: ${statusCode}`
); );
// if we tried to make the delete on a snode not in our swarm, just trigger a pRetry error so the outer block here finds new snodes to make the request to.
if (statusCode === 421) {
throw new pRetry.AbortError(
'421 error on network delete_all. Retrying with a new snode'
);
}
} else { } else {
window?.log?.warn( window?.log?.warn(
`Could not delete data from ${ed25519Str( `Could not delete data from ${ed25519Str(
@ -662,7 +668,7 @@ export const forceNetworkDeletion = async (): Promise<Array<string> | null> => {
minTimeout: exports.TEST_getMinTimeout(), minTimeout: exports.TEST_getMinTimeout(),
onFailedAttempt: e => { onFailedAttempt: e => {
window?.log?.warn( window?.log?.warn(
`delete_all OUTER request attempt #${e.attemptNumber} failed. ${e.retriesLeft} retries left...` `delete_all OUTER request attempt #${e.attemptNumber} failed. ${e.retriesLeft} retries left...${e.message}`
); );
}, },
} }

@ -1,8 +1,14 @@
import { default as insecureNodeFetch } from 'node-fetch'; import { default as insecureNodeFetch } from 'node-fetch';
import pRetry from 'p-retry';
import { Snode } from '../../data/data'; import { Snode } from '../../data/data';
import { getStoragePubKey } from '../types'; import { getStoragePubKey } from '../types';
import { lokiOnionFetch, snodeHttpsAgent, SnodeResponse } from './onions'; import {
ERROR_421_HANDLED_RETRY_REQUEST,
lokiOnionFetch,
snodeHttpsAgent,
SnodeResponse,
} from './onions';
interface FetchOptions { interface FetchOptions {
method: string; method: string;
@ -80,6 +86,9 @@ async function lokiFetch({
if (e.code === 'ENOTFOUND') { if (e.code === 'ENOTFOUND') {
throw new window.textsecure.NotFoundError('Failed to resolve address', e); throw new window.textsecure.NotFoundError('Failed to resolve address', e);
} }
if (e.message === ERROR_421_HANDLED_RETRY_REQUEST) {
throw new pRetry.AbortError(ERROR_421_HANDLED_RETRY_REQUEST);
}
throw e; throw e;
} }
} }

@ -37,6 +37,8 @@ export interface SnodeResponse {
} }
export const NEXT_NODE_NOT_FOUND_PREFIX = 'Next node not found: '; export const NEXT_NODE_NOT_FOUND_PREFIX = 'Next node not found: ';
export const ERROR_421_HANDLED_RETRY_REQUEST =
'421 handled. Retry this request with a new targetNode';
export const CLOCK_OUT_OF_SYNC_MESSAGE_ERROR = export const CLOCK_OUT_OF_SYNC_MESSAGE_ERROR =
'Your clock is out of sync with the network. Check your clock.'; 'Your clock is out of sync with the network. Check your clock.';
@ -530,9 +532,8 @@ async function handle421InvalidSwarm({
// this does not make much sense to have a 421 without a publicKey set. // this does not make much sense to have a 421 without a publicKey set.
throw new Error('status 421 without a final destination or no associatedWith makes no sense'); throw new Error('status 421 without a final destination or no associatedWith makes no sense');
} }
window?.log?.info(`Invalidating swarm for ${associatedWith}`); window?.log?.info(`Invalidating swarm for ${ed25519Str(associatedWith)}`);
const exceptionMessage = '421 handled. Retry this request with a new targetNode';
try { try {
const parsedBody = JSON.parse(body); const parsedBody = JSON.parse(body);
@ -541,16 +542,16 @@ async function handle421InvalidSwarm({
// the snode gave us the new swarm. Save it for the next retry // the snode gave us the new swarm. Save it for the next retry
window?.log?.warn( window?.log?.warn(
'Wrong swarm, now looking at snodes', 'Wrong swarm, now looking at snodes',
parsedBody.snodes.map((s: any) => s.pubkey_ed25519) parsedBody.snodes.map((s: any) => ed25519Str(s.pubkey_ed25519))
); );
await updateSwarmFor(associatedWith, parsedBody.snodes); await updateSwarmFor(associatedWith, parsedBody.snodes);
throw new pRetry.AbortError(exceptionMessage); throw new pRetry.AbortError(ERROR_421_HANDLED_RETRY_REQUEST);
} }
// remove this node from the swarm of this pubkey // remove this node from the swarm of this pubkey
await dropSnodeFromSwarmIfNeeded(associatedWith, snodeEd25519); await dropSnodeFromSwarmIfNeeded(associatedWith, snodeEd25519);
} catch (e) { } catch (e) {
if (e.message !== exceptionMessage) { if (e.message !== ERROR_421_HANDLED_RETRY_REQUEST) {
window?.log?.warn( window?.log?.warn(
'Got error while parsing 421 result. Dropping this snode from the swarm of this pubkey', 'Got error while parsing 421 result. Dropping this snode from the swarm of this pubkey',
e e
@ -562,7 +563,7 @@ async function handle421InvalidSwarm({
await Onions.incrementBadSnodeCountOrDrop({ snodeEd25519, associatedWith }); await Onions.incrementBadSnodeCountOrDrop({ snodeEd25519, associatedWith });
// this is important we throw so another retry is made and we exit the handling of that reponse // this is important we throw so another retry is made and we exit the handling of that reponse
throw new pRetry.AbortError(exceptionMessage); throw new pRetry.AbortError(ERROR_421_HANDLED_RETRY_REQUEST);
} }
/** /**

@ -287,9 +287,10 @@ export class SwarmPolling {
{ {
minTimeout: 100, minTimeout: 100,
retries: 1, retries: 1,
onFailedAttempt: e => { onFailedAttempt: e => {
window?.log?.warn( window?.log?.warn(
`retrieveNextMessages attempt #${e.attemptNumber} failed. ${e.retriesLeft} retries left...` `retrieveNextMessages attempt #${e.attemptNumber} failed. ${e.retriesLeft} retries left... ${e.name}:`
); );
}, },
} }

Loading…
Cancel
Save