99 Commits
ntcp ... master

Author SHA1 Message Date
eyedeekay
f9127c0998 Update various things to post-refactor API interfaces 2025-07-15 18:28:02 -04:00
eyedeekay
b9e73d816d update modules 2025-07-08 21:55:30 -04:00
eyedeekay
4edc7b392d move common into it's own package, because it's getting hard to keep track of everything in here. Also going to move crypto into it's own package soon. This way common and crypto will have their own CI and will be able to present stable interfaces before the rest of go-i2p is ready. 2025-07-07 15:15:27 -04:00
eyedeekay
d7888ac9be return corrected size 2025-06-28 13:53:13 -04:00
eyedeekay
68408bb48e Expose WriteMessageToConn and start work on sessions 2025-05-31 13:40:33 -04:00
eyedeekay
4715b76ade IGNORE THIS CHECKIN: regenerate call graphs, regenerate godoc 2025-05-15 20:30:26 -04:00
eyedeekay
ac7e369b6a work on reseeding 2025-05-15 20:20:46 -04:00
eyedeekay
7d51d83b40 Fix nil return in when performing noise handshake to return a session 2025-05-15 19:20:37 -04:00
eyedeekay
89c82cb2fe Remove unused function, fix spelling, update godoc 2025-05-15 19:17:42 -04:00
eyedeekay
808f7d6fdf move processors back due to import cycle 2025-05-15 19:03:41 -04:00
eyedeekay
537ab808f8 fix issues with transports 2025-05-15 18:56:10 -04:00
eyedeekay
b41bb0eef8 move sessionmessageprocessors to own directory 2025-05-15 18:42:39 -04:00
eyedeekay
8787fea069 Put an X over handshake. It's broken, but it's there! 2025-05-10 23:22:43 -04:00
eyedeekay
fc9734d43d fix page workflow 2025-05-10 23:19:50 -04:00
eyedeekay
0a262d5780 Add GitHub Actions workflow for page generation 2025-05-10 23:15:45 -04:00
eyedeekay
2f233e931d delete more now-unused functions 2025-05-10 23:13:47 -04:00
eyedeekay
e9991099b7 update godoc again, delete more now-unused functions 2025-05-10 23:13:11 -04:00
eyedeekay
761dcb5f98 get rid of math/rand usages 2025-05-10 23:09:22 -04:00
eyedeekay
f68d9b5606 check in utility functions 2025-05-10 23:03:53 -04:00
eyedeekay
9fd3400585 More function deletions 2025-05-10 22:55:39 -04:00
eyedeekay
c85822163b Regenerate godoc 2025-05-10 22:36:36 -04:00
eyedeekay
e2fdb7c4e0 Move to SessionProcessors 2025-05-10 22:33:43 -04:00
eyedeekay
1babf06091 More code deduplication 2025-05-10 22:18:50 -04:00
eyedeekay
62e565b36c More code deduplication 2025-05-10 22:16:25 -04:00
eyedeekay
c7a17eac86 fmt 2025-05-10 21:55:30 -04:00
eyedeekay
89e53fdb9f More migration to processors 2025-05-10 21:55:06 -04:00
eyedeekay
ebdd1ae0aa Work on implementing and migrating to message processors 2025-05-10 21:46:07 -04:00
eyedeekay
b65f6c2682 Work on implementing and migrating to message processors 2025-05-10 21:43:30 -04:00
eyedeekay
14a0e56f6a Work on implementing and migrating to message processors 2025-05-10 21:37:47 -04:00
eyedeekay
4a89c14734 Work on implementing and migrating to message processors 2025-05-10 21:23:05 -04:00
eyedeekay
09fe22178d more method consolidation 2025-05-10 21:12:49 -04:00
eyedeekay
ef156f6944 more method consolidation 2025-05-10 21:11:46 -04:00
eyedeekay
a4acb01be9 handshake interface implementation stuff 2025-05-10 20:25:02 -04:00
eyedeekay
dd116095aa More duplicated code reduction, interface improvement 2025-05-10 20:09:42 -04:00
eyedeekay
1922f3a0ab Start implementing messages as message processors 2025-05-08 23:22:42 -04:00
eyedeekay
2a28c8ee01 Start implementing the message handlers 2025-05-08 22:59:36 -04:00
eyedeekay
9cb4af8f06 plan new handshake interfaces 2025-05-08 21:41:09 -04:00
eyedeekay
56faebd746 Plan re-org of handshake functions 2025-05-08 20:29:46 -04:00
eyedeekay
8b035711b6 Move sessionRequest methods to own file, organization changes 2025-05-08 18:01:58 -04:00
eyedeekay
c93b258844 Move ntcp2 messages into ntcp2 directory 2025-05-08 16:22:22 -04:00
eyedeekay
2df5d23528 Implement findClosestPeers 2025-05-08 14:24:08 -04:00
eyedeekay
98ea3d55c4 Implement lookup for kadResolver, change kadresolver to KademliaResolver 2025-05-07 21:19:46 -04:00
eyedeekay
b5454a4317 Implement lookup for kadResolver, change kadresolver to KademliaResolver 2025-05-07 21:17:38 -04:00
eyedeekay
83502face7 change lookup interface, needs to be more intuitive to use, we can thread elsewhere 2025-05-07 20:51:30 -04:00
eyedeekay
c99b15ba7f NetDB entry serialization and deserialization, TODO: leaseset struct port 2025-05-07 20:14:18 -04:00
eyedeekay
8e73c36922 check in the stuff I have locally that I haven't yet, mostly ECDSA stuff which is not very useful 2025-05-05 22:37:46 -04:00
eyedeekay
89b1995593 ecdsa_p256_private impl, rest of ecdsa to follow 2025-04-04 11:00:59 -04:00
eyedeekay
4577408d6d return a descriptive error upon a hash size mismatch 2025-04-03 17:00:10 -04:00
eyedeekay
e7e26ae021 Fix unimplemented funcs in rsa3072 2025-04-03 15:53:17 -04:00
eyedeekay
1d1568de71 Add rsa4096 implementation and use the same functin for all key reads 2025-04-03 15:30:06 -04:00
eyedeekay
b21a6cee9e Add rsa2048 implementation 2025-04-03 15:04:39 -04:00
eyedeekay
35b47969b0 Add rsa3072 implementation 2025-04-03 14:57:08 -04:00
eyedeekay
816df5642c implement first handshake message sender and reciever, create a test file 2025-03-31 21:49:31 -04:00
eyedeekay
1bd439f989 Implement Sender for Handshake Message 1 2025-03-31 17:33:01 -04:00
eyedeekay
6158eb68f3 fix some interfaces 2025-03-31 14:56:04 -04:00
eyedeekay
03eeeab781 reorganized old hansdhake stuff 2025-03-31 14:55:05 -04:00
eyedeekay
0099392f6d fix some interfaces 2025-03-31 14:51:53 -04:00
eyedeekay
a09f155835 Add quantized padding file and my notes on quantized padding 2025-03-31 13:46:45 -04:00
eyedeekay
fa561fc431 Merge branch 'master' of github.com:go-i2p/go-i2p 2025-03-29 17:54:58 -04:00
eyedeekay
c5125c1bfd more ntcp2 progress, figure out what the rules of the crypto library interfaces need to be, etc 2025-03-29 17:54:23 -04:00
idk
9e1bac3ff1 Merge pull request #37 from satk0/add-database-lookup
Add DatabaseLookup
2025-03-29 14:41:44 -04:00
eyedeekay
b4e1f3cfdf THIS LARGE CHECKIN CONTAINS REGENERATED DOCS ONLY. update/regenerate docs. 2025-03-27 22:18:24 -04:00
eyedeekay
d4ff0e373c stub out more methods 2025-03-27 22:01:34 -04:00
eyedeekay
0c9c8270a5 migrate hmac to crypto/hmac, I swear we do everything the hard way... 2025-03-27 21:56:23 -04:00
eyedeekay
f2bacc5018 Add basic chacha20-poly1305 implementation 2025-03-27 21:45:23 -04:00
eyedeekay
94691f1e75 Stub out ECDSA requirements 2025-03-27 20:30:31 -04:00
eyedeekay
8c4f718601 Make all the tests compile again, some of the elgamal ones might fail but mixing up our packages with third-party elgamal packages was causing problems. We should bring crypto in-house as dependencies, wrap our interfaces around it per our requirements, and not touch the upstream library if we can help it. That means wrap private keys, public keys, signing and encryption operations with our own code reporting our own errors. 2025-03-27 20:13:17 -04:00
eyedeekay
9a0d164276 Use curve25519+ChaCha20-Poly1305 instead of AES-GCM in curve25519, I think we might need to override it sometimes but it's the thing that makes sense right now 2025-03-27 19:50:55 -04:00
eyedeekay
f3f5d744ed Fix curve25519 decrypter 2025-03-27 19:24:23 -04:00
eyedeekay
3b9fb603f4 fix a few more compile errors and sync 2025-03-26 21:10:16 -04:00
eyedeekay
29d5a20216 Fix compile errors in NTCP handshake 2025-03-26 19:38:01 -04:00
eyedeekay
3c252e22cd split the rsa stub package into one file per component 2025-03-26 19:32:54 -04:00
eyedeekay
dcb11d1fda split the rsa stub package into one file per component 2025-03-26 19:31:32 -04:00
eyedeekay
a721856688 split the elgamal package into one file per component 2025-03-26 19:26:03 -04:00
eyedeekay
b66c5813cb split the ed25519 package into one file per component 2025-03-26 19:19:24 -04:00
eyedeekay
441549743d Fix some of the compile errors in routerinfo_keystore.go 2025-03-26 18:57:27 -04:00
eyedeekay
30f84713ea split the ecdsa package into one file per component 2025-03-26 18:52:51 -04:00
eyedeekay
6057677956 split the dsa package into one file per component 2025-03-26 18:48:12 -04:00
eyedeekay
c026b9a4a5 split the curve25519 package into one file per component 2025-03-26 18:40:38 -04:00
eyedeekay
9c6cfc14e5 split the curve25519 package into one file per component 2025-03-26 18:40:31 -04:00
eyedeekay
4533c2fd92 split the aes package into one file per component 2025-03-26 18:24:31 -04:00
satk0
89e51820f1 Add DatabaseLookup and test it 2025-03-26 20:32:44 +01:00
eyedeekay
17a789bed7 refactor crypto library into smaller components 2025-03-25 19:08:47 -04:00
eyedeekay
d236f19f81 add custom handshake manager 2025-03-25 18:37:14 -04:00
eyedeekay
d0b81d9ce9 add remaining session messages 2025-03-25 18:17:34 -04:00
eyedeekay
06cf6b41b4 add remaining session messages 2025-03-25 18:15:44 -04:00
eyedeekay
ac8349d083 Add SessionCreated implementation 2025-03-25 17:02:25 -04:00
eyedeekay
45296be6d3 let the machine find simple errors in the common library and call it a night 2025-03-24 23:55:04 -04:00
eyedeekay
1f25f0c9b3 Finish initialization of NTCP2Sessions 2025-03-24 23:22:23 -04:00
eyedeekay
d1a708a594 Actually use the message objects, duh 2025-03-24 23:16:12 -04:00
eyedeekay
b153bfc050 Refactor and comment ComposeInitiatorHandshakeMessage 2025-03-24 19:36:14 -04:00
eyedeekay
d401b06c0f Remove dot-imports from LeaseSets 2025-03-22 18:49:26 -04:00
eyedeekay
9091834074 fix more tests 2025-03-22 18:12:13 -04:00
eyedeekay
8561b3ec69 fmt 2025-03-22 18:03:24 -04:00
eyedeekay
8aac97351d fix some tests 2025-03-22 18:03:06 -04:00
idk
3142a394aa Merge pull request #31 from go-i2p/ntcp
NTCP2 Handshake Development
2025-03-21 15:48:13 -04:00
idk
d97624282e Merge pull request #35 from satk0/i2np-build-res
Add i2np Build Response Record
2025-02-11 14:12:08 -05:00
satk0
46af6d55ef Update upload-artifact in workflow 2025-02-11 13:19:39 +01:00
satk0
9591f496eb Add BuildResponseRecord 2025-02-11 13:15:47 +01:00
372 changed files with 15264 additions and 28484 deletions

60
.github/workflows/page.yml vendored Normal file
View 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 }}"

View File

@@ -83,7 +83,7 @@ jobs:
- name: Upload Test Logs
if: always()
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.test_target }}-logs
path: ./test-logs/${{ matrix.test_target }}.log # Adjust this path as needed

View File

@@ -21,24 +21,24 @@ please keep up with these changes, as they will not be backward compatible and r
- [ ] 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
- [X] HMAC
- [X] Noise subsystem
- End-to-End Crypto
- [ ] Garlic messages
@@ -48,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
@@ -60,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

View File

@@ -2,7 +2,7 @@
dirs=$(find lib/ -type d)
for dir in $dirs; do
files=$(find "$dir" -maxdepth 1 -type f -name "*.go")
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
@@ -13,7 +13,7 @@ for dir in $dirs; do
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"
git mv -v "$dir/doc.md" "$dir/README.md"
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

View File

@@ -1,5 +1,5 @@
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
@@ -21,10 +21,54 @@ test-i2np-data:
test-i2np-regression:
$(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 \
test-i2np-message \
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

28
go.mod
View File

@@ -1,22 +1,21 @@
module github.com/go-i2p/go-i2p
go 1.23.3
toolchain go1.23.5
go 1.24.2
require (
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.16.1
github.com/samber/oops v1.19.0
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.9.1
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.10.0
go.step.sm/crypto v0.58.1
golang.org/x/crypto v0.35.0
golang.org/x/crypto v0.39.0
gopkg.in/yaml.v3 v3.0.1
)
@@ -28,23 +27,24 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/magiconair/properties v1.8.9 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/oklog/ulid/v2 v2.1.0 // 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.7.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/samber/lo v1.49.1 // indirect
github.com/samber/lo v1.51.0 // indirect
github.com/sourcegraph/conc v0.3.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.opentelemetry.io/otel v1.34.0 // indirect
go.opentelemetry.io/otel/trace v1.34.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-20250218142911-aa4b98e5adaa // indirect
golang.org/x/net v0.35.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/text v0.22.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
)

54
go.sum
View File

@@ -17,10 +17,16 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk
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.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
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=
@@ -36,8 +42,8 @@ github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a
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/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU=
github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
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=
@@ -51,10 +57,10 @@ github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsF
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.49.1 h1:4BIFyVfuQSEpluc7Fua+j1NolZHiEHEpaSEKdsH0tew=
github.com/samber/lo v1.49.1/go.mod h1:dO6KHFzUKXgP8LDhU0oI8d2hekjXnGOu0DB8Jecxd6o=
github.com/samber/oops v1.16.1 h1:XlKkXsWM5g8hE4C+sEV9n0X282fZn3XabVmAKU2RiHI=
github.com/samber/oops v1.16.1/go.mod h1:8eXgMAJcDXRAijQsFRhfy/EHDOTiSvwkg6khFqFK078=
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=
@@ -75,30 +81,30 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
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.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
go.step.sm/crypto v0.58.1 h1:2PpEYTbytA3el9dW0gh9uJEe/CR/J6wS+x2vWYLG83M=
go.step.sm/crypto v0.58.1/go.mod h1:yluOL5OqY7mXGGQ7JUmAv/6h8T8Ge3yXdlEESWHOqDQ=
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.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4=
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk=
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.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
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.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.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.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
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=

View File

