gnutella 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLI.md +1 -0
- package/gnutella.json.example +1 -0
- package/package.json +4 -3
- package/src/cli_shared.ts +32 -43
- package/src/const.ts +1 -9
- package/src/descriptor_routing/index.ts +17 -0
- package/src/descriptor_routing/pong_cache.ts +32 -0
- package/src/descriptor_routing/response_routes.ts +15 -0
- package/src/descriptor_routing/seen.ts +20 -0
- package/src/descriptor_routing/ttl.ts +37 -0
- package/src/descriptor_routing/types.ts +27 -0
- package/src/gwebcache/bootstrap.ts +21 -58
- package/src/gwebcache/types.ts +6 -10
- package/src/handshake_policy/admission.ts +17 -0
- package/src/handshake_policy/capabilities.ts +167 -0
- package/src/handshake_policy/headers.ts +157 -0
- package/src/handshake_policy/index.ts +21 -0
- package/src/handshake_policy/types.ts +36 -0
- package/src/peer_address.ts +68 -0
- package/src/peer_discovery/candidate_policy.ts +80 -0
- package/src/peer_discovery/index.ts +8 -0
- package/src/peer_discovery/types.ts +26 -0
- package/src/persistence/config_doc.ts +61 -0
- package/src/persistence/index.ts +14 -0
- package/src/persistence/peer_state.ts +113 -0
- package/src/persistence/types.ts +28 -0
- package/src/protocol/codec.ts +27 -67
- package/src/protocol/content_urn.ts +5 -1
- package/src/protocol/file_hash.ts +12 -0
- package/src/protocol/file_server.ts +1 -1
- package/src/protocol/ggep.ts +13 -8
- package/src/protocol/handshake.ts +18 -161
- package/src/protocol/http_download_reader.ts +9 -7
- package/src/protocol/magnet.ts +15 -13
- package/src/protocol/node.ts +1 -1
- package/src/protocol/node_handshake.ts +55 -113
- package/src/protocol/node_protocol_runtime.ts +69 -60
- package/src/protocol/node_qrp_runtime.ts +7 -6
- package/src/protocol/node_query_routing.ts +43 -132
- package/src/protocol/node_state.ts +2 -3
- package/src/protocol/node_topology.ts +38 -82
- package/src/protocol/node_transfer.ts +52 -35
- package/src/protocol/peer_state.ts +36 -207
- package/src/protocol/qrp.ts +1 -549
- package/src/protocol/query_matching.ts +22 -0
- package/src/protocol/share_index.ts +8 -70
- package/src/protocol/share_library.ts +30 -73
- package/src/query_routing/dynamic_query.ts +117 -0
- package/src/query_routing/index.ts +27 -0
- package/src/query_routing/qrp/constants.ts +9 -0
- package/src/query_routing/qrp/hash.ts +27 -0
- package/src/query_routing/qrp/patch_values.ts +29 -0
- package/src/query_routing/qrp/remote_state.ts +98 -0
- package/src/query_routing/qrp/routing.ts +46 -0
- package/src/query_routing/qrp/table.ts +319 -0
- package/src/query_routing/qrp/terms.ts +62 -0
- package/src/query_routing/qrp/types.ts +31 -0
- package/src/query_routing/qrp.ts +13 -0
- package/src/share_catalog/catalog.ts +108 -0
- package/src/share_catalog/index.ts +16 -0
- package/src/share_catalog/keywords.ts +15 -0
- package/src/share_catalog/manifest.ts +81 -0
- package/src/share_catalog/types.ts +43 -0
- package/src/shared.ts +9 -68
- package/src/topology/admission.ts +51 -0
- package/src/topology/classify.ts +19 -0
- package/src/topology/index.ts +17 -0
- package/src/topology/slots.ts +43 -0
- package/src/topology/types.ts +25 -0
- package/src/transfers/index.ts +13 -0
- package/src/transfers/planner.ts +52 -0
- package/src/transfers/ranges.ts +57 -0
- package/src/transfers/results.ts +45 -0
- package/src/transfers/types.ts +43 -0
- package/src/types.ts +43 -55
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import net from "node:net";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { MAX_XTRY } from "../const";
|
|
4
|
+
import {
|
|
5
|
+
buildBaseHandshakeHeaders,
|
|
6
|
+
buildClientFinalHeaders as buildPolicyClientFinalHeaders,
|
|
7
|
+
buildPeerCapabilities,
|
|
8
|
+
buildRejectHeaders,
|
|
9
|
+
buildServerHandshakeHeaders as buildPolicyServerHandshakeHeaders,
|
|
10
|
+
type LocalHandshakePolicy,
|
|
11
|
+
} from "../handshake_policy";
|
|
4
12
|
import {
|
|
5
13
|
errMsg,
|
|
6
14
|
normalizeIpv4,
|
|
@@ -19,13 +27,9 @@ import {
|
|
|
19
27
|
describeHandshakeResponse,
|
|
20
28
|
findHeaderEnd,
|
|
21
29
|
hasToken,
|
|
22
|
-
lowerCaseHeaders,
|
|
23
30
|
mergeHeaders,
|
|
24
|
-
parseBoolHeader,
|
|
25
31
|
parseHandshakeBlock,
|
|
26
|
-
parseListenIpHeader,
|
|
27
32
|
parsePeerHeaderList,
|
|
28
|
-
parsePositiveIntHeader,
|
|
29
33
|
} from "./handshake";
|
|
30
34
|
import type { GnutellaServent } from "./node";
|
|
31
35
|
import type { ProbeCtx } from "./node_types";
|
|
@@ -140,70 +144,40 @@ function emitHandshakeBlock(
|
|
|
140
144
|
);
|
|
141
145
|
}
|
|
142
146
|
|
|
143
|
-
function
|
|
144
|
-
if (node.nodeMode() !== "ultrapeer") return undefined;
|
|
145
|
-
if (
|
|
146
|
-
node.connectedMeshPeerCount() < node.config().maxUltrapeerConnections
|
|
147
|
-
)
|
|
148
|
-
return "True";
|
|
149
|
-
if (node.connectedLeafCount() < node.config().maxLeafConnections)
|
|
150
|
-
return "False";
|
|
151
|
-
return undefined;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const GTK_MODERN_ULTRAPEER_MIN_DEGREE = 16;
|
|
155
|
-
|
|
156
|
-
function baseRoleHeaders(node: GnutellaServent): Record<string, string> {
|
|
157
|
-
const headers: Record<string, string> = {
|
|
158
|
-
"x-ultrapeer": node.nodeMode() === "ultrapeer" ? "True" : "False",
|
|
159
|
-
};
|
|
160
|
-
const ultrapeerNeeded = ultrapeerNeededHeader(node);
|
|
161
|
-
if (ultrapeerNeeded) headers["x-ultrapeer-needed"] = ultrapeerNeeded;
|
|
162
|
-
if (node.nodeMode() === "ultrapeer") {
|
|
163
|
-
headers["x-ultrapeer-query-routing"] = "0.1";
|
|
164
|
-
headers["x-dynamic-querying"] = "0.1";
|
|
165
|
-
headers["x-ext-probes"] = "0.1";
|
|
166
|
-
headers["x-degree"] = String(
|
|
167
|
-
Math.max(
|
|
168
|
-
GTK_MODERN_ULTRAPEER_MIN_DEGREE,
|
|
169
|
-
node.config().maxUltrapeerConnections,
|
|
170
|
-
),
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
return headers;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
function baseFeatureHeaders(
|
|
147
|
+
function localHandshakePolicy(
|
|
177
148
|
node: GnutellaServent,
|
|
178
|
-
)
|
|
149
|
+
tlsEnabled = node.tlsEnabled(),
|
|
150
|
+
): LocalHandshakePolicy {
|
|
179
151
|
const c = node.config();
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
152
|
+
return {
|
|
153
|
+
userAgent: c.userAgent,
|
|
154
|
+
advertisedHost: node.currentAdvertisedHost(),
|
|
155
|
+
advertisedPort: node.currentAdvertisedPort(),
|
|
156
|
+
maxTtl: c.maxTtl,
|
|
157
|
+
nodeMode: node.nodeMode(),
|
|
158
|
+
maxUltrapeerConnections: c.maxUltrapeerConnections,
|
|
159
|
+
maxLeafConnections: c.maxLeafConnections,
|
|
160
|
+
connectedMeshPeerCount: node.connectedMeshPeerCount(),
|
|
161
|
+
connectedLeafCount: node.connectedLeafCount(),
|
|
162
|
+
enableQrp: c.enableQrp,
|
|
163
|
+
queryRoutingVersion: c.queryRoutingVersion,
|
|
164
|
+
enableCompression: c.enableCompression,
|
|
165
|
+
enablePongCaching: c.enablePongCaching,
|
|
166
|
+
enableGgep: c.enableGgep,
|
|
167
|
+
enableBye: c.enableBye,
|
|
168
|
+
tlsEnabled,
|
|
169
|
+
tlsUpgradeToken: node.tlsUpgradeToken(),
|
|
170
|
+
};
|
|
188
171
|
}
|
|
189
172
|
|
|
190
173
|
export function baseHandshakeHeaders(
|
|
191
174
|
node: GnutellaServent,
|
|
192
175
|
remoteIp?: string,
|
|
193
176
|
): Record<string, string> {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
"user-agent": c.userAgent || DEFAULT_USER_AGENT,
|
|
199
|
-
"listen-ip": `${advertisedHost}:${advertisedPort}`,
|
|
200
|
-
"x-max-ttl": String(c.maxTtl),
|
|
201
|
-
...baseRoleHeaders(node),
|
|
202
|
-
...baseFeatureHeaders(node),
|
|
203
|
-
};
|
|
204
|
-
const observedRemote = normalizeIpv4(remoteIp);
|
|
205
|
-
if (observedRemote) headers["remote-ip"] = observedRemote;
|
|
206
|
-
return headers;
|
|
177
|
+
return buildBaseHandshakeHeaders(
|
|
178
|
+
localHandshakePolicy(node, false),
|
|
179
|
+
remoteIp,
|
|
180
|
+
);
|
|
207
181
|
}
|
|
208
182
|
|
|
209
183
|
export function buildServerHandshakeHeaders(
|
|
@@ -211,18 +185,11 @@ export function buildServerHandshakeHeaders(
|
|
|
211
185
|
requestHeaders: Record<string, string>,
|
|
212
186
|
remoteIp?: string,
|
|
213
187
|
): Record<string, string> {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
if (
|
|
220
|
-
node.config().enableCompression &&
|
|
221
|
-
hasToken(requestHeaders["accept-encoding"], "deflate")
|
|
222
|
-
) {
|
|
223
|
-
headers["content-encoding"] = "deflate";
|
|
224
|
-
}
|
|
225
|
-
return headers;
|
|
188
|
+
return buildPolicyServerHandshakeHeaders(
|
|
189
|
+
localHandshakePolicy(node),
|
|
190
|
+
requestHeaders,
|
|
191
|
+
remoteIp,
|
|
192
|
+
);
|
|
226
193
|
}
|
|
227
194
|
|
|
228
195
|
export function buildClientFinalHeaders(
|
|
@@ -230,18 +197,11 @@ export function buildClientFinalHeaders(
|
|
|
230
197
|
serverHeaders: Record<string, string>,
|
|
231
198
|
remoteIp?: string,
|
|
232
199
|
): Record<string, string> {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
if (
|
|
239
|
-
node.config().enableCompression &&
|
|
240
|
-
hasToken(serverHeaders["accept-encoding"], "deflate")
|
|
241
|
-
) {
|
|
242
|
-
headers["content-encoding"] = "deflate";
|
|
243
|
-
}
|
|
244
|
-
return headers;
|
|
200
|
+
return buildPolicyClientFinalHeaders(
|
|
201
|
+
localHandshakePolicy(node),
|
|
202
|
+
serverHeaders,
|
|
203
|
+
remoteIp,
|
|
204
|
+
);
|
|
245
205
|
}
|
|
246
206
|
|
|
247
207
|
export function buildCapabilities(
|
|
@@ -251,30 +211,14 @@ export function buildCapabilities(
|
|
|
251
211
|
compressIn: boolean,
|
|
252
212
|
compressOut: boolean,
|
|
253
213
|
): PeerCapabilities {
|
|
254
|
-
|
|
255
|
-
return {
|
|
214
|
+
return buildPeerCapabilities({
|
|
256
215
|
version,
|
|
257
|
-
headers
|
|
258
|
-
userAgent: h["user-agent"],
|
|
259
|
-
supportsGgep: !!h["ggep"],
|
|
260
|
-
supportsPongCaching: !!h["pong-caching"],
|
|
261
|
-
supportsBye: !!h["bye-packet"],
|
|
262
|
-
supportsTls: node.peerRequestedTlsUpgrade(h),
|
|
263
|
-
supportsCompression:
|
|
264
|
-
hasToken(h["accept-encoding"], "deflate") ||
|
|
265
|
-
hasToken(h["content-encoding"], "deflate"),
|
|
216
|
+
headers,
|
|
266
217
|
compressIn,
|
|
267
218
|
compressOut,
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
ultrapeerQueryRoutingVersion: h["x-ultrapeer-query-routing"],
|
|
272
|
-
dynamicQueryingVersion: h["x-dynamic-querying"],
|
|
273
|
-
extProbesVersion: h["x-ext-probes"],
|
|
274
|
-
degree: parsePositiveIntHeader(h["x-degree"]),
|
|
275
|
-
isCrawler: !!h["crawler"],
|
|
276
|
-
listenIp: parseListenIpHeader(h["listen-ip"]),
|
|
277
|
-
};
|
|
219
|
+
tlsEnabled: node.tlsEnabled(),
|
|
220
|
+
tlsUpgradeToken: node.tlsUpgradeToken(),
|
|
221
|
+
});
|
|
278
222
|
}
|
|
279
223
|
|
|
280
224
|
export function selectTryPeers(
|
|
@@ -337,13 +281,11 @@ export function reject06(
|
|
|
337
281
|
extraHeaders: Record<string, string> = {},
|
|
338
282
|
): void {
|
|
339
283
|
const tryPeers = node.selectTryPeers();
|
|
340
|
-
const headers =
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
headers["x-try-ultrapeers"] = tryPeers.join(",");
|
|
346
|
-
}
|
|
284
|
+
const headers = buildRejectHeaders({
|
|
285
|
+
extraHeaders,
|
|
286
|
+
remoteIp: socket.remoteAddress,
|
|
287
|
+
tryPeers,
|
|
288
|
+
});
|
|
347
289
|
emitHandshakeBlock(
|
|
348
290
|
node,
|
|
349
291
|
"inbound",
|
|
@@ -1,8 +1,25 @@
|
|
|
1
|
-
import crypto from "node:crypto";
|
|
2
1
|
import type net from "node:net";
|
|
3
2
|
import zlib from "node:zlib";
|
|
4
3
|
|
|
5
|
-
import { HEADER_LEN,
|
|
4
|
+
import { HEADER_LEN, TYPE, TYPE_NAME } from "../const";
|
|
5
|
+
import {
|
|
6
|
+
forwardedDescriptorLifetime,
|
|
7
|
+
normalizeQueryLifetime as normalizeQueryLifetimePolicy,
|
|
8
|
+
overflowPongCacheKeys,
|
|
9
|
+
pongCacheKey,
|
|
10
|
+
pongReplyTtl,
|
|
11
|
+
queryHitReplyTtl,
|
|
12
|
+
responseRouteDecision,
|
|
13
|
+
selectCachedPongPayloads,
|
|
14
|
+
shouldMarkDescriptorSeen,
|
|
15
|
+
shouldRelayPing,
|
|
16
|
+
shouldSuppressDescriptor,
|
|
17
|
+
} from "../descriptor_routing";
|
|
18
|
+
import type { DescriptorLifetime } from "../descriptor_routing/types";
|
|
19
|
+
import {
|
|
20
|
+
initialRemoteQrpState,
|
|
21
|
+
splitSearchTerms,
|
|
22
|
+
} from "../query_routing/qrp";
|
|
6
23
|
import { errMsg, toBuffer, ts } from "../shared";
|
|
7
24
|
import type {
|
|
8
25
|
PendingPush,
|
|
@@ -42,11 +59,7 @@ import type {
|
|
|
42
59
|
Peer,
|
|
43
60
|
} from "./node_types";
|
|
44
61
|
import { firstSha1Urn } from "./content_urn";
|
|
45
|
-
import {
|
|
46
|
-
initialRemoteQrpState,
|
|
47
|
-
matchQuery as shareMatchesQuery,
|
|
48
|
-
splitSearchTerms,
|
|
49
|
-
} from "./qrp";
|
|
62
|
+
import { matchQuery as shareMatchesQuery } from "./query_matching";
|
|
50
63
|
|
|
51
64
|
function descriptorTypeName(payloadType: number): string {
|
|
52
65
|
return TYPE_NAME[payloadType] || `0x${payloadType.toString(16)}`;
|
|
@@ -426,15 +439,16 @@ export function forwardToRoute(
|
|
|
426
439
|
hops: number,
|
|
427
440
|
payload: Buffer,
|
|
428
441
|
): void {
|
|
429
|
-
|
|
442
|
+
const lifetime = forwardedDescriptorLifetime(ttl, hops);
|
|
443
|
+
if (!lifetime) return;
|
|
430
444
|
const peer = node.peers.get(route.peerKey);
|
|
431
445
|
if (!peer) return;
|
|
432
446
|
node.sendToPeer(
|
|
433
447
|
peer,
|
|
434
448
|
payloadType,
|
|
435
449
|
descriptorId,
|
|
436
|
-
|
|
437
|
-
hops
|
|
450
|
+
lifetime.ttl,
|
|
451
|
+
lifetime.hops,
|
|
438
452
|
payload,
|
|
439
453
|
);
|
|
440
454
|
}
|
|
@@ -479,11 +493,8 @@ export function normalizeQueryLifetime(
|
|
|
479
493
|
node: GnutellaServent,
|
|
480
494
|
ttl: number,
|
|
481
495
|
hops: number,
|
|
482
|
-
):
|
|
483
|
-
|
|
484
|
-
const maxLife = Math.max(1, node.config().maxTtl);
|
|
485
|
-
if (hops > maxLife) return null;
|
|
486
|
-
return { ttl: Math.max(0, Math.min(ttl, maxLife - hops)), hops };
|
|
496
|
+
): DescriptorLifetime | null {
|
|
497
|
+
return normalizeQueryLifetimePolicy(ttl, hops, node.config().maxTtl);
|
|
487
498
|
}
|
|
488
499
|
|
|
489
500
|
export function isIndexQuery(
|
|
@@ -532,16 +543,14 @@ export function cachePongPayload(
|
|
|
532
543
|
node: GnutellaServent,
|
|
533
544
|
payload: Buffer,
|
|
534
545
|
): void {
|
|
535
|
-
const digest =
|
|
546
|
+
const digest = pongCacheKey(payload);
|
|
536
547
|
node.pongCache.set(digest, {
|
|
537
548
|
payload: Buffer.from(payload),
|
|
538
549
|
at: node.now(),
|
|
539
550
|
});
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
.slice(0, node.pongCache.size - 64);
|
|
544
|
-
for (const [key] of oldest) node.pongCache.delete(key);
|
|
551
|
+
for (const key of overflowPongCacheKeys(node.pongCache.entries(), 64)) {
|
|
552
|
+
node.pongCache.delete(key);
|
|
553
|
+
}
|
|
545
554
|
}
|
|
546
555
|
|
|
547
556
|
export function shouldIgnoreDescriptor(
|
|
@@ -550,15 +559,15 @@ export function shouldIgnoreDescriptor(
|
|
|
550
559
|
hdr: RoutedDescriptor,
|
|
551
560
|
payload: Buffer,
|
|
552
561
|
): boolean {
|
|
553
|
-
|
|
554
|
-
peer.closingAfterBye
|
|
555
|
-
hdr.payloadType
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
+
return shouldSuppressDescriptor({
|
|
563
|
+
closingAfterBye: !!peer.closingAfterBye,
|
|
564
|
+
payloadType: hdr.payloadType,
|
|
565
|
+
alreadySeen: node.hasSeen(
|
|
566
|
+
hdr.payloadType,
|
|
567
|
+
hdr.descriptorIdHex,
|
|
568
|
+
payload,
|
|
569
|
+
),
|
|
570
|
+
});
|
|
562
571
|
}
|
|
563
572
|
|
|
564
573
|
export function rejectRelayedLeafDescriptor(
|
|
@@ -589,7 +598,7 @@ export function onPingDescriptor(
|
|
|
589
598
|
});
|
|
590
599
|
node.respondPong(peer, hdr);
|
|
591
600
|
if (!node.shouldRelayPings()) return;
|
|
592
|
-
if (hdr.ttl
|
|
601
|
+
if (!shouldRelayPing(hdr.ttl, node.now(), peer.lastPingAt, 1000)) return;
|
|
593
602
|
peer.lastPingAt = node.now();
|
|
594
603
|
broadcastPingToPeers(
|
|
595
604
|
node,
|
|
@@ -681,7 +690,7 @@ export function handleDescriptor(
|
|
|
681
690
|
): void {
|
|
682
691
|
if (node.rejectRelayedLeafDescriptor(peer, hdr)) return;
|
|
683
692
|
if (node.shouldIgnoreDescriptor(peer, hdr, payload)) return;
|
|
684
|
-
if (hdr.payloadType
|
|
693
|
+
if (shouldMarkDescriptorSeen(hdr.payloadType)) {
|
|
685
694
|
node.markSeen(hdr.payloadType, hdr.descriptorIdHex, payload);
|
|
686
695
|
}
|
|
687
696
|
node.dispatchDescriptor(peer, hdr, payload);
|
|
@@ -709,7 +718,7 @@ export function respondPong(
|
|
|
709
718
|
peer: Peer,
|
|
710
719
|
hdr: Pick<DescriptorHeader, "descriptorId" | "hops">,
|
|
711
720
|
): void {
|
|
712
|
-
const ttl =
|
|
721
|
+
const ttl = pongReplyTtl(hdr.hops);
|
|
713
722
|
const own = encodePong(
|
|
714
723
|
node.currentAdvertisedPort(),
|
|
715
724
|
node.currentAdvertisedHost(),
|
|
@@ -719,17 +728,12 @@ export function respondPong(
|
|
|
719
728
|
node.sendToPeer(peer, TYPE.PONG, hdr.descriptorId, ttl, 0, own);
|
|
720
729
|
if (!node.config().enablePongCaching) return;
|
|
721
730
|
let sent = 1;
|
|
722
|
-
const
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
hdr.descriptorId,
|
|
729
|
-
ttl,
|
|
730
|
-
0,
|
|
731
|
-
entry.payload,
|
|
732
|
-
);
|
|
731
|
+
for (const payload of selectCachedPongPayloads(
|
|
732
|
+
node.pongCache.values(),
|
|
733
|
+
sent,
|
|
734
|
+
10,
|
|
735
|
+
)) {
|
|
736
|
+
node.sendToPeer(peer, TYPE.PONG, hdr.descriptorId, ttl, 0, payload);
|
|
733
737
|
sent++;
|
|
734
738
|
}
|
|
735
739
|
}
|
|
@@ -750,10 +754,7 @@ export function respondQueryHit(
|
|
|
750
754
|
const limit = Math.max(1, node.config().maxResultsPerQuery);
|
|
751
755
|
const batchSize = 16;
|
|
752
756
|
const chosen = matches.slice(0, limit);
|
|
753
|
-
const replyTtl =
|
|
754
|
-
node.config().maxTtl,
|
|
755
|
-
Math.max(1, hdr.hops + 2),
|
|
756
|
-
);
|
|
757
|
+
const replyTtl = queryHitReplyTtl(hdr.hops, node.config().maxTtl);
|
|
757
758
|
for (let off = 0; off < chosen.length; off += batchSize) {
|
|
758
759
|
const batch = chosen.slice(off, off + batchSize);
|
|
759
760
|
const out = encodeQueryHit(
|
|
@@ -792,9 +793,12 @@ export function onPong(
|
|
|
792
793
|
const pong = parsePong(payload);
|
|
793
794
|
node.cachePongPayload(payload);
|
|
794
795
|
node.addKnownPeer(pong.ip, pong.port);
|
|
795
|
-
const
|
|
796
|
-
|
|
797
|
-
|
|
796
|
+
const decision = responseRouteDecision(
|
|
797
|
+
node.pingRoutes.get(hdr.descriptorIdHex),
|
|
798
|
+
{ forwardInLeaf: true },
|
|
799
|
+
);
|
|
800
|
+
if (decision.kind === "drop") return;
|
|
801
|
+
if (decision.kind === "local") {
|
|
798
802
|
node.emitEvent({
|
|
799
803
|
type: "PONG",
|
|
800
804
|
at: ts(),
|
|
@@ -806,7 +810,7 @@ export function onPong(
|
|
|
806
810
|
return;
|
|
807
811
|
}
|
|
808
812
|
node.forwardToRoute(
|
|
809
|
-
route,
|
|
813
|
+
decision.route,
|
|
810
814
|
TYPE.PONG,
|
|
811
815
|
hdr.descriptorId,
|
|
812
816
|
hdr.ttl,
|
|
@@ -826,9 +830,12 @@ export function onQueryHit(
|
|
|
826
830
|
peerKey: peer.key,
|
|
827
831
|
ts: node.now(),
|
|
828
832
|
});
|
|
829
|
-
const
|
|
830
|
-
|
|
831
|
-
|
|
833
|
+
const decision = responseRouteDecision(
|
|
834
|
+
node.queryRoutes.get(hdr.descriptorIdHex),
|
|
835
|
+
{ nodeMode: node.nodeMode() },
|
|
836
|
+
);
|
|
837
|
+
if (decision.kind === "drop") return;
|
|
838
|
+
if (decision.kind === "local") {
|
|
832
839
|
for (const result of qh.results) {
|
|
833
840
|
const hit: SearchHit = {
|
|
834
841
|
resultNo: node.resultSeq++,
|
|
@@ -854,9 +861,8 @@ export function onQueryHit(
|
|
|
854
861
|
}
|
|
855
862
|
return;
|
|
856
863
|
}
|
|
857
|
-
if (node.nodeMode() === "leaf") return;
|
|
858
864
|
node.forwardToRoute(
|
|
859
|
-
route,
|
|
865
|
+
decision.route,
|
|
860
866
|
TYPE.QUERY_HIT,
|
|
861
867
|
hdr.descriptorId,
|
|
862
868
|
hdr.ttl,
|
|
@@ -877,10 +883,13 @@ export async function onPush(
|
|
|
877
883
|
return;
|
|
878
884
|
}
|
|
879
885
|
if (node.nodeMode() === "leaf") return;
|
|
880
|
-
const
|
|
881
|
-
|
|
886
|
+
const decision = responseRouteDecision(
|
|
887
|
+
node.pushRoutes.get(push.serventIdHex),
|
|
888
|
+
{ nodeMode: node.nodeMode() },
|
|
889
|
+
);
|
|
890
|
+
if (decision.kind !== "forward") return;
|
|
882
891
|
node.forwardToRoute(
|
|
883
|
-
route,
|
|
892
|
+
decision.route,
|
|
884
893
|
TYPE.PUSH,
|
|
885
894
|
hdr.descriptorId,
|
|
886
895
|
hdr.ttl,
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TYPE } from "../const";
|
|
2
|
+
import {
|
|
3
|
+
DEFAULT_QRP_ENTRY_BITS,
|
|
4
|
+
QrpTable,
|
|
5
|
+
validateRemoteQrpPatchSequence,
|
|
6
|
+
validateRemoteQrpReset,
|
|
7
|
+
} from "../query_routing/qrp";
|
|
2
8
|
import { errMsg } from "../shared";
|
|
3
9
|
import { parseRouteTableUpdate } from "./codec";
|
|
4
10
|
import type { GnutellaServent } from "./node";
|
|
@@ -7,11 +13,6 @@ import {
|
|
|
7
13
|
sendPublishedQrpToMeshPeers,
|
|
8
14
|
} from "./node_query_routing";
|
|
9
15
|
import type { Peer } from "./node_types";
|
|
10
|
-
import {
|
|
11
|
-
QrpTable,
|
|
12
|
-
validateRemoteQrpPatchSequence,
|
|
13
|
-
validateRemoteQrpReset,
|
|
14
|
-
} from "./qrp";
|
|
15
16
|
|
|
16
17
|
function rejectQrpUpdate(
|
|
17
18
|
node: GnutellaServent,
|