gnutella 1.0.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 +189 -0
- package/DEVELOPER.md +193 -0
- package/LICENSE +674 -0
- package/QUICKSTART.md +133 -0
- package/README.md +74 -0
- package/bin/gnutella.ts +15 -0
- package/gnutella.json.example +18 -0
- package/package.json +72 -0
- package/src/cli.ts +692 -0
- package/src/cli_shared.ts +359 -0
- package/src/const.ts +138 -0
- package/src/gwebcache/bootstrap.ts +491 -0
- package/src/gwebcache/response.ts +391 -0
- package/src/gwebcache/shared.ts +116 -0
- package/src/gwebcache/types.ts +187 -0
- package/src/gwebcache_client.ts +13 -0
- package/src/protocol/browse_host.ts +552 -0
- package/src/protocol/client_blocking.ts +29 -0
- package/src/protocol/codec.ts +715 -0
- package/src/protocol/content_urn.ts +170 -0
- package/src/protocol/core_utils.ts +43 -0
- package/src/protocol/file_server.ts +245 -0
- package/src/protocol/ggep.ts +168 -0
- package/src/protocol/handshake.ts +199 -0
- package/src/protocol/http_download_reader.ts +112 -0
- package/src/protocol/magnet.ts +176 -0
- package/src/protocol/node.ts +416 -0
- package/src/protocol/node_handshake.ts +992 -0
- package/src/protocol/node_lifecycle.ts +210 -0
- package/src/protocol/node_protocol_runtime.ts +949 -0
- package/src/protocol/node_qrp_runtime.ts +97 -0
- package/src/protocol/node_query_routing.ts +208 -0
- package/src/protocol/node_state.ts +745 -0
- package/src/protocol/node_tls.ts +257 -0
- package/src/protocol/node_topology.ts +141 -0
- package/src/protocol/node_transfer.ts +455 -0
- package/src/protocol/node_types.ts +106 -0
- package/src/protocol/peer_state.ts +675 -0
- package/src/protocol/qrp.ts +549 -0
- package/src/protocol/query_search.ts +29 -0
- package/src/protocol/share_index.ts +131 -0
- package/src/protocol/share_library.ts +246 -0
- package/src/protocol.ts +36 -0
- package/src/shared.ts +236 -0
- package/src/types.ts +452 -0
package/CLI.md
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# CLI Guide
|
|
2
|
+
|
|
3
|
+
This guide covers the full terminal interface: setup, configuration, commands, and common workflows.
|
|
4
|
+
|
|
5
|
+
## Running GnutellaBun
|
|
6
|
+
|
|
7
|
+
You can use either:
|
|
8
|
+
|
|
9
|
+
- a prebuilt binary from the [releases page](https://github.com/RickCarlino/gnutella-bun-client/releases)
|
|
10
|
+
- the source checkout with Bun
|
|
11
|
+
|
|
12
|
+
If you are running from source:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
bun install
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Throughout this guide, commands use the CLI command:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
gnutella
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
If you are running from source, replace `gnutella` with:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
bun run bin/gnutella.ts
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
If you are using a compiled binary, replace `gnutella` with the executable path.
|
|
31
|
+
|
|
32
|
+
## Create A Config
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
gnutella init --config gnutella.json
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
That creates a default config if it does not already exist.
|
|
39
|
+
|
|
40
|
+
Start the client with:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
gnutella run --config gnutella.json
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Config File Reference
|
|
47
|
+
|
|
48
|
+
GnutellaBun keeps both settings and remembered state in the same JSON file.
|
|
49
|
+
|
|
50
|
+
### Main Settings
|
|
51
|
+
|
|
52
|
+
| Setting | What it is for |
|
|
53
|
+
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
54
|
+
| `config.data_dir` | Root folder for GnutellaBun data. Shared files and downloaded files both live under `<data_dir>/downloads`. |
|
|
55
|
+
| `config.listen_ip` | Local IPv4 address to bind to. Leave `0.0.0.0` unless you need something more specific. |
|
|
56
|
+
| `config.listen_port` | Local TCP port GnutellaBun listens on. |
|
|
57
|
+
| `config.advertised_ip` | External IPv4 address other peers should use to reach you. Useful when your local bind address is not the address seen on the internet. |
|
|
58
|
+
| `config.advertised_port` | External TCP port other peers should use to reach you. |
|
|
59
|
+
| `config.blocked_ips` | IPv4 addresses to refuse, forget, and stop dialing. |
|
|
60
|
+
| `config.gwebcache_urls` | Optional custom Gnutella Web Cache list. When set, it replaces the built-in list. This is mainly useful for local development or controlled environments. |
|
|
61
|
+
| `config.ultrapeer` | Set `true` if you want GnutellaBun to behave like a larger relay-style node. Leave `false` for a lighter client. |
|
|
62
|
+
| `config.max_ultrapeer_connections` | Cap for ultrapeer-to-ultrapeer links. |
|
|
63
|
+
| `config.max_leaf_connections` | Cap for leaf links. |
|
|
64
|
+
| `config.log_ignore` | Event categories to hide when `monitor` is enabled. |
|
|
65
|
+
|
|
66
|
+
### Saved State
|
|
67
|
+
|
|
68
|
+
| Setting | What it is for |
|
|
69
|
+
| ---------------------- | ------------------------------------------------------------------------------------------ |
|
|
70
|
+
| `state.peers` | Optional peers GnutellaBun will try on startup. GnutellaBun can also bootstrap on its own. |
|
|
71
|
+
| `state.servent_id_hex` | GnutellaBun's node identity. In normal use, leave it alone. |
|
|
72
|
+
|
|
73
|
+
## Where Files Go
|
|
74
|
+
|
|
75
|
+
GnutellaBun uses `<data_dir>/downloads` for two things:
|
|
76
|
+
|
|
77
|
+
- files you want to share
|
|
78
|
+
- files you download
|
|
79
|
+
|
|
80
|
+
With the default config, that folder is `./downloads`.
|
|
81
|
+
|
|
82
|
+
## Command Reference
|
|
83
|
+
|
|
84
|
+
### Session And Visibility
|
|
85
|
+
|
|
86
|
+
| Command | What it does |
|
|
87
|
+
| --------------- | ------------------------------------------------------- |
|
|
88
|
+
| `help` | Shows the available commands. |
|
|
89
|
+
| `status` | Shows peer, share, result, and known-peer counts. |
|
|
90
|
+
| `monitor` | Toggles noisy live logging. |
|
|
91
|
+
| `clear` | Clears the current search result list. |
|
|
92
|
+
| `save` | Writes the current config and remembered state to disk. |
|
|
93
|
+
| `sleep` | Pauses scripted command sequences. |
|
|
94
|
+
| `quit` / `exit` | Stops the node cleanly. |
|
|
95
|
+
|
|
96
|
+
### Peers And Network
|
|
97
|
+
|
|
98
|
+
| Command | What it does |
|
|
99
|
+
| ------------------- | --------------------------------------------------- |
|
|
100
|
+
| `peers` | Lists connected peers and their keys such as `p1`. |
|
|
101
|
+
| `connect <ip:port>` | Connects to a peer and remembers it for later runs. |
|
|
102
|
+
| `ping [ttl]` | Sends a network ping. |
|
|
103
|
+
| `blocked` | Lists blocked IPv4 addresses. |
|
|
104
|
+
| `block <ipv4>` | Blocks an IPv4 address and drops matching peers. |
|
|
105
|
+
| `unblock <ipv4>` | Removes an IPv4 address from the block list. |
|
|
106
|
+
|
|
107
|
+
### Searching And Browsing
|
|
108
|
+
|
|
109
|
+
| Command | What it does |
|
|
110
|
+
| --------------------------- | -------------------------------------------------------------------------------- |
|
|
111
|
+
| `query <search terms...>` | Searches the network. |
|
|
112
|
+
| `results` | Shows the current result list. |
|
|
113
|
+
| `info <resultNo>` | Shows detailed information for one result. |
|
|
114
|
+
| `magnet <resultNo>` | Prints a magnet link for one result. |
|
|
115
|
+
| `browse <peerKey\|ip:port>` | Loads a peer's full shared library by connected peer key or direct IPv4 address. |
|
|
116
|
+
|
|
117
|
+
### Sharing And Downloads
|
|
118
|
+
|
|
119
|
+
| Command | What it does |
|
|
120
|
+
| -------------------------------- | ------------------------------------------------------------------------------------------------- |
|
|
121
|
+
| `shares` | Lists the files you are sharing. |
|
|
122
|
+
| `rescan` | Rebuilds the local share index. |
|
|
123
|
+
| `download <resultNo> [destPath]` | Downloads one result. If `destPath` is omitted, GnutellaBun picks a path in the downloads folder. |
|
|
124
|
+
|
|
125
|
+
## Common Tasks
|
|
126
|
+
|
|
127
|
+
### Search Then Download
|
|
128
|
+
|
|
129
|
+
```text
|
|
130
|
+
query jazz piano
|
|
131
|
+
results
|
|
132
|
+
info 1
|
|
133
|
+
download 1
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Browse The Host Behind A Result
|
|
137
|
+
|
|
138
|
+
If a result came from `198.51.100.25:6346`, you can browse that host directly:
|
|
139
|
+
|
|
140
|
+
```text
|
|
141
|
+
browse 198.51.100.25:6346
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
If the peer is already connected, you can also browse by key:
|
|
145
|
+
|
|
146
|
+
```text
|
|
147
|
+
peers
|
|
148
|
+
browse p1
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Remember A Useful Peer
|
|
152
|
+
|
|
153
|
+
```text
|
|
154
|
+
connect 203.0.113.10:6346
|
|
155
|
+
save
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
That peer is then kept in `state.peers` for the next run.
|
|
159
|
+
|
|
160
|
+
### Quiet A Noisy Session
|
|
161
|
+
|
|
162
|
+
Turn live logging on or off:
|
|
163
|
+
|
|
164
|
+
```text
|
|
165
|
+
monitor
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
If you like `monitor` but want less noise, add event names to `config.log_ignore`.
|
|
169
|
+
|
|
170
|
+
## Scripted Usage
|
|
171
|
+
|
|
172
|
+
You can queue CLI commands with repeated `--exec` flags.
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
gnutella run --config gnutella.json \
|
|
176
|
+
--exec 'status' \
|
|
177
|
+
--exec 'query hello world' \
|
|
178
|
+
--exec 'sleep 2' \
|
|
179
|
+
--exec 'results' \
|
|
180
|
+
--exec 'quit'
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
This is useful for smoke tests, local demos, and small automation tasks.
|
|
184
|
+
|
|
185
|
+
## Next Step
|
|
186
|
+
|
|
187
|
+
If you want the shortest path to a working session, go back to [QUICKSTART.md](QUICKSTART.md).
|
|
188
|
+
|
|
189
|
+
If you want to control GnutellaBun from code instead of the terminal, read [DEVELOPER.md](DEVELOPER.md).
|
package/DEVELOPER.md
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# Developer Guide
|
|
2
|
+
|
|
3
|
+
Use this guide if you want to run GnutellaBun inside your own TypeScript app instead of driving it through the CLI.
|
|
4
|
+
|
|
5
|
+
Most apps only need three things:
|
|
6
|
+
|
|
7
|
+
- `loadDoc()` to load or create a config file
|
|
8
|
+
- `GnutellaServent` to run the node
|
|
9
|
+
- the public getters and actions on the node instance
|
|
10
|
+
|
|
11
|
+
## Basic Example
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { GnutellaServent, loadDoc, type GnutellaEvent } from "gnutella";
|
|
15
|
+
|
|
16
|
+
const configPath = "./gnutella.json";
|
|
17
|
+
const doc = await loadDoc(configPath);
|
|
18
|
+
|
|
19
|
+
const node = new GnutellaServent(configPath, doc, {
|
|
20
|
+
onEvent(event: GnutellaEvent) {
|
|
21
|
+
if (event.type === "QUERY_RESULT") {
|
|
22
|
+
console.log(
|
|
23
|
+
`#${event.hit.resultNo} ${event.hit.fileName} from ${event.hit.remoteHost}:${event.hit.remotePort}`,
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (event.type === "DOWNLOAD_SUCCEEDED") {
|
|
28
|
+
console.log("downloaded to", event.destPath);
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
await node.start();
|
|
34
|
+
await node.connectToPeer("203.0.113.10:6346");
|
|
35
|
+
node.sendQuery("hello world");
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
When you are done:
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
await node.save();
|
|
42
|
+
await node.stop();
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Loading And Saving State
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import { loadDoc } from "gnutella";
|
|
49
|
+
|
|
50
|
+
const doc = await loadDoc("./gnutella.json");
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`loadDoc()` creates a default config if the file does not exist yet.
|
|
54
|
+
|
|
55
|
+
The config file uses the same settings as the CLI, so anything you learn in [CLI.md](CLI.md) also applies here.
|
|
56
|
+
|
|
57
|
+
Call `node.save()` when you want to persist remembered peers, blocked IPs, and other changes immediately.
|
|
58
|
+
|
|
59
|
+
## Starting A Node
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
const node = new GnutellaServent("./gnutella.json", doc);
|
|
63
|
+
await node.start();
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`start()` loads shares, starts listening, and begins normal background work such as peer reconnects.
|
|
67
|
+
|
|
68
|
+
Call `stop()` for a clean shutdown:
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
await node.stop();
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Listening For Events
|
|
75
|
+
|
|
76
|
+
You can subscribe in the constructor with `onEvent`, or later with `subscribe()`.
|
|
77
|
+
|
|
78
|
+
Useful events for most apps:
|
|
79
|
+
|
|
80
|
+
- `QUERY_RESULT`: a search hit arrived
|
|
81
|
+
- `DOWNLOAD_SUCCEEDED`: a download finished
|
|
82
|
+
- `PEER_CONNECTED`: a peer connected
|
|
83
|
+
- `PEER_DROPPED`: a peer disconnected
|
|
84
|
+
- `SHARES_REFRESHED`: the share list changed
|
|
85
|
+
- `MAINTENANCE_ERROR`: background work failed
|
|
86
|
+
|
|
87
|
+
## Common Node Actions
|
|
88
|
+
|
|
89
|
+
### Connect To A Peer
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
await node.connectToPeer("203.0.113.10:6346");
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Search
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
node.sendQuery("ambient techno");
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Then read the result list:
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
const results = node.getResults();
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Browse A Peer
|
|
108
|
+
|
|
109
|
+
Browse a connected peer by key:
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
await node.browsePeer("p1");
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Or browse directly by address:
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
await node.browsePeer("203.0.113.10:6346");
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Browse results are added to the normal result list returned by `getResults()`.
|
|
122
|
+
|
|
123
|
+
### Download A Result
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
await node.downloadResult(1);
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Or choose the destination path yourself:
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
await node.downloadResult(1, "./downloads/example.bin");
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Refresh Shared Files
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
await node.refreshShares();
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Use this after your app adds or removes files from the shared downloads folder.
|
|
142
|
+
|
|
143
|
+
## Reading Runtime State
|
|
144
|
+
|
|
145
|
+
These getters are the ones most apps care about:
|
|
146
|
+
|
|
147
|
+
- `getStatus()`: summary counts
|
|
148
|
+
- `getPeers()`: connected peers
|
|
149
|
+
- `getKnownPeers()`: remembered peer addresses
|
|
150
|
+
- `getShares()`: local shared files
|
|
151
|
+
- `getResults()`: current result list
|
|
152
|
+
- `getDownloads()`: completed downloads
|
|
153
|
+
|
|
154
|
+
Example:
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
const status = node.getStatus();
|
|
158
|
+
const peers = node.getPeers();
|
|
159
|
+
const results = node.getResults();
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Runtime Overrides
|
|
163
|
+
|
|
164
|
+
If you want to change behavior at startup without editing the JSON file first, pass `runtimeConfig` to the constructor:
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
const node = new GnutellaServent(configPath, doc, {
|
|
168
|
+
runtimeConfig: {
|
|
169
|
+
ultrapeer: true,
|
|
170
|
+
gwebCacheUrls: ["http://127.0.0.1:6346/gwc.php"],
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
This is useful when you want one app-specific setup while still keeping the same saved config format.
|
|
176
|
+
|
|
177
|
+
## A Good Default Pattern
|
|
178
|
+
|
|
179
|
+
For most embedding cases, this flow works well:
|
|
180
|
+
|
|
181
|
+
1. `loadDoc()`
|
|
182
|
+
2. `new GnutellaServent(...)`
|
|
183
|
+
3. attach an event listener
|
|
184
|
+
4. `start()`
|
|
185
|
+
5. `connectToPeer(...)` or rely on remembered peers
|
|
186
|
+
6. `sendQuery(...)` or `browsePeer(...)`
|
|
187
|
+
7. inspect `getResults()`
|
|
188
|
+
8. `downloadResult(...)` when needed
|
|
189
|
+
9. `save()` and `stop()` on shutdown
|
|
190
|
+
|
|
191
|
+
## Next Step
|
|
192
|
+
|
|
193
|
+
If you are mainly using the terminal, read [CLI.md](CLI.md) instead.
|