@@ -18,14 +18,40 @@ 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)
}
```
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
bootstrap
github.com/go-i2p/go-i2p/lib/bootstrap
[go-i2p template file](/template.md)

View File

@@ -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)
}

View File

@@ -4,10 +4,255 @@
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
-->
<!-- Title: gocallvis Pages: 1 -->
<svg width="0pt" height="0pt"
viewBox="0.00 0.00 0.00 0.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 0)">
<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,0 0,0 0,0 0,0"/>
<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&#45;i2p/go&#45;i2p/lib/netdb/reseed.Reseed</title>
<g id="a_clust5"><a xlink:title="type: github.com/go&#45;i2p/go&#45;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&#45;i2p/logger.Logger</title>
<g id="a_clust3"><a xlink:title="type: *github.com/go&#45;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&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap</title>
<g id="a_clust2"><a xlink:title="type: *github.com/go&#45;i2p/go&#45;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&#45;i2p/go&#45;i2p/lib/netdb/reseed.NewReseed -->
<g id="node2" class="node">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/netdb/reseed.NewReseed</title>
<g id="a_node2"><a xlink:title="github.com/go&#45;i2p/go&#45;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&#45;i2p/go&#45;i2p/lib/bootstrap.init -->
<g id="node3" class="node">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/bootstrap.init</title>
<g id="a_node3"><a xlink:title="github.com/go&#45;i2p/go&#45;i2p/lib/bootstrap.init | defined in .:0&#10;at reseed_bootstrap.go:15: calling [github.com/go&#45;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&#45;i2p/logger.GetGoI2PLogger -->
<g id="node4" class="node">
<title>github.com/go&#45;i2p/logger.GetGoI2PLogger</title>
<g id="a_node4"><a xlink:title="github.com/go&#45;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&#45;i2p/go&#45;i2p/lib/bootstrap.init&#45;&gt;github.com/go&#45;i2p/logger.GetGoI2PLogger -->
<g id="edge10" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/bootstrap.init&#45;&gt;github.com/go&#45;i2p/logger.GetGoI2PLogger</title>
<g id="a_edge10"><a xlink:title="at reseed_bootstrap.go:15: calling [github.com/go&#45;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&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers -->
<g id="node5" class="node">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers</title>
<g id="a_node5"><a xlink:title="(*github.com/go&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers | defined in reseed_bootstrap.go:32&#10;at reseed_bootstrap.go:40: calling [github.com/samber/oops.Errorf]&#10;at reseed_bootstrap.go:53: calling [github.com/samber/oops.Errorf]&#10;at reseed_bootstrap.go:73: calling [github.com/samber/oops.Errorf]&#10;at reseed_bootstrap.go:43: calling [(*github.com/go&#45;i2p/logger.Logger).WithField]&#10;at reseed_bootstrap.go:52: calling [(*github.com/go&#45;i2p/logger.Logger).WithField]&#10;at reseed_bootstrap.go:43: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at reseed_bootstrap.go:52: calling [(*github.com/go&#45;i2p/logger.Logger).WithError]&#10;at reseed_bootstrap.go:52: calling [(*github.com/go&#45;i2p/logger.Logger).Warn]&#10;at reseed_bootstrap.go:63: calling [(*github.com/sirupsen/logrus.Logger).Info]&#10;at reseed_bootstrap.go:46: calling [github.com/go&#45;i2p/go&#45;i2p/lib/netdb/reseed.NewReseed]&#10;at reseed_bootstrap.go:49: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/netdb/reseed.Reseed).SingleReseed]&#10;at reseed_bootstrap.go:59: calling [(*github.com/go&#45;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&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers&#45;&gt;github.com/samber/oops.Errorf -->
<g id="edge1" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers&#45;&gt;github.com/samber/oops.Errorf</title>
<g id="a_edge1"><a xlink:title="at reseed_bootstrap.go:40: calling [github.com/samber/oops.Errorf]&#10;at reseed_bootstrap.go:53: calling [github.com/samber/oops.Errorf]&#10;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&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers&#45;&gt;github.com/go&#45;i2p/go&#45;i2p/lib/netdb/reseed.NewReseed -->
<g id="edge7" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers&#45;&gt;github.com/go&#45;i2p/go&#45;i2p/lib/netdb/reseed.NewReseed</title>
<g id="a_edge7"><a xlink:title="at reseed_bootstrap.go:46: calling [github.com/go&#45;i2p/go&#45;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&#45;i2p/logger.Logger).WithField -->
<g id="node6" class="node">
<title>(*github.com/go&#45;i2p/logger.Logger).WithField</title>
<g id="a_node6"><a xlink:title="(*github.com/go&#45;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&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithField -->
<g id="edge2" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithField</title>
<g id="a_edge2"><a xlink:title="at reseed_bootstrap.go:43: calling [(*github.com/go&#45;i2p/logger.Logger).WithField]&#10;at reseed_bootstrap.go:52: calling [(*github.com/go&#45;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&#45;i2p/logger.Logger).WithError -->
<g id="node7" class="node">
<title>(*github.com/go&#45;i2p/logger.Logger).WithError</title>
<g id="a_node7"><a xlink:title="(*github.com/go&#45;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&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithError -->
<g id="edge4" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithError</title>
<g id="a_edge4"><a xlink:title="at reseed_bootstrap.go:52: calling [(*github.com/go&#45;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&#45;i2p/logger.Logger).Warn -->
<g id="node8" class="node">
<title>(*github.com/go&#45;i2p/logger.Logger).Warn</title>
<g id="a_node8"><a xlink:title="(*github.com/go&#45;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&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).Warn -->
<g id="edge5" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).Warn</title>
<g id="a_edge5"><a xlink:title="at reseed_bootstrap.go:52: calling [(*github.com/go&#45;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&#45;i2p/logger.Logger).WithFields -->
<g id="node9" class="node">
<title>(*github.com/go&#45;i2p/logger.Logger).WithFields</title>
<g id="a_node9"><a xlink:title="(*github.com/go&#45;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&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields -->
<g id="edge9" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields</title>
<g id="a_edge9"><a xlink:title="at reseed_bootstrap.go:59: calling [(*github.com/go&#45;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&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug -->
<g id="edge3" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers&#45;&gt;(*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&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers&#45;&gt;(*github.com/sirupsen/logrus.Logger).Info -->
<g id="edge6" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers&#45;&gt;(*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&#45;i2p/go&#45;i2p/lib/netdb/reseed.Reseed).SingleReseed -->
<g id="node12" class="node">
<title>(github.com/go&#45;i2p/go&#45;i2p/lib/netdb/reseed.Reseed).SingleReseed</title>
<g id="a_node12"><a xlink:title="(github.com/go&#45;i2p/go&#45;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&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers&#45;&gt;(github.com/go&#45;i2p/go&#45;i2p/lib/netdb/reseed.Reseed).SingleReseed -->
<g id="edge8" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/bootstrap.ReseedBootstrap).GetPeers&#45;&gt;(github.com/go&#45;i2p/go&#45;i2p/lib/netdb/reseed.Reseed).SingleReseed</title>
<g id="a_edge8"><a xlink:title="at reseed_bootstrap.go:49: calling [(github.com/go&#45;i2p/go&#45;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>

Before

Width:  |  Height:  |  Size: 584 B

After

Width:  |  Height:  |  Size: 23 KiB

View 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
}

View File

@@ -1,41 +0,0 @@
# base32
--
import "github.com/go-i2p/go-i2p/lib/common/base32"
![base32.svg](base32.svg)
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
base32
github.com/go-i2p/go-i2p/lib/common/base32

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -1,41 +0,0 @@
# base64
--
import "github.com/go-i2p/go-i2p/lib/common/base64"
![base64.svg](base64.svg)
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.
base64
github.com/go-i2p/go-i2p/lib/common/base64

View File

@@ -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)
}

View File

@@ -1,13 +0,0 @@
<?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="0pt" height="0pt"
viewBox="0.00 0.00 0.00 0.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 0)">
<title>gocallvis</title>
<polygon fill="#d3d3d3" stroke="transparent" points="0,0 0,0 0,0 0,0 0,0"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 584 B

View File

@@ -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)
}

View File

@@ -1,125 +0,0 @@
# certificate
--
import "github.com/go-i2p/go-i2p/lib/common/certificate"
![certificate.svg](certificate.svg)
## 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
#### func GetSignatureTypeFromCertificate
```go
func GetSignatureTypeFromCertificate(cert Certificate) (int, error)
```
#### 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() *Certificate
```
NewCertificate creates a new Certificate with default NULL type
#### func NewCertificateDeux
```go
func NewCertificateDeux(certType int, payload []byte) (*Certificate, error)
```
#### func NewCertificateWithType
```go
func NewCertificateWithType(certType uint8, payload []byte) (*Certificate, error)
```
NewCertificateWithType creates a new Certificate with specified type and payload
#### 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,
certificate
github.com/go-i2p/go-i2p/lib/common/certificate

View File

@@ -1,290 +0,0 @@
// Package certificate implements the certificate common-structure of I2P.
package certificate
import (
"encoding/binary"
"fmt"
"github.com/samber/oops"
"github.com/sirupsen/logrus"
// log "github.com/sirupsen/logrus"
"github.com/go-i2p/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
}
// readCertificate 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(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 = oops.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 = oops.Errorf("error parsing certificate: certificate is too short")
return
default:
certificate.kind = Integer(data[0:1])
certificate.len = Integer(data[1:3])
payloadLength := len(data) - CERT_MIN_SIZE
certificate.payload = data[CERT_MIN_SIZE:]
if certificate.len.Int() > len(data)-CERT_MIN_SIZE {
err = oops.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": payloadLength,
"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 = readCertificate(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
}
// NewCertificate creates a new Certificate with default NULL type
func NewCertificate() *Certificate {
return &Certificate{
kind: Integer([]byte{CERT_NULL}),
len: Integer([]byte{0}),
payload: make([]byte, 0),
}
}
func NewCertificateDeux(certType int, payload []byte) (*Certificate, error) {
if certType < 0 || certType > 255 {
return nil, oops.Errorf("invalid certificate type: %d", certType)
}
certTypeByte := byte(certType)
if len(payload) > 65535 {
return nil, oops.Errorf("payload too long: %d bytes", len(payload))
}
_len, err := NewIntegerFromInt(len(payload), 2)
if err != nil {
panic(err)
}
cert := &Certificate{
kind: Integer([]byte{certTypeByte}),
len: *_len,
payload: payload,
}
log.WithFields(logrus.Fields{
"type": certType,
"length": len(payload),
}).Debug("Successfully created new certificate")
return cert, nil
}
// NewCertificateWithType creates a new Certificate with specified type and payload
func NewCertificateWithType(certType uint8, payload []byte) (*Certificate, error) {
// Validate certificate type
switch certType {
case CERT_NULL, CERT_HASHCASH, CERT_HIDDEN, CERT_SIGNED, CERT_MULTIPLE, CERT_KEY:
// Valid type
default:
return nil, oops.Errorf("invalid certificate type: %d", certType)
}
// For NULL certificates, payload should be empty
if certType == CERT_NULL && len(payload) > 0 {
return nil, oops.Errorf("NULL certificates must have empty payload")
}
length, _ := NewIntegerFromInt(len(payload), 2)
cert := &Certificate{
kind: Integer([]byte{certType}),
len: *length,
payload: make([]byte, len(payload)),
}
// Copy payload if present
if len(payload) > 0 {
copy(cert.payload, payload)
}
return cert, nil
}
func GetSignatureTypeFromCertificate(cert Certificate) (int, error) {
if cert.Type() != CERT_KEY {
return 0, oops.Errorf("unexpected certificate type: %d", cert.Type())
}
if len(cert.payload) < 4 {
return 0, oops.Errorf("certificate payload too short to contain signature type")
}
sigType := int(binary.BigEndian.Uint16(cert.payload[2:4])) // Changed offset to read signing key type
return sigType, nil
}

View File

@@ -1,617 +0,0 @@
<?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="1146pt" height="928pt"
viewBox="0.00 0.00 1146.34 928.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 928)">
<title>gocallvis</title>
<polygon fill="#d3d3d3" stroke="transparent" points="0,0 0,-928 1146.344,-928 1146.344,0 0,0"/>
<g id="clust1" class="cluster">
<title>cluster_focus</title>
<polygon fill="#e6ecfa" stroke="#000000" stroke-width=".5" points="8,-8 8,-920 1138.344,-920 1138.344,-8 8,-8"/>
<text text-anchor="middle" x="573.172" y="-899.8" font-family="Arial" font-size="18.00" fill="#000000">certificate</text>
</g>
<g id="clust5" class="cluster">
<title>cluster_github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer</title>
<g id="a_clust5"><a xlink:title="type: github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer">
<path fill="#eed8ae" stroke="#000000" stroke-width=".5" d="M1038.4239,-407C1038.4239,-407 1086.3103,-407 1086.3103,-407 1092.3103,-407 1098.3103,-413 1098.3103,-419 1098.3103,-419 1098.3103,-534 1098.3103,-534 1098.3103,-540 1092.3103,-546 1086.3103,-546 1086.3103,-546 1038.4239,-546 1038.4239,-546 1032.4239,-546 1026.4239,-540 1026.4239,-534 1026.4239,-534 1026.4239,-419 1026.4239,-419 1026.4239,-413 1032.4239,-407 1038.4239,-407"/>
<text text-anchor="middle" x="1062.3671" y="-415.5" font-family="Arial" font-size="15.00" fill="#222222">(Integer)</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="M1035.7065,-262C1035.7065,-262 1090.0277,-262 1090.0277,-262 1096.0277,-262 1102.0277,-268 1102.0277,-274 1102.0277,-274 1102.0277,-328 1102.0277,-328 1102.0277,-334 1096.0277,-340 1090.0277,-340 1090.0277,-340 1035.7065,-340 1035.7065,-340 1029.7065,-340 1023.7065,-334 1023.7065,-328 1023.7065,-328 1023.7065,-274 1023.7065,-274 1023.7065,-268 1029.7065,-262 1035.7065,-262"/>
<text text-anchor="middle" x="1062.8671" y="-270.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&#45;i2p/logger.Logger</title>
<g id="a_clust3"><a xlink:title="type: *github.com/go&#45;i2p/logger.Logger">
<path fill="#eed8ae" stroke="#000000" stroke-width=".5" d="M1023.2577,-619C1023.2577,-619 1101.4765,-619 1101.4765,-619 1107.4765,-619 1113.4765,-625 1113.4765,-631 1113.4765,-631 1113.4765,-807 1113.4765,-807 1113.4765,-813 1107.4765,-819 1101.4765,-819 1101.4765,-819 1023.2577,-819 1023.2577,-819 1017.2577,-819 1011.2577,-813 1011.2577,-807 1011.2577,-807 1011.2577,-631 1011.2577,-631 1011.2577,-625 1017.2577,-619 1023.2577,-619"/>
<text text-anchor="middle" x="1062.3671" y="-627.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&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate</title>
<g id="a_clust2"><a xlink:title="type: *github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate">
<path fill="#b0c4de" stroke="#000000" stroke-width=".5" d="M322.261,-285C322.261,-285 866.0844,-285 866.0844,-285 872.0844,-285 878.0844,-291 878.0844,-297 878.0844,-297 878.0844,-534 878.0844,-534 878.0844,-540 872.0844,-546 866.0844,-546 866.0844,-546 322.261,-546 322.261,-546 316.261,-546 310.261,-540 310.261,-534 310.261,-534 310.261,-297 310.261,-297 310.261,-291 316.261,-285 322.261,-285"/>
<text text-anchor="middle" x="594.1727" y="-293.5" font-family="Arial" font-size="15.00" fill="#222222">(*Certificate)</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.readCertificate -->
<g id="node1" class="node">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.readCertificate</title>
<g id="a_node1"><a xlink:title="github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.readCertificate | defined in certificate.go:150&#10;at certificate.go:194: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at certificate.go:160: calling [(*github.com/go&#45;i2p/logger.Logger).Error]&#10;at certificate.go:170: calling [(*github.com/go&#45;i2p/logger.Logger).Error]&#10;at certificate.go:188: calling [(*github.com/go&#45;i2p/logger.Logger).Error]&#10;at certificate.go:161: calling [github.com/samber/oops.Errorf]&#10;at certificate.go:171: calling [github.com/samber/oops.Errorf]&#10;at certificate.go:179: calling [github.com/samber/oops.Errorf]&#10;at certificate.go:159: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]&#10;at certificate.go:169: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]&#10;at certificate.go:178: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]&#10;at certificate.go:182: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]&#10;at certificate.go:192: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]&#10;at certificate.go:193: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]&#10;at certificate.go:156: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]&#10;at certificate.go:166: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]&#10;at certificate.go:180: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]&#10;at certificate.go:191: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="#add8e6" stroke="#000000" stroke-width=".5" d="M879.924,-615C879.924,-615 796.587,-615 796.587,-615 790.587,-615 784.587,-609 784.587,-603 784.587,-603 784.587,-591 784.587,-591 784.587,-585 790.587,-579 796.587,-579 796.587,-579 879.924,-579 879.924,-579 885.924,-579 891.924,-585 891.924,-591 891.924,-591 891.924,-603 891.924,-603 891.924,-609 885.924,-615 879.924,-615"/>
<text text-anchor="middle" x="838.2555" y="-592.8" font-family="Verdana" font-size="14.00" fill="#000000">readCertificate</text>
</a>
</g>
</g>
<!-- github.com/samber/oops.Errorf -->
<g id="node2" class="node">
<title>github.com/samber/oops.Errorf</title>
<g id="a_node2"><a xlink:title="github.com/samber/oops.Errorf | defined in oops.go:34">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M1079.5624,-129C1079.5624,-129 1045.1718,-129 1045.1718,-129 1039.1718,-129 1033.1718,-123 1033.1718,-117 1033.1718,-117 1033.1718,-105 1033.1718,-105 1033.1718,-99 1039.1718,-93 1045.1718,-93 1045.1718,-93 1079.5624,-93 1079.5624,-93 1085.5624,-93 1091.5624,-99 1091.5624,-105 1091.5624,-105 1091.5624,-117 1091.5624,-117 1091.5624,-123 1085.5624,-129 1079.5624,-129"/>
<text text-anchor="middle" x="1062.3671" y="-115.2" font-family="Verdana" font-size="14.00" fill="#000000">oops</text>
<text text-anchor="middle" x="1062.3671" y="-98.4" font-family="Verdana" font-size="14.00" fill="#000000">Errorf</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.readCertificate&#45;&gt;github.com/samber/oops.Errorf -->
<g id="edge17" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.readCertificate&#45;&gt;github.com/samber/oops.Errorf</title>
<g id="a_edge17"><a xlink:title="at certificate.go:161: calling [github.com/samber/oops.Errorf]&#10;at certificate.go:171: calling [github.com/samber/oops.Errorf]&#10;at certificate.go:179: calling [github.com/samber/oops.Errorf]">
<path fill="none" stroke="#8b4513" d="M887.6922,-578.8268C900.2566,-572.1105 912.6559,-563.2952 921.3902,-552 962.8333,-498.4057 971.7912,-319.8683 994.3902,-256 1009.3883,-213.6131 1032.5644,-166.915 1047.601,-138.2675"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1050.7756,-139.7516 1052.3648,-129.2766 1044.5902,-136.4742 1050.7756,-139.7516"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/logger.Logger).WithFields -->
<g id="node17" class="node">
<title>(*github.com/go&#45;i2p/logger.Logger).WithFields</title>
<g id="a_node17"><a xlink:title="(*github.com/go&#45;i2p/logger.Logger).WithFields | defined in log.go:60">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M1093.5862,-750C1093.5862,-750 1031.148,-750 1031.148,-750 1025.148,-750 1019.148,-744 1019.148,-738 1019.148,-738 1019.148,-726 1019.148,-726 1019.148,-720 1025.148,-714 1031.148,-714 1031.148,-714 1093.5862,-714 1093.5862,-714 1099.5862,-714 1105.5862,-720 1105.5862,-726 1105.5862,-726 1105.5862,-738 1105.5862,-738 1105.5862,-744 1099.5862,-750 1093.5862,-750"/>
<text text-anchor="middle" x="1062.3671" y="-736.2" font-family="Verdana" font-size="14.00" fill="#000000">logger</text>
<text text-anchor="middle" x="1062.3671" y="-719.4" font-family="Verdana" font-size="14.00" fill="#000000">WithFields</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.readCertificate&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields -->
<g id="edge39" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.readCertificate&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields</title>
<g id="a_edge39"><a xlink:title="at certificate.go:156: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]&#10;at certificate.go:166: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]&#10;at certificate.go:180: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]&#10;at certificate.go:191: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="none" stroke="#8b4513" d="M862.2851,-615.121C892.2409,-637.2428 945.472,-675.0325 994.3902,-702 999.262,-704.6857 1004.4214,-707.3179 1009.6333,-709.8383"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1008.4809,-713.1637 1019.0207,-714.242 1011.4538,-706.8263 1008.4809,-713.1637"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/logger.Logger).Error -->
<g id="node19" class="node">
<title>(*github.com/go&#45;i2p/logger.Logger).Error</title>
<g id="a_node19"><a xlink:title="(*github.com/go&#45;i2p/logger.Logger).Error | defined in log.go:42">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M1080.1334,-689C1080.1334,-689 1044.6008,-689 1044.6008,-689 1038.6008,-689 1032.6008,-683 1032.6008,-677 1032.6008,-677 1032.6008,-665 1032.6008,-665 1032.6008,-659 1038.6008,-653 1044.6008,-653 1044.6008,-653 1080.1334,-653 1080.1334,-653 1086.1334,-653 1092.1334,-659 1092.1334,-665 1092.1334,-665 1092.1334,-677 1092.1334,-677 1092.1334,-683 1086.1334,-689 1080.1334,-689"/>
<text text-anchor="middle" x="1062.3671" y="-675.2" font-family="Verdana" font-size="14.00" fill="#000000">logger</text>
<text text-anchor="middle" x="1062.3671" y="-658.4" font-family="Verdana" font-size="14.00" fill="#000000">Error</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.readCertificate&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).Error -->
<g id="edge16" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.readCertificate&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).Error</title>
<g id="a_edge16"><a xlink:title="at certificate.go:160: calling [(*github.com/go&#45;i2p/logger.Logger).Error]&#10;at certificate.go:170: calling [(*github.com/go&#45;i2p/logger.Logger).Error]&#10;at certificate.go:188: calling [(*github.com/go&#45;i2p/logger.Logger).Error]">
<path fill="none" stroke="#8b4513" d="M891.9358,-614.7248C932.1804,-628.0133 986.3626,-645.9039 1022.7345,-657.9136"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1021.9014,-661.3243 1032.4946,-661.1363 1024.0963,-654.6773 1021.9014,-661.3243"/>
</a>
</g>
</g>
<!-- (*github.com/sirupsen/logrus.Logger).Debug -->
<g id="node20" class="node">
<title>(*github.com/sirupsen/logrus.Logger).Debug</title>
<g id="a_node20"><a xlink:title="(*github.com/sirupsen/logrus.Logger).Debug | defined in logger.go:221">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M1081.1891,-332C1081.1891,-332 1043.5451,-332 1043.5451,-332 1037.5451,-332 1031.5451,-326 1031.5451,-320 1031.5451,-320 1031.5451,-308 1031.5451,-308 1031.5451,-302 1037.5451,-296 1043.5451,-296 1043.5451,-296 1081.1891,-296 1081.1891,-296 1087.1891,-296 1093.1891,-302 1093.1891,-308 1093.1891,-308 1093.1891,-320 1093.1891,-320 1093.1891,-326 1087.1891,-332 1081.1891,-332"/>
<text text-anchor="middle" x="1062.3671" y="-318.2" font-family="Verdana" font-size="14.00" fill="#000000">logrus</text>
<text text-anchor="middle" x="1062.3671" y="-301.4" font-family="Verdana" font-size="14.00" fill="#000000">Debug</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.readCertificate&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug -->
<g id="edge2" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.readCertificate&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug</title>
<g id="a_edge2"><a xlink:title="at certificate.go:194: calling [(*github.com/sirupsen/logrus.Logger).Debug]">
<path fill="none" stroke="#8b4513" d="M883.6249,-578.925C896.9934,-571.9937 910.8476,-563.037 921.3902,-552 972.8783,-498.0971 954.9975,-464.2831 994.3902,-401 1007.8831,-379.3241 1025.7385,-356.651 1039.7636,-339.887"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1042.5136,-342.0555 1046.305,-332.1623 1037.1716,-337.5318 1042.5136,-342.0555"/>
</a>
</g>
</g>
<!-- (github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int -->
<g id="node21" class="node">
<title>(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int</title>
<g id="a_node21"><a xlink:title="(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int | defined in integer.go:32">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M1077.3671,-538C1077.3671,-538 1047.3671,-538 1047.3671,-538 1041.3671,-538 1035.3671,-532 1035.3671,-526 1035.3671,-526 1035.3671,-514 1035.3671,-514 1035.3671,-508 1041.3671,-502 1047.3671,-502 1047.3671,-502 1077.3671,-502 1077.3671,-502 1083.3671,-502 1089.3671,-508 1089.3671,-514 1089.3671,-514 1089.3671,-526 1089.3671,-526 1089.3671,-532 1083.3671,-538 1077.3671,-538"/>
<text text-anchor="middle" x="1062.3671" y="-524.2" font-family="Verdana" font-size="14.00" fill="#000000">data</text>
<text text-anchor="middle" x="1062.3671" y="-507.4" font-family="Verdana" font-size="14.00" fill="#000000">Int</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.readCertificate&#45;&gt;(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int -->
<g id="edge20" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.readCertificate&#45;&gt;(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int</title>
<g id="a_edge20"><a xlink:title="at certificate.go:159: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]&#10;at certificate.go:169: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]&#10;at certificate.go:178: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]&#10;at certificate.go:182: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]&#10;at certificate.go:192: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]&#10;at certificate.go:193: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]">
<path fill="none" stroke="#8b4513" d="M890.7997,-578.9469C932.19,-564.7261 988.8409,-545.2621 1025.521,-532.6595"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1026.9878,-535.8565 1035.3079,-529.297 1024.7132,-529.2363 1026.9878,-535.8565"/>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate -->
<g id="node3" class="node">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate</title>
<g id="a_node3"><a xlink:title="github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate | defined in certificate.go:201&#10;at certificate.go:202: calling [github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.readCertificate]&#10;at certificate.go:210: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at certificate.go:207: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).ExcessBytes]&#10;at certificate.go:204: calling [(*github.com/go&#45;i2p/logger.Logger).Warn]&#10;at certificate.go:208: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="#add8e6" stroke="#000000" stroke-width="1.5" d="M167.867,-845C167.867,-845 80.178,-845 80.178,-845 74.178,-845 68.178,-839 68.178,-833 68.178,-833 68.178,-821 68.178,-821 68.178,-815 74.178,-809 80.178,-809 80.178,-809 167.867,-809 167.867,-809 173.867,-809 179.867,-815 179.867,-821 179.867,-821 179.867,-833 179.867,-833 179.867,-839 173.867,-845 167.867,-845"/>
<text text-anchor="middle" x="124.0225" y="-822.8" font-family="Verdana" font-size="14.00" fill="#000000">ReadCertificate</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate&#45;&gt;github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.readCertificate -->
<g id="edge8" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate&#45;&gt;github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.readCertificate</title>
<g id="a_edge8"><a xlink:title="at certificate.go:202: calling [github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.readCertificate]">
<path fill="none" stroke="#000000" d="M180.1672,-827C229.1368,-827 302.0893,-827 365.6397,-827 365.6397,-827 365.6397,-827 527.1776,-827 662.8932,-827 778.1694,-683.7089 820.7207,-623.3279"/>
<polygon fill="#000000" stroke="#000000" points="823.6406,-625.2592 826.4648,-615.0477 817.889,-621.2692 823.6406,-625.2592"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).ExcessBytes -->
<g id="node11" class="node">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).ExcessBytes</title>
<g id="a_node11"><a xlink:title="(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).ExcessBytes | defined in certificate.go:87&#10;at certificate.go:90: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]&#10;at certificate.go:92: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at certificate.go:95: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at certificate.go:88: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]&#10;at certificate.go:89: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]">
<path fill="#add8e6" stroke="#000000" stroke-width="1.5" d="M400.8974,-477C400.8974,-477 330.382,-477 330.382,-477 324.382,-477 318.382,-471 318.382,-465 318.382,-465 318.382,-453 318.382,-453 318.382,-447 324.382,-441 330.382,-441 330.382,-441 400.8974,-441 400.8974,-441 406.8974,-441 412.8974,-447 412.8974,-453 412.8974,-453 412.8974,-465 412.8974,-465 412.8974,-471 406.8974,-477 400.8974,-477"/>
<text text-anchor="middle" x="365.6397" y="-454.8" font-family="Verdana" font-size="14.00" fill="#000000">ExcessBytes</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).ExcessBytes -->
<g id="edge18" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).ExcessBytes</title>
<g id="a_edge18"><a xlink:title="at certificate.go:207: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).ExcessBytes]">
<path fill="none" stroke="#000000" d="M129.437,-808.9044C146.6115,-754.2052 204.7309,-588.3227 305.045,-490 307.6901,-487.4074 310.5958,-484.985 313.6587,-482.7299"/>
<polygon fill="#000000" stroke="#000000" points="315.668,-485.597 322.0625,-477.1494 311.7957,-479.7656 315.668,-485.597"/>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields -->
<g id="edge22" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields</title>
<g id="a_edge22"><a xlink:title="at certificate.go:208: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="none" stroke="#8b4513" d="M179.9695,-836.824C228.8138,-844.544 301.6938,-854 365.6397,-854 365.6397,-854 365.6397,-854 838.2555,-854 918.5747,-854 924.2112,-802.065 994.3902,-763 999.5451,-760.1306 1005.014,-757.3022 1010.5228,-754.5908"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1012.2784,-757.6307 1019.7827,-750.1517 1009.2523,-751.3185 1012.2784,-757.6307"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/logger.Logger).Warn -->
<g id="node18" class="node">
<title>(*github.com/go&#45;i2p/logger.Logger).Warn</title>
<g id="a_node18"><a xlink:title="(*github.com/go&#45;i2p/logger.Logger).Warn | defined in log.go:30">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M1080.1334,-811C1080.1334,-811 1044.6008,-811 1044.6008,-811 1038.6008,-811 1032.6008,-805 1032.6008,-799 1032.6008,-799 1032.6008,-787 1032.6008,-787 1032.6008,-781 1038.6008,-775 1044.6008,-775 1044.6008,-775 1080.1334,-775 1080.1334,-775 1086.1334,-775 1092.1334,-781 1092.1334,-787 1092.1334,-787 1092.1334,-799 1092.1334,-799 1092.1334,-805 1086.1334,-811 1080.1334,-811"/>
<text text-anchor="middle" x="1062.3671" y="-797.2" font-family="Verdana" font-size="14.00" fill="#000000">logger</text>
<text text-anchor="middle" x="1062.3671" y="-780.4" font-family="Verdana" font-size="14.00" fill="#000000">Warn</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).Warn -->
<g id="edge21" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).Warn</title>
<g id="a_edge21"><a xlink:title="at certificate.go:204: calling [(*github.com/go&#45;i2p/logger.Logger).Warn]">
<path fill="none" stroke="#8b4513" d="M174.6643,-845.1314C223.0522,-860.819 298.3724,-881 365.6397,-881 365.6397,-881 365.6397,-881 838.2555,-881 892.3836,-881 907.9658,-880.678 958.3902,-861 985.466,-850.4337 1012.8462,-832.1507 1032.7088,-817.2021"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1034.9416,-819.9004 1040.7382,-811.0319 1030.6763,-814.3499 1034.9416,-819.9004"/>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug -->
<g id="edge9" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug</title>
<g id="a_edge9"><a xlink:title="at certificate.go:210: calling [(*github.com/sirupsen/logrus.Logger).Debug]">
<path fill="none" stroke="#8b4513" d="M126.618,-808.9925C142.1927,-704.3357 227.2637,-179 365.6397,-179 365.6397,-179 365.6397,-179 838.2555,-179 876.2584,-179 889.4097,-178.4702 921.3902,-199 965.6091,-227.3863 951.2954,-261.9346 994.3902,-292 1002.5446,-297.689 1012.2569,-301.9722 1021.752,-305.1723"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1020.9084,-308.5739 1031.4939,-308.1286 1022.9412,-301.8755 1020.9084,-308.5739"/>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.init -->
<g id="node4" class="node">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.init</title>
<g id="a_node4"><a xlink:title="github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.init | defined in .:0&#10;at certificate.go:18: calling [github.com/go&#45;i2p/logger.GetGoI2PLogger]">
<path fill="#add8e6" stroke="#000000" stroke-width=".5" d="M139.0225,-59C139.0225,-59 109.0225,-59 109.0225,-59 103.0225,-59 97.0225,-53 97.0225,-47 97.0225,-47 97.0225,-35 97.0225,-35 97.0225,-29 103.0225,-23 109.0225,-23 109.0225,-23 139.0225,-23 139.0225,-23 145.0225,-23 151.0225,-29 151.0225,-35 151.0225,-35 151.0225,-47 151.0225,-47 151.0225,-53 145.0225,-59 139.0225,-59"/>
<text text-anchor="middle" x="124.0225" y="-36.8" font-family="Verdana" font-size="14.00" fill="#000000">init</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/logger.GetGoI2PLogger -->
<g id="node5" class="node">
<title>github.com/go&#45;i2p/logger.GetGoI2PLogger</title>
<g id="a_node5"><a xlink:title="github.com/go&#45;i2p/logger.GetGoI2PLogger | defined in log.go:120">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M414.3292,-59C414.3292,-59 316.9502,-59 316.9502,-59 310.9502,-59 304.9502,-53 304.9502,-47 304.9502,-47 304.9502,-35 304.9502,-35 304.9502,-29 310.9502,-23 316.9502,-23 316.9502,-23 414.3292,-23 414.3292,-23 420.3292,-23 426.3292,-29 426.3292,-35 426.3292,-35 426.3292,-47 426.3292,-47 426.3292,-53 420.3292,-59 414.3292,-59"/>
<text text-anchor="middle" x="365.6397" y="-45.2" font-family="Verdana" font-size="14.00" fill="#000000">logger</text>
<text text-anchor="middle" x="365.6397" y="-28.4" font-family="Verdana" font-size="14.00" fill="#000000">GetGoI2PLogger</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.init&#45;&gt;github.com/go&#45;i2p/logger.GetGoI2PLogger -->
<g id="edge36" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.init&#45;&gt;github.com/go&#45;i2p/logger.GetGoI2PLogger</title>
<g id="a_edge36"><a xlink:title="at certificate.go:18: calling [github.com/go&#45;i2p/logger.GetGoI2PLogger]">
<path fill="none" stroke="#8b4513" d="M151.2694,-41C185.8355,-41 246.7324,-41 294.8092,-41"/>
<polygon fill="#8b4513" stroke="#8b4513" points="294.8596,-44.5001 304.8596,-41 294.8595,-37.5001 294.8596,-44.5001"/>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.GetSignatureTypeFromCertificate -->
<g id="node6" class="node">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.GetSignatureTypeFromCertificate</title>
<g id="a_node6"><a xlink:title="github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.GetSignatureTypeFromCertificate | defined in certificate.go:281&#10;at certificate.go:282: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type]&#10;at certificate.go:283: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type]&#10;at certificate.go:283: calling [github.com/samber/oops.Errorf]&#10;at certificate.go:286: calling [github.com/samber/oops.Errorf]">
<path fill="#add8e6" stroke="#000000" stroke-width="1.5" d="M220.0675,-223C220.0675,-223 27.9775,-223 27.9775,-223 21.9775,-223 15.9775,-217 15.9775,-211 15.9775,-211 15.9775,-199 15.9775,-199 15.9775,-193 21.9775,-187 27.9775,-187 27.9775,-187 220.0675,-187 220.0675,-187 226.0675,-187 232.0675,-193 232.0675,-199 232.0675,-199 232.0675,-211 232.0675,-211 232.0675,-217 226.0675,-223 220.0675,-223"/>
<text text-anchor="middle" x="124.0225" y="-200.8" font-family="Verdana" font-size="14.00" fill="#000000">GetSignatureTypeFromCertificate</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.GetSignatureTypeFromCertificate&#45;&gt;github.com/samber/oops.Errorf -->
<g id="edge4" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.GetSignatureTypeFromCertificate&#45;&gt;github.com/samber/oops.Errorf</title>
<g id="a_edge4"><a xlink:title="at certificate.go:283: calling [github.com/samber/oops.Errorf]&#10;at certificate.go:286: calling [github.com/samber/oops.Errorf]">
<path fill="none" stroke="#8b4513" d="M145.3922,-186.9364C185.6792,-154.7915 276.818,-91 365.6397,-91 365.6397,-91 365.6397,-91 718.6208,-91 829.0428,-91 959.081,-101.4127 1022.9377,-107.2115"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1022.6938,-110.7038 1032.9723,-108.1345 1023.335,-103.7332 1022.6938,-110.7038"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type -->
<g id="node15" class="node">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type</title>
<g id="a_node15"><a xlink:title="(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type | defined in certificate.go:116&#10;at certificate.go:117: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]&#10;at certificate.go:120: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at certificate.go:118: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="#add8e6" stroke="#000000" stroke-width="1.5" d="M380.6397,-416C380.6397,-416 350.6397,-416 350.6397,-416 344.6397,-416 338.6397,-410 338.6397,-404 338.6397,-404 338.6397,-392 338.6397,-392 338.6397,-386 344.6397,-380 350.6397,-380 350.6397,-380 380.6397,-380 380.6397,-380 386.6397,-380 392.6397,-386 392.6397,-392 392.6397,-392 392.6397,-404 392.6397,-404 392.6397,-410 386.6397,-416 380.6397,-416"/>
<text text-anchor="middle" x="365.6397" y="-393.8" font-family="Verdana" font-size="14.00" fill="#000000">Type</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.GetSignatureTypeFromCertificate&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type -->
<g id="edge3" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.GetSignatureTypeFromCertificate&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type</title>
<g id="a_edge3"><a xlink:title="at certificate.go:282: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type]&#10;at certificate.go:283: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type]">
<path fill="none" stroke="#000000" d="M140.8989,-223.1706C171.4062,-255.2997 238.7388,-322.9884 305.045,-368 312.5955,-373.1256 321.1482,-377.9048 329.3982,-382.0752"/>
<polygon fill="#000000" stroke="#000000" points="327.9911,-385.2828 338.5145,-386.5112 331.054,-378.9885 327.9911,-385.2828"/>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.NewCertificateDeux -->
<g id="node7" class="node">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.NewCertificateDeux</title>
<g id="a_node7"><a xlink:title="github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.NewCertificateDeux | defined in certificate.go:223&#10;at certificate.go:243: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]&#10;at certificate.go:225: calling [github.com/samber/oops.Errorf]&#10;at certificate.go:230: calling [github.com/samber/oops.Errorf]&#10;at certificate.go:246: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at certificate.go:233: calling [github.com/go&#45;i2p/go&#45;i2p/lib/common/data.NewIntegerFromInt]">
<path fill="#add8e6" stroke="#000000" stroke-width="1.5" d="M896.0832,-153C896.0832,-153 780.4278,-153 780.4278,-153 774.4278,-153 768.4278,-147 768.4278,-141 768.4278,-141 768.4278,-129 768.4278,-129 768.4278,-123 774.4278,-117 780.4278,-117 780.4278,-117 896.0832,-117 896.0832,-117 902.0832,-117 908.0832,-123 908.0832,-129 908.0832,-129 908.0832,-141 908.0832,-141 908.0832,-147 902.0832,-153 896.0832,-153"/>
<text text-anchor="middle" x="838.2555" y="-130.8" font-family="Verdana" font-size="14.00" fill="#000000">NewCertificateDeux</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.NewCertificateDeux&#45;&gt;github.com/samber/oops.Errorf -->
<g id="edge23" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.NewCertificateDeux&#45;&gt;github.com/samber/oops.Errorf</title>
<g id="a_edge23"><a xlink:title="at certificate.go:225: calling [github.com/samber/oops.Errorf]&#10;at certificate.go:230: calling [github.com/samber/oops.Errorf]">
<path fill="none" stroke="#8b4513" d="M908.244,-127.505C945.9757,-123.4643 991.1517,-118.6264 1022.8055,-115.2366"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1023.4211,-118.6908 1032.9915,-114.1458 1022.6757,-111.7306 1023.4211,-118.6908"/>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/data.NewIntegerFromInt -->
<g id="node8" class="node">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/data.NewIntegerFromInt</title>
<g id="a_node8"><a xlink:title="github.com/go&#45;i2p/go&#45;i2p/lib/common/data.NewIntegerFromInt | defined in integer.go:68">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M1118.3209,-53C1118.3209,-53 1006.4133,-53 1006.4133,-53 1000.4133,-53 994.4133,-47 994.4133,-41 994.4133,-41 994.4133,-29 994.4133,-29 994.4133,-23 1000.4133,-17 1006.4133,-17 1006.4133,-17 1118.3209,-17 1118.3209,-17 1124.3209,-17 1130.3209,-23 1130.3209,-29 1130.3209,-29 1130.3209,-41 1130.3209,-41 1130.3209,-47 1124.3209,-53 1118.3209,-53"/>
<text text-anchor="middle" x="1062.3671" y="-39.2" font-family="Verdana" font-size="14.00" fill="#000000">data</text>
<text text-anchor="middle" x="1062.3671" y="-22.4" font-family="Verdana" font-size="14.00" fill="#000000">NewIntegerFromInt</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.NewCertificateDeux&#45;&gt;github.com/go&#45;i2p/go&#45;i2p/lib/common/data.NewIntegerFromInt -->
<g id="edge37" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.NewCertificateDeux&#45;&gt;github.com/go&#45;i2p/go&#45;i2p/lib/common/data.NewIntegerFromInt</title>
<g id="a_edge37"><a xlink:title="at certificate.go:233: calling [github.com/go&#45;i2p/go&#45;i2p/lib/common/data.NewIntegerFromInt]">
<path fill="none" stroke="#8b4513" d="M878.8404,-116.8908C916.3257,-100.1646 972.1246,-75.2668 1012.3495,-57.3182"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1014.0001,-60.4143 1021.7061,-53.1432 1011.1477,-54.0218 1014.0001,-60.4143"/>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.NewCertificateDeux&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields -->
<g id="edge12" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.NewCertificateDeux&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields</title>
<g id="a_edge12"><a xlink:title="at certificate.go:243: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="none" stroke="#8b4513" d="M851.522,-153.0586C870.1671,-179.3685 903.8061,-230.4117 921.3902,-279 953.8513,-368.6964 935.6768,-626.8209 994.3902,-702 998.6579,-707.4646 1004.1302,-711.9569 1010.1131,-715.6445"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1008.6953,-718.8555 1019.1632,-720.4908 1011.9999,-712.6846 1008.6953,-718.8555"/>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.NewCertificateDeux&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug -->
<g id="edge34" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.NewCertificateDeux&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug</title>
<g id="a_edge34"><a xlink:title="at certificate.go:246: calling [(*github.com/sirupsen/logrus.Logger).Debug]">
<path fill="none" stroke="#8b4513" d="M908.395,-144.374C926.6456,-149.8377 944.937,-158.4481 958.3902,-172 997.6189,-211.5165 955.4437,-252.2053 994.3902,-292 1001.7432,-299.5132 1011.6778,-304.4629 1021.6788,-307.7231"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1021.0388,-311.1769 1031.6088,-310.4525 1022.8941,-304.4273 1021.0388,-311.1769"/>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.NewCertificateWithType -->
<g id="node9" class="node">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.NewCertificateWithType</title>
<g id="a_node9"><a xlink:title="github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.NewCertificateWithType | defined in certificate.go:252&#10;at certificate.go:258: calling [github.com/samber/oops.Errorf]&#10;at certificate.go:263: calling [github.com/samber/oops.Errorf]&#10;at certificate.go:265: calling [github.com/go&#45;i2p/go&#45;i2p/lib/common/data.NewIntegerFromInt]">
<path fill="#add8e6" stroke="#000000" stroke-width="1.5" d="M909.5251,-57C909.5251,-57 766.9859,-57 766.9859,-57 760.9859,-57 754.9859,-51 754.9859,-45 754.9859,-45 754.9859,-33 754.9859,-33 754.9859,-27 760.9859,-21 766.9859,-21 766.9859,-21 909.5251,-21 909.5251,-21 915.5251,-21 921.5251,-27 921.5251,-33 921.5251,-33 921.5251,-45 921.5251,-45 921.5251,-51 915.5251,-57 909.5251,-57"/>
<text text-anchor="middle" x="838.2555" y="-34.8" font-family="Verdana" font-size="14.00" fill="#000000">NewCertificateWithType</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.NewCertificateWithType&#45;&gt;github.com/samber/oops.Errorf -->
<g id="edge28" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.NewCertificateWithType&#45;&gt;github.com/samber/oops.Errorf</title>
<g id="a_edge28"><a xlink:title="at certificate.go:258: calling [github.com/samber/oops.Errorf]&#10;at certificate.go:263: calling [github.com/samber/oops.Errorf]">
<path fill="none" stroke="#8b4513" d="M894.519,-57.0757C934.8151,-70.0216 988.0345,-87.1193 1023.6417,-98.5588"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1022.6011,-101.9006 1033.1924,-101.6271 1024.7422,-95.236 1022.6011,-101.9006"/>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.NewCertificateWithType&#45;&gt;github.com/go&#45;i2p/go&#45;i2p/lib/common/data.NewIntegerFromInt -->
<g id="edge40" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.NewCertificateWithType&#45;&gt;github.com/go&#45;i2p/go&#45;i2p/lib/common/data.NewIntegerFromInt</title>
<g id="a_edge40"><a xlink:title="at certificate.go:265: calling [github.com/go&#45;i2p/go&#45;i2p/lib/common/data.NewIntegerFromInt]">
<path fill="none" stroke="#8b4513" d="M921.7064,-37.5105C942.1472,-37.1457 963.949,-36.7566 984.1349,-36.3963"/>
<polygon fill="#8b4513" stroke="#8b4513" points="984.2775,-39.8944 994.2134,-36.2164 984.1525,-32.8955 984.2775,-39.8944"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length -->
<g id="node10" class="node">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length</title>
<g id="a_node10"><a xlink:title="(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length | defined in certificate.go:125&#10;at certificate.go:129: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at certificate.go:126: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]&#10;at certificate.go:127: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="#add8e6" stroke="#000000" stroke-width="1.5" d="M857.9142,-538C857.9142,-538 818.5968,-538 818.5968,-538 812.5968,-538 806.5968,-532 806.5968,-526 806.5968,-526 806.5968,-514 806.5968,-514 806.5968,-508 812.5968,-502 818.5968,-502 818.5968,-502 857.9142,-502 857.9142,-502 863.9142,-502 869.9142,-508 869.9142,-514 869.9142,-514 869.9142,-526 869.9142,-526 869.9142,-532 863.9142,-538 857.9142,-538"/>
<text text-anchor="middle" x="838.2555" y="-515.8" font-family="Verdana" font-size="14.00" fill="#000000">Length</text>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields -->
<g id="edge38" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields</title>
<g id="a_edge38"><a xlink:title="at certificate.go:127: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="none" stroke="#8b4513" d="M870.0778,-521.9339C886.97,-524.4397 907.1252,-529.9669 921.3902,-542 981.1357,-592.3975 938.7785,-647.0748 994.3902,-702 998.9677,-706.521 1004.3418,-710.4191 1010.0282,-713.7654"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1008.6741,-717.0082 1019.1517,-718.5799 1011.9411,-710.8173 1008.6741,-717.0082"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug -->
<g id="edge24" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug</title>
<g id="a_edge24"><a xlink:title="at certificate.go:129: calling [(*github.com/sirupsen/logrus.Logger).Debug]">
<path fill="none" stroke="#8b4513" d="M863.6821,-501.7945C880.5068,-489.4202 902.8082,-472.3815 921.3902,-456 964.9263,-417.6195 1011.6811,-368.8553 1038.9109,-339.6073"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1041.4949,-341.9681 1045.7268,-332.2552 1036.3615,-337.2091 1041.4949,-341.9681"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length&#45;&gt;(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int -->
<g id="edge35" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length&#45;&gt;(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int</title>
<g id="a_edge35"><a xlink:title="at certificate.go:126: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]">
<path fill="none" stroke="#8b4513" d="M870.3652,-520C911.289,-520 981.8968,-520 1025.1348,-520"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1025.2399,-523.5001 1035.2399,-520 1025.2398,-516.5001 1025.2399,-523.5001"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).ExcessBytes&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields -->
<g id="edge6" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).ExcessBytes&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields</title>
<g id="a_edge6"><a xlink:title="at certificate.go:90: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="none" stroke="#8b4513" d="M413.037,-477.0926C418.1184,-480.6981 422.7107,-484.966 426.2344,-490 463.4737,-543.2008 413.5692,-737.0025 462.2344,-780 503.5475,-816.5017 904.5976,-792.0624 958.3902,-780 975.6557,-776.1284 978.3402,-770.4489 994.3902,-763 1000.477,-760.1751 1006.8798,-757.2259 1013.2223,-754.3181"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1014.7903,-757.4497 1022.4278,-750.1066 1011.8781,-751.0842 1014.7903,-757.4497"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).ExcessBytes&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug -->
<g id="edge19" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).ExcessBytes&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug</title>
<g id="a_edge19"><a xlink:title="at certificate.go:92: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at certificate.go:95: calling [(*github.com/sirupsen/logrus.Logger).Debug]">
<path fill="none" stroke="#8b4513" d="M407.6685,-440.8914C414.1432,-437.349 420.556,-433.3622 426.2344,-429 480.1656,-387.5692 459.1696,-314 527.1776,-314 527.1776,-314 527.1776,-314 838.2555,-314 902.192,-314 976.3886,-314 1021.3294,-314"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1021.5535,-317.5001 1031.5535,-314 1021.5535,-310.5001 1021.5535,-317.5001"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).ExcessBytes&#45;&gt;(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int -->
<g id="edge30" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).ExcessBytes&#45;&gt;(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int</title>
<g id="a_edge30"><a xlink:title="at certificate.go:88: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]&#10;at certificate.go:89: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]">
<path fill="none" stroke="#8b4513" d="M413.0536,-442.2321C444.9043,-432.4424 488.049,-422 527.1776,-422 527.1776,-422 527.1776,-422 718.6208,-422 779.7179,-422 950.1975,-479.98 1025.6438,-506.7463"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1024.618,-510.0963 1035.2127,-510.1547 1026.9669,-503.5021 1024.618,-510.0963"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes -->
<g id="node12" class="node">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes</title>
<g id="a_node12"><a xlink:title="(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes | defined in certificate.go:100&#10;at certificate.go:104: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]&#10;at certificate.go:101: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Bytes]&#10;at certificate.go:102: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Bytes]&#10;at certificate.go:106: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at certificate.go:103: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data]">
<path fill="#add8e6" stroke="#000000" stroke-width="1.5" d="M543.0641,-538C543.0641,-538 511.2911,-538 511.2911,-538 505.2911,-538 499.2911,-532 499.2911,-526 499.2911,-526 499.2911,-514 499.2911,-514 499.2911,-508 505.2911,-502 511.2911,-502 511.2911,-502 543.0641,-502 543.0641,-502 549.0641,-502 555.0641,-508 555.0641,-514 555.0641,-514 555.0641,-526 555.0641,-526 555.0641,-532 549.0641,-538 543.0641,-538"/>
<text text-anchor="middle" x="527.1776" y="-515.8" font-family="Verdana" font-size="14.00" fill="#000000">Bytes</text>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data -->
<g id="node13" class="node">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data</title>
<g id="a_node13"><a xlink:title="(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data | defined in certificate.go:134&#10;at certificate.go:138: calling [(*github.com/go&#45;i2p/logger.Logger).Warn]&#10;at certificate.go:144: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at certificate.go:135: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length]&#10;at certificate.go:142: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="#add8e6" stroke="#000000" stroke-width="1.5" d="M670.1208,-538C670.1208,-538 640.1208,-538 640.1208,-538 634.1208,-538 628.1208,-532 628.1208,-526 628.1208,-526 628.1208,-514 628.1208,-514 628.1208,-508 634.1208,-502 640.1208,-502 640.1208,-502 670.1208,-502 670.1208,-502 676.1208,-502 682.1208,-508 682.1208,-514 682.1208,-514 682.1208,-526 682.1208,-526 682.1208,-532 676.1208,-538 670.1208,-538"/>
<text text-anchor="middle" x="655.1208" y="-515.8" font-family="Verdana" font-size="14.00" fill="#000000">Data</text>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data -->
<g id="edge32" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data</title>
<g id="a_edge32"><a xlink:title="at certificate.go:103: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data]">
<path fill="none" stroke="#000000" d="M555.2553,-520C573.6714,-520 597.9555,-520 617.9655,-520"/>
<polygon fill="#000000" stroke="#000000" points="617.9862,-523.5001 627.9861,-520 617.9861,-516.5001 617.9862,-523.5001"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields -->
<g id="edge1" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields</title>
<g id="a_edge1"><a xlink:title="at certificate.go:104: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="none" stroke="#8b4513" d="M529.9125,-538.0109C538.4723,-586.9966 569.4835,-719 655.1208,-719 655.1208,-719 655.1208,-719 838.2555,-719 896.6494,-719 963.4583,-723.453 1008.8298,-727.1466"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1008.7727,-730.6539 1019.0281,-727.9935 1009.3521,-723.6779 1008.7727,-730.6539"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug -->
<g id="edge27" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug</title>
<g id="a_edge27"><a xlink:title="at certificate.go:106: calling [(*github.com/sirupsen/logrus.Logger).Debug]">
<path fill="none" stroke="#8b4513" d="M535.3242,-501.8239C552.2462,-467.1555 594.7211,-395 655.1208,-395 655.1208,-395 655.1208,-395 718.6208,-395 830.9451,-395 958.5435,-353.5187 1022.0321,-329.926"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1023.5331,-333.1008 1031.659,-326.3022 1021.067,-326.5495 1023.5331,-333.1008"/>
</a>
</g>
</g>
<!-- (github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Bytes -->
<g id="node22" class="node">
<title>(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Bytes</title>
<g id="a_node22"><a xlink:title="(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Bytes | defined in integer.go:27">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M1078.2536,-477C1078.2536,-477 1046.4806,-477 1046.4806,-477 1040.4806,-477 1034.4806,-471 1034.4806,-465 1034.4806,-465 1034.4806,-453 1034.4806,-453 1034.4806,-447 1040.4806,-441 1046.4806,-441 1046.4806,-441 1078.2536,-441 1078.2536,-441 1084.2536,-441 1090.2536,-447 1090.2536,-453 1090.2536,-453 1090.2536,-465 1090.2536,-465 1090.2536,-471 1084.2536,-477 1078.2536,-477"/>
<text text-anchor="middle" x="1062.3671" y="-463.2" font-family="Verdana" font-size="14.00" fill="#000000">data</text>
<text text-anchor="middle" x="1062.3671" y="-446.4" font-family="Verdana" font-size="14.00" fill="#000000">Bytes</text>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes&#45;&gt;(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Bytes -->
<g id="edge25" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes&#45;&gt;(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Bytes</title>
<g id="a_edge25"><a xlink:title="at certificate.go:101: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Bytes]&#10;at certificate.go:102: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Bytes]">
<path fill="none" stroke="#8b4513" d="M555.1926,-504.3634C580.5012,-491.7165 619.1824,-476 655.1208,-476 655.1208,-476 655.1208,-476 838.2555,-476 903.8206,-476 979.867,-468.6762 1024.3892,-463.6427"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1024.9341,-467.1032 1034.4676,-462.4812 1024.1326,-460.1492 1024.9341,-467.1032"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length -->
<g id="edge26" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length</title>
<g id="a_edge26"><a xlink:title="at certificate.go:135: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length]">
<path fill="none" stroke="#000000" d="M682.143,-520C712.169,-520 761.0347,-520 796.0998,-520"/>
<polygon fill="#000000" stroke="#000000" points="796.503,-523.5001 806.5029,-520 796.5029,-516.5001 796.503,-523.5001"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields -->
<g id="edge31" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields</title>
<g id="a_edge31"><a xlink:title="at certificate.go:142: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="none" stroke="#8b4513" d="M662.5733,-538.0526C676.177,-568.6482 708.0373,-630.4325 755.1208,-662 765.7096,-669.0994 923.8065,-702.9794 1008.9624,-720.8715"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1008.4652,-724.3433 1018.9709,-722.9713 1009.9026,-717.4924 1008.4652,-724.3433"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).Warn -->
<g id="edge14" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).Warn</title>
<g id="a_edge14"><a xlink:title="at certificate.go:138: calling [(*github.com/go&#45;i2p/logger.Logger).Warn]">
<path fill="none" stroke="#8b4513" d="M660.6886,-538.1788C672.3115,-572.9981 702.5344,-649.1699 755.1208,-689 837.4468,-751.3554 959.4954,-777.7431 1022.106,-787.6955"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1021.9424,-791.211 1032.3563,-789.2615 1022.9997,-784.2913 1021.9424,-791.211"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug -->
<g id="edge15" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug</title>
<g id="a_edge15"><a xlink:title="at certificate.go:144: calling [(*github.com/sirupsen/logrus.Logger).Debug]">
<path fill="none" stroke="#8b4513" d="M682.1656,-509.4896C730.9543,-490.2072 836.5157,-447.009 921.3902,-402 958.6511,-382.2405 999.3255,-356.3539 1027.366,-337.7802"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1029.6243,-340.4813 1036.0057,-332.0238 1025.743,-334.6558 1029.6243,-340.4813"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).length -->
<g id="node14" class="node">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).length</title>
<g id="a_node14"><a xlink:title="(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).length | defined in certificate.go:110&#10;at certificate.go:111: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes]">
<path fill="#add8e6" stroke="#000000" stroke-width=".5" d="M383.1355,-538C383.1355,-538 348.1439,-538 348.1439,-538 342.1439,-538 336.1439,-532 336.1439,-526 336.1439,-526 336.1439,-514 336.1439,-514 336.1439,-508 342.1439,-502 348.1439,-502 348.1439,-502 383.1355,-502 383.1355,-502 389.1355,-502 395.1355,-508 395.1355,-514 395.1355,-514 395.1355,-526 395.1355,-526 395.1355,-532 389.1355,-538 383.1355,-538"/>
<text text-anchor="middle" x="365.6397" y="-515.8" font-family="Verdana" font-size="14.00" fill="#000000">length</text>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).length&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes -->
<g id="edge7" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).length&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes</title>
<g id="a_edge7"><a xlink:title="at certificate.go:111: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes]">
<path fill="none" stroke="#000000" d="M395.2682,-520C421.6326,-520 460.3466,-520 489.0205,-520"/>
<polygon fill="#000000" stroke="#000000" points="489.0889,-523.5001 499.0889,-520 489.0888,-516.5001 489.0889,-523.5001"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields -->
<g id="edge33" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields</title>
<g id="a_edge33"><a xlink:title="at certificate.go:118: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="none" stroke="#8b4513" d="M392.8854,-405.4307C405.0472,-410.1699 418.3791,-417.6229 426.2344,-429 508.5551,-548.228 369.8577,-641.3821 462.2344,-753 481.4902,-776.2666 496.9762,-773 527.1776,-773 527.1776,-773 527.1776,-773 838.2555,-773 897.4598,-773 964.0466,-758.9838 1009.1435,-747.3416"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1010.2151,-750.6788 1018.9943,-744.7479 1008.4327,-743.9095 1010.2151,-750.6788"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug -->
<g id="edge11" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug</title>
<g id="a_edge11"><a xlink:title="at certificate.go:120: calling [(*github.com/sirupsen/logrus.Logger).Debug]">
<path fill="none" stroke="#8b4513" d="M392.7503,-388.5653C404.0291,-383.6871 416.6888,-376.869 426.2344,-368 449.2966,-346.5723 437.5241,-326.5042 462.2344,-307 485.9407,-288.2882 496.9762,-287 527.1776,-287 527.1776,-287 527.1776,-287 838.2555,-287 902.7902,-287 977.0323,-298.1719 1021.7903,-306.143"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1021.2301,-309.5984 1031.6944,-307.9407 1022.4802,-302.711 1021.2301,-309.5984"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type&#45;&gt;(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int -->
<g id="edge10" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type&#45;&gt;(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int</title>
<g id="a_edge10"><a xlink:title="at certificate.go:117: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Int]">
<path fill="none" stroke="#8b4513" d="M392.7931,-389.8024C424.6635,-380.9199 479.2568,-368 527.1776,-368 527.1776,-368 527.1776,-368 838.2555,-368 926.3206,-368 921.2143,-441.0025 994.3902,-490 1003.9919,-496.4291 1015.1971,-502.0322 1025.7081,-506.6001"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1024.5221,-509.8973 1035.0999,-510.4981 1027.2055,-503.432 1024.5221,-509.8973"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).RawBytes -->
<g id="node16" class="node">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).RawBytes</title>
<g id="a_node16"><a xlink:title="(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).RawBytes | defined in certificate.go:76&#10;at certificate.go:80: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]&#10;at certificate.go:77: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Bytes]&#10;at certificate.go:78: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Bytes]&#10;at certificate.go:82: calling [(*github.com/sirupsen/logrus.Logger).Debug]">
<path fill="#add8e6" stroke="#000000" stroke-width="1.5" d="M394.1852,-355C394.1852,-355 337.0942,-355 337.0942,-355 331.0942,-355 325.0942,-349 325.0942,-343 325.0942,-343 325.0942,-331 325.0942,-331 325.0942,-325 331.0942,-319 337.0942,-319 337.0942,-319 394.1852,-319 394.1852,-319 400.1852,-319 406.1852,-325 406.1852,-331 406.1852,-331 406.1852,-343 406.1852,-343 406.1852,-349 400.1852,-355 394.1852,-355"/>
<text text-anchor="middle" x="365.6397" y="-332.8" font-family="Verdana" font-size="14.00" fill="#000000">RawBytes</text>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).RawBytes&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields -->
<g id="edge5" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).RawBytes&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields</title>
<g id="a_edge5"><a xlink:title="at certificate.go:80: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="none" stroke="#8b4513" d="M406.2658,-351.7653C413.7563,-356.0336 420.8884,-361.3814 426.2344,-368 535.4971,-503.2716 353.2904,-746 527.1776,-746 527.1776,-746 527.1776,-746 838.2555,-746 896.665,-746 963.4713,-741.2044 1008.8379,-737.2267"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1009.3865,-740.6917 1019.035,-736.3147 1008.7629,-733.7195 1009.3865,-740.6917"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).RawBytes&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug -->
<g id="edge29" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).RawBytes&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug</title>
<g id="a_edge29"><a xlink:title="at certificate.go:82: calling [(*github.com/sirupsen/logrus.Logger).Debug]">
<path fill="none" stroke="#8b4513" d="M406.2343,-326.7314C413.3846,-323.7232 420.3965,-319.8824 426.2344,-315 450.677,-294.5581 440.8621,-276.6333 462.2344,-253 486.1323,-226.5738 491.5482,-206 527.1776,-206 527.1776,-206 527.1776,-206 838.2555,-206 895.5894,-206 911.0429,-220.6671 958.3902,-253 977.8704,-266.3028 974.5202,-279.2867 994.3902,-292 1002.6878,-297.309 1012.3789,-301.4413 1021.8004,-304.616"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1020.8641,-307.9898 1031.4513,-307.5869 1022.9237,-301.2996 1020.8641,-307.9898"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).RawBytes&#45;&gt;(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Bytes -->
<g id="edge13" class="edge">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).RawBytes&#45;&gt;(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Bytes</title>
<g id="a_edge13"><a xlink:title="at certificate.go:77: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Bytes]&#10;at certificate.go:78: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/data.Integer).Bytes]">
<path fill="none" stroke="#8b4513" d="M406.3953,-323.1598C413.0929,-320.6131 419.9087,-317.8521 426.2344,-315 472.8101,-294.0003 476.0867,-260 527.1776,-260 527.1776,-260 527.1776,-260 838.2555,-260 940.5999,-260 1017.9747,-377.4734 1048.3334,-431.9054"/>
<polygon fill="#8b4513" stroke="#8b4513" points="1045.4271,-433.8864 1053.2885,-440.9891 1051.5723,-430.5342 1045.4271,-433.8864"/>
</a>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 61 KiB

