@ -21,6 +21,13 @@ import { fileServerHost } from '../file_server_api/FileServerApi';
import { hrefPnServerProd } from '../push_notification_api/PnServer' ;
import { hrefPnServerProd } from '../push_notification_api/PnServer' ;
import { ERROR_CODE_NO_CONNECT } from './SNodeAPI' ;
import { ERROR_CODE_NO_CONNECT } from './SNodeAPI' ;
import { MergedAbortSignal , WithAbortSignal , WithTimeoutMs } from './requestWith' ;
import { MergedAbortSignal , WithAbortSignal , WithTimeoutMs } from './requestWith' ;
import {
WithAllow401s ,
WithAssociatedWith ,
WithDestinationEd25519 ,
WithGuardNode ,
WithSymmetricKey ,
} from '../../types/with' ;
// hold the ed25519 key of a snode against the time it fails. Used to remove a snode only after a few failures (snodeFailureThreshold failures)
// hold the ed25519 key of a snode against the time it fails. Used to remove a snode only after a few failures (snodeFailureThreshold failures)
let snodeFailureCount : Record < string , number > = { } ;
let snodeFailureCount : Record < string , number > = { } ;
@ -310,13 +317,11 @@ export async function processOnionRequestErrorAtDestination({
destinationSnodeEd25519 ,
destinationSnodeEd25519 ,
associatedWith ,
associatedWith ,
allow401s ,
allow401s ,
} : {
} : WithAllow401s &
statusCode : number ;
Partial < WithDestinationEd25519 & WithAssociatedWith > & {
body : string ;
statusCode : number ;
destinationSnodeEd25519? : string ;
body : string ;
associatedWith? : string ;
} ) {
allow401s : boolean ;
} ) {
if ( statusCode === 200 ) {
if ( statusCode === 200 ) {
return ;
return ;
}
}
@ -328,13 +333,13 @@ export async function processOnionRequestErrorAtDestination({
process401Error ( statusCode ) ;
process401Error ( statusCode ) ;
}
}
processOxenServerError ( statusCode , body ) ;
processOxenServerError ( statusCode , body ) ;
await process421Error ( statusCode , body , associatedWith , destinationSnodeEd25519 ) ;
await process421Error ( statusCode , body , associatedWith || undefined , destinationSnodeEd25519 ) ;
if ( destinationSnodeEd25519 ) {
if ( destinationSnodeEd25519 ) {
await processAnyOtherErrorAtDestination (
await processAnyOtherErrorAtDestination (
statusCode ,
statusCode ,
body ,
body ,
destinationSnodeEd25519 ,
destinationSnodeEd25519 ,
associatedWith
associatedWith || undefined
) ;
) ;
}
}
}
}
@ -342,9 +347,8 @@ export async function processOnionRequestErrorAtDestination({
async function handleNodeNotFound ( {
async function handleNodeNotFound ( {
ed25519NotFound ,
ed25519NotFound ,
associatedWith ,
associatedWith ,
} : {
} : Partial < WithAssociatedWith > & {
ed25519NotFound : string ;
ed25519NotFound : string ;
associatedWith? : string ;
} ) {
} ) {
const shortNodeNotFound = ed25519Str ( ed25519NotFound ) ;
const shortNodeNotFound = ed25519Str ( ed25519NotFound ) ;
window ? . log ? . warn ( 'Handling NODE NOT FOUND with: ' , shortNodeNotFound ) ;
window ? . log ? . warn ( 'Handling NODE NOT FOUND with: ' , shortNodeNotFound ) ;
@ -526,14 +530,11 @@ async function processOnionResponse({
associatedWith ,
associatedWith ,
destinationSnodeEd25519 ,
destinationSnodeEd25519 ,
allow401s ,
allow401s ,
} : Partial < WithAbortSignal > & {
} : Partial < WithAbortSignal & WithDestinationEd25519 & WithAssociatedWith & WithSymmetricKey > &
response ? : { text : ( ) = > Promise < string > ; status : number } ;
WithAllow401s &
symmetricKey? : ArrayBuffer ;
WithGuardNode & {
guardNode : Snode ;
response ? : { text : ( ) = > Promise < string > ; status : number } ;
destinationSnodeEd25519? : string ;
} ) : Promise < SnodeResponse > {
associatedWith? : string ;
allow401s : boolean ;
} ) : Promise < SnodeResponse > {
let ciphertext = '' ;
let ciphertext = '' ;
processAbortedRequest ( abortSignal ) ;
processAbortedRequest ( abortSignal ) ;
@ -549,7 +550,7 @@ async function processOnionResponse({
ciphertext ,
ciphertext ,
guardNode . pubkey_ed25519 ,
guardNode . pubkey_ed25519 ,
destinationSnodeEd25519 ,
destinationSnodeEd25519 ,
associatedWith
associatedWith || undefined
) ;
) ;
if ( ! ciphertext ) {
if ( ! ciphertext ) {
@ -598,7 +599,7 @@ async function processOnionResponse({
}
}
return value ;
return value ;
} ) as Record < string , any > ;
} ) as Record < string , any > ;
// TODO: type those status
const status = jsonRes . status_code || jsonRes . status ;
const status = jsonRes . status_code || jsonRes . status ;
await processOnionRequestErrorAtDestination ( {
await processOnionRequestErrorAtDestination ( {
@ -642,13 +643,10 @@ async function processOnionResponseV4({
guardNode ,
guardNode ,
destinationSnodeEd25519 ,
destinationSnodeEd25519 ,
associatedWith ,
associatedWith ,
} : Partial < WithAbortSignal > & {
} : Partial < WithAbortSignal & WithDestinationEd25519 & WithAssociatedWith & WithSymmetricKey > &
response? : Response ;
WithGuardNode & {
symmetricKey? : ArrayBuffer ;
response? : Response ;
guardNode : Snode ;
} ) : Promise < SnodeResponseV4 | undefined > {
destinationSnodeEd25519? : string ;
associatedWith? : string ;
} ) : Promise < SnodeResponseV4 | undefined > {
processAbortedRequest ( abortSignal ) ;
processAbortedRequest ( abortSignal ) ;
const validSymmetricKey = await processNoSymmetricKeyError ( guardNode , symmetricKey ) ;
const validSymmetricKey = await processNoSymmetricKeyError ( guardNode , symmetricKey ) ;
@ -669,7 +667,7 @@ async function processOnionResponseV4({
cipherText ,
cipherText ,
guardNode . pubkey_ed25519 ,
guardNode . pubkey_ed25519 ,
destinationSnodeEd25519 ,
destinationSnodeEd25519 ,
associatedWith
associatedWith || undefined
) ;
) ;
const plaintextBuffer = await callUtilsWorker (
const plaintextBuffer = await callUtilsWorker (
@ -705,9 +703,8 @@ export type FinalRelayOptions = {
port? : number ; // default to 443
port? : number ; // default to 443
} ;
} ;
export type DestinationContext = {
export type DestinationContext = WithSymmetricKey & {
ciphertext : Uint8Array ;
ciphertext : Uint8Array ;
symmetricKey : ArrayBuffer ;
ephemeralKey : ArrayBuffer ;
ephemeralKey : ArrayBuffer ;
} ;
} ;
@ -721,10 +718,8 @@ async function handle421InvalidSwarm({
body ,
body ,
destinationSnodeEd25519 ,
destinationSnodeEd25519 ,
associatedWith ,
associatedWith ,
} : {
} : Partial < WithDestinationEd25519 & WithAssociatedWith > & {
body : string ;
body : string ;
destinationSnodeEd25519? : string ;
associatedWith? : string ;
} ) {
} ) {
if ( ! destinationSnodeEd25519 || ! associatedWith ) {
if ( ! destinationSnodeEd25519 || ! associatedWith ) {
// The snode isn't associated with the given public key anymore
// The snode isn't associated with the given public key anymore
@ -784,9 +779,8 @@ async function handle421InvalidSwarm({
async function incrementBadSnodeCountOrDrop ( {
async function incrementBadSnodeCountOrDrop ( {
snodeEd25519 ,
snodeEd25519 ,
associatedWith ,
associatedWith ,
} : {
} : Partial < WithAssociatedWith > & {
snodeEd25519 : string ;
snodeEd25519 : string ;
associatedWith? : string ;
} ) {
} ) {
const oldFailureCount = snodeFailureCount [ snodeEd25519 ] || 0 ;
const oldFailureCount = snodeFailureCount [ snodeEd25519 ] || 0 ;
const newFailureCount = oldFailureCount + 1 ;
const newFailureCount = oldFailureCount + 1 ;
@ -828,15 +822,15 @@ async function sendOnionRequestHandlingSnodeEjectNoRetries({
allow401s ,
allow401s ,
timeoutMs ,
timeoutMs ,
} : WithAbortSignal &
} : WithAbortSignal &
WithTimeoutMs & {
WithTimeoutMs &
WithAllow401s &
Partial < WithAssociatedWith > & {
nodePath : Array < Snode > ;
nodePath : Array < Snode > ;
destSnodeX25519 : string ;
destSnodeX25519 : string ;
finalDestOptions : FinalDestOptions ;
finalDestOptions : FinalDestOptions ;
finalRelayOptions? : FinalRelayOptions ;
finalRelayOptions? : FinalRelayOptions ;
associatedWith? : string ;
useV4 : boolean ;
useV4 : boolean ;
throwErrors : boolean ;
throwErrors : boolean ;
allow401s : boolean ;
} ) : Promise < SnodeResponse | SnodeResponseV4 | undefined > {
} ) : Promise < SnodeResponse | SnodeResponseV4 | undefined > {
// this sendOnionRequestNoRetries() call has to be the only one like this.
// this sendOnionRequestNoRetries() call has to be the only one like this.
// If you need to call it, call it through sendOnionRequestHandlingSnodeEjectNoRetries because this is the one handling path rebuilding and known errors
// If you need to call it, call it through sendOnionRequestHandlingSnodeEjectNoRetries because this is the one handling path rebuilding and known errors
@ -1118,13 +1112,13 @@ async function sendOnionRequestSnodeDestNoRetries({
timeoutMs ,
timeoutMs ,
associatedWith ,
associatedWith ,
} : WithTimeoutMs &
} : WithTimeoutMs &
WithAbortSignal & {
WithAbortSignal &
WithAllow401s &
Partial < WithAssociatedWith > & {
onionPath : Array < Snode > ;
onionPath : Array < Snode > ;
targetNode : Snode ;
targetNode : Snode ;
headers : Record < string , any > ;
headers : Record < string , any > ;
plaintext : string | null ;
plaintext : string | null ;
allow401s : boolean ;
associatedWith? : string ;
} ) {
} ) {
return Onions . sendOnionRequestHandlingSnodeEjectNoRetries ( {
return Onions . sendOnionRequestHandlingSnodeEjectNoRetries ( {
nodePath : onionPath ,
nodePath : onionPath ,
@ -1155,12 +1149,12 @@ async function lokiOnionFetchNoRetries({
abortSignal ,
abortSignal ,
timeoutMs ,
timeoutMs ,
} : WithTimeoutMs &
} : WithTimeoutMs &
WithAbortSignal & {
WithAbortSignal &
WithAllow401s &
Partial < WithAssociatedWith > & {
targetNode : Snode ;
targetNode : Snode ;
headers : Record < string , any > ;
headers : Record < string , any > ;
body : string | null ;
body : string | null ;
associatedWith? : string ;
allow401s : boolean ;
} ) : Promise < SnodeResponse | undefined > {
} ) : Promise < SnodeResponse | undefined > {
try {
try {
// Get a path excluding `targetNode`:
// Get a path excluding `targetNode`: