mirror of
https://github.com/go-i2p/go-i2p.git
synced 2025-08-19 09:45:28 -04:00
Compare commits
281 Commits
noise-expe
...
master
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f9127c0998 | ||
![]() |
b9e73d816d | ||
![]() |
4edc7b392d | ||
![]() |
d7888ac9be | ||
![]() |
68408bb48e | ||
![]() |
4715b76ade | ||
![]() |
ac7e369b6a | ||
![]() |
7d51d83b40 | ||
![]() |
89c82cb2fe | ||
![]() |
808f7d6fdf | ||
![]() |
537ab808f8 | ||
![]() |
b41bb0eef8 | ||
![]() |
8787fea069 | ||
![]() |
fc9734d43d | ||
![]() |
0a262d5780 | ||
![]() |
2f233e931d | ||
![]() |
e9991099b7 | ||
![]() |
761dcb5f98 | ||
![]() |
f68d9b5606 | ||
![]() |
9fd3400585 | ||
![]() |
c85822163b | ||
![]() |
e2fdb7c4e0 | ||
![]() |
1babf06091 | ||
![]() |
62e565b36c | ||
![]() |
c7a17eac86 | ||
![]() |
89e53fdb9f | ||
![]() |
ebdd1ae0aa | ||
![]() |
b65f6c2682 | ||
![]() |
14a0e56f6a | ||
![]() |
4a89c14734 | ||
![]() |
09fe22178d | ||
![]() |
ef156f6944 | ||
![]() |
a4acb01be9 | ||
![]() |
dd116095aa | ||
![]() |
1922f3a0ab | ||
![]() |
2a28c8ee01 | ||
![]() |
9cb4af8f06 | ||
![]() |
56faebd746 | ||
![]() |
8b035711b6 | ||
![]() |
c93b258844 | ||
![]() |
2df5d23528 | ||
![]() |
98ea3d55c4 | ||
![]() |
b5454a4317 | ||
![]() |
83502face7 | ||
![]() |
c99b15ba7f | ||
![]() |
8e73c36922 | ||
![]() |
89b1995593 | ||
![]() |
4577408d6d | ||
![]() |
e7e26ae021 | ||
![]() |
1d1568de71 | ||
![]() |
b21a6cee9e | ||
![]() |
35b47969b0 | ||
![]() |
816df5642c | ||
![]() |
1bd439f989 | ||
![]() |
6158eb68f3 | ||
![]() |
03eeeab781 | ||
![]() |
0099392f6d | ||
![]() |
a09f155835 | ||
![]() |
fa561fc431 | ||
![]() |
c5125c1bfd | ||
![]() |
9e1bac3ff1 | ||
![]() |
b4e1f3cfdf | ||
![]() |
d4ff0e373c | ||
![]() |
0c9c8270a5 | ||
![]() |
f2bacc5018 | ||
![]() |
94691f1e75 | ||
![]() |
8c4f718601 | ||
![]() |
9a0d164276 | ||
![]() |
f3f5d744ed | ||
![]() |
3b9fb603f4 | ||
![]() |
29d5a20216 | ||
![]() |
3c252e22cd | ||
![]() |
dcb11d1fda | ||
![]() |
a721856688 | ||
![]() |
b66c5813cb | ||
![]() |
441549743d | ||
![]() |
30f84713ea | ||
![]() |
6057677956 | ||
![]() |
c026b9a4a5 | ||
![]() |
9c6cfc14e5 | ||
![]() |
4533c2fd92 | ||
![]() |
89e51820f1 | ||
![]() |
17a789bed7 | ||
![]() |
d236f19f81 | ||
![]() |
d0b81d9ce9 | ||
![]() |
06cf6b41b4 | ||
![]() |
ac8349d083 | ||
![]() |
45296be6d3 | ||
![]() |
1f25f0c9b3 | ||
![]() |
d1a708a594 | ||
![]() |
b153bfc050 | ||
![]() |
d401b06c0f | ||
![]() |
9091834074 | ||
![]() |
8561b3ec69 | ||
![]() |
8aac97351d | ||
![]() |
3142a394aa | ||
![]() |
f2b6d4bc01 | ||
![]() |
fa0a42855c | ||
![]() |
3212cae276 | ||
![]() |
ad7bac666b | ||
![]() |
ba0c89d567 | ||
![]() |
6a64b28bb3 | ||
![]() |
9fa714f648 | ||
![]() |
eda403443d | ||
![]() |
84cc45d3e4 | ||
![]() |
598ee1eb70 | ||
![]() |
bd6edf446d | ||
![]() |
94e43f8aa6 | ||
![]() |
7bdaf6d4ea | ||
![]() |
393263294e | ||
![]() |
55f92bdd8a | ||
![]() |
8ea238f3dd | ||
![]() |
91d8b30495 | ||
![]() |
ea4d126358 | ||
![]() |
f46bd95b68 | ||
![]() |
35eb66084b | ||
![]() |
a9289dd4d3 | ||
![]() |
7f78fdf784 | ||
![]() |
ae4970b3a9 | ||
![]() |
3d6a08a76b | ||
![]() |
18b2afe828 | ||
![]() |
c6867e0b16 | ||
![]() |
d0b4db769e | ||
![]() |
26a9a00b34 | ||
![]() |
99df4c7ce8 | ||
![]() |
b95b0c4fa3 | ||
![]() |
036f9116a5 | ||
![]() |
d97624282e | ||
![]() |
46af6d55ef | ||
![]() |
9591f496eb | ||
![]() |
71fff44d4b | ||
![]() |
6b2f231c36 | ||
![]() |
4eeaf915f0 | ||
![]() |
440b9e8118 | ||
![]() |
8bc5ca162a | ||
![]() |
bd92221d56 | ||
![]() |
22111a6cb7 | ||
![]() |
74d2998e10 | ||
![]() |
0b89baf98b | ||
![]() |
daac1a59b5 | ||
![]() |
6f65a7c068 | ||
![]() |
db91315582 | ||
![]() |
5f3a7f2340 | ||
![]() |
8494da07a7 | ||
![]() |
832e0d9114 | ||
![]() |
8d56d033ae | ||
![]() |
ad22d3e249 | ||
![]() |
f55788e8ab | ||
![]() |
2a4f4d6186 | ||
![]() |
ca1180c57f | ||
![]() |
76c3e5f293 | ||
![]() |
91abe52725 | ||
![]() |
a0ad9e0122 | ||
![]() |
b23edc28d1 | ||
![]() |
b547faf286 | ||
![]() |
a145555bb2 | ||
![]() |
280c877d39 | ||
![]() |
ef4d4658c0 | ||
![]() |
15bf28403e | ||
![]() |
b40c0ab6f9 | ||
![]() |
b952be5e08 | ||
![]() |
aafbf74986 | ||
![]() |
3cdc5676eb | ||
![]() |
d41efdba0e | ||
![]() |
edc436ac39 | ||
![]() |
414b489b37 | ||
![]() |
da875738e4 | ||
![]() |
2a027ebb6c | ||
![]() |
d658dee6de | ||
![]() |
8fde3c9400 | ||
![]() |
9421374384 | ||
![]() |
daad2dcacd | ||
![]() |
5f8dc3f9a2 | ||
![]() |
9cc2e8f410 | ||
![]() |
6ac46aa747 | ||
![]() |
5548b865b4 | ||
![]() |
55245b2aa7 | ||
![]() |
208051f92d | ||
![]() |
8a672ca6ca | ||
![]() |
45def9dd0c | ||
![]() |
cb1da321b9 | ||
![]() |
d291624436 | ||
![]() |
a58f64566f | ||
![]() |
891d915bb2 | ||
![]() |
a0a8704c6c | ||
![]() |
c68acf848e | ||
![]() |
7a6927cf53 | ||
![]() |
37e11ffee1 | ||
![]() |
e15e427f60 | ||
![]() |
f0803a095e | ||
![]() |
bf7e88bec1 | ||
![]() |
065ceeb88f | ||
![]() |
ca4a7a13ea | ||
![]() |
0b0753cac1 | ||
![]() |
40c2c4806c | ||
![]() |
9e3c8bcb98 | ||
![]() |
9b4bf2663d | ||
![]() |
4a6f49d14a | ||
![]() |
5d789973b2 | ||
![]() |
08127861f1 | ||
![]() |
0e6ffd856b | ||
![]() |
10daacbc9b | ||
![]() |
eeb1e215a5 | ||
![]() |
08e599e59a | ||
![]() |
30f5565217 | ||
![]() |
fc3ba17af5 | ||
![]() |
631f8d1850 | ||
![]() |
cc43160bb9 | ||
![]() |
09acf3d23d | ||
![]() |
cbe4af8459 | ||
![]() |
b72ed0a37d | ||
![]() |
07268df720 | ||
![]() |
def8789b77 | ||
![]() |
59c53bc5c1 | ||
![]() |
ee56e0f40f | ||
![]() |
4e2b55ccbe | ||
![]() |
64d90a157c | ||
![]() |
3acff32f17 | ||
![]() |
362513bbe5 | ||
![]() |
c9f3227116 | ||
![]() |
f0702ffba9 | ||
![]() |
11b9018630 | ||
![]() |
f6daa5d9b6 | ||
![]() |
58d1f0d815 | ||
![]() |
62ececf102 | ||
![]() |
1d90db3239 | ||
![]() |
f729bda62d | ||
![]() |
4ad0f97bfe | ||
![]() |
e296441f29 | ||
![]() |
62086c7d04 | ||
![]() |
ddba94d6ae | ||
![]() |
767b91df49 | ||
![]() |
1292098cf0 | ||
![]() |
24bc4c3c17 | ||
![]() |
81eb270351 | ||
![]() |
b6f197cf92 | ||
![]() |
c10d98a3b2 | ||
![]() |
6d16ca5f87 | ||
![]() |
003d6c9ab8 | ||
![]() |
015c4b23e2 | ||
![]() |
e29c3c7abb | ||
![]() |
6f6291a9f6 | ||
![]() |
767864d457 | ||
![]() |
0a98236d85 | ||
![]() |
c1fa63f6ec | ||
![]() |
a75c275b4c | ||
![]() |
d40b3e0cd3 | ||
![]() |
2ee2d77d7c | ||
![]() |
df45c19272 | ||
![]() |
f6894e9064 | ||
![]() |
b36ef65a10 | ||
![]() |
271cf56ded | ||
![]() |
a29fa0bc03 | ||
![]() |
63c48dd3b7 | ||
![]() |
8bec47efd2 | ||
![]() |
69a50e2035 | ||
![]() |
8319444890 | ||
![]() |
b378661e0e | ||
![]() |
f4086e5f68 | ||
![]() |
877fc707c4 | ||
![]() |
98d05e27c8 | ||
![]() |
8c2b952616 | ||
![]() |
4020db8a19 | ||
![]() |
67a02f5d69 | ||
![]() |
ca1280231c | ||
![]() |
02b309df43 | ||
![]() |
a5b3c3f194 | ||
![]() |
0aa7a5554b | ||
![]() |
266a1b71d6 | ||
![]() |
d32f2e78ab | ||
![]() |
9e806bc32e | ||
![]() |
c52112a36f | ||
![]() |
db0fd9f7e9 | ||
![]() |
3ab258cde6 | ||
![]() |
20b9bbd8e4 | ||
![]() |
1fa520613c | ||
![]() |
fb99b98a7e | ||
![]() |
d6b8cd9d4d | ||
![]() |
92e4656774 | ||
![]() |
5f2bfb8d9d | ||
![]() |
9494c226a6 |
19
.github/workflows/auto-assign.yml
vendored
Normal file
19
.github/workflows/auto-assign.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
name: Auto Assign
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
pull_request:
|
||||
types: [opened]
|
||||
jobs:
|
||||
run:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: 'Auto-assign issue'
|
||||
uses: pozil/auto-assign-issue@v1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
assignees: eyedeekay
|
||||
numOfAssignee: 1
|
60
.github/workflows/page.yml
vendored
Normal file
60
.github/workflows/page.yml
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
name: Generate and Deploy GitHub Pages
|
||||
|
||||
on:
|
||||
# Run once hourly
|
||||
schedule:
|
||||
- cron: '0 * * * *'
|
||||
# Allow manual trigger
|
||||
workflow_dispatch:
|
||||
# Run on pushes to main branch
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Fetch all history for proper repo data
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.24.x'
|
||||
cache: true
|
||||
|
||||
- name: Build Site Generator
|
||||
run: |
|
||||
go install github.com/go-i2p/go-gh-page/cmd/github-site-gen@latest
|
||||
export GOBIN=$(go env GOPATH)/bin
|
||||
cp -v "$GOBIN/github-site-gen" ./github-site-gen
|
||||
# Ensure the binary is executable
|
||||
chmod +x github-site-gen
|
||||
|
||||
- name: Generate Site
|
||||
run: |
|
||||
# Determine current repository owner and name
|
||||
REPO_OWNER=$(echo $GITHUB_REPOSITORY | cut -d '/' -f 1)
|
||||
REPO_NAME=$(echo $GITHUB_REPOSITORY | cut -d '/' -f 2)
|
||||
|
||||
# Generate the site
|
||||
./github-site-gen -repo "${REPO_OWNER}/${REPO_NAME}" -output ./site
|
||||
|
||||
# Create a .nojekyll file to disable Jekyll processing
|
||||
touch ./site/.nojekyll
|
||||
|
||||
# Add a .gitattributes file to ensure consistent line endings
|
||||
echo "* text=auto" > ./site/.gitattributes
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
uses: JamesIves/github-pages-deploy-action@v4
|
||||
with:
|
||||
folder: site # The folder the action should deploy
|
||||
branch: gh-pages # The branch the action should deploy to
|
||||
clean: true # Automatically remove deleted files from the deploy branch
|
||||
commit-message: "Deploy site generated on ${{ github.sha }}"
|
89
.github/workflows/tests.yml
vendored
Normal file
89
.github/workflows/tests.yml
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
name: Go Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, master ]
|
||||
pull_request:
|
||||
branches: [ main, master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.21'
|
||||
- run: make build
|
||||
env:
|
||||
GO: go
|
||||
CGO_ENABLED: 0
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false # Ensure all matrix jobs run even if some fail
|
||||
matrix:
|
||||
test_target:
|
||||
- "test-string-all"
|
||||
- "test-mapping-all"
|
||||
- "test-crypto-aes-all"
|
||||
- "test-crypto-dsa-all"
|
||||
- "test-crypto-ed25519-all"
|
||||
- "test-crypto-elg-all"
|
||||
- "test-crypto-hmac-all"
|
||||
- "test-i2np-header-all"
|
||||
- "test-key-cert-all"
|
||||
- "test-keys-cert-all"
|
||||
- "test-lease-set-all"
|
||||
- "test-noise-transport-all"
|
||||
- "test-router-address-all"
|
||||
- "test-router-info-all"
|
||||
- "test-su3-all"
|
||||
- "test-tunnel-all"
|
||||
- "test-base32-encode-decode-not-mangled"
|
||||
- "test-base64-encode-decode-not-mangled"
|
||||
- "test-lease-all"
|
||||
- "test-date-time-from-milliseconds"
|
||||
- "test-cert-all"
|
||||
- "test-signatures"
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.21' # Adjust this version as needed
|
||||
|
||||
- name: Cache Go modules
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/go/pkg/mod
|
||||
~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
|
||||
- name: Install gofumpt
|
||||
run: go install mvdan.cc/gofumpt@latest
|
||||
|
||||
- name: Go mod tidy
|
||||
run: go mod tidy
|
||||
|
||||
- name: Run ${{ matrix.test_target }}
|
||||
run: make ${{ matrix.test_target }}
|
||||
env:
|
||||
GO: go
|
||||
DEBUG_I2P: debug
|
||||
CGO_ENABLED: 0
|
||||
|
||||
- name: Upload Test Logs
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.test_target }}-logs
|
||||
path: ./test-logs/${{ matrix.test_target }}.log # Adjust this path as needed
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -9,3 +9,6 @@ go-i2p
|
||||
.idea/
|
||||
router.info
|
||||
log
|
||||
*.gv
|
||||
diff
|
||||
err
|
@@ -1,20 +1,35 @@
|
||||
# Contributing
|
||||
|
||||
Thanks for taking a look at go-i2p! Please reach out if you have any questions or need help getting started.
|
||||
Thanks for taking a look at go-i2p! Please reach out if you have any questions or need help getting started. We have an IRC channel on IRC2P: #go-i2p-dev and we're reachable here at github.com/go-i2p also.
|
||||
|
||||
## Getting Starting
|
||||
## Getting Started
|
||||
|
||||
Install required dependencies
|
||||
|
||||
This example assumes Ubuntu 16.04
|
||||
This example assumes Ubuntu or Debian based Linux, a reasonably modern version.
|
||||
The instructions will be similar for other Linux distributions with slightly different package managers and package names.
|
||||
|
||||
```sh
|
||||
go get github.com/hkparker/go-i2p
|
||||
go get github.com/Sirupsen/logrus
|
||||
go get github.com/stretchr/testify/assert
|
||||
# For obtaining, modifying, compiling, and tracking changes to go-i2p, install:
|
||||
sudo apt-get install golang-go make git
|
||||
# If you want to generate markdown versions of the godoc locally, also install:
|
||||
go install github.com/robertkrimen/godocdown/godocdown@master
|
||||
# If you want to generate call graphs locally, also install:
|
||||
go install github.com/ofabry/go-callvis@master
|
||||
```
|
||||
|
||||
Fork go-i2p and clone it into your workspace. Make sure you can execute `go test ./...` in the project's root directory. At that point you should have everything you need to start making changes and opening pull requests. If you aren't sure what to work on, take a look at some good [getting started issues](https://github.com/hkparker/go-i2p/issues?q=is%3Aopen+is%3Aissue+label%3A%22start+here%22).
|
||||
On Windows, one must install the latest versions of Go and Git Bash from their respective sources.
|
||||
|
||||
## Set up your workspace:
|
||||
|
||||
```sh
|
||||
github_username=yourusername
|
||||
cd $(go env GOPATH)
|
||||
git clone git@github.com:$github_username/go-i2p github.com/go-i2p/go-i2p
|
||||
github.com/go-i2p/go-i2p
|
||||
```
|
||||
|
||||
Fork go-i2p and clone it into your workspace. Make sure you can execute `go test ./...` in the project's root directory. At that point you should have everything you need to start making changes and opening pull requests.
|
||||
|
||||
## I2P Specifications
|
||||
|
||||
@@ -26,9 +41,17 @@ The I2P community maintains up-to-date [specifications](https://geti2p.net/spec)
|
||||
|
||||
## Conventions
|
||||
|
||||
#### Errors
|
||||
|
||||
We use oops to provide context to the errors we return. Do not use `errors.New` or `fmt.Errorf` when returning errors from functions. Instead, wrap raw errors in oops errors. When an error is recieved, used oops to supplement the log output.
|
||||
|
||||
It is OK to use `fmt.Errorf` for declaring custom error types.
|
||||
|
||||
#### Logging
|
||||
|
||||
Logrus is used for logging across all of go-i2p. All log statements should contain an `at` fields and a `reason` field. Here is a good example from the go-i2p implementation of a LeaseSet:
|
||||
Logrus is used for logging across all of go-i2p. We have a small extension of logrus at https://github.com/go-i2p/logger which we use to add a "Fail Fast mode." We are mostly converted over to using it.
|
||||
|
||||
All log statements should contain an `at` fields and a `reason` field. Here is a good example from the go-i2p implementation of a LeaseSet:
|
||||
|
||||
```go
|
||||
log.WithFields(log.Fields{
|
||||
@@ -56,4 +79,4 @@ func TestRouterAddressCountReturnsCorrectCount(t *testing.T) {
|
||||
|
||||
## Pull Requests
|
||||
|
||||
Pull requests should pass all tests, test all new behavior, and be correctly formatted by `gofmt` before merge. Feel free to open incomplete pull requests if you are struggling, I will enthusiasticlly help you complete the PR in any way needed.
|
||||
Pull requests should pass all tests, test all new behavior, and be correctly formatted by `gofumpt -w -s -extra` before merge. Feel free to open incomplete pull requests and ask for help and advice.
|
58
Makefile
58
Makefile
@@ -3,6 +3,7 @@ RELEASE_VERSION=${RELEASE_TAG}
|
||||
RELEASE_DESCRIPTION=`cat PASTA.md`
|
||||
REPO := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
CGO_ENABLED=0
|
||||
export DEBUG_I2P=debug
|
||||
|
||||
ifdef GOROOT
|
||||
GO = $(GOROOT)/bin/go
|
||||
@@ -25,8 +26,29 @@ build: clean $(EXE)
|
||||
$(EXE):
|
||||
$(GO) build --tags netgo,osusergo -v -o $(EXE)
|
||||
|
||||
test: check_gofumpt fmt
|
||||
$(GO) test -v -failfast ./lib/common/...
|
||||
# Include test definitions
|
||||
-include doc/tests/*.mk
|
||||
|
||||
test: test-string-all \
|
||||
test-mapping-all \
|
||||
test-crypto-aes-all \
|
||||
test-crypto-dsa-all \
|
||||
test-crypto-ed25519-all \
|
||||
test-crypto-elg-all \
|
||||
test-crypto-hmac-all \
|
||||
test-i2np-header-all \
|
||||
test-key-cert-all \
|
||||
test-keys-cert-all \
|
||||
test-lease-set-all \
|
||||
test-noise-transport-all \
|
||||
test-router-address-all \
|
||||
test-router-info-all \
|
||||
test-su3-all \
|
||||
test-tunnel-all \
|
||||
test-base32-encode-decode-not-mangled \
|
||||
test-base64-encode-decode-not-mangled \
|
||||
test-lease-all \
|
||||
test-date-time-from-milliseconds
|
||||
|
||||
clean:
|
||||
$(GO) clean -v
|
||||
@@ -42,35 +64,5 @@ info:
|
||||
release:
|
||||
github-release release -u go-i2p -r go-i2p -n "${RELEASE_VERSION}" -t "${RELEASE_TAG}" -d "${RELEASE_DESCRIPTION}" -p
|
||||
|
||||
callvis:
|
||||
go-callvis -format svg -focus upgrade -group pkg,type -limit github.com/go-i2p/go-i2p github.com/go-i2p/go-i2p
|
||||
|
||||
godoc:
|
||||
find lib -type d -exec bash -c "ls {}/*.go && godocdown -o ./{}/doc.md ./{}" \;
|
||||
|
||||
# Include test definitions
|
||||
-include doc/tests/*.mk
|
||||
|
||||
# Define the all-tests target that runs every test suite
|
||||
test-all: test-string-all \
|
||||
test-mapping-all \
|
||||
test-crypto-aes-all \
|
||||
test-crypto-dsa-all \
|
||||
test-crypto-ed25519-all \
|
||||
test-crypto-elg-all \
|
||||
test-crypto-hmac-all \
|
||||
test-i2np-header-all \
|
||||
test-i2np-build-request-all \
|
||||
test-key-cert-all \
|
||||
test-keys-cert-all \
|
||||
test-lease-set-all \
|
||||
test-noise-transport-all \
|
||||
test-router-address-all \
|
||||
test-router-info-all \
|
||||
test-su3-all \
|
||||
test-tunnel-all
|
||||
|
||||
#-include $(shell find doc/tests -type f -name '*.mk') #search for .mk files recursively
|
||||
|
||||
#test-base64-encode-decode-not-mangled:
|
||||
#go test -v ./lib/common/base64 -run TestEncodeDecodeNotMangled
|
||||
./callgraph.sh
|
||||
|
18
PASTA.md
18
PASTA.md
@@ -1,18 +0,0 @@
|
||||
At long last... something useful
|
||||
================================
|
||||
|
||||
It's been 2 years of me mostly not having time to work on go-i2p itself since my last update.
|
||||
However, after much waiting, this library is actually **useful** for something.
|
||||
It is now being used in the `reseed-tools` application to examine RouterInfos prior to including them in reseed bundles.
|
||||
Routers that self-report as unreachable or congested will be excluded from future reseed bundles.
|
||||
Additionally, routers that self-report an old version will be excluded from reseed bundles.
|
||||
This should help new users build better connections faster with the existing, working router implementations.
|
||||
|
||||
This is not a working release of a go-i2p router
|
||||
------------------------------------------------
|
||||
|
||||
It is a numbered version of the go-i2p library, which is pre-release, expressly for use in the `reseed-tools` application.
|
||||
The common library works, and so do some of the cryptographic primitives, however the API is unstable and the software itself is certain to have serious bugs outside of a few well-tested areas.
|
||||
If you're using it for something other than parsing and analyzing RouterInfos and LeaseSets, you'll probably encounter bugs.
|
||||
Please report them to the https://github.com/go-i2p/go-i2p
|
||||
Use any part of it at your own risk.
|
41
README.md
41
README.md
@@ -15,33 +15,31 @@ please keep up with these changes, as they will not be backward compatible and r
|
||||
- [ ] Datagrams
|
||||
- [ ] I2CP
|
||||
- [ ] Message routing
|
||||
- [ ] SAM
|
||||
- [ ] Streaming
|
||||
- [ ] Tunnel Manager
|
||||
- Cryptographic primitives
|
||||
- Signing
|
||||
- [ ] ECDSA_SHA256_P256
|
||||
- [ ] ECDSA_SHA384_P384
|
||||
- [ ] ECDSA_SHA512_P521
|
||||
- [ ] Ed25519
|
||||
- [X] Ed25519
|
||||
- Verifying
|
||||
- [ ] DSA
|
||||
- [X] DSA
|
||||
- [ ] ECDSA_SHA256_P256
|
||||
- [ ] ECDSA_SHA384_P384
|
||||
- [ ] ECDSA_SHA512_P521
|
||||
- [ ] RSA_SHA256_2048
|
||||
- [ ] RSA_SHA384_3072
|
||||
- [ ] RSA_SHA512_4096
|
||||
- [ ] Ed25519
|
||||
- [X] Ed25519
|
||||
- [ ] Red25519
|
||||
- [ ] ElGamal
|
||||
- [ ] AES256
|
||||
- [ ] X25519
|
||||
- [ ] ChaCha20/Poly1305
|
||||
- [X] ElGamal
|
||||
- [X] AES256
|
||||
- [X] X25519
|
||||
- [X] ChaCha20/Poly1305
|
||||
- [ ] Elligator2
|
||||
- [ ] HKDF
|
||||
- [ ] HMAC
|
||||
- [/] Noise subsystem
|
||||
- [X] HMAC
|
||||
- [X] Noise subsystem
|
||||
- End-to-End Crypto
|
||||
- [ ] Garlic messages
|
||||
- [ ] ElGamal/AES+SessionTag
|
||||
@@ -50,8 +48,8 @@ please keep up with these changes, as they will not be backward compatible and r
|
||||
- [ ] Message parsing
|
||||
- [ ] Message handling
|
||||
- NetDB
|
||||
- [/] Local storage
|
||||
- [/] Persistence to disk
|
||||
- [~] Local storage
|
||||
- [~] Persistence to disk
|
||||
- [X] Reseeding
|
||||
- [ ] Lookups
|
||||
- [ ] Expiry
|
||||
@@ -62,7 +60,7 @@ please keep up with these changes, as they will not be backward compatible and r
|
||||
- Transports
|
||||
- [X] Transport manager
|
||||
- NTCP2
|
||||
- [ ] Handshake
|
||||
- [X] Handshake
|
||||
- [ ] Session tracking
|
||||
- [ ] Automatic session creation
|
||||
- SSU2
|
||||
@@ -94,7 +92,7 @@ please keep up with these changes, as they will not be backward compatible and r
|
||||
- [X] Session Tag
|
||||
|
||||
## Verbosity ##
|
||||
Logging can be enabled and configured using the DEBUG_I2P environment variable. By default, logging is disabled.
|
||||
Logging can be enabled and configured using the `DEBUG_I2P` environment variable. By default, logging is disabled.
|
||||
|
||||
There are three available log levels:
|
||||
|
||||
@@ -111,7 +109,18 @@ export DEBUG_I2P=warn
|
||||
export DEBUG_I2P=error
|
||||
```
|
||||
|
||||
If I2P_DEBUG is set to an unrecognized variable, it will fall back to "debug".
|
||||
If DEBUG_I2P is set to an unrecognized variable, it will fall back to "debug".
|
||||
|
||||
## Fast-Fail mode ##
|
||||
|
||||
Fast-Fail mode can be activated by setting `WARNFAIL_I2P` to any non-empty value. When set, every warning or error is Fatal.
|
||||
It is unsafe for production use, and intended only for debugging and testing purposes.
|
||||
|
||||
```shell
|
||||
export WARNFAIL_I2P=true
|
||||
```
|
||||
|
||||
If `WARNFAIL_I2P` is set and `DEBUG_I2P` is unset, `DEBUG_I2P` will be set to `debug`.
|
||||
|
||||
## Contributing
|
||||
|
||||
|
41
ROADMAP.md
Normal file
41
ROADMAP.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# go-i2p Implementation Roadmap
|
||||
|
||||
## Transport Layer (NTCP2)
|
||||
- Build on existing lib/transport/noise implementation
|
||||
- Core NTCP2 components:
|
||||
* Session handshake using noise protocol
|
||||
* Connection management
|
||||
* I2NP message transport
|
||||
|
||||
## Reseed System
|
||||
- SU3 file format implementation:
|
||||
* Format parsing and validation(Much of this work is done in reseed-tools, may need to be moved here)
|
||||
* Signature verification system(Much of this work is done in reseed-tools, may need to be moved here)
|
||||
- Local reseed functionality:
|
||||
* File-based reseed operations
|
||||
- Self-signed/Package-pinned X.509 certificate handling for reseed validation
|
||||
|
||||
## NetDb and Database Store
|
||||
- Database Store message handling:
|
||||
* Message structure implementation
|
||||
* Message handling implementation
|
||||
- NetDb core implementation:
|
||||
* RouterInfo management
|
||||
* LeaseSet management
|
||||
* Lookup system
|
||||
* Storage interface
|
||||
* Peer selection logic?(Maybe do something very basic for now like i2pd used to do, and then improve it later, the important part will be interface design at first)
|
||||
|
||||
## Tunnel Implementation
|
||||
- Tunnel cryptography:
|
||||
* Key generation and management
|
||||
* Layered encryption scheme
|
||||
- Message processing:
|
||||
* Build request/response handling
|
||||
* Gateway implementation
|
||||
* Message forwarding logic
|
||||
|
||||
Notes:
|
||||
- Excluding legacy protocols (SSU1, NTCP1, elgamal, DSA)
|
||||
- Leveraging existing noise protocol implementation
|
||||
- SSU2 is not on this roadmap but is fair game for implementation as soon as NTCP2 is done. We're focused on NTCP2 to get this thing sending I2NP messages.
|
19
callgraph.sh
Executable file
19
callgraph.sh
Executable file
@@ -0,0 +1,19 @@
|
||||
#! /usr/bin/env sh
|
||||
|
||||
dirs=$(find lib/ -type d)
|
||||
for dir in $dirs; do
|
||||
files=$(find "$dir" -maxdepth 2 -type f -name "*.go" -not -name "fuzz")
|
||||
#echo "Files in $dir: $files"
|
||||
file=$(echo $files | awk '{print $1}')
|
||||
if [ -z "$file" ]; then
|
||||
echo "no go files, skipping"
|
||||
continue
|
||||
fi
|
||||
packageLine=$(grep -E "^package" $file)
|
||||
package=$(echo $packageLine | awk '{print $2}')
|
||||
echo "Generating callgraph for $package"
|
||||
go-callvis -nostd -focus "$package" -group type -format svg -file $dir/$package "github.com/go-i2p/go-i2p/$dir"
|
||||
godocdown -template template.md -o "$dir/README.md" "./$dir"
|
||||
git add -v "$dir/README.md"
|
||||
git add -v "$dir/$package.svg" "$dir/README.md"
|
||||
done
|
@@ -1,15 +1,15 @@
|
||||
test-crypto-aes-all: test-crypto-aes-core test-crypto-aes-validation test-crypto-aes-padding
|
||||
|
||||
test-crypto-aes-core:
|
||||
go test -v ./lib/crypto -run TestAESEncryptDecrypt
|
||||
$(GO) test -v ./lib/crypto -run TestAESEncryptDecrypt
|
||||
|
||||
test-crypto-aes-validation:
|
||||
go test -v ./lib/crypto -run TestAESEncryptInvalidKey
|
||||
go test -v ./lib/crypto -run TestAESDecryptInvalidInput
|
||||
$(GO) test -v ./lib/crypto -run TestAESEncryptInvalidKey
|
||||
$(GO) test -v ./lib/crypto -run TestAESDecryptInvalidInput
|
||||
|
||||
test-crypto-aes-padding:
|
||||
go test -v ./lib/crypto -run TestPKCS7PadUnpad
|
||||
go test -v ./lib/crypto -run TestPKCS7UnpadInvalidInput
|
||||
$(GO) test -v ./lib/crypto -run TestPKCS7PadUnpad
|
||||
$(GO) test -v ./lib/crypto -run TestPKCS7UnpadInvalidInput
|
||||
|
||||
.PHONY: test-crypto-aes-all \
|
||||
test-crypto-aes-core \
|
||||
|
@@ -1,4 +1,4 @@
|
||||
test-base32-encode-decode-not-mangled:
|
||||
go test -v ./lib/common/base32 -run TestEncodeDecodeNotMangled
|
||||
$(GO) test -v ./lib/common/base32 -run TestEncodeDecodeNotMangled
|
||||
|
||||
.PHONY: test-base32-encode-decode-not-mangled
|
@@ -1,4 +1,4 @@
|
||||
test-base64-encode-decode-not-mangled:
|
||||
go test -v ./lib/common/base64 -run TestEncodeDecodeNotMangled
|
||||
$(GO) test -v ./lib/common/base64 -run TestEncodeDecodeNotMangled
|
||||
|
||||
.PHONY: test-base64-encode-decode-not-mangled
|
@@ -1,22 +1,22 @@
|
||||
test-build-request-all: test-build-request-receive test-build-request-ident test-build-request-components
|
||||
|
||||
test-build-request-receive:
|
||||
go test -v ./lib/i2np -run TestReadBuildRequestRecordReceiveTunnel
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordReceiveTunnel
|
||||
|
||||
test-build-request-ident:
|
||||
go test -v ./lib/i2np -run TestReadBuildRequestRecordOurIdent
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordOurIdent
|
||||
|
||||
test-build-request-components:
|
||||
go test -v ./lib/i2np -run TestReadBuildRequestRecordNextTunnel
|
||||
go test -v ./lib/i2np -run TestReadBuildRequestRecordNextIdent
|
||||
go test -v ./lib/i2np -run TestReadBuildRequestRecordLayerKey
|
||||
go test -v ./lib/i2np -run TestReadBuildRequestRecordIVKey
|
||||
go test -v ./lib/i2np -run TestReadBuildRequestRecordReplyKey
|
||||
go test -v ./lib/i2np -run TestReadBuildRequestRecordReplyIV
|
||||
go test -v ./lib/i2np -run TestReadBuildRequestRecordFlag
|
||||
go test -v ./lib/i2np -run TestReadBuildRequestRecordRequestTime
|
||||
go test -v ./lib/i2np -run TestReadBuildRequestRecordSendMessageID
|
||||
go test -v ./lib/i2np -run TestReadBuildRequestRecordPadding
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordNextTunnel
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordNextIdent
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordLayerKey
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordIVKey
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordReplyKey
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordReplyIV
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordFlag
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordRequestTime
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordSendMessageID
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordPadding
|
||||
|
||||
.PHONY: test-build-request-all \
|
||||
test-build-request-receive \
|
||||
|
@@ -1,49 +1,92 @@
|
||||
|
||||
test-cert-all: test-cert-type test-cert-length test-cert-data test-cert-read test-cert-length-correct test-cert-length-too-short test-cert-length-data-short test-cert-data-correct test-cert-data-too-long test-cert-data-too-short test-cert-read-correct test-cert-read-short test-cert-read-remainder test-cert-read-invalid
|
||||
test-cert-all: test-cert-type test-cert-length test-cert-data test-cert-read test-cert-length-correct test-cert-length-too-short test-cert-length-data-short test-cert-data-correct test-cert-data-too-long test-cert-data-too-short test-cert-read-correct test-cert-read-short test-cert-read-remainder test-cert-read-invalid test-cert-new-null-type test-cert-new-null-payload test-cert-new-key-type test-cert-new-invalid-type test-cert-new-payload-too-long test-cert-bytes-serialization test-cert-fields-after-creation test-cert-zero-length-payload test-cert-new-deux test-cert-invalid-payload-length test-cert-excess-bytes test-cert-serialization test-cert-serialization-excess test-cert-serialization-empty test-cert-serialization-max
|
||||
|
||||
test-cert-type:
|
||||
go test -v ./lib/common/certificate -run TestCertificateTypeIsFirstByte
|
||||
$(GO) test -v ./lib/common/certificate -run TestCertificateTypeIsFirstByte
|
||||
|
||||
test-cert-length:
|
||||
go test -v ./lib/common/certificate -run TestCertificateLength
|
||||
$(GO) test -v ./lib/common/certificate -run TestCertificateLength
|
||||
|
||||
test-cert-data:
|
||||
go test -v ./lib/common/certificate -run TestCertificateData
|
||||
$(GO) test -v ./lib/common/certificate -run TestCertificateData
|
||||
|
||||
test-cert-read:
|
||||
go test -v ./lib/common/certificate -run TestReadCertificate
|
||||
$(GO) test -v ./lib/common/certificate -run TestReadCertificate
|
||||
|
||||
test-cert-length-correct:
|
||||
go test -v ./lib/common/certificate -run TestCertificateLengthCorrect
|
||||
$(GO) test -v ./lib/common/certificate -run TestCertificateLengthCorrect
|
||||
|
||||
test-cert-length-too-short:
|
||||
go test -v ./lib/common/certificate -run TestCertificateLengthErrWhenTooShort
|
||||
$(GO) test -v ./lib/common/certificate -run TestCertificateLengthErrWhenTooShort
|
||||
|
||||
test-cert-length-data-short:
|
||||
go test -v ./lib/common/certificate -run TestCertificateLengthErrWhenDataTooShort
|
||||
$(GO) test -v ./lib/common/certificate -run TestCertificateLengthErrWhenDataTooShort
|
||||
|
||||
test-cert-data-correct:
|
||||
go test -v ./lib/common/certificate -run TestCertificateDataWhenCorrectSize
|
||||
$(GO) test -v ./lib/common/certificate -run TestCertificateDataWhenCorrectSize
|
||||
|
||||
test-cert-data-too-long:
|
||||
go test -v ./lib/common/certificate -run TestCertificateDataWhenTooLong
|
||||
$(GO) test -v ./lib/common/certificate -run TestCertificateDataWhenTooLong
|
||||
|
||||
test-cert-data-too-short:
|
||||
go test -v ./lib/common/certificate -run TestCertificateDataWhenTooShort
|
||||
$(GO) test -v ./lib/common/certificate -run TestCertificateDataWhenTooShort
|
||||
|
||||
test-cert-read-correct:
|
||||
go test -v ./lib/common/certificate -run TestReadCertificateWithCorrectData
|
||||
$(GO) test -v ./lib/common/certificate -run TestReadCertificateWithCorrectData
|
||||
|
||||
test-cert-read-short:
|
||||
go test -v ./lib/common/certificate -run TestReadCertificateWithDataTooShort
|
||||
$(GO) test -v ./lib/common/certificate -run TestReadCertificateWithDataTooShort
|
||||
|
||||
test-cert-read-remainder:
|
||||
go test -v ./lib/common/certificate -run TestReadCertificateWithRemainder
|
||||
$(GO) test -v ./lib/common/certificate -run TestReadCertificateWithRemainder
|
||||
|
||||
test-cert-read-invalid:
|
||||
go test -v ./lib/common/certificate -run TestReadCertificateWithInvalidLength
|
||||
$(GO) test -v ./lib/common/certificate -run TestReadCertificateWithInvalidLength
|
||||
|
||||
test-cert-new-null-type:
|
||||
$(GO) test -v ./lib/common/certificate -run TestNewCertificateNullType
|
||||
|
||||
test-cert-new-null-payload:
|
||||
$(GO) test -v ./lib/common/certificate -run TestNewCertificateNullTypeWithPayload
|
||||
|
||||
test-cert-new-key-type:
|
||||
$(GO) test -v ./lib/common/certificate -run TestNewCertificateKeyType
|
||||
|
||||
test-cert-new-invalid-type:
|
||||
$(GO) test -v ./lib/common/certificate -run TestNewCertificateInvalidType
|
||||
|
||||
test-cert-new-payload-too-long:
|
||||
$(GO) test -v ./lib/common/certificate -run TestNewCertificatePayloadTooLong
|
||||
|
||||
test-cert-bytes-serialization:
|
||||
$(GO) test -v ./lib/common/certificate -run TestCertificateBytesSerialization
|
||||
|
||||
test-cert-fields-after-creation:
|
||||
$(GO) test -v ./lib/common/certificate -run TestCertificateFieldsAfterCreation
|
||||
|
||||
test-cert-zero-length-payload:
|
||||
$(GO) test -v ./lib/common/certificate -run TestCertificateWithZeroLengthPayload
|
||||
|
||||
test-cert-new-deux:
|
||||
$(GO) test -v ./lib/common/certificate -run TestNewCertificateDeuxFunction
|
||||
|
||||
test-cert-invalid-payload-length:
|
||||
$(GO) test -v ./lib/common/certificate -run TestNewCertificateWithInvalidPayloadLength
|
||||
|
||||
test-cert-excess-bytes:
|
||||
$(GO) test -v ./lib/common/certificate -run TestCertificateExcessBytes
|
||||
|
||||
test-cert-serialization:
|
||||
$(GO) test -v ./lib/common/certificate -run TestCertificateSerializationDeserialization
|
||||
|
||||
test-cert-serialization-excess:
|
||||
$(GO) test -v ./lib/common/certificate -run TestCertificateSerializationDeserializationWithExcessBytes
|
||||
|
||||
test-cert-serialization-empty:
|
||||
$(GO) test -v ./lib/common/certificate -run TestCertificateSerializationDeserializationEmptyPayload
|
||||
|
||||
test-cert-serialization-max:
|
||||
$(GO) test -v ./lib/common/certificate -run TestCertificateSerializationDeserializationMaxPayload
|
||||
|
||||
# Declare all targets as PHONY
|
||||
.PHONY: test-cert-all \
|
||||
test-cert-type \
|
||||
test-cert-length \
|
||||
@@ -58,4 +101,19 @@ test-cert-read-invalid:
|
||||
test-cert-read-correct \
|
||||
test-cert-read-short \
|
||||
test-cert-read-remainder \
|
||||
test-cert-read-invalid
|
||||
test-cert-read-invalid \
|
||||
test-cert-new-null-type \
|
||||
test-cert-new-null-payload \
|
||||
test-cert-new-key-type \
|
||||
test-cert-new-invalid-type \
|
||||
test-cert-new-payload-too-long \
|
||||
test-cert-bytes-serialization \
|
||||
test-cert-fields-after-creation \
|
||||
test-cert-zero-length-payload \
|
||||
test-cert-new-deux \
|
||||
test-cert-invalid-payload-length \
|
||||
test-cert-excess-bytes \
|
||||
test-cert-serialization \
|
||||
test-cert-serialization-excess \
|
||||
test-cert-serialization-empty \
|
||||
test-cert-serialization-max
|
@@ -1,2 +1,2 @@
|
||||
test-date-time-from-milliseconds:
|
||||
go test -v ./lib/common/data -run TestTimeFromMilliseconds
|
||||
$(GO) test -v ./lib/common/data -run TestTimeFromMilliseconds
|
@@ -1,17 +1,17 @@
|
||||
test-crypto-dsa-all: test-crypto-dsa test-crypto-dsa-benchmarks
|
||||
|
||||
test-crypto-dsa:
|
||||
go test -v ./lib/crypto -run TestDSA
|
||||
$(GO) test -v ./lib/crypto -run TestDSA
|
||||
|
||||
test-crypto-dsa-benchmarks:
|
||||
go test -v ./lib/crypto -bench=DSA -run=^$
|
||||
$(GO) test -v ./lib/crypto -bench=DSA -run=^$
|
||||
|
||||
# Individual benchmarks
|
||||
test-crypto-dsa-bench-generate:
|
||||
go test -v ./lib/crypto -bench=DSAGenerate -run=^$
|
||||
$(GO) test -v ./lib/crypto -bench=DSAGenerate -run=^$
|
||||
|
||||
test-crypto-dsa-bench-sign-verify:
|
||||
go test -v ./lib/crypto -bench=DSASignVerify -run=^$
|
||||
$(GO) test -v ./lib/crypto -bench=DSASignVerify -run=^$
|
||||
|
||||
.PHONY: test-crypto-dsa-all \
|
||||
test-crypto-dsa \
|
||||
|
@@ -1,7 +1,7 @@
|
||||
test-crypto-ed25519-all: test-crypto-ed25519
|
||||
|
||||
test-crypto-ed25519:
|
||||
go test -v ./lib/crypto -run TestEd25519
|
||||
$(GO) test -v ./lib/crypto -run TestEd25519
|
||||
|
||||
.PHONY: test-crypto-ed25519-all \
|
||||
test-crypto-ed25519
|
||||
|
@@ -1,20 +1,20 @@
|
||||
test-crypto-elg-all: test-crypto-elg test-crypto-elg-benchmarks
|
||||
|
||||
test-crypto-elg:
|
||||
go test -v ./lib/crypto -run TestElg
|
||||
$(GO) test -v ./lib/crypto -run TestElg
|
||||
|
||||
test-crypto-elg-benchmarks:
|
||||
go test -v ./lib/crypto -bench=Elg -run=^$
|
||||
$(GO) test -v ./lib/crypto -bench=Elg -run=^$
|
||||
|
||||
# Individual benchmarks
|
||||
test-crypto-elg-bench-generate:
|
||||
go test -v ./lib/crypto -bench=ElgGenerate -run=^$
|
||||
$(GO) test -v ./lib/crypto -bench=ElgGenerate -run=^$
|
||||
|
||||
test-crypto-elg-bench-encrypt:
|
||||
go test -v ./lib/crypto -bench=ElgEncrypt -run=^$
|
||||
$(GO) test -v ./lib/crypto -bench=ElgEncrypt -run=^$
|
||||
|
||||
test-crypto-elg-bench-decrypt:
|
||||
go test -v ./lib/crypto -bench=ElgDecrypt -run=^$
|
||||
$(GO) test -v ./lib/crypto -bench=ElgDecrypt -run=^$
|
||||
|
||||
.PHONY: test-crypto-elg-all \
|
||||
test-crypto-elg \
|
||||
|
@@ -1,25 +1,66 @@
|
||||
|
||||
test-i2np-header-all: test-i2np-type test-i2np-message test-i2np-expiration test-i2np-ntcp-components test-i2np-data test-i2np-regression
|
||||
test-i2np-header-all: test-i2np-type test-i2np-message test-i2np-expiration test-i2np-ntcp-components test-i2np-data test-i2np-regression test-i2np-build-request-record test-i2np-build-response-record test-i2np-database-lookup
|
||||
|
||||
test-i2np-type:
|
||||
go test -v ./lib/i2np -run TestReadI2NPTypeWith
|
||||
$(GO) test -v ./lib/i2np -run TestReadI2NPTypeWith
|
||||
|
||||
test-i2np-message:
|
||||
go test -v ./lib/i2np -run TestReadI2NPNTCPMessageID
|
||||
$(GO) test -v ./lib/i2np -run TestReadI2NPNTCPMessageID
|
||||
|
||||
test-i2np-expiration:
|
||||
go test -v ./lib/i2np -run TestReadI2NPNTCPMessageExpiration
|
||||
go test -v ./lib/i2np -run TestReadI2NPSSUMessageExpiration
|
||||
$(GO) test -v ./lib/i2np -run TestReadI2NPNTCPMessageExpiration
|
||||
$(GO) test -v ./lib/i2np -run TestReadI2NPSSUMessageExpiration
|
||||
|
||||
test-i2np-ntcp-components:
|
||||
go test -v ./lib/i2np -run TestReadI2NPNTCPMessageSize
|
||||
go test -v ./lib/i2np -run TestReadI2NPNTCPMessageChecksum
|
||||
$(GO) test -v ./lib/i2np -run TestReadI2NPNTCPMessageSize
|
||||
$(GO) test -v ./lib/i2np -run TestReadI2NPNTCPMessageChecksum
|
||||
|
||||
test-i2np-data:
|
||||
go test -v ./lib/i2np -run TestReadI2NPNTCPData
|
||||
$(GO) test -v ./lib/i2np -run TestReadI2NPNTCPData
|
||||
|
||||
test-i2np-regression:
|
||||
go test -v ./lib/i2np -run TestCrasherRegression123781
|
||||
$(GO) test -v ./lib/i2np -run TestCrasherRegression123781
|
||||
|
||||
test-i2np-build-request-record:
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordReceiveTunnelTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordReceiveTunnelValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordOurIdentTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordOurIdentValidData
|
||||
|
||||
test-i2np-build-response-record:
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildResponseRecordHashTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildResponseRecordHashValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildResponseRecordRandomDataTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildResponseRecordRandomDataValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildResponseRecordReplyTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildResponseRecordReplyValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildResponseRecordTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildResponseRecordValidData
|
||||
|
||||
test-i2np-database-lookup:
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupKeyTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupKeyValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupFromTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupFromValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupFlagsTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupFlagsValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupReplyTunnelIDTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupReplyTunnelIDNotIncluded
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupReplyTunnelIDValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupSizeTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupSizeValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupExcludedPeersTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupExcludedPeersZeroSize
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupExcludedPeersValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupReplyKeyTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupReplyKeyValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupTagsTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupTagsValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupReplyTagsTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupReplyTagsZeroTags
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupReplyTagsValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupValidData
|
||||
|
||||
.PHONY: test-i2np-header-all \
|
||||
test-i2np-type \
|
||||
@@ -27,4 +68,7 @@ test-i2np-regression:
|
||||
test-i2np-expiration \
|
||||
test-i2np-ntcp-components \
|
||||
test-i2np-data \
|
||||
test-i2np-regression
|
||||
test-i2np-regression \
|
||||
test-i2np-build-request-record \
|
||||
test-i2np-build-response-record \
|
||||
test-i2np-database-lookup
|
||||
|
@@ -1,7 +1,7 @@
|
||||
test-crypto-hmac-all: test-crypto-hmac
|
||||
|
||||
test-crypto-hmac:
|
||||
go test -v ./lib/crypto -run Test_I2PHMAC
|
||||
$(GO) test -v ./lib/crypto -run Test_I2PHMAC
|
||||
|
||||
.PHONY: test-crypto-hmac-all \
|
||||
test-crypto-hmac
|
||||
|
@@ -1,13 +1,13 @@
|
||||
test-integer-all: test-integer-big-endian test-integer-one-byte test-integer-zero
|
||||
|
||||
test-integer-big-endian:
|
||||
go test -v ./lib/common/integer -run TestIntegerBigEndian
|
||||
$(GO) test -v ./lib/common/integer -run TestIntegerBigEndian
|
||||
|
||||
test-integer-one-byte:
|
||||
go test -v ./lib/common/integer -run TestWorksWithOneByte
|
||||
$(GO) test -v ./lib/common/integer -run TestWorksWithOneByte
|
||||
|
||||
test-integer-zero:
|
||||
go test -v ./lib/common/integer -run TestIsZeroWithNoData
|
||||
$(GO) test -v ./lib/common/integer -run TestIsZeroWithNoData
|
||||
|
||||
.PHONY: test-integer-all \
|
||||
test-integer-big-endian \
|
||||
|
@@ -1,21 +1,21 @@
|
||||
test-key-cert-all: test-key-cert-signing test-key-cert-public test-key-cert-construct
|
||||
|
||||
test-key-cert-signing:
|
||||
go test -v ./lib/common/key_certificate -run TestSingingPublicKeyTypeReturnsCorrectInteger
|
||||
go test -v ./lib/common/key_certificate -run TestSingingPublicKeyTypeReportsWhenDataTooSmall
|
||||
go test -v ./lib/common/key_certificate -run TestConstructSigningPublicKeyReportsWhenDataTooSmall
|
||||
go test -v ./lib/common/key_certificate -run TestConstructSigningPublicKeyWithDSASHA1
|
||||
go test -v ./lib/common/key_certificate -run TestConstructSigningPublicKeyWithP256
|
||||
go test -v ./lib/common/key_certificate -run TestConstructSigningPublicKeyWithP384
|
||||
go test -v ./lib/common/key_certificate -run TestConstructSigningPublicKeyWithP521
|
||||
$(GO) test -v ./lib/common/key_certificate -run TestSingingPublicKeyTypeReturnsCorrectInteger
|
||||
$(GO) test -v ./lib/common/key_certificate -run TestSingingPublicKeyTypeReportsWhenDataTooSmall
|
||||
$(GO) test -v ./lib/common/key_certificate -run TestConstructSigningPublicKeyReportsWhenDataTooSmall
|
||||
$(GO) test -v ./lib/common/key_certificate -run TestConstructSigningPublicKeyWithDSASHA1
|
||||
$(GO) test -v ./lib/common/key_certificate -run TestConstructSigningPublicKeyWithP256
|
||||
$(GO) test -v ./lib/common/key_certificate -run TestConstructSigningPublicKeyWithP384
|
||||
$(GO) test -v ./lib/common/key_certificate -run TestConstructSigningPublicKeyWithP521
|
||||
|
||||
test-key-cert-public:
|
||||
go test -v ./lib/common/key_certificate -run TestPublicKeyTypeReturnsCorrectInteger
|
||||
go test -v ./lib/common/key_certificate -run TestPublicKeyTypeReportsWhenDataTooSmall
|
||||
$(GO) test -v ./lib/common/key_certificate -run TestPublicKeyTypeReturnsCorrectInteger
|
||||
$(GO) test -v ./lib/common/key_certificate -run TestPublicKeyTypeReportsWhenDataTooSmall
|
||||
|
||||
test-key-cert-construct:
|
||||
go test -v ./lib/common/key_certificate -run TestConstructPublicKeyReportsWhenDataTooSmall
|
||||
go test -v ./lib/common/key_certificate -run TestConstructPublicKeyReturnsCorrectDataWithElg
|
||||
$(GO) test -v ./lib/common/key_certificate -run TestConstructPublicKeyReportsWhenDataTooSmall
|
||||
$(GO) test -v ./lib/common/key_certificate -run TestConstructPublicKeyReturnsCorrectDataWithElg
|
||||
|
||||
.PHONY: test-key-cert-all \
|
||||
test-key-cert-signing \
|
||||
|
@@ -1,27 +1,27 @@
|
||||
test-keys-cert-all: test-keys-cert-certificate test-keys-cert-public test-keys-cert-signing test-keys-cert-creation
|
||||
|
||||
test-keys-cert-certificate:
|
||||
go test -v ./lib/common/keys_and_cert -run TestCertificateWithValidData
|
||||
$(GO) test -v ./lib/common/keys_and_cert -run TestCertificateWithValidData
|
||||
|
||||
test-keys-cert-public:
|
||||
go test -v ./lib/common/keys_and_cert -run TestPublicKeyWithBadData
|
||||
go test -v ./lib/common/keys_and_cert -run TestPublicKeyWithBadCertificate
|
||||
go test -v ./lib/common/keys_and_cert -run TestPublicKeyWithNullCertificate
|
||||
go test -v ./lib/common/keys_and_cert -run TestPublicKeyWithKeyCertificate
|
||||
$(GO) test -v ./lib/common/keys_and_cert -run TestPublicKeyWithBadData
|
||||
$(GO) test -v ./lib/common/keys_and_cert -run TestPublicKeyWithBadCertificate
|
||||
$(GO) test -v ./lib/common/keys_and_cert -run TestPublicKeyWithNullCertificate
|
||||
$(GO) test -v ./lib/common/keys_and_cert -run TestPublicKeyWithKeyCertificate
|
||||
|
||||
test-keys-cert-signing:
|
||||
go test -v ./lib/common/keys_and_cert -run TestSigningPublicKeyWithBadData
|
||||
go test -v ./lib/common/keys_and_cert -run TestSigningPublicKeyWithBadCertificate
|
||||
go test -v ./lib/common/keys_and_cert -run TestSigningPublicKeyWithNullCertificate
|
||||
go test -v ./lib/common/keys_and_cert -run TestSigningPublicKeyWithKeyCertificate
|
||||
$(GO) test -v ./lib/common/keys_and_cert -run TestSigningPublicKeyWithBadData
|
||||
$(GO) test -v ./lib/common/keys_and_cert -run TestSigningPublicKeyWithBadCertificate
|
||||
$(GO) test -v ./lib/common/keys_and_cert -run TestSigningPublicKeyWithNullCertificate
|
||||
$(GO) test -v ./lib/common/keys_and_cert -run TestSigningPublicKeyWithKeyCertificate
|
||||
|
||||
test-keys-cert-creation:
|
||||
go test -v ./lib/common/keys_and_cert -run TestNewKeysAndCertWithMissingData
|
||||
go test -v ./lib/common/keys_and_cert -run TestNewKeysAndCertWithMissingCertData
|
||||
go test -v ./lib/common/keys_and_cert -run TestNewKeysAndCertWithValidDataWithCertificate
|
||||
go test -v ./lib/common/keys_and_cert -run TestNewKeysAndCertWithValidDataWithoutCertificate
|
||||
go test -v ./lib/common/keys_and_cert -run TestNewKeysAndCertWithValidDataWithCertificateAndRemainder
|
||||
go test -v ./lib/common/keys_and_cert -run TestNewKeysAndCertWithValidDataWithoutCertificateAndRemainder
|
||||
$(GO) test -v ./lib/common/keys_and_cert -run TestNewKeysAndCertWithMissingData
|
||||
$(GO) test -v ./lib/common/keys_and_cert -run TestNewKeysAndCertWithMissingCertData
|
||||
$(GO) test -v ./lib/common/keys_and_cert -run TestNewKeysAndCertWithValidDataWithCertificate
|
||||
$(GO) test -v ./lib/common/keys_and_cert -run TestNewKeysAndCertWithValidDataWithoutCertificate
|
||||
$(GO) test -v ./lib/common/keys_and_cert -run TestNewKeysAndCertWithValidDataWithCertificateAndRemainder
|
||||
$(GO) test -v ./lib/common/keys_and_cert -run TestNewKeysAndCertWithValidDataWithoutCertificateAndRemainder
|
||||
|
||||
.PHONY: test-keys-cert-all \
|
||||
test-keys-cert-certificate \
|
||||
|
15
doc/tests/lease.mk
Normal file
15
doc/tests/lease.mk
Normal file
@@ -0,0 +1,15 @@
|
||||
test-lease-all: test-lease-tunnel-gateway test-lease-tunnel-id test-lease-date
|
||||
|
||||
test-lease-tunnel-gateway:
|
||||
$(GO) test -v ./lib/common/lease -run TestTunnelGateway
|
||||
|
||||
test-lease-tunnel-id:
|
||||
$(GO) test -v ./lib/common/lease -run TestTunnelID
|
||||
|
||||
test-lease-date:
|
||||
$(GO) test -v ./lib/common/lease -run TestDate
|
||||
|
||||
.PHONY: test-lease-all \
|
||||
test-lease-tunnel-gateway \
|
||||
test-lease-tunnel-id \
|
||||
test-lease-date
|
@@ -1,22 +1,26 @@
|
||||
test-lease-set-all: test-lease-set-basic test-lease-set-leases test-lease-set-expiration
|
||||
test-lease-set-all: test-lease-set-creation \
|
||||
test-lease-set-validation \
|
||||
test-lease-set-components \
|
||||
test-lease-set-expirations \
|
||||
test-lease-set-signature-verification
|
||||
test-lease-set-creation:
|
||||
$(GO) test -v ./lib/common/lease_set -run TestLeaseSetCreation
|
||||
|
||||
test-lease-set-basic:
|
||||
go test -v ./lib/common/lease_set -run TestDestinationIsCorrect
|
||||
go test -v ./lib/common/lease_set -run TestPublicKeyIsCorrect
|
||||
go test -v ./lib/common/lease_set -run TestSigningKeyIsCorrect
|
||||
go test -v ./lib/common/lease_set -run TestSignatureIsCorrect
|
||||
test-lease-set-validation:
|
||||
$(GO) test -v ./lib/common/lease_set -run TestLeaseSetValidation
|
||||
|
||||
test-lease-set-leases:
|
||||
go test -v ./lib/common/lease_set -run TestLeaseCountCorrect
|
||||
go test -v ./lib/common/lease_set -run TestLeaseCountCorrectWithMultiple
|
||||
go test -v ./lib/common/lease_set -run TestLeaseCountErrorWithTooMany
|
||||
go test -v ./lib/common/lease_set -run TestLeasesHaveCorrectData
|
||||
test-lease-set-components:
|
||||
$(GO) test -v ./lib/common/lease_set -run TestLeaseSetComponents
|
||||
|
||||
test-lease-set-expiration:
|
||||
go test -v ./lib/common/lease_set -run TestNewestExpirationIsCorrect
|
||||
go test -v ./lib/common/lease_set -run TestOldestExpirationIsCorrect
|
||||
test-lease-set-expirations:
|
||||
$(GO) test -v ./lib/common/lease_set -run TestExpirations
|
||||
|
||||
test-lease-set-signature-verification:
|
||||
$(GO) test -v ./lib/common/lease_set -run TestSignatureVerification
|
||||
|
||||
.PHONY: test-lease-set-all \
|
||||
test-lease-set-basic \
|
||||
test-lease-set-leases \
|
||||
test-lease-set-expiration
|
||||
test-lease-set-creation \
|
||||
test-lease-set-validation \
|
||||
test-lease-set-components \
|
||||
test-lease-set-expirations \
|
||||
test-lease-set-signature-verification
|
||||
|
@@ -1,25 +1,25 @@
|
||||
test-mapping-all: test-mapping-values test-mapping-duplicates test-mapping-conversion test-mapping-utils
|
||||
|
||||
test-mapping-values:
|
||||
go test -v ./lib/common/data -run TestValuesExclusesPairWithBadData
|
||||
go test -v ./lib/common/data -run TestValuesWarnsMissingData
|
||||
go test -v ./lib/common/data -run TestValuesWarnsExtraData
|
||||
go test -v ./lib/common/data -run TestValuesEnforcesEqualDelimitor
|
||||
go test -v ./lib/common/data -run TestValuesEnforcedSemicolonDelimitor
|
||||
go test -v ./lib/common/data -run TestValuesReturnsValues
|
||||
$(GO) test -v ./lib/common/data -run TestValuesExclusesPairWithBadData
|
||||
$(GO) test -v ./lib/common/data -run TestValuesWarnsMissingData
|
||||
$(GO) test -v ./lib/common/data -run TestValuesWarnsExtraData
|
||||
$(GO) test -v ./lib/common/data -run TestValuesEnforcesEqualDelimitor
|
||||
$(GO) test -v ./lib/common/data -run TestValuesEnforcedSemicolonDelimitor
|
||||
$(GO) test -v ./lib/common/data -run TestValuesReturnsValues
|
||||
|
||||
test-mapping-duplicates:
|
||||
go test -v ./lib/common/data -run TestHasDuplicateKeysTrueWhenDuplicates
|
||||
go test -v ./lib/common/data -run TestHasDuplicateKeysFalseWithoutDuplicates
|
||||
go test -v ./lib/common/data -run TestReadMappingHasDuplicateKeys
|
||||
$(GO) test -v ./lib/common/data -run TestHasDuplicateKeysTrueWhenDuplicates
|
||||
$(GO) test -v ./lib/common/data -run TestHasDuplicateKeysFalseWithoutDuplicates
|
||||
$(GO) test -v ./lib/common/data -run TestReadMappingHasDuplicateKeys
|
||||
|
||||
test-mapping-conversion:
|
||||
go test -v ./lib/common/data -run TestGoMapToMappingProducesCorrectMapping
|
||||
go test -v ./lib/common/data -run TestFullGoMapToMappingProducesCorrectMapping
|
||||
$(GO) test -v ./lib/common/data -run TestGoMapToMappingProducesCorrectMapping
|
||||
$(GO) test -v ./lib/common/data -run TestFullGoMapToMappingProducesCorrectMapping
|
||||
|
||||
test-mapping-utils:
|
||||
go test -v ./lib/common/data -run TestStopValueRead
|
||||
go test -v ./lib/common/data -run TestBeginsWith
|
||||
$(GO) test -v ./lib/common/data -run TestStopValueRead
|
||||
$(GO) test -v ./lib/common/data -run TestBeginsWith
|
||||
|
||||
.PHONY: test-mapping-all \
|
||||
test-mapping-values \
|
||||
|
@@ -1,2 +1,2 @@
|
||||
test-mapping-values-order:
|
||||
go test -v ./lib/common/data -run TestMappingOrderSortsValuesThenKeys
|
||||
$(GO) test -v ./lib/common/data -run TestMappingOrderSortsValuesThenKeys
|
@@ -1,16 +1,16 @@
|
||||
test-noise-transport-all: test-noise-packet-encryption test-noise-transport-connection test-noise-packet-obfuscation test-noise-packet-obfuscation-func
|
||||
|
||||
test-noise-packet-encryption:
|
||||
go test -v ./lib/transport/noise -run TestEncryptDecryptPacketOffline
|
||||
$(GO) test -v ./lib/transport/noise -run TestEncryptDecryptPacketOffline
|
||||
|
||||
test-noise-transport-connection:
|
||||
go test -v ./lib/transport/noise -run TestTransport
|
||||
$(GO) test -v ./lib/transport/noise -run TestTransport
|
||||
|
||||
test-noise-packet-obfuscation:
|
||||
go test -v ./lib/transport/noise -run TestEncryptDecryptPacketObfsOffline
|
||||
$(GO) test -v ./lib/transport/noise -run TestEncryptDecryptPacketObfsOffline
|
||||
|
||||
test-noise-packet-obfuscation-func:
|
||||
go test -v ./lib/transport/noise -run TestEncryptDecryptPacketObfsOfflineWithFunc
|
||||
$(GO) test -v ./lib/transport/noise -run TestEncryptDecryptPacketObfsOfflineWithFunc
|
||||
|
||||
.PHONY: test-noise-transport-all \
|
||||
test-noise-packet-encryption \
|
||||
|
@@ -1,17 +1,17 @@
|
||||
test-router-address-all: test-router-address-validation test-router-address-functionality test-router-address-fuzz
|
||||
|
||||
test-router-address-validation:
|
||||
go test -v ./lib/common/router_address -run TestCheckValidReportsEmptySlice
|
||||
go test -v ./lib/common/router_address -run TestCheckRouterAddressValidReportsDataMissing
|
||||
go test -v ./lib/common/router_address -run TestCheckRouterAddressValidNoErrWithValidData
|
||||
$(GO) test -v ./lib/common/router_address -run TestCheckValidReportsEmptySlice
|
||||
$(GO) test -v ./lib/common/router_address -run TestCheckRouterAddressValidReportsDataMissing
|
||||
$(GO) test -v ./lib/common/router_address -run TestCheckRouterAddressValidNoErrWithValidData
|
||||
|
||||
test-router-address-functionality:
|
||||
go test -v ./lib/common/router_address -run TestRouterAddressCostReturnsFirstByte
|
||||
go test -v ./lib/common/router_address -run TestRouterAddressExpirationReturnsCorrectData
|
||||
go test -v ./lib/common/router_address -run TestReadRouterAddressReturnsCorrectRemainderWithoutError
|
||||
$(GO) test -v ./lib/common/router_address -run TestRouterAddressCostReturnsFirstByte
|
||||
$(GO) test -v ./lib/common/router_address -run TestRouterAddressExpirationReturnsCorrectData
|
||||
$(GO) test -v ./lib/common/router_address -run TestReadRouterAddressReturnsCorrectRemainderWithoutError
|
||||
|
||||
test-router-address-fuzz:
|
||||
go test -v ./lib/common/router_address -run TestCorrectsFuzzCrasher1
|
||||
$(GO) test -v ./lib/common/router_address -run TestCorrectsFuzzCrasher1
|
||||
|
||||
.PHONY: test-router-address-all \
|
||||
test-router-address-validation \
|
||||
|
@@ -1,26 +1,52 @@
|
||||
test-router-info-all: test-router-info-published test-router-info-addresses test-router-info-identity test-router-info-misc
|
||||
test-router-info-all: test-router-info-creation test-router-info-published-date test-router-info-identity test-router-info-addresses test-router-info-serialization test-router-info-signature test-router-info-capabilities test-router-info-version test-router-info-good-version test-router-info-uncongested test-router-info-reachable test-router-info-10k
|
||||
|
||||
test-router-info-published:
|
||||
go test -v ./lib/common/router_info -run TestPublishedReturnsCorrectDate
|
||||
go test -v ./lib/common/router_info -run TestPublishedReturnsCorrectErrorWithPartialDate
|
||||
go test -v ./lib/common/router_info -run TestPublishedReturnsCorrectErrorWithInvalidData
|
||||
test-router-info-creation:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoCreation
|
||||
$(GO) test -v ./lib/common/router_info -run TestCreateRouterInfo
|
||||
|
||||
test-router-info-addresses:
|
||||
go test -v ./lib/common/router_info -run TestRouterAddressCountReturnsCorrectCount
|
||||
go test -v ./lib/common/router_info -run TestRouterAddressCountReturnsCorrectErrorWithInvalidData
|
||||
go test -v ./lib/common/router_info -run TestRouterAddressesReturnsAddresses
|
||||
go test -v ./lib/common/router_info -run TestRouterAddressesReturnsAddressesWithMultiple
|
||||
test-router-info-published-date:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoPublishedDate
|
||||
|
||||
test-router-info-identity:
|
||||
go test -v ./lib/common/router_info -run TestRouterIdentityIsCorrect
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoRouterIdentity
|
||||
|
||||
test-router-info-misc:
|
||||
go test -v ./lib/common/router_info -run TestPeerSizeIsZero
|
||||
go test -v ./lib/common/router_info -run TestOptionsAreCorrect
|
||||
go test -v ./lib/common/router_info -run TestSignatureIsCorrectSize
|
||||
test-router-info-addresses:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoAddresses
|
||||
|
||||
test-router-info-serialization:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoSerialization
|
||||
|
||||
test-router-info-signature:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoSignature
|
||||
|
||||
test-router-info-capabilities:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoCapabilities
|
||||
|
||||
test-router-info-version:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoVersion
|
||||
|
||||
test-router-info-good-version:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoGoodVersion
|
||||
|
||||
test-router-info-uncongested:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoUnCongested
|
||||
|
||||
test-router-info-reachable:
|
||||
$(GO) test -v ./lib/common/router_info -run TestRouterInfoReachable
|
||||
|
||||
test-router-info-10k:
|
||||
$(GO) test -v ./lib/common/router_info -run Test10K
|
||||
|
||||
.PHONY: test-router-info-all \
|
||||
test-router-info-published \
|
||||
test-router-info-addresses \
|
||||
test-router-info-creation \
|
||||
test-router-info-published-date \
|
||||
test-router-info-identity \
|
||||
test-router-info-misc
|
||||
test-router-info-addresses \
|
||||
test-router-info-serialization \
|
||||
test-router-info-signature \
|
||||
test-router-info-capabilities \
|
||||
test-router-info-version \
|
||||
test-router-info-good-version \
|
||||
test-router-info-uncongested \
|
||||
test-router-info-reachable \
|
||||
test-router-info-10k
|
7
doc/tests/signatures.mk
Normal file
7
doc/tests/signatures.mk
Normal file
@@ -0,0 +1,7 @@
|
||||
test-signatures:
|
||||
$(GO) test -v ./lib/common/signature/ -run TestReadSignatureErrors
|
||||
$(GO) test -v ./lib/common/signature/ -run TestReadSignature
|
||||
$(GO) test -v ./lib/common/signature/ -run TestNewSignatureError
|
||||
$(GO) test -v ./lib/common/signature/ -run TestNewSignature
|
||||
|
||||
.PHONY: test-signatures
|
@@ -1,24 +1,24 @@
|
||||
test-string-all: test-string-length test-string-data test-string-conversion test-string-read
|
||||
|
||||
test-string-length:
|
||||
go test -v ./lib/common/data -run TestStringReportsCorrectLength
|
||||
go test -v ./lib/common/data -run TestI2PStringReportsLengthZeroError
|
||||
go test -v ./lib/common/data -run TestI2PStringReportsExtraDataError
|
||||
go test -v ./lib/common/data -run TestI2PStringDataReportsLengthZeroError
|
||||
$(GO) test -v ./lib/common/data -run TestStringReportsCorrectLength
|
||||
$(GO) test -v ./lib/common/data -run TestI2PStringReportsLengthZeroError
|
||||
$(GO) test -v ./lib/common/data -run TestI2PStringReportsExtraDataError
|
||||
$(GO) test -v ./lib/common/data -run TestI2PStringDataReportsLengthZeroError
|
||||
|
||||
test-string-data:
|
||||
go test -v ./lib/common/data -run TestI2PStringDataReportsExtraDataError
|
||||
go test -v ./lib/common/data -run TestI2PStringDataEmptyWhenZeroLength
|
||||
go test -v ./lib/common/data -run TestI2PStringDataErrorWhenNonZeroLengthOnly
|
||||
$(GO) test -v ./lib/common/data -run TestI2PStringDataReportsExtraDataError
|
||||
$(GO) test -v ./lib/common/data -run TestI2PStringDataEmptyWhenZeroLength
|
||||
$(GO) test -v ./lib/common/data -run TestI2PStringDataErrorWhenNonZeroLengthOnly
|
||||
|
||||
test-string-conversion:
|
||||
go test -v ./lib/common/data -run TestToI2PI2PStringFormatsCorrectly
|
||||
go test -v ./lib/common/data -run TestToI2PStringReportsOverflows
|
||||
$(GO) test -v ./lib/common/data -run TestToI2PI2PStringFormatsCorrectly
|
||||
$(GO) test -v ./lib/common/data -run TestToI2PStringReportsOverflows
|
||||
|
||||
test-string-read:
|
||||
go test -v ./lib/common/data -run TestReadStringReadsLength
|
||||
go test -v ./lib/common/data -run TestReadI2PStringErrWhenEmptySlice
|
||||
go test -v ./lib/common/data -run TestReadI2PStringErrWhenDataTooShort
|
||||
$(GO) test -v ./lib/common/data -run TestReadStringReadsLength
|
||||
$(GO) test -v ./lib/common/data -run TestReadI2PStringErrWhenEmptySlice
|
||||
$(GO) test -v ./lib/common/data -run TestReadI2PStringErrWhenDataTooShort
|
||||
|
||||
.PHONY: test-string-all \
|
||||
test-string-length \
|
||||
|
@@ -1,10 +1,10 @@
|
||||
test-su3-all: test-su3-read test-su3-signature
|
||||
|
||||
test-su3-read:
|
||||
go test -v ./lib/su3 -run TestRead
|
||||
$(GO) test -v ./lib/su3 -run TestRead
|
||||
|
||||
test-su3-signature:
|
||||
go test -v ./lib/su3 -run TestReadSignatureFirst
|
||||
$(GO) test -v ./lib/su3 -run TestReadSignatureFirst
|
||||
|
||||
.PHONY: test-su3-all \
|
||||
test-su3-read \
|
||||
|
@@ -2,18 +2,18 @@ test-tunnel-all: test-tunnel-delivery-instructions test-tunnel-message
|
||||
|
||||
# Tests from delivery_test.go
|
||||
test-tunnel-delivery-instructions:
|
||||
go test -v ./lib/tunnel -run TestReadDeliveryInstructions
|
||||
$(GO) test -v ./lib/tunnel -run TestReadDeliveryInstructions
|
||||
|
||||
# Tests from message_test.go
|
||||
test-tunnel-message: test-tunnel-message-padding test-tunnel-message-fragments
|
||||
|
||||
test-tunnel-message-padding:
|
||||
go test -v ./lib/tunnel -run TestDeliveryInstructionDataWithNoPadding
|
||||
go test -v ./lib/tunnel -run TestDeliveryInstructionDataWithSomePadding
|
||||
go test -v ./lib/tunnel -run TestDeliveryInstructionDataWithOnlyPadding
|
||||
$(GO) test -v ./lib/tunnel -run TestDeliveryInstructionDataWithNoPadding
|
||||
$(GO) test -v ./lib/tunnel -run TestDeliveryInstructionDataWithSomePadding
|
||||
$(GO) test -v ./lib/tunnel -run TestDeliveryInstructionDataWithOnlyPadding
|
||||
|
||||
test-tunnel-message-fragments:
|
||||
go test -v ./lib/tunnel -run TestDeliveryInstructionsWithFragments
|
||||
$(GO) test -v ./lib/tunnel -run TestDeliveryInstructionsWithFragments
|
||||
|
||||
.PHONY: test-tunnel-all \
|
||||
test-tunnel-delivery-instructions \
|
||||
|
52
go.mod
52
go.mod
@@ -1,46 +1,50 @@
|
||||
module github.com/go-i2p/go-i2p
|
||||
|
||||
go 1.23.1
|
||||
go 1.24.2
|
||||
|
||||
require (
|
||||
github.com/emirpasic/gods v1.18.1
|
||||
github.com/beevik/ntp v1.4.3
|
||||
github.com/emirpasic/gods v1.18.1
|
||||
github.com/eyedeekay/go-unzip v0.0.0-20240201194209-560d8225b50e
|
||||
github.com/flynn/noise v1.1.0
|
||||
github.com/go-i2p/common v0.0.0-20250715213359-dfa5527ece83
|
||||
github.com/go-i2p/crypto v0.0.0-20250715205812-c9e7853bc978
|
||||
github.com/go-i2p/logger v0.0.0-20241123010126-3050657e5d0c
|
||||
github.com/samber/oops v1.19.0
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/stretchr/testify v1.9.0
|
||||
go.step.sm/crypto v0.53.0
|
||||
golang.org/x/crypto v0.27.0
|
||||
github.com/spf13/cobra v1.9.1
|
||||
github.com/spf13/viper v1.19.0
|
||||
github.com/stretchr/testify v1.10.0
|
||||
golang.org/x/crypto v0.39.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.8.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/magiconair/properties v1.8.9 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/oklog/ulid/v2 v2.1.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.7.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/samber/lo v1.51.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/spf13/cast v1.7.0 // indirect
|
||||
github.com/spf13/cobra v1.8.1 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.19.0 // indirect
|
||||
github.com/spf13/afero v1.12.0 // indirect
|
||||
github.com/spf13/cast v1.7.1 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
golang.org/x/text v0.18.0 // indirect
|
||||
go.opentelemetry.io/otel v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.36.0 // indirect
|
||||
go.step.sm/crypto v0.67.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
|
||||
golang.org/x/net v0.41.0 // indirect
|
||||
golang.org/x/sys v0.33.0 // indirect
|
||||
golang.org/x/text v0.26.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
golang.org/x/net v0.28.0 // indirect
|
||||
golang.org/x/sys v0.24.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
108
go.sum
108
go.sum
@@ -1,10 +1,9 @@
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/beevik/ntp v1.4.3 h1:PlbTvE5NNy4QHmA4Mg57n7mcFTmr1W1j3gcK7L1lqho=
|
||||
github.com/beevik/ntp v1.4.3/go.mod h1:Unr8Zg+2dRn7d8bHFuehIMSvvUYssHMxW3Q5Nx4RW5Q=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -14,81 +13,98 @@ github.com/eyedeekay/go-unzip v0.0.0-20240201194209-560d8225b50e h1:NMjWYVkgcQHG
|
||||
github.com/eyedeekay/go-unzip v0.0.0-20240201194209-560d8225b50e/go.mod h1:fKfFM3BsOOyjtZmEty7FsGzGabXo8Eb/dHjyIhTtxsE=
|
||||
github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg=
|
||||
github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
|
||||
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/go-i2p/common v0.0.0-20250709015428-90b991723618 h1:ZOvrfUmG/SIzOVsICzrqpgoLRZb/gv2i0TgURvqMgeo=
|
||||
github.com/go-i2p/common v0.0.0-20250709015428-90b991723618/go.mod h1:Hq9v0qoOgIWVs/cYszDqw5rhk6DjnHLHm6+75/+Y6m0=
|
||||
github.com/go-i2p/common v0.0.0-20250715213359-dfa5527ece83 h1:F6xM06QyqR+qMYA4SzWzUzfVmkSE1P41tHK32TmGxP8=
|
||||
github.com/go-i2p/common v0.0.0-20250715213359-dfa5527ece83/go.mod h1:e6X6esQk0zaevdZPZecKY7n8+wOfOLukQfWw558DYfk=
|
||||
github.com/go-i2p/crypto v0.0.0-20250715205812-c9e7853bc978 h1:YnaXZy814nG+kSpZs6z53Z4TMt1NnMIJNbBHlE4KBc0=
|
||||
github.com/go-i2p/crypto v0.0.0-20250715205812-c9e7853bc978/go.mod h1:1Y3NCpVg6OgE3c2VPRQ3QDmWPtDpJYLIyRBA1iJCd3E=
|
||||
github.com/go-i2p/logger v0.0.0-20241123010126-3050657e5d0c h1:VTiECn3dFEmUlZjto+wOwJ7SSJTHPLyNprQMR5HzIMI=
|
||||
github.com/go-i2p/logger v0.0.0-20241123010126-3050657e5d0c/go.mod h1:te7Zj3g3oMeIl8uBXAgO62UKmZ6m6kHRNg1Mm+X8Hzk=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM=
|
||||
github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/oklog/ulid/v2 v2.1.1 h1:suPZ4ARWLOJLegGFiZZ1dFAkqzhMjL3J1TzI+5wHz8s=
|
||||
github.com/oklog/ulid/v2 v2.1.1/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
|
||||
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
|
||||
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
|
||||
github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo=
|
||||
github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k=
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
||||
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
|
||||
github.com/samber/lo v1.51.0 h1:kysRYLbHy/MB7kQZf5DSN50JHmMsNEdeY24VzJFu7wI=
|
||||
github.com/samber/lo v1.51.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0=
|
||||
github.com/samber/oops v1.19.0 h1:sfZAwC8MmTXBRRyNc4Z1utuTPBx+hFKF5fJ9DEQRZfw=
|
||||
github.com/samber/oops v1.19.0/go.mod h1:+f+61dbiMxEMQ8gw/zTxW2pk+YGobaDM4glEHQtPOww=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
||||
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
|
||||
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
|
||||
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
|
||||
github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
|
||||
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
|
||||
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
|
||||
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
go.step.sm/crypto v0.53.0 h1:+1as1ogzuCzx15/468M4mEC5juogI5a0Fzbsyh1CuYY=
|
||||
go.step.sm/crypto v0.53.0/go.mod h1:AqLU78RqNUHepLzyOWZuNN/2++Lu7dZENdO9UzWOGSk=
|
||||
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
|
||||
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
|
||||
go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
|
||||
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
|
||||
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
|
||||
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
|
||||
go.step.sm/crypto v0.67.0 h1:1km9LmxMKG/p+mKa1R4luPN04vlJYnRLlLQrWv7egGU=
|
||||
go.step.sm/crypto v0.67.0/go.mod h1:+AoDpB0mZxbW/PmOXuwkPSpXRgaUaoIK+/Wx/HGgtAU=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
|
||||
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
|
||||
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
|
||||
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
|
57
lib/bootstrap/README.md
Normal file
57
lib/bootstrap/README.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# bootstrap
|
||||
--
|
||||
import "github.com/go-i2p/go-i2p/lib/bootstrap"
|
||||
|
||||

|
||||
|
||||
provides generic interfaces for initial bootstrap into network and network
|
||||
### reseeding
|
||||
|
||||
## Usage
|
||||
|
||||
#### type Bootstrap
|
||||
|
||||
```go
|
||||
type Bootstrap interface {
|
||||
// get more peers for bootstrap
|
||||
// try obtaining at most n router infos
|
||||
// if n is 0 then try obtaining as many router infos as possible
|
||||
// returns nil and error if we cannot fetch ANY router infos
|
||||
// returns a channel that yields 1 slice of router infos containing n or fewer router infos, caller must close channel after use
|
||||
GetPeers(ctx context.Context, n int) ([]router_info.RouterInfo, error)
|
||||
}
|
||||
```
|
||||
|
||||
interface defining a way to bootstrap into the i2p network
|
||||
|
||||
#### type ReseedBootstrap
|
||||
|
||||
```go
|
||||
type ReseedBootstrap struct {
|
||||
}
|
||||
```
|
||||
|
||||
ReseedBootstrap implements the Bootstrap interface using HTTP reseeding
|
||||
|
||||
#### func NewReseedBootstrap
|
||||
|
||||
```go
|
||||
func NewReseedBootstrap(config *config.BootstrapConfig) *ReseedBootstrap
|
||||
```
|
||||
NewReseedBootstrap creates a new reseeder with the provided configuration
|
||||
|
||||
#### func (*ReseedBootstrap) GetPeers
|
||||
|
||||
```go
|
||||
func (rb *ReseedBootstrap) GetPeers(ctx context.Context, n int) ([]router_info.RouterInfo, error)
|
||||
```
|
||||
GetPeers implements the Bootstrap interface by obtaining RouterInfos from
|
||||
configured reseed servers
|
||||
|
||||
|
||||
|
||||
bootstrap
|
||||
|
||||
github.com/go-i2p/go-i2p/lib/bootstrap
|
||||
|
||||
[go-i2p template file](/template.md)
|
@@ -1,6 +1,10 @@
|
||||
package bootstrap
|
||||
|
||||
import "github.com/go-i2p/go-i2p/lib/common/router_info"
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-i2p/common/router_info"
|
||||
)
|
||||
|
||||
// interface defining a way to bootstrap into the i2p network
|
||||
type Bootstrap interface {
|
||||
@@ -9,5 +13,5 @@ type Bootstrap interface {
|
||||
// if n is 0 then try obtaining as many router infos as possible
|
||||
// returns nil and error if we cannot fetch ANY router infos
|
||||
// returns a channel that yields 1 slice of router infos containing n or fewer router infos, caller must close channel after use
|
||||
GetPeers(n int) (chan []router_info.RouterInfo, error)
|
||||
GetPeers(ctx context.Context, n int) ([]router_info.RouterInfo, error)
|
||||
}
|
||||
|
258
lib/bootstrap/bootstrap.svg
Normal file
258
lib/bootstrap/bootstrap.svg
Normal file
@@ -0,0 +1,258 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
||||
-->
|
||||
<!-- Title: gocallvis Pages: 1 -->
|
||||
<svg width="365pt" height="722pt"
|
||||
viewBox="0.00 0.00 364.72 722.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(0 722)">
|
||||
<title>gocallvis</title>
|
||||
<polygon fill="#d3d3d3" stroke="transparent" points="0,0 0,-722 364.7182,-722 364.7182,0 0,0"/>
|
||||
<g id="clust1" class="cluster">
|
||||
<title>cluster_focus</title>
|
||||
<polygon fill="#e6ecfa" stroke="#000000" stroke-width=".5" points="0,-8 0,-714 356.7182,-714 356.7182,-8 0,-8"/>
|
||||
<text text-anchor="middle" x="178.3591" y="-693.8" font-family="Arial" font-size="18.00" fill="#000000">bootstrap</text>
|
||||
</g>
|
||||
<g id="clust5" class="cluster">
|
||||
<title>cluster_github.com/go-i2p/go-i2p/lib/netdb/reseed.Reseed</title>
|
||||
<g id="a_clust5"><a xlink:title="type: github.com/go-i2p/go-i2p/lib/netdb/reseed.Reseed">
|
||||
<path fill="#eed8ae" stroke="#000000" stroke-width=".5" d="M242.0218,-598C242.0218,-598 334.2252,-598 334.2252,-598 340.2252,-598 346.2252,-604 346.2252,-610 346.2252,-610 346.2252,-664 346.2252,-664 346.2252,-670 340.2252,-676 334.2252,-676 334.2252,-676 242.0218,-676 242.0218,-676 236.0218,-676 230.0218,-670 230.0218,-664 230.0218,-664 230.0218,-610 230.0218,-610 230.0218,-604 236.0218,-598 242.0218,-598"/>
|
||||
<text text-anchor="middle" x="288.1235" y="-606.5" font-family="Arial" font-size="15.00" fill="#222222">(Reseed)</text>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<g id="clust4" class="cluster">
|
||||
<title>cluster_*github.com/sirupsen/logrus.Logger</title>
|
||||
<g id="a_clust4"><a xlink:title="type: *github.com/sirupsen/logrus.Logger">
|
||||
<path fill="#eed8ae" stroke="#000000" stroke-width=".5" d="M261.4629,-451C261.4629,-451 315.7841,-451 315.7841,-451 321.7841,-451 327.7841,-457 327.7841,-463 327.7841,-463 327.7841,-578 327.7841,-578 327.7841,-584 321.7841,-590 315.7841,-590 315.7841,-590 261.4629,-590 261.4629,-590 255.4629,-590 249.4629,-584 249.4629,-578 249.4629,-578 249.4629,-463 249.4629,-463 249.4629,-457 255.4629,-451 261.4629,-451"/>
|
||||
<text text-anchor="middle" x="288.6235" y="-459.5" font-family="Arial" font-size="15.00" fill="#222222">(*Logger)</text>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<g id="clust3" class="cluster">
|
||||
<title>cluster_*github.com/go-i2p/logger.Logger</title>
|
||||
<g id="a_clust3"><a xlink:title="type: *github.com/go-i2p/logger.Logger">
|
||||
<path fill="#eed8ae" stroke="#000000" stroke-width=".5" d="M249.0141,-182C249.0141,-182 327.2329,-182 327.2329,-182 333.2329,-182 339.2329,-188 339.2329,-194 339.2329,-194 339.2329,-431 339.2329,-431 339.2329,-437 333.2329,-443 327.2329,-443 327.2329,-443 249.0141,-443 249.0141,-443 243.0141,-443 237.0141,-437 237.0141,-431 237.0141,-431 237.0141,-194 237.0141,-194 237.0141,-188 243.0141,-182 249.0141,-182"/>
|
||||
<text text-anchor="middle" x="288.1235" y="-190.5" font-family="Arial" font-size="15.00" fill="#222222">(*Logger)</text>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<g id="clust2" class="cluster">
|
||||
<title>cluster_*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap</title>
|
||||
<g id="a_clust2"><a xlink:title="type: *github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap">
|
||||
<path fill="#b0c4de" stroke="#000000" stroke-width=".5" d="M20,-304C20,-304 143.5288,-304 143.5288,-304 149.5288,-304 155.5288,-310 155.5288,-316 155.5288,-316 155.5288,-370 155.5288,-370 155.5288,-376 149.5288,-382 143.5288,-382 143.5288,-382 20,-382 20,-382 14,-382 8,-376 8,-370 8,-370 8,-316 8,-316 8,-310 14,-304 20,-304"/>
|
||||
<text text-anchor="middle" x="81.7644" y="-312.5" font-family="Arial" font-size="15.00" fill="#222222">(*ReseedBootstrap)</text>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- github.com/samber/oops.Errorf -->
|
||||
<g id="node1" class="node">
|
||||
<title>github.com/samber/oops.Errorf</title>
|
||||
<g id="a_node1"><a xlink:title="github.com/samber/oops.Errorf | defined in oops.go:34">
|
||||
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M305.3188,-113C305.3188,-113 270.9282,-113 270.9282,-113 264.9282,-113 258.9282,-107 258.9282,-101 258.9282,-101 258.9282,-89 258.9282,-89 258.9282,-83 264.9282,-77 270.9282,-77 270.9282,-77 305.3188,-77 305.3188,-77 311.3188,-77 317.3188,-83 317.3188,-89 317.3188,-89 317.3188,-101 317.3188,-101 317.3188,-107 311.3188,-113 305.3188,-113"/>
|
||||
<text text-anchor="middle" x="288.1235" y="-99.2" font-family="Verdana" font-size="14.00" fill="#000000">oops</text>
|
||||
<text text-anchor="middle" x="288.1235" y="-82.4" font-family="Verdana" font-size="14.00" fill="#000000">Errorf</text>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- github.com/go-i2p/go-i2p/lib/netdb/reseed.NewReseed -->
|
||||
<g id="node2" class="node">
|
||||
<title>github.com/go-i2p/go-i2p/lib/netdb/reseed.NewReseed</title>
|
||||
<g id="a_node2"><a xlink:title="github.com/go-i2p/go-i2p/lib/netdb/reseed.NewReseed | defined in new.go:10">
|
||||
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M321.4764,-174C321.4764,-174 254.7706,-174 254.7706,-174 248.7706,-174 242.7706,-168 242.7706,-162 242.7706,-162 242.7706,-150 242.7706,-150 242.7706,-144 248.7706,-138 254.7706,-138 254.7706,-138 321.4764,-138 321.4764,-138 327.4764,-138 333.4764,-144 333.4764,-150 333.4764,-150 333.4764,-162 333.4764,-162 333.4764,-168 327.4764,-174 321.4764,-174"/>
|
||||
<text text-anchor="middle" x="288.1235" y="-160.2" font-family="Verdana" font-size="14.00" fill="#000000">reseed</text>
|
||||
<text text-anchor="middle" x="288.1235" y="-143.4" font-family="Verdana" font-size="14.00" fill="#000000">NewReseed</text>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- github.com/go-i2p/go-i2p/lib/bootstrap.init -->
|
||||
<g id="node3" class="node">
|
||||
<title>github.com/go-i2p/go-i2p/lib/bootstrap.init</title>
|
||||
<g id="a_node3"><a xlink:title="github.com/go-i2p/go-i2p/lib/bootstrap.init | defined in .:0 at reseed_bootstrap.go:15: calling [github.com/go-i2p/logger.GetGoI2PLogger]">
|
||||
<path fill="#add8e6" stroke="#000000" stroke-width=".5" d="M96.2644,-52C96.2644,-52 66.2644,-52 66.2644,-52 60.2644,-52 54.2644,-46 54.2644,-40 54.2644,-40 54.2644,-28 54.2644,-28 54.2644,-22 60.2644,-16 66.2644,-16 66.2644,-16 96.2644,-16 96.2644,-16 102.2644,-16 108.2644,-22 108.2644,-28 108.2644,-28 108.2644,-40 108.2644,-40 108.2644,-46 102.2644,-52 96.2644,-52"/>
|
||||
<text text-anchor="middle" x="81.2644" y="-29.8" font-family="Verdana" font-size="14.00" fill="#000000">init</text>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- github.com/go-i2p/logger.GetGoI2PLogger -->
|
||||
<g id="node4" class="node">
|
||||
<title>github.com/go-i2p/logger.GetGoI2PLogger</title>
|
||||
<g id="a_node4"><a xlink:title="github.com/go-i2p/logger.GetGoI2PLogger | defined in log.go:120">
|
||||
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M336.813,-52C336.813,-52 239.434,-52 239.434,-52 233.434,-52 227.434,-46 227.434,-40 227.434,-40 227.434,-28 227.434,-28 227.434,-22 233.434,-16 239.434,-16 239.434,-16 336.813,-16 336.813,-16 342.813,-16 348.813,-22 348.813,-28 348.813,-28 348.813,-40 348.813,-40 348.813,-46 342.813,-52 336.813,-52"/>
|
||||
<text text-anchor="middle" x="288.1235" y="-38.2" font-family="Verdana" font-size="14.00" fill="#000000">logger</text>
|
||||
<text text-anchor="middle" x="288.1235" y="-21.4" font-family="Verdana" font-size="14.00" fill="#000000">GetGoI2PLogger</text>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- github.com/go-i2p/go-i2p/lib/bootstrap.init->github.com/go-i2p/logger.GetGoI2PLogger -->
|
||||
<g id="edge10" class="edge">
|
||||
<title>github.com/go-i2p/go-i2p/lib/bootstrap.init->github.com/go-i2p/logger.GetGoI2PLogger</title>
|
||||
<g id="a_edge10"><a xlink:title="at reseed_bootstrap.go:15: calling [github.com/go-i2p/logger.GetGoI2PLogger]">
|
||||
<path fill="none" stroke="#8b4513" d="M108.3076,-34C135.736,-34 179.3573,-34 216.7663,-34"/>
|
||||
<polygon fill="#8b4513" stroke="#8b4513" points="217.1342,-37.5001 227.1342,-34 217.1341,-30.5001 217.1342,-37.5001"/>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- (*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers -->
|
||||
<g id="node5" class="node">
|
||||
<title>(*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers</title>
|
||||
<g id="a_node5"><a xlink:title="(*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers | defined in reseed_bootstrap.go:32 at reseed_bootstrap.go:40: calling [github.com/samber/oops.Errorf] at reseed_bootstrap.go:53: calling [github.com/samber/oops.Errorf] at reseed_bootstrap.go:73: calling [github.com/samber/oops.Errorf] at reseed_bootstrap.go:43: calling [(*github.com/go-i2p/logger.Logger).WithField] at reseed_bootstrap.go:52: calling [(*github.com/go-i2p/logger.Logger).WithField] at reseed_bootstrap.go:43: calling [(*github.com/sirupsen/logrus.Logger).Debug] at reseed_bootstrap.go:52: calling [(*github.com/go-i2p/logger.Logger).WithError] at reseed_bootstrap.go:52: calling [(*github.com/go-i2p/logger.Logger).Warn] at reseed_bootstrap.go:63: calling [(*github.com/sirupsen/logrus.Logger).Info] at reseed_bootstrap.go:46: calling [github.com/go-i2p/go-i2p/lib/netdb/reseed.NewReseed] at reseed_bootstrap.go:49: calling [(github.com/go-i2p/go-i2p/lib/netdb/reseed.Reseed).SingleReseed] at reseed_bootstrap.go:59: calling [(*github.com/go-i2p/logger.Logger).WithFields]">
|
||||
<path fill="#add8e6" stroke="#000000" stroke-width="1.5" d="M106.2947,-374C106.2947,-374 56.2341,-374 56.2341,-374 50.2341,-374 44.2341,-368 44.2341,-362 44.2341,-362 44.2341,-350 44.2341,-350 44.2341,-344 50.2341,-338 56.2341,-338 56.2341,-338 106.2947,-338 106.2947,-338 112.2947,-338 118.2947,-344 118.2947,-350 118.2947,-350 118.2947,-362 118.2947,-362 118.2947,-368 112.2947,-374 106.2947,-374"/>
|
||||
<text text-anchor="middle" x="81.2644" y="-351.8" font-family="Verdana" font-size="14.00" fill="#000000">GetPeers</text>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- (*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers->github.com/samber/oops.Errorf -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>(*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers->github.com/samber/oops.Errorf</title>
|
||||
<g id="a_edge1"><a xlink:title="at reseed_bootstrap.go:40: calling [github.com/samber/oops.Errorf] at reseed_bootstrap.go:53: calling [github.com/samber/oops.Errorf] at reseed_bootstrap.go:73: calling [github.com/samber/oops.Errorf]">
|
||||
<path fill="none" stroke="#8b4513" d="M118.4074,-352.073C131.5385,-349.0001 145.5161,-343.5697 155.5288,-334 190.8891,-300.2044 195.4391,-162.9154 227.5288,-126 233.5557,-119.0668 241.5102,-113.4857 249.6658,-109.0748"/>
|
||||
<polygon fill="#8b4513" stroke="#8b4513" points="251.4166,-112.115 258.8672,-104.5824 248.3454,-105.8247 251.4166,-112.115"/>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- (*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers->github.com/go-i2p/go-i2p/lib/netdb/reseed.NewReseed -->
|
||||
<g id="edge7" class="edge">
|
||||
<title>(*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers->github.com/go-i2p/go-i2p/lib/netdb/reseed.NewReseed</title>
|
||||
<g id="a_edge7"><a xlink:title="at reseed_bootstrap.go:46: calling [github.com/go-i2p/go-i2p/lib/netdb/reseed.NewReseed]">
|
||||
<path fill="none" stroke="#8b4513" d="M118.6751,-351.3434C131.5313,-348.1844 145.2575,-342.8857 155.5288,-334 213.2793,-284.0401 171.3098,-229.6772 227.5288,-178 229.4394,-176.2438 231.5009,-174.6252 233.6705,-173.1338"/>
|
||||
<polygon fill="#8b4513" stroke="#8b4513" points="235.6115,-176.0535 242.4829,-167.9892 232.0823,-170.0083 235.6115,-176.0535"/>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- (*github.com/go-i2p/logger.Logger).WithField -->
|
||||
<g id="node6" class="node">
|
||||
<title>(*github.com/go-i2p/logger.Logger).WithField</title>
|
||||
<g id="a_node6"><a xlink:title="(*github.com/go-i2p/logger.Logger).WithField | defined in log.go:54">
|
||||
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M316.398,-252C316.398,-252 259.849,-252 259.849,-252 253.849,-252 247.849,-246 247.849,-240 247.849,-240 247.849,-228 247.849,-228 247.849,-222 253.849,-216 259.849,-216 259.849,-216 316.398,-216 316.398,-216 322.398,-216 328.398,-222 328.398,-228 328.398,-228 328.398,-240 328.398,-240 328.398,-246 322.398,-252 316.398,-252"/>
|
||||
<text text-anchor="middle" x="288.1235" y="-238.2" font-family="Verdana" font-size="14.00" fill="#000000">logger</text>
|
||||
<text text-anchor="middle" x="288.1235" y="-221.4" font-family="Verdana" font-size="14.00" fill="#000000">WithField</text>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- (*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers->(*github.com/go-i2p/logger.Logger).WithField -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>(*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers->(*github.com/go-i2p/logger.Logger).WithField</title>
|
||||
<g id="a_edge2"><a xlink:title="at reseed_bootstrap.go:43: calling [(*github.com/go-i2p/logger.Logger).WithField] at reseed_bootstrap.go:52: calling [(*github.com/go-i2p/logger.Logger).WithField]">
|
||||
<path fill="none" stroke="#8b4513" d="M118.5683,-348.6617C130.8549,-345.2944 144.2489,-340.5496 155.5288,-334 193.8581,-311.7444 191.4175,-290.6986 227.5288,-265 231.4159,-262.2337 235.5842,-259.5689 239.8482,-257.0424"/>
|
||||
<polygon fill="#8b4513" stroke="#8b4513" points="241.6859,-260.0242 248.6757,-252.0623 238.2464,-253.9275 241.6859,-260.0242"/>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- (*github.com/go-i2p/logger.Logger).WithError -->
|
||||
<g id="node7" class="node">
|
||||
<title>(*github.com/go-i2p/logger.Logger).WithError</title>
|
||||
<g id="a_node7"><a xlink:title="(*github.com/go-i2p/logger.Logger).WithError | defined in log.go:66">
|
||||
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M316.655,-313C316.655,-313 259.592,-313 259.592,-313 253.592,-313 247.592,-307 247.592,-301 247.592,-301 247.592,-289 247.592,-289 247.592,-283 253.592,-277 259.592,-277 259.592,-277 316.655,-277 316.655,-277 322.655,-277 328.655,-283 328.655,-289 328.655,-289 328.655,-301 328.655,-301 328.655,-307 322.655,-313 316.655,-313"/>
|
||||
<text text-anchor="middle" x="288.1235" y="-299.2" font-family="Verdana" font-size="14.00" fill="#000000">logger</text>
|
||||
<text text-anchor="middle" x="288.1235" y="-282.4" font-family="Verdana" font-size="14.00" fill="#000000">WithError</text>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- (*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers->(*github.com/go-i2p/logger.Logger).WithError -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>(*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers->(*github.com/go-i2p/logger.Logger).WithError</title>
|
||||
<g id="a_edge4"><a xlink:title="at reseed_bootstrap.go:52: calling [(*github.com/go-i2p/logger.Logger).WithError]">
|
||||
<path fill="none" stroke="#8b4513" d="M118.725,-344.9534C151.9288,-335.162 200.7001,-320.78 237.3948,-309.9592"/>
|
||||
<polygon fill="#8b4513" stroke="#8b4513" points="238.7997,-313.194 247.4014,-307.0084 236.8198,-306.4798 238.7997,-313.194"/>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- (*github.com/go-i2p/logger.Logger).Warn -->
|
||||
<g id="node8" class="node">
|
||||
<title>(*github.com/go-i2p/logger.Logger).Warn</title>
|
||||
<g id="a_node8"><a xlink:title="(*github.com/go-i2p/logger.Logger).Warn | defined in log.go:30">
|
||||
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M305.8898,-374C305.8898,-374 270.3572,-374 270.3572,-374 264.3572,-374 258.3572,-368 258.3572,-362 258.3572,-362 258.3572,-350 258.3572,-350 258.3572,-344 264.3572,-338 270.3572,-338 270.3572,-338 305.8898,-338 305.8898,-338 311.8898,-338 317.8898,-344 317.8898,-350 317.8898,-350 317.8898,-362 317.8898,-362 317.8898,-368 311.8898,-374 305.8898,-374"/>
|
||||
<text text-anchor="middle" x="288.1235" y="-360.2" font-family="Verdana" font-size="14.00" fill="#000000">logger</text>
|
||||
<text text-anchor="middle" x="288.1235" y="-343.4" font-family="Verdana" font-size="14.00" fill="#000000">Warn</text>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- (*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers->(*github.com/go-i2p/logger.Logger).Warn -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>(*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers->(*github.com/go-i2p/logger.Logger).Warn</title>
|
||||
<g id="a_edge5"><a xlink:title="at reseed_bootstrap.go:52: calling [(*github.com/go-i2p/logger.Logger).Warn]">
|
||||
<path fill="none" stroke="#8b4513" d="M118.725,-356C155.3343,-356 210.8683,-356 248.2746,-356"/>
|
||||
<polygon fill="#8b4513" stroke="#8b4513" points="248.3136,-359.5001 258.3136,-356 248.3135,-352.5001 248.3136,-359.5001"/>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- (*github.com/go-i2p/logger.Logger).WithFields -->
|
||||
<g id="node9" class="node">
|
||||
<title>(*github.com/go-i2p/logger.Logger).WithFields</title>
|
||||
<g id="a_node9"><a xlink:title="(*github.com/go-i2p/logger.Logger).WithFields | defined in log.go:60">
|
||||
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M319.3426,-435C319.3426,-435 256.9044,-435 256.9044,-435 250.9044,-435 244.9044,-429 244.9044,-423 244.9044,-423 244.9044,-411 244.9044,-411 244.9044,-405 250.9044,-399 256.9044,-399 256.9044,-399 319.3426,-399 319.3426,-399 325.3426,-399 331.3426,-405 331.3426,-411 331.3426,-411 331.3426,-423 331.3426,-423 331.3426,-429 325.3426,-435 319.3426,-435"/>
|
||||
<text text-anchor="middle" x="288.1235" y="-421.2" font-family="Verdana" font-size="14.00" fill="#000000">logger</text>
|
||||
<text text-anchor="middle" x="288.1235" y="-404.4" font-family="Verdana" font-size="14.00" fill="#000000">WithFields</text>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- (*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers->(*github.com/go-i2p/logger.Logger).WithFields -->
|
||||
<g id="edge9" class="edge">
|
||||
<title>(*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers->(*github.com/go-i2p/logger.Logger).WithFields</title>
|
||||
<g id="a_edge9"><a xlink:title="at reseed_bootstrap.go:59: calling [(*github.com/go-i2p/logger.Logger).WithFields]">
|
||||
<path fill="none" stroke="#8b4513" d="M118.725,-367.0466C151.1839,-376.6183 198.5195,-390.577 234.9071,-401.3072"/>
|
||||
<polygon fill="#8b4513" stroke="#8b4513" points="234.2768,-404.7703 244.8585,-404.2417 236.2568,-398.0561 234.2768,-404.7703"/>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- (*github.com/sirupsen/logrus.Logger).Debug -->
|
||||
<g id="node10" class="node">
|
||||
<title>(*github.com/sirupsen/logrus.Logger).Debug</title>
|
||||
<g id="a_node10"><a xlink:title="(*github.com/sirupsen/logrus.Logger).Debug | defined in logger.go:221">
|
||||
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M306.9455,-521C306.9455,-521 269.3015,-521 269.3015,-521 263.3015,-521 257.3015,-515 257.3015,-509 257.3015,-509 257.3015,-497 257.3015,-497 257.3015,-491 263.3015,-485 269.3015,-485 269.3015,-485 306.9455,-485 306.9455,-485 312.9455,-485 318.9455,-491 318.9455,-497 318.9455,-497 318.9455,-509 318.9455,-509 318.9455,-515 312.9455,-521 306.9455,-521"/>
|
||||
<text text-anchor="middle" x="288.1235" y="-507.2" font-family="Verdana" font-size="14.00" fill="#000000">logrus</text>
|
||||
<text text-anchor="middle" x="288.1235" y="-490.4" font-family="Verdana" font-size="14.00" fill="#000000">Debug</text>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- (*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers->(*github.com/sirupsen/logrus.Logger).Debug -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>(*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers->(*github.com/sirupsen/logrus.Logger).Debug</title>
|
||||
<g id="a_edge3"><a xlink:title="at reseed_bootstrap.go:43: calling [(*github.com/sirupsen/logrus.Logger).Debug]">
|
||||
<path fill="none" stroke="#8b4513" d="M106.6294,-374.0251C143.6948,-400.3648 212.738,-449.4289 254.1541,-478.8604"/>
|
||||
<polygon fill="#8b4513" stroke="#8b4513" points="252.3722,-481.8878 262.551,-484.8275 256.427,-476.1818 252.3722,-481.8878"/>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- (*github.com/sirupsen/logrus.Logger).Info -->
|
||||
<g id="node11" class="node">
|
||||
<title>(*github.com/sirupsen/logrus.Logger).Info</title>
|
||||
<g id="a_node11"><a xlink:title="(*github.com/sirupsen/logrus.Logger).Info | defined in logger.go:225">
|
||||
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M305.6193,-582C305.6193,-582 270.6277,-582 270.6277,-582 264.6277,-582 258.6277,-576 258.6277,-570 258.6277,-570 258.6277,-558 258.6277,-558 258.6277,-552 264.6277,-546 270.6277,-546 270.6277,-546 305.6193,-546 305.6193,-546 311.6193,-546 317.6193,-552 317.6193,-558 317.6193,-558 317.6193,-570 317.6193,-570 317.6193,-576 311.6193,-582 305.6193,-582"/>
|
||||
<text text-anchor="middle" x="288.1235" y="-568.2" font-family="Verdana" font-size="14.00" fill="#000000">logrus</text>
|
||||
<text text-anchor="middle" x="288.1235" y="-551.4" font-family="Verdana" font-size="14.00" fill="#000000">Info</text>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- (*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers->(*github.com/sirupsen/logrus.Logger).Info -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>(*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers->(*github.com/sirupsen/logrus.Logger).Info</title>
|
||||
<g id="a_edge6"><a xlink:title="at reseed_bootstrap.go:63: calling [(*github.com/sirupsen/logrus.Logger).Info]">
|
||||
<path fill="none" stroke="#8b4513" d="M92.3256,-374.0399C114.3749,-408.7975 166.9292,-485.8578 227.5288,-534 234.1285,-539.243 241.7932,-543.9051 249.4061,-547.8995"/>
|
||||
<polygon fill="#8b4513" stroke="#8b4513" points="248.0753,-551.1458 258.5915,-552.435 251.1745,-544.8692 248.0753,-551.1458"/>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- (github.com/go-i2p/go-i2p/lib/netdb/reseed.Reseed).SingleReseed -->
|
||||
<g id="node12" class="node">
|
||||
<title>(github.com/go-i2p/go-i2p/lib/netdb/reseed.Reseed).SingleReseed</title>
|
||||
<g id="a_node12"><a xlink:title="(github.com/go-i2p/go-i2p/lib/netdb/reseed.Reseed).SingleReseed | defined in reseed.go:31">
|
||||
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M326.3271,-668C326.3271,-668 249.9199,-668 249.9199,-668 243.9199,-668 237.9199,-662 237.9199,-656 237.9199,-656 237.9199,-644 237.9199,-644 237.9199,-638 243.9199,-632 249.9199,-632 249.9199,-632 326.3271,-632 326.3271,-632 332.3271,-632 338.3271,-638 338.3271,-644 338.3271,-644 338.3271,-656 338.3271,-656 338.3271,-662 332.3271,-668 326.3271,-668"/>
|
||||
<text text-anchor="middle" x="288.1235" y="-654.2" font-family="Verdana" font-size="14.00" fill="#000000">reseed</text>
|
||||
<text text-anchor="middle" x="288.1235" y="-637.4" font-family="Verdana" font-size="14.00" fill="#000000">SingleReseed</text>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
<!-- (*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers->(github.com/go-i2p/go-i2p/lib/netdb/reseed.Reseed).SingleReseed -->
|
||||
<g id="edge8" class="edge">
|
||||
<title>(*github.com/go-i2p/go-i2p/lib/bootstrap.ReseedBootstrap).GetPeers->(github.com/go-i2p/go-i2p/lib/netdb/reseed.Reseed).SingleReseed</title>
|
||||
<g id="a_edge8"><a xlink:title="at reseed_bootstrap.go:49: calling [(github.com/go-i2p/go-i2p/lib/netdb/reseed.Reseed).SingleReseed]">
|
||||
<path fill="none" stroke="#8b4513" d="M89.919,-374.0435C110.3702,-415.6822 164.7136,-520.678 227.5288,-596 236.2167,-606.4176 246.9389,-616.6363 256.9371,-625.3325"/>
|
||||
<polygon fill="#8b4513" stroke="#8b4513" points="254.8567,-628.1572 264.7475,-631.9549 259.3837,-622.8181 254.8567,-628.1572"/>
|
||||
</a>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 23 KiB |
@@ -1,23 +0,0 @@
|
||||
# bootstrap
|
||||
--
|
||||
import "github.com/go-i2p/go-i2p/lib/bootstrap"
|
||||
|
||||
provides generic interfaces for initial bootstrap into network and network
|
||||
### reseeding
|
||||
|
||||
## Usage
|
||||
|
||||
#### type Bootstrap
|
||||
|
||||
```go
|
||||
type Bootstrap interface {
|
||||
// get more peers for bootstrap
|
||||
// try obtaining at most n router infos
|
||||
// if n is 0 then try obtaining as many router infos as possible
|
||||
// returns nil and error if we cannot fetch ANY router infos
|
||||
// returns a channel that yields 1 slice of router infos containing n or fewer router infos, caller must close channel after use
|
||||
GetPeers(n int) (chan []router_info.RouterInfo, error)
|
||||
}
|
||||
```
|
||||
|
||||
interface defining a way to bootstrap into the i2p network
|
77
lib/bootstrap/reseed_bootstrap.go
Normal file
77
lib/bootstrap/reseed_bootstrap.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-i2p/common/router_info"
|
||||
"github.com/go-i2p/go-i2p/lib/config"
|
||||
"github.com/go-i2p/go-i2p/lib/netdb/reseed"
|
||||
"github.com/go-i2p/logger"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/samber/oops"
|
||||
)
|
||||
|
||||
var log = logger.GetGoI2PLogger()
|
||||
|
||||
// ReseedBootstrap implements the Bootstrap interface using HTTP reseeding
|
||||
type ReseedBootstrap struct {
|
||||
// Configuration containing reseed servers
|
||||
config *config.BootstrapConfig
|
||||
}
|
||||
|
||||
// NewReseedBootstrap creates a new reseeder with the provided configuration
|
||||
func NewReseedBootstrap(config *config.BootstrapConfig) *ReseedBootstrap {
|
||||
return &ReseedBootstrap{
|
||||
config: config,
|
||||
}
|
||||
}
|
||||
|
||||
// GetPeers implements the Bootstrap interface by obtaining RouterInfos
|
||||
// from configured reseed servers
|
||||
func (rb *ReseedBootstrap) GetPeers(ctx context.Context, n int) ([]router_info.RouterInfo, error) {
|
||||
var allRouterInfos []router_info.RouterInfo
|
||||
var lastErr error
|
||||
|
||||
// Try each reseed server until we get enough routerInfos or exhaust all servers
|
||||
for _, server := range rb.config.ReseedServers {
|
||||
// Check if context is canceled before making request
|
||||
if ctx.Err() != nil {
|
||||
return nil, oops.Errorf("reseed canceled: %v", ctx.Err())
|
||||
}
|
||||
|
||||
log.WithField("server", server.Url).Debug("Attempting to reseed from server")
|
||||
|
||||
// Use the existing Reseed implementation with a timeout context
|
||||
reseeder := reseed.NewReseed()
|
||||
|
||||
// Perform the actual reseeding operation synchronously
|
||||
serverRIs, err := reseeder.SingleReseed(server.Url)
|
||||
|
||||
if err != nil {
|
||||
log.WithError(err).WithField("server", server.Url).Warn("Reseed attempt failed")
|
||||
lastErr = oops.Errorf("reseed from %s failed: %v", server.Url, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Add the retrieved RouterInfos to our collection
|
||||
allRouterInfos = append(allRouterInfos, serverRIs...)
|
||||
log.WithFields(logrus.Fields{
|
||||
"server": server.Url,
|
||||
"count": len(serverRIs),
|
||||
"total": len(allRouterInfos),
|
||||
}).Info("Successfully obtained router infos from reseed server")
|
||||
|
||||
// Check if we have enough RouterInfos
|
||||
if n > 0 && len(allRouterInfos) >= n {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// If we couldn't get any RouterInfos from any server, return the last error
|
||||
if len(allRouterInfos) == 0 && lastErr != nil {
|
||||
return nil, oops.Errorf("all reseed attempts failed: %w", lastErr)
|
||||
}
|
||||
|
||||
return allRouterInfos, nil
|
||||
}
|
@@ -1,23 +0,0 @@
|
||||
// Package base32 implmenets utilities for encoding and decoding text using I2P's alphabet
|
||||
package base32
|
||||
|
||||
import (
|
||||
b32 "encoding/base32"
|
||||
)
|
||||
|
||||
// I2PEncodeAlphabet is the base32 encoding used throughout I2P.
|
||||
// RFC 3548 using lowercase characters.
|
||||
const I2PEncodeAlphabet = "abcdefghijklmnopqrstuvwxyz234567"
|
||||
|
||||
// I2PEncoding is the standard base32 encoding used through I2P.
|
||||
var I2PEncoding *b32.Encoding = b32.NewEncoding(I2PEncodeAlphabet)
|
||||
|
||||
// EncodeToString encodes []byte to a base32 string using I2PEncoding
|
||||
func EncodeToString(data []byte) string {
|
||||
return I2PEncoding.EncodeToString(data)
|
||||
}
|
||||
|
||||
// DecodeString decodes base64 string to []byte I2PEncoding
|
||||
func DecodeString(data string) ([]byte, error) {
|
||||
return I2PEncoding.DecodeString(data)
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
package base32
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestEncodeDecodeNotMangled(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
// Random pangram
|
||||
testInput := []byte("How vexingly quick daft zebras jump!")
|
||||
|
||||
encodedString := EncodeToString(testInput)
|
||||
decodedString, err := DecodeString(encodedString)
|
||||
assert.Nil(err)
|
||||
|
||||
assert.ElementsMatch(testInput, decodedString)
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
# base32
|
||||
--
|
||||
import "github.com/go-i2p/go-i2p/lib/common/base32"
|
||||
|
||||
Package base32 implmenets utilities for encoding and decoding text using I2P's
|
||||
### alphabet
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
const I2PEncodeAlphabet = "abcdefghijklmnopqrstuvwxyz234567"
|
||||
```
|
||||
I2PEncodeAlphabet is the base32 encoding used throughout I2P. RFC 3548 using
|
||||
lowercase characters.
|
||||
|
||||
```go
|
||||
var I2PEncoding *b32.Encoding = b32.NewEncoding(I2PEncodeAlphabet)
|
||||
```
|
||||
I2PEncoding is the standard base32 encoding used through I2P.
|
||||
|
||||
#### func DecodeString
|
||||
|
||||
```go
|
||||
func DecodeString(data string) ([]byte, error)
|
||||
```
|
||||
DecodeString decodes base64 string to []byte I2PEncoding
|
||||
|
||||
#### func EncodeToString
|
||||
|
||||
```go
|
||||
func EncodeToString(data []byte) string
|
||||
```
|
||||
EncodeToString encodes []byte to a base32 string using I2PEncoding
|
@@ -1,23 +0,0 @@
|
||||
// Package base64 implmenets utilities for encoding and decoding text using I2P's alphabet
|
||||
package base64
|
||||
|
||||
import (
|
||||
b64 "encoding/base64"
|
||||
)
|
||||
|
||||
// I2PEncodeAlphabet is the base64 encoding used throughout I2P.
|
||||
// RFC 4648 with "/"" replaced with "~", and "+" replaced with "-".
|
||||
const I2PEncodeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-~"
|
||||
|
||||
// I2PEncoding is the standard base64 encoding used through I2P.
|
||||
var I2PEncoding *b64.Encoding = b64.NewEncoding(I2PEncodeAlphabet)
|
||||
|
||||
// I2PEncoding is the standard base64 encoding used through I2P.
|
||||
func EncodeToString(data []byte) string {
|
||||
return I2PEncoding.EncodeToString(data)
|
||||
}
|
||||
|
||||
// DecodeString decodes base64 string to []byte I2PEncoding
|
||||
func DecodeString(str string) ([]byte, error) {
|
||||
return I2PEncoding.DecodeString(str)
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
package base64
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestEncodeDecodeNotMangled(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
// Random pangram
|
||||
testInput := []byte("Glib jocks quiz nymph to vex dwarf.")
|
||||
|
||||
encodedString := EncodeToString(testInput)
|
||||
decodedString, err := DecodeString(encodedString)
|
||||
assert.Nil(err)
|
||||
|
||||
assert.ElementsMatch(testInput, decodedString)
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
# base64
|
||||
--
|
||||
import "github.com/go-i2p/go-i2p/lib/common/base64"
|
||||
|
||||
Package base64 implmenets utilities for encoding and decoding text using I2P's
|
||||
### alphabet
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
const I2PEncodeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-~"
|
||||
```
|
||||
I2PEncodeAlphabet is the base64 encoding used throughout I2P. RFC 4648 with "/""
|
||||
replaced with "~", and "+" replaced with "-".
|
||||
|
||||
```go
|
||||
var I2PEncoding *b64.Encoding = b64.NewEncoding(I2PEncodeAlphabet)
|
||||
```
|
||||
I2PEncoding is the standard base64 encoding used through I2P.
|
||||
|
||||
#### func DecodeString
|
||||
|
||||
```go
|
||||
func DecodeString(str string) ([]byte, error)
|
||||
```
|
||||
DecodeString decodes base64 string to []byte I2PEncoding
|
||||
|
||||
#### func EncodeToString
|
||||
|
||||
```go
|
||||
func EncodeToString(data []byte) string
|
||||
```
|
||||
I2PEncoding is the standard base64 encoding used through I2P.
|
@@ -1,210 +0,0 @@
|
||||
// Package certificate implements the certificate common-structure of I2P.
|
||||
|
||||
package certificate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
// log "github.com/sirupsen/logrus"
|
||||
"github.com/go-i2p/go-i2p/lib/util/logger"
|
||||
|
||||
. "github.com/go-i2p/go-i2p/lib/common/data"
|
||||
)
|
||||
|
||||
var log = logger.GetGoI2PLogger()
|
||||
|
||||
// Certificate Types
|
||||
const (
|
||||
CERT_NULL = iota
|
||||
CERT_HASHCASH
|
||||
CERT_HIDDEN
|
||||
CERT_SIGNED
|
||||
CERT_MULTIPLE
|
||||
CERT_KEY
|
||||
)
|
||||
|
||||
// CERT_MIN_SIZE is the minimum size of a valid Certificate in []byte
|
||||
// 1 byte for type
|
||||
// 2 bytes for payload length
|
||||
const CERT_MIN_SIZE = 3
|
||||
|
||||
/*
|
||||
[I2P Certificate]
|
||||
Accurate for version 0.9.49
|
||||
|
||||
Description
|
||||
A certifificate is a container for various receipts of proof of works used throughout the I2P network.
|
||||
|
||||
Contents
|
||||
1 byte Integer specifying certificate type, followed by a 2 byte Integer specifying the size of the certificate playload, then that many bytes.
|
||||
|
||||
+----+----+----+----+----+-//
|
||||
|type| length | payload
|
||||
+----+----+----+----+----+-//
|
||||
|
||||
type :: Integer
|
||||
length -> 1 byte
|
||||
|
||||
case 0 -> NULL
|
||||
case 1 -> HASHCASH
|
||||
case 2 -> HIDDEN
|
||||
case 3 -> SIGNED
|
||||
case 4 -> MULTIPLE
|
||||
case 5 -> KEY
|
||||
|
||||
length :: Integer
|
||||
length -> 2 bytes
|
||||
|
||||
payload :: data
|
||||
length -> $length bytes
|
||||
*/
|
||||
|
||||
// Certificate is the representation of an I2P Certificate.
|
||||
//
|
||||
// https://geti2p.net/spec/common-structures#certificate
|
||||
type Certificate struct {
|
||||
kind Integer
|
||||
len Integer
|
||||
payload []byte
|
||||
}
|
||||
|
||||
// RawBytes returns the entire certificate in []byte form, includes excess payload data.
|
||||
func (c *Certificate) RawBytes() []byte {
|
||||
bytes := c.kind.Bytes()
|
||||
bytes = append(bytes, c.len.Bytes()...)
|
||||
bytes = append(bytes, c.payload...)
|
||||
log.WithFields(logrus.Fields{
|
||||
"raw_bytes_length": len(bytes),
|
||||
}).Debug("Generated raw bytes for certificate")
|
||||
return bytes
|
||||
}
|
||||
|
||||
// ExcessBytes returns the excess bytes in a certificate found after the specified payload length.
|
||||
func (c *Certificate) ExcessBytes() []byte {
|
||||
if len(c.payload) >= c.len.Int() {
|
||||
excess := c.payload[c.len.Int():]
|
||||
log.WithFields(logrus.Fields{
|
||||
"excess_bytes_length": len(excess),
|
||||
}).Debug("Found excess bytes in certificate")
|
||||
return excess
|
||||
}
|
||||
log.Debug("No excess bytes found in certificate")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Bytes returns the entire certificate in []byte form, trims payload to specified length.
|
||||
func (c *Certificate) Bytes() []byte {
|
||||
bytes := c.kind.Bytes()
|
||||
bytes = append(bytes, c.len.Bytes()...)
|
||||
bytes = append(bytes, c.Data()...)
|
||||
log.WithFields(logrus.Fields{
|
||||
"bytes_length": len(bytes),
|
||||
}).Debug("Generated bytes for certificate")
|
||||
return bytes
|
||||
}
|
||||
|
||||
func (c *Certificate) length() (cert_len int) {
|
||||
cert_len = len(c.Bytes())
|
||||
return
|
||||
}
|
||||
|
||||
// Type returns the Certificate type specified in the first byte of the Certificate,
|
||||
func (c *Certificate) Type() (cert_type int) {
|
||||
cert_type = c.kind.Int()
|
||||
log.WithFields(logrus.Fields{
|
||||
"cert_type": cert_type,
|
||||
}).Debug("Retrieved certificate type")
|
||||
return
|
||||
}
|
||||
|
||||
// Length returns the payload length of a Certificate.
|
||||
func (c *Certificate) Length() (length int) {
|
||||
length = c.len.Int()
|
||||
log.WithFields(logrus.Fields{
|
||||
"length": length,
|
||||
}).Debug("Retrieved certificate length")
|
||||
return
|
||||
}
|
||||
|
||||
// Data returns the payload of a Certificate, payload is trimmed to the specified length.
|
||||
func (c *Certificate) Data() (data []byte) {
|
||||
lastElement := c.Length()
|
||||
if lastElement > len(c.payload) {
|
||||
data = c.payload
|
||||
log.Warn("Certificate payload shorter than specified length")
|
||||
} else {
|
||||
data = c.payload[0:lastElement]
|
||||
}
|
||||
log.WithFields(logrus.Fields{
|
||||
"data_length": len(data),
|
||||
}).Debug("Retrieved certificate data")
|
||||
return
|
||||
}
|
||||
|
||||
// NewCertificate creates a new Certficiate from []byte
|
||||
// returns err if the certificate is too short or if the payload doesn't match specified length.
|
||||
func NewCertificate(data []byte) (certificate Certificate, err error) {
|
||||
certificate = Certificate{}
|
||||
switch len(data) {
|
||||
case 0:
|
||||
certificate.kind = Integer([]byte{0})
|
||||
certificate.len = Integer([]byte{0})
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "(Certificate) NewCertificate",
|
||||
"certificate_bytes_length": len(data),
|
||||
"reason": "too short (len < CERT_MIN_SIZE)" + fmt.Sprintf("%d", certificate.kind.Int()),
|
||||
}).Error("invalid certificate, empty")
|
||||
err = fmt.Errorf("error parsing certificate: certificate is empty")
|
||||
return
|
||||
case 1, 2:
|
||||
certificate.kind = Integer(data[0 : len(data)-1])
|
||||
certificate.len = Integer([]byte{0})
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "(Certificate) NewCertificate",
|
||||
"certificate_bytes_length": len(data),
|
||||
"reason": "too short (len < CERT_MIN_SIZE)" + fmt.Sprintf("%d", certificate.kind.Int()),
|
||||
}).Error("invalid certificate, too short")
|
||||
err = fmt.Errorf("error parsing certificate: certificate is too short")
|
||||
return
|
||||
default:
|
||||
certificate.kind = Integer(data[0:1])
|
||||
certificate.len = Integer(data[1:3])
|
||||
payleng := len(data) - CERT_MIN_SIZE
|
||||
certificate.payload = data[CERT_MIN_SIZE:]
|
||||
if certificate.len.Int() > len(data)-CERT_MIN_SIZE {
|
||||
err = fmt.Errorf("certificate parsing warning: certificate data is shorter than specified by length")
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "(Certificate) NewCertificate",
|
||||
"certificate_bytes_length": certificate.len.Int(),
|
||||
"certificate_payload_length": payleng,
|
||||
"data_bytes:": string(data),
|
||||
"kind_bytes": data[0:1],
|
||||
"len_bytes": data[1:3],
|
||||
"reason": err.Error(),
|
||||
}).Error("invalid certificate, shorter than specified by length")
|
||||
return
|
||||
}
|
||||
log.WithFields(logrus.Fields{
|
||||
"type": certificate.kind.Int(),
|
||||
"length": certificate.len.Int(),
|
||||
}).Debug("Successfully created new certificate")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// ReadCertificate creates a Certificate from []byte and returns any ExcessBytes at the end of the input.
|
||||
// returns err if the certificate could not be read.
|
||||
func ReadCertificate(data []byte) (certificate Certificate, remainder []byte, err error) {
|
||||
certificate, err = NewCertificate(data)
|
||||
if err != nil && err.Error() == "certificate parsing warning: certificate data is longer than specified by length" {
|
||||
log.Warn("Certificate data longer than specified length")
|
||||
err = nil
|
||||
}
|
||||
remainder = certificate.ExcessBytes()
|
||||
log.WithFields(logrus.Fields{
|
||||
"remainder_length": len(remainder),
|
||||
}).Debug("Read certificate and extracted remainder")
|
||||
return
|
||||
}
|
@@ -1,146 +0,0 @@
|
||||
package certificate
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCertificateTypeIsFirstByte(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
bytes := []byte{0x03, 0x00, 0x00}
|
||||
certificate, err := NewCertificate(bytes)
|
||||
cert_type := certificate.Type()
|
||||
|
||||
assert.Equal(cert_type, 3, "certificate.Type() should be the first bytes in a certificate")
|
||||
assert.Nil(err)
|
||||
}
|
||||
|
||||
func TestCertificateLengthCorrect(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
bytes := []byte{0x03, 0x00, 0x02, 0xff, 0xff}
|
||||
certificate, err := NewCertificate(bytes)
|
||||
cert_len := certificate.Length()
|
||||
|
||||
assert.Equal(cert_len, 2, "certificate.Length() should return integer from second two bytes")
|
||||
assert.Nil(err)
|
||||
}
|
||||
|
||||
func TestCertificateLengthErrWhenTooShort(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
bytes := []byte{0x03, 0x01}
|
||||
certificate, _, err := ReadCertificate(bytes)
|
||||
cert_len := certificate.Length()
|
||||
|
||||
assert.Equal(cert_len, 0, "certificate.Length() did not return zero length for missing length data")
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal("error parsing certificate: certificate is too short", err.Error(), "correct error message should be returned")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCertificateLengthErrWhenDataTooShort(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
bytes := []byte{0x03, 0x00, 0x02, 0xff}
|
||||
certificate, err := NewCertificate(bytes)
|
||||
cert_len := certificate.Length()
|
||||
|
||||
assert.Equal(cert_len, 2, "certificate.Length() did not return indicated length when data was actually missing")
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal("certificate parsing warning: certificate data is shorter than specified by length", err.Error(), "correct error message should be returned")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCertificateDataWhenCorrectSize(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
bytes := []byte{0x03, 0x00, 0x01, 0xaa}
|
||||
certificate, err := NewCertificate(bytes)
|
||||
cert_data := certificate.Data()
|
||||
|
||||
assert.Nil(err, "certificate.Data() returned error with valid data")
|
||||
cert_len := len(cert_data)
|
||||
assert.Equal(cert_len, 1, "certificate.Length() did not return indicated length when data was valid")
|
||||
assert.Equal(170, int(cert_data[0]), "certificate.Data() returned incorrect data")
|
||||
}
|
||||
|
||||
func TestCertificateDataWhenTooLong(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
bytes := []byte{0x03, 0x00, 0x02, 0xff, 0xff, 0xaa, 0xaa}
|
||||
certificate, _, _ := ReadCertificate(bytes)
|
||||
cert_data := certificate.Data()
|
||||
|
||||
cert_len := certificate.Length() // len(cert_data)
|
||||
assert.Equal(cert_len, 2, "certificate.Length() did not return indicated length when data was too long")
|
||||
if cert_data[0] != 0xff || cert_data[1] != 0xff {
|
||||
t.Fatal("certificate.Data() returned incorrect data when data was too long")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCertificateDataWhenTooShort(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
bytes := []byte{0x03, 0x00, 0x02, 0xff}
|
||||
certificate, err := NewCertificate(bytes)
|
||||
cert_data := certificate.Data()
|
||||
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal("certificate parsing warning: certificate data is shorter than specified by length", err.Error(), "correct error message should be returned")
|
||||
}
|
||||
cert_len := len(cert_data)
|
||||
assert.Equal(cert_len, 1, "certificate.Data() did not return correct amount of data when data too short")
|
||||
assert.Equal(255, int(cert_data[0]), "certificate.Data() did not return correct data values when data was too short")
|
||||
}
|
||||
|
||||
func TestReadCertificateWithCorrectData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
bytes := []byte{0x00, 0x00, 0x02, 0xff, 0xff}
|
||||
cert, remainder, err := ReadCertificate(bytes)
|
||||
|
||||
assert.Equal(cert.length(), 5, "ReadCertificate() did not return correct amount of data for valid certificate")
|
||||
assert.Equal(len(remainder), 0, "ReadCertificate() did not return a zero length remainder on a valid certificate")
|
||||
assert.Nil(err, "ReadCertificate() should not return an error with valid data")
|
||||
}
|
||||
|
||||
func TestReadCertificateWithDataTooShort(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
bytes := []byte{0x00, 0x00, 0x02, 0xff}
|
||||
cert, remainder, err := ReadCertificate(bytes)
|
||||
|
||||
assert.Equal(cert.length(), 4, "ReadCertificate() did not return correct amount of data for certificate with missing data")
|
||||
assert.Equal(len(remainder), 0, "ReadCertificate() did not return a zero length remainder on certificate with missing data")
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal("certificate parsing warning: certificate data is shorter than specified by length", err.Error(), "correct error message should be returned")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadCertificateWithRemainder(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
bytes := []byte{0x00, 0x00, 0x02, 0xff, 0xff, 0x01}
|
||||
cert, remainder, err := ReadCertificate(bytes)
|
||||
|
||||
assert.Equal(cert.length(), 5, "ReadCertificate() did not return correct amount of data for certificate with extra data")
|
||||
assert.Equal(len(remainder), 1, "ReadCertificate() returned incorrect length remainder on certificate with extra data")
|
||||
// assert.Equal(1, int(remainder[0]), "ReadCertificate() did not return correct remainder value")
|
||||
assert.Nil(err)
|
||||
}
|
||||
|
||||
func TestReadCertificateWithInvalidLength(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
bytes := []byte{0x00, 0x00}
|
||||
cert, remainder, err := ReadCertificate(bytes)
|
||||
|
||||
assert.Equal(cert.length(), 2, "ReadCertificate() should populate the certificate with the provided data even when invalid")
|
||||
assert.Equal(len(remainder), 0, "ReadCertificate() returned non-zero length remainder on invalid certificate")
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal("error parsing certificate: certificate is too short", err.Error(), "correct error message should be returned")
|
||||
}
|
||||
}
|
@@ -1,98 +0,0 @@
|
||||
# certificate
|
||||
--
|
||||
import "github.com/go-i2p/go-i2p/lib/common/certificate"
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
const (
|
||||
CERT_NULL = iota
|
||||
CERT_HASHCASH
|
||||
CERT_HIDDEN
|
||||
CERT_SIGNED
|
||||
CERT_MULTIPLE
|
||||
CERT_KEY
|
||||
)
|
||||
```
|
||||
Certificate Types
|
||||
|
||||
```go
|
||||
const CERT_MIN_SIZE = 3
|
||||
```
|
||||
CERT_MIN_SIZE is the minimum size of a valid Certificate in []byte 1 byte for
|
||||
type 2 bytes for payload length
|
||||
|
||||
#### type Certificate
|
||||
|
||||
```go
|
||||
type Certificate struct {
|
||||
}
|
||||
```
|
||||
|
||||
Certificate is the representation of an I2P Certificate.
|
||||
|
||||
https://geti2p.net/spec/common-structures#certificate
|
||||
|
||||
#### func NewCertificate
|
||||
|
||||
```go
|
||||
func NewCertificate(data []byte) (certificate Certificate, err error)
|
||||
```
|
||||
NewCertificate creates a new Certficiate from []byte returns err if the
|
||||
certificate is too short or if the payload doesn't match specified length.
|
||||
|
||||
#### func ReadCertificate
|
||||
|
||||
```go
|
||||
func ReadCertificate(data []byte) (certificate Certificate, remainder []byte, err error)
|
||||
```
|
||||
ReadCertificate creates a Certificate from []byte and returns any ExcessBytes at
|
||||
the end of the input. returns err if the certificate could not be read.
|
||||
|
||||
#### func (*Certificate) Bytes
|
||||
|
||||
```go
|
||||
func (c *Certificate) Bytes() []byte
|
||||
```
|
||||
Bytes returns the entire certificate in []byte form, trims payload to specified
|
||||
length.
|
||||
|
||||
#### func (*Certificate) Data
|
||||
|
||||
```go
|
||||
func (c *Certificate) Data() (data []byte)
|
||||
```
|
||||
Data returns the payload of a Certificate, payload is trimmed to the specified
|
||||
length.
|
||||
|
||||
#### func (*Certificate) ExcessBytes
|
||||
|
||||
```go
|
||||
func (c *Certificate) ExcessBytes() []byte
|
||||
```
|
||||
ExcessBytes returns the excess bytes in a certificate found after the specified
|
||||
payload length.
|
||||
|
||||
#### func (*Certificate) Length
|
||||
|
||||
```go
|
||||
func (c *Certificate) Length() (length int)
|
||||
```
|
||||
Length returns the payload length of a Certificate.
|
||||
|
||||
#### func (*Certificate) RawBytes
|
||||
|
||||
```go
|
||||
func (c *Certificate) RawBytes() []byte
|
||||
```
|
||||
RawBytes returns the entire certificate in []byte form, includes excess payload
|
||||
data.
|
||||
|
||||
#### func (*Certificate) Type
|
||||
|
||||
```go
|
||||
func (c *Certificate) Type() (cert_type int)
|
||||
```
|
||||
Type returns the Certificate type specified in the first byte of the
|
||||
Certificate,
|
@@ -1,87 +0,0 @@
|
||||
// Package data implements common data structures used in higher level structures.
|
||||
package data
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/go-i2p/go-i2p/lib/util/logger"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var log = logger.GetGoI2PLogger()
|
||||
|
||||
// DATE_SIZE is the length in bytes of an I2P Date.
|
||||
const DATE_SIZE = 8
|
||||
|
||||
/*
|
||||
[I2P Date]
|
||||
Accurate for version 0.9.49
|
||||
|
||||
Description
|
||||
The number of milliseconds since midnight on Januyar 1, 1970 in the GMT timezone.
|
||||
If the number is 0, the date is undefined or null.
|
||||
|
||||
Contents
|
||||
8 byte Integer
|
||||
*/
|
||||
|
||||
// Date is the represenation of an I2P Date.
|
||||
//
|
||||
// https://geti2p.net/spec/common-structures#date
|
||||
type Date [8]byte
|
||||
|
||||
// Bytes returns the raw []byte content of a Date.
|
||||
func (i Date) Bytes() []byte {
|
||||
return i[:]
|
||||
}
|
||||
|
||||
// Int returns the Date as a Go integer.
|
||||
func (i Date) Int() int {
|
||||
return intFromBytes(i.Bytes())
|
||||
}
|
||||
|
||||
// Time takes the value stored in date as an 8 byte big-endian integer representing the
|
||||
// number of milliseconds since the beginning of unix time and converts it to a Go time.Time
|
||||
// struct.
|
||||
func (date Date) Time() (date_time time.Time) {
|
||||
seconds := Integer(date[:])
|
||||
date_time = time.Unix(0, int64(seconds.Int()*1000000))
|
||||
return
|
||||
}
|
||||
|
||||
// ReadDate creates a Date from []byte using the first DATE_SIZE bytes.
|
||||
// Any data after DATE_SIZE is returned as a remainder.
|
||||
func ReadDate(data []byte) (date Date, remainder []byte, err error) {
|
||||
if len(data) < 8 {
|
||||
log.WithFields(logrus.Fields{
|
||||
"data": data,
|
||||
}).Error("ReadDate: data is too short")
|
||||
err = errors.New("ReadDate: data is too short")
|
||||
return
|
||||
}
|
||||
copy(date[:], data[:8])
|
||||
remainder = data[8:]
|
||||
log.WithFields(logrus.Fields{
|
||||
"date_value": date.Int(),
|
||||
"remainder_length": len(remainder),
|
||||
}).Debug("Successfully read Date from data")
|
||||
return
|
||||
}
|
||||
|
||||
// NewDate creates a new Date from []byte using ReadDate.
|
||||
// Returns a pointer to Date unlike ReadDate.
|
||||
func NewDate(data []byte) (date *Date, remainder []byte, err error) {
|
||||
objdate, remainder, err := ReadDate(data)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to create new Date")
|
||||
return nil, remainder, err
|
||||
}
|
||||
|
||||
date = &objdate
|
||||
log.WithFields(logrus.Fields{
|
||||
"date_value": date.Int(),
|
||||
"remainder_length": len(remainder),
|
||||
}).Debug("Successfully created new Date")
|
||||
return
|
||||
}
|
@@ -1,16 +0,0 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestTimeFromMilliseconds(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
next_day := Date{0x00, 0x00, 0x00, 0x00, 0x05, 0x26, 0x5c, 0x00}
|
||||
go_time := next_day.Time()
|
||||
|
||||
assert.Equal(int64(86400), go_time.Unix(), "Date.Time() did not parse time in milliseconds")
|
||||
}
|
@@ -1,297 +0,0 @@
|
||||
# data
|
||||
--
|
||||
import "github.com/go-i2p/go-i2p/lib/common/data"
|
||||
|
||||
Package data implements common data structures used in higher level structures.
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
const DATE_SIZE = 8
|
||||
```
|
||||
DATE_SIZE is the length in bytes of an I2P Date.
|
||||
|
||||
```go
|
||||
const MAX_INTEGER_SIZE = 8
|
||||
```
|
||||
MAX_INTEGER_SIZE is the maximum length of an I2P integer in bytes.
|
||||
|
||||
```go
|
||||
const STRING_MAX_SIZE = 255
|
||||
```
|
||||
STRING_MAX_SIZE is the maximum number of bytes that can be stored in an I2P
|
||||
string
|
||||
|
||||
#### func PrintErrors
|
||||
|
||||
```go
|
||||
func PrintErrors(errs []error)
|
||||
```
|
||||
PrintErrors prints a formatted list of errors to the console.
|
||||
|
||||
#### func WrapErrors
|
||||
|
||||
```go
|
||||
func WrapErrors(errs []error) error
|
||||
```
|
||||
WrapErrors compiles a slice of errors and returns them wrapped together as a
|
||||
single error.
|
||||
|
||||
#### type Date
|
||||
|
||||
```go
|
||||
type Date [8]byte
|
||||
```
|
||||
|
||||
Date is the represenation of an I2P Date.
|
||||
|
||||
https://geti2p.net/spec/common-structures#date
|
||||
|
||||
#### func NewDate
|
||||
|
||||
```go
|
||||
func NewDate(data []byte) (date *Date, remainder []byte, err error)
|
||||
```
|
||||
NewDate creates a new Date from []byte using ReadDate. Returns a pointer to Date
|
||||
unlike ReadDate.
|
||||
|
||||
#### func ReadDate
|
||||
|
||||
```go
|
||||
func ReadDate(data []byte) (date Date, remainder []byte, err error)
|
||||
```
|
||||
ReadDate creates a Date from []byte using the first DATE_SIZE bytes. Any data
|
||||
after DATE_SIZE is returned as a remainder.
|
||||
|
||||
#### func (Date) Bytes
|
||||
|
||||
```go
|
||||
func (i Date) Bytes() []byte
|
||||
```
|
||||
Bytes returns the raw []byte content of a Date.
|
||||
|
||||
#### func (Date) Int
|
||||
|
||||
```go
|
||||
func (i Date) Int() int
|
||||
```
|
||||
Int returns the Date as a Go integer.
|
||||
|
||||
#### func (Date) Time
|
||||
|
||||
```go
|
||||
func (date Date) Time() (date_time time.Time)
|
||||
```
|
||||
Time takes the value stored in date as an 8 byte big-endian integer representing
|
||||
the number of milliseconds since the beginning of unix time and converts it to a
|
||||
Go time.Time struct.
|
||||
|
||||
#### type Hash
|
||||
|
||||
```go
|
||||
type Hash [32]byte
|
||||
```
|
||||
|
||||
Hash is the represenation of an I2P Hash.
|
||||
|
||||
https://geti2p.net/spec/common-structures#hash
|
||||
|
||||
#### func HashData
|
||||
|
||||
```go
|
||||
func HashData(data []byte) (h Hash)
|
||||
```
|
||||
HashData returns the SHA256 sum of a []byte input as Hash.
|
||||
|
||||
#### func HashReader
|
||||
|
||||
```go
|
||||
func HashReader(r io.Reader) (h Hash, err error)
|
||||
```
|
||||
HashReader returns the SHA256 sum from all data read from an io.Reader. return
|
||||
error if one occurs while reading from reader
|
||||
|
||||
#### func (Hash) Bytes
|
||||
|
||||
```go
|
||||
func (h Hash) Bytes() [32]byte
|
||||
```
|
||||
|
||||
#### type I2PString
|
||||
|
||||
```go
|
||||
type I2PString []byte
|
||||
```
|
||||
|
||||
I2PString is the represenation of an I2P String.
|
||||
|
||||
https://geti2p.net/spec/common-structures#string
|
||||
|
||||
#### func ReadI2PString
|
||||
|
||||
```go
|
||||
func ReadI2PString(data []byte) (str I2PString, remainder []byte, err error)
|
||||
```
|
||||
ReadI2PString returns I2PString from a []byte. The remaining bytes after the
|
||||
specified length are also returned. Returns a list of errors that occurred
|
||||
during parsing.
|
||||
|
||||
#### func ToI2PString
|
||||
|
||||
```go
|
||||
func ToI2PString(data string) (str I2PString, err error)
|
||||
```
|
||||
ToI2PString converts a Go string to an I2PString. Returns error if the string
|
||||
exceeds STRING_MAX_SIZE.
|
||||
|
||||
#### func (I2PString) Data
|
||||
|
||||
```go
|
||||
func (str I2PString) Data() (data string, err error)
|
||||
```
|
||||
Data returns the I2PString content as a string trimmed to the specified length
|
||||
and not including the length byte. Returns error encountered by Length.
|
||||
|
||||
#### func (I2PString) Length
|
||||
|
||||
```go
|
||||
func (str I2PString) Length() (length int, err error)
|
||||
```
|
||||
Length returns the length specified in the first byte. Returns error if the
|
||||
specified does not match the actual length or the string is otherwise invalid.
|
||||
|
||||
#### type Integer
|
||||
|
||||
```go
|
||||
type Integer []byte
|
||||
```
|
||||
|
||||
Integer is the represenation of an I2P Integer.
|
||||
|
||||
https://geti2p.net/spec/common-structures#integer
|
||||
|
||||
#### func NewInteger
|
||||
|
||||
```go
|
||||
func NewInteger(bytes []byte, size int) (integer *Integer, remainder []byte, err error)
|
||||
```
|
||||
NewInteger creates a new Integer from []byte using ReadInteger. Limits the
|
||||
length of the created Integer to MAX_INTEGER_SIZE. Returns a pointer to Integer
|
||||
unlike ReadInteger.
|
||||
|
||||
#### func NewIntegerFromInt
|
||||
|
||||
```go
|
||||
func NewIntegerFromInt(value int, size int) (integer *Integer, err error)
|
||||
```
|
||||
NewIntegerFromInt creates a new Integer from a Go integer of a specified []byte
|
||||
length.
|
||||
|
||||
#### func ReadInteger
|
||||
|
||||
```go
|
||||
func ReadInteger(bytes []byte, size int) (Integer, []byte)
|
||||
```
|
||||
ReadInteger returns an Integer from a []byte of specified length. The remaining
|
||||
bytes after the specified length are also returned.
|
||||
|
||||
#### func (Integer) Bytes
|
||||
|
||||
```go
|
||||
func (i Integer) Bytes() []byte
|
||||
```
|
||||
Bytes returns the raw []byte content of an Integer.
|
||||
|
||||
#### func (Integer) Int
|
||||
|
||||
```go
|
||||
func (i Integer) Int() int
|
||||
```
|
||||
Int returns the Date as a Go integer
|
||||
|
||||
#### type Mapping
|
||||
|
||||
```go
|
||||
type Mapping struct {
|
||||
}
|
||||
```
|
||||
|
||||
Mapping is the represenation of an I2P Mapping.
|
||||
|
||||
https://geti2p.net/spec/common-structures#mapping
|
||||
|
||||
#### func GoMapToMapping
|
||||
|
||||
```go
|
||||
func GoMapToMapping(gomap map[string]string) (mapping *Mapping, err error)
|
||||
```
|
||||
GoMapToMapping converts a Go map of unformatted strings to *Mapping.
|
||||
|
||||
#### func NewMapping
|
||||
|
||||
```go
|
||||
func NewMapping(bytes []byte) (values *Mapping, remainder []byte, err []error)
|
||||
```
|
||||
NewMapping creates a new *Mapping from []byte using ReadMapping. Returns a
|
||||
pointer to Mapping unlike ReadMapping.
|
||||
|
||||
#### func ReadMapping
|
||||
|
||||
```go
|
||||
func ReadMapping(bytes []byte) (mapping Mapping, remainder []byte, err []error)
|
||||
```
|
||||
ReadMapping returns Mapping from a []byte. The remaining bytes after the
|
||||
specified length are also returned. Returns a list of errors that occurred
|
||||
during parsing.
|
||||
|
||||
#### func ValuesToMapping
|
||||
|
||||
```go
|
||||
func ValuesToMapping(values MappingValues) *Mapping
|
||||
```
|
||||
ValuesToMapping creates a *Mapping using MappingValues. The values are sorted in
|
||||
the order defined in mappingOrder.
|
||||
|
||||
#### func (*Mapping) Data
|
||||
|
||||
```go
|
||||
func (mapping *Mapping) Data() []byte
|
||||
```
|
||||
Data returns a Mapping in its []byte form.
|
||||
|
||||
#### func (*Mapping) HasDuplicateKeys
|
||||
|
||||
```go
|
||||
func (mapping *Mapping) HasDuplicateKeys() bool
|
||||
```
|
||||
HasDuplicateKeys returns true if two keys in a mapping are identical.
|
||||
|
||||
#### func (Mapping) Values
|
||||
|
||||
```go
|
||||
func (mapping Mapping) Values() MappingValues
|
||||
```
|
||||
Values returns the values contained in a Mapping as MappingValues.
|
||||
|
||||
#### type MappingValues
|
||||
|
||||
```go
|
||||
type MappingValues [][2]I2PString
|
||||
```
|
||||
|
||||
MappingValues represents the parsed key value pairs inside of an I2P Mapping.
|
||||
|
||||
#### func ReadMappingValues
|
||||
|
||||
```go
|
||||
func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingValues, remainder_bytes []byte, errs []error)
|
||||
```
|
||||
ReadMappingValues returns *MappingValues from a []byte. The remaining bytes
|
||||
after the specified length are also returned. Returns a list of errors that
|
||||
occurred during parsing.
|
||||
|
||||
#### func (MappingValues) Get
|
||||
|
||||
```go
|
||||
func (m MappingValues) Get(key I2PString) I2PString
|
||||
```
|
@@ -1,19 +0,0 @@
|
||||
package data
|
||||
|
||||
import "fmt"
|
||||
|
||||
// WrapErrors compiles a slice of errors and returns them wrapped together as a single error.
|
||||
func WrapErrors(errs []error) error {
|
||||
var err error
|
||||
for i, e := range errs {
|
||||
err = fmt.Errorf("%v\n\t%d: %v", err, i, e)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// PrintErrors prints a formatted list of errors to the console.
|
||||
func PrintErrors(errs []error) {
|
||||
for i, e := range errs {
|
||||
fmt.Printf("\t%d: %v\n", i, e)
|
||||
}
|
||||
}
|
@@ -1,47 +0,0 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"io"
|
||||
)
|
||||
|
||||
/*
|
||||
[I2P Hash]
|
||||
Accurate for version 0.9.49
|
||||
|
||||
Description
|
||||
Represents the SHA256 of some data.
|
||||
|
||||
Contents
|
||||
32 bytes
|
||||
|
||||
[I2P Hash]:
|
||||
*/
|
||||
|
||||
// Hash is the represenation of an I2P Hash.
|
||||
//
|
||||
// https://geti2p.net/spec/common-structures#hash
|
||||
type Hash [32]byte
|
||||
|
||||
func (h Hash) Bytes() [32]byte {
|
||||
return h
|
||||
}
|
||||
|
||||
// HashData returns the SHA256 sum of a []byte input as Hash.
|
||||
func HashData(data []byte) (h Hash) {
|
||||
// log.Println("Hashing Data:", data)
|
||||
h = sha256.Sum256(data)
|
||||
return
|
||||
}
|
||||
|
||||
// HashReader returns the SHA256 sum from all data read from an io.Reader.
|
||||
// return error if one occurs while reading from reader
|
||||
func HashReader(r io.Reader) (h Hash, err error) {
|
||||
sha := sha256.New()
|
||||
_, err = io.Copy(sha, r)
|
||||
if err == nil {
|
||||
d := sha.Sum(nil)
|
||||
copy(h[:], d)
|
||||
}
|
||||
return
|
||||
}
|
@@ -1,85 +0,0 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// MAX_INTEGER_SIZE is the maximum length of an I2P integer in bytes.
|
||||
const MAX_INTEGER_SIZE = 8
|
||||
|
||||
/*
|
||||
[I2P Hash]
|
||||
Accurate for version 0.9.49
|
||||
|
||||
Description
|
||||
Represents a non-negative integer.
|
||||
|
||||
Contents
|
||||
1 to 8 bytes in network byte order (big endian) representing an unsigned integer.
|
||||
*/
|
||||
|
||||
// Integer is the represenation of an I2P Integer.
|
||||
//
|
||||
// https://geti2p.net/spec/common-structures#integer
|
||||
type Integer []byte
|
||||
|
||||
// Bytes returns the raw []byte content of an Integer.
|
||||
func (i Integer) Bytes() []byte {
|
||||
return i[:]
|
||||
}
|
||||
|
||||
// Int returns the Date as a Go integer
|
||||
func (i Integer) Int() int {
|
||||
return intFromBytes(i.Bytes())
|
||||
}
|
||||
|
||||
// ReadInteger returns an Integer from a []byte of specified length.
|
||||
// The remaining bytes after the specified length are also returned.
|
||||
func ReadInteger(bytes []byte, size int) (Integer, []byte) {
|
||||
if len(bytes) < size {
|
||||
return bytes[:size], bytes[len(bytes):]
|
||||
}
|
||||
return bytes[:size], bytes[size:]
|
||||
}
|
||||
|
||||
// NewInteger creates a new Integer from []byte using ReadInteger.
|
||||
// Limits the length of the created Integer to MAX_INTEGER_SIZE.
|
||||
// Returns a pointer to Integer unlike ReadInteger.
|
||||
func NewInteger(bytes []byte, size int) (integer *Integer, remainder []byte, err error) {
|
||||
integerSize := MAX_INTEGER_SIZE
|
||||
if size < MAX_INTEGER_SIZE {
|
||||
integerSize = size
|
||||
}
|
||||
intBytes := bytes[:integerSize]
|
||||
remainder = bytes[integerSize:]
|
||||
i, _ := ReadInteger(intBytes, integerSize)
|
||||
integer = &i
|
||||
return
|
||||
}
|
||||
|
||||
// NewIntegerFromInt creates a new Integer from a Go integer of a specified []byte length.
|
||||
func NewIntegerFromInt(value int, size int) (integer *Integer, err error) {
|
||||
bytes := make([]byte, MAX_INTEGER_SIZE)
|
||||
binary.BigEndian.PutUint64(bytes, uint64(value))
|
||||
integerSize := MAX_INTEGER_SIZE
|
||||
if size < MAX_INTEGER_SIZE {
|
||||
integerSize = size
|
||||
}
|
||||
objinteger, _, err := NewInteger(bytes[MAX_INTEGER_SIZE-integerSize:], integerSize)
|
||||
integer = objinteger
|
||||
return
|
||||
}
|
||||
|
||||
// Interpret a slice of bytes from length 0 to length 8 as a big-endian
|
||||
// integer and return an int representation.
|
||||
func intFromBytes(number []byte) (value int) {
|
||||
num_len := len(number)
|
||||
if num_len < MAX_INTEGER_SIZE {
|
||||
number = append(
|
||||
make([]byte, MAX_INTEGER_SIZE-num_len),
|
||||
number...,
|
||||
)
|
||||
}
|
||||
value = int(binary.BigEndian.Uint64(number))
|
||||
return
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestIntegerBigEndian(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
bytes := []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}
|
||||
integer := Integer(bytes)
|
||||
|
||||
assert.Equal(integer.Int(), 1, "Integer() did not parse bytes big endian")
|
||||
}
|
||||
|
||||
func TestWorksWithOneByte(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
integer := Integer([]byte{0x01})
|
||||
|
||||
assert.Equal(integer.Int(), 1, "Integer() did not correctly parse single byte slice")
|
||||
}
|
||||
|
||||
func TestIsZeroWithNoData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
integer := Integer([]byte{})
|
||||
|
||||
assert.Equal(integer.Int(), 0, "Integer() did not correctly parse zero length byte slice")
|
||||
}
|
@@ -1,233 +0,0 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
/*
|
||||
[I2P Mapping]
|
||||
Accurate for version 0.9.49
|
||||
|
||||
Description
|
||||
A set of key/value mappings or properties
|
||||
|
||||
|
||||
Contents
|
||||
A 2-byte size Integer followed by a series of String=String; pairs
|
||||
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| size |key_string (len + data) | = |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| val_string (len + data) | ; | ...
|
||||
+----+----+----+----+----+----+----+
|
||||
size :: Integer
|
||||
length -> 2 bytes
|
||||
Total number of bytes that follow
|
||||
|
||||
key_string :: String
|
||||
A string (one byte length followed by UTF-8 encoded characters)
|
||||
|
||||
= :: A single byte containing '='
|
||||
|
||||
val_string :: String
|
||||
A string (one byte length followed by UTF-8 encoded characters)
|
||||
|
||||
; :: A single byte containing ';'
|
||||
*/
|
||||
|
||||
// Mapping is the represenation of an I2P Mapping.
|
||||
//
|
||||
// https://geti2p.net/spec/common-structures#mapping
|
||||
type Mapping struct {
|
||||
size *Integer
|
||||
vals *MappingValues
|
||||
}
|
||||
|
||||
// Values returns the values contained in a Mapping as MappingValues.
|
||||
func (mapping Mapping) Values() MappingValues {
|
||||
if mapping.vals == nil {
|
||||
log.Debug("Mapping values are nil, returning empty MappingValues")
|
||||
return MappingValues{}
|
||||
}
|
||||
log.WithFields(logrus.Fields{
|
||||
"values_count": len(*mapping.vals),
|
||||
}).Debug("Retrieved Mapping values")
|
||||
return *mapping.vals
|
||||
}
|
||||
|
||||
// Data returns a Mapping in its []byte form.
|
||||
func (mapping *Mapping) Data() []byte {
|
||||
keyOrValIntegerLength := 1
|
||||
bytes := mapping.size.Bytes()
|
||||
for _, pair := range mapping.Values() {
|
||||
klen, _ := pair[0].Length()
|
||||
keylen, _ := NewIntegerFromInt(klen, keyOrValIntegerLength)
|
||||
bytes = append(bytes, keylen.Bytes()...)
|
||||
bytes = append(bytes, pair[0][1:]...)
|
||||
bytes = append(bytes, 0x3d)
|
||||
vlen, _ := pair[1].Length()
|
||||
vallen, _ := NewIntegerFromInt(vlen, keyOrValIntegerLength)
|
||||
bytes = append(bytes, vallen.Bytes()...)
|
||||
bytes = append(bytes, pair[1][1:]...)
|
||||
bytes = append(bytes, 0x3b)
|
||||
}
|
||||
return bytes
|
||||
}
|
||||
|
||||
// HasDuplicateKeys returns true if two keys in a mapping are identical.
|
||||
func (mapping *Mapping) HasDuplicateKeys() bool {
|
||||
log.Debug("Checking for duplicate keys in Mapping")
|
||||
seen_values := make(map[string]bool)
|
||||
values := mapping.Values()
|
||||
for _, pair := range values {
|
||||
key, _ := pair[0].Data()
|
||||
if _, present := seen_values[key]; present {
|
||||
log.WithFields(logrus.Fields{
|
||||
"duplicate_key": key,
|
||||
}).Warn("Found duplicate key in Mapping")
|
||||
return true
|
||||
} else {
|
||||
seen_values[key] = true
|
||||
}
|
||||
}
|
||||
log.Debug("No duplicate keys found in Mapping")
|
||||
return false
|
||||
}
|
||||
|
||||
// GoMapToMapping converts a Go map of unformatted strings to *Mapping.
|
||||
func GoMapToMapping(gomap map[string]string) (mapping *Mapping, err error) {
|
||||
log.WithFields(logrus.Fields{
|
||||
"input_map_size": len(gomap),
|
||||
}).Debug("Converting Go map to Mapping")
|
||||
map_vals := MappingValues{}
|
||||
for k, v := range gomap {
|
||||
key_str, kerr := ToI2PString(k)
|
||||
if kerr != nil {
|
||||
log.WithError(kerr).Error("Failed to convert key to I2PString")
|
||||
err = kerr
|
||||
return
|
||||
}
|
||||
val_str, verr := ToI2PString(v)
|
||||
if verr != nil {
|
||||
log.WithError(verr).Error("Failed to convert value to I2PString")
|
||||
err = verr
|
||||
return
|
||||
}
|
||||
map_vals = append(
|
||||
map_vals,
|
||||
[2]I2PString{key_str, val_str},
|
||||
)
|
||||
}
|
||||
mapping = ValuesToMapping(map_vals)
|
||||
log.WithFields(logrus.Fields{
|
||||
"mapping_size": len(map_vals),
|
||||
}).Debug("Successfully converted Go map to Mapping")
|
||||
return
|
||||
}
|
||||
|
||||
// Check if the string parsing error indicates that the Mapping
|
||||
// should no longer be parsed.
|
||||
func stopValueRead(err error) bool {
|
||||
result := err.Error() == "error parsing string: zero length"
|
||||
if result {
|
||||
log.WithError(err).Debug("Stopping value read due to zero length error")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Determine if the first byte in a slice of bytes is the provided byte.
|
||||
func beginsWith(bytes []byte, chr byte) bool {
|
||||
/*
|
||||
return len(bytes) != 0 &&
|
||||
bytes[0] == chr
|
||||
*/
|
||||
result := len(bytes) != 0 && bytes[0] == chr
|
||||
log.WithFields(logrus.Fields{
|
||||
"bytes_length": len(bytes),
|
||||
"expected_char": string(chr),
|
||||
"result": result,
|
||||
}).Debug("Checked if bytes begin with specific character")
|
||||
return result
|
||||
}
|
||||
|
||||
// ReadMapping returns Mapping from a []byte.
|
||||
// The remaining bytes after the specified length are also returned.
|
||||
// Returns a list of errors that occurred during parsing.
|
||||
func ReadMapping(bytes []byte) (mapping Mapping, remainder []byte, err []error) {
|
||||
log.WithFields(logrus.Fields{
|
||||
"input_length": len(bytes),
|
||||
}).Debug("Reading Mapping from bytes")
|
||||
if len(bytes) < 3 {
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "ReadMapping",
|
||||
"reason": "zero length",
|
||||
}).Warn("mapping format violation")
|
||||
e := errors.New("zero length")
|
||||
err = append(err, e)
|
||||
return
|
||||
}
|
||||
size, remainder, e := NewInteger(bytes, 2)
|
||||
if e != nil {
|
||||
log.WithError(e).Error("Failed to read Mapping size")
|
||||
err = append(err, e)
|
||||
}
|
||||
if size.Int() == 0 {
|
||||
log.Warn("Mapping size is zero")
|
||||
return
|
||||
}
|
||||
mapping.size = size
|
||||
map_bytes := remainder[:mapping.size.Int()]
|
||||
remainder = remainder[mapping.size.Int():]
|
||||
if len(remainder) == 0 {
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "ReadMapping",
|
||||
"reason": "zero length",
|
||||
}).Warn("mapping format violation")
|
||||
e := errors.New("zero length")
|
||||
err = append(err, e)
|
||||
}
|
||||
// TODO: this should take the remainder and the length we already parsed above, as a parameter.
|
||||
// Like tomorrow morning.
|
||||
// ReadMappingValues should not attempt to figure out the length of the bytes it's reading over.
|
||||
vals, _, mappingValueErrs := ReadMappingValues(map_bytes, *mapping.size)
|
||||
|
||||
err = append(err, mappingValueErrs...)
|
||||
mapping.vals = vals
|
||||
if len(mappingValueErrs) > 0 {
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "ReadMapping",
|
||||
"reason": "error parsing mapping values",
|
||||
}).Warn("mapping format violation")
|
||||
e := errors.New("error parsing mapping values")
|
||||
err = append(err, e)
|
||||
}
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"mapping_size": mapping.size.Int(),
|
||||
"values_count": len(*mapping.vals),
|
||||
"remainder_length": len(remainder),
|
||||
"error_count": len(err),
|
||||
}).Debug("Finished reading Mapping")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// NewMapping creates a new *Mapping from []byte using ReadMapping.
|
||||
// Returns a pointer to Mapping unlike ReadMapping.
|
||||
func NewMapping(bytes []byte) (values *Mapping, remainder []byte, err []error) {
|
||||
log.WithFields(logrus.Fields{
|
||||
"input_length": len(bytes),
|
||||
}).Debug("Creating new Mapping")
|
||||
|
||||
objvalues, remainder, err := ReadMapping(bytes)
|
||||
values = &objvalues
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"values_count": len(values.Values()),
|
||||
"remainder_length": len(remainder),
|
||||
"error_count": len(err),
|
||||
}).Debug("Finished creating new Mapping")
|
||||
return
|
||||
}
|
@@ -1,192 +0,0 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestValuesExclusesPairWithBadData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
bad_key, _, errs := NewMapping([]byte{0x00, 0x0c, 0x01, 0x61, 0x3d, 0x01, 0x62, 0x3b, 0x00})
|
||||
values := bad_key.Values()
|
||||
|
||||
e := WrapErrors(errs)
|
||||
t.Log(e)
|
||||
|
||||
assert.NotNil(errs, "Values() did not return errors when some values had bad key")
|
||||
|
||||
if assert.Equal(1, len(values), "Values() did not return valid values when some values had bad key") {
|
||||
k := values[0][0]
|
||||
key, _ := k.Data()
|
||||
v := values[0][1]
|
||||
val, _ := v.Data()
|
||||
assert.Equal(key, "a", "Values() returned by data with invalid key contains incorrect present key")
|
||||
assert.Equal(val, "b", "Values() returned by data with invalid key contains incorrect present key")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValuesWarnsMissingData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
_, _, errs := NewMapping([]byte{0x00, 0x06, 0x01, 0x61, 0x3d, 0x01, 0x62})
|
||||
|
||||
if assert.Equal(2, len(errs), "Values() reported wrong error count when mapping had missing data") {
|
||||
assert.Equal(errs[0].Error(), "warning parsing mapping: mapping length exceeds provided data")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValuesWarnsExtraData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
mapping, _, errs := NewMapping([]byte{0x00, 0x06, 0x01, 0x61, 0x3d, 0x01, 0x62, 0x3b, 0x00})
|
||||
values := mapping.Values()
|
||||
|
||||
key, kerr := values[0][0].Data()
|
||||
val, verr := values[0][1].Data()
|
||||
|
||||
assert.Nil(kerr)
|
||||
assert.Nil(verr)
|
||||
assert.Equal(key, "a", "Values() did not return key in valid data")
|
||||
assert.Equal(val, "b", "Values() did not return value in valid data")
|
||||
|
||||
if assert.Equal(2, len(errs), "Values() reported wrong error count when mapping had extra data") {
|
||||
assert.Equal("warning parsing mapping: data exists beyond length of mapping", errs[0].Error(), "correct error message should be returned")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValuesEnforcesEqualDelimitor(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
mapping, _, errs := NewMapping([]byte{0x00, 0x06, 0x01, 0x61, 0x30, 0x01, 0x62, 0x3b})
|
||||
values := mapping.Values()
|
||||
|
||||
if assert.Equal(2, len(errs), "Values() reported wrong error count when mapping had = format error") {
|
||||
assert.Equal("mapping format violation, expected =", errs[0].Error(), "correct error message should be returned")
|
||||
}
|
||||
assert.Equal(0, len(values), "Values() not empty with invalid data due to = format error")
|
||||
}
|
||||
|
||||
func TestValuesEnforcedSemicolonDelimitor(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
mapping, _, errs := NewMapping([]byte{0x00, 0x06, 0x01, 0x61, 0x3d, 0x01, 0x62, 0x30})
|
||||
values := mapping.Values()
|
||||
|
||||
if assert.Equal(2, len(errs), "Values() reported wrong error count when mapping had ; format error") {
|
||||
assert.Equal("mapping format violation, expected ;", errs[0].Error(), "correct error message should be returned")
|
||||
}
|
||||
assert.Equal(0, len(values), "Values() not empty with invalid data due to ; format error")
|
||||
}
|
||||
|
||||
func TestValuesReturnsValues(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
mapping, _, errs := NewMapping([]byte{0x00, 0x06, 0x01, 0x61, 0x3d, 0x01, 0x62, 0x3b})
|
||||
values := mapping.Values()
|
||||
|
||||
key, kerr := values[0][0].Data()
|
||||
val, verr := values[0][1].Data()
|
||||
|
||||
assert.Nil(errs, "Values() returned a errors with parsing valid data")
|
||||
assert.Nil(kerr)
|
||||
assert.Nil(verr)
|
||||
assert.Equal("a", key, "Values() did not return key in valid data")
|
||||
assert.Equal("b", val, "Values() did not return value in valid data")
|
||||
}
|
||||
|
||||
func TestHasDuplicateKeysTrueWhenDuplicates(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
dups, _, _ := NewMapping([]byte{0x00, 0x0c, 0x01, 0x61, 0x3d, 0x01, 0x62, 0x3b, 0x01, 0x61, 0x3d, 0x01, 0x62, 0x3b})
|
||||
|
||||
assert.Equal(true, dups.HasDuplicateKeys(), "HasDuplicateKeys() did not report true when duplicate keys present")
|
||||
}
|
||||
|
||||
func TestHasDuplicateKeysFalseWithoutDuplicates(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
mapping, _, _ := NewMapping([]byte{0x00, 0x06, 0x01, 0x61, 0x3d, 0x01, 0x62, 0x3b})
|
||||
|
||||
assert.Equal(false, mapping.HasDuplicateKeys(), "HasDuplicateKeys() did not report false when no duplicate keys present")
|
||||
}
|
||||
|
||||
func TestReadMappingHasDuplicateKeys(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
_, _, errs := NewMapping([]byte{0x00, 0x0c, 0x01, 0x61, 0x3d, 0x01, 0x62, 0x3b, 0x01, 0x61, 0x3d, 0x01, 0x62, 0x3b})
|
||||
|
||||
assert.Equal("mapping format violation, duplicate key in mapping", errs[0].Error(), "ReadMapping should throw an error when duplicate keys are present.")
|
||||
}
|
||||
|
||||
func TestGoMapToMappingProducesCorrectMapping(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
gomap := map[string]string{"a": "b"}
|
||||
mapping, err := GoMapToMapping(gomap)
|
||||
|
||||
assert.Nil(err, "GoMapToMapping() returned error with valid data")
|
||||
expected := []byte{0x00, 0x06, 0x01, 0x61, 0x3d, 0x01, 0x62, 0x3b}
|
||||
if bytes.Compare(mapping.Data(), expected) != 0 {
|
||||
t.Fatal("GoMapToMapping did not produce correct Mapping", mapping, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFullGoMapToMappingProducesCorrectMapping(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
gomap := map[string]string{
|
||||
"a": "b",
|
||||
"c": "d",
|
||||
}
|
||||
mapping, err := GoMapToMapping(gomap)
|
||||
|
||||
assert.Nil(err, "GoMapToMapping() returned error with valid data")
|
||||
expected := []byte{0x00, 0x0c, 0x01, 0x61, 0x3d, 0x01, 0x62, 0x3b, 0x01, 0x63, 0x3d, 0x01, 0x64, 0x3b}
|
||||
if bytes.Compare(mapping.Data(), expected) != 0 {
|
||||
t.Fatal("GoMapToMapping did not produce correct Mapping", mapping, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStopValueReadTrueWhenCorrectErr(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
status := stopValueRead(errors.New("error parsing string: zero length"))
|
||||
|
||||
assert.Equal(true, status, "stopValueRead() did not return true when String error found")
|
||||
}
|
||||
|
||||
func TestStopValueReadFalseWhenWrongErr(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
status := stopValueRead(errors.New("something else"))
|
||||
|
||||
assert.Equal(false, status, "stopValueRead() did not return false when non String error found")
|
||||
}
|
||||
|
||||
func TestBeginsWithCorrectWhenTrue(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
slice := []byte{0x41}
|
||||
|
||||
assert.Equal(true, beginsWith(slice, 0x41), "beginsWith() did not return true when correct")
|
||||
}
|
||||
|
||||
func TestBeginsWithCorrectWhenFalse(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
slice := []byte{0x00}
|
||||
|
||||
assert.Equal(false, beginsWith(slice, 0x41), "beginsWith() did not false when incorrect")
|
||||
}
|
||||
|
||||
func TestBeginsWithCorrectWhenNil(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
slice := make([]byte, 0)
|
||||
|
||||
assert.Equal(false, beginsWith(slice, 0x41), "beginsWith() did not return false on empty slice")
|
||||
}
|
@@ -1,222 +0,0 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sort"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// MappingValues represents the parsed key value pairs inside of an I2P Mapping.
|
||||
type MappingValues [][2]I2PString
|
||||
|
||||
func (m MappingValues) Get(key I2PString) I2PString {
|
||||
keyBytes, _ := key.Data()
|
||||
log.WithFields(logrus.Fields{
|
||||
"key": string(keyBytes),
|
||||
}).Debug("Searching for key in MappingValues")
|
||||
for _, pair := range m {
|
||||
kb, _ := pair[0][0:].Data()
|
||||
if kb == keyBytes {
|
||||
log.WithFields(logrus.Fields{
|
||||
"key": string(keyBytes),
|
||||
"value": string(pair[1][1:]),
|
||||
}).Debug("Found matching key in MappingValues")
|
||||
return pair[1]
|
||||
}
|
||||
}
|
||||
log.WithFields(logrus.Fields{
|
||||
"key": string(keyBytes),
|
||||
}).Debug("Key not found in MappingValues")
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValuesToMapping creates a *Mapping using MappingValues.
|
||||
// The values are sorted in the order defined in mappingOrder.
|
||||
func ValuesToMapping(values MappingValues) *Mapping {
|
||||
// Default length to 2 * len
|
||||
// 1 byte for ;
|
||||
// 1 byte for =
|
||||
log.WithFields(logrus.Fields{
|
||||
"values_count": len(values),
|
||||
}).Debug("Converting MappingValues to Mapping")
|
||||
baseLength := 2 * len(values)
|
||||
for _, mappingVals := range values {
|
||||
for _, keyOrVal := range mappingVals {
|
||||
baseLength += len(keyOrVal)
|
||||
}
|
||||
}
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"mapping_size": baseLength,
|
||||
}).Debug("Created Mapping from MappingValues")
|
||||
|
||||
mappingSize, _ := NewIntegerFromInt(baseLength, 2)
|
||||
return &Mapping{
|
||||
size: mappingSize,
|
||||
vals: &values,
|
||||
}
|
||||
}
|
||||
|
||||
// I2P Mappings require consistent order in some cases for cryptographic signing, and sorting
|
||||
// by keys. The Mapping is sorted lexographically by keys. Duplicate keys are allowed in general,
|
||||
// but in implementations where they must be sorted like I2CP SessionConfig duplicate keys are not allowed.
|
||||
// In practice routers do not seem to allow duplicate keys.
|
||||
func mappingOrder(values MappingValues) {
|
||||
sort.SliceStable(values, func(i, j int) bool {
|
||||
// Lexographic sort on keys only
|
||||
data1, _ := values[i][0].Data()
|
||||
data2, _ := values[j][0].Data()
|
||||
return data1 < data2
|
||||
})
|
||||
}
|
||||
|
||||
// ReadMappingValues returns *MappingValues from a []byte.
|
||||
// The remaining bytes after the specified length are also returned.
|
||||
// Returns a list of errors that occurred during parsing.
|
||||
func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingValues, remainder_bytes []byte, errs []error) {
|
||||
// mapping := remainder
|
||||
// var remainder = mapping
|
||||
// var err error
|
||||
log.WithFields(logrus.Fields{
|
||||
"input_length": len(remainder),
|
||||
"map_length": map_length.Int(),
|
||||
}).Debug("Reading MappingValues")
|
||||
|
||||
if remainder == nil || len(remainder) < 1 {
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "(Mapping) Values",
|
||||
"reason": "data shorter than expected",
|
||||
}).Error("mapping contained no data")
|
||||
errs = []error{errors.New("mapping contained no data")}
|
||||
return
|
||||
}
|
||||
map_values := make(MappingValues, 0)
|
||||
int_map_length := map_length.Int()
|
||||
mapping_len := len(remainder)
|
||||
if mapping_len > int_map_length {
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "(Mapping) Values",
|
||||
"mapping_bytes_length": mapping_len,
|
||||
"mapping_length_field": int_map_length,
|
||||
"reason": "data longer than expected",
|
||||
}).Warn("mapping format warning")
|
||||
errs = append(errs, errors.New("warning parsing mapping: data exists beyond length of mapping"))
|
||||
} else if int_map_length > mapping_len {
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "(Mapping) Values",
|
||||
"mapping_bytes_length": mapping_len,
|
||||
"mapping_length_field": int_map_length,
|
||||
"reason": "data shorter than expected",
|
||||
}).Warn("mapping format warning")
|
||||
errs = append(errs, errors.New("warning parsing mapping: mapping length exceeds provided data"))
|
||||
}
|
||||
|
||||
encounteredKeysMap := map[string]bool{}
|
||||
// pop off length bytes before parsing kv pairs
|
||||
// remainder = remainder[2:]
|
||||
|
||||
for {
|
||||
// Read a key, breaking on fatal errors
|
||||
// and appending warnings
|
||||
|
||||
// Minimum byte length required for another KV pair.
|
||||
// Two bytes for each string length
|
||||
// At least 1 byte per string
|
||||
// One byte for =
|
||||
// One byte for ;
|
||||
if len(remainder) < 6 {
|
||||
// Not returning an error here as the issue is already flagged by mapping length being wrong.
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "(Mapping) Values",
|
||||
"reason": "mapping format violation",
|
||||
}).Warn("mapping format violation, too few bytes for a kv pair")
|
||||
break
|
||||
}
|
||||
|
||||
key_str, more, err := ReadI2PString(remainder)
|
||||
if err != nil {
|
||||
if stopValueRead(err) {
|
||||
errs = append(errs, err)
|
||||
// return
|
||||
}
|
||||
}
|
||||
// overwriting remainder with more as another var to prevent memory weirdness in loops
|
||||
remainder = more
|
||||
// log.Printf("(MAPPING VALUES DEBUG) Remainder: %s\n", remainder)
|
||||
|
||||
// Check if key has already been encountered in this mapping
|
||||
keyBytes, _ := key_str.Data()
|
||||
keyAsString := string(keyBytes)
|
||||
_, ok := encounteredKeysMap[keyAsString]
|
||||
if ok {
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "(Mapping) Values",
|
||||
"reason": "duplicate key in mapping",
|
||||
"key": string(key_str),
|
||||
}).Error("mapping format violation")
|
||||
log.Printf("DUPE: %s", key_str)
|
||||
errs = append(errs, errors.New("mapping format violation, duplicate key in mapping"))
|
||||
// Based on other implementations this does not seem to happen often?
|
||||
// Java throws an exception in this case, the base object is a Hashmap so the value is overwritten and an exception is thrown.
|
||||
// i2pd as far as I can tell just overwrites the original value
|
||||
// Continue on, we can check if the Mapping contains duplicate keys later.
|
||||
}
|
||||
|
||||
if !beginsWith(remainder, 0x3d) {
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "(Mapping) Values",
|
||||
"reason": "expected =",
|
||||
"value:": string(remainder),
|
||||
}).Warn("mapping format violation")
|
||||
errs = append(errs, errors.New("mapping format violation, expected ="))
|
||||
log.Printf("ERRVAL: %s", remainder)
|
||||
break
|
||||
} else {
|
||||
remainder = remainder[1:]
|
||||
}
|
||||
|
||||
// Read a value, breaking on fatal errors
|
||||
// and appending warnings
|
||||
val_str, more, err := ReadI2PString(remainder)
|
||||
if err != nil {
|
||||
if stopValueRead(err) {
|
||||
errs = append(errs, err)
|
||||
// return
|
||||
}
|
||||
}
|
||||
// overwriting remainder with more as another var to prevent memory weirdness in loops
|
||||
remainder = more
|
||||
// log.Printf("(MAPPING VALUES DEBUG) Remainder: %s\n", remainder)
|
||||
// log.Printf("(MAPPING VALUES DEBUG) String: value: %s", val_str)
|
||||
if !beginsWith(remainder, 0x3b) {
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "(Mapping) Values",
|
||||
"reason": "expected ;",
|
||||
"value:": string(remainder),
|
||||
}).Warn("mapping format violation")
|
||||
errs = append(errs, errors.New("mapping format violation, expected ;"))
|
||||
break
|
||||
} else {
|
||||
remainder = remainder[1:]
|
||||
}
|
||||
|
||||
// Append the key-value pair and break if there is no more data to read
|
||||
map_values = append(map_values, [2]I2PString{key_str, val_str})
|
||||
if len(remainder) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
// Store the encountered key with arbitrary data
|
||||
encounteredKeysMap[keyAsString] = true
|
||||
}
|
||||
values = &map_values
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"values_count": len(map_values),
|
||||
"remainder_length": len(remainder_bytes),
|
||||
"error_count": len(errs),
|
||||
}).Debug("Finished reading MappingValues")
|
||||
|
||||
return
|
||||
}
|
@@ -1,47 +0,0 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMappingOrderSortsValuesThenKeys(t *testing.T) {
|
||||
a, _ := ToI2PString("a")
|
||||
b, _ := ToI2PString("b")
|
||||
aa, _ := ToI2PString("aa")
|
||||
ab, _ := ToI2PString("ab")
|
||||
ac, _ := ToI2PString("ac")
|
||||
values := MappingValues{
|
||||
[2]I2PString{b, b},
|
||||
[2]I2PString{ac, a},
|
||||
[2]I2PString{ab, b},
|
||||
[2]I2PString{aa, a},
|
||||
[2]I2PString{a, a},
|
||||
}
|
||||
mappingOrder(values)
|
||||
for i, pair := range values {
|
||||
key, _ := pair[0].Data()
|
||||
switch i {
|
||||
case 0:
|
||||
if !(key == "a") {
|
||||
t.Fatal(fmt.Sprintf("mappingOrder expected key a, got %s at index", key), i)
|
||||
}
|
||||
case 1:
|
||||
if !(key == "aa") {
|
||||
t.Fatal(fmt.Sprintf("mappingOrder expected key aa, got %s at index", key), i)
|
||||
}
|
||||
case 2:
|
||||
if !(key == "ab") {
|
||||
t.Fatal(fmt.Sprintf("mappingOrder expected key ab, got %s at index", key), i)
|
||||
}
|
||||
case 3:
|
||||
if !(key == "ac") {
|
||||
t.Fatal(fmt.Sprintf("mappingOrder expected key ac, got %s at index", key), i)
|
||||
}
|
||||
case 4:
|
||||
if !(key == "b") {
|
||||
t.Fatal(fmt.Sprintf("mappingOrder expected key b, got %s at index", key), i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,170 +0,0 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// STRING_MAX_SIZE is the maximum number of bytes that can be stored in an I2P string
|
||||
const STRING_MAX_SIZE = 255
|
||||
|
||||
/*
|
||||
[I2P String]
|
||||
Accurate for version 0.9.49
|
||||
|
||||
Description
|
||||
Represents a UTF-8 encoded string.
|
||||
|
||||
Contents
|
||||
1 or more bytes where the first byte is the number of bytes (not characters!) in the string
|
||||
and the remaining 0-255 bytes are the non-null terminated UTF-8 encoded character array.
|
||||
Length limit is 255 bytes (not characters). Length may be 0.
|
||||
*/
|
||||
|
||||
// I2PString is the represenation of an I2P String.
|
||||
//
|
||||
// https://geti2p.net/spec/common-structures#string
|
||||
type I2PString []byte
|
||||
|
||||
// Length returns the length specified in the first byte.
|
||||
// Returns error if the specified does not match the actual length or the string is otherwise invalid.
|
||||
func (str I2PString) Length() (length int, err error) {
|
||||
if len(str) == 0 {
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "(I2PString) Length",
|
||||
"reason": "no data",
|
||||
}).Error("error parsing string")
|
||||
err = errors.New("error parsing string: zero length")
|
||||
return
|
||||
}
|
||||
l, _, err := NewInteger(str[:], 1)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to create Integer from I2PString")
|
||||
return l.Int(), err
|
||||
}
|
||||
length = l.Int()
|
||||
str_len := len(str)
|
||||
if length > str_len {
|
||||
/*log.WithFields(log.Fields{
|
||||
"at": "(I2PString) Length",
|
||||
"string_bytes_length": str_len,
|
||||
"string_length_field": length,
|
||||
"data": string(str),
|
||||
"reason": "data less than specified by length",
|
||||
}).Error("string format warning")*/
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "(I2PString) Length",
|
||||
"string_bytes_length": str_len,
|
||||
"string_length_field": length,
|
||||
"reason": "data less than specified by length",
|
||||
}).Warn("string format warning")
|
||||
err = errors.New("string parsing warning: string data is shorter than specified by length")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Data returns the I2PString content as a string trimmed to the specified length and not including the length byte.
|
||||
// Returns error encountered by Length.
|
||||
func (str I2PString) Data() (data string, err error) {
|
||||
length, err := str.Length()
|
||||
if err != nil {
|
||||
switch err.Error() {
|
||||
case "error parsing string: zero length":
|
||||
log.WithError(err).Warn("Zero length I2PString")
|
||||
return
|
||||
case "string parsing warning: string data is shorter than specified by length":
|
||||
log.WithError(err).Warn("I2PString data shorter than specified length")
|
||||
if is, e := ToI2PString(string(str[:])); e != nil {
|
||||
log.WithError(e).Error("Failed to convert short I2PString")
|
||||
return "", e
|
||||
} else {
|
||||
return is.Data()
|
||||
}
|
||||
case "string parsing warning: string contains data beyond length":
|
||||
log.WithError(err).Warn("I2PString contains data beyond specified length")
|
||||
data = string(str[1:])
|
||||
return
|
||||
}
|
||||
}
|
||||
if length == 0 {
|
||||
log.Debug("I2PString is empty")
|
||||
return
|
||||
}
|
||||
data = string(str[1 : length+1])
|
||||
log.WithFields(logrus.Fields{
|
||||
"data_length": len(data),
|
||||
}).Debug("Retrieved I2PString data")
|
||||
return
|
||||
}
|
||||
|
||||
// ToI2PString converts a Go string to an I2PString.
|
||||
// Returns error if the string exceeds STRING_MAX_SIZE.
|
||||
func ToI2PString(data string) (str I2PString, err error) {
|
||||
log.WithFields(logrus.Fields{
|
||||
"input_length": len(data),
|
||||
}).Debug("Converting string to I2PString")
|
||||
data_len := len(data)
|
||||
if data_len > STRING_MAX_SIZE {
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "ToI2PI2PString",
|
||||
"string_len": data_len,
|
||||
"max_len": STRING_MAX_SIZE,
|
||||
"reason": "too much data",
|
||||
}).Error("cannot create I2P string")
|
||||
err = errors.New("cannot store that much data in I2P string")
|
||||
return
|
||||
}
|
||||
i2p_string := []byte{byte(data_len)}
|
||||
i2p_string = append(i2p_string, []byte(data)...)
|
||||
str = I2PString(i2p_string)
|
||||
log.WithFields(logrus.Fields{
|
||||
"i2pstring_length": len(str),
|
||||
}).Debug("Successfully converted string to I2PString")
|
||||
return
|
||||
}
|
||||
|
||||
//
|
||||
// Read a string from a slice of bytes, returning any extra data on the end
|
||||
// of the slice and any errors encountered parsing the I2PString.
|
||||
//
|
||||
|
||||
// ReadI2PString returns I2PString from a []byte.
|
||||
// The remaining bytes after the specified length are also returned.
|
||||
// Returns a list of errors that occurred during parsing.
|
||||
func ReadI2PString(data []byte) (str I2PString, remainder []byte, err error) {
|
||||
log.WithFields(logrus.Fields{
|
||||
"input_length": len(data),
|
||||
}).Debug("Reading I2PString from bytes")
|
||||
length, _, err := NewInteger(data, 1)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to read I2PString length")
|
||||
return
|
||||
}
|
||||
data_len := length.Int() + 1
|
||||
str = data[:data_len]
|
||||
remainder = data[data_len:]
|
||||
l, err := str.Length()
|
||||
if l != data_len-1 {
|
||||
err = fmt.Errorf("error reading I2P string, length does not match data")
|
||||
log.WithFields(logrus.Fields{
|
||||
"expected_length": data_len - 1,
|
||||
"actual_length": l,
|
||||
}).Error("I2PString length mismatch")
|
||||
return
|
||||
}
|
||||
log.WithFields(logrus.Fields{
|
||||
"string_length": l,
|
||||
"remainder_length": len(remainder),
|
||||
}).Debug("Successfully read I2PString from bytes")
|
||||
return
|
||||
}
|
||||
|
||||
// NewI2PString creates a new *I2PString from []byte using ReadI2PString.
|
||||
// Returns a pointer to I2PString unlike ReadI2PString.
|
||||
/*func NewI2PString(data []byte) (str *I2PString, remainder []byte, err error) {
|
||||
objstr, remainder, err := ReadI2PString(data)
|
||||
str = &objstr
|
||||
return
|
||||
}*/
|
@@ -1,149 +0,0 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestStringReportsCorrectLength(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
str_len, err := I2PString([]byte{0x02, 0x00, 0x00}).Length()
|
||||
|
||||
assert.Equal(str_len, 2, "Length() did not report correct length")
|
||||
assert.Nil(err, "Length() reported an error on valid string")
|
||||
}
|
||||
|
||||
func TestI2PStringReportsLengthZeroError(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
str_len, err := I2PString(make([]byte, 0)).Length()
|
||||
|
||||
assert.Equal(str_len, 0, "Length() reported non-zero length on empty slice")
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal(err.Error(), "error parsing string: zero length", "correct error message should be returned")
|
||||
}
|
||||
}
|
||||
|
||||
func TestI2PStringReportsExtraDataError(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
str_len, err := I2PString([]byte{0x01, 0x00, 0x00}).Length()
|
||||
|
||||
assert.Equal(str_len, 1, "Length() reported wrong size when extra data present")
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal(err.Error(), "string parsing warning: string contains data beyond length", "correct error message should be returned")
|
||||
}
|
||||
}
|
||||
|
||||
func TestI2PStringDataReportsLengthZeroError(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
str_len, err := I2PString([]byte{0x01}).Length()
|
||||
|
||||
assert.Equal(str_len, 1, "Length() reported wrong size with missing data")
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal(err.Error(), "string parsing warning: string data is shorter than specified by length", "correct error message should be returned")
|
||||
}
|
||||
}
|
||||
|
||||
func TestI2PStringDataReportsExtraDataError(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
data, err := I2PString([]byte{0x01, 0x00, 0x01}).Data()
|
||||
data_len := len(data)
|
||||
|
||||
assert.Equal(data_len, 1, "Data() reported wrong size on string with extra data")
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal(err.Error(), "string parsing warning: string contains data beyond length", "correct error message should be returned")
|
||||
}
|
||||
}
|
||||
|
||||
func TestI2PStringDataEmptyWhenZeroLength(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
data, err := I2PString(make([]byte, 0)).Data()
|
||||
|
||||
assert.Equal(len(data), 0, "Data() returned data when none was present:")
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal(err.Error(), "error parsing string: zero length", "correct error message should be returned")
|
||||
}
|
||||
}
|
||||
|
||||
func TestI2PStringDataErrorWhenNonZeroLengthOnly(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
data, err := I2PString([]byte{0x01}).Data()
|
||||
|
||||
assert.Equal(len(data), 0, "Data() returned data when only length was present")
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal(err.Error(), "string parsing warning: string data is shorter than specified by length", "correct error message should be returned")
|
||||
}
|
||||
}
|
||||
|
||||
func TestToI2PI2PStringFormatsCorrectly(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
i2p_string, err := ToI2PString(string([]byte{0x08, 0x09}))
|
||||
|
||||
assert.Nil(err, "ToI2PString() returned error on valid data")
|
||||
assert.Equal(2, int(i2p_string[0]), "ToI2PString() did not prepend the correct length")
|
||||
assert.Equal(8, int(i2p_string[1]), "ToI2PString() did not include string")
|
||||
assert.Equal(9, int(i2p_string[2]), "ToI2PString() did not include string")
|
||||
}
|
||||
|
||||
func TestToI2PStringReportsOverflows(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
i2p_string, err := ToI2PString(string(make([]byte, 256)))
|
||||
|
||||
assert.Equal(len(i2p_string), 0, "ToI2PString() returned data when overflowed")
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal(err.Error(), "cannot store that much data in I2P string", "correct error message should be returned")
|
||||
}
|
||||
|
||||
_, err = ToI2PString(string(make([]byte, 255)))
|
||||
|
||||
assert.Nil(err, "ToI2PString() reported error with acceptable size")
|
||||
}
|
||||
|
||||
func TestReadStringReadsLength(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
bytes := []byte{0x01, 0x04, 0x06}
|
||||
str, remainder, err := ReadI2PString(bytes)
|
||||
|
||||
assert.Nil(err, "ReadI2PString() returned error reading string with extra data")
|
||||
assert.Equal(len(str), 2, "ReadI2PString() did not return correct string length")
|
||||
assert.Equal(1, int(str[0]), "ReadI2PString() did not return correct string")
|
||||
assert.Equal(4, int(str[1]), "ReadI2PString() did not return correct string")
|
||||
assert.Equal(len(remainder), 1, "ReadI2PString() did not return correct remainder length")
|
||||
assert.Equal(6, int(remainder[0]), "ReadI2PString() did not return correct remainder")
|
||||
}
|
||||
|
||||
func TestReadI2PStringErrWhenEmptySlice(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
bytes := make([]byte, 0)
|
||||
_, _, err := ReadI2PString(bytes)
|
||||
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal(err.Error(), "error parsing string: zero length", "correct error message should be returned")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadI2PStringErrWhenDataTooShort(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
short_str := []byte{0x03, 0x01}
|
||||
str, remainder, err := ReadI2PString(short_str)
|
||||
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal(err.Error(), "string parsing warning: string data is shorter than specified by length", "correct error message should be returned")
|
||||
}
|
||||
assert.Equal(len(str), 2, "ReadI2PString() did not return the slice as string when too long")
|
||||
assert.Equal(3, int(str[0]), "ReadI2PString() did not return the correct partial string")
|
||||
assert.Equal(1, int(str[1]), "ReadI2PString() did not return the correct partial string")
|
||||
assert.Equal(len(remainder), 0, "ReadI2PString() returned a remainder when the string data was too short")
|
||||
}
|
@@ -1,85 +0,0 @@
|
||||
// Package destination implements the I2P Destination common data structure
|
||||
package destination
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/go-i2p/go-i2p/lib/util/logger"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
. "github.com/go-i2p/go-i2p/lib/common/keys_and_cert"
|
||||
|
||||
"github.com/go-i2p/go-i2p/lib/common/base32"
|
||||
"github.com/go-i2p/go-i2p/lib/common/base64"
|
||||
"github.com/go-i2p/go-i2p/lib/crypto"
|
||||
)
|
||||
|
||||
var log = logger.GetGoI2PLogger()
|
||||
|
||||
/*
|
||||
[Destination]
|
||||
Accurate for version 0.9.49
|
||||
|
||||
Description
|
||||
A Destination defines a particular endpoint to which messages can be directed for secure delivery.
|
||||
|
||||
Contents
|
||||
Identical to KeysAndCert.
|
||||
*/
|
||||
|
||||
// Destination is the represenation of an I2P Destination.
|
||||
//
|
||||
// https://geti2p.net/spec/common-structures#destination
|
||||
type Destination struct {
|
||||
KeysAndCert
|
||||
}
|
||||
|
||||
// Base32Address returns the I2P base32 address for this Destination.
|
||||
func (destination Destination) Base32Address() (str string) {
|
||||
log.Debug("Generating Base32 address for Destination")
|
||||
|
||||
dest := destination.KeysAndCert.KeyCertificate.Bytes()
|
||||
hash := crypto.SHA256(dest)
|
||||
str = strings.Trim(base32.EncodeToString(hash[:]), "=")
|
||||
str = str + ".b32.i2p"
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"base32_address": str,
|
||||
}).Debug("Generated Base32 address for Destination")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Base64 returns the I2P base64 address for this Destination.
|
||||
func (destination Destination) Base64() string {
|
||||
log.Debug("Generating Base64 address for Destination")
|
||||
|
||||
dest := destination.KeysAndCert.KeyCertificate.Bytes()
|
||||
base64Address := base64.EncodeToString(dest)
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"base64_address_length": len(base64Address),
|
||||
}).Debug("Generated Base64 address for Destination")
|
||||
|
||||
return base64Address
|
||||
}
|
||||
|
||||
// ReadDestination returns Destination from a []byte.
|
||||
// The remaining bytes after the specified length are also returned.
|
||||
// Returns a list of errors that occurred during parsing.
|
||||
func ReadDestination(data []byte) (destination Destination, remainder []byte, err error) {
|
||||
log.WithFields(logrus.Fields{
|
||||
"input_length": len(data),
|
||||
}).Debug("Reading Destination from bytes")
|
||||
|
||||
keys_and_cert, remainder, err := ReadKeysAndCert(data)
|
||||
destination = Destination{
|
||||
keys_and_cert,
|
||||
}
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"remainder_length": len(remainder),
|
||||
}).Debug("Successfully read Destination from bytes")
|
||||
|
||||
return
|
||||
}
|
@@ -1,42 +0,0 @@
|
||||
# destination
|
||||
--
|
||||
import "github.com/go-i2p/go-i2p/lib/common/destination"
|
||||
|
||||
Package destination implements the I2P Destination common data structure
|
||||
|
||||
## Usage
|
||||
|
||||
#### type Destination
|
||||
|
||||
```go
|
||||
type Destination struct {
|
||||
KeysAndCert
|
||||
}
|
||||
```
|
||||
|
||||
Destination is the represenation of an I2P Destination.
|
||||
|
||||
https://geti2p.net/spec/common-structures#destination
|
||||
|
||||
#### func ReadDestination
|
||||
|
||||
```go
|
||||
func ReadDestination(data []byte) (destination Destination, remainder []byte, err error)
|
||||
```
|
||||
ReadDestination returns Destination from a []byte. The remaining bytes after the
|
||||
specified length are also returned. Returns a list of errors that occurred
|
||||
during parsing.
|
||||
|
||||
#### func (Destination) Base32Address
|
||||
|
||||
```go
|
||||
func (destination Destination) Base32Address() (str string)
|
||||
```
|
||||
Base32Address returns the I2P base32 address for this Destination.
|
||||
|
||||
#### func (Destination) Base64
|
||||
|
||||
```go
|
||||
func (destination Destination) Base64() string
|
||||
```
|
||||
Base64 returns the I2P base64 address for this Destination.
|
@@ -1,13 +0,0 @@
|
||||
FROM golang
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get upgrade -y
|
||||
|
||||
RUN go get github.com/dvyukov/go-fuzz/go-fuzz
|
||||
RUN go get github.com/dvyukov/go-fuzz/go-fuzz-build
|
||||
RUN go get github.com/hkparker/go-i2p
|
||||
RUN go get github.com/ddollar/forego
|
||||
|
||||
WORKDIR /go/src/github.com/hkparker/go-i2p
|
||||
|
||||
ENTRYPOINT ["make", "fuzz"]
|
@@ -1,8 +0,0 @@
|
||||
fuzz:
|
||||
go-fuzz-build -o keys_and_cert/exportable-fuzz.zip github.com/hkparker/go-i2p/lib/common/fuzz/keys_and_cert
|
||||
go-fuzz-build -o certificate/exportable-fuzz.zip github.com/hkparker/go-i2p/lib/common/fuzz/certificate
|
||||
go-fuzz-build -o destination/exportable-fuzz.zip github.com/hkparker/go-i2p/lib/common/fuzz/destination
|
||||
go-fuzz-build -o router_address/exportable-fuzz.zip github.com/hkparker/go-i2p/lib/common/fuzz/router_address
|
||||
go-fuzz-build -o router_identity/exportable-fuzz.zip github.com/hkparker/go-i2p/lib/common/fuzz/router_identity
|
||||
go-fuzz-build -o string/exportable-fuzz.zip github.com/hkparker/go-i2p/lib/common/fuzz/string
|
||||
forego start
|
@@ -1,6 +0,0 @@
|
||||
keys_and_cert: go-fuzz -bin=keys_and_cert/exportable-fuzz.zip -workdir=lib/common/fuzz/keys_and_cert -procs=2
|
||||
certificate: go-fuzz -bin=certificate/exportable-fuzz.zip -workdir=lib/common/fuzz/certificate -procs=2
|
||||
destination: go-fuzz -bin=destination/exportable-fuzz.zip -workdir=lib/common/fuzz/destination -procs=2
|
||||
router_address: go-fuzz -bin=router_address/exportable-fuzz.zip -workdir=lib/common/fuzz/router_address -procs=2
|
||||
router_identity: go-fuzz -bin=router_identity/exportable-fuzz.zip -workdir=lib/common/fuzz/router_identity -procs=2
|
||||
string: go-fuzz -bin=string/exportable-fuzz.zip -workdir=lib/common/fuzz/string -procs=2
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +0,0 @@
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +0,0 @@
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,12 +0,0 @@
|
||||
# exportable
|
||||
--
|
||||
import "github.com/go-i2p/go-i2p/lib/common/fuzz/certificate"
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
#### func Fuzz
|
||||
|
||||
```go
|
||||
func Fuzz(data []byte) int
|
||||
```
|
@@ -1,11 +0,0 @@
|
||||
package exportable
|
||||
|
||||
import common "github.com/go-i2p/go-i2p/lib/common/certificate"
|
||||
|
||||
func Fuzz(data []byte) int {
|
||||
cert, _, _ := common.ReadCertificate(data)
|
||||
cert.Data()
|
||||
cert.Length()
|
||||
cert.Type()
|
||||
return 0
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +0,0 @@
|
||||
|
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user