View File

@@ -1,369 +0,0 @@
package certificate
import (
"bytes"
"testing"
"github.com/stretchr/testify/assert"
)
func TestCertificateTypeIsFirstByte(t *testing.T) {
assert := assert.New(t)
bytes := []byte{0x03, 0x00, 0x00}
certificate, err := readCertificate(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 := readCertificate(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 := readCertificate(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 := readCertificate(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 := readCertificate(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")
}
}
func TestNewCertificateNullType(t *testing.T) {
assert := assert.New(t)
// Create a NULL certificate with no payload
cert, err := NewCertificateWithType(CERT_NULL, []byte{})
assert.Nil(err, "Expected no error when creating NULL certificate with empty payload")
assert.Equal(CERT_NULL, cert.Type(), "Certificate type should be CERT_NULL")
assert.Equal(0, cert.Length(), "Certificate length should be 0 for NULL certificate")
assert.Equal(0, len(cert.Data()), "Certificate data should be empty for NULL certificate")
}
func TestNewCertificateNullTypeWithPayload(t *testing.T) {
assert := assert.New(t)
// Attempt to create a NULL certificate with a payload (should fail)
_, err := NewCertificateWithType(CERT_NULL, []byte{0x00})
assert.NotNil(err, "Expected error when creating NULL certificate with payload")
assert.Equal("NULL certificates must have empty payload", err.Error(), "Correct error message should be returned")
}
func TestNewCertificateKeyType(t *testing.T) {
assert := assert.New(t)
payload := []byte{0x00, 0x01, 0x02, 0x03, 0x04}
cert, err := NewCertificateWithType(CERT_KEY, payload)
assert.Nil(err, "Expected no error when creating KEY certificate with valid payload")
assert.Equal(CERT_KEY, cert.Type(), "Certificate type should be CERT_KEY")
assert.Equal(len(payload), cert.Length(), "Certificate length should match payload length")
assert.Equal(payload, cert.Data(), "Certificate data should match payload")
}
func TestNewCertificateInvalidType(t *testing.T) {
assert := assert.New(t)
invalidCertType := uint8(6) // Invalid type (valid types are 0-5)
_, err := NewCertificateWithType(invalidCertType, []byte{})
assert.NotNil(err, "Expected error when creating certificate with invalid type")
assert.Equal("invalid certificate type: 6", err.Error(), "Correct error message should be returned")
}
/*
func TestNewCertificatePayloadTooLong(t *testing.T) {
assert := assert.New(t)
// Create a payload that exceeds the maximum allowed length (65535 bytes)
payload := make([]byte, 65536) // 65536 bytes
_, err := NewCertificateWithType(CERT_KEY, payload)
assert.NotNil(err, "Expected error when creating certificate with payload too long")
assert.Equal("certificate payload too long: maximum length is 65535 bytes", err.Error(), "Correct error message should be returned")
}
*/
func TestCertificateBytesSerialization(t *testing.T) {
assert := assert.New(t)
payload := []byte{0xAA, 0xBB, 0xCC}
certType := CERT_SIGNED
cert, err := NewCertificateWithType(uint8(certType), payload)
assert.Nil(err, "Expected no error when creating SIGNED certificate")
expectedBytes := []byte{
byte(certType), // Certificate type
0x00, byte(len(payload)), // Certificate length (2 bytes)
0xAA, 0xBB, 0xCC, // Payload
}
actualBytes := cert.Bytes()
assert.Equal(expectedBytes, actualBytes, "Certificate bytes should match expected serialization")
}
func TestCertificateFieldsAfterCreation(t *testing.T) {
assert := assert.New(t)
payload := []byte{0xDE, 0xAD, 0xBE, 0xEF}
certType := CERT_MULTIPLE
cert, err := NewCertificateWithType(uint8(certType), payload)
assert.Nil(err, "Expected no error when creating MULTIPLE certificate")
assert.Equal(certType, cert.Type(), "Certificate type should match")
assert.Equal(len(payload), cert.Length(), "Certificate length should match payload length")
assert.Equal(payload, cert.Data(), "Certificate data should match payload")
}
func TestCertificateWithZeroLengthPayload(t *testing.T) {
assert := assert.New(t)
certType := CERT_HASHCASH
cert, err := NewCertificateWithType(uint8(certType), []byte{})
assert.Nil(err, "Expected no error when creating certificate with zero-length payload")
assert.Equal(certType, cert.Type(), "Certificate type should match")
assert.Equal(0, cert.Length(), "Certificate length should be 0 for zero-length payload")
assert.Equal(0, len(cert.Data()), "Certificate data should be empty")
}
func TestNewCertificateDeuxFunction(t *testing.T) {
assert := assert.New(t)
payload := []byte{0x11, 0x22}
certType := CERT_HIDDEN
cert, err := NewCertificateDeux(certType, payload)
assert.Nil(err, "Expected no error when creating certificate with NewCertificateDeux")
assert.Equal(certType, cert.Type(), "Certificate type should match")
assert.Equal(len(payload), cert.Length(), "Certificate length should match payload length")
assert.Equal(payload, cert.Data(), "Certificate data should match payload")
}
func TestNewCertificateWithInvalidPayloadLength(t *testing.T) {
assert := assert.New(t)
payload := make([]byte, 70000) // Exceeds 65535 bytes
_, err := NewCertificateDeux(CERT_KEY, payload)
assert.NotNil(err, "Expected error when creating certificate with payload exceeding maximum length")
assert.Equal("payload too long: 70000 bytes", err.Error(), "Correct error message should be returned")
}
func TestCertificateExcessBytes(t *testing.T) {
assert := assert.New(t)
payload := []byte{0x01, 0x02}
extraBytes := []byte{0x03, 0x04}
certData := append(payload, extraBytes...)
certBytes := append([]byte{byte(CERT_SIGNED)}, []byte{0x00, byte(len(payload))}...)
certBytes = append(certBytes, certData...)
cert, err := readCertificate(certBytes)
assert.Nil(err, "Expected no error when reading certificate with excess bytes")
excess := cert.ExcessBytes()
assert.Equal(extraBytes, excess, "ExcessBytes should return the extra bytes in the payload")
assert.Equal(payload, cert.Data(), "Data() should return the valid payload excluding excess bytes")
}
func TestCertificateSerializationDeserialization(t *testing.T) {
assert := assert.New(t)
payload := []byte{0xAA, 0xBB, 0xCC}
certType := CERT_SIGNED
originalCert, err := NewCertificateWithType(uint8(certType), payload)
assert.Nil(err, "Expected no error when creating SIGNED certificate")
serializedBytes := originalCert.Bytes()
assert.NotNil(serializedBytes, "Serialized bytes should not be nil")
deserializedCert, err := readCertificate(serializedBytes)
assert.Nil(err, "Expected no error when deserializing certificate")
assert.Equal(originalCert.Type(), deserializedCert.Type(), "Certificate types should match")
assert.Equal(originalCert.Length(), deserializedCert.Length(), "Certificate lengths should match")
assert.Equal(originalCert.Data(), deserializedCert.Data(), "Certificate payloads should match")
}
func TestCertificateSerializationDeserializationWithExcessBytes(t *testing.T) {
assert := assert.New(t)
payload := []byte{0x01, 0x02}
certType := CERT_MULTIPLE
originalCert, err := NewCertificateWithType(uint8(certType), payload)
assert.Nil(err, "Expected no error when creating MULTIPLE certificate")
serializedBytes := originalCert.Bytes()
excessBytes := []byte{0x03, 0x04}
serializedBytesWithExcess := append(serializedBytes, excessBytes...)
deserializedCert, err := readCertificate(serializedBytesWithExcess)
assert.Nil(err, "Expected no error when deserializing certificate with excess bytes")
assert.Equal(originalCert.Type(), deserializedCert.Type(), "Certificate types should match")
assert.Equal(originalCert.Length(), deserializedCert.Length(), "Certificate lengths should match")
assert.Equal(originalCert.Data(), deserializedCert.Data(), "Certificate payloads should match")
excess := deserializedCert.ExcessBytes()
assert.Equal(excessBytes, excess, "ExcessBytes should return the extra bytes appended to the serialized data")
}
func TestCertificateSerializationDeserializationEmptyPayload(t *testing.T) {
assert := assert.New(t)
payload := []byte{}
certType := CERT_NULL
originalCert, err := NewCertificateWithType(uint8(certType), payload)
assert.Nil(err, "Expected no error when creating NULL certificate")
serializedBytes := originalCert.Bytes()
deserializedCert, err := readCertificate(serializedBytes)
assert.Nil(err, "Expected no error when deserializing NULL certificate")
assert.Equal(originalCert.Type(), deserializedCert.Type(), "Certificate types should match")
assert.Equal(originalCert.Length(), deserializedCert.Length(), "Certificate lengths should match")
assert.Equal(originalCert.Data(), deserializedCert.Data(), "Certificate payloads should match")
}
func TestCertificateSerializationDeserializationMaxPayload(t *testing.T) {
assert := assert.New(t)
payload := make([]byte, 65535)
for i := range payload {
payload[i] = byte(i % 256)
}
certType := CERT_KEY
originalCert, err := NewCertificateWithType(uint8(certType), payload)
assert.Nil(err, "Expected no error when creating KEY certificate with maximum payload")
serializedBytes := originalCert.Bytes()
assert.Equal(1+2+65535, len(serializedBytes), "Serialized bytes length should be correct for maximum payload")
deserializedCert, err := readCertificate(serializedBytes)
assert.Nil(err, "Expected no error when deserializing certificate with maximum payload")
assert.Equal(originalCert.Type(), deserializedCert.Type(), "Certificate types should match")
assert.Equal(originalCert.Length(), deserializedCert.Length(), "Certificate lengths should match")
assert.True(bytes.Equal(originalCert.Data(), deserializedCert.Data()), "Certificate payloads should match")
}

View File

@@ -1,315 +0,0 @@
# data
--
import "github.com/go-i2p/go-i2p/lib/common/data"
![data.svg](data.svg)
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
```go
var (
ErrZeroLength = oops.Errorf("error parsing string: zero length")
ErrDataTooShort = oops.Errorf("string parsing warning: string data is shorter than specified by length")
ErrDataTooLong = oops.Errorf("string parsing warning: string contains data beyond length")
ErrLengthMismatch = oops.Errorf("error reading I2P string, length does not match data")
ErrMappingLengthMismatch = oops.Errorf("warning parsing mapping: mapping length exceeds provided data")
)
```
#### 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 Integer 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
```
data
github.com/go-i2p/go-i2p/lib/common/data

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 139 KiB

View File

@@ -1,87 +0,0 @@
// Package data implements common data structures used in higher level structures.
package data
import (
"time"
"github.com/go-i2p/logger"
"github.com/samber/oops"
"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 = oops.Errorf("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
}

View File

@@ -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")
}

View File

@@ -1,31 +0,0 @@
package data
import (
"fmt"
"github.com/samber/oops"
)
var (
ErrZeroLength = fmt.Errorf("error parsing string: zero length")
ErrDataTooShort = fmt.Errorf("string parsing warning: string data is shorter than specified by length")
ErrDataTooLong = fmt.Errorf("string parsing warning: string contains data beyond length")
ErrLengthMismatch = fmt.Errorf("error reading I2P string, length does not match data")
ErrMappingLengthMismatch = fmt.Errorf("warning parsing mapping: mapping length exceeds provided data")
)
// 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 = oops.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)
}
}

View File

@@ -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
}

View File

@@ -1,78 +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 Integer as a Go integer
func (i Integer) Int() int {
return intFromBytes(i.Bytes())
}
// 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) {
numLen := len(number)
if numLen < MAX_INTEGER_SIZE {
paddedNumber := make([]byte, MAX_INTEGER_SIZE)
copy(paddedNumber[MAX_INTEGER_SIZE-numLen:], number)
number = paddedNumber
}
value = int(binary.BigEndian.Uint64(number))
return
}
// 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, nil
}
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) {
i, remainder := ReadInteger(bytes, size)
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
}

View File

@@ -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")
}

View File

@@ -1,260 +0,0 @@
package data
import (
"github.com/samber/oops"
"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 := oops.Errorf("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)
}
mapping.size = size
if size.Int() == 0 {
log.Warn("Mapping size is zero")
return
}
// Length Check
if len(remainder) < size.Int() {
log.WithFields(logrus.Fields{
"expected_size": size.Int(),
"actual_size": len(remainder),
}).Warn("mapping format violation: mapping length exceeds provided data")
e := oops.Errorf("warning parsing mapping: mapping length exceeds provided data")
err = append(err, e)
// Use whatever data is available (recovery)
map_bytes := remainder
remainder = nil
vals, _, mappingValueErrs := ReadMappingValues(map_bytes, *size)
err = append(err, mappingValueErrs...)
mapping.vals = vals
return
}
// Proceed normally if enough data is present
map_bytes := remainder[:size.Int()]
remainder = remainder[size.Int():]
vals, _, mappingValueErrs := ReadMappingValues(map_bytes, *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 := oops.Errorf("error parsing mapping values")
err = append(err, e)
}
if len(remainder) > 0 { // Handle extra bytes beyond mapping length
log.WithFields(logrus.Fields{
"expected_size": size.Int(),
"actual_size": len(remainder),
}).Error("mapping format violation: data exists beyond length of mapping")
e := oops.Errorf("warning parsing mapping: data exists beyond length of mapping")
err = append(err, e)
// Slice the exact mapping bytes
/* // Don't attempt recovery, can cause panics
map_bytes := remainder[:size.Int()]
remainder = remainder[size.Int():]
vals, _, mappingValueErrs := ReadMappingValues(map_bytes, *size)
err = append(err, mappingValueErrs...)
mapping.vals = vals
*/
return
}
log.WithFields(logrus.Fields{
"mapping_size": 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
}

View File

@@ -1,192 +0,0 @@
package data
import (
"bytes"
"testing"
"github.com/samber/oops"
"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(1, 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(oops.Errorf("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(oops.Errorf("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")
}

View File

@@ -1,224 +0,0 @@
package data
import (
"sort"
"github.com/samber/oops"
"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 {
mappingOrder(values)
// 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{oops.Errorf("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, oops.Errorf("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, oops.Errorf("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, oops.Errorf("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, oops.Errorf("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, oops.Errorf("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
}

View File

@@ -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)
}
}
}
}

View File

@@ -1,191 +0,0 @@
package data
import (
"github.com/samber/oops"
"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 = ErrZeroLength
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 - 1) {
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 = ErrDataTooShort
}
if (str_len - 1) > length {
log.WithFields(logrus.Fields{
"at": "(I2PString) Length",
"string_bytes_length": str_len,
"string_length_field": length,
"reason": "data contains extra bytes beyond specified length",
}).Warn("string format warning")
err = ErrDataTooLong
}
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 {
case ErrZeroLength:
log.WithError(err).Warn("Zero length I2PString")
return "", err
case ErrDataTooShort:
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()
}
*/ //Recovery attempt
return "", err
case ErrDataTooLong:
log.WithError(err).Warn("I2PString contains data beyond specified length")
data = string(str[1:])
// data = string(str[1 : length+1]) // Should we recover and trim?
return
default:
log.WithError(err).Error("Unknown error encountered in I2PString.Data()")
return "", err
}
}
if length == 0 {
log.Debug("I2PString is empty")
return "", nil
}
data = string(str[1 : length+1])
log.WithFields(logrus.Fields{
"data_length": len(data),
}).Debug("Retrieved I2PString data")
return data, nil
}
// 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 = oops.Errorf("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) {
if len(data) == 0 {
err = ErrZeroLength
log.WithError(err).Error("Passed data with len == 0")
return
}
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
if data_len > len(data) {
log.Errorf("I2PString length %d exceeds available data %d", data_len-1, len(data)-1)
err = ErrDataTooShort
log.WithError(err).Error("Failed to read I2PString")
return
}
str = data[:data_len]
remainder = data[data_len:]
l, err := str.Length()
if l != data_len-1 {
err = ErrLengthMismatch
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
}*/

View File

@@ -1,153 +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, 2, "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(), ErrZeroLength.Error(), "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(), ErrDataTooShort.Error(), "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")
*/
assert.Equal(len(str), 0, "ReadI2PString() should not return any data when data is too short")
assert.Equal(len(remainder), 0, "ReadI2PString() should not return any remainder when data is too short")
}

View File

@@ -1,50 +0,0 @@
# destination
--
import "github.com/go-i2p/go-i2p/lib/common/destination"
![destination.svg](destination.svg)
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.
destination
github.com/go-i2p/go-i2p/lib/common/destination

View File

@@ -1,87 +0,0 @@
// Package destination implements the I2P Destination common data structure
package destination
import (
"strings"
"github.com/go-i2p/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")
cert := destination.KeysAndCert.Certificate()
dest := cert.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")
cert := destination.KeysAndCert.Certificate()
dest := cert.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
}

View File

@@ -1,300 +0,0 @@
<?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="357pt" height="609pt"
viewBox="0.00 0.00 356.94 609.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 609)">
<title>gocallvis</title>
<polygon fill="#d3d3d3" stroke="transparent" points="0,0 0,-609 356.9356,-609 356.9356,0 0,0"/>
<g id="clust1" class="cluster">
<title>cluster_focus</title>
<polygon fill="#e6ecfa" stroke="#000000" stroke-width=".5" points="8,-8 8,-601 348.9356,-601 348.9356,-8 8,-8"/>
<text text-anchor="middle" x="178.4678" y="-580.8" font-family="Arial" font-size="18.00" fill="#000000">destination</text>
</g>
<g id="clust6" class="cluster">
<title>cluster_github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination</title>
<g id="a_clust6"><a xlink:title="type: github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination">
<path fill="#b0c4de" stroke="#000000" stroke-width=".5" d="M28,-295C28,-295 131.0814,-295 131.0814,-295 137.0814,-295 143.0814,-301 143.0814,-307 143.0814,-307 143.0814,-422 143.0814,-422 143.0814,-428 137.0814,-434 131.0814,-434 131.0814,-434 28,-434 28,-434 22,-434 16,-428 16,-422 16,-422 16,-307 16,-307 16,-301 22,-295 28,-295"/>
<text text-anchor="middle" x="79.5407" y="-303.5" font-family="Arial" font-size="15.00" fill="#222222">(Destination)</text>
</a>
</g>
</g>
<g id="clust5" class="cluster">
<title>cluster_*github.com/sirupsen/logrus.Logger</title>
<g id="a_clust5"><a xlink:title="type: *github.com/sirupsen/logrus.Logger">
<path fill="#eed8ae" stroke="#000000" stroke-width=".5" d="M249.4047,-121C249.4047,-121 303.7259,-121 303.7259,-121 309.7259,-121 315.7259,-127 315.7259,-133 315.7259,-133 315.7259,-187 315.7259,-187 315.7259,-193 309.7259,-199 303.7259,-199 303.7259,-199 249.4047,-199 249.4047,-199 243.4047,-199 237.4047,-193 237.4047,-187 237.4047,-187 237.4047,-133 237.4047,-133 237.4047,-127 243.4047,-121 249.4047,-121"/>
<text text-anchor="middle" x="276.5653" y="-129.5" font-family="Arial" font-size="15.00" fill="#222222">(*Logger)</text>
</a>
</g>
</g>
<g id="clust4" class="cluster">
<title>cluster_*github.com/go&#45;i2p/logger.Logger</title>
<g id="a_clust4"><a xlink:title="type: *github.com/go&#45;i2p/logger.Logger">
<path fill="#eed8ae" stroke="#000000" stroke-width=".5" d="M236.9559,-260C236.9559,-260 315.1747,-260 315.1747,-260 321.1747,-260 327.1747,-266 327.1747,-272 327.1747,-272 327.1747,-326 327.1747,-326 327.1747,-332 321.1747,-338 315.1747,-338 315.1747,-338 236.9559,-338 236.9559,-338 230.9559,-338 224.9559,-332 224.9559,-326 224.9559,-326 224.9559,-272 224.9559,-272 224.9559,-266 230.9559,-260 236.9559,-260"/>
<text text-anchor="middle" x="276.0653" y="-268.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&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.KeysAndCert</title>
<g id="a_clust3"><a xlink:title="type: *github.com/go&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.KeysAndCert">
<path fill="#eed8ae" stroke="#000000" stroke-width=".5" d="M227.6382,-432C227.6382,-432 324.4924,-432 324.4924,-432 330.4924,-432 336.4924,-438 336.4924,-444 336.4924,-444 336.4924,-498 336.4924,-498 336.4924,-504 330.4924,-510 324.4924,-510 324.4924,-510 227.6382,-510 227.6382,-510 221.6382,-510 215.6382,-504 215.6382,-498 215.6382,-498 215.6382,-444 215.6382,-444 215.6382,-438 221.6382,-432 227.6382,-432"/>
<text text-anchor="middle" x="276.0653" y="-440.5" font-family="Arial" font-size="15.00" fill="#222222">(*KeysAndCert)</text>
</a>
</g>
</g>
<g id="clust2" class="cluster">
<title>cluster_*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate</title>
<g id="a_clust2"><a xlink:title="type: *github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate">
<path fill="#eed8ae" stroke="#000000" stroke-width=".5" d="M239.087,-346C239.087,-346 314.0436,-346 314.0436,-346 320.0436,-346 326.0436,-352 326.0436,-358 326.0436,-358 326.0436,-412 326.0436,-412 326.0436,-418 320.0436,-424 314.0436,-424 314.0436,-424 239.087,-424 239.087,-424 233.087,-424 227.087,-418 227.087,-412 227.087,-412 227.087,-358 227.087,-358 227.087,-352 233.087,-346 239.087,-346"/>
<text text-anchor="middle" x="276.5653" y="-354.5" font-family="Arial" font-size="15.00" fill="#222222">(*Certificate)</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.ReadDestination -->
<g id="node1" class="node">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.ReadDestination</title>
<g id="a_node1"><a xlink:title="github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.ReadDestination | defined in destination.go:72&#10;at destination.go:77: calling [github.com/go&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.ReadKeysAndCert]&#10;at destination.go:75: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at destination.go:84: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at destination.go:73: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]&#10;at destination.go:82: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="#add8e6" stroke="#000000" stroke-width="1.5" d="M126.3497,-191C126.3497,-191 32.7317,-191 32.7317,-191 26.7317,-191 20.7317,-185 20.7317,-179 20.7317,-179 20.7317,-167 20.7317,-167 20.7317,-161 26.7317,-155 32.7317,-155 32.7317,-155 126.3497,-155 126.3497,-155 132.3497,-155 138.3497,-161 138.3497,-167 138.3497,-167 138.3497,-179 138.3497,-179 138.3497,-185 132.3497,-191 126.3497,-191"/>
<text text-anchor="middle" x="79.5407" y="-168.8" font-family="Verdana" font-size="14.00" fill="#000000">ReadDestination</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.ReadKeysAndCert -->
<g id="node2" class="node">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.ReadKeysAndCert</title>
<g id="a_node2"><a xlink:title="github.com/go&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.ReadKeysAndCert | defined in keys_and_cert.go:142">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M328.8062,-113C328.8062,-113 223.3244,-113 223.3244,-113 217.3244,-113 211.3244,-107 211.3244,-101 211.3244,-101 211.3244,-89 211.3244,-89 211.3244,-83 217.3244,-77 223.3244,-77 223.3244,-77 328.8062,-77 328.8062,-77 334.8062,-77 340.8062,-83 340.8062,-89 340.8062,-89 340.8062,-101 340.8062,-101 340.8062,-107 334.8062,-113 328.8062,-113"/>
<text text-anchor="middle" x="276.0653" y="-99.2" font-family="Verdana" font-size="14.00" fill="#000000">keys_and_cert</text>
<text text-anchor="middle" x="276.0653" y="-82.4" font-family="Verdana" font-size="14.00" fill="#000000">ReadKeysAndCert</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.ReadDestination&#45;&gt;github.com/go&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.ReadKeysAndCert -->
<g id="edge1" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.ReadDestination&#45;&gt;github.com/go&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.ReadKeysAndCert</title>
<g id="a_edge1"><a xlink:title="at destination.go:77: calling [github.com/go&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.ReadKeysAndCert]">
<path fill="none" stroke="#8b4513" d="M119.8466,-154.9251C145.7433,-143.5438 180.215,-128.8228 211.195,-117 211.5179,-116.8768 211.8418,-116.7535 212.1667,-116.6302"/>
<polygon fill="#8b4513" stroke="#8b4513" points="213.6372,-119.8181 221.8003,-113.0642 211.2071,-113.2534 213.6372,-119.8181"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/logger.Logger).WithFields -->
<g id="node9" class="node">
<title>(*github.com/go&#45;i2p/logger.Logger).WithFields</title>
<g id="a_node9"><a xlink:title="(*github.com/go&#45;i2p/logger.Logger).WithFields | defined in log.go:60">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M307.2844,-330C307.2844,-330 244.8462,-330 244.8462,-330 238.8462,-330 232.8462,-324 232.8462,-318 232.8462,-318 232.8462,-306 232.8462,-306 232.8462,-300 238.8462,-294 244.8462,-294 244.8462,-294 307.2844,-294 307.2844,-294 313.2844,-294 319.2844,-300 319.2844,-306 319.2844,-306 319.2844,-318 319.2844,-318 319.2844,-324 313.2844,-330 307.2844,-330"/>
<text text-anchor="middle" x="276.0653" y="-316.2" font-family="Verdana" font-size="14.00" fill="#000000">logger</text>
<text text-anchor="middle" x="276.0653" y="-299.4" font-family="Verdana" font-size="14.00" fill="#000000">WithFields</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.ReadDestination&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields -->
<g id="edge13" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.ReadDestination&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields</title>
<g id="a_edge13"><a xlink:title="at destination.go:73: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]&#10;at destination.go:82: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="none" stroke="#8b4513" d="M95.6552,-191.3454C118.8737,-216.761 164.144,-262.6371 211.195,-290 215.0581,-292.2466 219.1849,-294.3077 223.4146,-296.1894"/>
<polygon fill="#8b4513" stroke="#8b4513" points="222.196,-299.4724 232.7765,-300.0243 224.8495,-292.9948 222.196,-299.4724"/>
</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="M294.8873,-191C294.8873,-191 257.2433,-191 257.2433,-191 251.2433,-191 245.2433,-185 245.2433,-179 245.2433,-179 245.2433,-167 245.2433,-167 245.2433,-161 251.2433,-155 257.2433,-155 257.2433,-155 294.8873,-155 294.8873,-155 300.8873,-155 306.8873,-161 306.8873,-167 306.8873,-167 306.8873,-179 306.8873,-179 306.8873,-185 300.8873,-191 294.8873,-191"/>
<text text-anchor="middle" x="276.0653" y="-177.2" font-family="Verdana" font-size="14.00" fill="#000000">logrus</text>
<text text-anchor="middle" x="276.0653" y="-160.4" font-family="Verdana" font-size="14.00" fill="#000000">Debug</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.ReadDestination&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug -->
<g id="edge4" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.ReadDestination&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug</title>
<g id="a_edge4"><a xlink:title="at destination.go:75: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at destination.go:84: calling [(*github.com/sirupsen/logrus.Logger).Debug]">
<path fill="none" stroke="#8b4513" d="M138.2384,-173C169.429,-173 207.0043,-173 235.0381,-173"/>
<polygon fill="#8b4513" stroke="#8b4513" points="235.282,-176.5001 245.282,-173 235.2819,-169.5001 235.282,-176.5001"/>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.init -->
<g id="node3" class="node">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.init</title>
<g id="a_node3"><a xlink:title="github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.init | defined in .:0&#10;at destination.go:17: calling [github.com/go&#45;i2p/logger.GetGoI2PLogger]">
<path fill="#add8e6" stroke="#000000" stroke-width=".5" d="M94.5407,-52C94.5407,-52 64.5407,-52 64.5407,-52 58.5407,-52 52.5407,-46 52.5407,-40 52.5407,-40 52.5407,-28 52.5407,-28 52.5407,-22 58.5407,-16 64.5407,-16 64.5407,-16 94.5407,-16 94.5407,-16 100.5407,-16 106.5407,-22 106.5407,-28 106.5407,-28 106.5407,-40 106.5407,-40 106.5407,-46 100.5407,-52 94.5407,-52"/>
<text text-anchor="middle" x="79.5407" y="-29.8" font-family="Verdana" font-size="14.00" fill="#000000">init</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/logger.GetGoI2PLogger -->
<g id="node4" class="node">
<title>github.com/go&#45;i2p/logger.GetGoI2PLogger</title>
<g id="a_node4"><a xlink:title="github.com/go&#45;i2p/logger.GetGoI2PLogger | defined in log.go:120">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M324.7548,-52C324.7548,-52 227.3758,-52 227.3758,-52 221.3758,-52 215.3758,-46 215.3758,-40 215.3758,-40 215.3758,-28 215.3758,-28 215.3758,-22 221.3758,-16 227.3758,-16 227.3758,-16 324.7548,-16 324.7548,-16 330.7548,-16 336.7548,-22 336.7548,-28 336.7548,-28 336.7548,-40 336.7548,-40 336.7548,-46 330.7548,-52 324.7548,-52"/>
<text text-anchor="middle" x="276.0653" y="-38.2" font-family="Verdana" font-size="14.00" fill="#000000">logger</text>
<text text-anchor="middle" x="276.0653" y="-21.4" font-family="Verdana" font-size="14.00" fill="#000000">GetGoI2PLogger</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.init&#45;&gt;github.com/go&#45;i2p/logger.GetGoI2PLogger -->
<g id="edge14" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.init&#45;&gt;github.com/go&#45;i2p/logger.GetGoI2PLogger</title>
<g id="a_edge14"><a xlink:title="at destination.go:17: calling [github.com/go&#45;i2p/logger.GetGoI2PLogger]">
<path fill="none" stroke="#8b4513" d="M106.8666,-34C132.1954,-34 170.9888,-34 205.043,-34"/>
<polygon fill="#8b4513" stroke="#8b4513" points="205.4392,-37.5001 215.4392,-34 205.4392,-30.5001 205.4392,-37.5001"/>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/base32.EncodeToString -->
<g id="node5" class="node">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/base32.EncodeToString</title>
<g id="a_node5"><a xlink:title="github.com/go&#45;i2p/go&#45;i2p/lib/common/base32.EncodeToString | defined in base32.go:16">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M321.8244,-563C321.8244,-563 230.3062,-563 230.3062,-563 224.3062,-563 218.3062,-557 218.3062,-551 218.3062,-551 218.3062,-539 218.3062,-539 218.3062,-533 224.3062,-527 230.3062,-527 230.3062,-527 321.8244,-527 321.8244,-527 327.8244,-527 333.8244,-533 333.8244,-539 333.8244,-539 333.8244,-551 333.8244,-551 333.8244,-557 327.8244,-563 321.8244,-563"/>
<text text-anchor="middle" x="276.0653" y="-549.2" font-family="Verdana" font-size="14.00" fill="#000000">base32</text>
<text text-anchor="middle" x="276.0653" y="-532.4" font-family="Verdana" font-size="14.00" fill="#000000">EncodeToString</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/base64.EncodeToString -->
<g id="node6" class="node">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/base64.EncodeToString</title>
<g id="a_node6"><a xlink:title="github.com/go&#45;i2p/go&#45;i2p/lib/common/base64.EncodeToString | defined in base64.go:16">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M321.8244,-252C321.8244,-252 230.3062,-252 230.3062,-252 224.3062,-252 218.3062,-246 218.3062,-240 218.3062,-240 218.3062,-228 218.3062,-228 218.3062,-222 224.3062,-216 230.3062,-216 230.3062,-216 321.8244,-216 321.8244,-216 327.8244,-216 333.8244,-222 333.8244,-228 333.8244,-228 333.8244,-240 333.8244,-240 333.8244,-246 327.8244,-252 321.8244,-252"/>
<text text-anchor="middle" x="276.0653" y="-238.2" font-family="Verdana" font-size="14.00" fill="#000000">base64</text>
<text text-anchor="middle" x="276.0653" y="-221.4" font-family="Verdana" font-size="14.00" fill="#000000">EncodeToString</text>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes -->
<g id="node7" class="node">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes</title>
<g id="a_node7"><a xlink:title="(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes | defined in certificate.go:100">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M304.0219,-416C304.0219,-416 248.1087,-416 248.1087,-416 242.1087,-416 236.1087,-410 236.1087,-404 236.1087,-404 236.1087,-392 236.1087,-392 236.1087,-386 242.1087,-380 248.1087,-380 248.1087,-380 304.0219,-380 304.0219,-380 310.0219,-380 316.0219,-386 316.0219,-392 316.0219,-392 316.0219,-404 316.0219,-404 316.0219,-410 310.0219,-416 304.0219,-416"/>
<text text-anchor="middle" x="276.0653" y="-402.2" font-family="Verdana" font-size="14.00" fill="#000000">certificate</text>
<text text-anchor="middle" x="276.0653" y="-385.4" font-family="Verdana" font-size="14.00" fill="#000000">Bytes</text>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.KeysAndCert).Certificate -->
<g id="node8" class="node">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.KeysAndCert).Certificate</title>
<g id="a_node8"><a xlink:title="(*github.com/go&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.KeysAndCert).Certificate | defined in keys_and_cert.go:136">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M316.4196,-502C316.4196,-502 235.711,-502 235.711,-502 229.711,-502 223.711,-496 223.711,-490 223.711,-490 223.711,-478 223.711,-478 223.711,-472 229.711,-466 235.711,-466 235.711,-466 316.4196,-466 316.4196,-466 322.4196,-466 328.4196,-472 328.4196,-478 328.4196,-478 328.4196,-490 328.4196,-490 328.4196,-496 322.4196,-502 316.4196,-502"/>
<text text-anchor="middle" x="276.0653" y="-488.2" font-family="Verdana" font-size="14.00" fill="#000000">keys_and_cert</text>
<text text-anchor="middle" x="276.0653" y="-471.4" font-family="Verdana" font-size="14.00" fill="#000000">Certificate</text>
</a>
</g>
</g>
<!-- (github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address -->
<g id="node11" class="node">
<title>(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address</title>
<g id="a_node11"><a xlink:title="(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address | defined in destination.go:38&#10;at destination.go:42: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes]&#10;at destination.go:41: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.KeysAndCert).Certificate]&#10;at destination.go:39: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at destination.go:49: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at destination.go:44: calling [github.com/go&#45;i2p/go&#45;i2p/lib/common/base32.EncodeToString]&#10;at destination.go:47: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="#add8e6" stroke="#000000" stroke-width="1.5" d="M123.1221,-426C123.1221,-426 35.9593,-426 35.9593,-426 29.9593,-426 23.9593,-420 23.9593,-414 23.9593,-414 23.9593,-402 23.9593,-402 23.9593,-396 29.9593,-390 35.9593,-390 35.9593,-390 123.1221,-390 123.1221,-390 129.1221,-390 135.1221,-396 135.1221,-402 135.1221,-402 135.1221,-414 135.1221,-414 135.1221,-420 129.1221,-426 123.1221,-426"/>
<text text-anchor="middle" x="79.5407" y="-403.8" font-family="Verdana" font-size="14.00" fill="#000000">Base32Address</text>
</a>
</g>
</g>
<!-- (github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address&#45;&gt;github.com/go&#45;i2p/go&#45;i2p/lib/common/base32.EncodeToString -->
<g id="edge9" class="edge">
<title>(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address&#45;&gt;github.com/go&#45;i2p/go&#45;i2p/lib/common/base32.EncodeToString</title>
<g id="a_edge9"><a xlink:title="at destination.go:44: calling [github.com/go&#45;i2p/go&#45;i2p/lib/common/base32.EncodeToString]">
<path fill="none" stroke="#8b4513" d="M98.3658,-426.2155C122.8623,-449.2395 167.6924,-489.1061 211.195,-516 214.7364,-518.1894 218.4716,-520.3055 222.2878,-522.3296"/>
<polygon fill="#8b4513" stroke="#8b4513" points="220.7827,-525.4905 231.2865,-526.8769 223.9399,-519.2429 220.7827,-525.4905"/>
</a>
</g>
</g>
<!-- (github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes -->
<g id="edge2" class="edge">
<title>(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes</title>
<g id="a_edge2"><a xlink:title="at destination.go:42: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes]">
<path fill="none" stroke="#8b4513" d="M135.3003,-423.7554C148.355,-425.819 162.2348,-426.7045 175.195,-425 192.0147,-422.7879 210.016,-418.5853 226.0877,-414.143"/>
<polygon fill="#8b4513" stroke="#8b4513" points="227.1646,-417.4754 235.8175,-411.3617 225.2406,-410.745 227.1646,-417.4754"/>
</a>
</g>
</g>
<!-- (github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.KeysAndCert).Certificate -->
<g id="edge5" class="edge">
<title>(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.KeysAndCert).Certificate</title>
<g id="a_edge5"><a xlink:title="at destination.go:41: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.KeysAndCert).Certificate]">
<path fill="none" stroke="#8b4513" d="M126.1143,-426.0109C154.2801,-436.9032 190.3668,-450.8587 220.0806,-462.3496"/>
<polygon fill="#8b4513" stroke="#8b4513" points="218.8966,-465.6443 229.4859,-465.9868 221.4214,-459.1155 218.8966,-465.6443"/>
</a>
</g>
</g>
<!-- (github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields -->
<g id="edge10" class="edge">
<title>(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields</title>
<g id="a_edge10"><a xlink:title="at destination.go:47: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="none" stroke="#8b4513" d="M135.4607,-410.5532C149.2676,-408.9965 163.4512,-405.3584 175.195,-398 200.9047,-381.8908 188.214,-359.8083 211.195,-340 215.0451,-336.6814 219.3484,-333.7036 223.8574,-331.0431"/>
<polygon fill="#8b4513" stroke="#8b4513" points="225.5446,-334.1099 232.7168,-326.3118 222.247,-327.9353 225.5446,-334.1099"/>
</a>
</g>
</g>
<!-- (github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug -->
<g id="edge8" class="edge">
<title>(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug</title>
<g id="a_edge8"><a xlink:title="at destination.go:39: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at destination.go:49: calling [(*github.com/sirupsen/logrus.Logger).Debug]">
<path fill="none" stroke="#8b4513" d="M128.4239,-389.9118C133.8188,-386.5287 138.8725,-382.5818 143.0814,-378 201.7913,-314.0883 148.9351,-255.4587 211.195,-195 217.9616,-188.4291 226.762,-183.8181 235.6865,-180.5832"/>
<polygon fill="#8b4513" stroke="#8b4513" points="236.8188,-183.8965 245.3289,-177.5856 234.7406,-177.2121 236.8188,-183.8965"/>
</a>
</g>
</g>
<!-- (github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64 -->
<g id="node12" class="node">
<title>(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64</title>
<g id="a_node12"><a xlink:title="(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64 | defined in destination.go:55&#10;at destination.go:59: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes]&#10;at destination.go:58: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.KeysAndCert).Certificate]&#10;at destination.go:60: calling [github.com/go&#45;i2p/go&#45;i2p/lib/common/base64.EncodeToString]&#10;at destination.go:56: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at destination.go:64: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at destination.go:62: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="#add8e6" stroke="#000000" stroke-width="1.5" d="M100.2514,-365C100.2514,-365 58.83,-365 58.83,-365 52.83,-365 46.83,-359 46.83,-353 46.83,-353 46.83,-341 46.83,-341 46.83,-335 52.83,-329 58.83,-329 58.83,-329 100.2514,-329 100.2514,-329 106.2514,-329 112.2514,-335 112.2514,-341 112.2514,-341 112.2514,-353 112.2514,-353 112.2514,-359 106.2514,-365 100.2514,-365"/>
<text text-anchor="middle" x="79.5407" y="-342.8" font-family="Verdana" font-size="14.00" fill="#000000">Base64</text>
</a>
</g>
</g>
<!-- (github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64&#45;&gt;github.com/go&#45;i2p/go&#45;i2p/lib/common/base64.EncodeToString -->
<g id="edge7" class="edge">
<title>(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64&#45;&gt;github.com/go&#45;i2p/go&#45;i2p/lib/common/base64.EncodeToString</title>
<g id="a_edge7"><a xlink:title="at destination.go:60: calling [github.com/go&#45;i2p/go&#45;i2p/lib/common/base64.EncodeToString]">
<path fill="none" stroke="#8b4513" d="M112.1939,-338.8592C122.5317,-335.4699 133.7005,-330.9153 143.0814,-325 176.9686,-303.632 175.1512,-282.1226 209.631,-257.6621"/>
<polygon fill="#8b4513" stroke="#8b4513" points="211.6947,-260.4935 218.1081,-252.0603 207.8355,-254.6534 211.6947,-260.4935"/>
</a>
</g>
</g>
<!-- (github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes -->
<g id="edge3" class="edge">
<title>(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes</title>
<g id="a_edge3"><a xlink:title="at destination.go:59: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Bytes]">
<path fill="none" stroke="#8b4513" d="M112.2576,-348.1387C130.9214,-349.3528 154.6235,-351.8541 175.195,-357 193.2842,-361.5249 212.4093,-368.65 229.0864,-375.6996"/>
<polygon fill="#8b4513" stroke="#8b4513" points="228.0292,-379.056 238.5963,-379.8214 230.8129,-372.6333 228.0292,-379.056"/>
</a>
</g>
</g>
<!-- (github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.KeysAndCert).Certificate -->
<g id="edge6" class="edge">
<title>(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.KeysAndCert).Certificate</title>
<g id="a_edge6"><a xlink:title="at destination.go:58: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/keys_and_cert.KeysAndCert).Certificate]">
<path fill="none" stroke="#8b4513" d="M112.2798,-361.284C122.4063,-366.1451 133.4308,-371.9033 143.0814,-378 163.9636,-391.1922 214.3577,-432.4214 246.7655,-459.4025"/>
<polygon fill="#8b4513" stroke="#8b4513" points="244.6676,-462.2104 254.5883,-465.9293 249.1521,-456.8354 244.6676,-462.2104"/>
</a>
</g>
</g>
<!-- (github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields -->
<g id="edge12" class="edge">
<title>(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64&#45;&gt;(*github.com/go&#45;i2p/logger.Logger).WithFields</title>
<g id="a_edge12"><a xlink:title="at destination.go:62: calling [(*github.com/go&#45;i2p/logger.Logger).WithFields]">
<path fill="none" stroke="#8b4513" d="M112.3907,-341.0766C130.5996,-337.7992 153.6485,-333.6603 174.195,-330 190.0047,-327.1835 207.1979,-324.1387 222.8796,-321.3685"/>
<polygon fill="#8b4513" stroke="#8b4513" points="223.6975,-324.7783 232.9366,-319.5929 222.4804,-317.8849 223.6975,-324.7783"/>
</a>
</g>
</g>
<!-- (github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug -->
<g id="edge11" class="edge">
<title>(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64&#45;&gt;(*github.com/sirupsen/logrus.Logger).Debug</title>
<g id="a_edge11"><a xlink:title="at destination.go:56: calling [(*github.com/sirupsen/logrus.Logger).Debug]&#10;at destination.go:64: calling [(*github.com/sirupsen/logrus.Logger).Debug]">
<path fill="none" stroke="#8b4513" d="M112.3191,-341.1468C123.1386,-337.8792 134.5697,-332.8178 143.0814,-325 168.1559,-301.9697 158.3099,-285.1129 174.195,-255 188.8126,-227.2898 186.6888,-214.5186 211.195,-195 218.2916,-189.3477 226.9195,-185.1105 235.5357,-181.9469"/>
<polygon fill="#8b4513" stroke="#8b4513" points="236.7484,-185.2331 245.1766,-178.8131 234.5844,-178.5759 236.7484,-185.2331"/>
</a>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -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"]

View File

@@ -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

View File

@@ -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

View File

@@ -1,21 +0,0 @@
# exportable
--
import "github.com/go-i2p/go-i2p/lib/common/fuzz/certificate"
![exportable.svg](exportable.svg)
## Usage
#### func Fuzz
```go
func Fuzz(data []byte) int
```
exportable
github.com/go-i2p/go-i2p/lib/common/fuzz/certificate

View File

@@ -1 +0,0 @@


View File

@@ -1,111 +0,0 @@
<?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="272pt" height="306pt"
viewBox="0.00 0.00 271.84 306.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 306)">
<title>gocallvis</title>
<polygon fill="#d3d3d3" stroke="transparent" points="0,0 0,-306 271.8444,-306 271.8444,0 0,0"/>
<g id="clust1" class="cluster">
<title>cluster_focus</title>
<polygon fill="#e6ecfa" stroke="#000000" stroke-width=".5" points="8,-8 8,-298 263.8444,-298 263.8444,-8 8,-8"/>
<text text-anchor="middle" x="135.9222" y="-277.8" font-family="Arial" font-size="18.00" fill="#000000">exportable</text>
</g>
<g id="clust2" class="cluster">
<title>cluster_*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate</title>
<g id="a_clust2"><a xlink:title="type: *github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate">
<path fill="#eed8ae" stroke="#000000" stroke-width=".5" d="M162.9439,-60C162.9439,-60 237.9005,-60 237.9005,-60 243.9005,-60 249.9005,-66 249.9005,-72 249.9005,-72 249.9005,-248 249.9005,-248 249.9005,-254 243.9005,-260 237.9005,-260 237.9005,-260 162.9439,-260 162.9439,-260 156.9439,-260 150.9439,-254 150.9439,-248 150.9439,-248 150.9439,-72 150.9439,-72 150.9439,-66 156.9439,-60 162.9439,-60"/>
<text text-anchor="middle" x="200.4222" y="-68.5" font-family="Arial" font-size="15.00" fill="#222222">(*Certificate)</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/certificate.Fuzz -->
<g id="node1" class="node">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/certificate.Fuzz</title>
<g id="a_node1"><a xlink:title="github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/certificate.Fuzz | defined in fuzz.go:5&#10;at fuzz.go:6: calling [github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate]&#10;at fuzz.go:7: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data]&#10;at fuzz.go:8: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length]&#10;at fuzz.go:9: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type]">
<path fill="#add8e6" stroke="#000000" stroke-width="1.5" d="M58,-160C58,-160 28,-160 28,-160 22,-160 16,-154 16,-148 16,-148 16,-136 16,-136 16,-130 22,-124 28,-124 28,-124 58,-124 58,-124 64,-124 70,-130 70,-136 70,-136 70,-148 70,-148 70,-154 64,-160 58,-160"/>
<text text-anchor="middle" x="43" y="-137.8" font-family="Verdana" font-size="14.00" fill="#000000">Fuzz</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate -->
<g id="node2" class="node">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate</title>
<g id="a_node2"><a xlink:title="github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate | defined in certificate.go:201">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M243.7667,-52C243.7667,-52 156.0777,-52 156.0777,-52 150.0777,-52 144.0777,-46 144.0777,-40 144.0777,-40 144.0777,-28 144.0777,-28 144.0777,-22 150.0777,-16 156.0777,-16 156.0777,-16 243.7667,-16 243.7667,-16 249.7667,-16 255.7667,-22 255.7667,-28 255.7667,-28 255.7667,-40 255.7667,-40 255.7667,-46 249.7667,-52 243.7667,-52"/>
<text text-anchor="middle" x="199.9222" y="-38.2" font-family="Verdana" font-size="14.00" fill="#000000">certificate</text>
<text text-anchor="middle" x="199.9222" y="-21.4" font-family="Verdana" font-size="14.00" fill="#000000">ReadCertificate</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/certificate.Fuzz&#45;&gt;github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate -->
<g id="edge1" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/certificate.Fuzz&#45;&gt;github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate</title>
<g id="a_edge1"><a xlink:title="at fuzz.go:6: calling [github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.ReadCertificate]">
<path fill="none" stroke="#8b4513" d="M60.5563,-123.8395C78.2431,-106.2965 107.1045,-79.6361 142.3601,-57.393"/>
<polygon fill="#8b4513" stroke="#8b4513" points="144.2536,-60.3376 150.9601,-52.1355 140.6025,-54.3652 144.2536,-60.3376"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data -->
<g id="node3" class="node">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data</title>
<g id="a_node3"><a xlink:title="(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data | defined in certificate.go:134">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M227.8788,-130C227.8788,-130 171.9656,-130 171.9656,-130 165.9656,-130 159.9656,-124 159.9656,-118 159.9656,-118 159.9656,-106 159.9656,-106 159.9656,-100 165.9656,-94 171.9656,-94 171.9656,-94 227.8788,-94 227.8788,-94 233.8788,-94 239.8788,-100 239.8788,-106 239.8788,-106 239.8788,-118 239.8788,-118 239.8788,-124 233.8788,-130 227.8788,-130"/>
<text text-anchor="middle" x="199.9222" y="-116.2" font-family="Verdana" font-size="14.00" fill="#000000">certificate</text>
<text text-anchor="middle" x="199.9222" y="-99.4" font-family="Verdana" font-size="14.00" fill="#000000">Data</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/certificate.Fuzz&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data -->
<g id="edge2" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/certificate.Fuzz&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data</title>
<g id="a_edge2"><a xlink:title="at fuzz.go:7: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Data]">
<path fill="none" stroke="#8b4513" d="M70.3338,-136.7744C92.2913,-132.5766 123.7111,-126.5699 150.1132,-121.5224"/>
<polygon fill="#8b4513" stroke="#8b4513" points="150.7913,-124.9562 159.9562,-119.6406 149.4768,-118.0807 150.7913,-124.9562"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length -->
<g id="node4" class="node">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length</title>
<g id="a_node4"><a xlink:title="(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length | defined in certificate.go:125">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M227.8788,-191C227.8788,-191 171.9656,-191 171.9656,-191 165.9656,-191 159.9656,-185 159.9656,-179 159.9656,-179 159.9656,-167 159.9656,-167 159.9656,-161 165.9656,-155 171.9656,-155 171.9656,-155 227.8788,-155 227.8788,-155 233.8788,-155 239.8788,-161 239.8788,-167 239.8788,-167 239.8788,-179 239.8788,-179 239.8788,-185 233.8788,-191 227.8788,-191"/>
<text text-anchor="middle" x="199.9222" y="-177.2" font-family="Verdana" font-size="14.00" fill="#000000">certificate</text>
<text text-anchor="middle" x="199.9222" y="-160.4" font-family="Verdana" font-size="14.00" fill="#000000">Length</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/certificate.Fuzz&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length -->
<g id="edge3" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/certificate.Fuzz&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length</title>
<g id="a_edge3"><a xlink:title="at fuzz.go:8: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Length]">
<path fill="none" stroke="#8b4513" d="M70.3338,-147.3998C92.2913,-151.7375 123.7111,-157.9445 150.1132,-163.1602"/>
<polygon fill="#8b4513" stroke="#8b4513" points="149.4674,-166.6002 159.9562,-165.1047 150.8241,-159.7329 149.4674,-166.6002"/>
</a>
</g>
</g>
<!-- (*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type -->
<g id="node5" class="node">
<title>(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type</title>
<g id="a_node5"><a xlink:title="(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type | defined in certificate.go:116">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M227.8788,-252C227.8788,-252 171.9656,-252 171.9656,-252 165.9656,-252 159.9656,-246 159.9656,-240 159.9656,-240 159.9656,-228 159.9656,-228 159.9656,-222 165.9656,-216 171.9656,-216 171.9656,-216 227.8788,-216 227.8788,-216 233.8788,-216 239.8788,-222 239.8788,-228 239.8788,-228 239.8788,-240 239.8788,-240 239.8788,-246 233.8788,-252 227.8788,-252"/>
<text text-anchor="middle" x="199.9222" y="-238.2" font-family="Verdana" font-size="14.00" fill="#000000">certificate</text>
<text text-anchor="middle" x="199.9222" y="-221.4" font-family="Verdana" font-size="14.00" fill="#000000">Type</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/certificate.Fuzz&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type -->
<g id="edge4" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/certificate.Fuzz&#45;&gt;(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type</title>
<g id="a_edge4"><a xlink:title="at fuzz.go:9: calling [(*github.com/go&#45;i2p/go&#45;i2p/lib/common/certificate.Certificate).Type]">
<path fill="none" stroke="#8b4513" d="M70.1769,-159.2759C90.3621,-171.9616 118.6668,-189.4457 144,-204 148.084,-206.3463 152.3634,-208.7456 156.6592,-211.1147"/>
<polygon fill="#8b4513" stroke="#8b4513" points="154.9879,-214.1898 165.4424,-215.9086 158.3415,-208.0455 154.9879,-214.1898"/>
</a>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 9.6 KiB

View File

@@ -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
}

View File

@@ -1,21 +0,0 @@
# exportable
--
import "github.com/go-i2p/go-i2p/lib/common/fuzz/destination"
![exportable.svg](exportable.svg)
## Usage
#### func Fuzz
```go
func Fuzz(data []byte) int
```
exportable
github.com/go-i2p/go-i2p/lib/common/fuzz/destination

View File

@@ -1,92 +0,0 @@
<?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="281pt" height="245pt"
viewBox="0.00 0.00 281.19 245.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 245)">
<title>gocallvis</title>
<polygon fill="#d3d3d3" stroke="transparent" points="0,0 0,-245 281.195,-245 281.195,0 0,0"/>
<g id="clust1" class="cluster">
<title>cluster_focus</title>
<polygon fill="#e6ecfa" stroke="#000000" stroke-width=".5" points="8,-8 8,-237 273.195,-237 273.195,-8 8,-8"/>
<text text-anchor="middle" x="140.5975" y="-216.8" font-family="Arial" font-size="18.00" fill="#000000">exportable</text>
</g>
<g id="clust2" class="cluster">
<title>cluster_github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination</title>
<g id="a_clust2"><a xlink:title="type: github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination">
<path fill="#eed8ae" stroke="#000000" stroke-width=".5" d="M150.1136,-60C150.1136,-60 253.195,-60 253.195,-60 259.195,-60 265.195,-66 265.195,-72 265.195,-72 265.195,-187 265.195,-187 265.195,-193 259.195,-199 253.195,-199 253.195,-199 150.1136,-199 150.1136,-199 144.1136,-199 138.1136,-193 138.1136,-187 138.1136,-187 138.1136,-72 138.1136,-72 138.1136,-66 144.1136,-60 150.1136,-60"/>
<text text-anchor="middle" x="201.6543" y="-68.5" font-family="Arial" font-size="15.00" fill="#222222">(Destination)</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/destination.Fuzz -->
<g id="node1" class="node">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/destination.Fuzz</title>
<g id="a_node1"><a xlink:title="github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/destination.Fuzz | defined in fuzz.go:5&#10;at fuzz.go:6: calling [github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.ReadDestination]&#10;at fuzz.go:7: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address]&#10;at fuzz.go:8: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64]">
<path fill="#add8e6" stroke="#000000" stroke-width="1.5" d="M58,-130C58,-130 28,-130 28,-130 22,-130 16,-124 16,-118 16,-118 16,-106 16,-106 16,-100 22,-94 28,-94 28,-94 58,-94 58,-94 64,-94 70,-100 70,-106 70,-106 70,-118 70,-118 70,-124 64,-130 58,-130"/>
<text text-anchor="middle" x="43" y="-107.8" font-family="Verdana" font-size="14.00" fill="#000000">Fuzz</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.ReadDestination -->
<g id="node2" class="node">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.ReadDestination</title>
<g id="a_node2"><a xlink:title="github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.ReadDestination | defined in destination.go:72">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M248.4633,-52C248.4633,-52 154.8453,-52 154.8453,-52 148.8453,-52 142.8453,-46 142.8453,-40 142.8453,-40 142.8453,-28 142.8453,-28 142.8453,-22 148.8453,-16 154.8453,-16 154.8453,-16 248.4633,-16 248.4633,-16 254.4633,-16 260.4633,-22 260.4633,-28 260.4633,-28 260.4633,-40 260.4633,-40 260.4633,-46 254.4633,-52 248.4633,-52"/>
<text text-anchor="middle" x="201.6543" y="-38.2" font-family="Verdana" font-size="14.00" fill="#000000">destination</text>
<text text-anchor="middle" x="201.6543" y="-21.4" font-family="Verdana" font-size="14.00" fill="#000000">ReadDestination</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/destination.Fuzz&#45;&gt;github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.ReadDestination -->
<g id="edge1" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/destination.Fuzz&#45;&gt;github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.ReadDestination</title>
<g id="a_edge1"><a xlink:title="at fuzz.go:6: calling [github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.ReadDestination]">
<path fill="none" stroke="#8b4513" d="M70.1001,-94.0845C88.7169,-82.2726 114.281,-67.0087 138.1136,-56 138.2063,-55.9572 138.2992,-55.9144 138.3921,-55.8716"/>
<polygon fill="#8b4513" stroke="#8b4513" points="139.5119,-59.2012 147.2891,-52.0063 136.7226,-52.7809 139.5119,-59.2012"/>
</a>
</g>
</g>
<!-- (github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address -->
<g id="node3" class="node">
<title>(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address</title>
<g id="a_node3"><a xlink:title="(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address | defined in destination.go:38">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M245.2357,-130C245.2357,-130 158.0729,-130 158.0729,-130 152.0729,-130 146.0729,-124 146.0729,-118 146.0729,-118 146.0729,-106 146.0729,-106 146.0729,-100 152.0729,-94 158.0729,-94 158.0729,-94 245.2357,-94 245.2357,-94 251.2357,-94 257.2357,-100 257.2357,-106 257.2357,-106 257.2357,-118 257.2357,-118 257.2357,-124 251.2357,-130 245.2357,-130"/>
<text text-anchor="middle" x="201.6543" y="-116.2" font-family="Verdana" font-size="14.00" fill="#000000">destination</text>
<text text-anchor="middle" x="201.6543" y="-99.4" font-family="Verdana" font-size="14.00" fill="#000000">Base32Address</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/destination.Fuzz&#45;&gt;(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address -->
<g id="edge2" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/destination.Fuzz&#45;&gt;(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address</title>
<g id="a_edge2"><a xlink:title="at fuzz.go:7: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base32Address]">
<path fill="none" stroke="#8b4513" d="M70.2736,-112C88.3329,-112 112.8362,-112 135.7903,-112"/>
<polygon fill="#8b4513" stroke="#8b4513" points="135.853,-115.5001 145.853,-112 135.8529,-108.5001 135.853,-115.5001"/>
</a>
</g>
</g>
<!-- (github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64 -->
<g id="node4" class="node">
<title>(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64</title>
<g id="a_node4"><a xlink:title="(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64 | defined in destination.go:55">
<path fill="#ffe4b5" stroke="#000000" stroke-width="1.5" d="M232.5916,-191C232.5916,-191 170.717,-191 170.717,-191 164.717,-191 158.717,-185 158.717,-179 158.717,-179 158.717,-167 158.717,-167 158.717,-161 164.717,-155 170.717,-155 170.717,-155 232.5916,-155 232.5916,-155 238.5916,-155 244.5916,-161 244.5916,-167 244.5916,-167 244.5916,-179 244.5916,-179 244.5916,-185 238.5916,-191 232.5916,-191"/>
<text text-anchor="middle" x="201.6543" y="-177.2" font-family="Verdana" font-size="14.00" fill="#000000">destination</text>
<text text-anchor="middle" x="201.6543" y="-160.4" font-family="Verdana" font-size="14.00" fill="#000000">Base64</text>
</a>
</g>
</g>
<!-- github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/destination.Fuzz&#45;&gt;(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64 -->
<g id="edge3" class="edge">
<title>github.com/go&#45;i2p/go&#45;i2p/lib/common/fuzz/destination.Fuzz&#45;&gt;(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64</title>
<g id="a_edge3"><a xlink:title="at fuzz.go:8: calling [(github.com/go&#45;i2p/go&#45;i2p/lib/common/destination.Destination).Base64]">
<path fill="none" stroke="#8b4513" d="M70.2736,-122.4863C91.973,-130.8293 122.976,-142.7495 149.4161,-152.9153"/>
<polygon fill="#8b4513" stroke="#8b4513" points="148.3351,-156.2494 158.9251,-156.5713 150.8473,-149.7157 148.3351,-156.2494"/>
</a>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 7.8 KiB

View File

@@ -1,10 +0,0 @@
package exportable
import common "github.com/go-i2p/go-i2p/lib/common/destination"
func Fuzz(data []byte) int {
destination, _, _ := common.ReadDestination(data)
destination.Base32Address()
destination.Base64()
return 0
}

View File

@@ -1,21 +0,0 @@
# exportable
--
import "github.com/go-i2p/go-i2p/lib/common/fuzz/keys_and_cert"
![exportable.svg](exportable.svg)
## Usage
#### func Fuzz
```go
func Fuzz(data []byte) int
```
exportable
github.com/go-i2p/go-i2p/lib/common/fuzz/keys_and_cert

Some files were not shown because too many files have changed in this diff Show More