Compare commits
336 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7048131842 | ||
![]() |
b47b3971f7 | ||
![]() |
e31a7636d0 | ||
![]() |
9b05750814 | ||
![]() |
494f0274ba | ||
![]() |
a079a9c9ff | ||
![]() |
fa15eeec97 | ||
![]() |
d5422aee75 | ||
![]() |
4232b6e197 | ||
![]() |
fcdd8b7f52 | ||
![]() |
529a5f77cb | ||
![]() |
8be5dfbee0 | ||
![]() |
87e663ed3d | ||
![]() |
ff11aeebc4 | ||
![]() |
8e0af0c4f6 | ||
![]() |
3ab932c170 | ||
![]() |
6159dc47f0 | ||
![]() |
bf6b920eff | ||
![]() |
aa52be69ff | ||
![]() |
d2f767dbe0 | ||
![]() |
b89d62e481 | ||
![]() |
06113918ea | ||
![]() |
a884fa4692 | ||
![]() |
fc36f9cf6f | ||
![]() |
3248dd789d | ||
![]() |
71ca8cd65f | ||
![]() |
60e9f15b18 | ||
![]() |
ee8617deb0 | ||
![]() |
029317222e | ||
![]() |
bcd32aa8ad | ||
![]() |
3c1a44e1d2 | ||
![]() |
7167ba3a1c | ||
![]() |
3ff494c374 | ||
![]() |
aebbe18f3b | ||
![]() |
081b25d54c | ||
![]() |
78306cc9e6 | ||
![]() |
0e40939f7d | ||
![]() |
ccc29b5e66 | ||
![]() |
36655256c3 | ||
![]() |
efccedaafb | ||
![]() |
a75baf9db7 | ||
![]() |
d67c0c0e31 | ||
![]() |
e88e3a0a6b | ||
![]() |
f530ccd37f | ||
![]() |
afdc44afc6 | ||
![]() |
6b873f4fc2 | ||
![]() |
c427d576cb | ||
![]() |
383fafea25 | ||
![]() |
9254afc776 | ||
![]() |
29c48f906c | ||
![]() |
38a4e1b3ad | ||
![]() |
bd255b651b | ||
![]() |
7b7238db56 | ||
![]() |
e0e31c041a | ||
![]() |
a8b416b8b1 | ||
![]() |
61b8dc0813 | ||
![]() |
862b7a8c3a | ||
![]() |
d8755c1229 | ||
![]() |
0131d84eb5 | ||
![]() |
2643598a6e | ||
![]() |
8bc137072c | ||
![]() |
976338c5c9 | ||
![]() |
6274e4ac6b | ||
![]() |
70689f669f | ||
![]() |
86a305d47f | ||
![]() |
0e126429da | ||
![]() |
e459edd194 | ||
![]() |
b6c3371366 | ||
![]() |
7c0d7cb0d5 | ||
![]() |
888fe2e1bb | ||
![]() |
eff15e73ba | ||
![]() |
a812fbd784 | ||
![]() |
a7f81444e2 | ||
![]() |
a781f8cea1 | ||
![]() |
d708ea6a18 | ||
![]() |
a40083695e | ||
![]() |
03255526ec | ||
![]() |
2779413484 | ||
![]() |
593a62f27c | ||
![]() |
c3192414f7 | ||
![]() |
d7607117be | ||
![]() |
22de47a2c5 | ||
![]() |
0cd844cbd8 | ||
![]() |
3c99520aa7 | ||
![]() |
713635d568 | ||
![]() |
d771ba0ea8 | ||
![]() |
88a0bd74cb | ||
![]() |
f1a9fa0efd | ||
![]() |
339cafddeb | ||
![]() |
9df4822e1e | ||
![]() |
433aef42fe | ||
![]() |
76b5f7acb2 | ||
![]() |
d5f792142e | ||
![]() |
70a8ab4019 | ||
![]() |
5ddea40045 | ||
![]() |
7fe45cca93 | ||
![]() |
4319726630 | ||
![]() |
00e5cb49c7 | ||
![]() |
20d1d9f244 | ||
![]() |
25556ee378 | ||
![]() |
62c065c510 | ||
![]() |
5df5187cc0 | ||
![]() |
00488deee3 | ||
![]() |
df3c2edac0 | ||
![]() |
c4cbf34ade | ||
![]() |
478d69d105 | ||
![]() |
5a08db5475 | ||
![]() |
29735355fe | ||
![]() |
ff8389a7c9 | ||
![]() |
89b42eb2bf | ||
![]() |
de9ea2d402 | ||
![]() |
790f01be80 | ||
![]() |
7135facd9c | ||
![]() |
7889f63232 | ||
![]() |
0e51342fe0 | ||
![]() |
4a28a7a07d | ||
![]() |
ec6172e4d1 | ||
![]() |
5ede568549 | ||
![]() |
ac5f5e3313 | ||
![]() |
fdf75d99a0 | ||
![]() |
8b4b86b3ee | ||
![]() |
ac76fc7a5c | ||
![]() |
ffdf5d2299 | ||
![]() |
e59b43395f | ||
![]() |
ac48fd6619 | ||
![]() |
54eb978f11 | ||
![]() |
afa6a568ff | ||
![]() |
d7ac6372bf | ||
![]() |
e3aa6be988 | ||
![]() |
c291f23435 | ||
![]() |
bd82f268eb | ||
![]() |
10d7f7c24a | ||
![]() |
8f07c65a1f | ||
![]() |
9e7fb0deb6 | ||
![]() |
148ef4096c | ||
![]() |
d134080415 | ||
![]() |
aa4a9551f3 | ||
![]() |
c7a428ed25 | ||
![]() |
04d57c329e | ||
![]() |
246740cb7f | ||
![]() |
8882f39efe | ||
![]() |
992dc1d464 | ||
![]() |
5c13d44e14 | ||
![]() |
7808bea943 | ||
![]() |
c32fb66558 | ||
![]() |
addfd33936 | ||
![]() |
a8093d9e76 | ||
![]() |
298df15b2e | ||
![]() |
7ae14054a5 | ||
![]() |
059eb57d35 | ||
![]() |
525d54e7b2 | ||
![]() |
f6aff1be50 | ||
![]() |
1112123584 | ||
![]() |
fa675eadad | ||
![]() |
3bc86464f7 | ||
![]() |
07c87424f5 | ||
![]() |
02221ab3a7 | ||
![]() |
ce8643b90c | ||
![]() |
35587dded7 | ||
![]() |
fad86f2d42 | ||
![]() |
32585c7e2c | ||
![]() |
c6c4e768aa | ||
![]() |
8b288b0332 | ||
![]() |
547e1df401 | ||
![]() |
cbc735e3d3 | ||
![]() |
5be974dddb | ||
![]() |
9a86763243 | ||
![]() |
d313a88bc6 | ||
![]() |
5d3fd84f4a | ||
![]() |
23dc60391c | ||
![]() |
34bee0faf7 | ||
![]() |
292663fae1 | ||
![]() |
4baef9026a | ||
![]() |
5a33a15207 | ||
![]() |
7f05a1c283 | ||
![]() |
c869402fee | ||
![]() |
b8804f758d | ||
![]() |
7e5be05689 | ||
![]() |
3ae3641f84 | ||
![]() |
61f04fd2cb | ||
![]() |
970d670edf | ||
![]() |
930652f52a | ||
![]() |
f7dc34ab34 | ||
![]() |
6b6c74653b | ||
![]() |
edd8ee3746 | ||
![]() |
9957f2bc6d | ||
![]() |
2d3a3caf9d | ||
![]() |
8bab575a71 | ||
![]() |
5a27ae3ff1 | ||
![]() |
c75801db46 | ||
![]() |
7bb6d863ff | ||
![]() |
23c173ea95 | ||
![]() |
18b170a949 | ||
![]() |
e47a8eb94c | ||
![]() |
20e49356c6 | ||
![]() |
3631c87bfa | ||
![]() |
577a84adf3 | ||
![]() |
6e887f10e6 | ||
![]() |
6f166d6cdd | ||
![]() |
c0d3bcb238 | ||
![]() |
38d1564eb0 | ||
![]() |
e30ca92b85 | ||
![]() |
8ec3f58993 | ||
![]() |
c3fb2e04f3 | ||
![]() |
3e053eeecf | ||
![]() |
d3881d9cc2 | ||
![]() |
15f032e310 | ||
![]() |
4e6d25705f | ||
![]() |
67d53a6052 | ||
![]() |
5cb1e29489 | ||
![]() |
6536f34c23 | ||
![]() |
c7e2ce21f2 | ||
![]() |
692de44793 | ||
![]() |
6e03eba5a4 | ||
![]() |
4e7a98ee47 | ||
![]() |
1f4bd09b1c | ||
![]() |
1b8aef71f5 | ||
![]() |
02ff8d6b87 | ||
![]() |
b2e016e059 | ||
![]() |
9608c7be09 | ||
![]() |
acd4f17536 | ||
![]() |
e031f4483c | ||
![]() |
82814f8dcf | ||
![]() |
68986f6194 | ||
![]() |
86c7624075 | ||
![]() |
6701d35daf | ||
![]() |
f0070524c1 | ||
![]() |
a29f56e8c3 | ||
![]() |
921289fd4d | ||
![]() |
c016ffa6dc | ||
![]() |
d87c57672e | ||
![]() |
3c415e114a | ||
![]() |
c2bf0bd822 | ||
![]() |
0db741aa00 | ||
![]() |
2b7f275f50 | ||
![]() |
9ab4d5efee | ||
![]() |
364a35c10a | ||
![]() |
3979d87390 | ||
![]() |
6bc7558bef | ||
![]() |
db94225e60 | ||
![]() |
9bf8bbb7b8 | ||
![]() |
d1385398d3 | ||
![]() |
0d2835d74e | ||
![]() |
a013524011 | ||
![]() |
815e124555 | ||
![]() |
febf285738 | ||
![]() |
3ca55982ec | ||
![]() |
8f0ce23667 | ||
![]() |
58771aa31e | ||
![]() |
a3f47f1fed | ||
![]() |
6c044b2029 | ||
![]() |
1f8c617eb5 | ||
![]() |
7a05f9e343 | ||
![]() |
30f2dbfddf | ||
![]() |
1c455ee84a | ||
![]() |
569d5efcc3 | ||
![]() |
92f961bd79 | ||
![]() |
124b22e986 | ||
![]() |
fe92d3c89e | ||
![]() |
4ba85e54c1 | ||
![]() |
4b88902fb1 | ||
![]() |
5e51cc87ff | ||
![]() |
8c16480db3 | ||
![]() |
74b1c390ae | ||
![]() |
4ef9263111 | ||
![]() |
11c3bb47a6 | ||
![]() |
b6a2b334dd | ||
![]() |
93ad5b3a43 | ||
![]() |
f0bbea5e6d | ||
![]() |
9fae6cf923 | ||
![]() |
2fd6131127 | ||
![]() |
0f283bc8dd | ||
![]() |
79ffc5099e | ||
![]() |
69009fcfd4 | ||
![]() |
81721c166a | ||
![]() |
ad27955dfb | ||
![]() |
dc48d03118 | ||
![]() |
a7ab90b328 | ||
![]() |
df9c44b82f | ||
![]() |
0aefc3a0e4 | ||
![]() |
9d2dcb1749 | ||
![]() |
f431e8c59b | ||
![]() |
2f172136ce | ||
![]() |
330f5bf0c0 | ||
![]() |
7c53bd8f3b | ||
![]() |
a831dc0c1c | ||
![]() |
3fa0b71fc6 | ||
![]() |
dbd9acb623 | ||
![]() |
ad6df28bf5 | ||
![]() |
b93ce475a4 | ||
![]() |
3e4780795e | ||
![]() |
cd458b3d1b | ||
![]() |
c3a2f88796 | ||
![]() |
b34078bfd1 | ||
![]() |
e9bc78e215 | ||
![]() |
5b33d09b0c | ||
![]() |
ee65a82cc9 | ||
![]() |
237c0ec41e | ||
![]() |
1684b4f919 | ||
![]() |
55a8568e8c | ||
![]() |
7e3487ec28 | ||
![]() |
96fcfe8a62 | ||
![]() |
c6ddebedcb | ||
![]() |
c1427c74f3 | ||
![]() |
911f205d6c | ||
![]() |
d6d12b7ae0 | ||
![]() |
d246d1ba7d | ||
![]() |
055df02607 | ||
![]() |
a945eeeeb7 | ||
![]() |
8630d5fcdd | ||
![]() |
cd3733d2b0 | ||
![]() |
2070ca935a | ||
![]() |
f5d93be0f4 | ||
![]() |
2bd4243384 | ||
![]() |
2336bdbd0b | ||
![]() |
a21f10558d | ||
![]() |
b562d2ba2b | ||
![]() |
b53e0dee95 | ||
![]() |
a874659167 | ||
![]() |
62e18862d8 | ||
![]() |
b4d0c2d98f | ||
![]() |
7284e84554 | ||
![]() |
126067d003 | ||
![]() |
5176224668 | ||
![]() |
29cc1dc5de | ||
![]() |
fd96ce4794 | ||
![]() |
5524660b0c | ||
![]() |
bd4201e955 | ||
![]() |
8d618e67e2 | ||
![]() |
a423c181ca | ||
![]() |
848150a4cf | ||
![]() |
67055ab95b | ||
![]() |
9a9e27272b | ||
![]() |
abc874b6b8 | ||
![]() |
93ddb65858 | ||
![]() |
5e5e79db86 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -3,3 +3,7 @@ bin/*
|
||||
.go
|
||||
*.i2pkeys
|
||||
*/*.i2pkeys
|
||||
README.md.asc
|
||||
samcatd
|
||||
*/*.pem
|
||||
*.pem
|
||||
|
@@ -21,7 +21,7 @@ before_install:
|
||||
install:
|
||||
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
sleep 10;
|
||||
make deps noopts; else
|
||||
make deps all; else
|
||||
sudo service i2pd start; sleep 10;
|
||||
make deps noopts test;
|
||||
make deps all test;
|
||||
sudo service i2pd stop; fi
|
||||
|
22
Dockerfile
22
Dockerfile
@@ -1,20 +1,18 @@
|
||||
FROM alpine:3.8
|
||||
ARG user=eephttpd
|
||||
ARG path=example/path
|
||||
FROM alpine:edge
|
||||
ARG user=samcatd
|
||||
ENV samhost=sam-host
|
||||
ENV samport=7656
|
||||
ENV args="-r"
|
||||
ENV args=""
|
||||
ENV user=$user
|
||||
ENV GOPATH=/usr
|
||||
RUN apk update -U
|
||||
RUN apk add go git make musl-dev
|
||||
RUN apk add go git make musl-dev webkit2gtk-dev gtk+3.0-dev
|
||||
RUN mkdir -p /opt/$user
|
||||
RUN adduser -h /opt/$user -D -g "$user,,,," $user
|
||||
COPY . /usr/src/eephttpd
|
||||
WORKDIR /usr/src/eephttpd
|
||||
RUN make deps server
|
||||
RUN install -m755 bin/eephttpd /usr/bin/eephttpd
|
||||
|
||||
COPY . /usr/src/sam-forwarder
|
||||
WORKDIR /usr/src/github.com/eyedeekay/sam-forwarder
|
||||
RUN go get -u github.com/eyedeekay/sam-forwarder/samcatd
|
||||
RUN make dylink install
|
||||
USER $user
|
||||
WORKDIR /opt/$user/
|
||||
COPY $path /opt/$user/www
|
||||
CMD eephttpd -f /usr/src/eephttpd/etc/eephttpd/eephttpd.conf -s /opt/$user/ -sh=$samhost -sp=$samport $args
|
||||
CMD samcatd -f /usr/src/eephttpd/etc/samcatd/tunnels.ini -littleboss start
|
||||
|
16
EMBEDDING.md
16
EMBEDDING.md
@@ -1,16 +0,0 @@
|
||||
Embedding i2p support in your Go application with samforwarder
|
||||
==============================================================
|
||||
|
||||
One neat thing you can do with samforwarder is make eepWeb(?) services configure
|
||||
themselves automatically by adding it to an existing Go application. To help
|
||||
with this process, the samforwarder/config/ file has a bunch of helper
|
||||
functions and a class for parsing configuration files directly. You can import
|
||||
it, add a few flags(or however you configure your service) and fire off the
|
||||
forwarder as a goroutne, all you have to do is configure it to forward the port
|
||||
used by your service. This makes it extremely easy to do, but in my opinion, it
|
||||
should only be used in this way for applications that would already be safe to
|
||||
host as services in i2p or other overlay networks. That means avoiding the risk
|
||||
of out-of-band communication accidentally, such as by making the server retrieve
|
||||
a resource from a clearnet service.
|
||||
|
||||
When I'm less tired and more interested, I'll try to finish this document.
|
17
LICENSE.md
17
LICENSE.md
@@ -1,7 +1,18 @@
|
||||
Copyright 2018 eyedeekay <eyedeekay@safe-mail.net>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
342
Makefile
342
Makefile
@@ -1,173 +1,251 @@
|
||||
|
||||
GOPATH = $(PWD)/.go
|
||||
#GOPATH=$(HOME)/go
|
||||
|
||||
appname = ephsite
|
||||
eephttpd = eephttpd
|
||||
network = si
|
||||
packagename = sam-forwarder
|
||||
samcatd = samcatd
|
||||
network = host
|
||||
samhost = sam-host
|
||||
samport = 7656
|
||||
args = -r
|
||||
USER_GH=eyedeekay
|
||||
|
||||
PREFIX := /
|
||||
VAR := var/
|
||||
RUN := run/
|
||||
LIB := lib/
|
||||
LOG := log/
|
||||
ETC := etc/
|
||||
USR := usr/
|
||||
LOCAL := local/
|
||||
VERSION := 0.32.09
|
||||
|
||||
GO111MODULE=on
|
||||
|
||||
echo:
|
||||
@echo "$(GOPATH)"
|
||||
find . -name "*.go" -exec gofmt -w {} \;
|
||||
find . -name "*.i2pkeys" -exec rm {} \;
|
||||
find . -path ./.go -prune -o -name "*.go" -exec gofmt -w {} \;
|
||||
find . -path ./.go -prune -o -name "*.i2pkeys" -exec rm {} \;
|
||||
find . -path ./.go -prune -o -name "*.pem" -exec rm {} \;
|
||||
find . -path ./.go -prune -o -name "*.go" -exec cat {} \; | nl
|
||||
|
||||
test:
|
||||
go test
|
||||
cd udp && go test
|
||||
cd config && go test
|
||||
tag:
|
||||
gothub release -s $(GITHUB_TOKEN) -u $(USER_GH) -r $(packagename) -t v$(VERSION) -d "I2P Tunnel Management tool for Go applications"
|
||||
|
||||
recopy:
|
||||
#find ./tcp/ -name '*.go' -exec cp -rv {} . \;
|
||||
#sed -i '1s|^|//AUTO-GENERATED FOR BACKWARD COMPATIBILITY, USE ./tcp in the future\n|' *.go
|
||||
|
||||
## TODO: Remove this, replace with something right
|
||||
fix-debian:
|
||||
find ./debian -type f -exec sed -i 's|lair repo key|eyedeekay|g' {} \;
|
||||
find ./debian -type f -exec sed -i 's|eyedeekay@safe-mail.net|hankhill19580@gmail.com|g' {} \;
|
||||
|
||||
try:
|
||||
./bin/samcatd -f etc/samcatd/tunnels.ini
|
||||
|
||||
test: test-keys test-ntcp test-ssu test-config test-manager
|
||||
|
||||
long-test: test-serve test
|
||||
|
||||
full-test: test test-serve
|
||||
|
||||
test-serve:
|
||||
cd serve_test && go test -v -tags netgo \
|
||||
-ldflags '-w -extldflags "-static"'
|
||||
|
||||
test-ntcp:
|
||||
cd tcp && go test -v -tags netgo \
|
||||
-ldflags '-w -extldflags "-static"'
|
||||
|
||||
test-ssu:
|
||||
cd udp && go test -v -tags netgo \
|
||||
-ldflags '-w -extldflags "-static"'
|
||||
|
||||
test-config:
|
||||
cd config && go test -v -tags netgo \
|
||||
-ldflags '-w -extldflags "-static"'
|
||||
|
||||
test-manager:
|
||||
cd manager && go test -v -tags netgo \
|
||||
-ldflags '-w -extldflags "-static"'
|
||||
|
||||
test-keys:
|
||||
cd i2pkeys && go test -v -tags netgo \
|
||||
-ldflags '-w -extldflags "-static"'
|
||||
|
||||
refresh:
|
||||
|
||||
deps:
|
||||
go get -u github.com/zieckey/goini
|
||||
go get -u github.com/eyedeekay/sam-forwarder
|
||||
go get -u github.com/eyedeekay/sam-forwarder/udp
|
||||
go get -u github.com/eyedeekay/sam-forwarder/config
|
||||
go get -u github.com/kpetku/sam3
|
||||
go get -u github.com/eyedeekay/sam3
|
||||
|
||||
build: clean bin/$(appname)
|
||||
|
||||
bin/$(appname):
|
||||
mkdir -p bin
|
||||
cd main && go build -a -tags netgo -ldflags '-w -extldflags "-static"' -o ../bin/$(appname)
|
||||
|
||||
server: clean-server bin/$(eephttpd)
|
||||
|
||||
bin/$(eephttpd):
|
||||
mkdir -p bin
|
||||
go build -a -tags netgo -ldflags '-w -extldflags "-static"' -o ./bin/$(eephttpd) ./example/serve.go
|
||||
|
||||
all: build server
|
||||
|
||||
clean-all: clean clean-server
|
||||
|
||||
clean:
|
||||
rm -f bin/$(appname)
|
||||
|
||||
clean-server:
|
||||
rm -f bin/$(eephttpd)
|
||||
|
||||
noopts: clean
|
||||
mkdir -p bin
|
||||
cd main && go build -o ../bin/$(appname)
|
||||
go get -u -d github.com/eyedeekay/sam-forwarder/samcatd
|
||||
|
||||
install:
|
||||
install -m755 bin/ephsite /usr/local/bin/ephsite
|
||||
install -m755 ./bin/$(samcatd) $(PREFIX)$(USR)$(LOCAL)/bin/
|
||||
install -m644 ./etc/init.d/samcatd $(PREFIX)$(ETC)/init.d
|
||||
mkdir -p $(PREFIX)$(ETC)/samcatd/ $(PREFIX)$(ETC)/sam-forwarder/ $(PREFIX)$(ETC)/i2pvpn/
|
||||
install -m644 ./etc/samcatd/tunnels.ini $(PREFIX)$(ETC)/samcatd/
|
||||
install -m644 ./etc/sam-forwarder/tunnels.ini $(PREFIX)$(ETC)/sam-forwarder/
|
||||
|
||||
install-server:
|
||||
install -m755 bin/eephttpd /usr/local/bin/eephttpd
|
||||
daemon: clean-daemon bin/$(samcatd)
|
||||
|
||||
install-all: install install-server
|
||||
daemon-webview: bin/$(samcatd)-webview
|
||||
|
||||
remove:
|
||||
daemon-cli: bin/$(samcatd)-cli
|
||||
|
||||
gendoc: all
|
||||
@echo "$(appname) - Easy forwarding of local services to i2p" > USAGE.md
|
||||
bin/$(samcatd)-cli:
|
||||
mkdir -p bin
|
||||
cd samcatd && go build -a -tags "netgo cli" \
|
||||
-ldflags '-w -extldflags "-static"' \
|
||||
-o ../bin/$(samcatd)-cli \
|
||||
./*.go
|
||||
|
||||
bin/$(samcatd):
|
||||
mkdir -p bin
|
||||
cd samcatd && go build -a -tags "netgo static" \
|
||||
-ldflags '-w -extldflags "-static"' \
|
||||
-o ../bin/$(samcatd) \
|
||||
./*.go
|
||||
|
||||
bin/$(samcatd)-webview:
|
||||
mkdir -p bin
|
||||
cd samcatd && go build -a -tags "netgo nostatic" \
|
||||
-o ../bin/$(samcatd)-webview \
|
||||
./*.go
|
||||
|
||||
update:
|
||||
git config --global url."git@github.com:RTradeLtd".insteadOf "https://github.com/RTradeLtd"
|
||||
|
||||
all: daemon-cli daemon daemon-webview
|
||||
|
||||
clean: clean-all echo
|
||||
|
||||
clean-all: clean-daemon
|
||||
|
||||
clean-daemon:
|
||||
rm -f bin/$(samcatd)*
|
||||
|
||||
install-forwarder:
|
||||
install -m755 bin/$(samcatd) /usr/local/bin/$(samcatd)
|
||||
|
||||
install-all: install
|
||||
|
||||
gendoc:
|
||||
@echo "$(samcatd) - Router-independent tunnel management for i2p" > USAGE.md
|
||||
@echo "=========================================================" >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@echo "$(samcatd) is a daemon which runs a group of forwarding proxies to" >> USAGE.md
|
||||
@echo "provide services over i2p independent of the router. It also serves" >> USAGE.md
|
||||
@echo "as a generalized i2p networking utility for power-users. It's" >> USAGE.md
|
||||
@echo "intended to be a Swiss-army knife for the SAM API." >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@echo "usage:" >> USAGE.md
|
||||
@echo "------" >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@echo '```' >> USAGE.md
|
||||
./bin/$(samcatd) -h 2>> USAGE.md; true
|
||||
@echo '```' >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
make key-management
|
||||
make example-config
|
||||
|
||||
key-management:
|
||||
@echo "managing $(samcatd) save-encryption keys" >> USAGE.md
|
||||
@echo "=====================================" >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@echo "In order to keep from saving the .i2pkeys files in plaintext format, samcatd" >> USAGE.md
|
||||
@echo "can optionally generate a key and encrypt the .i2pkeys files securely. Of" >> USAGE.md
|
||||
@echo "course, to fully benefit from this arrangement, you need to move those keys" >> USAGE.md
|
||||
@echo "away from the machine where the tunnel keys(the .i2pkeys file) are located," >> USAGE.md
|
||||
@echo "or protect them in some other way(sandboxing, etc). If you want to use" >> USAGE.md
|
||||
@echo "encrypted .i2pkeys files, you can specify a key file to use with the -cr" >> USAGE.md
|
||||
@echo "option on the terminal or with keyfile option in the .ini file." >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
|
||||
example-config:
|
||||
@echo "example config - valid for both ephsite and samcat" >> USAGE.md
|
||||
@echo "==================================================" >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@echo "$(appname) is a forwarding proxy designed to configure a tunnel for use" >> USAGE.md
|
||||
@echo "with i2p. It can be used to easily forward a local service to the" >> USAGE.md
|
||||
@echo "i2p network using i2p's SAM API instead of the tunnel interface." >> USAGE.md
|
||||
@echo "Options are still being added, pretty much as fast as I can put them" >> USAGE.md
|
||||
@echo "in. For up-to-the-minute options, see [the checklist](config/CHECKLIST.md)" >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@echo "usage:" >> USAGE.md
|
||||
@echo "------" >> USAGE.md
|
||||
@echo "(**ephsite** will only use top-level options, but they can be labeled or" >> USAGE.md
|
||||
@echo "unlabeled)" >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@echo '```' >> USAGE.md
|
||||
./bin/$(appname) -h 2>> USAGE.md; true
|
||||
@echo "(**samcatd** treats the first set of options it sees as the default, and" >> USAGE.md
|
||||
@echo "does not start tunnels based on unlabeled options unless passed the" >> USAGE.md
|
||||
@echo "-s flag.)" >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@echo '``` ini' >> USAGE.md
|
||||
cat etc/samcatd/tunnels.ini >> USAGE.md
|
||||
@echo '```' >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@echo "$(eephttpd) - Static file server automatically forwarded to i2p" >> USAGE.md
|
||||
@echo "============================================================" >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@echo "usage:" >> USAGE.md
|
||||
@echo "------" >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@echo "$(eephttpd) is a static http server which automatically runs on i2p with" >> USAGE.md
|
||||
@echo "the help of the SAM bridge. By default it will only be available from" >> USAGE.md
|
||||
@echo "the localhost and it's i2p tunnel. It can be masked from the localhost" >> USAGE.md
|
||||
@echo "using a container." >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@echo '```' >> USAGE.md
|
||||
./bin/$(eephttpd) -h 2>> USAGE.md; true
|
||||
@echo '```' >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
make docker-cmd
|
||||
@echo "" >> USAGE.md
|
||||
@echo "instance" >> USAGE.md
|
||||
@echo "--------" >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@echo "a running instance of eephttpd with the example index file is availble on" >> USAGE.md
|
||||
@grep 'and on' eephttpd.log | sed 's|and on||g' | tr -d '\t' >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@cat USAGE.md
|
||||
mv USAGE.md docs/USAGE.md
|
||||
|
||||
|
||||
docker-build:
|
||||
docker build --force-rm \
|
||||
--build-arg user=$(eephttpd) \
|
||||
--build-arg path=example/www \
|
||||
docker build --build-arg user=$(samcatd) \
|
||||
-f Dockerfile \
|
||||
-t eyedeekay/$(eephttpd) .
|
||||
-t eyedeekay/$(samcatd) .
|
||||
|
||||
docker-volume:
|
||||
docker run -i -t -d \
|
||||
--name $(eephttpd)-volume \
|
||||
--volume $(eephttpd):/home/$(eephttpd)/ \
|
||||
eyedeekay/$(eephttpd); true
|
||||
docker stop $(eephttpd)-volume; true
|
||||
|
||||
docker-run: docker-volume
|
||||
docker rm -f eephttpd; true
|
||||
docker-run:
|
||||
docker rm -f $(samcatd); true
|
||||
docker run -i -t -d \
|
||||
--cap-add "net_bind_service" \
|
||||
--network $(network) \
|
||||
--env samhost=$(samhost) \
|
||||
--env samport=$(samport) \
|
||||
--env args=$(args) \
|
||||
--network-alias $(eephttpd) \
|
||||
--hostname $(eephttpd) \
|
||||
--name $(eephttpd) \
|
||||
--hostname $(samcatd) \
|
||||
--name $(samcatd) \
|
||||
--restart always \
|
||||
--volumes-from $(eephttpd)-volume \
|
||||
eyedeekay/$(eephttpd)
|
||||
-p 127.0.0.1:7957:7957 \
|
||||
eyedeekay/$(samcatd)
|
||||
make follow
|
||||
|
||||
follow:
|
||||
docker logs -f $(eephttpd)
|
||||
docker logs -f $(samcatd)
|
||||
|
||||
docker: docker-build docker-volume docker-run
|
||||
|
||||
docker-cmd:
|
||||
@echo "### build in docker" >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@echo '```' >> USAGE.md
|
||||
@echo "docker build --build-arg user=$(eephttpd) --build-arg path=example/www -f Dockerfile -t eyedeekay/$(eephttpd) ." >> USAGE.md
|
||||
@echo '```' >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@echo "### Run in docker" >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@echo '```' >> USAGE.md
|
||||
@echo "docker run -i -t -d \\" >> USAGE.md
|
||||
@echo " --name $(eephttpd)-volume \\" >> USAGE.md
|
||||
@echo " --volume $(eephttpd):/home/$(eephttpd)/ \\" >> USAGE.md
|
||||
@echo " eyedeekay/$(eephttpd)" >> USAGE.md
|
||||
@echo '```' >> USAGE.md
|
||||
@echo "" >> USAGE.md
|
||||
@echo '```' >> USAGE.md
|
||||
@echo "docker run -i -t -d \\" >> USAGE.md
|
||||
@echo " --network $(network) \\" >> USAGE.md
|
||||
@echo " --env samhost=$(samhost) \\" >> USAGE.md
|
||||
@echo " --env samport=$(samport) \\" >> USAGE.md
|
||||
@echo " --env args=$(args) # Additional arguments to pass to eephttpd\\" >> USAGE.md
|
||||
@echo " --network-alias $(eephttpd) \\" >> USAGE.md
|
||||
@echo " --hostname $(eephttpd) \\" >> USAGE.md
|
||||
@echo " --name $(eephttpd) \\" >> USAGE.md
|
||||
@echo " --restart always \\" >> USAGE.md
|
||||
@echo " --volumes-from $(eephttpd)-volume \\" >> USAGE.md
|
||||
@echo " eyedeekay/$(eephttpd)" >> USAGE.md
|
||||
@echo '```' >> USAGE.md
|
||||
docker: docker-build docker-run
|
||||
|
||||
index:
|
||||
pandoc USAGE.md -o example/www/index.html
|
||||
pandoc README.md -o docs/index.html
|
||||
pandoc docs/USAGE.md -o example/www/index.html && cp example/www/index.html docs/usage.html
|
||||
pandoc docs/EMBEDDING.md -o docs/embedding.html
|
||||
pandoc docs/PACKAGECONF.md -o docs/packageconf.html
|
||||
pandoc interface/README.md -o docs/interface.html
|
||||
cp config/CHECKLIST.md docs/config
|
||||
pandoc docs/config/CHECKLIST.md -o docs/checklist.html
|
||||
|
||||
visit:
|
||||
http_proxy=http://127.0.0.1:44443 surf http://566niximlxdzpanmn4qouucvua3k7neniwss47li5r6ugoertzuq.b32.i2p
|
||||
http_proxy=http://127.0.0.1:4444 surf http://566niximlxdzpanmn4qouucvua3k7neniwss47li5r6ugoertzuq.b32.i2p
|
||||
|
||||
gojs:
|
||||
go get -u github.com/gopherjs/gopherjs
|
||||
|
||||
GOPHERJS=$(GOPATH)/bin/gopherjs
|
||||
|
||||
js:
|
||||
mkdir -p bin
|
||||
$(GOPHERJS) build -v --tags netgo \
|
||||
-o ./javascript/$(samcatd).js \
|
||||
./samcatd/*.go
|
||||
|
||||
cleantar:
|
||||
rm -f ../$(packagename)_$(VERSION).orig.tar.xz
|
||||
|
||||
tar:
|
||||
tar --exclude .git \
|
||||
--exclude .go \
|
||||
--exclude bin \
|
||||
-cJvf ../$(packagename)_$(VERSION).orig.tar.xz .
|
||||
|
||||
sed:
|
||||
sed -i 's|func(\*Conf)|func(samtunnel.SAMTunnel)|g' ./config/*.go
|
||||
sed -i 's|func(c \*Conf)|func(c samtunnel.SAMTunnel)|g' ./config/*.go
|
||||
|
||||
tasks:
|
||||
golint ./tcp
|
||||
#golint ./udp
|
||||
#golint ./config
|
||||
#golint ./config
|
||||
#golint ./config
|
||||
#golint ./config
|
||||
|
205
README.md
205
README.md
@@ -1,9 +1,14 @@
|
||||
# sam-forwarder
|
||||
|
||||
Forward a local port to i2p over the SAM API, or proxy a destination to a port
|
||||
on the local host. This is a work-in-progress, but the basic functionality is,
|
||||
there and it's already pretty useful. Everything TCP works, but UDP forwarding
|
||||
is still not well tested, and UDP clients aren't enabled yet. I'm out of excuses
|
||||
not to finish it now, too.
|
||||
on the local host. This is no longer substantially a work-in-progress, it's a
|
||||
very useful way of configuring applications in an i2ptunnel-like way. TCP and
|
||||
UDP are supported, but there may be some lingering bugs in UDP, please report
|
||||
them if found.
|
||||
|
||||
## getting
|
||||
|
||||
go get -u github.com/eyedeekay/sam-forwarder/samcatd
|
||||
|
||||
## building
|
||||
|
||||
@@ -15,162 +20,88 @@ and it will be in the folder ./bin/
|
||||
|
||||
[](https://travis-ci.org/eyedeekay/sam-forwarder)
|
||||
|
||||
## usage
|
||||
## Usage:
|
||||
|
||||
./bin/ephsite -host=host -port=port
|
||||
There are a number of ways to use sam-forwarder:
|
||||
|
||||
So, to serve an eepSite version of a local service on port 8080 -
|
||||
### [usage/configuration](docs/USAGE.md) as an application(Start here for samcatd)
|
||||
|
||||
./bin/ephsite -host=127.0.0.1 -port=8080
|
||||
### [embedding](docs/EMBEDDING.md) in other applications
|
||||
|
||||
For more information, [look here](USAGE.md)
|
||||
### [encapsulate](docs/PACKAGECONF.md) configuration for i2p-enabled packages
|
||||
|
||||
## ini-like configuration
|
||||
### [implement](interface/README.md) the interface for fine-grained control over SAM connections
|
||||
|
||||
I made it parse INI-like configuration files, optionally, which allows it to
|
||||
generate tunnels from snippets of i2pd tunnel configuration files. That's kinda
|
||||
useful. It appears to be more-or-less compatible with i2pd's tunnels.conf
|
||||
format, but it only supports the following options:
|
||||
## binaries
|
||||
|
||||
type = server
|
||||
host = 127.0.0.1
|
||||
port = 8081
|
||||
dir = /path/to/save/data/in #This is not shared with i2pd tunnels.conf
|
||||
inbound.length = 6
|
||||
outbound.length = 6
|
||||
inbound.lengthVariance = 6
|
||||
outbound.lengthVariance = 6
|
||||
inbound.backupQuantity = 5
|
||||
outbound.backupQuantity = 5
|
||||
inbound.quantity = 15
|
||||
outbound.quantity = 15
|
||||
inbound.allowZeroHop = true
|
||||
outbound.allowZeroHop = true
|
||||
i2cp.encryptLeaseSet = true
|
||||
gzip = true
|
||||
i2cp.reduceOnIdle = true
|
||||
i2cp.reduceIdleTime = 3000000
|
||||
i2cp.reduceQuantity = 4
|
||||
i2cp.enableWhiteList = false
|
||||
i2cp.enableBlackList = true
|
||||
i2cp.accessList = BASE64KEYSSEPARATEDBY,COMMAS
|
||||
keys = forwarder
|
||||
The standalone application for configuring tunnels is named samcatd and it's
|
||||
main package is in the directory ```./samcatd```. It works as a cli and is
|
||||
capable of running a WebUI, which is currently view-only. In a future time, the
|
||||
WebUI will also be capable of configuring and editing tunnels.
|
||||
|
||||
Also it doesn't support sections. Didn't realize that at first. Will address
|
||||
soon.
|
||||
|
||||
Other options are added to the config structure, but have to be referenced
|
||||
manually, there are no convenience functions for them.
|
||||
|
||||
## Static eepsite in like no seconds
|
||||
|
||||
Using this port forwarder, it's possible to create an instant eepsite from a
|
||||
folder full of html files(and the resources they call upon). Probably obviously
|
||||
to everybody reading this right now, but maybe not obviously to everyone reading
|
||||
this forever. A go application that does this I call eephttpd can be built with
|
||||
the command:
|
||||
|
||||
make server
|
||||
|
||||
and run from ./bin/eephttpd. The default behavior is to look for the files to
|
||||
serve under the current directory in ./www. It can be configured to behave
|
||||
differently according to the rules in [USAGE.md](USAGE.md). A Dockerfile is also
|
||||
available.
|
||||
|
||||
## Quick-And-Dirty i2p-enabled golang web applications
|
||||
|
||||
Normal web applications can easily add the ability to serve itself over i2p by
|
||||
importing and configuring this forwarding doodad. Wherever it takes the argument
|
||||
for the web server's listening host and/or port, pass that same host and/or port
|
||||
to a new instance of the "SAMForwarder" and then run the "Serve" function of the
|
||||
SAMForwarder as a goroutine. This simply forwards the running service to the i2p
|
||||
network, it doesn't do any filtering, and if your application establishes
|
||||
out-of-band connections, those may escape. Also, if your application is
|
||||
listening on all addresses, it will be visible from the local network.
|
||||
|
||||
Here's a simple example with a simple static file server:
|
||||
|
||||
```Diff
|
||||
package main package main
|
||||
|
||||
import ( import (
|
||||
"flag" "flag"
|
||||
"log" "log"
|
||||
"net/http" "net/http"
|
||||
) )
|
||||
|
||||
> import "github.com/eyedeekay/sam-forwarder"
|
||||
>
|
||||
func main() { func main() {
|
||||
port := flag.String("p", "8100", "port to serve on") port := flag.String("p", "8100", "port to serve on")
|
||||
directory := flag.String("d", ".", "the directory of static file to host") directory := flag.String("d", ".", "the directory of static file to host")
|
||||
flag.Parse() flag.Parse()
|
||||
>
|
||||
> forwarder, err := samforwarder.NewSAMForwarderFromOptions(
|
||||
> samforwarder.SetHost("127.0.0.1"),
|
||||
> samforwarder.SetPort(*port),
|
||||
> samforwarder.SetSAMHost("127.0.0.1"),
|
||||
> samforwarder.SetSAMPort("7656"),
|
||||
> samforwarder.SetName("staticfiles"),
|
||||
> )
|
||||
> if err != nil {
|
||||
> log.Fatal(err.Error())
|
||||
> }
|
||||
> go forwarder.Serve()
|
||||
|
||||
http.Handle("/", http.FileServer(http.Dir(*directory))) http.Handle("/", http.FileServer(http.Dir(*directory)))
|
||||
|
||||
log.Printf("Serving %s on HTTP port: %s\n", *directory, *port) log.Printf("Serving %s on HTTP port: %s\n", *directory, *port)
|
||||
log.Fatal(http.ListenAndServe("127.0.0.1:"+*port, nil)) log.Fatal(http.ListenAndServe("127.0.0.1:"+*port, nil))
|
||||
} }
|
||||
|
||||
```
|
||||
|
||||
[This tiny file server taken from here and used for this example](https://gist.github.com/paulmach/7271283)
|
||||
The previous application ephsite has been fully retired. If you were using it,
|
||||
it can usually be replaced with ```samcatd -s``` and your existing arguments.
|
||||
|
||||
Current limitations:
|
||||
====================
|
||||
|
||||
Datagrams are still a work-in-progress. They're enabled, but I don't know for
|
||||
sure how well they'll work yet. TCP is pretty good though.
|
||||
I need samcatd to accept a configuration folder identical to
|
||||
/etc/i2pd/tunnels.conf.d, since part of the point of this is to be compatible
|
||||
with i2pd's tunnels configuration. Once this is done, I'll resume turning it
|
||||
into a .deb package.
|
||||
|
||||
I'm in the process of adding client proxying to a specific i2p destination by
|
||||
base32 or (pre-added)jump address. TCP works well. UDP exists, but is not
|
||||
thoroughly tested.
|
||||
It doesn't encrypt the .i2pkeys file by default, so if someone can steal them,
|
||||
then they can use them to construct tunnels to impersonate you. Experimental
|
||||
support for encrypted saves has been added. The idea is that only the person
|
||||
with the key will be able to decrypt and start the tunnels. It is up to the user
|
||||
to determine how to go about managing these keys. Right now this system is
|
||||
pretty bad. I'll be addressing that soon too.
|
||||
|
||||
Experimental support for KCP-based error correction and streaming-over-datagrams
|
||||
is in the works. Some kind of reverse-proxy or filter is also an obvious choice.
|
||||
|
||||
I've only enabled the use of a subset of the i2cp and tunnel configuration
|
||||
options, the ones I use the most and for no other real reason assume other
|
||||
people use the most. They're pretty easy to add, it's just boring. *If you*
|
||||
*want an i2cp or tunnel option that isn't available, bring it to my attention*
|
||||
*please.* I'm pretty responsive when people actually contact me, it'll probably
|
||||
be added within 24 hours.
|
||||
be added within 24 hours. I intend to have configuration options for all
|
||||
relevant i2cp and tunnel options, which I'm keeping track of
|
||||
[here](config/CHECKLIST.md).
|
||||
|
||||
Encrypted leasesets are only half-implemented. The option seems to do nothing at
|
||||
the moment. Soon it will be configurable.
|
||||
I need to just change how the configuration is done entirely. I want it to work
|
||||
with the configuration formats used by each I2P router.
|
||||
|
||||
I should probably have some options that are available in other general network
|
||||
utilities like netcat and socat(ephsite may have it's name changed to samcat at
|
||||
that point). Configuring timeouts and the like. In order to do this, some of the
|
||||
existing flags should also be aliased to be more familiar and netcat-like.
|
||||
TLS configuration is experimental. I have decided to implement optional,
|
||||
automatically-configured self-signed TLS certificates. No CA support is planned
|
||||
as an alternative CA would have to be used and no apparent option exists which
|
||||
would be usable. If you're working on anything like that, I would like very
|
||||
to know.
|
||||
|
||||
I want it to be able to save ini files based on the settings used for a running
|
||||
forwarder. Should be easy, I just need to decide how I want to do it. Also to
|
||||
focus a bit more.
|
||||
## Stuff that's using it:
|
||||
|
||||
I've written a handful of example tools, but some of them might be better as
|
||||
their own projects. An i2p-native static site generator in the style of jekyll
|
||||
(but in go) could be cool.
|
||||
Mostly mine, but this is all Free-as-in-Freedom for anyone to use:
|
||||
|
||||
Haha. Well shit. I migrated colluding\_sites\_attack to auto-configure using
|
||||
the forwarder and the X-I2p-Dest* headers aren't passed through. Implies some
|
||||
interesting arrangements, but also makes colluding\_sites\_attack useless in
|
||||
it's present state. I mean I know what I did with si-i2p-plugin works, so it's
|
||||
not that important. I'll have to look for a way to make this behavior
|
||||
configurable though. On a related note, I finally know the difference between
|
||||
http tunnels and server tunnels.
|
||||
* [eephttpd](https://github.com/eyedeekay/eephttpd)
|
||||
* [my fork of wikigopher](https://github.com/eyedeekay/wikigopher)
|
||||
* [orangeforum](https://github.com/s-gv/orangeforum)
|
||||
|
||||
It would be really awesome if I could make this run on Android. So I'll make
|
||||
that happen eventually.
|
||||
Donate
|
||||
------
|
||||
|
||||
TLS configuration is experimental. It might not be possible(To multiplex http
|
||||
and https on the same SAM tunnel).
|
||||
### Monero Wallet Address
|
||||
|
||||
XMR:43V6cTZrUfAb9JD6Dmn3vjdT9XxLbiE27D1kaoehb359ACaHs8191mR4RsJH7hGjRTiAoSwFQAVdsCBToXXPAqTMDdP2bZB
|
||||
|
||||
### Bitcoin Wallet Address
|
||||
|
||||
BTC:159M8MEUwhTzE9RXmcZxtigKaEjgfwRbHt
|
||||
|
||||
Index
|
||||
-----
|
||||
|
||||
* [readme](index.html)
|
||||
* [usage](usage.html)
|
||||
* [configuration](packageconf.html)
|
||||
* [embedding](embedding.html)
|
||||
* [interface](interface.htnl)
|
||||
|
240
README.md.asc
240
README.md.asc
@@ -1,15 +1,20 @@
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA256
|
||||
Hash: SHA512
|
||||
|
||||
# sam-forwarder
|
||||
|
||||
Forward a local port to i2p over the SAM API, or proxy a destination to a port
|
||||
on the local host. This is a work-in-progress, but the basic functionality is,
|
||||
there and it's already pretty useful. Everything TCP works, but UDP forwarding
|
||||
is still not well tested, and UDP clients aren't enabled yet. I'm out of excuses
|
||||
not to finish it now, too.
|
||||
has much less real use than TCP. Turns out UDP was less broken than I thought
|
||||
though. Yay. There's also a simple client-server VPN built on top of it,
|
||||
eventually, it will be replaced with a peer-to-peer version.
|
||||
|
||||
Since it seems to be doing UDP now, if you'd like to donate to further
|
||||
development there are some wallet addresses at the bottom of this readme for
|
||||
now.
|
||||
|
||||
## building
|
||||
|
||||
Just:
|
||||
|
||||
make deps build
|
||||
@@ -18,173 +23,120 @@ and it will be in the folder ./bin/
|
||||
|
||||
[](https://travis-ci.org/eyedeekay/sam-forwarder)
|
||||
|
||||
## usage
|
||||
## Usage:
|
||||
|
||||
./bin/ephsite -host=host -port=port
|
||||
There are a number of ways to use sam-forwarder:
|
||||
|
||||
So, to serve an eepSite version of a local service on port 8080 -
|
||||
### [usage/configuration](docs/USAGE.md) as an application(Start here for samcatd)
|
||||
|
||||
./bin/ephsite -host=127.0.0.1 -port=8080
|
||||
### [embedding](docs/EMBEDDING.md) in other applications
|
||||
|
||||
For more information, [look here](USAGE.md)
|
||||
### [encapsulate](docs/PACKAGECONF.md) configuration for i2p-enabled packages
|
||||
|
||||
## ini-like configuration
|
||||
## binaries
|
||||
|
||||
I made it parse INI-like configuration files, optionally, which allows it to
|
||||
generate tunnels from snippets of i2pd tunnel configuration files. That's kinda
|
||||
useful. It appears to be more-or-less compatible with i2pd's tunnels.conf
|
||||
format, but it only supports the following options:
|
||||
Two binaries are produced by this repo. The first, ephsite, is only capable
|
||||
of running one tunnel at a time and doesn't have VPN support. I'm only updating
|
||||
it to make sure that the embeddable interface in existing applications doesn't
|
||||
change. It will go away and be replaced with a wrapper to translate it to
|
||||
'samcatd -s' commands whenever I complete [docs/CHECKLIST.md](docs/CHECKLIST.md).
|
||||
|
||||
type = server
|
||||
host = 127.0.0.1
|
||||
port = 8081
|
||||
dir = /path/to/save/data/in #This is not shared with i2pd tunnels.conf
|
||||
inbound.length = 6
|
||||
outbound.length = 6
|
||||
inbound.lengthVariance = 6
|
||||
outbound.lengthVariance = 6
|
||||
inbound.backupQuantity = 5
|
||||
outbound.backupQuantity = 5
|
||||
inbound.quantity = 15
|
||||
outbound.quantity = 15
|
||||
inbound.allowZeroHop = true
|
||||
outbound.allowZeroHop = true
|
||||
i2cp.encryptLeaseSet = true
|
||||
gzip = true
|
||||
i2cp.reduceOnIdle = true
|
||||
i2cp.reduceIdleTime = 3000000
|
||||
i2cp.reduceQuantity = 4
|
||||
i2cp.enableWhiteList = false
|
||||
i2cp.enableBlackList = true
|
||||
i2cp.accessList = BASE64KEYSSEPARATEDBY,COMMAS
|
||||
keys = forwarder
|
||||
|
||||
Also it doesn't support sections. Didn't realize that at first. Will address
|
||||
soon.
|
||||
|
||||
Other options are added to the config structure, but have to be referenced
|
||||
manually, there are no convenience functions for them.
|
||||
|
||||
## Static eepsite in like no seconds
|
||||
|
||||
Using this port forwarder, it's possible to create an instant eepsite from a
|
||||
folder full of html files(and the resources they call upon). Probably obviously
|
||||
to everybody reading this right now, but maybe not obviously to everyone reading
|
||||
this forever. A go application that does this I call eephttpd can be built with
|
||||
the command:
|
||||
|
||||
make server
|
||||
|
||||
and run from ./bin/eephttpd. The default behavior is to look for the files to
|
||||
serve under the current directory in ./www. It can be configured to behave
|
||||
differently according to the rules in [USAGE.md](USAGE.md). A Dockerfile is also
|
||||
available.
|
||||
|
||||
## Quick-And-Dirty i2p-enabled golang web applications
|
||||
|
||||
Normal web applications can easily add the ability to serve itself over i2p by
|
||||
importing and configuring this forwarding doodad. Wherever it takes the argument
|
||||
for the web server's listening host and/or port, pass that same host and/or port
|
||||
to a new instance of the "SAMForwarder" and then run the "Serve" function of the
|
||||
SAMForwarder as a goroutine. This simply forwards the running service to the i2p
|
||||
network, it doesn't do any filtering, and if your application establishes
|
||||
out-of-band connections, those may escape. Also, if your application is
|
||||
listening on all addresses, it will be visible from the local network.
|
||||
|
||||
Here's a simple example with a simple static file server:
|
||||
|
||||
```Diff
|
||||
package main package main
|
||||
|
||||
import ( import (
|
||||
"flag" "flag"
|
||||
"log" "log"
|
||||
"net/http" "net/http"
|
||||
) )
|
||||
|
||||
> import "github.com/eyedeekay/sam-forwarder"
|
||||
>
|
||||
func main() { func main() {
|
||||
port := flag.String("p", "8100", "port to serve on") port := flag.String("p", "8100", "port to serve on")
|
||||
directory := flag.String("d", ".", "the directory of static file to host") directory := flag.String("d", ".", "the directory of static file to host")
|
||||
flag.Parse() flag.Parse()
|
||||
>
|
||||
> forwarder, err := samforwarder.NewSAMForwarderFromOptions(
|
||||
> samforwarder.SetHost("127.0.0.1"),
|
||||
> samforwarder.SetPort(*port),
|
||||
> samforwarder.SetSAMHost("127.0.0.1"),
|
||||
> samforwarder.SetSAMPort("7656"),
|
||||
> samforwarder.SetName("staticfiles"),
|
||||
> )
|
||||
> if err != nil {
|
||||
> log.Fatal(err.Error())
|
||||
> }
|
||||
> go forwarder.Serve()
|
||||
|
||||
http.Handle("/", http.FileServer(http.Dir(*directory))) http.Handle("/", http.FileServer(http.Dir(*directory)))
|
||||
|
||||
log.Printf("Serving %s on HTTP port: %s\n", *directory, *port) log.Printf("Serving %s on HTTP port: %s\n", *directory, *port)
|
||||
log.Fatal(http.ListenAndServe("127.0.0.1:"+*port, nil)) log.Fatal(http.ListenAndServe("127.0.0.1:"+*port, nil))
|
||||
} }
|
||||
|
||||
```
|
||||
|
||||
[This tiny file server taken from here and used for this example](https://gist.github.com/paulmach/7271283)
|
||||
The second, samcatd, is more advanced. It can start multiple tunnels with their
|
||||
own settings, or be used to start tunnels on the fly like ephsite by passing the
|
||||
- -s option. Eventually I'm probably just going to use this to configure all of my
|
||||
tunnels.
|
||||
|
||||
Current limitations:
|
||||
====================
|
||||
|
||||
Datagrams are still a work-in-progress. They're enabled, but I don't know for
|
||||
sure how well they'll work yet. TCP is pretty good though.
|
||||
I need to document it better.
|
||||
[Besides fixing up the comments, this should help for now.](docs/USAGE.md). I
|
||||
also need to control output verbosity better.
|
||||
|
||||
I'm in the process of adding client proxying to a specific i2p destination by
|
||||
base32 or (pre-added)jump address. TCP works well. UDP exists, but is not
|
||||
thoroughly tested.
|
||||
I need samcatd to accept a configuration folder identical to
|
||||
/etc/i2pd/tunnels.conf.d, since part of the point of this is to be compatible
|
||||
with i2pd's tunnels configuration. Once this is done, I'll resume turning it
|
||||
into a .deb package.
|
||||
|
||||
It doesn't encrypt the .i2pkeys file by default, so if someone can steal them,
|
||||
then they can use them to construct tunnels to impersonate you. Experimental
|
||||
support for encrypted saves has been added. The idea is that only the person
|
||||
with the key will be able to decrypt and start the tunnels. It is up to the user
|
||||
to determine how to go about managing these keys. Right now this system is
|
||||
pretty bad. I'll be addressing that soon too.
|
||||
|
||||
TCP and UDP are both working now. Additional functionality might be added by
|
||||
adding other kinds of protocols overtop the TCP and UDP tunnels as a primitive.
|
||||
There's a very basic UDP-based VPN available in samcatd by configuration-file
|
||||
only for now. Also it requires root. Probably need to split the VPN part into
|
||||
it's own application. The package will need to give the application
|
||||
CAP\_NET\_BIND\_SERVICE or something. This might work:
|
||||
|
||||
sudo setcap cap_net_bind_service=epi ./bin/samcatd
|
||||
sudo setcap cap_net_bind_service=epi ./bin/samcatd-web
|
||||
|
||||
But I need to learn more about capabilities before I make that part of the
|
||||
thing.
|
||||
|
||||
Some kind of reverse-proxy or filter is also an obvious choice.
|
||||
|
||||
I've only enabled the use of a subset of the i2cp and tunnel configuration
|
||||
options, the ones I use the most and for no other real reason assume other
|
||||
people use the most. They're pretty easy to add, it's just boring. *If you*
|
||||
*want an i2cp or tunnel option that isn't available, bring it to my attention*
|
||||
*please.* I'm pretty responsive when people actually contact me, it'll probably
|
||||
be added within 24 hours.
|
||||
|
||||
Encrypted leasesets are only half-implemented. The option seems to do nothing at
|
||||
the moment. Soon it will be configurable.
|
||||
be added within 24 hours. I intend to have configuration options for all
|
||||
relevant i2cp and tunnel options, which I'm keeping track of
|
||||
[here](config/CHECKLIST.md).
|
||||
|
||||
I should probably have some options that are available in other general network
|
||||
utilities like netcat and socat(ephsite may have it's name changed to samcat at
|
||||
that point). Configuring timeouts and the like. In order to do this, some of the
|
||||
existing flags should also be aliased to be more familiar and netcat-like.
|
||||
utilities. I've started to do this with samcatd.
|
||||
|
||||
I want it to be able to save ini files based on the settings used for a running
|
||||
forwarder. Should be easy, I just need to decide how I want to do it. Also to
|
||||
focus a bit more.
|
||||
focus a bit more. I've got more of a plan here now. tunconf has the loaded ini
|
||||
file inside it, and variables to track the state of the config options while
|
||||
running, and they can be switched to save options that might be changed via some
|
||||
interface or another.
|
||||
|
||||
I've written a handful of example tools, but some of them might be better as
|
||||
their own projects. An i2p-native static site generator in the style of jekyll
|
||||
(but in go) could be cool.
|
||||
|
||||
Haha. Well shit. I migrated colluding\_sites\_attack to auto-configure using
|
||||
the forwarder and the X-I2p-Dest* headers aren't passed through. Implies some
|
||||
interesting arrangements, but also makes colluding\_sites\_attack useless in
|
||||
it's present state. I mean I know what I did with si-i2p-plugin works, so it's
|
||||
not that important. I'll have to look for a way to make this behavior
|
||||
configurable though. On a related note, I finally know the difference between
|
||||
http tunnels and server tunnels.
|
||||
Example tools built using this are being broken off into their own repos. Use
|
||||
the other repos where appropriate, so I can leave the examples un-messed with.
|
||||
|
||||
It would be really awesome if I could make this run on Android. So I'll make
|
||||
that happen eventually.
|
||||
that happen eventually. I started a daemon for managing multiple tunnels and I
|
||||
figure I give it a web interface to configure stuff with. I'll probably put that
|
||||
in a different repo though. This is looking a little cluttered.
|
||||
|
||||
TLS configuration is experimental. It might not be possible(To multiplex http
|
||||
and https on the same SAM tunnel).
|
||||
TLS configuration is experimental.
|
||||
|
||||
I've made it self-supervising, but I need to make better use of contexts.
|
||||
|
||||
## Stuff that's using it:
|
||||
|
||||
Mostly mine, but this is all Free-as-in-Freedom for anyone to use:
|
||||
|
||||
* [eephttpd](https://github.com/eyedeekay/eephttpd)
|
||||
* [my fork of wikigopher](https://github.com/eyedeekay/wikigopher)
|
||||
* [orangeforum](https://github.com/s-gv/orangeforum)
|
||||
|
||||
Donate
|
||||
- ------
|
||||
|
||||
### Monero Wallet Address
|
||||
|
||||
XMR:43V6cTZrUfAb9JD6Dmn3vjdT9XxLbiE27D1kaoehb359ACaHs8191mR4RsJH7hGjRTiAoSwFQAVdsCBToXXPAqTMDdP2bZB
|
||||
|
||||
### Bitcoin Wallet Address
|
||||
|
||||
BTC:159M8MEUwhTzE9RXmcZxtigKaEjgfwRbHt
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQEzBAEBCAAdFiEEcNIGBzi++AUjrK/311wDs5teFOEFAluW3DMACgkQ11wDs5te
|
||||
FOEtsAf9FPNwaocFwDStpEfWPs3ko8mI/34kJ+DXcCAFzWIKYimKD6vbOLl5vqIn
|
||||
4HfGpsZaEMTVhW4kcAks9NQlDE3/yAMv7QRSX3pQTinXnXk13UdMbAG5oWUuKiSV
|
||||
KBmqY7R9wwQu8JElW7iv84Ajl+9UrQeo5mMvp0jXkVbX0ZnCE/2spmhC+B1MySM3
|
||||
df7ogmXbeoqOZc/FFGJjKGXtCLw8/MYuB7LfPCAoenOCVa2Hp17ujpPT4SyaXj29
|
||||
bmhGCPdU0lf6Tp3IKXgi71nsIb7qtPSaY1f2B8n946YqXzT9/ys2BZ8OdvVPgZsP
|
||||
P/DHK8YM/ayaciJ4RslbITaDygOR4A==
|
||||
=bJY2
|
||||
iQEzBAEBCgAdFiEEcNIGBzi++AUjrK/311wDs5teFOEFAlxfdWIACgkQ11wDs5te
|
||||
FOH2Hwf+L63UsgKujukILs6/vPFe5rTvqVpM1NXko+49KcI8M0toiOS3Fqq66n4R
|
||||
o3iy7bKR9W0wlkbvXrhCAI6QHT4C4Rv3lneN18+Lw3L5l7AzbSqa/+nHGj7IoVg3
|
||||
5U8IH0HRv3LvAA4PJhmYmKCU/zO0Cblc8n1hFtVlT6Xby4NUNypqVRh9SK9NFg+i
|
||||
AcenunoBMD6ggYR0nEZ9gKRW2LNY7+0kGc4oCwckQ5I9j1PIbhpwsQjVunLEUmd+
|
||||
x1fFd4gzt4mnih06XkyVNbggMZQmgJ+BRv5kBMBlpfzrSsaFcolRRrvNeua2uLWm
|
||||
3RZgd29GUvDU7OPALdbUcy0+a0Q6+g==
|
||||
=0nQN
|
||||
-----END PGP SIGNATURE-----
|
||||
|
173
USAGE.md
173
USAGE.md
@@ -1,173 +0,0 @@
|
||||
ephsite - Easy forwarding of local services to i2p
|
||||
==================================================
|
||||
|
||||
ephsite is a forwarding proxy designed to configure a tunnel for use
|
||||
with i2p. It can be used to easily forward a local service to the
|
||||
i2p network using i2p's SAM API instead of the tunnel interface.
|
||||
|
||||
usage:
|
||||
------
|
||||
|
||||
```
|
||||
Usage of ./bin/ephsite:
|
||||
-access string
|
||||
Type of access list to use, can be "whitelist" "blacklist" or "none". (default "none")
|
||||
-accesslist value
|
||||
Specify an access list member(can be used multiple times)
|
||||
-client
|
||||
Client proxy mode(true or false)
|
||||
-close
|
||||
Close tunnel idle(true or false)
|
||||
-closetime int
|
||||
Reduce tunnel quantity after X (milliseconds) (default 600000)
|
||||
-dest string
|
||||
Destination for client tunnels. Ignored for service tunnels. (default "none")
|
||||
-dir string
|
||||
Directory to save tunnel configuration file in.
|
||||
-encryptlease
|
||||
Use an encrypted leaseset(true or false) (default true)
|
||||
-gzip
|
||||
Uze gzip(true or false)
|
||||
-host string
|
||||
Target host(Host of service to forward to i2p) (default "127.0.0.1")
|
||||
-inback int
|
||||
Set inbound tunnel backup quantity(0 to 5) (default 4)
|
||||
-incount int
|
||||
Set inbound tunnel quantity(0 to 15) (default 6)
|
||||
-ini string
|
||||
Use an ini file for configuration(config file options override passed arguments for now.) (default "none")
|
||||
-inlen int
|
||||
Set inbound tunnel length(0 to 7) (default 3)
|
||||
-invar int
|
||||
Set inbound tunnel length variance(-7 to 7)
|
||||
-lsk string
|
||||
path to saved encrypted leaseset keys (default "none")
|
||||
-name string
|
||||
Tunnel name, this must be unique but can be anything. (default "forwarder")
|
||||
-outback int
|
||||
Set outbound tunnel backup quantity(0 to 5) (default 4)
|
||||
-outcount int
|
||||
Set outbound tunnel quantity(0 to 15) (default 6)
|
||||
-outlen int
|
||||
Set outbound tunnel length(0 to 7) (default 3)
|
||||
-outvar int
|
||||
Set outbound tunnel length variance(-7 to 7)
|
||||
-port string
|
||||
Target port(Port of service to forward to i2p) (default "8081")
|
||||
-reduce
|
||||
Reduce tunnel quantity when idle(true or false)
|
||||
-reducecount int
|
||||
Reduce idle tunnel quantity to X (0 to 5) (default 3)
|
||||
-reducetime int
|
||||
Reduce tunnel quantity after X (milliseconds) (default 600000)
|
||||
-samhost string
|
||||
SAM host (default "127.0.0.1")
|
||||
-samport string
|
||||
SAM port (default "7656")
|
||||
-save
|
||||
Use saved file and persist tunnel(If false, tunnel will not persist after program is stopped.
|
||||
-tlsport string
|
||||
(Currently inoperative. Target TLS port(HTTPS Port of service to forward to i2p)
|
||||
-udp
|
||||
UDP mode(true or false)
|
||||
-zeroin
|
||||
Allow zero-hop, non-anonymous tunnels in(true or false)
|
||||
-zeroout
|
||||
Allow zero-hop, non-anonymous tunnels out(true or false)
|
||||
```
|
||||
|
||||
eephttpd - Static file server automatically forwarded to i2p
|
||||
============================================================
|
||||
|
||||
usage:
|
||||
------
|
||||
|
||||
eephttpd is a static http server which automatically runs on i2p with
|
||||
the help of the SAM bridge. By default it will only be available from
|
||||
the localhost and it's i2p tunnel. It can be masked from the localhost
|
||||
using a container.
|
||||
|
||||
```
|
||||
Usage of ./bin/eephttpd:
|
||||
-a string
|
||||
hostname to serve on (default "127.0.0.1")
|
||||
-c Use an encrypted leaseset(true or false)
|
||||
-d string
|
||||
the directory of static files to host(default ./www) (default "./www")
|
||||
-f string
|
||||
Use an ini file for configuration (default "none")
|
||||
-g Uze gzip(true or false) (default true)
|
||||
-i save i2p keys(and thus destinations) across reboots (default true)
|
||||
-ib int
|
||||
Set inbound tunnel backup quantity(0 to 5) (default 4)
|
||||
-il int
|
||||
Set inbound tunnel length(0 to 7) (default 3)
|
||||
-iq int
|
||||
Set inbound tunnel quantity(0 to 15) (default 8)
|
||||
-iv int
|
||||
Set inbound tunnel length variance(-7 to 7)
|
||||
-l string
|
||||
Type of access list to use, can be "whitelist" "blacklist" or "none". (default "none")
|
||||
-m string
|
||||
Certificate name to use (default "cert")
|
||||
-n string
|
||||
name to give the tunnel(default static-eepSite) (default "static-eepSite")
|
||||
-ob int
|
||||
Set outbound tunnel backup quantity(0 to 5) (default 4)
|
||||
-ol int
|
||||
Set outbound tunnel length(0 to 7) (default 3)
|
||||
-oq int
|
||||
Set outbound tunnel quantity(0 to 15) (default 8)
|
||||
-ov int
|
||||
Set outbound tunnel length variance(-7 to 7)
|
||||
-p string
|
||||
port to serve locally on (default "7880")
|
||||
-r Reduce tunnel quantity when idle(true or false)
|
||||
-rc int
|
||||
Reduce idle tunnel quantity to X (0 to 5) (default 3)
|
||||
-rt int
|
||||
Reduce tunnel quantity after X (milliseconds) (default 600000)
|
||||
-s string
|
||||
the directory to save the keys in(default ./) (default ".")
|
||||
-sh string
|
||||
sam host to connect to (default "127.0.0.1")
|
||||
-sp string
|
||||
sam port to connect to (default "7656")
|
||||
-t Generate or use an existing TLS certificate
|
||||
-z Allow zero-hop, non-anonymous tunnels(true or false)
|
||||
```
|
||||
|
||||
### build in docker
|
||||
|
||||
```
|
||||
docker build --build-arg user=eephttpd --build-arg path=example/www -f Dockerfile -t eyedeekay/eephttpd .
|
||||
```
|
||||
|
||||
### Run in docker
|
||||
|
||||
```
|
||||
docker run -i -t -d \
|
||||
--name eephttpd-volume \
|
||||
--volume eephttpd:/home/eephttpd/ \
|
||||
eyedeekay/eephttpd
|
||||
```
|
||||
|
||||
```
|
||||
docker run -i -t -d \
|
||||
--network si \
|
||||
--env samhost=sam-host \
|
||||
--env samport=7656 \
|
||||
--env args=-r # Additional arguments to pass to eephttpd\
|
||||
--network-alias eephttpd \
|
||||
--hostname eephttpd \
|
||||
--name eephttpd \
|
||||
--restart always \
|
||||
--volumes-from eephttpd-volume \
|
||||
eyedeekay/eephttpd
|
||||
```
|
||||
|
||||
instance
|
||||
--------
|
||||
|
||||
a running instance of eephttpd with the example index file is availble on
|
||||
|
107
config/CHECKLIST.md
Normal file
107
config/CHECKLIST.md
Normal file
@@ -0,0 +1,107 @@
|
||||
I2CP/Tunnel Options Implementation Checklist
|
||||
============================================
|
||||
|
||||
This version of this document is valid for sam-forwarder. If you'd like to use
|
||||
it, the original is at [CHECKLIST.orig.md](CHECKLIST.orig.md).
|
||||
|
||||
key:
|
||||
|
||||
- \[U\] - Undone/Unknown
|
||||
- \[C\] - Confirmed Working
|
||||
- \[W\] - Work in progress
|
||||
- \[N\] - Not applicable/Won't be implemented without good reason.
|
||||
- \[*\] - See also
|
||||
|
||||
Version Recommended Allowable Default
|
||||
[U] - clientMessageTimeout 8*1000 - 120*1000 60*1000 The timeout (ms) for all sent messages. Unused. See the protocol specification for per-message settings.
|
||||
[N] - crypto.lowTagThreshold 0.9.2 1-128 30 Minimum number of ElGamal/AES Session Tags before we send more. Recommended: approximately tagsToSend * 2/3
|
||||
[N] - crypto.tagsToSend 0.9.2 1-128 40 Number of ElGamal/AES Session Tags to send at a time. For clients with relatively low bandwidth per-client-pair (IRC, some UDP apps), this may be set lower.
|
||||
[U] - explicitPeers null Comma-separated list of Base 64 Hashes of peers to build tunnels through; for debugging only
|
||||
[C] - i2cp.dontPublishLeaseSet true,false false Should generally be set to true for clients and false for servers
|
||||
[C] - i2cp.fastReceive 0.9.4 true,false false If true, the router just sends the MessagePayload instead of sending a MessageStatus and awaiting a ReceiveMessageBegin.
|
||||
[C] - i2cp.messageReliability BestEffort, None BestEffort Guaranteed is disabled; None implemented in 0.8.1; the streaming lib default is None as of 0.8.1, the client side default is None as of 0.9.4
|
||||
[U] - i2cp.password 0.8.2 string For authorization, if required by the router. If the client is running in the same JVM as a router, this option is not required. Warning - username and password are sent in the clear to the router, unless using SSL (i2cp.SSL=true). Authorization is only recommended when using SSL.
|
||||
[U] - i2cp.username 0.8.2 string
|
||||
[C] - inbound.allowZeroHop true,false true If incoming zero hop tunnel is allowed
|
||||
[C] - outbound.allowZeroHop true,false true If outgoing zero hop tunnel is allowed
|
||||
[C] - inbound.backupQuantity 0 to 3 No limit 0 Number of redundant fail-over for tunnels in
|
||||
[C] - outbound.backupQuantity 0 to 3 No limit 0 Number of redundant fail-over for tunnels out
|
||||
[U] - inbound.IPRestriction 0 to 4 0 to 4 2 Number of IP bytes to match to determine if two routers should not be in the same tunnel. 0 to disable.
|
||||
[U] - outbound.IPRestriction 0 to 4 0 to 4 2 Number of IP bytes to match to determine if two routers should not be in the same tunnel. 0 to disable.
|
||||
[C] - inbound.length 0 to 3 0 to 7 3 Length of tunnels in
|
||||
[C] - outbound.length 0 to 3 0 to 7 3 Length of tunnels out
|
||||
[C] - inbound.lengthVariance -1 to 2 -7 to 7 0 Random amount to add or subtract to the length of tunnels in. A positive number x means add a random amount from 0 to x inclusive. A negative number -x means add a random amount from -x to x inclusive. The router will limit the total length of the tunnel to 0 to 7 inclusive. The default variance was 1 prior to release 0.7.6.
|
||||
[C] - outbound.lengthVariance -1 to 2 -7 to 7 0 Random amount to add or subtract to the length of tunnels out. A positive number x means add a random amount from 0 to x inclusive. A negative number -x means add a random amount from -x to x inclusive. The router will limit the total length of the tunnel to 0 to 7 inclusive. The default variance was 1 prior to release 0.7.6.
|
||||
[U] - inbound.nickname string Name of tunnel - generally used in routerconsole, which will use the first few characters of the Base64 hash of the destination by default.
|
||||
[U] - outbound.nickname string Name of tunnel - generally ignored unless inbound.nickname is unset.
|
||||
[U] - outbound.priority 0.9.4 -25 to 25 -25 to 25 0 Priority adjustment for outbound messages. Higher is higher priority.
|
||||
[C] - inbound.quantity 1 to 3 1 to 16 2 Number of tunnels in. Limit was increased from 6 to 16 in release 0.9; however, numbers higher than 6 are incompatible with older releases.
|
||||
[C] - outbound.quantity 1 to 3 No limit 2 Number of tunnels out
|
||||
[U] - inbound.randomKey 0.9.17 Base 64 encoding of 32 random bytes Used for consistent peer ordering across restarts.
|
||||
[U] - outbound.randomKey 0.9.17 Base 64 encoding of 32 random bytes Used for consistent peer ordering across restarts.
|
||||
[*] - inbound.* Any other options prefixed with "inbound." are stored in the "unknown options" properties of the inbound tunnel pool's settings.
|
||||
[*] - outbound.* Any other options prefixed with "outbound." are stored in the "unknown options" properties of the outbound tunnel pool's settings.
|
||||
[U] - shouldBundleReplyInfo 0.9.2 true,false true Set to false to disable ever bundling a reply LeaseSet. For clients that do not publish their LeaseSet, this option must be true for any reply to be possible. "true" is also recommended for multihomed servers with long connection times. Setting to "false" may save significant outbound bandwidth, especially if the client is configured with a large number of inbound tunnels (Leases). If replies are still required, this may shift the bandwidth burden to the far-end client and the floodfill. There are several cases where "false" may be appropriate: Unidirectional communication, no reply required LeaseSet is published and higher reply latency is acceptable LeaseSet is published, client is a "server", all connections are inbound so the connecting far-end destination obviously has the leaseset already. Connections are either short, or it is acceptable for latency on a long-lived connection to temporarily increase while the other end re-fetches the LeaseSet after expiration. HTTP servers may fit these requirements.
|
||||
[C] - i2cp.closeIdleTime 0.7.1 1800000 300000 minimum (ms) Idle time required (default 30 minutes)
|
||||
[C] - i2cp.closeOnIdle 0.7.1 true,false false Close I2P session when idle
|
||||
[C] - i2cp.encryptLeaseSet 0.7.1 true,false false Encrypt the lease
|
||||
[C] - i2cp.fastReceive 0.9.4 true,false true If true, the router just sends the MessagePayload instead of sending a MessageStatus and awaiting a ReceiveMessageBegin.
|
||||
[C] - i2cp.gzip 0.6.5 true,false true Gzip outbound data
|
||||
[C] - i2cp.leaseSetKey 0.7.1 For encrypted leasesets. Base 64 SessionKey (44 characters)
|
||||
[C] - i2cp.leaseSetPrivateKey 0.9.18 Base 64 private key for encryption. Optionally preceded by the key type and ':'. Only "ELGAMAL_2048:" is supported, which is the default. I2CP will generate the public key from the private key. Use for persistent leaseset keys across restarts.
|
||||
[C] - i2cp.leaseSetSigningPrivateKey 0.9.18 Base 64 private key for signatures. Optionally preceded by the key type and ':'. DSA_SHA1 is the default. Key type must match the signature type in the destination. I2CP will generate the public key from the private key. Use for persistent leaseset keys across restarts.
|
||||
[C] - i2cp.reduceIdleTime 0.7.1 1200000 300000 minimum (ms) Idle time required (default 20 minutes, minimum 5 minutes)
|
||||
[C] - i2cp.reduceOnIdle 0.7.1 true,false false Reduce tunnel quantity when idle
|
||||
[C] - i2cp.reduceQuantity 0.7.1 1 1 to 5 1 Tunnel quantity when reduced (applies to both inbound and outbound)
|
||||
[*] - i2cp.SSL 0.8.3 true,false false Connect to the router using SSL. If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.
|
||||
[*] - i2cp.tcp.host 127.0.0.1 Router hostname. If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.
|
||||
[*] - i2cp.tcp.port 1-65535 7654 Router I2CP port. If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.
|
||||
|
||||
Default Description
|
||||
[C] - i2cp.accessList null Comma- or space-separated list of Base64 peer Hashes used for either access list or blocklist. As of release 0.7.13.
|
||||
[U] - i2cp.destination.sigType DSA_SHA1 Use the access list as a allowlist for incoming connections. The name or number of the signature type for a transient destination. As of release 0.9.12.
|
||||
[C] - i2cp.enableAccessList false Use the access list as a allowlist for incoming connections. As of release 0.7.13.
|
||||
[C] - i2cp.enableBlackList false Use the access list as a blocklist for incoming connections. As of release 0.7.13.
|
||||
[U] - i2p.streaming.answerPings true Whether to respond to incoming pings
|
||||
[U] - i2p.streaming.blocklist null Comma- or space-separated list of Base64 peer Hashes to be blocklisted for incoming connections to ALL destinations in the context. This option must be set in the context properties, NOT in the createManager() options argument. Note that setting this in the router context will not affect clients outside the router in a separate JVM and context. As of release 0.9.3.
|
||||
[U] - i2p.streaming.bufferSize 64K How much transmit data (in bytes) will be accepted that hasn't been written out yet.
|
||||
[U] - i2p.streaming.congestionAvoidanceGrowthRateFactor 1 When we're in congestion avoidance, we grow the window size at the rate of 1/(windowSize*factor). In standard TCP, window sizes are in bytes, while in I2P, window sizes are in messages. A higher number means slower growth.
|
||||
[U] - i2p.streaming.connectDelay -1 How long to wait after instantiating a new con before actually attempting to connect. If this is <= 0, connect immediately with no initial data. If greater than 0, wait until the output stream is flushed, the buffer fills, or that many milliseconds pass, and include any initial data with the SYN.
|
||||
[U] - i2p.streaming.connectTimeout 5*60*1000 How long to block on connect, in milliseconds. Negative means indefinitely. Default is 5 minutes.
|
||||
[U] - i2p.streaming.disableRejectLogging false Whether to disable warnings in the logs when an incoming connection is rejected due to connection limits. As of release 0.9.4.
|
||||
[U] - i2p.streaming.dsalist null Comma- or space-separated list of Base64 peer Hashes or host names to be contacted using an alternate DSA destination. Only applies if multisession is enabled and the primary session is non-DSA (generally for shared clients only). This option must be set in the context properties, NOT in the createManager() options argument. Note that setting this in the router context will not affect clients outside the router in a separate JVM and context. As of release 0.9.21.
|
||||
[U] - i2p.streaming.enforceProtocol true Whether to listen only for the streaming protocol. Setting to true will prohibit communication with Destinations earlier than release 0.7.1 (released March 2009). Set to true if running multiple protocols on this Destination. As of release 0.9.1. Default true as of release 0.9.36.
|
||||
[U] - i2p.streaming.inactivityAction 2 (send) (0=noop, 1=disconnect) What to do on an inactivity timeout - do nothing, disconnect, or send a duplicate ack.
|
||||
[U] - i2p.streaming.inactivityTimeout 90*1000 Idle time before sending a keepalive
|
||||
[U] - i2p.streaming.initialAckDelay 750 Delay before sending an ack
|
||||
[U] - i2p.streaming.initialResendDelay 1000 The initial value of the resend delay field in the packet header, times 1000. Not fully implemented; see below.
|
||||
[U] - i2p.streaming.initialRTO 9000 Initial timeout (if no sharing data available). As of release 0.9.8.
|
||||
[U] - i2p.streaming.initialRTT 8000 Initial round trip time estimate (if no sharing data available). Disabled as of release 0.9.8; uses actual RTT.
|
||||
[U] - i2p.streaming.initialWindowSize 6 (if no sharing data available) In standard TCP, window sizes are in bytes, while in I2P, window sizes are in messages.
|
||||
[U] - i2p.streaming.limitAction reset What action to take when an incoming connection exceeds limits. Valid values are: reset (reset the connection); drop (drop the connection); or http (send a hardcoded HTTP 429 response). Any other value is a custom response to be sent. backslash-r and backslash-n will be replaced with CR and LF. As of release 0.9.34.
|
||||
[U] - i2p.streaming.maxConcurrentStreams -1 (0 or negative value means unlimited) This is a total limit for incoming and outgoing combined.
|
||||
[U] - i2p.streaming.maxConnsPerMinute 0 Incoming connection limit (per peer; 0 means disabled) As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxConnsPerHour 0 (per peer; 0 means disabled) As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxConnsPerDay 0 (per peer; 0 means disabled) As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxMessageSize 1730 The MTU in bytes.
|
||||
[U] - i2p.streaming.maxResends 8 Maximum number of retransmissions before failure.
|
||||
[U] - i2p.streaming.maxTotalConnsPerMinute 0 Incoming connection limit (all peers; 0 means disabled) As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxTotalConnsPerHour 0 (all peers; 0 means disabled) Use with caution as exceeding this will disable a server for a long time. As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxTotalConnsPerDay 0 (all peers; 0 means disabled) Use with caution as exceeding this will disable a server for a long time. As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxWindowSize 128
|
||||
[U] - i2p.streaming.profile 1 (bulk) (2=interactive not supported) This doesn't currently do anything, but setting it to a value other than 1 will cause an error.
|
||||
[U] - i2p.streaming.readTimeout -1 How long to block on read, in milliseconds. Negative means indefinitely.
|
||||
[U] - i2p.streaming.slowStartGrowthRateFactor 1 When we're in slow start, we grow the window size at the rate of 1/(factor). In standard TCP, window sizes are in bytes, while in I2P, window sizes are in messages. A higher number means slower growth.
|
||||
[U] - i2p.streaming.tcbcache.rttDampening 0.75 Ref: RFC 2140. Floating point value. May be set only via context properties, not connection options. As of release 0.9.8.
|
||||
[U] - i2p.streaming.tcbcache.rttdevDampening 0.75 Ref: RFC 2140. Floating point value. May be set only via context properties, not connection options. As of release 0.9.8.
|
||||
[U] - i2p.streaming.tcbcache.wdwDampening 0.75 Ref: RFC 2140. Floating point value. May be set only via context properties, not connection options. As of release 0.9.8.
|
||||
[U] - i2p.streaming.writeTimeout -1 How long to block on write/flush, in milliseconds. Negative means indefinitely.
|
||||
|
||||
[C] - destination useful to consider adding to custom applications for client ocnfiguration
|
||||
|
||||
\* : I'd like to have something like this setting internal to samcatd, but it
|
||||
might not always be relevant to pass it through to the real i2p router. Right
|
||||
now, I'm leaning toward a samcatd specific setting, but maybe just alter the
|
||||
behavior of this setting for use with samcatd instead? Probably just give
|
||||
samcatd it's own thing.
|
||||
|
97
config/CHECKLIST.orig.md
Normal file
97
config/CHECKLIST.orig.md
Normal file
@@ -0,0 +1,97 @@
|
||||
I2CP/Tunnel Options Implementation Checklist
|
||||
============================================
|
||||
|
||||
key:
|
||||
|
||||
- \[U\] - Undone/Unknoqn
|
||||
- \[C\] - Confirmed Working
|
||||
- \[W\] - Work in progress
|
||||
- \[N\] - Not applicable
|
||||
- \[*\] - See also
|
||||
|
||||
Version Recommended Allowable Default
|
||||
[U] - clientMessageTimeout 8*1000 - 120*1000 60*1000 The timeout (ms) for all sent messages. Unused. See the protocol specification for per-message settings.
|
||||
[U] - crypto.lowTagThreshold 0.9.2 1-128 30 Minimum number of ElGamal/AES Session Tags before we send more. Recommended: approximately tagsToSend * 2/3
|
||||
[U] - crypto.tagsToSend 0.9.2 1-128 40 Number of ElGamal/AES Session Tags to send at a time. For clients with relatively low bandwidth per-client-pair (IRC, some UDP apps), this may be set lower.
|
||||
[U] - explicitPeers null Comma-separated list of Base 64 Hashes of peers to build tunnels through; for debugging only
|
||||
[U] - i2cp.dontPublishLeaseSet true,false false Should generally be set to true for clients and false for servers
|
||||
[U] - i2cp.fastReceive 0.9.4 true,false false If true, the router just sends the MessagePayload instead of sending a MessageStatus and awaiting a ReceiveMessageBegin.
|
||||
[U] - i2cp.messageReliability BestEffort, None BestEffort Guaranteed is disabled; None implemented in 0.8.1; the streaming lib default is None as of 0.8.1, the client side default is None as of 0.9.4
|
||||
[U] - i2cp.password 0.8.2 string For authorization, if required by the router. If the client is running in the same JVM as a router, this option is not required. Warning - username and password are sent in the clear to the router, unless using SSL (i2cp.SSL=true). Authorization is only recommended when using SSL.
|
||||
[U] - i2cp.username 0.8.2 string
|
||||
[U] - inbound.allowZeroHop true,false true If incoming zero hop tunnel is allowed
|
||||
[U] - outbound.allowZeroHop true,false true If outgoing zero hop tunnel is allowed
|
||||
[U] - inbound.backupQuantity 0 to 3 No limit 0 Number of redundant fail-over for tunnels in
|
||||
[U] - outbound.backupQuantity 0 to 3 No limit 0 Number of redundant fail-over for tunnels out
|
||||
[U] - inbound.IPRestriction 0 to 4 0 to 4 2 Number of IP bytes to match to determine if two routers should not be in the same tunnel. 0 to disable.
|
||||
[U] - outbound.IPRestriction 0 to 4 0 to 4 2 Number of IP bytes to match to determine if two routers should not be in the same tunnel. 0 to disable.
|
||||
[U] - inbound.length 0 to 3 0 to 7 3 Length of tunnels in
|
||||
[U] - outbound.length 0 to 3 0 to 7 3 Length of tunnels out
|
||||
[U] - inbound.lengthVariance -1 to 2 -7 to 7 0 Random amount to add or subtract to the length of tunnels in. A positive number x means add a random amount from 0 to x inclusive. A negative number -x means add a random amount from -x to x inclusive. The router will limit the total length of the tunnel to 0 to 7 inclusive. The default variance was 1 prior to release 0.7.6.
|
||||
[U] - outbound.lengthVariance -1 to 2 -7 to 7 0 Random amount to add or subtract to the length of tunnels out. A positive number x means add a random amount from 0 to x inclusive. A negative number -x means add a random amount from -x to x inclusive. The router will limit the total length of the tunnel to 0 to 7 inclusive. The default variance was 1 prior to release 0.7.6.
|
||||
[U] - inbound.nickname string Name of tunnel - generally used in routerconsole, which will use the first few characters of the Base64 hash of the destination by default.
|
||||
[U] - outbound.nickname string Name of tunnel - generally ignored unless inbound.nickname is unset.
|
||||
[U] - outbound.priority 0.9.4 -25 to 25 -25 to 25 0 Priority adjustment for outbound messages. Higher is higher priority.
|
||||
[U] - inbound.quantity 1 to 3 1 to 16 2 Number of tunnels in. Limit was increased from 6 to 16 in release 0.9; however, numbers higher than 6 are incompatible with older releases.
|
||||
[U] - outbound.quantity 1 to 3 No limit 2 Number of tunnels out
|
||||
[U] - inbound.randomKey 0.9.17 Base 64 encoding of 32 random bytes Used for consistent peer ordering across restarts.
|
||||
[U] - outbound.randomKey 0.9.17 Base 64 encoding of 32 random bytes Used for consistent peer ordering across restarts.
|
||||
[U] - inbound.* Any other options prefixed with "inbound." are stored in the "unknown options" properties of the inbound tunnel pool's settings.
|
||||
[U] - outbound.* Any other options prefixed with "outbound." are stored in the "unknown options" properties of the outbound tunnel pool's settings.
|
||||
[U] - shouldBundleReplyInfo 0.9.2 true,false true Set to false to disable ever bundling a reply LeaseSet. For clients that do not publish their LeaseSet, this option must be true for any reply to be possible. "true" is also recommended for multihomed servers with long connection times. Setting to "false" may save significant outbound bandwidth, especially if the client is configured with a large number of inbound tunnels (Leases). If replies are still required, this may shift the bandwidth burden to the far-end client and the floodfill. There are several cases where "false" may be appropriate: Unidirectional communication, no reply required LeaseSet is published and higher reply latency is acceptable LeaseSet is published, client is a "server", all connections are inbound so the connecting far-end destination obviously has the leaseset already. Connections are either short, or it is acceptable for latency on a long-lived connection to temporarily increase while the other end re-fetches the LeaseSet after expiration. HTTP servers may fit these requirements.
|
||||
|
||||
[U] - i2cp.closeIdleTime 0.7.1 1800000 300000 minimum (ms) Idle time required (default 30 minutes)
|
||||
[U] - i2cp.closeOnIdle 0.7.1 true,false false Close I2P session when idle
|
||||
[U] - i2cp.encryptLeaseSet 0.7.1 true,false false Encrypt the lease
|
||||
[U] - i2cp.gzip 0.6.5 true,false true Gzip outbound data
|
||||
[U] - i2cp.leaseSetKey 0.7.1 For encrypted leasesets. Base 64 SessionKey (44 characters)
|
||||
[U] - i2cp.leaseSetPrivateKey 0.9.18 Base 64 private key for encryption. Optionally preceded by the key type and ':'. Only "ELGAMAL_2048:" is supported, which is the default. I2CP will generate the public key from the private key. Use for persistent leaseset keys across restarts.
|
||||
[U] - i2cp.leaseSetSigningPrivateKey 0.9.18 Base 64 private key for signatures. Optionally preceded by the key type and ':'. DSA_SHA1 is the default. Key type must match the signature type in the destination. I2CP will generate the public key from the private key. Use for persistent leaseset keys across restarts.
|
||||
[U] - i2cp.reduceIdleTime 0.7.1 1200000 300000 minimum (ms) Idle time required (default 20 minutes, minimum 5 minutes)
|
||||
[U] - i2cp.reduceOnIdle 0.7.1 true,false false Reduce tunnel quantity when idle
|
||||
[U] - i2cp.reduceQuantity 0.7.1 1 1 to 5 1 Tunnel quantity when reduced (applies to both inbound and outbound)
|
||||
[U] - i2cp.SSL 0.8.3 true,false false Connect to the router using SSL. If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.
|
||||
[U] - i2cp.tcp.host 127.0.0.1 Router hostname. If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.
|
||||
[U] - i2cp.tcp.port 1-65535 7654 Router I2CP port. If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.
|
||||
|
||||
Default Description
|
||||
[U] - i2cp.accessList null Comma- or space-separated list of Base64 peer Hashes used for either access list or blocklist. As of release 0.7.13.
|
||||
[U] - i2cp.destination.sigType DSA_SHA1 Use the access list as a allowlist for incoming connections. The name or number of the signature type for a transient destination. As of release 0.9.12.
|
||||
[U] - i2cp.enableAccessList false Use the access list as a allowlist for incoming connections. As of release 0.7.13.
|
||||
[U] - i2cp.enableBlackList false Use the access list as a blocklist for incoming connections. As of release 0.7.13.
|
||||
[U] - i2p.streaming.answerPings true Whether to respond to incoming pings
|
||||
[U] - i2p.streaming.blocklist null Comma- or space-separated list of Base64 peer Hashes to be blocklisted for incoming connections to ALL destinations in the context. This option must be set in the context properties, NOT in the createManager() options argument. Note that setting this in the router context will not affect clients outside the router in a separate JVM and context. As of release 0.9.3.
|
||||
[U] - i2p.streaming.bufferSize 64K How much transmit data (in bytes) will be accepted that hasn't been written out yet.
|
||||
[U] - i2p.streaming.congestionAvoidanceGrowthRateFactor 1 When we're in congestion avoidance, we grow the window size at the rate of 1/(windowSize*factor). In standard TCP, window sizes are in bytes, while in I2P, window sizes are in messages. A higher number means slower growth.
|
||||
[U] - i2p.streaming.connectDelay -1 How long to wait after instantiating a new con before actually attempting to connect. If this is <= 0, connect immediately with no initial data. If greater than 0, wait until the output stream is flushed, the buffer fills, or that many milliseconds pass, and include any initial data with the SYN.
|
||||
[U] - i2p.streaming.connectTimeout 5*60*1000 How long to block on connect, in milliseconds. Negative means indefinitely. Default is 5 minutes.
|
||||
[U] - i2p.streaming.disableRejectLogging false Whether to disable warnings in the logs when an incoming connection is rejected due to connection limits. As of release 0.9.4.
|
||||
[U] - i2p.streaming.dsalist null Comma- or space-separated list of Base64 peer Hashes or host names to be contacted using an alternate DSA destination. Only applies if multisession is enabled and the primary session is non-DSA (generally for shared clients only). This option must be set in the context properties, NOT in the createManager() options argument. Note that setting this in the router context will not affect clients outside the router in a separate JVM and context. As of release 0.9.21.
|
||||
[U] - i2p.streaming.enforceProtocol true Whether to listen only for the streaming protocol. Setting to true will prohibit communication with Destinations earlier than release 0.7.1 (released March 2009). Set to true if running multiple protocols on this Destination. As of release 0.9.1. Default true as of release 0.9.36.
|
||||
[U] - i2p.streaming.inactivityAction 2 (send) (0=noop, 1=disconnect) What to do on an inactivity timeout - do nothing, disconnect, or send a duplicate ack.
|
||||
[U] - i2p.streaming.inactivityTimeout 90*1000 Idle time before sending a keepalive
|
||||
[U] - i2p.streaming.initialAckDelay 750 Delay before sending an ack
|
||||
[U] - i2p.streaming.initialResendDelay 1000 The initial value of the resend delay field in the packet header, times 1000. Not fully implemented; see below.
|
||||
[U] - i2p.streaming.initialRTO 9000 Initial timeout (if no sharing data available). As of release 0.9.8.
|
||||
[U] - i2p.streaming.initialRTT 8000 Initial round trip time estimate (if no sharing data available). Disabled as of release 0.9.8; uses actual RTT.
|
||||
[U] - i2p.streaming.initialWindowSize 6 (if no sharing data available) In standard TCP, window sizes are in bytes, while in I2P, window sizes are in messages.
|
||||
[U] - i2p.streaming.limitAction reset What action to take when an incoming connection exceeds limits. Valid values are: reset (reset the connection); drop (drop the connection); or http (send a hardcoded HTTP 429 response). Any other value is a custom response to be sent. backslash-r and backslash-n will be replaced with CR and LF. As of release 0.9.34.
|
||||
[U] - i2p.streaming.maxConcurrentStreams -1 (0 or negative value means unlimited) This is a total limit for incoming and outgoing combined.
|
||||
[U] - i2p.streaming.maxConnsPerMinute 0 Incoming connection limit (per peer; 0 means disabled) As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxConnsPerHour 0 (per peer; 0 means disabled) As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxConnsPerDay 0 (per peer; 0 means disabled) As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxMessageSize 1730 The MTU in bytes.
|
||||
[U] - i2p.streaming.maxResends 8 Maximum number of retransmissions before failure.
|
||||
[U] - i2p.streaming.maxTotalConnsPerMinute 0 Incoming connection limit (all peers; 0 means disabled) As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxTotalConnsPerHour 0 (all peers; 0 means disabled) Use with caution as exceeding this will disable a server for a long time. As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxTotalConnsPerDay 0 (all peers; 0 means disabled) Use with caution as exceeding this will disable a server for a long time. As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxWindowSize 128
|
||||
[U] - i2p.streaming.profile 1 (bulk) (2=interactive not supported) This doesn't currently do anything, but setting it to a value other than 1 will cause an error.
|
||||
[U] - i2p.streaming.readTimeout -1 How long to block on read, in milliseconds. Negative means indefinitely.
|
||||
[U] - i2p.streaming.slowStartGrowthRateFactor 1 When we're in slow start, we grow the window size at the rate of 1/(factor). In standard TCP, window sizes are in bytes, while in I2P, window sizes are in messages. A higher number means slower growth.
|
||||
[U] - i2p.streaming.tcbcache.rttDampening 0.75 Ref: RFC 2140. Floating point value. May be set only via context properties, not connection options. As of release 0.9.8.
|
||||
[U] - i2p.streaming.tcbcache.rttdevDampening 0.75 Ref: RFC 2140. Floating point value. May be set only via context properties, not connection options. As of release 0.9.8.
|
||||
[U] - i2p.streaming.tcbcache.wdwDampening 0.75 Ref: RFC 2140. Floating point value. May be set only via context properties, not connection options. As of release 0.9.8.
|
||||
[U] - i2p.streaming.writeTimeout -1 How long to block on write/flush, in milliseconds. Negative means indefinitely.
|
||||
|
||||
[U] - destination useful to consider adding to custom applications for client ocnfiguration
|
1
config/README.md
Symbolic link
1
config/README.md
Symbolic link
@@ -0,0 +1 @@
|
||||
CHECKLIST.md
|
68
config/access.go
Normal file
68
config/access.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package i2ptunconf
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GetAccessListType takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetAccessListType(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
return c.AccessListType
|
||||
}
|
||||
|
||||
// SetAccessListType sets the access list type from a config file
|
||||
func (c *Conf) SetAccessListType(label ...string) {
|
||||
if v, ok := c.GetBool("i2cp.enableBlackList", label...); ok {
|
||||
if v {
|
||||
c.AccessListType = "blocklist"
|
||||
}
|
||||
}
|
||||
if v, ok := c.GetBool("i2cp.enableAccessList", label...); ok {
|
||||
if v {
|
||||
c.AccessListType = "allowlist"
|
||||
}
|
||||
}
|
||||
if c.AccessListType != "allowlist" && c.AccessListType != "blocklist" {
|
||||
c.AccessListType = "none"
|
||||
}
|
||||
}
|
||||
|
||||
// AddAccessListMember adds a member to either the blocklist or the allowlist
|
||||
func (c *Conf) AddAccessListMember(key string) {
|
||||
for _, item := range c.AccessList {
|
||||
if item == key {
|
||||
return
|
||||
}
|
||||
}
|
||||
c.AccessList = append(c.AccessList, key)
|
||||
}
|
||||
|
||||
func (c *Conf) accesslisttype() string {
|
||||
if c.AccessListType == "allowlist" {
|
||||
return "i2cp.enableAccessList=true"
|
||||
} else if c.AccessListType == "blocklist" {
|
||||
return "i2cp.enableBlackList=true"
|
||||
} else if c.AccessListType == "none" {
|
||||
return ""
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *Conf) accesslist() string {
|
||||
if c.AccessListType != "" && len(c.AccessList) > 0 {
|
||||
r := ""
|
||||
for _, s := range c.AccessList {
|
||||
r += s + ","
|
||||
}
|
||||
return "i2cp.accessList=" + strings.TrimSuffix(r, ",")
|
||||
}
|
||||
return ""
|
||||
}
|
1
config/auth.go
Normal file
1
config/auth.go
Normal file
@@ -0,0 +1 @@
|
||||
package i2ptunconf
|
53
config/backups.go
Normal file
53
config/backups.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package i2ptunconf
|
||||
|
||||
// GetInBackups takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetInBackups(arg, def int, label ...string) int {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.GetInt("inbound.backupQuantity", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// GetOutBackups takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetOutBackups(arg, def int, label ...string) int {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.GetInt("outbound.backupQuantity", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetInBackups sets the inbound tunnel backups from config file
|
||||
func (c *Conf) SetInBackups(label ...string) {
|
||||
if v, ok := c.GetInt("inbound.backupQuantity", label...); ok {
|
||||
c.InBackupQuantity = v
|
||||
} else {
|
||||
c.InBackupQuantity = 2
|
||||
}
|
||||
}
|
||||
|
||||
// SetOutBackups sets the outbound tunnel backups from config file
|
||||
func (c *Conf) SetOutBackups(label ...string) {
|
||||
if v, ok := c.GetInt("outbound.backupQuantity", label...); ok {
|
||||
c.OutBackupQuantity = v
|
||||
} else {
|
||||
c.OutBackupQuantity = 2
|
||||
}
|
||||
}
|
1
config/bundle.go
Normal file
1
config/bundle.go
Normal file
@@ -0,0 +1 @@
|
||||
package i2ptunconf
|
27
config/compress.go
Normal file
27
config/compress.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package i2ptunconf
|
||||
|
||||
// GetUseCompression takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetUseCompression(arg, def bool, label ...string) bool {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.GetBool("gzip", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetCompressed sets the compression from the config file
|
||||
func (c *Conf) SetCompressed(label ...string) {
|
||||
if v, ok := c.GetBool("gzip", label...); ok {
|
||||
c.UseCompression = v
|
||||
} else {
|
||||
c.UseCompression = true
|
||||
}
|
||||
}
|
182
config/conf.go
Normal file
182
config/conf.go
Normal file
@@ -0,0 +1,182 @@
|
||||
package i2ptunconf
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
import (
|
||||
sfi2pkeys "github.com/eyedeekay/sam-forwarder/i2pkeys"
|
||||
"github.com/eyedeekay/sam3/i2pkeys"
|
||||
)
|
||||
|
||||
var err error
|
||||
|
||||
func (f *Conf) ID() string {
|
||||
return f.TunName
|
||||
}
|
||||
|
||||
func (f *Conf) Keys() i2pkeys.I2PKeys {
|
||||
return f.LoadedKeys
|
||||
}
|
||||
|
||||
func (f *Conf) Cleanup() {
|
||||
|
||||
}
|
||||
|
||||
func (f *Conf) GetType() string {
|
||||
return f.Type
|
||||
}
|
||||
|
||||
/*func (f *Conf) targetForPort443() string {
|
||||
if f.TargetForPort443 != "" {
|
||||
return "targetForPort.4443=" + f.TargetHost + ":" + f.TargetForPort443
|
||||
}
|
||||
return ""
|
||||
}*/
|
||||
|
||||
func (f *Conf) print() []string {
|
||||
lsk, lspk, lspsk := f.leasesetsettings()
|
||||
return []string{
|
||||
//f.targetForPort443(),
|
||||
"inbound.length=" + fmt.Sprintf("%d", f.InLength),
|
||||
"outbound.length=" + fmt.Sprintf("%d", f.OutLength),
|
||||
"inbound.lengthVariance=" + fmt.Sprintf("%d", f.InVariance),
|
||||
"outbound.lengthVariance=" + fmt.Sprintf("%d", f.OutVariance),
|
||||
"inbound.backupQuantity=" + fmt.Sprintf("%d", f.InBackupQuantity),
|
||||
"outbound.backupQuantity=" + fmt.Sprintf("%d", f.OutBackupQuantity),
|
||||
"inbound.quantity=" + fmt.Sprintf("%d", f.InQuantity),
|
||||
"outbound.quantity=" + fmt.Sprintf("%d", f.OutQuantity),
|
||||
"inbound.allowZeroHop=" + fmt.Sprintf("%v", f.InAllowZeroHop),
|
||||
"outbound.allowZeroHop=" + fmt.Sprintf("%v", f.OutAllowZeroHop),
|
||||
"i2cp.fastRecieve=" + fmt.Sprintf("%v", f.FastRecieve),
|
||||
"i2cp.gzip=" + fmt.Sprintf("%v", f.UseCompression),
|
||||
"i2cp.reduceOnIdle=" + fmt.Sprintf("%v", f.ReduceIdle),
|
||||
"i2cp.reduceIdleTime=" + fmt.Sprintf("%v", f.ReduceIdleTime),
|
||||
"i2cp.reduceQuantity=" + fmt.Sprintf("%d", f.ReduceIdleQuantity),
|
||||
"i2cp.closeOnIdle=" + fmt.Sprintf("%v", f.CloseIdle),
|
||||
"i2cp.closeIdleTime=" + fmt.Sprintf("%d", f.CloseIdleTime),
|
||||
"i2cp.messageReliability=" + f.MessageReliability,
|
||||
"i2cp.encryptLeaseSet=" + fmt.Sprintf("%v", f.EncryptLeaseSet),
|
||||
"i2cp.leaseSetEncType=" + fmt.Sprintf("%s", f.LeaseSetEncType),
|
||||
lsk, lspk, lspsk,
|
||||
f.accesslisttype(),
|
||||
f.accesslist(),
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Conf) Props() map[string]string {
|
||||
r := make(map[string]string)
|
||||
print := f.print()
|
||||
print = append(print, "base32="+f.Base32())
|
||||
print = append(print, "base64="+f.Base64())
|
||||
print = append(print, "base32words="+f.Base32Readable())
|
||||
for _, prop := range print {
|
||||
k, v := sfi2pkeys.Prop(prop)
|
||||
r[k] = v
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func (f *Conf) Print() string {
|
||||
var r string
|
||||
r += "name=" + f.TunName + "\n"
|
||||
r += "type=" + f.Type + "\n"
|
||||
if f.Type == "http" {
|
||||
r += "httpserver\n"
|
||||
} else {
|
||||
r += "ntcpserver\n"
|
||||
}
|
||||
for _, s := range f.print() {
|
||||
r += s + "\n"
|
||||
}
|
||||
return strings.Replace(r, "\n\n", "\n", -1)
|
||||
}
|
||||
|
||||
func (f *Conf) Search(search string) string {
|
||||
terms := strings.Split(search, ",")
|
||||
if search == "" {
|
||||
return f.Print()
|
||||
}
|
||||
for _, value := range terms {
|
||||
if !strings.Contains(f.Print(), value) {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
return f.Print()
|
||||
}
|
||||
|
||||
/*
|
||||
func (f *Conf) accesslisttype() string {
|
||||
if f.accessListType == "allowlist" {
|
||||
return "i2cp.enableAccessList=true"
|
||||
} else if f.accessListType == "blocklist" {
|
||||
return "i2cp.enableBlackList=true"
|
||||
} else if f.accessListType == "none" {
|
||||
return ""
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (f *Conf) accesslist() string {
|
||||
if f.accessListType != "" && len(f.accessList) > 0 {
|
||||
r := ""
|
||||
for _, s := range f.accessList {
|
||||
r += s + ","
|
||||
}
|
||||
return "i2cp.accessList=" + strings.TrimSuffix(r, ",")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
*/
|
||||
func (f *Conf) leasesetsettings() (string, string, string) {
|
||||
var r, s, t string
|
||||
if f.LeaseSetKey != "" {
|
||||
r = "i2cp.leaseSetKey=" + f.LeaseSetKey
|
||||
}
|
||||
if f.LeaseSetPrivateKey != "" {
|
||||
s = "i2cp.leaseSetPrivateKey=" + f.LeaseSetPrivateKey
|
||||
}
|
||||
if f.LeaseSetPrivateSigningKey != "" {
|
||||
t = "i2cp.leaseSetPrivateSigningKey=" + f.LeaseSetPrivateSigningKey
|
||||
}
|
||||
return r, s, t
|
||||
}
|
||||
|
||||
// Target returns the host:port of the local service you want to forward to i2p
|
||||
func (f *Conf) Target() string {
|
||||
return f.TargetHost + ":" + f.TargetPort
|
||||
}
|
||||
|
||||
func (f *Conf) sam() string {
|
||||
return f.SamHost + ":" + f.SamPort
|
||||
}
|
||||
|
||||
//Base32 returns the base32 address where the local service is being forwarded
|
||||
func (f *Conf) Base32() string {
|
||||
return f.LoadedKeys.Addr().Base32()
|
||||
}
|
||||
|
||||
//Base32Readable will always be an empty string when used here.
|
||||
func (f *Conf) Base32Readable() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
//Base64 returns the base64 address where the local service is being forwarded
|
||||
func (f *Conf) Base64() string {
|
||||
return f.LoadedKeys.Addr().Base64()
|
||||
}
|
||||
|
||||
//Serve starts the SAM connection and and forwards the local host:port to i2p
|
||||
func (f *Conf) Serve() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Conf) Up() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
//Close shuts the whole thing down.
|
||||
func (f *Conf) Close() error {
|
||||
return nil
|
||||
}
|
20
config/config-options.go
Normal file
20
config/config-options.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package i2ptunconf
|
||||
|
||||
//Option is a Conf Option
|
||||
type Option func(*Conf) error
|
||||
|
||||
//SetTargetForPort sets the port of the Conf's SAM bridge using a string
|
||||
/*func SetTargetForPort443(s string) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
port, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Invalid Target Port %s; non-number ", s)
|
||||
}
|
||||
if port < 65536 && port > -1 {
|
||||
c.TargetForPort443 = s
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid port")
|
||||
}
|
||||
}
|
||||
*/
|
53
config/controlhostport.go
Normal file
53
config/controlhostport.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package i2ptunconf
|
||||
|
||||
// GetHost takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetControlHost(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("controlhost", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// GetPort takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetControlPort(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("controlport", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetHost sets the host to forward from the config file
|
||||
func (c *Conf) SetControlHost(label ...string) {
|
||||
if v, ok := c.Get("controlhost", label...); ok {
|
||||
c.ControlHost = v
|
||||
} else {
|
||||
c.ControlHost = "127.0.0.1"
|
||||
}
|
||||
}
|
||||
|
||||
// SetPort sets the port to forward from the config file
|
||||
func (c *Conf) SetControlPort(label ...string) {
|
||||
if v, ok := c.Get("controlport", label...); ok {
|
||||
c.ControlPort = v
|
||||
} else {
|
||||
c.ControlPort = ""
|
||||
}
|
||||
}
|
27
config/cryptsave.go
Normal file
27
config/cryptsave.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package i2ptunconf
|
||||
|
||||
// GetKeyFile takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetKeyFile(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("keyfile", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetKeyFile sets the key save directory from the config file
|
||||
func (c *Conf) SetKeyFile(label ...string) {
|
||||
if v, ok := c.Get("keyfile", label...); ok {
|
||||
c.KeyFilePath = v
|
||||
} else {
|
||||
c.KeyFilePath = "./"
|
||||
}
|
||||
}
|
27
config/dest.go
Normal file
27
config/dest.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package i2ptunconf
|
||||
|
||||
// GetClientDest takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetClientDest(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("destination", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetClientDest sets the key name from the config file
|
||||
func (c *Conf) SetClientDest(label ...string) {
|
||||
if v, ok := c.Get("destination", label...); ok {
|
||||
c.ClientDest = v
|
||||
} else {
|
||||
c.ClientDest = ""
|
||||
}
|
||||
}
|
29
config/dir.go
Normal file
29
config/dir.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package i2ptunconf
|
||||
|
||||
//
|
||||
|
||||
// GetDir takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetDir(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("dir", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetDir sets the key save directory from the config file
|
||||
func (c *Conf) SetDir(label ...string) {
|
||||
if v, ok := c.Get("dir", label...); ok {
|
||||
c.SaveDirectory = v
|
||||
} else {
|
||||
c.SaveDirectory = "./"
|
||||
}
|
||||
}
|
27
config/endpoint.go
Normal file
27
config/endpoint.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package i2ptunconf
|
||||
|
||||
// GetEndpointHost takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetEndpointHost(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("tunhost", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetEndpointHost sets the host to forward from the config file
|
||||
func (c *Conf) SetEndpointHost(label ...string) {
|
||||
if v, ok := c.Get("tunhost", label...); ok {
|
||||
c.TunnelHost = v
|
||||
} else {
|
||||
c.TunnelHost = "10.79.0.1"
|
||||
}
|
||||
}
|
27
config/fastrecieve.go
Normal file
27
config/fastrecieve.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package i2ptunconf
|
||||
|
||||
// GetFastRecieve takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetFastRecieve(arg, def bool, label ...string) bool {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.GetBool("i2cp.fastRecieve", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetFastRecieve sets the compression from the config file
|
||||
func (c *Conf) SetFastRecieve(label ...string) {
|
||||
if v, ok := c.GetBool("i2cp.fastRecieve", label...); ok {
|
||||
c.FastRecieve = v
|
||||
} else {
|
||||
c.FastRecieve = false
|
||||
}
|
||||
}
|
1
config/helpers/helper.go
Normal file
1
config/helpers/helper.go
Normal file
@@ -0,0 +1 @@
|
||||
package i2ptunhelper
|
226
config/helpers/tunconf_client.go
Normal file
226
config/helpers/tunconf_client.go
Normal file
@@ -0,0 +1,226 @@
|
||||
package i2ptunhelper
|
||||
|
||||
import (
|
||||
"github.com/eyedeekay/httptunnel"
|
||||
"github.com/eyedeekay/httptunnel/multiproxy"
|
||||
"github.com/eyedeekay/sam-forwarder/config"
|
||||
"github.com/eyedeekay/sam-forwarder/options"
|
||||
"github.com/eyedeekay/sam-forwarder/tcp"
|
||||
"github.com/eyedeekay/sam-forwarder/udp"
|
||||
)
|
||||
|
||||
func NewSAMHTTPClientFromConf(config *i2ptunconf.Conf) (*i2phttpproxy.SAMHTTPProxy, error) {
|
||||
if config != nil {
|
||||
return i2phttpproxy.NewHttpProxy(
|
||||
i2phttpproxy.SetName(config.TunName),
|
||||
i2phttpproxy.SetKeysPath(config.KeyFilePath),
|
||||
i2phttpproxy.SetHost(config.SamHost),
|
||||
i2phttpproxy.SetPort(config.SamPort),
|
||||
i2phttpproxy.SetProxyAddr(config.TargetHost+":"+config.TargetPort),
|
||||
i2phttpproxy.SetControlHost(config.ControlHost),
|
||||
i2phttpproxy.SetControlPort(config.ControlPort),
|
||||
i2phttpproxy.SetInLength(uint(config.InLength)),
|
||||
i2phttpproxy.SetOutLength(uint(config.OutLength)),
|
||||
i2phttpproxy.SetInQuantity(uint(config.InQuantity)),
|
||||
i2phttpproxy.SetOutQuantity(uint(config.OutQuantity)),
|
||||
i2phttpproxy.SetInBackups(uint(config.InBackupQuantity)),
|
||||
i2phttpproxy.SetOutBackups(uint(config.OutBackupQuantity)),
|
||||
i2phttpproxy.SetInVariance(config.InVariance),
|
||||
i2phttpproxy.SetOutVariance(config.OutVariance),
|
||||
i2phttpproxy.SetUnpublished(config.Client),
|
||||
i2phttpproxy.SetReduceIdle(config.ReduceIdle),
|
||||
i2phttpproxy.SetCompression(config.UseCompression),
|
||||
i2phttpproxy.SetReduceIdleTime(uint(config.ReduceIdleTime)),
|
||||
i2phttpproxy.SetReduceIdleQuantity(uint(config.ReduceIdleQuantity)),
|
||||
i2phttpproxy.SetCloseIdle(config.CloseIdle),
|
||||
i2phttpproxy.SetCloseIdleTime(uint(config.CloseIdleTime)),
|
||||
)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewSAMClientForwarderFromConfig generates a new SAMForwarder from a config file
|
||||
func NewSAMHTTPClientFromConfig(iniFile, SamHost, SamPort string, label ...string) (*i2phttpproxy.SAMHTTPProxy, error) {
|
||||
if iniFile != "none" {
|
||||
config, err := i2ptunconf.NewI2PTunConf(iniFile, label...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if SamHost != "" && SamHost != "127.0.0.1" && SamHost != "localhost" {
|
||||
config.SamHost = config.GetSAMHost(SamHost, config.SamHost)
|
||||
}
|
||||
if SamPort != "" && SamPort != "7656" {
|
||||
config.SamPort = config.GetSAMPort(SamPort, config.SamPort)
|
||||
}
|
||||
return NewSAMHTTPClientFromConf(config)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func NewSAMBrowserClientFromConf(config *i2ptunconf.Conf) (*i2pbrowserproxy.SAMMultiProxy, error) {
|
||||
if config != nil {
|
||||
return i2pbrowserproxy.NewHttpProxy(
|
||||
i2pbrowserproxy.SetName(config.TunName),
|
||||
i2pbrowserproxy.SetKeysPath(config.KeyFilePath),
|
||||
i2pbrowserproxy.SetHost(config.SamHost),
|
||||
i2pbrowserproxy.SetPort(config.SamPort),
|
||||
i2pbrowserproxy.SetProxyAddr(config.TargetHost+":"+config.TargetPort),
|
||||
i2pbrowserproxy.SetControlHost(config.ControlHost),
|
||||
i2pbrowserproxy.SetControlPort(config.ControlPort),
|
||||
i2pbrowserproxy.SetInLength(uint(config.InLength)),
|
||||
i2pbrowserproxy.SetOutLength(uint(config.OutLength)),
|
||||
i2pbrowserproxy.SetInQuantity(uint(config.InQuantity)),
|
||||
i2pbrowserproxy.SetOutQuantity(uint(config.OutQuantity)),
|
||||
i2pbrowserproxy.SetInBackups(uint(config.InBackupQuantity)),
|
||||
i2pbrowserproxy.SetOutBackups(uint(config.OutBackupQuantity)),
|
||||
i2pbrowserproxy.SetInVariance(config.InVariance),
|
||||
i2pbrowserproxy.SetOutVariance(config.OutVariance),
|
||||
i2pbrowserproxy.SetUnpublished(config.Client),
|
||||
i2pbrowserproxy.SetReduceIdle(config.ReduceIdle),
|
||||
i2pbrowserproxy.SetCompression(config.UseCompression),
|
||||
i2pbrowserproxy.SetReduceIdleTime(uint(config.ReduceIdleTime)),
|
||||
i2pbrowserproxy.SetReduceIdleQuantity(uint(config.ReduceIdleQuantity)),
|
||||
//i2pbrowserproxy.SetCloseIdle(config.CloseIdle),
|
||||
//i2pbrowserproxy.SetCloseIdleTime(uint(config.CloseIdleTime)),
|
||||
)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func NewSAMBrowserClientFromConfig(iniFile, SamHost, SamPort string, label ...string) (*i2pbrowserproxy.SAMMultiProxy, error) {
|
||||
if iniFile != "none" {
|
||||
config, err := i2ptunconf.NewI2PTunConf(iniFile, label...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if SamHost != "" && SamHost != "127.0.0.1" && SamHost != "localhost" {
|
||||
config.SamHost = config.GetSAMHost(SamHost, config.SamHost)
|
||||
}
|
||||
if SamPort != "" && SamPort != "7656" {
|
||||
config.SamPort = config.GetSAMPort(SamPort, config.SamPort)
|
||||
}
|
||||
return NewSAMBrowserClientFromConf(config)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewSAMClientForwarderFromConf generates a SAMforwarder from *i2ptunconf.Conf
|
||||
func NewSAMClientForwarderFromConf(config *i2ptunconf.Conf) (*samforwarder.SAMClientForwarder, error) {
|
||||
if config != nil {
|
||||
return samforwarder.NewSAMClientForwarderFromOptions(
|
||||
samoptions.SetSaveFile(config.SaveFile),
|
||||
samoptions.SetFilePath(config.SaveDirectory),
|
||||
samoptions.SetHost(config.TargetHost),
|
||||
samoptions.SetPort(config.TargetPort),
|
||||
samoptions.SetSAMHost(config.SamHost),
|
||||
samoptions.SetSAMPort(config.SamPort),
|
||||
samoptions.SetSigType(config.SigType),
|
||||
samoptions.SetName(config.TunName),
|
||||
samoptions.SetInLength(config.InLength),
|
||||
samoptions.SetOutLength(config.OutLength),
|
||||
samoptions.SetInVariance(config.InVariance),
|
||||
samoptions.SetOutVariance(config.OutVariance),
|
||||
samoptions.SetInQuantity(config.InQuantity),
|
||||
samoptions.SetOutQuantity(config.OutQuantity),
|
||||
samoptions.SetInBackups(config.InBackupQuantity),
|
||||
samoptions.SetOutBackups(config.OutBackupQuantity),
|
||||
samoptions.SetEncrypt(config.EncryptLeaseSet),
|
||||
samoptions.SetLeaseSetKey(config.LeaseSetKey),
|
||||
samoptions.SetLeaseSetPrivateKey(config.LeaseSetPrivateKey),
|
||||
samoptions.SetLeaseSetPrivateSigningKey(config.LeaseSetPrivateSigningKey),
|
||||
samoptions.SetAllowZeroIn(config.InAllowZeroHop),
|
||||
samoptions.SetAllowZeroOut(config.OutAllowZeroHop),
|
||||
samoptions.SetFastRecieve(config.FastRecieve),
|
||||
samoptions.SetCompress(config.UseCompression),
|
||||
samoptions.SetReduceIdle(config.ReduceIdle),
|
||||
samoptions.SetReduceIdleTimeMs(config.ReduceIdleTime),
|
||||
samoptions.SetReduceIdleQuantity(config.ReduceIdleQuantity),
|
||||
samoptions.SetCloseIdle(config.CloseIdle),
|
||||
samoptions.SetCloseIdleTimeMs(config.CloseIdleTime),
|
||||
samoptions.SetAccessListType(config.AccessListType),
|
||||
samoptions.SetAccessList(config.AccessList),
|
||||
samoptions.SetMessageReliability(config.MessageReliability),
|
||||
samoptions.SetPassword(config.KeyFilePath),
|
||||
samoptions.SetDestination(config.ClientDest),
|
||||
)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewSAMClientForwarderFromConfig generates a new SAMForwarder from a config file
|
||||
func NewSAMClientForwarderFromConfig(iniFile, SamHost, SamPort string, label ...string) (*samforwarder.SAMClientForwarder, error) {
|
||||
if iniFile != "none" {
|
||||
config, err := i2ptunconf.NewI2PTunConf(iniFile, label...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if SamHost != "" && SamHost != "127.0.0.1" && SamHost != "localhost" {
|
||||
config.SamHost = config.GetSAMHost(SamHost, config.SamHost)
|
||||
}
|
||||
if SamPort != "" && SamPort != "7656" {
|
||||
config.SamPort = config.GetSAMPort(SamPort, config.SamPort)
|
||||
}
|
||||
return NewSAMClientForwarderFromConf(config)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewSAMDGClientForwarderFromConf generates a SAMSSUforwarder from *i2ptunconf.Conf
|
||||
func NewSAMDGClientForwarderFromConf(config *i2ptunconf.Conf) (*samforwarderudp.SAMDGClientForwarder, error) {
|
||||
if config != nil {
|
||||
return samforwarderudp.NewSAMDGClientForwarderFromOptions(
|
||||
samoptions.SetSaveFile(config.SaveFile),
|
||||
samoptions.SetFilePath(config.SaveDirectory),
|
||||
samoptions.SetHost(config.TargetHost),
|
||||
samoptions.SetPort(config.TargetPort),
|
||||
samoptions.SetSAMHost(config.SamHost),
|
||||
samoptions.SetSAMPort(config.SamPort),
|
||||
samoptions.SetSigType(config.SigType),
|
||||
samoptions.SetName(config.TunName),
|
||||
samoptions.SetInLength(config.InLength),
|
||||
samoptions.SetOutLength(config.OutLength),
|
||||
samoptions.SetInVariance(config.InVariance),
|
||||
samoptions.SetOutVariance(config.OutVariance),
|
||||
samoptions.SetInQuantity(config.InQuantity),
|
||||
samoptions.SetOutQuantity(config.OutQuantity),
|
||||
samoptions.SetInBackups(config.InBackupQuantity),
|
||||
samoptions.SetOutBackups(config.OutBackupQuantity),
|
||||
samoptions.SetEncrypt(config.EncryptLeaseSet),
|
||||
samoptions.SetLeaseSetKey(config.LeaseSetKey),
|
||||
samoptions.SetLeaseSetPrivateKey(config.LeaseSetPrivateKey),
|
||||
samoptions.SetLeaseSetPrivateSigningKey(config.LeaseSetPrivateSigningKey),
|
||||
samoptions.SetAllowZeroIn(config.InAllowZeroHop),
|
||||
samoptions.SetAllowZeroOut(config.OutAllowZeroHop),
|
||||
samoptions.SetFastRecieve(config.FastRecieve),
|
||||
samoptions.SetCompress(config.UseCompression),
|
||||
samoptions.SetReduceIdle(config.ReduceIdle),
|
||||
samoptions.SetReduceIdleTimeMs(config.ReduceIdleTime),
|
||||
samoptions.SetReduceIdleQuantity(config.ReduceIdleQuantity),
|
||||
samoptions.SetCloseIdle(config.CloseIdle),
|
||||
samoptions.SetCloseIdleTimeMs(config.CloseIdleTime),
|
||||
samoptions.SetAccessListType(config.AccessListType),
|
||||
samoptions.SetAccessList(config.AccessList),
|
||||
samoptions.SetMessageReliability(config.MessageReliability),
|
||||
samoptions.SetPassword(config.KeyFilePath),
|
||||
samoptions.SetDestination(config.ClientDest),
|
||||
)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func NewSAMDGClientForwarderFromConfig(iniFile, SamHost, SamPort string, label ...string) (*samforwarderudp.SAMDGClientForwarder, error) {
|
||||
if iniFile != "none" {
|
||||
config, err := i2ptunconf.NewI2PTunConf(iniFile, label...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if SamHost != "" && SamHost != "127.0.0.1" && SamHost != "localhost" {
|
||||
config.SamHost = config.GetSAMHost(SamHost, config.SamHost)
|
||||
}
|
||||
if SamPort != "" && SamPort != "7656" {
|
||||
config.SamPort = config.GetSAMPort(SamPort, config.SamPort)
|
||||
}
|
||||
return NewSAMDGClientForwarderFromConf(config)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
130
config/helpers/tunconf_outproxy.go
Normal file
130
config/helpers/tunconf_outproxy.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package i2ptunhelper
|
||||
|
||||
import (
|
||||
"github.com/eyedeekay/outproxy"
|
||||
"github.com/eyedeekay/sam-forwarder/config"
|
||||
)
|
||||
|
||||
// NewOutProxyFromConf generates a SAMforwarder from *i2ptunconf.Conf
|
||||
func NewOutProxyFromConf(config *i2ptunconf.Conf) (*outproxy.OutProxy, error) {
|
||||
if config != nil {
|
||||
return outproxy.NewOutProxyFromOptions(
|
||||
outproxy.SetType(config.Type),
|
||||
outproxy.SetSaveFile(config.SaveFile),
|
||||
outproxy.SetFilePath(config.SaveDirectory),
|
||||
outproxy.SetHost(config.TargetHost),
|
||||
outproxy.SetPort(config.TargetPort),
|
||||
outproxy.SetSAMHost(config.SamHost),
|
||||
outproxy.SetSAMPort(config.SamPort),
|
||||
outproxy.SetSigType(config.SigType),
|
||||
outproxy.SetName(config.TunName),
|
||||
outproxy.SetInLength(config.InLength),
|
||||
outproxy.SetOutLength(config.OutLength),
|
||||
outproxy.SetInVariance(config.InVariance),
|
||||
outproxy.SetOutVariance(config.OutVariance),
|
||||
outproxy.SetInQuantity(config.InQuantity),
|
||||
outproxy.SetOutQuantity(config.OutQuantity),
|
||||
outproxy.SetInBackups(config.InBackupQuantity),
|
||||
outproxy.SetOutBackups(config.OutBackupQuantity),
|
||||
outproxy.SetEncrypt(config.EncryptLeaseSet),
|
||||
outproxy.SetLeaseSetKey(config.LeaseSetKey),
|
||||
outproxy.SetLeaseSetPrivateKey(config.LeaseSetPrivateKey),
|
||||
outproxy.SetLeaseSetPrivateSigningKey(config.LeaseSetPrivateSigningKey),
|
||||
outproxy.SetAllowZeroIn(config.InAllowZeroHop),
|
||||
outproxy.SetAllowZeroOut(config.OutAllowZeroHop),
|
||||
outproxy.SetFastRecieve(config.FastRecieve),
|
||||
outproxy.SetCompress(config.UseCompression),
|
||||
outproxy.SetReduceIdle(config.ReduceIdle),
|
||||
outproxy.SetReduceIdleTimeMs(config.ReduceIdleTime),
|
||||
outproxy.SetReduceIdleQuantity(config.ReduceIdleQuantity),
|
||||
outproxy.SetCloseIdle(config.CloseIdle),
|
||||
outproxy.SetCloseIdleTimeMs(config.CloseIdleTime),
|
||||
outproxy.SetAccessListType(config.AccessListType),
|
||||
outproxy.SetAccessList(config.AccessList),
|
||||
outproxy.SetMessageReliability(config.MessageReliability),
|
||||
outproxy.SetKeyFile(config.KeyFilePath),
|
||||
//outproxy.SetTargetForPort443(config.TargetForPort443),
|
||||
)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewOutProxyFromConfig generates a new OutProxy from a config file
|
||||
func NewOutProxyFromConfig(iniFile, SamHost, SamPort string, label ...string) (*outproxy.HttpOutProxy, error) {
|
||||
if iniFile != "none" {
|
||||
config, err := i2ptunconf.NewI2PTunConf(iniFile, label...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if SamHost != "" && SamHost != "127.0.0.1" && SamHost != "localhost" {
|
||||
config.SamHost = config.GetSAMHost(SamHost, config.SamHost)
|
||||
}
|
||||
if SamPort != "" && SamPort != "7656" {
|
||||
config.SamPort = config.GetSAMPort(SamPort, config.SamPort)
|
||||
}
|
||||
return NewHttpOutProxyFromConf(config)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewOutProxyFromConf generates a SAMforwarder from *i2ptunconf.Conf
|
||||
func NewHttpOutProxyFromConf(config *i2ptunconf.Conf) (*outproxy.HttpOutProxy, error) {
|
||||
if config != nil {
|
||||
return outproxy.NewHttpOutProxydFromOptions(
|
||||
outproxy.SetHttpType(config.Type),
|
||||
outproxy.SetHttpSaveFile(config.SaveFile),
|
||||
outproxy.SetHttpFilePath(config.SaveDirectory),
|
||||
outproxy.SetHttpHost(config.TargetHost),
|
||||
outproxy.SetHttpPort(config.TargetPort),
|
||||
outproxy.SetHttpSAMHost(config.SamHost),
|
||||
outproxy.SetHttpSAMPort(config.SamPort),
|
||||
outproxy.SetHttpSigType(config.SigType),
|
||||
outproxy.SetHttpName(config.TunName),
|
||||
outproxy.SetHttpInLength(config.InLength),
|
||||
outproxy.SetHttpOutLength(config.OutLength),
|
||||
outproxy.SetHttpInVariance(config.InVariance),
|
||||
outproxy.SetHttpOutVariance(config.OutVariance),
|
||||
outproxy.SetHttpInQuantity(config.InQuantity),
|
||||
outproxy.SetHttpOutQuantity(config.OutQuantity),
|
||||
outproxy.SetHttpInBackups(config.InBackupQuantity),
|
||||
outproxy.SetHttpOutBackups(config.OutBackupQuantity),
|
||||
outproxy.SetHttpEncrypt(config.EncryptLeaseSet),
|
||||
outproxy.SetHttpLeaseSetKey(config.LeaseSetKey),
|
||||
outproxy.SetHttpLeaseSetPrivateKey(config.LeaseSetPrivateKey),
|
||||
outproxy.SetHttpLeaseSetPrivateSigningKey(config.LeaseSetPrivateSigningKey),
|
||||
outproxy.SetHttpAllowZeroIn(config.InAllowZeroHop),
|
||||
outproxy.SetHttpAllowZeroOut(config.OutAllowZeroHop),
|
||||
outproxy.SetHttpFastRecieve(config.FastRecieve),
|
||||
outproxy.SetHttpCompress(config.UseCompression),
|
||||
outproxy.SetHttpReduceIdle(config.ReduceIdle),
|
||||
outproxy.SetHttpReduceIdleTimeMs(config.ReduceIdleTime),
|
||||
outproxy.SetHttpReduceIdleQuantity(config.ReduceIdleQuantity),
|
||||
outproxy.SetHttpCloseIdle(config.CloseIdle),
|
||||
outproxy.SetHttpCloseIdleTimeMs(config.CloseIdleTime),
|
||||
outproxy.SetHttpAccessListType(config.AccessListType),
|
||||
outproxy.SetHttpAccessList(config.AccessList),
|
||||
outproxy.SetHttpMessageReliability(config.MessageReliability),
|
||||
outproxy.SetHttpKeyFile(config.KeyFilePath),
|
||||
//outproxy.SetHttpTargetForPort443(config.TargetForPort443),
|
||||
)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewOutProxyFromConfig generates a new OutProxy from a config file
|
||||
func NewHttpOutProxyFromConfig(iniFile, SamHost, SamPort string, label ...string) (*outproxy.OutProxy, error) {
|
||||
if iniFile != "none" {
|
||||
config, err := i2ptunconf.NewI2PTunConf(iniFile, label...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if SamHost != "" && SamHost != "127.0.0.1" && SamHost != "localhost" {
|
||||
config.SamHost = config.GetSAMHost(SamHost, config.SamHost)
|
||||
}
|
||||
if SamPort != "" && SamPort != "7656" {
|
||||
config.SamPort = config.GetSAMPort(SamPort, config.SamPort)
|
||||
}
|
||||
return NewOutProxyFromConf(config)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
194
config/helpers/tunconf_server.go
Normal file
194
config/helpers/tunconf_server.go
Normal file
@@ -0,0 +1,194 @@
|
||||
package i2ptunhelper
|
||||
|
||||
import (
|
||||
"github.com/eyedeekay/eephttpd"
|
||||
"github.com/eyedeekay/sam-forwarder/config"
|
||||
"github.com/eyedeekay/sam-forwarder/options"
|
||||
"github.com/eyedeekay/sam-forwarder/tcp"
|
||||
"github.com/eyedeekay/sam-forwarder/udp"
|
||||
)
|
||||
|
||||
// NewSAMForwarderFromConf generates a SAMforwarder from *i2ptunconf.Conf
|
||||
func NewSAMForwarderFromConf(config *i2ptunconf.Conf) (*samforwarder.SAMForwarder, error) {
|
||||
if config != nil {
|
||||
return samforwarder.NewSAMForwarderFromOptions(
|
||||
samoptions.SetType(config.Type),
|
||||
samoptions.SetSaveFile(config.SaveFile),
|
||||
samoptions.SetFilePath(config.SaveDirectory),
|
||||
samoptions.SetHost(config.TargetHost),
|
||||
samoptions.SetPort(config.TargetPort),
|
||||
samoptions.SetSAMHost(config.SamHost),
|
||||
samoptions.SetSAMPort(config.SamPort),
|
||||
samoptions.SetSigType(config.SigType),
|
||||
samoptions.SetName(config.TunName),
|
||||
samoptions.SetInLength(config.InLength),
|
||||
samoptions.SetOutLength(config.OutLength),
|
||||
samoptions.SetInVariance(config.InVariance),
|
||||
samoptions.SetOutVariance(config.OutVariance),
|
||||
samoptions.SetInQuantity(config.InQuantity),
|
||||
samoptions.SetOutQuantity(config.OutQuantity),
|
||||
samoptions.SetInBackups(config.InBackupQuantity),
|
||||
samoptions.SetOutBackups(config.OutBackupQuantity),
|
||||
samoptions.SetEncrypt(config.EncryptLeaseSet),
|
||||
samoptions.SetLeaseSetKey(config.LeaseSetKey),
|
||||
samoptions.SetLeaseSetPrivateKey(config.LeaseSetPrivateKey),
|
||||
samoptions.SetLeaseSetPrivateSigningKey(config.LeaseSetPrivateSigningKey),
|
||||
samoptions.SetAllowZeroIn(config.InAllowZeroHop),
|
||||
samoptions.SetAllowZeroOut(config.OutAllowZeroHop),
|
||||
samoptions.SetFastRecieve(config.FastRecieve),
|
||||
samoptions.SetCompress(config.UseCompression),
|
||||
samoptions.SetReduceIdle(config.ReduceIdle),
|
||||
samoptions.SetReduceIdleTimeMs(config.ReduceIdleTime),
|
||||
samoptions.SetReduceIdleQuantity(config.ReduceIdleQuantity),
|
||||
samoptions.SetCloseIdle(config.CloseIdle),
|
||||
samoptions.SetCloseIdleTimeMs(config.CloseIdleTime),
|
||||
samoptions.SetAccessListType(config.AccessListType),
|
||||
samoptions.SetAccessList(config.AccessList),
|
||||
samoptions.SetMessageReliability(config.MessageReliability),
|
||||
samoptions.SetKeyFile(config.KeyFilePath),
|
||||
//samoptions.SetTargetForPort443(config.TargetForPort443),
|
||||
)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewSAMForwarderFromConfig generates a new SAMForwarder from a config file
|
||||
func NewSAMForwarderFromConfig(iniFile, SamHost, SamPort string, label ...string) (*samforwarder.SAMForwarder, error) {
|
||||
if iniFile != "none" {
|
||||
config, err := i2ptunconf.NewI2PTunConf(iniFile, label...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if SamHost != "" && SamHost != "127.0.0.1" && SamHost != "localhost" {
|
||||
config.SamHost = config.GetSAMHost(SamHost, config.SamHost)
|
||||
}
|
||||
if SamPort != "" && SamPort != "7656" {
|
||||
config.SamPort = config.GetSAMPort(SamPort, config.SamPort)
|
||||
}
|
||||
return NewSAMForwarderFromConf(config)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewSAMDGForwarderFromConf generates a SAMSSUforwarder from *i2ptunconf.Conf
|
||||
func NewSAMDGForwarderFromConf(config *i2ptunconf.Conf) (*samforwarderudp.SAMDGForwarder, error) {
|
||||
if config != nil {
|
||||
return samforwarderudp.NewSAMDGForwarderFromOptions(
|
||||
samoptions.SetSaveFile(config.SaveFile),
|
||||
samoptions.SetFilePath(config.SaveDirectory),
|
||||
samoptions.SetHost(config.TargetHost),
|
||||
samoptions.SetPort(config.TargetPort),
|
||||
samoptions.SetSAMHost(config.SamHost),
|
||||
samoptions.SetSAMPort(config.SamPort),
|
||||
samoptions.SetSigType(config.SigType),
|
||||
samoptions.SetName(config.TunName),
|
||||
samoptions.SetInLength(config.InLength),
|
||||
samoptions.SetOutLength(config.OutLength),
|
||||
samoptions.SetInVariance(config.InVariance),
|
||||
samoptions.SetOutVariance(config.OutVariance),
|
||||
samoptions.SetInQuantity(config.InQuantity),
|
||||
samoptions.SetOutQuantity(config.OutQuantity),
|
||||
samoptions.SetInBackups(config.InBackupQuantity),
|
||||
samoptions.SetOutBackups(config.OutBackupQuantity),
|
||||
samoptions.SetEncrypt(config.EncryptLeaseSet),
|
||||
samoptions.SetLeaseSetKey(config.LeaseSetKey),
|
||||
samoptions.SetLeaseSetPrivateKey(config.LeaseSetPrivateKey),
|
||||
samoptions.SetLeaseSetPrivateSigningKey(config.LeaseSetPrivateSigningKey),
|
||||
samoptions.SetAllowZeroIn(config.InAllowZeroHop),
|
||||
samoptions.SetAllowZeroOut(config.OutAllowZeroHop),
|
||||
samoptions.SetFastRecieve(config.FastRecieve),
|
||||
samoptions.SetCompress(config.UseCompression),
|
||||
samoptions.SetReduceIdle(config.ReduceIdle),
|
||||
samoptions.SetReduceIdleTimeMs(config.ReduceIdleTime),
|
||||
samoptions.SetReduceIdleQuantity(config.ReduceIdleQuantity),
|
||||
samoptions.SetCloseIdle(config.CloseIdle),
|
||||
samoptions.SetCloseIdleTimeMs(config.CloseIdleTime),
|
||||
samoptions.SetAccessListType(config.AccessListType),
|
||||
samoptions.SetAccessList(config.AccessList),
|
||||
samoptions.SetMessageReliability(config.MessageReliability),
|
||||
samoptions.SetKeyFile(config.KeyFilePath),
|
||||
)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewSAMDGForwarderFromConfig generates a new SAMDGForwarder from a config file
|
||||
func NewSAMDGForwarderFromConfig(iniFile, SamHost, SamPort string, label ...string) (*samforwarderudp.SAMDGForwarder, error) {
|
||||
if iniFile != "none" {
|
||||
config, err := i2ptunconf.NewI2PTunConf(iniFile, label...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if SamHost != "" && SamHost != "127.0.0.1" && SamHost != "localhost" {
|
||||
config.SamHost = config.GetSAMHost(SamHost, config.SamHost)
|
||||
}
|
||||
if SamPort != "" && SamPort != "7656" {
|
||||
config.SamPort = config.GetSAMPort(SamPort, config.SamPort)
|
||||
}
|
||||
return NewSAMDGForwarderFromConf(config)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewEepHttpdFromConf generates a SAMforwarder from *i2ptunconf.Conf
|
||||
func NewEepHttpdFromConf(config *i2ptunconf.Conf) (*eephttpd.EepHttpd, error) {
|
||||
if config != nil {
|
||||
return eephttpd.NewEepHttpdFromOptions(
|
||||
eephttpd.SetType(config.Type),
|
||||
eephttpd.SetSaveFile(config.SaveFile),
|
||||
eephttpd.SetFilePath(config.SaveDirectory),
|
||||
eephttpd.SetHost(config.TargetHost),
|
||||
eephttpd.SetPort(config.TargetPort),
|
||||
eephttpd.SetSAMHost(config.SamHost),
|
||||
eephttpd.SetSAMPort(config.SamPort),
|
||||
eephttpd.SetSigType(config.SigType),
|
||||
eephttpd.SetName(config.TunName),
|
||||
eephttpd.SetInLength(config.InLength),
|
||||
eephttpd.SetOutLength(config.OutLength),
|
||||
eephttpd.SetInVariance(config.InVariance),
|
||||
eephttpd.SetOutVariance(config.OutVariance),
|
||||
eephttpd.SetInQuantity(config.InQuantity),
|
||||
eephttpd.SetOutQuantity(config.OutQuantity),
|
||||
eephttpd.SetInBackups(config.InBackupQuantity),
|
||||
eephttpd.SetOutBackups(config.OutBackupQuantity),
|
||||
eephttpd.SetEncrypt(config.EncryptLeaseSet),
|
||||
eephttpd.SetLeaseSetKey(config.LeaseSetKey),
|
||||
eephttpd.SetLeaseSetPrivateKey(config.LeaseSetPrivateKey),
|
||||
eephttpd.SetLeaseSetPrivateSigningKey(config.LeaseSetPrivateSigningKey),
|
||||
eephttpd.SetAllowZeroIn(config.InAllowZeroHop),
|
||||
eephttpd.SetAllowZeroOut(config.OutAllowZeroHop),
|
||||
eephttpd.SetFastRecieve(config.FastRecieve),
|
||||
eephttpd.SetCompress(config.UseCompression),
|
||||
eephttpd.SetReduceIdle(config.ReduceIdle),
|
||||
eephttpd.SetReduceIdleTimeMs(config.ReduceIdleTime),
|
||||
eephttpd.SetReduceIdleQuantity(config.ReduceIdleQuantity),
|
||||
eephttpd.SetCloseIdle(config.CloseIdle),
|
||||
eephttpd.SetCloseIdleTimeMs(config.CloseIdleTime),
|
||||
eephttpd.SetAccessListType(config.AccessListType),
|
||||
eephttpd.SetAccessList(config.AccessList),
|
||||
eephttpd.SetMessageReliability(config.MessageReliability),
|
||||
eephttpd.SetKeyFile(config.KeyFilePath),
|
||||
eephttpd.SetServeDir(config.ServeDirectory),
|
||||
//eephttpd.SetTargetForPort443(config.TargetForPort443),
|
||||
)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// NewEepHttpdFromConfig generates a new EepHttpd from a config file
|
||||
func NewEepHttpdFromConfig(iniFile, SamHost, SamPort string, label ...string) (*eephttpd.EepHttpd, error) {
|
||||
if iniFile != "none" {
|
||||
config, err := i2ptunconf.NewI2PTunConf(iniFile, label...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if SamHost != "" && SamHost != "127.0.0.1" && SamHost != "localhost" {
|
||||
config.SamHost = config.GetSAMHost(SamHost, config.SamHost)
|
||||
}
|
||||
if SamPort != "" && SamPort != "7656" {
|
||||
config.SamPort = config.GetSAMPort(SamPort, config.SamPort)
|
||||
}
|
||||
return NewEepHttpdFromConf(config)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
53
config/hostport.go
Normal file
53
config/hostport.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package i2ptunconf
|
||||
|
||||
// GetHost takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetHost(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("host", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// GetPort takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetPort(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("port", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetHost sets the host to forward from the config file
|
||||
func (c *Conf) SetHost(label ...string) {
|
||||
if v, ok := c.Get("host", label...); ok {
|
||||
c.TargetHost = v
|
||||
} else {
|
||||
c.TargetHost = "127.0.0.1"
|
||||
}
|
||||
}
|
||||
|
||||
// SetPort sets the port to forward from the config file
|
||||
func (c *Conf) SetPort(label ...string) {
|
||||
if v, ok := c.Get("port", label...); ok {
|
||||
c.TargetPort = v
|
||||
} else {
|
||||
c.TargetPort = "8081"
|
||||
}
|
||||
}
|
131
config/leasesets.go
Normal file
131
config/leasesets.go
Normal file
@@ -0,0 +1,131 @@
|
||||
package i2ptunconf
|
||||
|
||||
// GetEncryptLeaseset takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetEncryptLeaseset(arg, def bool, label ...string) bool {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.GetBool("i2cp.encryptLeaseSet", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetEncryptLease tells the conf to use encrypted leasesets the from the config file
|
||||
func (c *Conf) SetEncryptLease(label ...string) {
|
||||
if v, ok := c.GetBool("i2cp.encryptLeaseSet", label...); ok {
|
||||
c.EncryptLeaseSet = v
|
||||
} else {
|
||||
c.EncryptLeaseSet = false
|
||||
}
|
||||
}
|
||||
|
||||
// GetLeasesetKey takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetLeasesetKey(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("i2cp.leaseSetKey", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetEncryptLease tells the conf to use encrypted leasesets the from the config file
|
||||
func (c *Conf) SetLeasesetKey(label ...string) {
|
||||
if v, ok := c.Get("i2cp.leaseSetKey", label...); ok {
|
||||
c.LeaseSetKey = v
|
||||
} else {
|
||||
c.LeaseSetKey = ""
|
||||
}
|
||||
}
|
||||
|
||||
// GetLeasesetPrivateKey takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetLeasesetPrivateKey(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("i2cp.leaseSetPrivateKey", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetLeasesetPrivateKey tells the conf to use encrypted leasesets the from the config file
|
||||
func (c *Conf) SetLeasesetPrivateKey(label ...string) {
|
||||
if v, ok := c.Get("i2cp.leaseSetPrivateKey", label...); ok {
|
||||
c.LeaseSetPrivateKey = v
|
||||
} else {
|
||||
c.LeaseSetPrivateKey = ""
|
||||
}
|
||||
}
|
||||
|
||||
// GetLeasesetPrivateSigningKey takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetLeasesetPrivateSigningKey(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("i2cp.leaseSetPrivateSigningKey", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetLeasesetPrivateSigningKey tells the conf to use encrypted leasesets the from the config file
|
||||
func (c *Conf) SetLeasesetPrivateSigningKey(label ...string) {
|
||||
if v, ok := c.Get("i2cp.leaseSetPrivateKey", label...); ok {
|
||||
c.LeaseSetPrivateSigningKey = v
|
||||
} else {
|
||||
c.LeaseSetPrivateSigningKey = ""
|
||||
}
|
||||
}
|
||||
|
||||
// GetLeaseSetEncType takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetLeaseSetEncType(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("i2cp.leaseSetEncType", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetLeaseSetEncType tells the conf to use encrypted leasesets the from the config file
|
||||
func (c *Conf) SetLeaseSetEncType(label ...string) {
|
||||
if v, ok := c.Get("i2cp.leaseSetEncType", label...); ok {
|
||||
c.LeaseSetEncType = v
|
||||
} else {
|
||||
c.LeaseSetEncType = ""
|
||||
}
|
||||
}
|
53
config/length.go
Normal file
53
config/length.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package i2ptunconf
|
||||
|
||||
// GetInLength takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetInLength(arg, def int, label ...string) int {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.GetInt("inbound.length", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// GetOutLength takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetOutLength(arg, def int, label ...string) int {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.GetInt("outbound.length", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetInLength sets the inbound length from the config file
|
||||
func (c *Conf) SetInLength(label ...string) {
|
||||
if v, ok := c.GetInt("inbound.length", label...); ok {
|
||||
c.OutLength = v
|
||||
} else {
|
||||
c.OutLength = 3
|
||||
}
|
||||
}
|
||||
|
||||
// SetOutLength sets the outbound lenth from the config file
|
||||
func (c *Conf) SetOutLength(label ...string) {
|
||||
if v, ok := c.GetInt("outbound.length", label...); ok {
|
||||
c.InLength = v
|
||||
} else {
|
||||
c.InLength = 3
|
||||
}
|
||||
}
|
52
config/name.go
Normal file
52
config/name.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package i2ptunconf
|
||||
|
||||
// GetSaveFile takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetSaveFile(arg, def bool, label ...string) bool {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
return c.SaveFile
|
||||
}
|
||||
|
||||
// GetKeys takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetKeys(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("keys", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetKeys sets the key name from the config file
|
||||
func (c *Conf) SetKeys(label ...string) {
|
||||
if v, ok := c.Get("keys", label...); ok {
|
||||
c.TunName = v
|
||||
c.SaveFile = true
|
||||
} else {
|
||||
c.TunName = "forwarder"
|
||||
c.SaveFile = false
|
||||
}
|
||||
}
|
||||
|
||||
// SetTunName sets the tunnel name from the config file
|
||||
func (c *Conf) SetTunName(label ...string) {
|
||||
if v, ok := c.Get("keys", label...); ok {
|
||||
c.TunName = v
|
||||
} else {
|
||||
c.TunName = "forwarder"
|
||||
}
|
||||
}
|
27
config/password.go
Normal file
27
config/password.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package i2ptunconf
|
||||
|
||||
// GetPassword takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetPassword(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("username", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetKeys sets the key name from the config file
|
||||
func (c *Conf) SetPassword(label ...string) {
|
||||
if v, ok := c.Get("username", label...); ok {
|
||||
c.Password = v
|
||||
} else {
|
||||
c.Password = "samcatd"
|
||||
}
|
||||
}
|
53
config/quantity.go
Normal file
53
config/quantity.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package i2ptunconf
|
||||
|
||||
// GetInQuantity takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetInQuantity(arg, def int, label ...string) int {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.GetInt("inbound.quantity", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// GetOutQuantity takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetOutQuantity(arg, def int, label ...string) int {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.GetInt("outbound.quantity", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetInQuantity sets the inbound tunnel quantity from config file
|
||||
func (c *Conf) SetInQuantity(label ...string) {
|
||||
if v, ok := c.GetInt("inbound.quantity", label...); ok {
|
||||
c.InQuantity = v
|
||||
} else {
|
||||
c.InQuantity = 1
|
||||
}
|
||||
}
|
||||
|
||||
// SetOutQuantity sets the outbound tunnel quantity from config file
|
||||
func (c *Conf) SetOutQuantity(label ...string) {
|
||||
if v, ok := c.GetInt("outbound.quantity", label...); ok {
|
||||
c.OutQuantity = v
|
||||
} else {
|
||||
c.OutQuantity = 1
|
||||
}
|
||||
}
|
131
config/reduceclose.go
Normal file
131
config/reduceclose.go
Normal file
@@ -0,0 +1,131 @@
|
||||
package i2ptunconf
|
||||
|
||||
// GetReduceOnIdle takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetReduceOnIdle(arg, def bool, label ...string) bool {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.GetBool("i2cp.reduceOnIdle", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// GetReduceIdleTime takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetReduceIdleTime(arg, def int, label ...string) int {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.GetInt("i2cp.reduceIdleTime", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// GetReduceIdleQuantity takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetReduceIdleQuantity(arg, def int, label ...string) int {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.GetInt("i2cp.reduceIdleQuantity", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// GetCloseOnIdle takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetCloseOnIdle(arg, def bool, label ...string) bool {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.GetBool("i2cp.closeOnIdle", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// GetCloseIdleTime takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetCloseIdleTime(arg, def int, label ...string) int {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.GetInt("i2cp.closeIdleTime", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetReduceIdle sets the config to reduce tunnels after idle time from config file
|
||||
func (c *Conf) SetReduceIdle(label ...string) {
|
||||
if v, ok := c.GetBool("i2cp.reduceOnIdle", label...); ok {
|
||||
c.ReduceIdle = v
|
||||
} else {
|
||||
c.ReduceIdle = false
|
||||
}
|
||||
}
|
||||
|
||||
// SetReduceIdleTime sets the time to wait before reducing tunnels from config file
|
||||
func (c *Conf) SetReduceIdleTime(label ...string) {
|
||||
if v, ok := c.GetInt("i2cp.reduceIdleTime", label...); ok {
|
||||
c.ReduceIdleTime = v
|
||||
} else {
|
||||
c.ReduceIdleTime = 300000
|
||||
}
|
||||
}
|
||||
|
||||
// SetReduceIdleQuantity sets the number of tunnels to reduce to from config file
|
||||
func (c *Conf) SetReduceIdleQuantity(label ...string) {
|
||||
if v, ok := c.GetInt("i2cp.reduceQuantity", label...); ok {
|
||||
c.ReduceIdleQuantity = v
|
||||
} else {
|
||||
c.ReduceIdleQuantity = 3
|
||||
}
|
||||
}
|
||||
|
||||
// SetCloseIdle sets the tunnel to automatically close on idle from the config file
|
||||
func (c *Conf) SetCloseIdle(label ...string) {
|
||||
if v, ok := c.GetBool("i2cp.closeOnIdle", label...); ok {
|
||||
c.CloseIdle = v
|
||||
} else {
|
||||
c.CloseIdle = false
|
||||
}
|
||||
}
|
||||
|
||||
// SetCloseIdleTime sets the time to wait before killing a tunnel from a config file
|
||||
func (c *Conf) SetCloseIdleTime(label ...string) {
|
||||
if v, ok := c.GetInt("i2cp.closeIdleTime", label...); ok {
|
||||
c.CloseIdleTime = v
|
||||
} else {
|
||||
c.CloseIdleTime = 300000
|
||||
}
|
||||
}
|
33
config/reliability.go
Normal file
33
config/reliability.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package i2ptunconf
|
||||
|
||||
//i2cp.messageReliability
|
||||
// GetMessageReliability takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetMessageReliability(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
return c.MessageReliability
|
||||
}
|
||||
|
||||
// SetMessageReliability sets the access list type from a config file
|
||||
func (c *Conf) SetMessageReliability(label ...string) {
|
||||
if v, ok := c.Get("i2cp.messageReliability", label...); ok {
|
||||
c.MessageReliability = v
|
||||
}
|
||||
if c.MessageReliability != "BestEffort" && c.MessageReliability != "none" {
|
||||
c.MessageReliability = "none"
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Conf) reliability() string {
|
||||
if c.MessageReliability != "" {
|
||||
return "i2cp.messageReliability=" + c.MessageReliability
|
||||
}
|
||||
return ""
|
||||
}
|
53
config/samhostport.go
Normal file
53
config/samhostport.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package i2ptunconf
|
||||
|
||||
// GetSAMHost takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetSAMHost(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("samhost", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// GetSAMPort takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetSAMPort(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("samport", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetSAMHost sets the SAM host from the config file
|
||||
func (c *Conf) SetSAMHost(label ...string) {
|
||||
if v, ok := c.Get("samhost", label...); ok {
|
||||
c.SamHost = v
|
||||
} else {
|
||||
c.SamHost = "127.0.0.1"
|
||||
}
|
||||
}
|
||||
|
||||
// SetSAMPort sets the SAM port from the config file
|
||||
func (c *Conf) SetSAMPort(label ...string) {
|
||||
if v, ok := c.Get("samport", label...); ok {
|
||||
c.SamPort = v
|
||||
} else {
|
||||
c.SamPort = "7656"
|
||||
}
|
||||
}
|
45
config/sigtype.go
Normal file
45
config/sigtype.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package i2ptunconf
|
||||
|
||||
// GetSigType takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetSigType(argt, def string, label ...string) string {
|
||||
var typ string
|
||||
if argt == "" {
|
||||
typ = ""
|
||||
} else if argt == "DSA_SHA1" {
|
||||
typ = "DSA_SHA1"
|
||||
} else if argt == "ECDSA_SHA256_P256" {
|
||||
typ = "ECDSA_SHA256_P256"
|
||||
} else if argt == "ECDSA_SHA384_P384" {
|
||||
typ = "ECDSA_SHA384_P384"
|
||||
} else if argt == "ECDSA_SHA512_P521" {
|
||||
typ = "ECDSA_SHA512_P521"
|
||||
} else if argt == "EdDSA_SHA512_Ed25519" {
|
||||
typ = "EdDSA_SHA512_Ed25519"
|
||||
} else {
|
||||
typ = "EdDSA_SHA512_Ed25519"
|
||||
}
|
||||
if typ != def {
|
||||
return typ
|
||||
}
|
||||
if c.Config == nil {
|
||||
return typ
|
||||
}
|
||||
if x, o := c.Get("signaturetype", label...); o {
|
||||
return x
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
// SetSigType sets the type of proxy to create from the config file
|
||||
func (c *Conf) SetSigType(label ...string) {
|
||||
if v, ok := c.Get("signaturetype", label...); ok {
|
||||
if c.SigType == "" || c.SigType == "DSA_SHA1" || c.SigType == "ECDSA_SHA256_P256" || c.SigType == "ECDSA_SHA384_P384" || c.SigType == "ECDSA_SHA512_P521" || c.SigType == "EdDSA_SHA512_Ed25519" {
|
||||
c.SigType = v
|
||||
}
|
||||
} else {
|
||||
c.SigType = "EdDSA_SHA512_Ed25519"
|
||||
}
|
||||
}
|
1
config/timeout.go
Normal file
1
config/timeout.go
Normal file
@@ -0,0 +1 @@
|
||||
package i2ptunconf
|
111
config/tls.go
Normal file
111
config/tls.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package i2ptunconf
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"strings"
|
||||
|
||||
"github.com/eyedeekay/sam-forwarder/tls"
|
||||
)
|
||||
|
||||
// GetPort443 takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetPort443(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("targetForPort.443", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetTargetPort443 sets the port to forward from the config file
|
||||
func (c *Conf) SetTargetPort443(label ...string) {
|
||||
if v, ok := c.Get("targetForPort.443", label...); ok {
|
||||
c.TargetForPort443 = v
|
||||
} else {
|
||||
c.TargetForPort443 = ""
|
||||
}
|
||||
}
|
||||
|
||||
// Get
|
||||
func (c *Conf) GetUseTLS(arg, def bool, label ...string) bool {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.GetBool("usetls", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetAllowZeroHopOut sets the config to allow zero-hop tunnels
|
||||
func (c *Conf) SetUseTLS(label ...string) {
|
||||
if v, ok := c.GetBool("usetls", label...); ok {
|
||||
c.UseTLS = v
|
||||
} else {
|
||||
c.UseTLS = false
|
||||
}
|
||||
}
|
||||
|
||||
// GetTLSConfig
|
||||
func (c *Conf) GetTLSConfigCertPem(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("cert.pem", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetClientDest sets the key name from the config file
|
||||
func (c *Conf) SetTLSConfigCertPem(label ...string) {
|
||||
if v, ok := c.Get("cert.pem", label...); ok {
|
||||
c.Cert = v
|
||||
} else {
|
||||
c.Cert = ""
|
||||
}
|
||||
}
|
||||
|
||||
// GetTLSConfig
|
||||
func (c *Conf) GetTLSConfigKeyPem(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("key.pem", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetClientDest sets the key name from the config file
|
||||
func (c *Conf) SetTLSConfigKeyPem(label ...string) {
|
||||
if v, ok := c.Get("key.pem", label...); ok {
|
||||
c.Pem = v
|
||||
} else {
|
||||
c.Pem = ""
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Conf) TLSConfig() (*tls.Config, error) {
|
||||
names := []string{c.Base32()}
|
||||
if c.HostName != "" && strings.HasSuffix(c.HostName, ".i2p") {
|
||||
names = append(names, c.HostName)
|
||||
}
|
||||
return i2ptls.TLSConfig(c.Cert, c.Pem, names)
|
||||
}
|
1275
config/tunconf.go
1275
config/tunconf.go
File diff suppressed because it is too large
Load Diff
119
config/type.go
Normal file
119
config/type.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package i2ptunconf
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GetType takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetTypes(argc, argu, argh bool, def string, label ...string) string {
|
||||
var typ string
|
||||
if argu {
|
||||
typ += "udp"
|
||||
}
|
||||
if argc {
|
||||
if argh == true {
|
||||
typ += "http"
|
||||
}
|
||||
typ += "client"
|
||||
c.Client = true
|
||||
} else {
|
||||
if argh == true {
|
||||
typ += "http"
|
||||
} else {
|
||||
typ += "server"
|
||||
}
|
||||
if typ != def {
|
||||
return typ
|
||||
}
|
||||
}
|
||||
if def == "kcpclient" {
|
||||
return def
|
||||
}
|
||||
if def == "kcpserver" {
|
||||
return def
|
||||
}
|
||||
if def == "eephttpd" {
|
||||
return def
|
||||
}
|
||||
if def == "vpnclient" {
|
||||
return def
|
||||
}
|
||||
if def == "vpnserver" {
|
||||
return def
|
||||
}
|
||||
if def == "outproxy" {
|
||||
return def
|
||||
}
|
||||
if def == "outproxyhttp" {
|
||||
return def
|
||||
}
|
||||
if def == "browserclient" {
|
||||
return def
|
||||
}
|
||||
if c.Config == nil {
|
||||
return typ
|
||||
}
|
||||
if x, o := c.Get("type", label...); o {
|
||||
return x
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
func (c *Conf) GetOtherType(typ, def string, label ...string) string {
|
||||
if typ != def {
|
||||
return typ
|
||||
}
|
||||
if c.Config == nil {
|
||||
return typ
|
||||
}
|
||||
if x, o := c.Get("type", label...); o {
|
||||
return x
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
// SetType sets the type of proxy to create from the config file
|
||||
func (c *Conf) SetType(label ...string) {
|
||||
if v, ok := c.Get("type", label...); ok {
|
||||
if strings.Contains(v, "client") {
|
||||
c.Client = true
|
||||
}
|
||||
switch c.Type {
|
||||
case "server":
|
||||
c.Type = v
|
||||
case "http":
|
||||
c.Type = v
|
||||
case "client":
|
||||
c.Type = v
|
||||
case "httpclient":
|
||||
c.Type = v
|
||||
case "browserclient":
|
||||
c.Type = v
|
||||
case "udpserver":
|
||||
c.Type = v
|
||||
case "udpclient":
|
||||
c.Type = v
|
||||
case "eephttpd":
|
||||
c.Type = v
|
||||
case "outproxy":
|
||||
c.Type = v
|
||||
case "outproxyhttp":
|
||||
c.Type = v
|
||||
case "vpnserver":
|
||||
c.Type = v
|
||||
case "vpnclient":
|
||||
c.Type = v
|
||||
case "kcpclient":
|
||||
c.Type = v
|
||||
case "kcpserver":
|
||||
c.Type = v
|
||||
default:
|
||||
c.Type = "browserclient"
|
||||
}
|
||||
} else {
|
||||
c.Type = "browserclient"
|
||||
}
|
||||
}
|
27
config/user.go
Normal file
27
config/user.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package i2ptunconf
|
||||
|
||||
// GetUserName takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetUserName(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("username", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetKeys sets the key name from the config file
|
||||
func (c *Conf) SetUserName(label ...string) {
|
||||
if v, ok := c.Get("username", label...); ok {
|
||||
c.UserName = v
|
||||
} else {
|
||||
c.UserName = "samcatd"
|
||||
}
|
||||
}
|
53
config/variance.go
Normal file
53
config/variance.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package i2ptunconf
|
||||
|
||||
// GetInVariance takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetInVariance(arg, def int, label ...string) int {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.GetInt("inbound.variance", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// GetOutVariance takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetOutVariance(arg, def int, label ...string) int {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.GetInt("outbound.variance", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetInVariance sets the inbound tunnel variance from config file
|
||||
func (c *Conf) SetInVariance(label ...string) {
|
||||
if v, ok := c.GetInt("inbound.variance", label...); ok {
|
||||
c.InVariance = v
|
||||
} else {
|
||||
c.InVariance = 0
|
||||
}
|
||||
}
|
||||
|
||||
// SetOutVariance sets the outbound tunnel variance from config file
|
||||
func (c *Conf) SetOutVariance(label ...string) {
|
||||
if v, ok := c.GetInt("outbound.variance", label...); ok {
|
||||
c.OutVariance = v
|
||||
} else {
|
||||
c.OutVariance = 0
|
||||
}
|
||||
}
|
29
config/wwwdir.go
Normal file
29
config/wwwdir.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package i2ptunconf
|
||||
|
||||
//
|
||||
|
||||
// GetDir takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetWWWDir(arg, def string, label ...string) string {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.Get("wwwdir", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetDir sets the key save directory from the config file
|
||||
func (c *Conf) SetWWWDir(label ...string) {
|
||||
if v, ok := c.Get("wwwdir", label...); ok {
|
||||
c.ServeDirectory = v
|
||||
} else {
|
||||
c.ServeDirectory = "./www"
|
||||
}
|
||||
}
|
53
config/zerohops.go
Normal file
53
config/zerohops.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package i2ptunconf
|
||||
|
||||
// GetInAllowZeroHop takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetInAllowZeroHop(arg, def bool, label ...string) bool {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.GetBool("inbound.allowZeroHop", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// GetOutAllowZeroHop takes an argument and a default. If the argument differs from the
|
||||
// default, the argument is always returned. If the argument and default are
|
||||
// the same and the key exists, the key is returned. If the key is absent, the
|
||||
// default is returned.
|
||||
func (c *Conf) GetOutAllowZeroHop(arg, def bool, label ...string) bool {
|
||||
if arg != def {
|
||||
return arg
|
||||
}
|
||||
if c.Config == nil {
|
||||
return arg
|
||||
}
|
||||
if x, o := c.GetBool("outbound.allowZeroHop", label...); o {
|
||||
return x
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
// SetAllowZeroHopIn sets the config to allow zero-hop tunnels
|
||||
func (c *Conf) SetAllowZeroHopIn(label ...string) {
|
||||
if v, ok := c.GetBool("inbound.allowZeroHop", label...); ok {
|
||||
c.InAllowZeroHop = v
|
||||
} else {
|
||||
c.InAllowZeroHop = false
|
||||
}
|
||||
}
|
||||
|
||||
// SetAllowZeroHopOut sets the config to allow zero-hop tunnels
|
||||
func (c *Conf) SetAllowZeroHopOut(label ...string) {
|
||||
if v, ok := c.GetBool("outbound.allowZeroHop", label...); ok {
|
||||
c.OutAllowZeroHop = v
|
||||
} else {
|
||||
c.OutAllowZeroHop = false
|
||||
}
|
||||
}
|
78
docs/EMBEDDING.md
Normal file
78
docs/EMBEDDING.md
Normal file
@@ -0,0 +1,78 @@
|
||||
Embedding i2p support in your Go application with samforwarder
|
||||
==============================================================
|
||||
|
||||
One neat thing you can do with samforwarder is make eepWeb(?) services configure
|
||||
themselves automatically by adding it to an existing Go application. To help
|
||||
with this process, the samforwarder/config/ file has a bunch of helper
|
||||
functions and a class for parsing configuration files directly. You can import
|
||||
it, add a few flags(or however you configure your service) and fire off the
|
||||
forwarder as a goroutne, all you have to do is configure it to forward the port
|
||||
used by your service. This makes it extremely easy to do, but it should only be
|
||||
used in this way for applications that would already be safe to host as services
|
||||
in i2p or other overlay networks. In particular, it should only be used for
|
||||
applications that don't require extensive login information and do not leak
|
||||
information at the application layer.
|
||||
|
||||
So without further ado, a blatant copy-paste of information that shouldn't have
|
||||
been in the README.md.
|
||||
|
||||
## Static eepsite in like no seconds
|
||||
|
||||
Using this port forwarder, it's possible to create an instant eepsite from a
|
||||
folder full of html files(and the resources they call upon). Probably obviously
|
||||
to everybody reading this right now, but maybe not obviously to everyone reading
|
||||
this forever. An example of an application that works this way is available
|
||||
[here at my eephttpd repo](https://github.com/eyedeekay/eephttpd).
|
||||
|
||||
## Quick-And-Dirty i2p-enabled golang web applications
|
||||
|
||||
Normal web applications can easily add the ability to serve itself over i2p by
|
||||
importing and configuring this forwarding doodad. Wherever it takes the argument
|
||||
for the web server's listening host and/or port, pass that same host and/or port
|
||||
to a new instance of the "SAMForwarder" and then run the "Serve" function of the
|
||||
SAMForwarder as a goroutine. This simply forwards the running service to the i2p
|
||||
network, it doesn't do any filtering, and if your application establishes
|
||||
out-of-band connections, those may escape. Also, if your application is
|
||||
listening on all addresses, it will be visible from the local network.
|
||||
|
||||
Here's a simple example with a simple static file server:
|
||||
|
||||
```Diff
|
||||
package main package main
|
||||
|
||||
import ( import (
|
||||
"flag" "flag"
|
||||
"log" "log"
|
||||
"net/http" "net/http"
|
||||
) )
|
||||
|
||||
> import "github.com/eyedeekay/sam-forwarder"
|
||||
>
|
||||
func main() { func main() {
|
||||
port := flag.String("p", "8100", "port to serve on") port := flag.String("p", "8100", "port to serve on")
|
||||
directory := flag.String("d", ".", "the directory of static file to host") directory := flag.String("d", ".", "the directory of static file to host")
|
||||
flag.Parse() flag.Parse()
|
||||
>
|
||||
> forwarder, err := samforwarder.NewSAMForwarderFromOptions(
|
||||
> samforwarder.SetHost("127.0.0.1"),
|
||||
> samforwarder.SetPort(*port),
|
||||
> samforwarder.SetSAMHost("127.0.0.1"),
|
||||
> samforwarder.SetSAMPort("7656"),
|
||||
> samforwarder.SetName("staticfiles"),
|
||||
> )
|
||||
> if err != nil {
|
||||
> log.Fatal(err.Error())
|
||||
> }
|
||||
> go forwarder.Serve()
|
||||
|
||||
http.Handle("/", http.FileServer(http.Dir(*directory))) http.Handle("/", http.FileServer(http.Dir(*directory)))
|
||||
|
||||
log.Printf("Serving %s on HTTP port: %s\n", *directory, *port) log.Printf("Serving %s on HTTP port: %s\n", *directory, *port)
|
||||
log.Fatal(http.ListenAndServe("127.0.0.1:"+*port, nil)) log.Fatal(http.ListenAndServe("127.0.0.1:"+*port, nil))
|
||||
} }
|
||||
|
||||
```
|
||||
|
||||
[This tiny file server taken from here and used for this example](https://gist.github.com/paulmach/7271283)
|
||||
|
||||
## Integrating your Go web application with i2p using sam-forwarder
|
3
docs/PACKAGECONF.md
Normal file
3
docs/PACKAGECONF.md
Normal file
@@ -0,0 +1,3 @@
|
||||
Encapsulating and Packaging Application Configuration with samcatd
|
||||
==================================================================
|
||||
|
225
docs/USAGE.md
Normal file
225
docs/USAGE.md
Normal file
@@ -0,0 +1,225 @@
|
||||
samcatd - Router-independent tunnel management for i2p
|
||||
=========================================================
|
||||
|
||||
samcatd is a daemon which runs a group of forwarding proxies to
|
||||
provide services over i2p independent of the router. It also serves
|
||||
as a generalized i2p networking utility for power-users. It's
|
||||
intended to be a Swiss-army knife for the SAM API.
|
||||
|
||||
usage:
|
||||
------
|
||||
|
||||
```
|
||||
flag needs an argument: -h
|
||||
Usage of ./bin/samcatd:
|
||||
-a string
|
||||
Type of access list to use, can be "allowlist" "blocklist" or "none". (default "none")
|
||||
-c Client proxy mode(true or false)
|
||||
-conv string
|
||||
Display the base32 and base64 values of a specified .i2pkeys file
|
||||
-cr string
|
||||
Encrypt/decrypt the key files with a passfile
|
||||
-css string
|
||||
custom CSS for web interface (default "css/styles.css")
|
||||
-ct int
|
||||
Reduce tunnel quantity after X (milliseconds) (default 600000)
|
||||
-d string
|
||||
Directory to save tunnel configuration file in.
|
||||
-de string
|
||||
Destination to connect client's to by default.
|
||||
-f string
|
||||
Use an ini file for configuration(config file options override passed arguments for now.) (default "none")
|
||||
-h string
|
||||
Target host(Host of service to forward to i2p) (default "127.0.0.1")
|
||||
-i string
|
||||
Destination for client tunnels. Ignored for service tunnels. (default "none")
|
||||
-ib int
|
||||
Set inbound tunnel backup quantity(0 to 5) (default 2)
|
||||
-ih
|
||||
Inject X-I2P-DEST headers
|
||||
-il int
|
||||
Set inbound tunnel length(0 to 7) (default 3)
|
||||
-iq int
|
||||
Set inbound tunnel quantity(0 to 15) (default 6)
|
||||
-iv int
|
||||
Set inbound tunnel length variance(-7 to 7)
|
||||
-js string
|
||||
custom JS for web interface (default "js/scripts.js")
|
||||
-k string
|
||||
key for encrypted leaseset (default "none")
|
||||
-l Use an encrypted leaseset(true or false) (default true)
|
||||
-littleboss string
|
||||
instruct the littleboss:
|
||||
|
||||
start: start and manage this process using service name "service-name"
|
||||
stop: signal the littleboss to shutdown the process
|
||||
status: print statistics about the running littleboss
|
||||
reload: restart the managed process using the executed binary
|
||||
bypass: disable littleboss, run the program directly (default "bypass")
|
||||
-n string
|
||||
Tunnel name, this must be unique but can be anything. (default "forwarder")
|
||||
-ob int
|
||||
Set outbound tunnel backup quantity(0 to 5) (default 2)
|
||||
-ol int
|
||||
Set outbound tunnel length(0 to 7) (default 3)
|
||||
-oq int
|
||||
Set outbound tunnel quantity(0 to 15) (default 6)
|
||||
-ov int
|
||||
Set outbound tunnel length variance(-7 to 7)
|
||||
-p string
|
||||
Target port(Port of service to forward to i2p) (default "8081")
|
||||
-pk string
|
||||
private key for encrypted leaseset (default "none")
|
||||
-psk string
|
||||
private signing key for encrypted leaseset (default "none")
|
||||
-r Reduce tunnel quantity when idle(true or false)
|
||||
-rq int
|
||||
Reduce idle tunnel quantity to X (0 to 5) (default 3)
|
||||
-rt int
|
||||
Reduce tunnel quantity after X (milliseconds) (default 600000)
|
||||
-s Start a tunnel with the passed parameters(Otherwise, they will be treated as default values.)
|
||||
-sh string
|
||||
SAM host (default "127.0.0.1")
|
||||
-sp string
|
||||
SAM port (default "7656")
|
||||
-st string
|
||||
Signature type
|
||||
-t Use saved file and persist tunnel(If false, tunnel will not persist after program is stopped.
|
||||
-tls string
|
||||
(Currently inoperative. Target TLS port(HTTPS Port of service to forward to i2p)
|
||||
-u UDP mode(true or false)
|
||||
-w Start web administration interface
|
||||
-wp string
|
||||
Web port (default "7957")
|
||||
-x Close tunnel idle(true or false)
|
||||
-z Uze gzip(true or false)
|
||||
-zi
|
||||
Allow zero-hop, non-anonymous tunnels in(true or false)
|
||||
-zo
|
||||
Allow zero-hop, non-anonymous tunnels out(true or false)
|
||||
```
|
||||
|
||||
managing samcatd save-encryption keys
|
||||
=====================================
|
||||
|
||||
In order to keep from saving the .i2pkeys files in plaintext format, samcatd
|
||||
can optionally generate a key and encrypt the .i2pkeys files securely. Of
|
||||
course, to fully benefit from this arrangement, you need to move those keys
|
||||
away from the machine where the tunnel keys(the .i2pkeys file) are located,
|
||||
or protect them in some other way(sandboxing, etc). If you want to use
|
||||
encrypted .i2pkeys files, you can specify a key file to use with the -cr
|
||||
option on the terminal or with keyfile option in the .ini file.
|
||||
|
||||
example config - valid for both ephsite and samcat
|
||||
==================================================
|
||||
Options are still being added, pretty much as fast as I can put them
|
||||
in. For up-to-the-minute options, see [the checklist](config/CHECKLIST.md)
|
||||
|
||||
(**ephsite** will only use top-level options, but they can be labeled or
|
||||
unlabeled)
|
||||
|
||||
(**samcatd** treats the first set of options it sees as the default, and
|
||||
does not start tunnels based on unlabeled options unless passed the
|
||||
-s flag.)
|
||||
|
||||
``` ini
|
||||
|
||||
## Defaults, these are only invoked with the -start option or if labeled tunnels
|
||||
## are not present(samcatd instructions). **THESE** are the correct config files
|
||||
## to use as defaults, and not the ones in ../sam-forwarder/tunnels.ini, which
|
||||
## are used for testing settings availability only.
|
||||
|
||||
inbound.length = 3
|
||||
outbound.length = 3
|
||||
inbound.lengthVariance = 0
|
||||
outbound.lengthVariance = 0
|
||||
inbound.backupQuantity = 3
|
||||
outbound.backupQuantity = 3
|
||||
inbound.quantity = 5
|
||||
outbound.quantity = 5
|
||||
inbound.allowZeroHop = false
|
||||
outbound.allowZeroHop = false
|
||||
i2cp.encryptLeaseSet = false
|
||||
gzip = true
|
||||
i2cp.reduceOnIdle = true
|
||||
i2cp.reduceIdleTime = 3000000
|
||||
i2cp.reduceQuantity = 2
|
||||
i2cp.enableWhiteList = false
|
||||
i2cp.enableBlackList = false
|
||||
keyfile = "/usr/share/samcatd/samcatd"
|
||||
|
||||
#[sam-forwarder-tcp-server]
|
||||
#type = server
|
||||
#host = 127.0.0.1
|
||||
#port = 8081
|
||||
#inbound.length = 3
|
||||
#outbound.length = 3
|
||||
#keys = forwarder
|
||||
|
||||
[sam-forwarder-tcp-client]
|
||||
type = client
|
||||
host = 127.0.0.1
|
||||
port = 8082
|
||||
inbound.length = 3
|
||||
outbound.length = 3
|
||||
destination = i2p-projekt.i2p
|
||||
keys = forwarder-two
|
||||
|
||||
#[sam-forwarder-udp-server]
|
||||
#type = udpserver
|
||||
#host = 127.0.0.1
|
||||
#port = 8084
|
||||
#inbound.length = 6
|
||||
#outbound.length = 3
|
||||
#keys = forwarder-four
|
||||
|
||||
#[sam-forwarder-udp-client]
|
||||
#type = udpclient
|
||||
#host = 127.0.0.1
|
||||
#port = 8083
|
||||
#inbound.length = 3
|
||||
#outbound.length = 3
|
||||
#destination = i2p-projekt.i2p
|
||||
#keys = forwarder-three
|
||||
|
||||
#[sam-forwarder-tcp-http-server]
|
||||
#type = http
|
||||
#host = 127.0.0.1
|
||||
#port = 8085
|
||||
#inbound.length = 3
|
||||
#outbound.length = 3
|
||||
#keys = forwarder-five
|
||||
|
||||
#[sam-forwarder-vpn-server]
|
||||
#type = udpserver
|
||||
#host = 127.0.0.1
|
||||
#port = 8084
|
||||
#inbound.length = 2
|
||||
#outbound.length = 2
|
||||
#inbound.backupQuantity = 3
|
||||
#outbound.backupQuantity = 3
|
||||
#inbound.quantity = 5
|
||||
#outbound.quantity = 5
|
||||
#i2cp.reduceOnIdle = true
|
||||
#i2cp.reduceIdleTime = 3000000
|
||||
#i2cp.reduceQuantity = 2
|
||||
#i2cp.closeOnIdle = false
|
||||
#keys = i2pvpnserver
|
||||
|
||||
#[sam-forwarder-vpn-client]
|
||||
#type = udpclient
|
||||
#host = 127.0.0.1
|
||||
#port = 8085
|
||||
#inbound.length = 2
|
||||
#outbound.length = 2
|
||||
#inbound.backupQuantity = 3
|
||||
#outbound.backupQuantity = 3
|
||||
#inbound.quantity = 5
|
||||
#outbound.quantity = 5
|
||||
#i2cp.reduceOnIdle = true
|
||||
#i2cp.reduceIdleTime = 3000000
|
||||
#i2cp.reduceQuantity = 2
|
||||
#destination = adestinationisrequiredorbespecifiedatruntime.i2p
|
||||
#keys = i2pvpnclient
|
||||
```
|
||||
|
96
docs/checklist.html
Normal file
96
docs/checklist.html
Normal file
@@ -0,0 +1,96 @@
|
||||
<h1 id="i2cptunnel-options-implementation-checklist">I2CP/Tunnel Options Implementation Checklist</h1>
|
||||
<p>This version of this document is valid for sam-forwarder. If you’d like to use it, the original is at <a href="CHECKLIST.orig.md" class="uri">CHECKLIST.orig.md</a>.</p>
|
||||
<p>key:</p>
|
||||
<pre><code>- \[U\] - Undone/Unknown
|
||||
- \[C\] - Confirmed Working
|
||||
- \[W\] - Work in progress
|
||||
- \[N\] - Not applicable/Won't be implemented without good reason.
|
||||
- \[*\] - See also
|
||||
|
||||
Version Recommended Allowable Default
|
||||
[U] - clientMessageTimeout 8*1000 - 120*1000 60*1000 The timeout (ms) for all sent messages. Unused. See the protocol specification for per-message settings.
|
||||
[N] - crypto.lowTagThreshold 0.9.2 1-128 30 Minimum number of ElGamal/AES Session Tags before we send more. Recommended: approximately tagsToSend * 2/3
|
||||
[N] - crypto.tagsToSend 0.9.2 1-128 40 Number of ElGamal/AES Session Tags to send at a time. For clients with relatively low bandwidth per-client-pair (IRC, some UDP apps), this may be set lower.
|
||||
[U] - explicitPeers null Comma-separated list of Base 64 Hashes of peers to build tunnels through; for debugging only
|
||||
[C] - i2cp.dontPublishLeaseSet true,false false Should generally be set to true for clients and false for servers
|
||||
[C] - i2cp.fastReceive 0.9.4 true,false false If true, the router just sends the MessagePayload instead of sending a MessageStatus and awaiting a ReceiveMessageBegin.
|
||||
[C] - i2cp.messageReliability BestEffort, None BestEffort Guaranteed is disabled; None implemented in 0.8.1; the streaming lib default is None as of 0.8.1, the client side default is None as of 0.9.4
|
||||
[U] - i2cp.password 0.8.2 string For authorization, if required by the router. If the client is running in the same JVM as a router, this option is not required. Warning - username and password are sent in the clear to the router, unless using SSL (i2cp.SSL=true). Authorization is only recommended when using SSL.
|
||||
[U] - i2cp.username 0.8.2 string
|
||||
[C] - inbound.allowZeroHop true,false true If incoming zero hop tunnel is allowed
|
||||
[C] - outbound.allowZeroHop true,false true If outgoing zero hop tunnel is allowed
|
||||
[C] - inbound.backupQuantity 0 to 3 No limit 0 Number of redundant fail-over for tunnels in
|
||||
[C] - outbound.backupQuantity 0 to 3 No limit 0 Number of redundant fail-over for tunnels out
|
||||
[U] - inbound.IPRestriction 0 to 4 0 to 4 2 Number of IP bytes to match to determine if two routers should not be in the same tunnel. 0 to disable.
|
||||
[U] - outbound.IPRestriction 0 to 4 0 to 4 2 Number of IP bytes to match to determine if two routers should not be in the same tunnel. 0 to disable.
|
||||
[C] - inbound.length 0 to 3 0 to 7 3 Length of tunnels in
|
||||
[C] - outbound.length 0 to 3 0 to 7 3 Length of tunnels out
|
||||
[C] - inbound.lengthVariance -1 to 2 -7 to 7 0 Random amount to add or subtract to the length of tunnels in. A positive number x means add a random amount from 0 to x inclusive. A negative number -x means add a random amount from -x to x inclusive. The router will limit the total length of the tunnel to 0 to 7 inclusive. The default variance was 1 prior to release 0.7.6.
|
||||
[C] - outbound.lengthVariance -1 to 2 -7 to 7 0 Random amount to add or subtract to the length of tunnels out. A positive number x means add a random amount from 0 to x inclusive. A negative number -x means add a random amount from -x to x inclusive. The router will limit the total length of the tunnel to 0 to 7 inclusive. The default variance was 1 prior to release 0.7.6.
|
||||
[U] - inbound.nickname string Name of tunnel - generally used in routerconsole, which will use the first few characters of the Base64 hash of the destination by default.
|
||||
[U] - outbound.nickname string Name of tunnel - generally ignored unless inbound.nickname is unset.
|
||||
[U] - outbound.priority 0.9.4 -25 to 25 -25 to 25 0 Priority adjustment for outbound messages. Higher is higher priority.
|
||||
[C] - inbound.quantity 1 to 3 1 to 16 2 Number of tunnels in. Limit was increased from 6 to 16 in release 0.9; however, numbers higher than 6 are incompatible with older releases.
|
||||
[C] - outbound.quantity 1 to 3 No limit 2 Number of tunnels out
|
||||
[U] - inbound.randomKey 0.9.17 Base 64 encoding of 32 random bytes Used for consistent peer ordering across restarts.
|
||||
[U] - outbound.randomKey 0.9.17 Base 64 encoding of 32 random bytes Used for consistent peer ordering across restarts.
|
||||
[*] - inbound.* Any other options prefixed with "inbound." are stored in the "unknown options" properties of the inbound tunnel pool's settings.
|
||||
[*] - outbound.* Any other options prefixed with "outbound." are stored in the "unknown options" properties of the outbound tunnel pool's settings.
|
||||
[U] - shouldBundleReplyInfo 0.9.2 true,false true Set to false to disable ever bundling a reply LeaseSet. For clients that do not publish their LeaseSet, this option must be true for any reply to be possible. "true" is also recommended for multihomed servers with long connection times. Setting to "false" may save significant outbound bandwidth, especially if the client is configured with a large number of inbound tunnels (Leases). If replies are still required, this may shift the bandwidth burden to the far-end client and the floodfill. There are several cases where "false" may be appropriate: Unidirectional communication, no reply required LeaseSet is published and higher reply latency is acceptable LeaseSet is published, client is a "server", all connections are inbound so the connecting far-end destination obviously has the leaseset already. Connections are either short, or it is acceptable for latency on a long-lived connection to temporarily increase while the other end re-fetches the LeaseSet after expiration. HTTP servers may fit these requirements.
|
||||
[C] - i2cp.closeIdleTime 0.7.1 1800000 300000 minimum (ms) Idle time required (default 30 minutes)
|
||||
[C] - i2cp.closeOnIdle 0.7.1 true,false false Close I2P session when idle
|
||||
[C] - i2cp.encryptLeaseSet 0.7.1 true,false false Encrypt the lease
|
||||
[C] - i2cp.fastReceive 0.9.4 true,false true If true, the router just sends the MessagePayload instead of sending a MessageStatus and awaiting a ReceiveMessageBegin.
|
||||
[C] - i2cp.gzip 0.6.5 true,false true Gzip outbound data
|
||||
[C] - i2cp.leaseSetKey 0.7.1 For encrypted leasesets. Base 64 SessionKey (44 characters)
|
||||
[C] - i2cp.leaseSetPrivateKey 0.9.18 Base 64 private key for encryption. Optionally preceded by the key type and ':'. Only "ELGAMAL_2048:" is supported, which is the default. I2CP will generate the public key from the private key. Use for persistent leaseset keys across restarts.
|
||||
[C] - i2cp.leaseSetSigningPrivateKey 0.9.18 Base 64 private key for signatures. Optionally preceded by the key type and ':'. DSA_SHA1 is the default. Key type must match the signature type in the destination. I2CP will generate the public key from the private key. Use for persistent leaseset keys across restarts.
|
||||
[C] - i2cp.reduceIdleTime 0.7.1 1200000 300000 minimum (ms) Idle time required (default 20 minutes, minimum 5 minutes)
|
||||
[C] - i2cp.reduceOnIdle 0.7.1 true,false false Reduce tunnel quantity when idle
|
||||
[C] - i2cp.reduceQuantity 0.7.1 1 1 to 5 1 Tunnel quantity when reduced (applies to both inbound and outbound)
|
||||
[*] - i2cp.SSL 0.8.3 true,false false Connect to the router using SSL. If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.
|
||||
[*] - i2cp.tcp.host 127.0.0.1 Router hostname. If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.
|
||||
[*] - i2cp.tcp.port 1-65535 7654 Router I2CP port. If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.
|
||||
|
||||
Default Description
|
||||
[C] - i2cp.accessList null Comma- or space-separated list of Base64 peer Hashes used for either access list or blocklist. As of release 0.7.13.
|
||||
[U] - i2cp.destination.sigType DSA_SHA1 Use the access list as a allowlist for incoming connections. The name or number of the signature type for a transient destination. As of release 0.9.12.
|
||||
[C] - i2cp.enableAccessList false Use the access list as a allowlist for incoming connections. As of release 0.7.13.
|
||||
[C] - i2cp.enableBlackList false Use the access list as a blocklist for incoming connections. As of release 0.7.13.
|
||||
[U] - i2p.streaming.answerPings true Whether to respond to incoming pings
|
||||
[U] - i2p.streaming.blocklist null Comma- or space-separated list of Base64 peer Hashes to be blocklisted for incoming connections to ALL destinations in the context. This option must be set in the context properties, NOT in the createManager() options argument. Note that setting this in the router context will not affect clients outside the router in a separate JVM and context. As of release 0.9.3.
|
||||
[U] - i2p.streaming.bufferSize 64K How much transmit data (in bytes) will be accepted that hasn't been written out yet.
|
||||
[U] - i2p.streaming.congestionAvoidanceGrowthRateFactor 1 When we're in congestion avoidance, we grow the window size at the rate of 1/(windowSize*factor). In standard TCP, window sizes are in bytes, while in I2P, window sizes are in messages. A higher number means slower growth.
|
||||
[U] - i2p.streaming.connectDelay -1 How long to wait after instantiating a new con before actually attempting to connect. If this is <= 0, connect immediately with no initial data. If greater than 0, wait until the output stream is flushed, the buffer fills, or that many milliseconds pass, and include any initial data with the SYN.
|
||||
[U] - i2p.streaming.connectTimeout 5*60*1000 How long to block on connect, in milliseconds. Negative means indefinitely. Default is 5 minutes.
|
||||
[U] - i2p.streaming.disableRejectLogging false Whether to disable warnings in the logs when an incoming connection is rejected due to connection limits. As of release 0.9.4.
|
||||
[U] - i2p.streaming.dsalist null Comma- or space-separated list of Base64 peer Hashes or host names to be contacted using an alternate DSA destination. Only applies if multisession is enabled and the primary session is non-DSA (generally for shared clients only). This option must be set in the context properties, NOT in the createManager() options argument. Note that setting this in the router context will not affect clients outside the router in a separate JVM and context. As of release 0.9.21.
|
||||
[U] - i2p.streaming.enforceProtocol true Whether to listen only for the streaming protocol. Setting to true will prohibit communication with Destinations earlier than release 0.7.1 (released March 2009). Set to true if running multiple protocols on this Destination. As of release 0.9.1. Default true as of release 0.9.36.
|
||||
[U] - i2p.streaming.inactivityAction 2 (send) (0=noop, 1=disconnect) What to do on an inactivity timeout - do nothing, disconnect, or send a duplicate ack.
|
||||
[U] - i2p.streaming.inactivityTimeout 90*1000 Idle time before sending a keepalive
|
||||
[U] - i2p.streaming.initialAckDelay 750 Delay before sending an ack
|
||||
[U] - i2p.streaming.initialResendDelay 1000 The initial value of the resend delay field in the packet header, times 1000. Not fully implemented; see below.
|
||||
[U] - i2p.streaming.initialRTO 9000 Initial timeout (if no sharing data available). As of release 0.9.8.
|
||||
[U] - i2p.streaming.initialRTT 8000 Initial round trip time estimate (if no sharing data available). Disabled as of release 0.9.8; uses actual RTT.
|
||||
[U] - i2p.streaming.initialWindowSize 6 (if no sharing data available) In standard TCP, window sizes are in bytes, while in I2P, window sizes are in messages.
|
||||
[U] - i2p.streaming.limitAction reset What action to take when an incoming connection exceeds limits. Valid values are: reset (reset the connection); drop (drop the connection); or http (send a hardcoded HTTP 429 response). Any other value is a custom response to be sent. backslash-r and backslash-n will be replaced with CR and LF. As of release 0.9.34.
|
||||
[U] - i2p.streaming.maxConcurrentStreams -1 (0 or negative value means unlimited) This is a total limit for incoming and outgoing combined.
|
||||
[U] - i2p.streaming.maxConnsPerMinute 0 Incoming connection limit (per peer; 0 means disabled) As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxConnsPerHour 0 (per peer; 0 means disabled) As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxConnsPerDay 0 (per peer; 0 means disabled) As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxMessageSize 1730 The MTU in bytes.
|
||||
[U] - i2p.streaming.maxResends 8 Maximum number of retransmissions before failure.
|
||||
[U] - i2p.streaming.maxTotalConnsPerMinute 0 Incoming connection limit (all peers; 0 means disabled) As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxTotalConnsPerHour 0 (all peers; 0 means disabled) Use with caution as exceeding this will disable a server for a long time. As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxTotalConnsPerDay 0 (all peers; 0 means disabled) Use with caution as exceeding this will disable a server for a long time. As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxWindowSize 128
|
||||
[U] - i2p.streaming.profile 1 (bulk) (2=interactive not supported) This doesn't currently do anything, but setting it to a value other than 1 will cause an error.
|
||||
[U] - i2p.streaming.readTimeout -1 How long to block on read, in milliseconds. Negative means indefinitely.
|
||||
[U] - i2p.streaming.slowStartGrowthRateFactor 1 When we're in slow start, we grow the window size at the rate of 1/(factor). In standard TCP, window sizes are in bytes, while in I2P, window sizes are in messages. A higher number means slower growth.
|
||||
[U] - i2p.streaming.tcbcache.rttDampening 0.75 Ref: RFC 2140. Floating point value. May be set only via context properties, not connection options. As of release 0.9.8.
|
||||
[U] - i2p.streaming.tcbcache.rttdevDampening 0.75 Ref: RFC 2140. Floating point value. May be set only via context properties, not connection options. As of release 0.9.8.
|
||||
[U] - i2p.streaming.tcbcache.wdwDampening 0.75 Ref: RFC 2140. Floating point value. May be set only via context properties, not connection options. As of release 0.9.8.
|
||||
[U] - i2p.streaming.writeTimeout -1 How long to block on write/flush, in milliseconds. Negative means indefinitely.
|
||||
|
||||
[C] - destination useful to consider adding to custom applications for client ocnfiguration</code></pre>
|
||||
<p>* : I’d like to have something like this setting internal to samcatd, but it might not always be relevant to pass it through to the real i2p router. Right now, I’m leaning toward a samcatd specific setting, but maybe just alter the behavior of this setting for use with samcatd instead? Probably just give samcatd it’s own thing.</p>
|
107
docs/config/CHECKLIST.md
Normal file
107
docs/config/CHECKLIST.md
Normal file
@@ -0,0 +1,107 @@
|
||||
I2CP/Tunnel Options Implementation Checklist
|
||||
============================================
|
||||
|
||||
This version of this document is valid for sam-forwarder. If you'd like to use
|
||||
it, the original is at [CHECKLIST.orig.md](CHECKLIST.orig.md).
|
||||
|
||||
key:
|
||||
|
||||
- \[U\] - Undone/Unknown
|
||||
- \[C\] - Confirmed Working
|
||||
- \[W\] - Work in progress
|
||||
- \[N\] - Not applicable/Won't be implemented without good reason.
|
||||
- \[*\] - See also
|
||||
|
||||
Version Recommended Allowable Default
|
||||
[U] - clientMessageTimeout 8*1000 - 120*1000 60*1000 The timeout (ms) for all sent messages. Unused. See the protocol specification for per-message settings.
|
||||
[N] - crypto.lowTagThreshold 0.9.2 1-128 30 Minimum number of ElGamal/AES Session Tags before we send more. Recommended: approximately tagsToSend * 2/3
|
||||
[N] - crypto.tagsToSend 0.9.2 1-128 40 Number of ElGamal/AES Session Tags to send at a time. For clients with relatively low bandwidth per-client-pair (IRC, some UDP apps), this may be set lower.
|
||||
[U] - explicitPeers null Comma-separated list of Base 64 Hashes of peers to build tunnels through; for debugging only
|
||||
[C] - i2cp.dontPublishLeaseSet true,false false Should generally be set to true for clients and false for servers
|
||||
[C] - i2cp.fastReceive 0.9.4 true,false false If true, the router just sends the MessagePayload instead of sending a MessageStatus and awaiting a ReceiveMessageBegin.
|
||||
[C] - i2cp.messageReliability BestEffort, None BestEffort Guaranteed is disabled; None implemented in 0.8.1; the streaming lib default is None as of 0.8.1, the client side default is None as of 0.9.4
|
||||
[U] - i2cp.password 0.8.2 string For authorization, if required by the router. If the client is running in the same JVM as a router, this option is not required. Warning - username and password are sent in the clear to the router, unless using SSL (i2cp.SSL=true). Authorization is only recommended when using SSL.
|
||||
[U] - i2cp.username 0.8.2 string
|
||||
[C] - inbound.allowZeroHop true,false true If incoming zero hop tunnel is allowed
|
||||
[C] - outbound.allowZeroHop true,false true If outgoing zero hop tunnel is allowed
|
||||
[C] - inbound.backupQuantity 0 to 3 No limit 0 Number of redundant fail-over for tunnels in
|
||||
[C] - outbound.backupQuantity 0 to 3 No limit 0 Number of redundant fail-over for tunnels out
|
||||
[U] - inbound.IPRestriction 0 to 4 0 to 4 2 Number of IP bytes to match to determine if two routers should not be in the same tunnel. 0 to disable.
|
||||
[U] - outbound.IPRestriction 0 to 4 0 to 4 2 Number of IP bytes to match to determine if two routers should not be in the same tunnel. 0 to disable.
|
||||
[C] - inbound.length 0 to 3 0 to 7 3 Length of tunnels in
|
||||
[C] - outbound.length 0 to 3 0 to 7 3 Length of tunnels out
|
||||
[C] - inbound.lengthVariance -1 to 2 -7 to 7 0 Random amount to add or subtract to the length of tunnels in. A positive number x means add a random amount from 0 to x inclusive. A negative number -x means add a random amount from -x to x inclusive. The router will limit the total length of the tunnel to 0 to 7 inclusive. The default variance was 1 prior to release 0.7.6.
|
||||
[C] - outbound.lengthVariance -1 to 2 -7 to 7 0 Random amount to add or subtract to the length of tunnels out. A positive number x means add a random amount from 0 to x inclusive. A negative number -x means add a random amount from -x to x inclusive. The router will limit the total length of the tunnel to 0 to 7 inclusive. The default variance was 1 prior to release 0.7.6.
|
||||
[U] - inbound.nickname string Name of tunnel - generally used in routerconsole, which will use the first few characters of the Base64 hash of the destination by default.
|
||||
[U] - outbound.nickname string Name of tunnel - generally ignored unless inbound.nickname is unset.
|
||||
[U] - outbound.priority 0.9.4 -25 to 25 -25 to 25 0 Priority adjustment for outbound messages. Higher is higher priority.
|
||||
[C] - inbound.quantity 1 to 3 1 to 16 2 Number of tunnels in. Limit was increased from 6 to 16 in release 0.9; however, numbers higher than 6 are incompatible with older releases.
|
||||
[C] - outbound.quantity 1 to 3 No limit 2 Number of tunnels out
|
||||
[U] - inbound.randomKey 0.9.17 Base 64 encoding of 32 random bytes Used for consistent peer ordering across restarts.
|
||||
[U] - outbound.randomKey 0.9.17 Base 64 encoding of 32 random bytes Used for consistent peer ordering across restarts.
|
||||
[*] - inbound.* Any other options prefixed with "inbound." are stored in the "unknown options" properties of the inbound tunnel pool's settings.
|
||||
[*] - outbound.* Any other options prefixed with "outbound." are stored in the "unknown options" properties of the outbound tunnel pool's settings.
|
||||
[U] - shouldBundleReplyInfo 0.9.2 true,false true Set to false to disable ever bundling a reply LeaseSet. For clients that do not publish their LeaseSet, this option must be true for any reply to be possible. "true" is also recommended for multihomed servers with long connection times. Setting to "false" may save significant outbound bandwidth, especially if the client is configured with a large number of inbound tunnels (Leases). If replies are still required, this may shift the bandwidth burden to the far-end client and the floodfill. There are several cases where "false" may be appropriate: Unidirectional communication, no reply required LeaseSet is published and higher reply latency is acceptable LeaseSet is published, client is a "server", all connections are inbound so the connecting far-end destination obviously has the leaseset already. Connections are either short, or it is acceptable for latency on a long-lived connection to temporarily increase while the other end re-fetches the LeaseSet after expiration. HTTP servers may fit these requirements.
|
||||
[C] - i2cp.closeIdleTime 0.7.1 1800000 300000 minimum (ms) Idle time required (default 30 minutes)
|
||||
[C] - i2cp.closeOnIdle 0.7.1 true,false false Close I2P session when idle
|
||||
[C] - i2cp.encryptLeaseSet 0.7.1 true,false false Encrypt the lease
|
||||
[C] - i2cp.fastReceive 0.9.4 true,false true If true, the router just sends the MessagePayload instead of sending a MessageStatus and awaiting a ReceiveMessageBegin.
|
||||
[C] - i2cp.gzip 0.6.5 true,false true Gzip outbound data
|
||||
[C] - i2cp.leaseSetKey 0.7.1 For encrypted leasesets. Base 64 SessionKey (44 characters)
|
||||
[C] - i2cp.leaseSetPrivateKey 0.9.18 Base 64 private key for encryption. Optionally preceded by the key type and ':'. Only "ELGAMAL_2048:" is supported, which is the default. I2CP will generate the public key from the private key. Use for persistent leaseset keys across restarts.
|
||||
[C] - i2cp.leaseSetSigningPrivateKey 0.9.18 Base 64 private key for signatures. Optionally preceded by the key type and ':'. DSA_SHA1 is the default. Key type must match the signature type in the destination. I2CP will generate the public key from the private key. Use for persistent leaseset keys across restarts.
|
||||
[C] - i2cp.reduceIdleTime 0.7.1 1200000 300000 minimum (ms) Idle time required (default 20 minutes, minimum 5 minutes)
|
||||
[C] - i2cp.reduceOnIdle 0.7.1 true,false false Reduce tunnel quantity when idle
|
||||
[C] - i2cp.reduceQuantity 0.7.1 1 1 to 5 1 Tunnel quantity when reduced (applies to both inbound and outbound)
|
||||
[*] - i2cp.SSL 0.8.3 true,false false Connect to the router using SSL. If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.
|
||||
[*] - i2cp.tcp.host 127.0.0.1 Router hostname. If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.
|
||||
[*] - i2cp.tcp.port 1-65535 7654 Router I2CP port. If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.
|
||||
|
||||
Default Description
|
||||
[C] - i2cp.accessList null Comma- or space-separated list of Base64 peer Hashes used for either access list or blocklist. As of release 0.7.13.
|
||||
[U] - i2cp.destination.sigType DSA_SHA1 Use the access list as a allowlist for incoming connections. The name or number of the signature type for a transient destination. As of release 0.9.12.
|
||||
[C] - i2cp.enableAccessList false Use the access list as a allowlist for incoming connections. As of release 0.7.13.
|
||||
[C] - i2cp.enableBlackList false Use the access list as a blocklist for incoming connections. As of release 0.7.13.
|
||||
[U] - i2p.streaming.answerPings true Whether to respond to incoming pings
|
||||
[U] - i2p.streaming.blocklist null Comma- or space-separated list of Base64 peer Hashes to be blocklisted for incoming connections to ALL destinations in the context. This option must be set in the context properties, NOT in the createManager() options argument. Note that setting this in the router context will not affect clients outside the router in a separate JVM and context. As of release 0.9.3.
|
||||
[U] - i2p.streaming.bufferSize 64K How much transmit data (in bytes) will be accepted that hasn't been written out yet.
|
||||
[U] - i2p.streaming.congestionAvoidanceGrowthRateFactor 1 When we're in congestion avoidance, we grow the window size at the rate of 1/(windowSize*factor). In standard TCP, window sizes are in bytes, while in I2P, window sizes are in messages. A higher number means slower growth.
|
||||
[U] - i2p.streaming.connectDelay -1 How long to wait after instantiating a new con before actually attempting to connect. If this is <= 0, connect immediately with no initial data. If greater than 0, wait until the output stream is flushed, the buffer fills, or that many milliseconds pass, and include any initial data with the SYN.
|
||||
[U] - i2p.streaming.connectTimeout 5*60*1000 How long to block on connect, in milliseconds. Negative means indefinitely. Default is 5 minutes.
|
||||
[U] - i2p.streaming.disableRejectLogging false Whether to disable warnings in the logs when an incoming connection is rejected due to connection limits. As of release 0.9.4.
|
||||
[U] - i2p.streaming.dsalist null Comma- or space-separated list of Base64 peer Hashes or host names to be contacted using an alternate DSA destination. Only applies if multisession is enabled and the primary session is non-DSA (generally for shared clients only). This option must be set in the context properties, NOT in the createManager() options argument. Note that setting this in the router context will not affect clients outside the router in a separate JVM and context. As of release 0.9.21.
|
||||
[U] - i2p.streaming.enforceProtocol true Whether to listen only for the streaming protocol. Setting to true will prohibit communication with Destinations earlier than release 0.7.1 (released March 2009). Set to true if running multiple protocols on this Destination. As of release 0.9.1. Default true as of release 0.9.36.
|
||||
[U] - i2p.streaming.inactivityAction 2 (send) (0=noop, 1=disconnect) What to do on an inactivity timeout - do nothing, disconnect, or send a duplicate ack.
|
||||
[U] - i2p.streaming.inactivityTimeout 90*1000 Idle time before sending a keepalive
|
||||
[U] - i2p.streaming.initialAckDelay 750 Delay before sending an ack
|
||||
[U] - i2p.streaming.initialResendDelay 1000 The initial value of the resend delay field in the packet header, times 1000. Not fully implemented; see below.
|
||||
[U] - i2p.streaming.initialRTO 9000 Initial timeout (if no sharing data available). As of release 0.9.8.
|
||||
[U] - i2p.streaming.initialRTT 8000 Initial round trip time estimate (if no sharing data available). Disabled as of release 0.9.8; uses actual RTT.
|
||||
[U] - i2p.streaming.initialWindowSize 6 (if no sharing data available) In standard TCP, window sizes are in bytes, while in I2P, window sizes are in messages.
|
||||
[U] - i2p.streaming.limitAction reset What action to take when an incoming connection exceeds limits. Valid values are: reset (reset the connection); drop (drop the connection); or http (send a hardcoded HTTP 429 response). Any other value is a custom response to be sent. backslash-r and backslash-n will be replaced with CR and LF. As of release 0.9.34.
|
||||
[U] - i2p.streaming.maxConcurrentStreams -1 (0 or negative value means unlimited) This is a total limit for incoming and outgoing combined.
|
||||
[U] - i2p.streaming.maxConnsPerMinute 0 Incoming connection limit (per peer; 0 means disabled) As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxConnsPerHour 0 (per peer; 0 means disabled) As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxConnsPerDay 0 (per peer; 0 means disabled) As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxMessageSize 1730 The MTU in bytes.
|
||||
[U] - i2p.streaming.maxResends 8 Maximum number of retransmissions before failure.
|
||||
[U] - i2p.streaming.maxTotalConnsPerMinute 0 Incoming connection limit (all peers; 0 means disabled) As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxTotalConnsPerHour 0 (all peers; 0 means disabled) Use with caution as exceeding this will disable a server for a long time. As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxTotalConnsPerDay 0 (all peers; 0 means disabled) Use with caution as exceeding this will disable a server for a long time. As of release 0.7.14.
|
||||
[U] - i2p.streaming.maxWindowSize 128
|
||||
[U] - i2p.streaming.profile 1 (bulk) (2=interactive not supported) This doesn't currently do anything, but setting it to a value other than 1 will cause an error.
|
||||
[U] - i2p.streaming.readTimeout -1 How long to block on read, in milliseconds. Negative means indefinitely.
|
||||
[U] - i2p.streaming.slowStartGrowthRateFactor 1 When we're in slow start, we grow the window size at the rate of 1/(factor). In standard TCP, window sizes are in bytes, while in I2P, window sizes are in messages. A higher number means slower growth.
|
||||
[U] - i2p.streaming.tcbcache.rttDampening 0.75 Ref: RFC 2140. Floating point value. May be set only via context properties, not connection options. As of release 0.9.8.
|
||||
[U] - i2p.streaming.tcbcache.rttdevDampening 0.75 Ref: RFC 2140. Floating point value. May be set only via context properties, not connection options. As of release 0.9.8.
|
||||
[U] - i2p.streaming.tcbcache.wdwDampening 0.75 Ref: RFC 2140. Floating point value. May be set only via context properties, not connection options. As of release 0.9.8.
|
||||
[U] - i2p.streaming.writeTimeout -1 How long to block on write/flush, in milliseconds. Negative means indefinitely.
|
||||
|
||||
[C] - destination useful to consider adding to custom applications for client ocnfiguration
|
||||
|
||||
\* : I'd like to have something like this setting internal to samcatd, but it
|
||||
might not always be relevant to pass it through to the real i2p router. Right
|
||||
now, I'm leaning toward a samcatd specific setting, but maybe just alter the
|
||||
behavior of this setting for use with samcatd instead? Probably just give
|
||||
samcatd it's own thing.
|
||||
|
42
docs/embedding.html
Normal file
42
docs/embedding.html
Normal file
@@ -0,0 +1,42 @@
|
||||
<h1 id="embedding-i2p-support-in-your-go-application-with-samforwarder">Embedding i2p support in your Go application with samforwarder</h1>
|
||||
<p>One neat thing you can do with samforwarder is make eepWeb(?) services configure themselves automatically by adding it to an existing Go application. To help with this process, the samforwarder/config/ file has a bunch of helper functions and a class for parsing configuration files directly. You can import it, add a few flags(or however you configure your service) and fire off the forwarder as a goroutne, all you have to do is configure it to forward the port used by your service. This makes it extremely easy to do, but it should only be used in this way for applications that would already be safe to host as services in i2p or other overlay networks. In particular, it should only be used for applications that don’t require extensive login information and do not leak information at the application layer.</p>
|
||||
<p>So without further ado, a blatant copy-paste of information that shouldn’t have been in the README.md.</p>
|
||||
<h2 id="static-eepsite-in-like-no-seconds">Static eepsite in like no seconds</h2>
|
||||
<p>Using this port forwarder, it’s possible to create an instant eepsite from a folder full of html files(and the resources they call upon). Probably obviously to everybody reading this right now, but maybe not obviously to everyone reading this forever. An example of an application that works this way is available <a href="https://github.com/eyedeekay/eephttpd">here at my eephttpd repo</a>.</p>
|
||||
<h2 id="quick-and-dirty-i2p-enabled-golang-web-applications">Quick-And-Dirty i2p-enabled golang web applications</h2>
|
||||
<p>Normal web applications can easily add the ability to serve itself over i2p by importing and configuring this forwarding doodad. Wherever it takes the argument for the web server’s listening host and/or port, pass that same host and/or port to a new instance of the “SAMForwarder” and then run the “Serve” function of the SAMForwarder as a goroutine. This simply forwards the running service to the i2p network, it doesn’t do any filtering, and if your application establishes out-of-band connections, those may escape. Also, if your application is listening on all addresses, it will be visible from the local network.</p>
|
||||
<p>Here’s a simple example with a simple static file server:</p>
|
||||
<div class="sourceCode" id="cb1"><pre class="sourceCode diff"><code class="sourceCode diff"><a class="sourceLine" id="cb1-1" title="1">package main package main</a>
|
||||
<a class="sourceLine" id="cb1-2" title="2"></a>
|
||||
<a class="sourceLine" id="cb1-3" title="3">import ( import (</a>
|
||||
<a class="sourceLine" id="cb1-4" title="4"> "flag" "flag"</a>
|
||||
<a class="sourceLine" id="cb1-5" title="5"> "log" "log"</a>
|
||||
<a class="sourceLine" id="cb1-6" title="6"> "net/http" "net/http"</a>
|
||||
<a class="sourceLine" id="cb1-7" title="7">) )</a>
|
||||
<a class="sourceLine" id="cb1-8" title="8"></a>
|
||||
<a class="sourceLine" id="cb1-9" title="9"> > import "github.com/eyedeekay/sam-forwarder"</a>
|
||||
<a class="sourceLine" id="cb1-10" title="10"> ></a>
|
||||
<a class="sourceLine" id="cb1-11" title="11">func main() { func main() {</a>
|
||||
<a class="sourceLine" id="cb1-12" title="12"> port := flag.String("p", "8100", "port to serve on") port := flag.String("p", "8100", "port to serve on")</a>
|
||||
<a class="sourceLine" id="cb1-13" title="13"> directory := flag.String("d", ".", "the directory of static file to host") directory := flag.String("d", ".", "the directory of static file to host")</a>
|
||||
<a class="sourceLine" id="cb1-14" title="14"> flag.Parse() flag.Parse()</a>
|
||||
<a class="sourceLine" id="cb1-15" title="15"> ></a>
|
||||
<a class="sourceLine" id="cb1-16" title="16"> > forwarder, err := samforwarder.NewSAMForwarderFromOptions(</a>
|
||||
<a class="sourceLine" id="cb1-17" title="17"> > samforwarder.SetHost("127.0.0.1"),</a>
|
||||
<a class="sourceLine" id="cb1-18" title="18"> > samforwarder.SetPort(*port),</a>
|
||||
<a class="sourceLine" id="cb1-19" title="19"> > samforwarder.SetSAMHost("127.0.0.1"),</a>
|
||||
<a class="sourceLine" id="cb1-20" title="20"> > samforwarder.SetSAMPort("7656"),</a>
|
||||
<a class="sourceLine" id="cb1-21" title="21"> > samforwarder.SetName("staticfiles"),</a>
|
||||
<a class="sourceLine" id="cb1-22" title="22"> > )</a>
|
||||
<a class="sourceLine" id="cb1-23" title="23"> > if err != nil {</a>
|
||||
<a class="sourceLine" id="cb1-24" title="24"> > log.Fatal(err.Error())</a>
|
||||
<a class="sourceLine" id="cb1-25" title="25"> > }</a>
|
||||
<a class="sourceLine" id="cb1-26" title="26"> > go forwarder.Serve()</a>
|
||||
<a class="sourceLine" id="cb1-27" title="27"></a>
|
||||
<a class="sourceLine" id="cb1-28" title="28"> http.Handle("/", http.FileServer(http.Dir(*directory))) http.Handle("/", http.FileServer(http.Dir(*directory)))</a>
|
||||
<a class="sourceLine" id="cb1-29" title="29"></a>
|
||||
<a class="sourceLine" id="cb1-30" title="30"> log.Printf("Serving %s on HTTP port: %s\n", *directory, *port) log.Printf("Serving %s on HTTP port: %s\n", *directory, *port)</a>
|
||||
<a class="sourceLine" id="cb1-31" title="31"> log.Fatal(http.ListenAndServe("127.0.0.1:"+*port, nil)) log.Fatal(http.ListenAndServe("127.0.0.1:"+*port, nil))</a>
|
||||
<a class="sourceLine" id="cb1-32" title="32">} }</a></code></pre></div>
|
||||
<p><a href="https://gist.github.com/paulmach/7271283">This tiny file server taken from here and used for this example</a></p>
|
||||
<h2 id="integrating-your-go-web-application-with-i2p-using-sam-forwarder">Integrating your Go web application with i2p using sam-forwarder</h2>
|
54
docs/index.html
Normal file
54
docs/index.html
Normal file
@@ -0,0 +1,54 @@
|
||||
<h1 id="sam-forwarder">sam-forwarder</h1>
|
||||
<p>Forward a local port to i2p over the SAM API, or proxy a destination to a port on the local host. This is a work-in-progress, but the basic functionality is, there and it’s already pretty useful. Everything TCP works, but UDP forwarding has much less real use than TCP. Turns out UDP was less broken than I thought though.</p>
|
||||
<p>Since it seems to be doing UDP now, if you’d like to donate to further development there are some wallet addresses at the bottom of this readme for now.</p>
|
||||
<h2 id="getting">getting</h2>
|
||||
<pre><code> go get -u github.com/eyedeekay/sam-forwarder/samcatd</code></pre>
|
||||
<h2 id="building">building</h2>
|
||||
<p>Just:</p>
|
||||
<pre><code> make deps build</code></pre>
|
||||
<p>and it will be in the folder ./bin/</p>
|
||||
<p><a href="https://travis-ci.org/eyedeekay/sam-forwarder"><img src="https://travis-ci.org/eyedeekay/sam-forwarder.svg?branch=master" alt="Build Status" /></a></p>
|
||||
<h2 id="usage">Usage:</h2>
|
||||
<p>There are a number of ways to use sam-forwarder:</p>
|
||||
<h3 id="usageconfiguration-as-an-applicationstart-here-for-samcatd"><a href="docs/USAGE.md">usage/configuration</a> as an application(Start here for samcatd)</h3>
|
||||
<h3 id="embedding-in-other-applications"><a href="docs/EMBEDDING.md">embedding</a> in other applications</h3>
|
||||
<h3 id="encapsulate-configuration-for-i2p-enabled-packages"><a href="docs/PACKAGECONF.md">encapsulate</a> configuration for i2p-enabled packages</h3>
|
||||
<h3 id="implement-the-interface-for-fine-grained-control-over-sam-connections"><a href="interface/README.md">implement</a> the interface for fine-grained control over SAM connections</h3>
|
||||
<h2 id="binaries">binaries</h2>
|
||||
<p>Two binaries are produced by this repo. The first, ephsite, is only capable of running one tunnel at a time and doesn’t have VPN support. I’m only updating it to make sure that the embeddable interface in existing applications doesn’t change. It will go away and be replaced with a wrapper to translate it to ‘samcatd -s’ commands whenever I complete <a href="docs/CHECKLIST.md" class="uri">docs/CHECKLIST.md</a>.</p>
|
||||
<p>The second, samcatd, is more advanced. It can start multiple tunnels with their own settings, or be used to start tunnels on the fly like ephsite by passing the -s option. Eventually I’m probably just going to use this to configure all of my tunnels.</p>
|
||||
<h1 id="current-limitations">Current limitations:</h1>
|
||||
<p>I need to document it better. <a href="docs/USAGE.md">Besides fixing up the comments, this should help for now.</a>. I also need to control output verbosity better.</p>
|
||||
<p>I need samcatd to accept a configuration folder identical to /etc/i2pd/tunnels.conf.d, since part of the point of this is to be compatible with i2pd’s tunnels configuration. Once this is done, I’ll resume turning it into a .deb package.</p>
|
||||
<p>It doesn’t encrypt the .i2pkeys file by default, so if someone can steal them, then they can use them to construct tunnels to impersonate you. Experimental support for encrypted saves has been added. The idea is that only the person with the key will be able to decrypt and start the tunnels. It is up to the user to determine how to go about managing these keys. Right now this system is pretty bad. I’ll be addressing that soon too.</p>
|
||||
<p>TCP and UDP are both working now. Additional functionality might be added by adding other kinds of protocols overtop the TCP and UDP tunnels as a primitive. There’s a very basic UDP-based VPN available in samcatd by configuration-file only for now. Also it requires root. Probably need to split the VPN part into it’s own application. The package will need to give the application CAP_NET_BIND_SERVICE or something. This might work:</p>
|
||||
<pre><code> sudo setcap cap_net_bind_service=epi ./bin/samcatd</code></pre>
|
||||
<p>But I need to learn more about capabilities before I make that part of the thing.</p>
|
||||
<p>Some kind of reverse-proxy or filter is also an obvious choice.</p>
|
||||
<p>I’ve only enabled the use of a subset of the i2cp and tunnel configuration options, the ones I use the most and for no other real reason assume other people use the most. They’re pretty easy to add, it’s just boring. <em>If you</em> <em>want an i2cp or tunnel option that isn’t available, bring it to my attention</em> <em>please.</em> I’m pretty responsive when people actually contact me, it’ll probably be added within 24 hours. I intend to have configuration options for all relevant i2cp and tunnel options, which I’m keeping track of <a href="config/CHECKLIST.md">here</a>.</p>
|
||||
<p>I should probably have some options that are available in other general network utilities. I’ve started to do this with samcatd.</p>
|
||||
<p>I want it to be able to save ini files based on the settings used for a running forwarder. Should be easy, I just need to decide how I want to do it. Also to focus a bit more. I’ve got more of a plan here now. tunconf has the loaded ini file inside it, and variables to track the state of the config options while running, and they can be switched to save options that might be changed via some interface or another.</p>
|
||||
<p>Example tools built using this are being broken off into their own repos. Use the other repos where appropriate, so I can leave the examples un-messed with.</p>
|
||||
<p>It would be really awesome if I could make this run on Android. So I’ll make that happen eventually. I started a daemon for managing multiple tunnels and I figure I give it a web interface to configure stuff with. I’ll probably put that in a different repo though. This is looking a little cluttered.</p>
|
||||
<p>TLS configuration is experimental.</p>
|
||||
<p>I’ve made it self-supervising, but I need to make better use of contexts.</p>
|
||||
<h2 id="stuff-thats-using-it">Stuff that’s using it:</h2>
|
||||
<p>Mostly mine, but this is all Free-as-in-Freedom for anyone to use:</p>
|
||||
<ul>
|
||||
<li><a href="https://github.com/eyedeekay/eephttpd">eephttpd</a></li>
|
||||
<li><a href="https://github.com/eyedeekay/wikigopher">my fork of wikigopher</a></li>
|
||||
<li><a href="https://github.com/s-gv/orangeforum">orangeforum</a></li>
|
||||
</ul>
|
||||
<h2 id="donate">Donate</h2>
|
||||
<h3 id="monero-wallet-address">Monero Wallet Address</h3>
|
||||
<p>XMR:43V6cTZrUfAb9JD6Dmn3vjdT9XxLbiE27D1kaoehb359ACaHs8191mR4RsJH7hGjRTiAoSwFQAVdsCBToXXPAqTMDdP2bZB</p>
|
||||
<h3 id="bitcoin-wallet-address">Bitcoin Wallet Address</h3>
|
||||
<p>BTC:159M8MEUwhTzE9RXmcZxtigKaEjgfwRbHt</p>
|
||||
<h2 id="index">Index</h2>
|
||||
<ul>
|
||||
<li><a href="index.html">readme</a></li>
|
||||
<li><a href="usage.html">usage</a></li>
|
||||
<li><a href="packageconf.html">configuration</a></li>
|
||||
<li><a href="embedding.html">embedding</a></li>
|
||||
<li><a href="interface.htnl">interface</a></li>
|
||||
</ul>
|
2
docs/interface.html
Normal file
2
docs/interface.html
Normal file
@@ -0,0 +1,2 @@
|
||||
<h1 id="implementing-the-sam-forwarder-interface">Implementing the sam-forwarder interface</h1>
|
||||
<p>The sam-forwrder interface(used int the Go sense of the word interface) is used to create custom types of tunnels.</p>
|
1
docs/packageconf.html
Normal file
1
docs/packageconf.html
Normal file
@@ -0,0 +1 @@
|
||||
<h1 id="encapsulating-and-packaging-application-configuration-with-samcatd">Encapsulating and Packaging Application Configuration with samcatd</h1>
|
194
docs/usage.html
Normal file
194
docs/usage.html
Normal file
@@ -0,0 +1,194 @@
|
||||
<h1 id="samcatd---router-independent-tunnel-management-for-i2p">samcatd - Router-independent tunnel management for i2p</h1>
|
||||
<p>samcatd is a daemon which runs a group of forwarding proxies to provide services over i2p independent of the router. It also serves as a generalized i2p networking utility for power-users. It’s intended to be a Swiss-army knife for the SAM API.</p>
|
||||
<h2 id="usage">usage:</h2>
|
||||
<pre><code>flag needs an argument: -h
|
||||
Usage of ./bin/samcatd:
|
||||
-a string
|
||||
Type of access list to use, can be "allowlist" "blocklist" or "none". (default "none")
|
||||
-c Client proxy mode(true or false)
|
||||
-conv string
|
||||
Display the base32 and base64 values of a specified .i2pkeys file
|
||||
-cr string
|
||||
Encrypt/decrypt the key files with a passfile
|
||||
-css string
|
||||
custom CSS for web interface (default "css/styles.css")
|
||||
-ct int
|
||||
Reduce tunnel quantity after X (milliseconds) (default 600000)
|
||||
-d string
|
||||
Directory to save tunnel configuration file in.
|
||||
-de string
|
||||
Destination to connect client's to by default.
|
||||
-f string
|
||||
Use an ini file for configuration(config file options override passed arguments for now.) (default "none")
|
||||
-h string
|
||||
Target host(Host of service to forward to i2p) (default "127.0.0.1")
|
||||
-i string
|
||||
Destination for client tunnels. Ignored for service tunnels. (default "none")
|
||||
-ib int
|
||||
Set inbound tunnel backup quantity(0 to 5) (default 2)
|
||||
-ih
|
||||
Inject X-I2P-DEST headers
|
||||
-il int
|
||||
Set inbound tunnel length(0 to 7) (default 3)
|
||||
-iq int
|
||||
Set inbound tunnel quantity(0 to 15) (default 6)
|
||||
-iv int
|
||||
Set inbound tunnel length variance(-7 to 7)
|
||||
-js string
|
||||
custom JS for web interface (default "js/scripts.js")
|
||||
-k string
|
||||
key for encrypted leaseset (default "none")
|
||||
-l Use an encrypted leaseset(true or false) (default true)
|
||||
-littleboss string
|
||||
instruct the littleboss:
|
||||
|
||||
start: start and manage this process using service name "service-name"
|
||||
stop: signal the littleboss to shutdown the process
|
||||
status: print statistics about the running littleboss
|
||||
reload: restart the managed process using the executed binary
|
||||
bypass: disable littleboss, run the program directly (default "bypass")
|
||||
-n string
|
||||
Tunnel name, this must be unique but can be anything. (default "forwarder")
|
||||
-ob int
|
||||
Set outbound tunnel backup quantity(0 to 5) (default 2)
|
||||
-ol int
|
||||
Set outbound tunnel length(0 to 7) (default 3)
|
||||
-oq int
|
||||
Set outbound tunnel quantity(0 to 15) (default 6)
|
||||
-ov int
|
||||
Set outbound tunnel length variance(-7 to 7)
|
||||
-p string
|
||||
Target port(Port of service to forward to i2p) (default "8081")
|
||||
-pk string
|
||||
private key for encrypted leaseset (default "none")
|
||||
-psk string
|
||||
private signing key for encrypted leaseset (default "none")
|
||||
-r Reduce tunnel quantity when idle(true or false)
|
||||
-rq int
|
||||
Reduce idle tunnel quantity to X (0 to 5) (default 3)
|
||||
-rt int
|
||||
Reduce tunnel quantity after X (milliseconds) (default 600000)
|
||||
-s Start a tunnel with the passed parameters(Otherwise, they will be treated as default values.)
|
||||
-sh string
|
||||
SAM host (default "127.0.0.1")
|
||||
-sp string
|
||||
SAM port (default "7656")
|
||||
-st string
|
||||
Signature type
|
||||
-t Use saved file and persist tunnel(If false, tunnel will not persist after program is stopped.
|
||||
-tls string
|
||||
(Currently inoperative. Target TLS port(HTTPS Port of service to forward to i2p)
|
||||
-u UDP mode(true or false)
|
||||
-w Start web administration interface
|
||||
-wp string
|
||||
Web port (default "7957")
|
||||
-x Close tunnel idle(true or false)
|
||||
-z Uze gzip(true or false)
|
||||
-zi
|
||||
Allow zero-hop, non-anonymous tunnels in(true or false)
|
||||
-zo
|
||||
Allow zero-hop, non-anonymous tunnels out(true or false)</code></pre>
|
||||
<h1 id="managing-samcatd-save-encryption-keys">managing samcatd save-encryption keys</h1>
|
||||
<p>In order to keep from saving the .i2pkeys files in plaintext format, samcatd can optionally generate a key and encrypt the .i2pkeys files securely. Of course, to fully benefit from this arrangement, you need to move those keys away from the machine where the tunnel keys(the .i2pkeys file) are located, or protect them in some other way(sandboxing, etc). If you want to use encrypted .i2pkeys files, you can specify a key file to use with the -cr option on the terminal or with keyfile option in the .ini file.</p>
|
||||
<h1 id="example-config---valid-for-both-ephsite-and-samcat">example config - valid for both ephsite and samcat</h1>
|
||||
<p>Options are still being added, pretty much as fast as I can put them in. For up-to-the-minute options, see <a href="config/CHECKLIST.md">the checklist</a></p>
|
||||
<p>(<strong>ephsite</strong> will only use top-level options, but they can be labeled or unlabeled)</p>
|
||||
<p>(<strong>samcatd</strong> treats the first set of options it sees as the default, and does not start tunnels based on unlabeled options unless passed the -s flag.)</p>
|
||||
<div class="sourceCode" id="cb2"><pre class="sourceCode ini"><code class="sourceCode ini"><a class="sourceLine" id="cb2-1" title="1"></a>
|
||||
<a class="sourceLine" id="cb2-2" title="2"><span class="co">## Defaults, these are only invoked with the -start option or if labeled tunnels</span></a>
|
||||
<a class="sourceLine" id="cb2-3" title="3"><span class="co">## are not present(samcatd instructions). **THESE** are the correct config files</span></a>
|
||||
<a class="sourceLine" id="cb2-4" title="4"><span class="co">## to use as defaults, and not the ones in ../sam-forwarder/tunnels.ini, which</span></a>
|
||||
<a class="sourceLine" id="cb2-5" title="5"><span class="co">## are used for testing settings availability only.</span></a>
|
||||
<a class="sourceLine" id="cb2-6" title="6"></a>
|
||||
<a class="sourceLine" id="cb2-7" title="7"><span class="dt">inbound.length </span><span class="ot">=</span><span class="st"> </span><span class="dv">3</span></a>
|
||||
<a class="sourceLine" id="cb2-8" title="8"><span class="dt">outbound.length </span><span class="ot">=</span><span class="st"> </span><span class="dv">3</span></a>
|
||||
<a class="sourceLine" id="cb2-9" title="9"><span class="dt">inbound.lengthVariance </span><span class="ot">=</span><span class="st"> </span><span class="dv">0</span></a>
|
||||
<a class="sourceLine" id="cb2-10" title="10"><span class="dt">outbound.lengthVariance </span><span class="ot">=</span><span class="st"> </span><span class="dv">0</span></a>
|
||||
<a class="sourceLine" id="cb2-11" title="11"><span class="dt">inbound.backupQuantity </span><span class="ot">=</span><span class="st"> </span><span class="dv">3</span></a>
|
||||
<a class="sourceLine" id="cb2-12" title="12"><span class="dt">outbound.backupQuantity </span><span class="ot">=</span><span class="st"> </span><span class="dv">3</span></a>
|
||||
<a class="sourceLine" id="cb2-13" title="13"><span class="dt">inbound.quantity </span><span class="ot">=</span><span class="st"> </span><span class="dv">5</span></a>
|
||||
<a class="sourceLine" id="cb2-14" title="14"><span class="dt">outbound.quantity </span><span class="ot">=</span><span class="st"> </span><span class="dv">5</span></a>
|
||||
<a class="sourceLine" id="cb2-15" title="15"><span class="dt">inbound.allowZeroHop </span><span class="ot">=</span><span class="st"> </span><span class="kw">false</span></a>
|
||||
<a class="sourceLine" id="cb2-16" title="16"><span class="dt">outbound.allowZeroHop </span><span class="ot">=</span><span class="st"> </span><span class="kw">false</span></a>
|
||||
<a class="sourceLine" id="cb2-17" title="17"><span class="dt">i2cp.encryptLeaseSet </span><span class="ot">=</span><span class="st"> </span><span class="kw">false</span></a>
|
||||
<a class="sourceLine" id="cb2-18" title="18"><span class="dt">gzip </span><span class="ot">=</span><span class="st"> </span><span class="kw">true</span></a>
|
||||
<a class="sourceLine" id="cb2-19" title="19"><span class="dt">i2cp.reduceOnIdle </span><span class="ot">=</span><span class="st"> </span><span class="kw">true</span></a>
|
||||
<a class="sourceLine" id="cb2-20" title="20"><span class="dt">i2cp.reduceIdleTime </span><span class="ot">=</span><span class="st"> </span><span class="dv">3000000</span></a>
|
||||
<a class="sourceLine" id="cb2-21" title="21"><span class="dt">i2cp.reduceQuantity </span><span class="ot">=</span><span class="st"> </span><span class="dv">2</span></a>
|
||||
<a class="sourceLine" id="cb2-22" title="22"><span class="dt">i2cp.enableWhiteList </span><span class="ot">=</span><span class="st"> </span><span class="kw">false</span></a>
|
||||
<a class="sourceLine" id="cb2-23" title="23"><span class="dt">i2cp.enableBlackList </span><span class="ot">=</span><span class="st"> </span><span class="kw">false</span></a>
|
||||
<a class="sourceLine" id="cb2-24" title="24"><span class="dt">keyfile </span><span class="ot">=</span><span class="st"> "/usr/share/samcatd/samcatd"</span></a>
|
||||
<a class="sourceLine" id="cb2-25" title="25"></a>
|
||||
<a class="sourceLine" id="cb2-26" title="26"><span class="co">#[sam-forwarder-tcp-server]</span></a>
|
||||
<a class="sourceLine" id="cb2-27" title="27"><span class="co">#type = server</span></a>
|
||||
<a class="sourceLine" id="cb2-28" title="28"><span class="co">#host = 127.0.0.1</span></a>
|
||||
<a class="sourceLine" id="cb2-29" title="29"><span class="co">#port = 8081</span></a>
|
||||
<a class="sourceLine" id="cb2-30" title="30"><span class="co">#inbound.length = 3</span></a>
|
||||
<a class="sourceLine" id="cb2-31" title="31"><span class="co">#outbound.length = 3</span></a>
|
||||
<a class="sourceLine" id="cb2-32" title="32"><span class="co">#keys = forwarder</span></a>
|
||||
<a class="sourceLine" id="cb2-33" title="33"></a>
|
||||
<a class="sourceLine" id="cb2-34" title="34"><span class="kw">[sam-forwarder-tcp-client]</span></a>
|
||||
<a class="sourceLine" id="cb2-35" title="35"><span class="dt">type </span><span class="ot">=</span><span class="st"> client</span></a>
|
||||
<a class="sourceLine" id="cb2-36" title="36"><span class="dt">host </span><span class="ot">=</span><span class="st"> </span><span class="dv">127</span><span class="st">.</span><span class="dv">0</span><span class="st">.</span><span class="fl">0.1</span></a>
|
||||
<a class="sourceLine" id="cb2-37" title="37"><span class="dt">port </span><span class="ot">=</span><span class="st"> </span><span class="dv">8082</span></a>
|
||||
<a class="sourceLine" id="cb2-38" title="38"><span class="dt">inbound.length </span><span class="ot">=</span><span class="st"> </span><span class="dv">3</span></a>
|
||||
<a class="sourceLine" id="cb2-39" title="39"><span class="dt">outbound.length </span><span class="ot">=</span><span class="st"> </span><span class="dv">3</span></a>
|
||||
<a class="sourceLine" id="cb2-40" title="40"><span class="dt">destination </span><span class="ot">=</span><span class="st"> i2p-projekt.i2p</span></a>
|
||||
<a class="sourceLine" id="cb2-41" title="41"><span class="dt">keys </span><span class="ot">=</span><span class="st"> forwarder-two</span></a>
|
||||
<a class="sourceLine" id="cb2-42" title="42"></a>
|
||||
<a class="sourceLine" id="cb2-43" title="43"><span class="co">#[sam-forwarder-udp-server]</span></a>
|
||||
<a class="sourceLine" id="cb2-44" title="44"><span class="co">#type = udpserver</span></a>
|
||||
<a class="sourceLine" id="cb2-45" title="45"><span class="co">#host = 127.0.0.1</span></a>
|
||||
<a class="sourceLine" id="cb2-46" title="46"><span class="co">#port = 8084</span></a>
|
||||
<a class="sourceLine" id="cb2-47" title="47"><span class="co">#inbound.length = 6</span></a>
|
||||
<a class="sourceLine" id="cb2-48" title="48"><span class="co">#outbound.length = 3</span></a>
|
||||
<a class="sourceLine" id="cb2-49" title="49"><span class="co">#keys = forwarder-four</span></a>
|
||||
<a class="sourceLine" id="cb2-50" title="50"></a>
|
||||
<a class="sourceLine" id="cb2-51" title="51"><span class="co">#[sam-forwarder-udp-client]</span></a>
|
||||
<a class="sourceLine" id="cb2-52" title="52"><span class="co">#type = udpclient</span></a>
|
||||
<a class="sourceLine" id="cb2-53" title="53"><span class="co">#host = 127.0.0.1</span></a>
|
||||
<a class="sourceLine" id="cb2-54" title="54"><span class="co">#port = 8083</span></a>
|
||||
<a class="sourceLine" id="cb2-55" title="55"><span class="co">#inbound.length = 3</span></a>
|
||||
<a class="sourceLine" id="cb2-56" title="56"><span class="co">#outbound.length = 3</span></a>
|
||||
<a class="sourceLine" id="cb2-57" title="57"><span class="co">#destination = i2p-projekt.i2p</span></a>
|
||||
<a class="sourceLine" id="cb2-58" title="58"><span class="co">#keys = forwarder-three</span></a>
|
||||
<a class="sourceLine" id="cb2-59" title="59"></a>
|
||||
<a class="sourceLine" id="cb2-60" title="60"><span class="co">#[sam-forwarder-tcp-http-server]</span></a>
|
||||
<a class="sourceLine" id="cb2-61" title="61"><span class="co">#type = http</span></a>
|
||||
<a class="sourceLine" id="cb2-62" title="62"><span class="co">#host = 127.0.0.1</span></a>
|
||||
<a class="sourceLine" id="cb2-63" title="63"><span class="co">#port = 8085</span></a>
|
||||
<a class="sourceLine" id="cb2-64" title="64"><span class="co">#inbound.length = 3</span></a>
|
||||
<a class="sourceLine" id="cb2-65" title="65"><span class="co">#outbound.length = 3</span></a>
|
||||
<a class="sourceLine" id="cb2-66" title="66"><span class="co">#keys = forwarder-five</span></a>
|
||||
<a class="sourceLine" id="cb2-67" title="67"></a>
|
||||
<a class="sourceLine" id="cb2-68" title="68"><span class="co">#[sam-forwarder-vpn-server]</span></a>
|
||||
<a class="sourceLine" id="cb2-69" title="69"><span class="co">#type = udpserver</span></a>
|
||||
<a class="sourceLine" id="cb2-70" title="70"><span class="co">#host = 127.0.0.1</span></a>
|
||||
<a class="sourceLine" id="cb2-71" title="71"><span class="co">#port = 8084</span></a>
|
||||
<a class="sourceLine" id="cb2-72" title="72"><span class="co">#inbound.length = 2</span></a>
|
||||
<a class="sourceLine" id="cb2-73" title="73"><span class="co">#outbound.length = 2</span></a>
|
||||
<a class="sourceLine" id="cb2-74" title="74"><span class="co">#inbound.backupQuantity = 3</span></a>
|
||||
<a class="sourceLine" id="cb2-75" title="75"><span class="co">#outbound.backupQuantity = 3</span></a>
|
||||
<a class="sourceLine" id="cb2-76" title="76"><span class="co">#inbound.quantity = 5</span></a>
|
||||
<a class="sourceLine" id="cb2-77" title="77"><span class="co">#outbound.quantity = 5</span></a>
|
||||
<a class="sourceLine" id="cb2-78" title="78"><span class="co">#i2cp.reduceOnIdle = true</span></a>
|
||||
<a class="sourceLine" id="cb2-79" title="79"><span class="co">#i2cp.reduceIdleTime = 3000000</span></a>
|
||||
<a class="sourceLine" id="cb2-80" title="80"><span class="co">#i2cp.reduceQuantity = 2</span></a>
|
||||
<a class="sourceLine" id="cb2-81" title="81"><span class="co">#i2cp.closeOnIdle = false</span></a>
|
||||
<a class="sourceLine" id="cb2-82" title="82"><span class="co">#keys = i2pvpnserver</span></a>
|
||||
<a class="sourceLine" id="cb2-83" title="83"></a>
|
||||
<a class="sourceLine" id="cb2-84" title="84"><span class="co">#[sam-forwarder-vpn-client]</span></a>
|
||||
<a class="sourceLine" id="cb2-85" title="85"><span class="co">#type = udpclient</span></a>
|
||||
<a class="sourceLine" id="cb2-86" title="86"><span class="co">#host = 127.0.0.1</span></a>
|
||||
<a class="sourceLine" id="cb2-87" title="87"><span class="co">#port = 8085</span></a>
|
||||
<a class="sourceLine" id="cb2-88" title="88"><span class="co">#inbound.length = 2</span></a>
|
||||
<a class="sourceLine" id="cb2-89" title="89"><span class="co">#outbound.length = 2</span></a>
|
||||
<a class="sourceLine" id="cb2-90" title="90"><span class="co">#inbound.backupQuantity = 3</span></a>
|
||||
<a class="sourceLine" id="cb2-91" title="91"><span class="co">#outbound.backupQuantity = 3</span></a>
|
||||
<a class="sourceLine" id="cb2-92" title="92"><span class="co">#inbound.quantity = 5</span></a>
|
||||
<a class="sourceLine" id="cb2-93" title="93"><span class="co">#outbound.quantity = 5</span></a>
|
||||
<a class="sourceLine" id="cb2-94" title="94"><span class="co">#i2cp.reduceOnIdle = true</span></a>
|
||||
<a class="sourceLine" id="cb2-95" title="95"><span class="co">#i2cp.reduceIdleTime = 3000000</span></a>
|
||||
<a class="sourceLine" id="cb2-96" title="96"><span class="co">#i2cp.reduceQuantity = 2</span></a>
|
||||
<a class="sourceLine" id="cb2-97" title="97"><span class="co">#destination = adestinationisrequiredorbespecifiedatruntime.i2p</span></a>
|
||||
<a class="sourceLine" id="cb2-98" title="98"><span class="co">#keys = i2pvpnclient</span></a></code></pre></div>
|
15
etc/i2pvpn/i2pvpn.ini
Normal file
15
etc/i2pvpn/i2pvpn.ini
Normal file
@@ -0,0 +1,15 @@
|
||||
[I2PVPNServer]
|
||||
type = udpserver
|
||||
host = 127.0.0.1
|
||||
port = 8084
|
||||
inbound.length = 2
|
||||
outbound.length = 2
|
||||
inbound.backupQuantity = 3
|
||||
outbound.backupQuantity = 3
|
||||
inbound.quantity = 5
|
||||
outbound.quantity = 5
|
||||
i2cp.reduceOnIdle = true
|
||||
i2cp.reduceIdleTime = 3000000
|
||||
i2cp.reduceQuantity = 2
|
||||
i2cp.closeOnIdle = false
|
||||
keys = i2pvpnserver
|
15
etc/i2pvpn/i2pvpnclient.ini
Normal file
15
etc/i2pvpn/i2pvpnclient.ini
Normal file
@@ -0,0 +1,15 @@
|
||||
[I2PVPNClient]
|
||||
type = udpclient
|
||||
host = 127.0.0.1
|
||||
port = 8085
|
||||
inbound.length = 2
|
||||
outbound.length = 2
|
||||
inbound.backupQuantity = 3
|
||||
outbound.backupQuantity = 3
|
||||
inbound.quantity = 5
|
||||
outbound.quantity = 5
|
||||
i2cp.reduceOnIdle = true
|
||||
i2cp.reduceIdleTime = 3000000
|
||||
i2cp.reduceQuantity = 2
|
||||
#destination = adestinationisrequiredorbespecifiedatruntime.i2p
|
||||
keys = i2pvpnclient
|
91
etc/init.d/samcatd
Normal file
91
etc/init.d/samcatd
Normal file
@@ -0,0 +1,91 @@
|
||||
#!/bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: samcatd
|
||||
# Required-Start: $local_fs $network $named $time $syslog
|
||||
# Required-Stop: $local_fs $network $named $time $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Description: <DESCRIPTION>
|
||||
### END INIT INFO
|
||||
|
||||
SCRIPT='/usr/local/bin/samcatd -f /etc/samcatd/tunnels.ini'
|
||||
RUNAS=samcatd
|
||||
|
||||
PIDFILE=/var/run/samcatd/samcatd.pid
|
||||
RUNFOLDER=/var/run/samcatd
|
||||
LOGFILE=/var/log/samcatd/samcatd.log
|
||||
|
||||
start() {
|
||||
if [ -f "$PIDFILE" ]; then
|
||||
echo 'Service already running' >&2
|
||||
return 1
|
||||
fi
|
||||
echo 'Starting destination-isolating proxy service…' >&2
|
||||
start-stop-daemon -S -b -q -d "$RUNFOLDER" -g "$RUNAS" -c "$RUNAS" -p "$PIDFILE" \
|
||||
--startas /bin/bash -- -c "exec $SCRIPT > $LOGFILE 2>&1"
|
||||
echo $! > "$PIDFILE"
|
||||
echo "Service started: $SCRIPT" >&2
|
||||
cat "$PIDFILE" >&2
|
||||
}
|
||||
|
||||
stop() {
|
||||
if [ ! -f "$PIDFILE" ]; then
|
||||
echo 'Service not running' >&2
|
||||
return 1
|
||||
fi
|
||||
echo 'Stopping destination-isolating proxy service…' >&2
|
||||
start-stop-daemon -K -q -d "$RUNFOLDER" -g "$RUNAS" -c "$RUNAS" -p "$PIDFILE" \
|
||||
--startas /bin/bash -- -c "exec $SCRIPT > $LOGFILE 2>&1"
|
||||
echo "Service stopped: $SCRIPT" >&2
|
||||
rm -f "$PIDFILE"
|
||||
}
|
||||
|
||||
status() {
|
||||
if [ -f "$PIDFILE" ]; then
|
||||
start-stop-daemon -T -q -d "$RUNFOLDER" -g "$RUNAS" -c "$RUNAS" -p "$PIDFILE" \
|
||||
--startas /bin/bash -- -c "exec $SCRIPT > $LOGFILE 2>&1"
|
||||
echo 'Currently open pipes:' >&2
|
||||
ls /var/run/samcatd/* >&2
|
||||
tail $LOGFILE >&2
|
||||
return 1
|
||||
else
|
||||
echo 'Service not running' >&2
|
||||
ls /var/run/samcatd >&2
|
||||
return 1
|
||||
fi
|
||||
echo 'Starting destination-isolating proxy service…' >&2
|
||||
}
|
||||
|
||||
uninstall() {
|
||||
echo -n "Are you really sure you want to uninstall this service? That cannot be undone. [yes|No] "
|
||||
local SURE
|
||||
read SURE
|
||||
if [ "$SURE" = "yes" ]; then
|
||||
stop
|
||||
rm -f "$PIDFILE"
|
||||
echo "Notice: log file is not be removed: '$LOGFILE'" >&2
|
||||
update-rc.d -f samcatd remove
|
||||
rm -fv "$0"
|
||||
fi
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
start
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
status)
|
||||
status
|
||||
;;
|
||||
uninstall)
|
||||
uninstall
|
||||
;;
|
||||
restart)
|
||||
stop
|
||||
start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart|uninstall}"
|
||||
esac
|
@@ -1,25 +1,22 @@
|
||||
|
||||
##Example configuration file, all crazy options enabled. Intended for adjustment.
|
||||
## DO NOT USE THESE AS DEFAULTS. THEY ARE FOR TESTING.
|
||||
|
||||
[ephsite]
|
||||
type = server
|
||||
host = 127.0.0.1
|
||||
port = 8081
|
||||
inbound.length = 3
|
||||
outbound.length = 6
|
||||
#inbound.lengthVariance = 6
|
||||
#outbound.lengthVariance = 6
|
||||
#inbound.backupQuantity = 3
|
||||
#outbound.backupQuantity = 5
|
||||
#inbound.quantity = 15
|
||||
#outbound.quantity = 15
|
||||
#inbound.allowZeroHop = true
|
||||
#outbound.allowZeroHop = true
|
||||
#i2cp.encryptLeaseSet = true
|
||||
#gzip = true
|
||||
#i2cp.reduceOnIdle = true
|
||||
#i2cp.reduceIdleTime = 3000000
|
||||
#i2cp.reduceQuantity = 4
|
||||
#i2cp.enableWhiteList = false
|
||||
#i2cp.enableBlackList = true
|
||||
#i2cp.accessList = BASE64KEYSSEPARATEDBY,COMMAS
|
||||
#keys = forwarder
|
||||
inbound.length = 1
|
||||
outbound.length = 2
|
||||
inbound.lengthVariance = 3
|
||||
outbound.lengthVariance = 4
|
||||
inbound.backupQuantity = 5
|
||||
outbound.backupQuantity = 4
|
||||
inbound.quantity = 3
|
||||
outbound.quantity = 2
|
||||
inbound.allowZeroHop = false
|
||||
outbound.allowZeroHop = false
|
||||
i2cp.encryptLeaseSet = false
|
||||
gzip = true
|
||||
i2cp.reduceOnIdle = true
|
||||
i2cp.reduceIdleTime = 3000000
|
||||
i2cp.reduceQuantity = 2
|
||||
i2cp.enableWhiteList = false
|
||||
i2cp.enableBlackList = false
|
||||
|
9897
etc/samcatd/hashwords.txt
Normal file
9897
etc/samcatd/hashwords.txt
Normal file
File diff suppressed because it is too large
Load Diff
83
etc/samcatd/tunnels.ini
Normal file
83
etc/samcatd/tunnels.ini
Normal file
@@ -0,0 +1,83 @@
|
||||
|
||||
## Defaults, these are only invoked with the -start option or if labeled tunnels
|
||||
## are not present(samcatd instructions). **THESE** are the correct config files
|
||||
## to use as defaults, and not the ones in ../sam-forwarder/tunnels.ini, which
|
||||
## are used for testing settings availability only.
|
||||
|
||||
inbound.length = 3
|
||||
outbound.length = 3
|
||||
inbound.lengthVariance = 1
|
||||
outbound.lengthVariance = 1
|
||||
inbound.backupQuantity = 1
|
||||
outbound.backupQuantity = 1
|
||||
inbound.quantity = 2
|
||||
outbound.quantity = 2
|
||||
inbound.allowZeroHop = false
|
||||
outbound.allowZeroHop = false
|
||||
i2cp.encryptLeaseSet = false
|
||||
gzip = true
|
||||
i2cp.reduceOnIdle = true
|
||||
i2cp.reduceIdleTime = 300000
|
||||
i2cp.reduceQuantity = 2
|
||||
i2cp.enableWhiteList = false
|
||||
i2cp.enableBlackList = false
|
||||
#keyfile = "/usr/share/samcatd/samcatd"
|
||||
|
||||
[sam-forwarder-tcp-server]
|
||||
type = server
|
||||
host = 127.0.0.1
|
||||
port = 7669
|
||||
inbound.length = 2
|
||||
outbound.length = 2
|
||||
keys = tcpserver
|
||||
|
||||
[sam-forwarder-tcp-client]
|
||||
type = client
|
||||
host = 127.0.0.1
|
||||
port = 8082
|
||||
inbound.length = 2
|
||||
outbound.length = 3
|
||||
destination = i2p-projekt.i2p
|
||||
keys = tcpclient
|
||||
|
||||
[sam-forwarder-udp-server]
|
||||
type = udpserver
|
||||
host = 127.0.0.1
|
||||
port = 8084
|
||||
inbound.length = 3
|
||||
outbound.length = 3
|
||||
keys = udpserver
|
||||
|
||||
[sam-forwarder-udp-client]
|
||||
type = udpclient
|
||||
host = 127.0.0.1
|
||||
port = 8083
|
||||
inbound.length = 3
|
||||
outbound.length = 3
|
||||
destination = icdj5g5u4jwwyjoinucty223s2yrq6pzxcqfwmyrmkp7ssn2fjlq.b32.i2p
|
||||
keys = udpclient
|
||||
|
||||
[sam-forwarder-tcp-http-server]
|
||||
type = http
|
||||
host = 127.0.0.1
|
||||
port = 8085
|
||||
inbound.length = 3
|
||||
outbound.length = 3
|
||||
keys = httpserver
|
||||
|
||||
#[sam-forwarder-tcp-http-client]
|
||||
#type = httpclient
|
||||
#host = 127.0.0.1
|
||||
#port = 8086
|
||||
#inbound.length = 3
|
||||
#outbound.length = 3
|
||||
#keys = proxy
|
||||
|
||||
[sam-forwarder-tcp-socks-outproxy]
|
||||
type = client
|
||||
host = 127.0.0.1
|
||||
port = 8087
|
||||
inbound.length = 2
|
||||
outbound.length = 3
|
||||
destination = 4oymiquy7qobjgx36tejs35zeqt24qpemsnzgtfeswmrw6csxbkq.b32.i2p
|
||||
keys = tcpclient
|
126
example/serve.go
126
example/serve.go
@@ -1,126 +0,0 @@
|
||||
package main
|
||||
|
||||
/*
|
||||
WARNING: This is not the official version of eephttpd. It is an older
|
||||
verion I use to test new sam-forwarder features. It is not intended for
|
||||
use in production.
|
||||
*/
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"flag"
|
||||
"log"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
import (
|
||||
"github.com/eyedeekay/sam-forwarder"
|
||||
"github.com/eyedeekay/sam-forwarder/config"
|
||||
)
|
||||
|
||||
var cfg = &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
|
||||
PreferServerCipherSuites: true,
|
||||
CipherSuites: []uint16{
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
|
||||
tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
},
|
||||
}
|
||||
|
||||
var (
|
||||
host = flag.String("a", "127.0.0.1", "hostname to serve on")
|
||||
port = flag.String("p", "7880", "port to serve locally on")
|
||||
samhost = flag.String("sh", "127.0.0.1", "sam host to connect to")
|
||||
samport = flag.String("sp", "7656", "sam port to connect to")
|
||||
directory = flag.String("d", "./www", "the directory of static files to host(default ./www)")
|
||||
sdirectory = flag.String("s", ".", "the directory to save the keys in(default ./)")
|
||||
usei2p = flag.Bool("i", true, "save i2p keys(and thus destinations) across reboots")
|
||||
servicename = flag.String("n", "static-eepSite", "name to give the tunnel(default static-eepSite)")
|
||||
useCompression = flag.Bool("g", true, "Uze gzip(true or false)")
|
||||
injectHeaders = flag.Bool("x", true, "Inject X-I2P-DEST headers")
|
||||
accessListType = flag.String("l", "none", "Type of access list to use, can be \"whitelist\" \"blacklist\" or \"none\".")
|
||||
encryptLeaseSet = flag.Bool("c", false, "Use an encrypted leaseset(true or false)")
|
||||
allowZeroHop = flag.Bool("z", false, "Allow zero-hop, non-anonymous tunnels(true or false)")
|
||||
reduceIdle = flag.Bool("r", false, "Reduce tunnel quantity when idle(true or false)")
|
||||
reduceIdleTime = flag.Int("rt", 600000, "Reduce tunnel quantity after X (milliseconds)")
|
||||
reduceIdleQuantity = flag.Int("rc", 3, "Reduce idle tunnel quantity to X (0 to 5)")
|
||||
inLength = flag.Int("il", 3, "Set inbound tunnel length(0 to 7)")
|
||||
outLength = flag.Int("ol", 3, "Set outbound tunnel length(0 to 7)")
|
||||
inQuantity = flag.Int("iq", 8, "Set inbound tunnel quantity(0 to 15)")
|
||||
outQuantity = flag.Int("oq", 8, "Set outbound tunnel quantity(0 to 15)")
|
||||
inVariance = flag.Int("iv", 0, "Set inbound tunnel length variance(-7 to 7)")
|
||||
outVariance = flag.Int("ov", 0, "Set outbound tunnel length variance(-7 to 7)")
|
||||
inBackupQuantity = flag.Int("ib", 4, "Set inbound tunnel backup quantity(0 to 5)")
|
||||
outBackupQuantity = flag.Int("ob", 4, "Set outbound tunnel backup quantity(0 to 5)")
|
||||
iniFile = flag.String("f", "none", "Use an ini file for configuration")
|
||||
useTLS = flag.Bool("t", false, "Generate or use an existing TLS certificate")
|
||||
certFile = flag.String("m", "cert", "Certificate name to use")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
var forwarder *samforwarder.SAMForwarder
|
||||
var err error
|
||||
config := i2ptunconf.NewI2PBlankTunConf()
|
||||
if *iniFile != "none" {
|
||||
config, err = i2ptunconf.NewI2PTunConf(*iniFile)
|
||||
}
|
||||
config.TargetHost = config.GetHost(*host, "127.0.0.1")
|
||||
config.TargetPort = config.GetPort(*port, "7880")
|
||||
config.SaveFile = config.GetSaveFile(*usei2p, true)
|
||||
config.SaveDirectory = config.GetDir(*sdirectory, "../")
|
||||
config.SamHost = config.GetSAMHost(*samhost, "127.0.0.1")
|
||||
config.SamPort = config.GetSAMPort(*samport, "7656")
|
||||
config.TunName = config.GetKeys(*servicename, "static-eepSite")
|
||||
config.InLength = config.GetInLength(*inLength, 3)
|
||||
config.OutLength = config.GetOutLength(*outLength, 3)
|
||||
config.InVariance = config.GetInVariance(*inVariance, 0)
|
||||
config.OutVariance = config.GetOutVariance(*outVariance, 0)
|
||||
config.InQuantity = config.GetInQuantity(*inQuantity, 6)
|
||||
config.OutQuantity = config.GetOutQuantity(*outQuantity, 6)
|
||||
config.InBackupQuantity = config.GetInBackups(*inBackupQuantity, 5)
|
||||
config.OutBackupQuantity = config.GetOutBackups(*outBackupQuantity, 5)
|
||||
config.EncryptLeaseSet = config.GetEncryptLeaseset(*encryptLeaseSet, false)
|
||||
config.InAllowZeroHop = config.GetInAllowZeroHop(*allowZeroHop, false)
|
||||
config.OutAllowZeroHop = config.GetOutAllowZeroHop(*allowZeroHop, false)
|
||||
config.UseCompression = config.GetUseCompression(*useCompression, true)
|
||||
config.ReduceIdle = config.GetReduceOnIdle(*reduceIdle, true)
|
||||
config.ReduceIdleTime = config.GetReduceIdleTime(*reduceIdleTime, 600000)
|
||||
config.ReduceIdleQuantity = config.GetReduceIdleQuantity(*reduceIdleQuantity, 2)
|
||||
config.CloseIdleTime = config.GetCloseIdleTime(*reduceIdleTime, 600000)
|
||||
config.AccessListType = config.GetAccessListType(*accessListType, "none")
|
||||
config.Type = config.GetType(false, false, *injectHeaders, "server")
|
||||
|
||||
if forwarder, err = i2ptunconf.NewSAMForwarderFromConf(config); err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
go forwarder.Serve()
|
||||
|
||||
if *useTLS {
|
||||
srv := &http.Server{
|
||||
Addr: *host + ":" + *port,
|
||||
Handler: http.FileServer(http.Dir(*directory)),
|
||||
TLSConfig: cfg,
|
||||
TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0),
|
||||
}
|
||||
log.Printf("Serving %s on HTTPS port: %s\n\t and on \n%s", *directory, *port, forwarder.Base32())
|
||||
log.Fatal(
|
||||
srv.ListenAndServeTLS(
|
||||
filepath.Join(*sdirectory+"/", *certFile+".crt"),
|
||||
filepath.Join(*sdirectory+"/", *certFile+".key"),
|
||||
),
|
||||
)
|
||||
} else {
|
||||
log.Printf("Serving %s on HTTP port: %s\n\t and on \n%s", *directory, *port, forwarder.Base32())
|
||||
log.Fatal(
|
||||
http.ListenAndServe(
|
||||
*host+":"+*port,
|
||||
http.FileServer(http.Dir(*directory)),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
package main package main
|
||||
|
||||
import ( import (
|
||||
"flag" "flag"
|
||||
"log" "log"
|
||||
"net/http" "net/http"
|
||||
) )
|
||||
|
||||
> import "github.com/eyedeekay/sam-forwarder"
|
||||
>
|
||||
func main() { func main() {
|
||||
port := flag.String("p", "8101", "port to serve on") | port := flag.String("p", "8100", "port to serve on")
|
||||
directory := flag.String("d", ".", "the directory of static file to host") directory := flag.String("d", ".", "the directory of static file to host")
|
||||
flag.Parse() flag.Parse()
|
||||
|
||||
> forwarder, err := samforwarder.NewSAMForwarderFromOptions(
|
||||
> samforwarder.SetHost("127.0.0.1"),
|
||||
> samforwarder.SetPort(*port),
|
||||
> samforwarder.SetSAMHost("127.0.0.1"),
|
||||
> samforwarder.SetSAMPort("7656"),
|
||||
> samforwarder.SetName("staticfiles"),
|
||||
> )
|
||||
> if err != nil {
|
||||
> log.Fatal(err.Error())
|
||||
> }
|
||||
> go forwarder.Serve()
|
||||
>
|
||||
http.Handle("/", http.FileServer(http.Dir(*directory))) http.Handle("/", http.FileServer(http.Dir(*directory)))
|
||||
|
||||
log.Printf("Serving %s on HTTP port: %s\n", *directory, *port) | log.Printf("Serving %s on HTTP port: %s\n", *directory, *port, "and on",
|
||||
log.Fatal(http.ListenAndServe(":"+*port, nil)) | forwarder.Base32()+".b32.i2p")
|
||||
> log.Fatal(http.ListenAndServe("127.0.0.1:"+*port, nil))
|
||||
} }
|
@@ -1,33 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
import "github.com/eyedeekay/sam-forwarder"
|
||||
|
||||
func main() {
|
||||
port := flag.String("p", "8100", "port to serve on")
|
||||
directory := flag.String("d", ".", "the directory of static file to host")
|
||||
flag.Parse()
|
||||
|
||||
forwarder, err := samforwarder.NewSAMForwarderFromOptions(
|
||||
samforwarder.SetHost("127.0.0.1"),
|
||||
samforwarder.SetPort(*port),
|
||||
samforwarder.SetSAMHost("127.0.0.1"),
|
||||
samforwarder.SetSAMPort("7656"),
|
||||
samforwarder.SetName("staticfiles"),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
go forwarder.Serve()
|
||||
|
||||
http.Handle("/", http.FileServer(http.Dir(*directory)))
|
||||
|
||||
log.Printf("Serving %s on HTTP port: %s\n", *directory, *port, "and on",
|
||||
forwarder.Base32()+".b32.i2p")
|
||||
log.Fatal(http.ListenAndServe("127.0.0.1:"+*port, nil))
|
||||
}
|
@@ -1,138 +0,0 @@
|
||||
<h1 id="ephsite---easy-forwarding-of-local-services-to-i2p">ephsite - Easy forwarding of local services to i2p</h1>
|
||||
<p>ephsite is a forwarding proxy designed to configure a tunnel for use with i2p. It can be used to easily forward a local service to the i2p network using i2p's SAM API instead of the tunnel interface.</p>
|
||||
<h2 id="usage">usage:</h2>
|
||||
<pre><code>Usage of ./bin/ephsite:
|
||||
-access string
|
||||
Type of access list to use, can be "whitelist" "blacklist" or "none". (default "none")
|
||||
-accesslist value
|
||||
Specify an access list member(can be used multiple times)
|
||||
-client
|
||||
Client proxy mode(true or false)
|
||||
-close
|
||||
Close tunnel idle(true or false)
|
||||
-closetime int
|
||||
Reduce tunnel quantity after X (milliseconds) (default 600000)
|
||||
-dest string
|
||||
Destination for client tunnels. Ignored for service tunnels. (default "none")
|
||||
-dir string
|
||||
Directory to save tunnel configuration file in.
|
||||
-encryptlease
|
||||
Use an encrypted leaseset(true or false) (default true)
|
||||
-gzip
|
||||
Uze gzip(true or false)
|
||||
-host string
|
||||
Target host(Host of service to forward to i2p) (default "127.0.0.1")
|
||||
-inback int
|
||||
Set inbound tunnel backup quantity(0 to 5) (default 4)
|
||||
-incount int
|
||||
Set inbound tunnel quantity(0 to 15) (default 6)
|
||||
-ini string
|
||||
Use an ini file for configuration(config file options override passed arguments for now.) (default "none")
|
||||
-inlen int
|
||||
Set inbound tunnel length(0 to 7) (default 3)
|
||||
-invar int
|
||||
Set inbound tunnel length variance(-7 to 7)
|
||||
-lsk string
|
||||
path to saved encrypted leaseset keys (default "none")
|
||||
-name string
|
||||
Tunnel name, this must be unique but can be anything. (default "forwarder")
|
||||
-outback int
|
||||
Set outbound tunnel backup quantity(0 to 5) (default 4)
|
||||
-outcount int
|
||||
Set outbound tunnel quantity(0 to 15) (default 6)
|
||||
-outlen int
|
||||
Set outbound tunnel length(0 to 7) (default 3)
|
||||
-outvar int
|
||||
Set outbound tunnel length variance(-7 to 7)
|
||||
-port string
|
||||
Target port(Port of service to forward to i2p) (default "8081")
|
||||
-reduce
|
||||
Reduce tunnel quantity when idle(true or false)
|
||||
-reducecount int
|
||||
Reduce idle tunnel quantity to X (0 to 5) (default 3)
|
||||
-reducetime int
|
||||
Reduce tunnel quantity after X (milliseconds) (default 600000)
|
||||
-samhost string
|
||||
SAM host (default "127.0.0.1")
|
||||
-samport string
|
||||
SAM port (default "7656")
|
||||
-save
|
||||
Use saved file and persist tunnel(If false, tunnel will not persist after program is stopped.
|
||||
-tlsport string
|
||||
(Currently inoperative. Target TLS port(HTTPS Port of service to forward to i2p)
|
||||
-udp
|
||||
UDP mode(true or false)
|
||||
-zeroin
|
||||
Allow zero-hop, non-anonymous tunnels in(true or false)
|
||||
-zeroout
|
||||
Allow zero-hop, non-anonymous tunnels out(true or false)</code></pre>
|
||||
<h1 id="eephttpd---static-file-server-automatically-forwarded-to-i2p">eephttpd - Static file server automatically forwarded to i2p</h1>
|
||||
<h2 id="usage-1">usage:</h2>
|
||||
<p>eephttpd is a static http server which automatically runs on i2p with the help of the SAM bridge. By default it will only be available from the localhost and it's i2p tunnel. It can be masked from the localhost using a container.</p>
|
||||
<pre><code>Usage of ./bin/eephttpd:
|
||||
-a string
|
||||
hostname to serve on (default "127.0.0.1")
|
||||
-c Use an encrypted leaseset(true or false)
|
||||
-d string
|
||||
the directory of static files to host(default ./www) (default "./www")
|
||||
-f string
|
||||
Use an ini file for configuration (default "none")
|
||||
-g Uze gzip(true or false) (default true)
|
||||
-i save i2p keys(and thus destinations) across reboots (default true)
|
||||
-ib int
|
||||
Set inbound tunnel backup quantity(0 to 5) (default 4)
|
||||
-il int
|
||||
Set inbound tunnel length(0 to 7) (default 3)
|
||||
-iq int
|
||||
Set inbound tunnel quantity(0 to 15) (default 8)
|
||||
-iv int
|
||||
Set inbound tunnel length variance(-7 to 7)
|
||||
-l string
|
||||
Type of access list to use, can be "whitelist" "blacklist" or "none". (default "none")
|
||||
-m string
|
||||
Certificate name to use (default "cert")
|
||||
-n string
|
||||
name to give the tunnel(default static-eepSite) (default "static-eepSite")
|
||||
-ob int
|
||||
Set outbound tunnel backup quantity(0 to 5) (default 4)
|
||||
-ol int
|
||||
Set outbound tunnel length(0 to 7) (default 3)
|
||||
-oq int
|
||||
Set outbound tunnel quantity(0 to 15) (default 8)
|
||||
-ov int
|
||||
Set outbound tunnel length variance(-7 to 7)
|
||||
-p string
|
||||
port to serve locally on (default "7880")
|
||||
-r Reduce tunnel quantity when idle(true or false)
|
||||
-rc int
|
||||
Reduce idle tunnel quantity to X (0 to 5) (default 3)
|
||||
-rt int
|
||||
Reduce tunnel quantity after X (milliseconds) (default 600000)
|
||||
-s string
|
||||
the directory to save the keys in(default ./) (default ".")
|
||||
-sh string
|
||||
sam host to connect to (default "127.0.0.1")
|
||||
-sp string
|
||||
sam port to connect to (default "7656")
|
||||
-t Generate or use an existing TLS certificate
|
||||
-z Allow zero-hop, non-anonymous tunnels(true or false)</code></pre>
|
||||
<h3 id="build-in-docker">build in docker</h3>
|
||||
<pre><code>docker build --build-arg user=eephttpd --build-arg path=example/www -f Dockerfile -t eyedeekay/eephttpd .</code></pre>
|
||||
<h3 id="run-in-docker">Run in docker</h3>
|
||||
<pre><code>docker run -i -t -d \
|
||||
--name eephttpd-volume \
|
||||
--volume eephttpd:/home/eephttpd/ \
|
||||
eyedeekay/eephttpd</code></pre>
|
||||
<pre><code>docker run -i -t -d \
|
||||
--network si \
|
||||
--env samhost=sam-host \
|
||||
--env samport=7656 \
|
||||
--env args=-r # Additional arguments to pass to eephttpd\
|
||||
--network-alias eephttpd \
|
||||
--hostname eephttpd \
|
||||
--name eephttpd \
|
||||
--restart always \
|
||||
--volumes-from eephttpd-volume \
|
||||
eyedeekay/eephttpd</code></pre>
|
||||
<h2 id="instance">instance</h2>
|
||||
<p>a running instance of eephttpd with the example index file is availble on</p>
|
@@ -1,338 +0,0 @@
|
||||
package samforwarder
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
//ClientOption is a SAMClientForwarder Option
|
||||
type ClientOption func(*SAMClientForwarder) error
|
||||
|
||||
//SetClientFilePath sets the host of the SAMClientForwarder's SAM bridge
|
||||
func SetClientFilePath(s string) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
c.FilePath = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientSaveFile tells the router to use an encrypted leaseset
|
||||
func SetClientSaveFile(b bool) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
c.save = b
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientHost sets the host of the SAMClientForwarder's SAM bridge
|
||||
func SetClientHost(s string) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
c.TargetHost = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientDestination sets the destination to forwarder SAMClientForwarder's to
|
||||
func SetClientDestination(s string) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
c.dest = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientPort sets the port of the SAMClientForwarder's SAM bridge using a string
|
||||
func SetClientPort(s string) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
port, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Invalid Target Port %s; non-number ", s)
|
||||
}
|
||||
if port < 65536 && port > -1 {
|
||||
c.TargetPort = s
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid port")
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientSAMHost sets the host of the SAMClientForwarder's SAM bridge
|
||||
func SetClientSAMHost(s string) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
c.SamHost = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientSAMPort sets the port of the SAMClientForwarder's SAM bridge using a string
|
||||
func SetClientSAMPort(s string) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
port, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Invalid SAM Port %s; non-number", s)
|
||||
}
|
||||
if port < 65536 && port > -1 {
|
||||
c.SamPort = s
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid port")
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientName sets the host of the SAMClientForwarder's SAM bridge
|
||||
func SetClientName(s string) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
c.TunName = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientInLength sets the number of hops inbound
|
||||
func SetClientInLength(u int) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
if u < 7 && u >= 0 {
|
||||
c.inLength = strconv.Itoa(u)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid inbound tunnel length")
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientOutLength sets the number of hops outbound
|
||||
func SetClientOutLength(u int) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
if u < 7 && u >= 0 {
|
||||
c.outLength = strconv.Itoa(u)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid outbound tunnel length")
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientInVariance sets the variance of a number of hops inbound
|
||||
func SetClientInVariance(i int) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
if i < 7 && i > -7 {
|
||||
c.inVariance = strconv.Itoa(i)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid inbound tunnel length")
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientOutVariance sets the variance of a number of hops outbound
|
||||
func SetClientOutVariance(i int) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
if i < 7 && i > -7 {
|
||||
c.outVariance = strconv.Itoa(i)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid outbound tunnel variance")
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientInQuantity sets the inbound tunnel quantity
|
||||
func SetClientInQuantity(u int) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
if u <= 16 && u > 0 {
|
||||
c.inQuantity = strconv.Itoa(u)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid inbound tunnel quantity")
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientOutQuantity sets the outbound tunnel quantity
|
||||
func SetClientOutQuantity(u int) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
if u <= 16 && u > 0 {
|
||||
c.outQuantity = strconv.Itoa(u)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid outbound tunnel quantity")
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientInBackups sets the inbound tunnel backups
|
||||
func SetClientInBackups(u int) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
if u < 6 && u >= 0 {
|
||||
c.inBackupQuantity = strconv.Itoa(u)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid inbound tunnel backup quantity")
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientOutBackups sets the inbound tunnel backups
|
||||
func SetClientOutBackups(u int) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
if u < 6 && u >= 0 {
|
||||
c.outBackupQuantity = strconv.Itoa(u)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid outbound tunnel backup quantity")
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientEncrypt tells the router to use an encrypted leaseset
|
||||
func SetClientEncrypt(b bool) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
if b {
|
||||
c.encryptLeaseSet = "true"
|
||||
return nil
|
||||
}
|
||||
c.encryptLeaseSet = "false"
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientAllowZeroIn tells the tunnel to accept zero-hop peers
|
||||
func SetClientAllowZeroIn(b bool) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
if b {
|
||||
c.inAllowZeroHop = "true"
|
||||
return nil
|
||||
}
|
||||
c.inAllowZeroHop = "false"
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientAllowZeroOut tells the tunnel to accept zero-hop peers
|
||||
func SetClientAllowZeroOut(b bool) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
if b {
|
||||
c.outAllowZeroHop = "true"
|
||||
return nil
|
||||
}
|
||||
c.outAllowZeroHop = "false"
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientCompress tells clients to use compression
|
||||
func SetClientCompress(b bool) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
if b {
|
||||
c.useCompression = "true"
|
||||
return nil
|
||||
}
|
||||
c.useCompression = "false"
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientReduceIdle tells the connection to reduce it's tunnels during extended idle time.
|
||||
func SetClientReduceIdle(b bool) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
if b {
|
||||
c.reduceIdle = "true"
|
||||
return nil
|
||||
}
|
||||
c.reduceIdle = "false"
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientReduceIdleTime sets the time to wait before reducing tunnels to idle levels
|
||||
func SetClientReduceIdleTime(u int) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
c.reduceIdleTime = strconv.Itoa(300000)
|
||||
if u >= 6 {
|
||||
c.reduceIdleTime = strconv.Itoa((u * 60) * 1000)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid reduce idle timeout(Measured in minutes) %v", u)
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientReduceIdleTimeMs sets the time to wait before reducing tunnels to idle levels in milliseconds
|
||||
func SetClientReduceIdleTimeMs(u int) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
c.reduceIdleTime = strconv.Itoa(300000)
|
||||
if u >= 300000 {
|
||||
c.reduceIdleTime = strconv.Itoa(u)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid reduce idle timeout(Measured in milliseconds) %v", u)
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientReduceIdleQuantity sets minimum number of tunnels to reduce to during idle time
|
||||
func SetClientReduceIdleQuantity(u int) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
if u < 5 {
|
||||
c.reduceIdleQuantity = strconv.Itoa(u)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid reduce tunnel quantity")
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientCloseIdle tells the connection to close it's tunnels during extended idle time.
|
||||
func SetClientCloseIdle(b bool) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
if b {
|
||||
c.closeIdle = "true"
|
||||
return nil
|
||||
}
|
||||
c.closeIdle = "false"
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientCloseIdleTime sets the time to wait before closing tunnels to idle levels
|
||||
func SetClientCloseIdleTime(u int) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
c.closeIdleTime = strconv.Itoa(300000)
|
||||
if u >= 6 {
|
||||
c.closeIdleTime = strconv.Itoa((u * 60) * 1000)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid close idle timeout(Measured in minutes) %v", u)
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientCloseIdleTimeMs sets the time to wait before closing tunnels to idle levels in milliseconds
|
||||
func SetClientCloseIdleTimeMs(u int) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
c.closeIdleTime = strconv.Itoa(300000)
|
||||
if u >= 300000 {
|
||||
c.closeIdleTime = strconv.Itoa(u)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid close idle timeout(Measured in milliseconds) %v", u)
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientAccessListType tells the system to treat the accessList as a whitelist
|
||||
func SetClientAccessListType(s string) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
if s == "whitelist" {
|
||||
c.accessListType = "whitelist"
|
||||
return nil
|
||||
} else if s == "blacklist" {
|
||||
c.accessListType = "blacklist"
|
||||
return nil
|
||||
} else if s == "none" {
|
||||
c.accessListType = ""
|
||||
return nil
|
||||
} else if s == "" {
|
||||
c.accessListType = ""
|
||||
}
|
||||
return fmt.Errorf("Invalid Access list type(whitelist, blacklist, none)")
|
||||
}
|
||||
}
|
||||
|
||||
//SetClientAccessList tells the system to treat the accessList as a whitelist
|
||||
func SetClientAccessList(s []string) func(*SAMClientForwarder) error {
|
||||
return func(c *SAMClientForwarder) error {
|
||||
if len(s) > 0 {
|
||||
for _, a := range s {
|
||||
c.accessList = append(c.accessList, a)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
@@ -1,235 +0,0 @@
|
||||
package samforwarder
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
import (
|
||||
"github.com/eyedeekay/sam3"
|
||||
)
|
||||
|
||||
// SAMClientForwarder is a tcp proxy that automatically forwards ports to i2p
|
||||
type SAMClientForwarder struct {
|
||||
SamHost string
|
||||
SamPort string
|
||||
TunName string
|
||||
|
||||
TargetHost string
|
||||
TargetPort string
|
||||
|
||||
samConn *sam3.SAM
|
||||
SamKeys sam3.I2PKeys
|
||||
connectStream *sam3.StreamSession
|
||||
dest string
|
||||
addr sam3.I2PAddr
|
||||
publishConnection net.Listener
|
||||
|
||||
FilePath string
|
||||
file io.ReadWriter
|
||||
save bool
|
||||
|
||||
// I2CP options
|
||||
encryptLeaseSet string
|
||||
LeaseSetKeys *sam3.I2PKeys
|
||||
inAllowZeroHop string
|
||||
outAllowZeroHop string
|
||||
inLength string
|
||||
outLength string
|
||||
inQuantity string
|
||||
outQuantity string
|
||||
inVariance string
|
||||
outVariance string
|
||||
inBackupQuantity string
|
||||
outBackupQuantity string
|
||||
useCompression string
|
||||
closeIdle string
|
||||
closeIdleTime string
|
||||
reduceIdle string
|
||||
reduceIdleTime string
|
||||
reduceIdleQuantity string
|
||||
|
||||
//Streaming Library options
|
||||
accessListType string
|
||||
accessList []string
|
||||
}
|
||||
|
||||
//var err error
|
||||
|
||||
func (f *SAMClientForwarder) accesslisttype() string {
|
||||
if f.accessListType == "whitelist" {
|
||||
return "i2cp.enableAccessList=true"
|
||||
} else if f.accessListType == "blacklist" {
|
||||
return "i2cp.enableBlackList=true"
|
||||
} else if f.accessListType == "none" {
|
||||
return ""
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (f *SAMClientForwarder) accesslist() string {
|
||||
if f.accessListType != "" && len(f.accessList) > 0 {
|
||||
r := ""
|
||||
for _, s := range f.accessList {
|
||||
r += s + ","
|
||||
}
|
||||
return "i2cp.accessList=" + strings.TrimSuffix(r, ",")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Target returns the host:port of the local service you want to forward to i2p
|
||||
func (f *SAMClientForwarder) Target() string {
|
||||
return f.TargetHost + ":" + f.TargetPort
|
||||
}
|
||||
|
||||
func (f *SAMClientForwarder) sam() string {
|
||||
return f.SamHost + ":" + f.SamPort
|
||||
}
|
||||
|
||||
//Base32 returns the base32 address of the local destination
|
||||
func (f *SAMClientForwarder) Base32() string {
|
||||
return f.SamKeys.Addr().Base32()
|
||||
}
|
||||
|
||||
//Base64 returns the base64 address of the local destiantion
|
||||
func (f *SAMClientForwarder) Base64() string {
|
||||
return f.SamKeys.Addr().Base64()
|
||||
}
|
||||
|
||||
func (f *SAMClientForwarder) forward(conn net.Conn) {
|
||||
client, err := f.connectStream.DialI2P(f.addr)
|
||||
if err != nil {
|
||||
log.Fatalf("Dial failed: %v", err)
|
||||
}
|
||||
log.Printf("Connected to localhost %v\n", conn)
|
||||
go func() {
|
||||
defer client.Close()
|
||||
defer conn.Close()
|
||||
io.Copy(client, conn)
|
||||
}()
|
||||
go func() {
|
||||
defer client.Close()
|
||||
defer conn.Close()
|
||||
io.Copy(conn, client)
|
||||
}()
|
||||
}
|
||||
|
||||
//Serve starts the SAM connection and and forwards the local host:port to i2p
|
||||
func (f *SAMClientForwarder) Serve(dest string) error {
|
||||
f.dest = dest
|
||||
if f.addr, err = f.samConn.Lookup(f.dest); err != nil {
|
||||
return err
|
||||
}
|
||||
if f.connectStream, err = f.samConn.NewStreamSession(f.TunName, f.SamKeys,
|
||||
[]string{
|
||||
"inbound.length=" + f.inLength,
|
||||
"outbound.length=" + f.outLength,
|
||||
"inbound.lengthVariance=" + f.inVariance,
|
||||
"outbound.lengthVariance=" + f.outVariance,
|
||||
"inbound.backupQuantity=" + f.inBackupQuantity,
|
||||
"outbound.backupQuantity=" + f.outBackupQuantity,
|
||||
"inbound.quantity=" + f.inQuantity,
|
||||
"outbound.quantity=" + f.outQuantity,
|
||||
"inbound.allowZeroHop=" + f.inAllowZeroHop,
|
||||
"outbound.allowZeroHop=" + f.outAllowZeroHop,
|
||||
"i2cp.encryptLeaseSet=" + f.encryptLeaseSet,
|
||||
"i2cp.gzip=" + f.useCompression,
|
||||
"i2cp.reduceOnIdle=" + f.reduceIdle,
|
||||
"i2cp.reduceIdleTime=" + f.reduceIdleTime,
|
||||
"i2cp.reduceQuantity=" + f.reduceIdleQuantity,
|
||||
"i2cp.closeOnIdle=" + f.closeIdle,
|
||||
"i2cp.closeIdleTime=" + f.closeIdleTime,
|
||||
f.accesslisttype(),
|
||||
f.accesslist(),
|
||||
}); err != nil {
|
||||
log.Println("Stream Creation error:", err.Error())
|
||||
return err
|
||||
}
|
||||
log.Println("SAM stream session established.")
|
||||
|
||||
for {
|
||||
conn, err := f.publishConnection.Accept()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Println("Forwarding client to i2p address:", f.addr.Base32())
|
||||
go f.forward(conn)
|
||||
}
|
||||
}
|
||||
|
||||
//NewSAMClientForwarder makes a new SAM forwarder with default options, accepts host:port arguments
|
||||
func NewSAMClientForwarder(host, port string) (*SAMClientForwarder, error) {
|
||||
return NewSAMClientForwarderFromOptions(SetClientHost(host), SetClientPort(port))
|
||||
}
|
||||
|
||||
//NewSAMClientForwarderFromOptions makes a new SAM forwarder with default options, accepts host:port arguments
|
||||
func NewSAMClientForwarderFromOptions(opts ...func(*SAMClientForwarder) error) (*SAMClientForwarder, error) {
|
||||
var s SAMClientForwarder
|
||||
s.SamHost = "127.0.0.1"
|
||||
s.SamPort = "7656"
|
||||
s.FilePath = ""
|
||||
s.save = false
|
||||
s.TargetHost = "127.0.0.1"
|
||||
s.TargetPort = "0"
|
||||
s.TunName = "samForwarder"
|
||||
s.inLength = "3"
|
||||
s.outLength = "3"
|
||||
s.inQuantity = "8"
|
||||
s.outQuantity = "8"
|
||||
s.inVariance = "1"
|
||||
s.outVariance = "1"
|
||||
s.inBackupQuantity = "3"
|
||||
s.outBackupQuantity = "3"
|
||||
s.inAllowZeroHop = "false"
|
||||
s.outAllowZeroHop = "false"
|
||||
s.encryptLeaseSet = "false"
|
||||
s.useCompression = "true"
|
||||
s.reduceIdle = "false"
|
||||
s.reduceIdleTime = "300000"
|
||||
s.reduceIdleQuantity = "4"
|
||||
s.closeIdle = "false"
|
||||
s.closeIdleTime = "300000"
|
||||
s.dest = "none"
|
||||
for _, o := range opts {
|
||||
if err := o(&s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if s.publishConnection, err = net.Listen("tcp", s.TargetHost+":"+s.TargetPort); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if s.samConn, err = sam3.NewSAM(s.sam()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Println("SAM Bridge connection established.")
|
||||
if s.SamKeys, err = s.samConn.NewKeys(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Println("Destination keys generated, tunnel name:", s.TunName)
|
||||
if s.save {
|
||||
if _, err := os.Stat(filepath.Join(s.FilePath, s.TunName+".i2pkeys")); os.IsNotExist(err) {
|
||||
s.file, err = os.Create(filepath.Join(s.FilePath, s.TunName+".i2pkeys"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = sam3.StoreKeysIncompat(s.SamKeys, s.file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
s.file, err = os.Open(filepath.Join(s.FilePath, s.TunName+".i2pkeys"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.SamKeys, err = sam3.LoadKeysIncompat(s.file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &s, nil
|
||||
}
|
@@ -1,360 +0,0 @@
|
||||
package samforwarder
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
//Option is a SAMForwarder Option
|
||||
type Option func(*SAMForwarder) error
|
||||
|
||||
//SetFilePath sets the host of the SAMForwarder's SAM bridge
|
||||
func SetFilePath(s string) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
c.FilePath = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetType sets the type of the forwarder server
|
||||
func SetType(s string) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
if s == "http" {
|
||||
c.Type = s
|
||||
return nil
|
||||
} else if s == "server" {
|
||||
c.Type = s
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid server type")
|
||||
}
|
||||
}
|
||||
|
||||
//SetSaveFile tells the router to use an encrypted leaseset
|
||||
func SetSaveFile(b bool) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
c.save = b
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetHost sets the host of the SAMForwarder's SAM bridge
|
||||
func SetHost(s string) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
c.TargetHost = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetPort sets the port of the SAMForwarder's SAM bridge using a string
|
||||
func SetPort(s string) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
port, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Invalid Target Port %s; non-number ", s)
|
||||
}
|
||||
if port < 65536 && port > -1 {
|
||||
c.TargetPort = s
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid port")
|
||||
}
|
||||
}
|
||||
|
||||
//SetSAMHost sets the host of the SAMForwarder's SAM bridge
|
||||
func SetSAMHost(s string) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
c.SamHost = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetSAMPort sets the port of the SAMForwarder's SAM bridge using a string
|
||||
func SetSAMPort(s string) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
port, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Invalid SAM Port %s; non-number", s)
|
||||
}
|
||||
if port < 65536 && port > -1 {
|
||||
c.SamPort = s
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid port")
|
||||
}
|
||||
}
|
||||
|
||||
//SetName sets the host of the SAMForwarder's SAM bridge
|
||||
func SetName(s string) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
c.TunName = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetInLength sets the number of hops inbound
|
||||
func SetInLength(u int) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
if u < 7 && u >= 0 {
|
||||
c.inLength = strconv.Itoa(u)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid inbound tunnel length")
|
||||
}
|
||||
}
|
||||
|
||||
//SetOutLength sets the number of hops outbound
|
||||
func SetOutLength(u int) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
if u < 7 && u >= 0 {
|
||||
c.outLength = strconv.Itoa(u)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid outbound tunnel length")
|
||||
}
|
||||
}
|
||||
|
||||
//SetInVariance sets the variance of a number of hops inbound
|
||||
func SetInVariance(i int) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
if i < 7 && i > -7 {
|
||||
c.inVariance = strconv.Itoa(i)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid inbound tunnel length")
|
||||
}
|
||||
}
|
||||
|
||||
//SetOutVariance sets the variance of a number of hops outbound
|
||||
func SetOutVariance(i int) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
if i < 7 && i > -7 {
|
||||
c.outVariance = strconv.Itoa(i)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid outbound tunnel variance")
|
||||
}
|
||||
}
|
||||
|
||||
//SetInQuantity sets the inbound tunnel quantity
|
||||
func SetInQuantity(u int) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
if u <= 16 && u > 0 {
|
||||
c.inQuantity = strconv.Itoa(u)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid inbound tunnel quantity")
|
||||
}
|
||||
}
|
||||
|
||||
//SetOutQuantity sets the outbound tunnel quantity
|
||||
func SetOutQuantity(u int) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
if u <= 16 && u > 0 {
|
||||
c.outQuantity = strconv.Itoa(u)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid outbound tunnel quantity")
|
||||
}
|
||||
}
|
||||
|
||||
//SetInBackups sets the inbound tunnel backups
|
||||
func SetInBackups(u int) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
if u < 6 && u >= 0 {
|
||||
c.inBackupQuantity = strconv.Itoa(u)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid inbound tunnel backup quantity")
|
||||
}
|
||||
}
|
||||
|
||||
//SetOutBackups sets the inbound tunnel backups
|
||||
func SetOutBackups(u int) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
if u < 6 && u >= 0 {
|
||||
c.outBackupQuantity = strconv.Itoa(u)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid outbound tunnel backup quantity")
|
||||
}
|
||||
}
|
||||
|
||||
//SetEncrypt tells the router to use an encrypted leaseset
|
||||
func SetEncrypt(b bool) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
if b {
|
||||
c.encryptLeaseSet = "true"
|
||||
return nil
|
||||
}
|
||||
c.encryptLeaseSet = "false"
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetAllowZeroIn tells the tunnel to accept zero-hop peers
|
||||
func SetAllowZeroIn(b bool) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
if b {
|
||||
c.inAllowZeroHop = "true"
|
||||
return nil
|
||||
}
|
||||
c.inAllowZeroHop = "false"
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetAllowZeroOut tells the tunnel to accept zero-hop peers
|
||||
func SetAllowZeroOut(b bool) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
if b {
|
||||
c.outAllowZeroHop = "true"
|
||||
return nil
|
||||
}
|
||||
c.outAllowZeroHop = "false"
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetCompress tells clients to use compression
|
||||
func SetCompress(b bool) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
if b {
|
||||
c.useCompression = "true"
|
||||
return nil
|
||||
}
|
||||
c.useCompression = "false"
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetReduceIdle tells the connection to reduce it's tunnels during extended idle time.
|
||||
func SetReduceIdle(b bool) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
if b {
|
||||
c.reduceIdle = "true"
|
||||
return nil
|
||||
}
|
||||
c.reduceIdle = "false"
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetReduceIdleTime sets the time to wait before reducing tunnels to idle levels
|
||||
func SetReduceIdleTime(u int) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
c.reduceIdleTime = strconv.Itoa(300000)
|
||||
if u >= 6 {
|
||||
c.reduceIdleTime = strconv.Itoa((u * 60) * 1000)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid reduce idle timeout(Measured in minutes) %v", u)
|
||||
}
|
||||
}
|
||||
|
||||
//SetReduceIdleTimeMs sets the time to wait before reducing tunnels to idle levels in milliseconds
|
||||
func SetReduceIdleTimeMs(u int) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
c.reduceIdleTime = strconv.Itoa(300000)
|
||||
if u >= 300000 {
|
||||
c.reduceIdleTime = strconv.Itoa(u)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid reduce idle timeout(Measured in milliseconds) %v", u)
|
||||
}
|
||||
}
|
||||
|
||||
//SetReduceIdleQuantity sets minimum number of tunnels to reduce to during idle time
|
||||
func SetReduceIdleQuantity(u int) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
if u < 5 {
|
||||
c.reduceIdleQuantity = strconv.Itoa(u)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid reduce tunnel quantity")
|
||||
}
|
||||
}
|
||||
|
||||
//SetCloseIdle tells the connection to close it's tunnels during extended idle time.
|
||||
func SetCloseIdle(b bool) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
if b {
|
||||
c.closeIdle = "true"
|
||||
return nil
|
||||
}
|
||||
c.closeIdle = "false"
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetCloseIdleTime sets the time to wait before closing tunnels to idle levels
|
||||
func SetCloseIdleTime(u int) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
c.closeIdleTime = strconv.Itoa(300000)
|
||||
if u >= 6 {
|
||||
c.closeIdleTime = strconv.Itoa((u * 60) * 1000)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid close idle timeout(Measured in minutes) %v", u)
|
||||
}
|
||||
}
|
||||
|
||||
//SetCloseIdleTimeMs sets the time to wait before closing tunnels to idle levels in milliseconds
|
||||
func SetCloseIdleTimeMs(u int) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
c.closeIdleTime = strconv.Itoa(300000)
|
||||
if u >= 300000 {
|
||||
c.closeIdleTime = strconv.Itoa(u)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid close idle timeout(Measured in milliseconds) %v", u)
|
||||
}
|
||||
}
|
||||
|
||||
//SetAccessListType tells the system to treat the accessList as a whitelist
|
||||
func SetAccessListType(s string) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
if s == "whitelist" {
|
||||
c.accessListType = "whitelist"
|
||||
return nil
|
||||
} else if s == "blacklist" {
|
||||
c.accessListType = "blacklist"
|
||||
return nil
|
||||
} else if s == "none" {
|
||||
c.accessListType = ""
|
||||
return nil
|
||||
} else if s == "" {
|
||||
c.accessListType = ""
|
||||
}
|
||||
return fmt.Errorf("Invalid Access list type(whitelist, blacklist, none)")
|
||||
}
|
||||
}
|
||||
|
||||
//SetAccessList tells the system to treat the accessList as a whitelist
|
||||
func SetAccessList(s []string) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
if len(s) > 0 {
|
||||
for _, a := range s {
|
||||
c.accessList = append(c.accessList, a)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetTargetForPort sets the port of the SAMForwarder's SAM bridge using a string
|
||||
/*func SetTargetForPort443(s string) func(*SAMForwarder) error {
|
||||
return func(c *SAMForwarder) error {
|
||||
port, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Invalid Target Port %s; non-number ", s)
|
||||
}
|
||||
if port < 65536 && port > -1 {
|
||||
c.TargetForPort443 = s
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid port")
|
||||
}
|
||||
}
|
||||
*/
|
277
forwarder.go
277
forwarder.go
@@ -1,277 +0,0 @@
|
||||
package samforwarder
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
import (
|
||||
"github.com/eyedeekay/sam3"
|
||||
)
|
||||
|
||||
//SAMForwarder is a structure which automatically configured the forwarding of
|
||||
//a local service to i2p over the SAM API.
|
||||
type SAMForwarder struct {
|
||||
SamHost string
|
||||
SamPort string
|
||||
TunName string
|
||||
|
||||
TargetHost string
|
||||
TargetPort string
|
||||
|
||||
samConn *sam3.SAM
|
||||
SamKeys sam3.I2PKeys
|
||||
publishStream *sam3.StreamSession
|
||||
publishListen *sam3.StreamListener
|
||||
publishConnection net.Conn
|
||||
|
||||
FilePath string
|
||||
file io.ReadWriter
|
||||
save bool
|
||||
|
||||
Type string
|
||||
|
||||
// I2CP options
|
||||
encryptLeaseSet string
|
||||
LeaseSetKeys *sam3.I2PKeys
|
||||
inAllowZeroHop string
|
||||
outAllowZeroHop string
|
||||
inLength string
|
||||
outLength string
|
||||
inQuantity string
|
||||
outQuantity string
|
||||
inVariance string
|
||||
outVariance string
|
||||
inBackupQuantity string
|
||||
outBackupQuantity string
|
||||
useCompression string
|
||||
closeIdle string
|
||||
closeIdleTime string
|
||||
reduceIdle string
|
||||
reduceIdleTime string
|
||||
reduceIdleQuantity string
|
||||
//Streaming Library options
|
||||
accessListType string
|
||||
accessList []string
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
/*func (f *SAMForwarder) targetForPort443() string {
|
||||
if f.TargetForPort443 != "" {
|
||||
return "targetForPort.4443=" + f.TargetHost + ":" + f.TargetForPort443
|
||||
}
|
||||
return ""
|
||||
}*/
|
||||
|
||||
func (f *SAMForwarder) accesslisttype() string {
|
||||
if f.accessListType == "whitelist" {
|
||||
return "i2cp.enableAccessList=true"
|
||||
} else if f.accessListType == "blacklist" {
|
||||
return "i2cp.enableBlackList=true"
|
||||
} else if f.accessListType == "none" {
|
||||
return ""
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (f *SAMForwarder) accesslist() string {
|
||||
if f.accessListType != "" && len(f.accessList) > 0 {
|
||||
r := ""
|
||||
for _, s := range f.accessList {
|
||||
r += s + ","
|
||||
}
|
||||
return "i2cp.accessList=" + strings.TrimSuffix(r, ",")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Target returns the host:port of the local service you want to forward to i2p
|
||||
func (f *SAMForwarder) Target() string {
|
||||
return f.TargetHost + ":" + f.TargetPort
|
||||
}
|
||||
|
||||
func (f *SAMForwarder) sam() string {
|
||||
return f.SamHost + ":" + f.SamPort
|
||||
}
|
||||
|
||||
func (f *SAMForwarder) HTTPRequestBytes(conn *sam3.SAMConn) ([]byte, error) {
|
||||
var request *http.Request
|
||||
var retrequest []byte
|
||||
var err error
|
||||
request, err = http.ReadRequest(bufio.NewReader(conn))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dest := conn.RemoteAddr().(sam3.I2PAddr)
|
||||
log.Printf("Adding headers to http connection\n\tX-I2p-Dest-Base64=%s\n\tX-I2p-Dest-Base32=%s\n\tX-I2p-Dest-Hash=%s",
|
||||
dest.Base64(), dest.Base32(), dest.DestHash().String())
|
||||
request.Header.Add("X-I2p-Dest-Base64", dest.Base64())
|
||||
request.Header.Add("X-I2p-Dest-Base32", dest.Base32())
|
||||
request.Header.Add("X-I2p-Dest-Hash", dest.DestHash().String())
|
||||
if retrequest, err = httputil.DumpRequest(request, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return retrequest, nil
|
||||
}
|
||||
|
||||
func (f *SAMForwarder) forward(conn *sam3.SAMConn) { //(conn net.Conn) {
|
||||
var err error
|
||||
client, err := net.Dial("tcp", f.Target())
|
||||
if err != nil {
|
||||
log.Fatalf("Dial failed: %v", err)
|
||||
}
|
||||
go func() {
|
||||
defer client.Close()
|
||||
defer conn.Close()
|
||||
if f.Type == "http" {
|
||||
if b, e := f.HTTPRequestBytes(conn); e == nil {
|
||||
client.Write(b)
|
||||
} else {
|
||||
log.Println("Error: ", b, e)
|
||||
}
|
||||
} else {
|
||||
io.Copy(client, conn)
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
defer client.Close()
|
||||
defer conn.Close()
|
||||
if f.Type == "http" {
|
||||
io.Copy(conn, client)
|
||||
} else {
|
||||
io.Copy(conn, client)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
//Base32 returns the base32 address where the local service is being forwarded
|
||||
func (f *SAMForwarder) Base32() string {
|
||||
return f.SamKeys.Addr().Base32()
|
||||
}
|
||||
|
||||
//Base64 returns the base64 address where the local service is being forwarded
|
||||
func (f *SAMForwarder) Base64() string {
|
||||
return f.SamKeys.Addr().Base64()
|
||||
}
|
||||
|
||||
//Serve starts the SAM connection and and forwards the local host:port to i2p
|
||||
func (f *SAMForwarder) Serve() error {
|
||||
if f.publishStream, err = f.samConn.NewStreamSession(f.TunName, f.SamKeys,
|
||||
[]string{
|
||||
//f.targetForPort443(),
|
||||
"inbound.length=" + f.inLength,
|
||||
"outbound.length=" + f.outLength,
|
||||
"inbound.lengthVariance=" + f.inVariance,
|
||||
"outbound.lengthVariance=" + f.outVariance,
|
||||
"inbound.backupQuantity=" + f.inBackupQuantity,
|
||||
"outbound.backupQuantity=" + f.outBackupQuantity,
|
||||
"inbound.quantity=" + f.inQuantity,
|
||||
"outbound.quantity=" + f.outQuantity,
|
||||
"inbound.allowZeroHop=" + f.inAllowZeroHop,
|
||||
"outbound.allowZeroHop=" + f.outAllowZeroHop,
|
||||
"i2cp.encryptLeaseSet=" + f.encryptLeaseSet,
|
||||
"i2cp.gzip=" + f.useCompression,
|
||||
"i2cp.reduceOnIdle=" + f.reduceIdle,
|
||||
"i2cp.reduceIdleTime=" + f.reduceIdleTime,
|
||||
"i2cp.reduceQuantity=" + f.reduceIdleQuantity,
|
||||
"i2cp.closeOnIdle=" + f.closeIdle,
|
||||
"i2cp.closeIdleTime=" + f.closeIdleTime,
|
||||
f.accesslisttype(),
|
||||
f.accesslist(),
|
||||
}); err != nil {
|
||||
log.Println("Stream Creation error:", err.Error())
|
||||
return err
|
||||
}
|
||||
log.Println("SAM stream session established.")
|
||||
if f.publishListen, err = f.publishStream.Listen(); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Println("Starting Listener.")
|
||||
b := string(f.SamKeys.Addr().Base32())
|
||||
log.Println("SAM Listener created,", b)
|
||||
|
||||
for {
|
||||
conn, err := f.publishListen.AcceptI2P()
|
||||
if err != nil {
|
||||
log.Fatalf("ERROR: failed to accept listener: %v", err)
|
||||
}
|
||||
log.Printf("Accepted connection %v\n", conn)
|
||||
go f.forward(conn)
|
||||
}
|
||||
}
|
||||
|
||||
//NewSAMForwarder makes a new SAM forwarder with default options, accepts host:port arguments
|
||||
func NewSAMForwarder(host, port string) (*SAMForwarder, error) {
|
||||
return NewSAMForwarderFromOptions(SetHost(host), SetPort(port))
|
||||
}
|
||||
|
||||
//NewSAMForwarderFromOptions makes a new SAM forwarder with default options, accepts host:port arguments
|
||||
func NewSAMForwarderFromOptions(opts ...func(*SAMForwarder) error) (*SAMForwarder, error) {
|
||||
var s SAMForwarder
|
||||
s.SamHost = "127.0.0.1"
|
||||
s.SamPort = "7656"
|
||||
s.FilePath = ""
|
||||
s.save = false
|
||||
s.TargetHost = "127.0.0.1"
|
||||
s.TargetPort = "8081"
|
||||
s.TunName = "samForwarder"
|
||||
s.inLength = "3"
|
||||
s.outLength = "3"
|
||||
s.inQuantity = "8"
|
||||
s.outQuantity = "8"
|
||||
s.inVariance = "1"
|
||||
s.outVariance = "1"
|
||||
s.inBackupQuantity = "3"
|
||||
s.outBackupQuantity = "3"
|
||||
s.inAllowZeroHop = "false"
|
||||
s.outAllowZeroHop = "false"
|
||||
s.encryptLeaseSet = "false"
|
||||
s.useCompression = "true"
|
||||
s.reduceIdle = "false"
|
||||
s.reduceIdleTime = "15"
|
||||
s.reduceIdleQuantity = "4"
|
||||
s.closeIdle = "false"
|
||||
s.closeIdleTime = "300000"
|
||||
for _, o := range opts {
|
||||
if err := o(&s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if s.samConn, err = sam3.NewSAM(s.sam()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Println("SAM Bridge connection established.")
|
||||
if s.SamKeys, err = s.samConn.NewKeys(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Println("Destination keys generated, tunnel name:", s.TunName)
|
||||
if s.save {
|
||||
if _, err := os.Stat(filepath.Join(s.FilePath, s.TunName+".i2pkeys")); os.IsNotExist(err) {
|
||||
s.file, err = os.Create(filepath.Join(s.FilePath, s.TunName+".i2pkeys"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = sam3.StoreKeysIncompat(s.SamKeys, s.file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
s.file, err = os.Open(filepath.Join(s.FilePath, s.TunName+".i2pkeys"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.SamKeys, err = sam3.LoadKeysIncompat(s.file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &s, nil
|
||||
}
|
26
go.mod
Normal file
26
go.mod
Normal file
@@ -0,0 +1,26 @@
|
||||
module github.com/eyedeekay/sam-forwarder
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
crawshaw.io/littleboss v0.0.0-20190317185602-8957d0aedcce
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
|
||||
github.com/boreq/friendlyhash v0.0.0-20190522010448-1ca64b3ca69e
|
||||
github.com/cryptix/goSam v0.1.0 // indirect
|
||||
github.com/eyedeekay/eephttpd v0.0.0-20190903000420-52f5a8485a4e
|
||||
github.com/eyedeekay/httptunnel v0.0.0-20190831071439-0ff3d5f798fb
|
||||
github.com/eyedeekay/i2pdig v0.0.0-20180718204453-a67cb46e2e5f // indirect
|
||||
github.com/eyedeekay/outproxy v0.0.0-20190908174238-22bd71d43733
|
||||
github.com/eyedeekay/portcheck v0.0.0-20190218044454-bb8718669680
|
||||
github.com/eyedeekay/sam3 v0.32.1
|
||||
github.com/gtank/cryptopasta v0.0.0-20170601214702-1f550f6f2f69
|
||||
github.com/justinas/nosurf v0.0.0-20190416172904-05988550ea18
|
||||
github.com/kr/pretty v0.2.0 // indirect
|
||||
github.com/russross/blackfriday v2.0.0+incompatible // indirect
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
||||
github.com/spf13/pflag v1.0.3 // indirect
|
||||
github.com/zieckey/goini v0.0.0-20180118150432-0da17d361d26
|
||||
github.com/zserge/lorca v0.1.8
|
||||
github.com/zserge/webview v0.0.0-20190123072648-16c93bcaeaeb
|
||||
gitlab.com/opennota/wd v0.0.0-20191124020556-236695b0ea63 // indirect
|
||||
)
|
85
go.sum
Normal file
85
go.sum
Normal file
@@ -0,0 +1,85 @@
|
||||
crawshaw.io/littleboss v0.0.0-20190317185602-8957d0aedcce h1:4VyRNGOpNgP9ioTYZ7ah3x8C28I7wsMt4Ao9nTXv2ec=
|
||||
crawshaw.io/littleboss v0.0.0-20190317185602-8957d0aedcce/go.mod h1:TIbCAHgttUfOKudw59Il7Z0XIlitzo228/mtwMe4vPM=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||
github.com/boreq/friendlyhash v0.0.0-20190522010448-1ca64b3ca69e h1:2q8XPjAYhXX8H71AoAPdgBrCUA3HPhC4ax8XHrTsY6I=
|
||||
github.com/boreq/friendlyhash v0.0.0-20190522010448-1ca64b3ca69e/go.mod h1:y80zLCg0QS5u3fJKeF2rwpezcyZuCpZpbFcWv6Pn98w=
|
||||
github.com/cryptix/go v1.3.1/go.mod h1:mFQotm9rTzptzvNjJM+1vSIDa/rVOVqMu0889GIXg70=
|
||||
github.com/cryptix/goSam v0.1.0/go.mod h1:7ewkjhXT8V5RG07pvWUOHHtMahvGbeKlEv8ukUyRiTA=
|
||||
github.com/d5/tengo v1.24.3 h1:wp44VW7fdfzMzIDT19tT5uNeGnm2UMd6s3TLAahrwSU=
|
||||
github.com/d5/tengo v1.24.3/go.mod h1:VhLq8Q2QFhCIJO3NhvM934qOThykMqJi9y9Siqd1ocQ=
|
||||
github.com/eyedeekay/eephttpd v0.0.0-20190903000420-52f5a8485a4e h1:YizBXWVO0QN/1vkcdXXGenBS0bJAHgJcG+2WO22im0Y=
|
||||
github.com/eyedeekay/eephttpd v0.0.0-20190903000420-52f5a8485a4e/go.mod h1:wFPQsNBnY95LkuujFEZARo7slafRwoF0D97FFHBoZro=
|
||||
github.com/eyedeekay/goSam v0.1.1-0.20190814204230-d4c9b8c57dd6 h1:+5eM/MhjGMWCGQCCqn9pb1bmvoRewweWhOaE6fA7kZ0=
|
||||
github.com/eyedeekay/goSam v0.1.1-0.20190814204230-d4c9b8c57dd6/go.mod h1:kGTfZrncJ4CwMX3d1qA6bcMJTOcuTbOqgWg7WrFNAQ0=
|
||||
github.com/eyedeekay/httptunnel v0.0.0-20190831065052-9eab288b8a82/go.mod h1:VeXBZz04xj4eUGAcD8ygn2WFxY/dAvRbSNYMWoDzMxc=
|
||||
github.com/eyedeekay/httptunnel v0.0.0-20190831071439-0ff3d5f798fb h1:jxY4AjQDgkeG2WBop17iJrKcwulVF+fOakOWSiIVcwY=
|
||||
github.com/eyedeekay/httptunnel v0.0.0-20190831071439-0ff3d5f798fb/go.mod h1:SnCAM9CskhwSFkzDfh+H5yNTbvhcTeKekkuX0ejCcSk=
|
||||
github.com/eyedeekay/i2pdig v0.0.0-20180718204453-a67cb46e2e5f/go.mod h1:Zp2JSsndmRykjDGbNS5QHnCYCLnOeYFvwuZFwsATz8k=
|
||||
github.com/eyedeekay/outproxy v0.0.0-20190908174238-22bd71d43733 h1:bm9QcH6cMUUKQ9cOiTgTVLaU9FwhvwecxCSZepKTMcU=
|
||||
github.com/eyedeekay/outproxy v0.0.0-20190908174238-22bd71d43733/go.mod h1:jUBr6XRbiuUBe/sSbVdO5upU4mp8842bdpXDsQY54Rc=
|
||||
github.com/eyedeekay/portcheck v0.0.0-20190218044454-bb8718669680 h1:wZxtUXCp5cOF5gB6PGeUny7ljGFcK6YKFfU7Sf8JBLc=
|
||||
github.com/eyedeekay/portcheck v0.0.0-20190218044454-bb8718669680/go.mod h1:8VVIH19/CU2VFJB8P6e58Mo9nvDqqKgllS0oQY3F83U=
|
||||
github.com/eyedeekay/ramp v0.0.0-20190429201811-305b382042ab h1:EfTRHxGSbiaEyxNzvKRBWVIDw3mD8xXGxj4gvwFzY7Q=
|
||||
github.com/eyedeekay/ramp v0.0.0-20190429201811-305b382042ab/go.mod h1:h7mvUAMgZ/rtRDUOkvKTK+8LnDMeUhJSoa5EPdB51fc=
|
||||
github.com/eyedeekay/sam-forwarder v0.0.0-20190814201550-7c0d7cb0d56c/go.mod h1:Ptrm1d4a3KC5/cN264Gn6OntYOmcuJ8Pkyd7+hA01gw=
|
||||
github.com/eyedeekay/sam-forwarder v0.0.0-20190831071254-d67c0c0e311f/go.mod h1:u4K8aGwSIuMSQ/OzsH7zkshnEvCQgUupfexLXZIjsDI=
|
||||
github.com/eyedeekay/sam-forwarder v0.0.0-20190905212604-029317222e15/go.mod h1:kFP6jkqHUTGGW/nMUZLnRonkPWE9fyEc8/eSU1CqTFg=
|
||||
github.com/eyedeekay/sam3 v0.0.0-20190613034117-99ad6522ebe3/go.mod h1:Vrxh+71E3HVYqyRlT5Jg+E26sSuu8UNTLB4p8qyT408=
|
||||
github.com/eyedeekay/sam3 v0.0.0-20190730185140-f8d54526ea25/go.mod h1:Y3igFVzN4ybqkkpfUWULGhw7WRp8lieq0ORXbLBbcZM=
|
||||
github.com/eyedeekay/sam3 v0.32.1 h1:xaquh9Sxyuxh0SKyv3Gh6wXcZ5QAfWC4Iz4IsjVSESk=
|
||||
github.com/eyedeekay/sam3 v0.32.1/go.mod h1:Y3igFVzN4ybqkkpfUWULGhw7WRp8lieq0ORXbLBbcZM=
|
||||
github.com/go-kit/kit v0.6.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-stack/stack v1.7.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gtank/cryptopasta v0.0.0-20170601214702-1f550f6f2f69 h1:7xsUJsB2NrdcttQPa7JLEaGzvdbk7KvfrjgHZXOQRo0=
|
||||
github.com/gtank/cryptopasta v0.0.0-20170601214702-1f550f6f2f69/go.mod h1:YLEMZOtU+AZ7dhN9T/IpGhXVGly2bvkJQ+zxj3WeVQo=
|
||||
github.com/justinas/nosurf v0.0.0-20190416172904-05988550ea18 h1:ci3v0mUqcCewO25ntt7hprt2ZMNA0AWI6s6qV0rSpc0=
|
||||
github.com/justinas/nosurf v0.0.0-20190416172904-05988550ea18/go.mod h1:Aucr5I5chr4OCuuVB4LTuHVrKHBuyRSo7vM2hqrcb7E=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/miolini/datacounter v0.0.0-20171104152933-fd4e42a1d5e0/go.mod h1:P6fDJzlxN+cWYR09KbE9/ta+Y6JofX9tAUhJpWkWPaM=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/russross/blackfriday v2.0.0+incompatible/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/zieckey/goini v0.0.0-20180118150432-0da17d361d26 h1:E0lEWrifmR0ACbGf5PLji1XbW6rtIXLHCXO/YOqi0AE=
|
||||
github.com/zieckey/goini v0.0.0-20180118150432-0da17d361d26/go.mod h1:TQpdgg7I9+PFIkatlx/dnZyZb4iZyCUx1HJj4rXi3+E=
|
||||
github.com/zserge/lorca v0.1.8 h1:gZwyvesmaoGCwxF5NssI6pdydXkCVHOoHw2nks/PBRs=
|
||||
github.com/zserge/lorca v0.1.8/go.mod h1:gTrVdXKyWxNhc8aUb1Uu3s0mY343arR1T6jUtxmBxR8=
|
||||
github.com/zserge/webview v0.0.0-20190123072648-16c93bcaeaeb h1:zVjnyZIM7UtkG3dNckiudIm+TUHkZqi5xlVQPd3J6/c=
|
||||
github.com/zserge/webview v0.0.0-20190123072648-16c93bcaeaeb/go.mod h1:a1CV8KR4Dd1eP2g+mEijGOp+HKczwdKHWyx0aPHKvo4=
|
||||
gitlab.com/golang-commonmark/html v0.0.0-20180917080848-cfaf75183c4a h1:Ax7kdHNICZiIeFpmevmaEWb0Ae3BUj3zCTKhZHZ+zd0=
|
||||
gitlab.com/golang-commonmark/html v0.0.0-20180917080848-cfaf75183c4a/go.mod h1:JT4uoTz0tfPoyVH88GZoWDNm5NHJI2VbUW+eyPClueI=
|
||||
gitlab.com/golang-commonmark/linkify v0.0.0-20180917065525-c22b7bdb1179 h1:rbON2KwBnWuFMlSHM8LELLlwroDRZw6xv0e6il6e5dk=
|
||||
gitlab.com/golang-commonmark/linkify v0.0.0-20180917065525-c22b7bdb1179/go.mod h1:Gn+LZmCrhPECMD3SOKlE+BOHwhOYD9j7WT9NUtkCrC8=
|
||||
gitlab.com/golang-commonmark/markdown v0.0.0-20181102083822-772775880e1f h1:jwXy/CsM4xS2aoiF2fHAlukmInWhd2TlWB+HDCyvzKc=
|
||||
gitlab.com/golang-commonmark/markdown v0.0.0-20181102083822-772775880e1f/go.mod h1:SIHlEr9462fpIfTrVWf3GqQDxnA65Vm3BMMsUtuA6W0=
|
||||
gitlab.com/golang-commonmark/mdurl v0.0.0-20180912090424-e5bce34c34f2 h1:wD/sPUgx2QJFPTyXZpJnLaROolfeKuruh06U4pRV0WY=
|
||||
gitlab.com/golang-commonmark/mdurl v0.0.0-20180912090424-e5bce34c34f2/go.mod h1:wQk4rLkWrdOPjUAtqJRJ10hIlseLSVYWP95PLrjDF9s=
|
||||
gitlab.com/golang-commonmark/puny v0.0.0-20180912090636-2cd490539afe h1:5kUPFAF52umOUPH12MuNUmyVTseJRNBftDl/KfsvX3I=
|
||||
gitlab.com/golang-commonmark/puny v0.0.0-20180912090636-2cd490539afe/go.mod h1:P9LSM1KVzrIstFgUaveuwiAm8PK5VTB3yJEU8kqlbrU=
|
||||
gitlab.com/opennota/wd v0.0.0-20191124020556-236695b0ea63/go.mod h1:n0SNS6rmmsb705EuaYk2RDZyy+pcmwEAuwQkTOOjsu8=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM=
|
||||
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190830142957-1e83adbbebd0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190830223141-573d9926052a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
24
gui/nostatic.go
Normal file
24
gui/nostatic.go
Normal file
@@ -0,0 +1,24 @@
|
||||
// +build nostatic
|
||||
|
||||
package gui
|
||||
|
||||
import (
|
||||
"github.com/eyedeekay/sam-forwarder/interface"
|
||||
"github.com/zserge/webview"
|
||||
)
|
||||
|
||||
func LaunchUI(s samtunnel.WebUI) (webview.WebView, error) {
|
||||
if s.UseWebUI() == true {
|
||||
settings := webview.Settings{
|
||||
Title: s.Title(),
|
||||
URL: s.URL(),
|
||||
Height: s.Height(),
|
||||
Width: s.Width(),
|
||||
Resizable: s.Resizable(),
|
||||
Debug: true,
|
||||
}
|
||||
view := webview.New(settings)
|
||||
return view, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
19
gui/static.go
Normal file
19
gui/static.go
Normal file
@@ -0,0 +1,19 @@
|
||||
// +build !nostatic
|
||||
|
||||
package gui
|
||||
|
||||
import (
|
||||
"github.com/eyedeekay/sam-forwarder/interface"
|
||||
"github.com/zserge/lorca"
|
||||
)
|
||||
|
||||
var USER = ""
|
||||
|
||||
func LaunchUI(s samtunnel.WebUI) (lorca.UI, error) {
|
||||
if s.UseWebUI() == true {
|
||||
if lorca.LocateChrome() != "" {
|
||||
return lorca.New(s.URL(), s.Title(), s.Width(), s.Height())
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
113
handler/login.go
Normal file
113
handler/login.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package samtunnelhandler
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Create a struct that models the structure of a user, both in the request body, and in the DB
|
||||
type Credentials struct {
|
||||
Password string `json:"password"`
|
||||
Username string `json:"username"`
|
||||
}
|
||||
|
||||
func GenerateRandomBytes(n int) ([]byte, error) {
|
||||
b := make([]byte, n)
|
||||
_, err := rand.Read(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func GenerateRandomString(s int) (string, error) {
|
||||
b, err := GenerateRandomBytes(s)
|
||||
return base64.URLEncoding.EncodeToString(b), err
|
||||
}
|
||||
|
||||
func (m *TunnelHandlerMux) Signin(w http.ResponseWriter, r *http.Request) {
|
||||
var creds Credentials
|
||||
err := json.NewDecoder(r.Body).Decode(&creds)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if creds.Username != m.user {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
if creds.Password != m.password {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
m.sessionToken, err = GenerateRandomString(32)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: "session_token",
|
||||
Value: m.sessionToken,
|
||||
Expires: time.Now().Add(10 * time.Minute),
|
||||
})
|
||||
}
|
||||
|
||||
func (m *TunnelHandlerMux) Home(w http.ResponseWriter, r *http.Request) {
|
||||
if m.CheckCookie(w, r) == false {
|
||||
return
|
||||
}
|
||||
// fmt.Fprintf(w, "URL PATH", r.URL.Path)
|
||||
if r.URL.Path == "/" {
|
||||
http.Redirect(w, r, "/index.html", 301)
|
||||
fmt.Fprintf(w, "redirecting to index.html")
|
||||
return
|
||||
}
|
||||
r2, err := http.NewRequest("GET", r.URL.Path+"/color", r.Body)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(w, "<!DOCTYPE html>\n")
|
||||
fmt.Fprintf(w, "<html>\n")
|
||||
fmt.Fprintf(w, "<head>\n")
|
||||
fmt.Fprintf(w, " <title>")
|
||||
fmt.Fprintf(w, "samcatd")
|
||||
fmt.Fprintf(w, " </title>")
|
||||
fmt.Fprintf(w, " <link rel=\"stylesheet\" href=\"/styles.css\">")
|
||||
fmt.Fprintf(w, "</head>\n")
|
||||
fmt.Fprintf(w, " <body>\n")
|
||||
fmt.Fprintf(w, " <h1>\n")
|
||||
w.Write([]byte(fmt.Sprintf(" <a href=\"/index.html\">Welcome %s! you are serving %d tunnels. </a>\n", m.user, len(m.tunnels))))
|
||||
//fmt.Fprintf(w, "")
|
||||
fmt.Fprintf(w, " </h1>\n")
|
||||
fmt.Fprintf(w, " <div id=\"toggleall\" class=\"global control\">\n")
|
||||
fmt.Fprintf(w, " <a href=\"#\" onclick=\"toggle_visibility_class('%s');\">Show/Hide %s</a>\n", "prop", "all")
|
||||
fmt.Fprintf(w, " </div>\n")
|
||||
for _, tunnel := range m.Tunnels() {
|
||||
tunnel.ServeHTTP(w, r2)
|
||||
}
|
||||
fmt.Fprintf(w, " <script src=\"/scripts.js\"></script>\n")
|
||||
fmt.Fprintf(w, " </body>\n")
|
||||
fmt.Fprintf(w, "</html>\n")
|
||||
}
|
||||
|
||||
func (m *TunnelHandlerMux) CSS(w http.ResponseWriter, r *http.Request) {
|
||||
if m.CheckCookie(w, r) == false {
|
||||
return
|
||||
}
|
||||
w.Header().Add("Content-Type", "text/css")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(fmt.Sprintf("%s\n", m.cssString)))
|
||||
}
|
||||
|
||||
func (m *TunnelHandlerMux) JS(w http.ResponseWriter, r *http.Request) {
|
||||
if m.CheckCookie(w, r) == false {
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(fmt.Sprintf("%s\n", m.jsString)))
|
||||
}
|
121
handler/mux.go
Normal file
121
handler/mux.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package samtunnelhandler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type TunnelHandlerMux struct {
|
||||
http.Server
|
||||
pagenames []string
|
||||
tunnels []*TunnelHandler
|
||||
user string
|
||||
password string
|
||||
sessionToken string
|
||||
cssString string
|
||||
jsString string
|
||||
}
|
||||
|
||||
func (m *TunnelHandlerMux) ListenAndServe() {
|
||||
m.Server.ListenAndServe()
|
||||
}
|
||||
|
||||
func (m *TunnelHandlerMux) CheckCookie(w http.ResponseWriter, r *http.Request) bool {
|
||||
if m.password != "" {
|
||||
if m.sessionToken == "" {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return false
|
||||
}
|
||||
c, err := r.Cookie("session_token")
|
||||
if err != nil {
|
||||
if err == http.ErrNoCookie {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return false
|
||||
}
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return false
|
||||
}
|
||||
if m.sessionToken != c.Value {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
func (m *TunnelHandlerMux) HandlerWrapper(h http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if m.CheckCookie(w, r) == false {
|
||||
return
|
||||
}
|
||||
if !strings.HasSuffix(r.URL.Path, "color") {
|
||||
h.ServeHTTP(w, r)
|
||||
} else {
|
||||
m.ColorHeader(h, r, w)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (t *TunnelHandlerMux) Tunnels() []*TunnelHandler {
|
||||
return t.tunnels
|
||||
}
|
||||
|
||||
func (m *TunnelHandlerMux) Append(v *TunnelHandler) *TunnelHandlerMux {
|
||||
if m == nil {
|
||||
return m
|
||||
}
|
||||
for _, prev := range m.tunnels {
|
||||
if v.ID() == prev.ID() {
|
||||
log.Printf("v.ID() found, %s == %s", v.ID(), prev.ID())
|
||||
return m
|
||||
}
|
||||
}
|
||||
log.Printf("Adding tunnel ID: %s", v.ID())
|
||||
m.tunnels = append(m.tunnels, v)
|
||||
Handler := m.Handler.(*http.ServeMux)
|
||||
Handler.Handle(fmt.Sprintf("/%d", len(m.tunnels)), m.HandlerWrapper(v))
|
||||
Handler.Handle(fmt.Sprintf("/%s", v.ID()), m.HandlerWrapper(v))
|
||||
Handler.Handle(fmt.Sprintf("/%d/color", len(m.tunnels)), m.HandlerWrapper(v))
|
||||
Handler.Handle(fmt.Sprintf("/%s/color", v.ID()), m.HandlerWrapper(v))
|
||||
m.Handler = Handler
|
||||
return m
|
||||
}
|
||||
|
||||
func ReadFile(filename string) (string, error) {
|
||||
r, e := ioutil.ReadFile(filename)
|
||||
return string(r), e
|
||||
}
|
||||
|
||||
func NewTunnelHandlerMux(host, port, user, password, css, javascript string) *TunnelHandlerMux {
|
||||
var m TunnelHandlerMux
|
||||
m.Addr = host + ":" + port
|
||||
Handler := http.NewServeMux()
|
||||
m.pagenames = []string{"index.html", "index", ""}
|
||||
m.user = user
|
||||
m.password = password
|
||||
m.sessionToken = ""
|
||||
m.tunnels = []*TunnelHandler{}
|
||||
var err error
|
||||
m.cssString, err = ReadFile(css)
|
||||
if err != nil {
|
||||
m.cssString = DefaultCSS()
|
||||
}
|
||||
m.jsString, err = ReadFile(javascript)
|
||||
if err != nil {
|
||||
m.jsString = DefaultJS()
|
||||
}
|
||||
for _, v := range m.pagenames {
|
||||
Handler.HandleFunc(fmt.Sprintf("/%s", v), m.Home)
|
||||
}
|
||||
Handler.HandleFunc("/styles.css", m.CSS)
|
||||
Handler.HandleFunc("/scripts.js", m.JS)
|
||||
if m.password != "" {
|
||||
Handler.HandleFunc("/login", m.Signin)
|
||||
}
|
||||
m.Handler = Handler
|
||||
return &m
|
||||
}
|
260
handler/pages.go
Normal file
260
handler/pages.go
Normal file
@@ -0,0 +1,260 @@
|
||||
package samtunnelhandler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func DefaultCSS() string {
|
||||
return `.server {
|
||||
width: 63%;
|
||||
min-height: 15%;
|
||||
background-color: #9DABD5;
|
||||
float: left;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
.client {
|
||||
width: 63%;
|
||||
min-height: 15%;
|
||||
background-color: #2D4470;
|
||||
float: left;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
.tcpclient {
|
||||
width: 63%;
|
||||
min-height: 15%;
|
||||
background-color: #2D4470;
|
||||
float: left;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
.http {
|
||||
width: 63%;
|
||||
min-height: 15%;
|
||||
background-color: #00ffff;
|
||||
float: left;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
.httpclient {
|
||||
width: 63%;
|
||||
min-height: 15%;
|
||||
background-color: #709fa6;
|
||||
float: left;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
.udpserver {
|
||||
width: 63%;
|
||||
min-height: 15%;
|
||||
background-color: #265ea7;
|
||||
float: left;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
.outproxy {
|
||||
width: 63%;
|
||||
min-height: 15%;
|
||||
background-color: #265ea7;
|
||||
float: left;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
.outproxyhttp {
|
||||
width: 63%;
|
||||
min-height: 15%;
|
||||
background-color: #265ea7;
|
||||
float: left;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
.udpclient {
|
||||
width: 63%;
|
||||
min-height: 15%;
|
||||
background-color: #222187;
|
||||
float: left;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
.vpnserver {
|
||||
width: 63%;
|
||||
min-height: 15%;
|
||||
background-color: #265ea7;
|
||||
float: left;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
.vpnclient {
|
||||
width: 63%;
|
||||
min-height: 15%;
|
||||
background-color: #222187;
|
||||
float: left;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
.TunName {
|
||||
font-weight: bold;
|
||||
}
|
||||
.panel {
|
||||
width: 33%;
|
||||
float: right;
|
||||
}
|
||||
.prop {
|
||||
|
||||
}
|
||||
.prop:hover {
|
||||
box-shadow: inset 0 0 100px 100px rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.global {
|
||||
background-color: #00ffff;
|
||||
}
|
||||
body {
|
||||
background-color: #9e9e9e;
|
||||
color: #070425;
|
||||
font-family: "monospace";
|
||||
font-size: 1rem;
|
||||
}
|
||||
a {
|
||||
color: #080808;
|
||||
}
|
||||
h1 {
|
||||
background-color: #9e9e9e;
|
||||
}
|
||||
span {
|
||||
float: left;
|
||||
display: inline;
|
||||
}
|
||||
textarea {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
resize: none;
|
||||
height: 1rem;
|
||||
float: right;
|
||||
display: inline;
|
||||
}
|
||||
.linkstyle {
|
||||
align-items: normal;
|
||||
background-color: rgba(0,0,0,0);
|
||||
border-color: rgb(0, 0, 238);
|
||||
border-style: none;
|
||||
box-sizing: content-box;
|
||||
color: rgb(0, 0, 238);
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
height: auto;
|
||||
display: inline;
|
||||
padding: 0;
|
||||
perspective-origin: 0 0;
|
||||
text-align: start;
|
||||
text-decoration: underline;
|
||||
transform-origin: 0 0;
|
||||
width: auto;
|
||||
-moz-appearance: none;
|
||||
-webkit-logical-height: 1em; /* Chrome ignores auto, so we have to use this hack to set the correct height */
|
||||
-webkit-logical-width: auto; /* Chrome ignores auto, but here for completeness */
|
||||
}
|
||||
|
||||
@supports (-moz-appearance:none) { /* Mozilla-only */
|
||||
.linkstyle::-moz-focus-inner { /* reset any predefined properties */
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
.linkstyle:focus { /* add outline to focus pseudo-class */
|
||||
outline-style: dotted;
|
||||
outline-width: 1px;
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
func DefaultJS() string {
|
||||
return `function toggle_visibility_id(id) {
|
||||
var e = document.getElementById(id);
|
||||
if(e.style.display == 'block')
|
||||
e.style.display = 'none';
|
||||
else
|
||||
e.style.display = 'block';
|
||||
}
|
||||
function toggle_visibility_class(id) {
|
||||
var elist = document.getElementsByClassName(id)
|
||||
for (let e of elist) {
|
||||
if(e.style.display == 'block')
|
||||
e.style.display = 'none';
|
||||
else
|
||||
e.style.display = 'block';
|
||||
}
|
||||
var tlist = document.getElementsByClassName("TunName")
|
||||
for (let t of tlist) {
|
||||
t.style.display = 'block';
|
||||
}
|
||||
var clist = document.getElementsByClassName("control")
|
||||
for (let c of clist) {
|
||||
c.style.display = 'block';
|
||||
}
|
||||
var slist = document.getElementsByClassName("status")
|
||||
for (let s of slist) {
|
||||
s.style.display = 'block';
|
||||
}
|
||||
}
|
||||
toggle_visibility_class("prop")
|
||||
`
|
||||
}
|
||||
|
||||
func (t *TunnelHandler) ColorSpan(shortid string) string {
|
||||
r := fmt.Sprintf(" <span id=\"toggle%s\" class=\"control\">\n", t.SAMTunnel.ID())
|
||||
r += fmt.Sprintf(" <a href=\"#\" onclick=\"toggle_visibility_class('%s');\"> Show/Hide %s</a><br>\n", t.SAMTunnel.ID(), t.SAMTunnel.ID())
|
||||
r += fmt.Sprintf(" <a href=\"/%s/color\">Tunnel page</a>\n", t.SAMTunnel.ID())
|
||||
r += fmt.Sprintf(" </span>\n")
|
||||
return r
|
||||
}
|
||||
|
||||
func (t *TunnelHandler) ColorForm(shortid, tuntype string) string {
|
||||
r := fmt.Sprintf(" </div>\n\n")
|
||||
r += fmt.Sprintf(" <div id=\"%s\" class=\"%s control panel\" >", shortid+".control", tuntype)
|
||||
|
||||
r += fmt.Sprintf(" <form class=\"linkstyle\" name=\"start\" action=\"/%s\" method=\"post\">", shortid)
|
||||
r += fmt.Sprintf(" <input class=\"linkstyle\" type=\"hidden\" value=\"start\" name=\"action\" />")
|
||||
r += fmt.Sprintf(" <input class=\"linkstyle\" type=\"submit\" value=\".[START]\">")
|
||||
r += fmt.Sprintf(" </form>")
|
||||
|
||||
r += fmt.Sprintf(" <form class=\"linkstyle\" name=\"stop\" action=\"/%s\" method=\"post\">", shortid)
|
||||
r += fmt.Sprintf(" <input class=\"linkstyle\" type=\"hidden\" value=\"stop\" name=\"action\" />")
|
||||
r += fmt.Sprintf(" <input class=\"linkstyle\" type=\"submit\" value=\".[STOP].\">")
|
||||
r += fmt.Sprintf(" </form>")
|
||||
|
||||
r += fmt.Sprintf(" <form class=\"linkstyle\" name=\"restart\" action=\"/%s\" method=\"post\">", shortid)
|
||||
r += fmt.Sprintf(" <input class=\"linkstyle\" type=\"hidden\" value=\"restart\" name=\"action\" />")
|
||||
r += fmt.Sprintf(" <input class=\"linkstyle\" type=\"submit\" value=\"[RESTART].\">")
|
||||
r += fmt.Sprintf(" </form>")
|
||||
|
||||
r += fmt.Sprintf(" <div id=\"%s.status\" class=\"%s status\">.[STATUS].</div>", shortid, shortid)
|
||||
r += fmt.Sprintf(" </div>\n\n")
|
||||
return r
|
||||
}
|
||||
|
||||
func (t *TunnelHandler) ColorWrap(longid, shortid, key, tuntype, prop, value string) string {
|
||||
r := fmt.Sprintf(" <div id=\"%s\" class=\"%s %s %s %s\" >\n", longid, shortid, key, tuntype, prop)
|
||||
r += fmt.Sprintf(" <span id=\"%s\" class=\"key\">%s</span>=", longid, key)
|
||||
r += fmt.Sprintf(" <textarea id=\"%s\" rows=\"1\" class=\"value\">%s</textarea>\n", longid, value)
|
||||
r += fmt.Sprintf(" </div>\n\n")
|
||||
return r
|
||||
}
|
||||
|
||||
func (t *TunnelHandler) ColorDiv(shortid, tuntype string) string {
|
||||
return fmt.Sprintf(" <div id=\"%s\" class=\"%s\" >", t.SAMTunnel.ID(), t.SAMTunnel.GetType())
|
||||
}
|
||||
|
||||
func (m *TunnelHandlerMux) ColorHeader(h http.Handler, r *http.Request, w http.ResponseWriter) {
|
||||
if !strings.HasSuffix(r.URL.Path, "color") {
|
||||
h.ServeHTTP(w, r)
|
||||
} else {
|
||||
fmt.Fprintf(w, "<!DOCTYPE html>\n")
|
||||
fmt.Fprintf(w, "<html>\n")
|
||||
fmt.Fprintf(w, "<head>\n")
|
||||
fmt.Fprintf(w, " <link rel=\"stylesheet\" href=\"/styles.css\">")
|
||||
fmt.Fprintf(w, "</head>\n")
|
||||
fmt.Fprintf(w, "<body>\n")
|
||||
fmt.Fprintf(w, "<h1>\n")
|
||||
w.Write([]byte(fmt.Sprintf("<a href=\"/index.html\">Welcome %s! you are serving %d tunnels. </a>\n", m.user, len(m.tunnels))))
|
||||
fmt.Fprintf(w, "</h1>\n")
|
||||
fmt.Fprintf(w, " <div id=\"toggleall\" class=\"global control\">\n")
|
||||
fmt.Fprintf(w, " <a href=\"#\" onclick=\"toggle_visibility_class('%s');\">Show/Hide %s</a>\n", "prop", "all")
|
||||
fmt.Fprintf(w, " </div>\n")
|
||||
h.ServeHTTP(w, r)
|
||||
fmt.Fprintf(w, " <script src=\"/scripts.js\"></script>\n")
|
||||
fmt.Fprintf(w, "</body>\n")
|
||||
fmt.Fprintf(w, "</html>\n")
|
||||
}
|
||||
}
|
126
handler/tunnelhandler.go
Normal file
126
handler/tunnelhandler.go
Normal file
@@ -0,0 +1,126 @@
|
||||
package samtunnelhandler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
import (
|
||||
"github.com/eyedeekay/sam-forwarder/interface"
|
||||
)
|
||||
|
||||
type TunnelHandler struct {
|
||||
samtunnel.SAMTunnel
|
||||
}
|
||||
|
||||
func (t *TunnelHandler) Printdivf(id, key, value string, rw http.ResponseWriter, req *http.Request) {
|
||||
if key == "" || value == "" {
|
||||
return
|
||||
}
|
||||
ID := t.SAMTunnel.ID()
|
||||
if id != "" {
|
||||
ID = t.SAMTunnel.ID() + "." + id
|
||||
}
|
||||
prop := ""
|
||||
if key != "TunName" {
|
||||
prop = "prop"
|
||||
}
|
||||
fmt.Fprintf(rw, t.ColorWrap(ID, t.SAMTunnel.ID(), key, t.SAMTunnel.GetType(), prop, value))
|
||||
}
|
||||
|
||||
func (t *TunnelHandler) Printf(id, key, value string, rw http.ResponseWriter, req *http.Request) {
|
||||
if key == "" || value == "" {
|
||||
return
|
||||
}
|
||||
ID := t.SAMTunnel.ID()
|
||||
if id != "" {
|
||||
ID = t.SAMTunnel.ID() + "." + id
|
||||
}
|
||||
fmt.Fprintf(rw, "%s=%s\n", ID, t.SAMTunnel.ID())
|
||||
}
|
||||
|
||||
func PropSort(props map[string]string) []string {
|
||||
var slice []string
|
||||
for k, v := range props {
|
||||
slice = append(slice, k+"="+v)
|
||||
}
|
||||
sort.Strings(slice)
|
||||
return slice
|
||||
}
|
||||
|
||||
func (t *TunnelHandler) ControlForm(rw http.ResponseWriter, req *http.Request) {
|
||||
if err := req.ParseForm(); err == nil {
|
||||
if action := req.PostFormValue("action"); action != "" {
|
||||
var err error
|
||||
switch action {
|
||||
case "start":
|
||||
if !t.SAMTunnel.Up() {
|
||||
fmt.Println("Starting tunnel", t.ID())
|
||||
if t.SAMTunnel, err = t.Load(); err == nil {
|
||||
t.Serve()
|
||||
}
|
||||
//return
|
||||
} else {
|
||||
fmt.Println(t.ID(), "already started")
|
||||
req.URL.Path = req.URL.Path + "/color"
|
||||
}
|
||||
case "stop":
|
||||
if t.SAMTunnel.Up() {
|
||||
fmt.Println("Stopping tunnel", t.ID())
|
||||
t.Close()
|
||||
} else {
|
||||
fmt.Println(t.ID(), "already stopped")
|
||||
req.URL.Path = req.URL.Path + "/color"
|
||||
}
|
||||
case "restart":
|
||||
if t.SAMTunnel.Up() {
|
||||
fmt.Println("Stopping tunnel", t.ID())
|
||||
t.Close()
|
||||
fmt.Println("Starting tunnel", t.ID())
|
||||
if t.SAMTunnel, err = t.Load(); err == nil {
|
||||
t.Serve()
|
||||
}
|
||||
return
|
||||
} else {
|
||||
fmt.Println(t.ID(), "stopped.")
|
||||
req.URL.Path = req.URL.Path + "/color"
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TunnelHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
t.ControlForm(rw, req)
|
||||
if strings.HasSuffix(req.URL.Path, "color") {
|
||||
fmt.Fprintf(rw, t.ColorDiv(t.SAMTunnel.ID(), t.SAMTunnel.GetType()))
|
||||
t.Printdivf(t.SAMTunnel.ID(), "TunName", t.SAMTunnel.ID(), rw, req)
|
||||
fmt.Fprintf(rw, t.ColorSpan(t.SAMTunnel.ID()))
|
||||
for _, value := range PropSort(t.SAMTunnel.Props()) {
|
||||
key := strings.SplitN(value, "=", 2)[0]
|
||||
val := strings.SplitN(value, "=", 2)[1]
|
||||
if key != "TunName" {
|
||||
t.Printdivf(key, key, val, rw, req)
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(rw, t.ColorForm(t.SAMTunnel.ID(), t.SAMTunnel.GetType()))
|
||||
} else {
|
||||
t.Printf(t.SAMTunnel.ID(), "TunName", t.SAMTunnel.ID(), rw, req)
|
||||
for _, value := range PropSort(t.SAMTunnel.Props()) {
|
||||
key := strings.SplitN(value, "=", 2)[0]
|
||||
val := strings.SplitN(value, "=", 2)[1]
|
||||
if key != "TunName" {
|
||||
t.Printf(key, key, val, rw, req)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func NewTunnelHandler(ob samtunnel.SAMTunnel, err error) (*TunnelHandler, error) {
|
||||
var t TunnelHandler
|
||||
t.SAMTunnel = ob
|
||||
return &t, err
|
||||
}
|
9903
hashhash/default.go
Normal file
9903
hashhash/default.go
Normal file
File diff suppressed because it is too large
Load Diff
76
hashhash/hashhash.go
Normal file
76
hashhash/hashhash.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package hashhash
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
)
|
||||
|
||||
import (
|
||||
"github.com/boreq/friendlyhash"
|
||||
)
|
||||
|
||||
type Hasher struct {
|
||||
FileName string
|
||||
split []string
|
||||
length int
|
||||
hasher *friendlyhash.FriendlyHash
|
||||
}
|
||||
|
||||
func (h *Hasher) dictionary() []string {
|
||||
if len(h.split) > 0 {
|
||||
return h.split
|
||||
}
|
||||
bytes, _ := ioutil.ReadFile(h.FileName)
|
||||
h.split = strings.Split(string(bytes), "\n")
|
||||
return h.split
|
||||
}
|
||||
|
||||
func (h *Hasher) Friendly(input string) (string, error) {
|
||||
slice, err := h.hasher.Humanize([]byte(input))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strings.Join(slice, " "), nil
|
||||
}
|
||||
|
||||
func (h *Hasher) Unfriendly(input string) (string, error) {
|
||||
slice := strings.Split(input, " ")
|
||||
hash, err := h.hasher.Dehumanize(slice)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(hash), nil
|
||||
}
|
||||
|
||||
func (h *Hasher) Unfriendlyslice(input []string) (string, error) {
|
||||
hash, err := h.hasher.Dehumanize(input)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(hash), nil
|
||||
}
|
||||
|
||||
func NewHasher(length int) (*Hasher, error) {
|
||||
var h Hasher
|
||||
var err error
|
||||
h.FileName = ""
|
||||
h.length = length
|
||||
h.split = Default()
|
||||
h.hasher, err = friendlyhash.New(h.dictionary(), length)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &h, nil
|
||||
}
|
||||
|
||||
func Init(FileName string, length int) (*Hasher, error) {
|
||||
var h Hasher
|
||||
var err error
|
||||
h.FileName = FileName
|
||||
h.length = length
|
||||
h.hasher, err = friendlyhash.New(h.dictionary(), length)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &h, nil
|
||||
}
|
94
i2pkeys/common.go
Normal file
94
i2pkeys/common.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package sfi2pkeys
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/eyedeekay/sam-forwarder/i2pkeys/keys"
|
||||
//"github.com/eyedeekay/sam-forwarder/i2pkeys/password"
|
||||
"github.com/eyedeekay/sam3"
|
||||
"github.com/eyedeekay/sam3/i2pkeys"
|
||||
)
|
||||
|
||||
func Encrypt(i2pkeypath, aeskeypath string) error {
|
||||
return i2pkeyscrypt.EncryptKey(i2pkeypath, aeskeypath)
|
||||
}
|
||||
|
||||
func Decrypt(i2pkeypath, aeskeypath string) error {
|
||||
return i2pkeyscrypt.DecryptKey(i2pkeypath, aeskeypath)
|
||||
}
|
||||
|
||||
func Save(FilePath, TunName, passfile string, SamKeys i2pkeys.I2PKeys) error {
|
||||
if _, err := os.Stat(filepath.Join(FilePath, TunName+".i2pkeys")); os.IsNotExist(err) {
|
||||
file, err := os.Create(filepath.Join(FilePath, TunName+".i2pkeys"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = i2pkeys.StoreKeysIncompat(SamKeys, file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//err = Encrypt(filepath.Join(FilePath, TunName+".i2pkeys"), passfile)
|
||||
//if err != nil {
|
||||
//return err
|
||||
//}
|
||||
return nil
|
||||
}
|
||||
file, err := os.Open(filepath.Join(FilePath, TunName+".i2pkeys"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//err = Decrypt(filepath.Join(FilePath, TunName+".i2pkeys"), passfile)
|
||||
//if err != nil {
|
||||
//return err
|
||||
//}
|
||||
SamKeys, err = i2pkeys.LoadKeysIncompat(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//SamKeys = &tempkeys
|
||||
//err = Encrypt(filepath.Join(FilePath, TunName+".i2pkeys"), passfile)
|
||||
//if err != nil {
|
||||
//return err
|
||||
//}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Load(FilePath, TunName, passfile string, samConn *sam3.SAM, save bool) (i2pkeys.I2PKeys, error) {
|
||||
if !save {
|
||||
return samConn.NewKeys()
|
||||
}
|
||||
if _, err := os.Stat(filepath.Join(FilePath, TunName+".i2pkeys")); os.IsNotExist(err) {
|
||||
log.Println("Generating keys from SAM bridge")
|
||||
SamKeys, err := samConn.NewKeys()
|
||||
if err != nil {
|
||||
return i2pkeys.I2PKeys{}, err
|
||||
}
|
||||
return SamKeys, nil
|
||||
}
|
||||
log.Println("Generating keys from disk")
|
||||
file, err := os.Open(filepath.Join(FilePath, TunName+".i2pkeys"))
|
||||
if err != nil {
|
||||
return i2pkeys.I2PKeys{}, err
|
||||
}
|
||||
//err = Decrypt(filepath.Join(FilePath, TunName+".i2pkeys"), passfile)
|
||||
//if err != nil {
|
||||
//return i2pkeys.I2PKeys{}, err
|
||||
//}
|
||||
return i2pkeys.LoadKeysIncompat(file)
|
||||
}
|
||||
|
||||
func Prop(in string) (string, string) {
|
||||
k := ""
|
||||
v := ""
|
||||
vals := strings.SplitN(in, "=", 2)
|
||||
if len(vals) >= 1 {
|
||||
k = vals[0]
|
||||
}
|
||||
if len(vals) >= 2 {
|
||||
v = vals[1]
|
||||
}
|
||||
return k, v
|
||||
}
|
45
i2pkeys/common_test.go
Normal file
45
i2pkeys/common_test.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package sfi2pkeys
|
||||
|
||||
import (
|
||||
//"os"
|
||||
"log"
|
||||
"testing"
|
||||
//"path/filepath"
|
||||
|
||||
"github.com/eyedeekay/sam3"
|
||||
)
|
||||
|
||||
func TestKeysGenLoad(t *testing.T) {
|
||||
sc, err := sam3.NewSAM("127.0.0.1:7656")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
log.Println("Initialized SAM connection")
|
||||
sk, err := Load("./", "test", "", sc, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
log.Println("Loaded tunnel keys")
|
||||
err = Save("./", "test", "", sk)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKeysGenLoadAgain(t *testing.T) {
|
||||
sc, err := sam3.NewSAM("127.0.0.1:7656")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
log.Println("Saved tunnel keys")
|
||||
sk, err := Load("./", "test", "", sc, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
log.Println("Loaded tunnel keys 2")
|
||||
err = Save("./", "test2", "", sk)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
log.Println("Saved tunnel keys 2")
|
||||
}
|
72
i2pkeys/keys/keys.go
Normal file
72
i2pkeys/keys/keys.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package i2pkeyscrypt
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/gtank/cryptopasta"
|
||||
)
|
||||
|
||||
func bytes(k [32]byte) []byte {
|
||||
var r []byte
|
||||
for _, v := range k {
|
||||
r = append(r, v)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func key(k []byte) *[32]byte {
|
||||
var r [32]byte
|
||||
for i, v := range k {
|
||||
r[i] = v
|
||||
}
|
||||
return &r
|
||||
}
|
||||
|
||||
func EncryptKey(i2pkeypath, aeskeypath string) error {
|
||||
if aeskeypath != "" {
|
||||
if r, e := ioutil.ReadFile(i2pkeypath); e != nil {
|
||||
return e
|
||||
} else {
|
||||
if _, err := os.Stat(aeskeypath); os.IsNotExist(err) {
|
||||
key := cryptopasta.NewEncryptionKey()
|
||||
ioutil.WriteFile(aeskeypath, bytes(*key), 644)
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
if ra, re := ioutil.ReadFile(aeskeypath); re != nil {
|
||||
return e
|
||||
} else {
|
||||
crypted, err := cryptopasta.Encrypt(r, key(ra))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ioutil.WriteFile(i2pkeypath, crypted, 644)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func DecryptKey(i2pkeypath, aeskeypath string) error {
|
||||
if aeskeypath != "" {
|
||||
if r, e := ioutil.ReadFile(i2pkeypath); e != nil {
|
||||
return e
|
||||
} else {
|
||||
if _, err := os.Stat(aeskeypath); os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
if ra, re := ioutil.ReadFile(aeskeypath); re != nil {
|
||||
return e
|
||||
} else {
|
||||
crypted, err := cryptopasta.Decrypt(r, key(ra))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ioutil.WriteFile(i2pkeypath, crypted, 644)
|
||||
}
|
||||
//crypted
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
35
i2pkeys/password/password.go
Normal file
35
i2pkeys/password/password.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package i2pkeyspass
|
||||
|
||||
import (
|
||||
//"io/ioutil"
|
||||
//"os"
|
||||
//"log"
|
||||
//"path/filepath"
|
||||
|
||||
//"github.com/eyedeekay/sam3"
|
||||
//"github.com/gtank/cryptopasta"
|
||||
)
|
||||
|
||||
func bytes(k [32]byte) []byte {
|
||||
var r []byte
|
||||
for _, v := range k {
|
||||
r = append(r, v)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func key(k []byte) *[32]byte {
|
||||
var r [32]byte
|
||||
for i, v := range k {
|
||||
r[i] = v
|
||||
}
|
||||
return &r
|
||||
}
|
||||
|
||||
func EncryptPassword(i2pkeypath, password string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func DecryptPassword(i2pkeypath, password string) error {
|
||||
return nil
|
||||
}
|
26
interface/README.md
Normal file
26
interface/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
Implementing the sam-forwarder interface
|
||||
========================================
|
||||
|
||||
The sam-forwrder interface(used int the Go sense of the word interface) is used
|
||||
to create custom types of tunnels. It's kind of big, and maybe too complex, so
|
||||
subject to change.
|
||||
|
||||
``` go
|
||||
type SAMTunnel interface {
|
||||
GetType() string
|
||||
Cleanup()
|
||||
Print() string
|
||||
Props() map[string]string
|
||||
Search(search string) string
|
||||
Target() string
|
||||
ID() string
|
||||
//Destination() string
|
||||
Base32() string
|
||||
Base64() string
|
||||
Keys() i2pkeys.I2PKeys
|
||||
Serve() error
|
||||
Close() error
|
||||
Up() bool
|
||||
Load() (SAMTunnel, error)
|
||||
}
|
||||
```
|
60
interface/interface.go
Normal file
60
interface/interface.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package samtunnel
|
||||
|
||||
import (
|
||||
"github.com/eyedeekay/sam-forwarder/config"
|
||||
"github.com/eyedeekay/sam3/i2pkeys"
|
||||
)
|
||||
|
||||
// SAMTunnel is an interface comprehensively representing an I2P tunnel over SAM
|
||||
// in Go
|
||||
type SAMTunnel interface {
|
||||
// Config returns the appropriate underlying config object all options, or
|
||||
// the common options passed into a compound tunnel.
|
||||
Config() *i2ptunconf.Conf
|
||||
// Tunnel Options
|
||||
// GetType Get the type of the tunnel in use(server, client, http, udp, etc)
|
||||
GetType() string
|
||||
// Print all the tunnel options as a string
|
||||
Print() string
|
||||
// Props Get a full list of tunnel properties as a map for user display/analysis
|
||||
Props() map[string]string
|
||||
//Search the Props for a common term
|
||||
Search(search string) string
|
||||
//Target The address of the local client or service to forward with a SAM tunnel
|
||||
Target() string
|
||||
//ID The user-chosen tunnel name
|
||||
ID() string
|
||||
//Destination() string
|
||||
|
||||
// Key handling
|
||||
// Get the .b32.i2p address of your service
|
||||
Base32() string
|
||||
// Create a more-readable representation of the .b32.i2p address using English words
|
||||
Base32Readable() string
|
||||
// Get the public base64 address of your I2P service
|
||||
Base64() string
|
||||
// Get all the parts of the keys to your I2P service
|
||||
Keys() i2pkeys.I2PKeys
|
||||
|
||||
// Service Management
|
||||
// Prepare tunnel keys and tunnel options
|
||||
Load() (SAMTunnel, error)
|
||||
// Start the tunnel
|
||||
Serve() error
|
||||
// Stop the tunnel and close all connections
|
||||
Close() error
|
||||
// Stop the tunnel but leave the sockets alone for now
|
||||
Cleanup()
|
||||
// Return "true" if the tunnel is ready to go up.
|
||||
Up() bool
|
||||
}
|
||||
|
||||
// WebUI is an interface which is used to generate a minimal UI. Open to suggestions.
|
||||
type WebUI interface {
|
||||
Title() string
|
||||
URL() string
|
||||
UseWebUI() bool
|
||||
Width() int
|
||||
Height() int
|
||||
Resizable() bool
|
||||
}
|
17
lsk/lsk.go
17
lsk/lsk.go
@@ -1,17 +0,0 @@
|
||||
package encryptedleasesetkeys
|
||||
|
||||
//import (
|
||||
//"crypto/x509"
|
||||
//)
|
||||
|
||||
type LeaseSetKey struct {
|
||||
//LeaseSetPrivateKey
|
||||
//LeaseSetPrivateSigningKey
|
||||
//
|
||||
}
|
||||
|
||||
/*
|
||||
// Get
|
||||
func Get() error {
|
||||
}
|
||||
*/
|
@@ -1,25 +0,0 @@
|
||||
package main
|
||||
|
||||
import "log"
|
||||
|
||||
import "github.com/eyedeekay/sam-forwarder/config"
|
||||
|
||||
func clientMode() {
|
||||
if *udpMode {
|
||||
log.Println("Proxying udp", *targetHost+":"+*targetPort, "to", *targetDestination)
|
||||
forwarder, err := i2ptunconf.NewSAMSSUClientForwarderFromConf(config)
|
||||
if err == nil {
|
||||
forwarder.Serve(*targetDestination)
|
||||
} else {
|
||||
log.Println(err.Error())
|
||||
}
|
||||
} else {
|
||||
log.Println("Proxying tcp", *targetHost+":"+*targetPort, "to", *targetDestination)
|
||||
forwarder, err := i2ptunconf.NewSAMClientForwarderFromConf(config)
|
||||
if err == nil {
|
||||
forwarder.Serve(*targetDestination)
|
||||
} else {
|
||||
log.Println(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
119
main/main.go
119
main/main.go
@@ -1,119 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"strings"
|
||||
)
|
||||
|
||||
import "github.com/eyedeekay/sam-forwarder/config"
|
||||
|
||||
type flagOpts []string
|
||||
|
||||
func (f *flagOpts) String() string {
|
||||
r := ""
|
||||
for _, s := range *f {
|
||||
r += s + ","
|
||||
}
|
||||
return strings.TrimSuffix(r, ",")
|
||||
}
|
||||
|
||||
func (f *flagOpts) Set(s string) error {
|
||||
*f = append(*f, s)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *flagOpts) StringSlice() []string {
|
||||
var r []string
|
||||
for _, s := range *f {
|
||||
r = append(r, s)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
var (
|
||||
saveFile = flag.Bool("save", false, "Use saved file and persist tunnel(If false, tunnel will not persist after program is stopped.")
|
||||
encryptLeaseSet = flag.Bool("encryptlease", true, "Use an encrypted leaseset(true or false)")
|
||||
inAllowZeroHop = flag.Bool("zeroin", false, "Allow zero-hop, non-anonymous tunnels in(true or false)")
|
||||
outAllowZeroHop = flag.Bool("zeroout", false, "Allow zero-hop, non-anonymous tunnels out(true or false)")
|
||||
useCompression = flag.Bool("gzip", false, "Uze gzip(true or false)")
|
||||
reduceIdle = flag.Bool("reduce", false, "Reduce tunnel quantity when idle(true or false)")
|
||||
closeIdle = flag.Bool("close", false, "Close tunnel idle(true or false)")
|
||||
udpMode = flag.Bool("udp", false, "UDP mode(true or false)")
|
||||
client = flag.Bool("client", false, "Client proxy mode(true or false)")
|
||||
injectHeaders = flag.Bool("headers", false, "Inject X-I2P-DEST headers")
|
||||
encryptedLeasesetKeys = flag.String("lsk", "none", "path to saved encrypted leaseset keys")
|
||||
targetDir = flag.String("dir", "", "Directory to save tunnel configuration file in.")
|
||||
iniFile = flag.String("ini", "none", "Use an ini file for configuration(config file options override passed arguments for now.)")
|
||||
targetDestination = flag.String("dest", "none", "Destination for client tunnels. Ignored for service tunnels.")
|
||||
targetHost = flag.String("host", "127.0.0.1", "Target host(Host of service to forward to i2p)")
|
||||
targetPort = flag.String("port", "8081", "Target port(Port of service to forward to i2p)")
|
||||
targetPort443 = flag.String("tlsport", "", "(Currently inoperative. Target TLS port(HTTPS Port of service to forward to i2p)")
|
||||
samHost = flag.String("samhost", "127.0.0.1", "SAM host")
|
||||
samPort = flag.String("samport", "7656", "SAM port")
|
||||
tunName = flag.String("name", "forwarder", "Tunnel name, this must be unique but can be anything.")
|
||||
accessListType = flag.String("access", "none", "Type of access list to use, can be \"whitelist\" \"blacklist\" or \"none\".")
|
||||
inLength = flag.Int("inlen", 3, "Set inbound tunnel length(0 to 7)")
|
||||
outLength = flag.Int("outlen", 3, "Set outbound tunnel length(0 to 7)")
|
||||
inQuantity = flag.Int("incount", 6, "Set inbound tunnel quantity(0 to 15)")
|
||||
outQuantity = flag.Int("outcount", 6, "Set outbound tunnel quantity(0 to 15)")
|
||||
inVariance = flag.Int("invar", 0, "Set inbound tunnel length variance(-7 to 7)")
|
||||
outVariance = flag.Int("outvar", 0, "Set outbound tunnel length variance(-7 to 7)")
|
||||
inBackupQuantity = flag.Int("inback", 4, "Set inbound tunnel backup quantity(0 to 5)")
|
||||
outBackupQuantity = flag.Int("outback", 4, "Set outbound tunnel backup quantity(0 to 5)")
|
||||
reduceIdleTime = flag.Int("reducetime", 600000, "Reduce tunnel quantity after X (milliseconds)")
|
||||
closeIdleTime = flag.Int("closetime", 600000, "Reduce tunnel quantity after X (milliseconds)")
|
||||
reduceIdleQuantity = flag.Int("reducecount", 3, "Reduce idle tunnel quantity to X (0 to 5)")
|
||||
)
|
||||
|
||||
var err error
|
||||
var accessList flagOpts
|
||||
var config *i2ptunconf.Conf
|
||||
|
||||
func main() {
|
||||
flag.Var(&accessList, "accesslist", "Specify an access list member(can be used multiple times)")
|
||||
flag.Parse()
|
||||
|
||||
config = i2ptunconf.NewI2PBlankTunConf()
|
||||
if *iniFile != "none" {
|
||||
config, err = i2ptunconf.NewI2PTunConf(*iniFile)
|
||||
}
|
||||
config.TargetHost = config.GetHost(*targetHost, "127.0.0.1")
|
||||
config.TargetPort = config.GetPort(*targetPort, "8081")
|
||||
config.SaveFile = config.GetSaveFile(*saveFile, true)
|
||||
config.SaveDirectory = config.GetDir(*targetDir, "../")
|
||||
config.SamHost = config.GetSAMHost(*samHost, "127.0.0.1")
|
||||
config.SamPort = config.GetSAMPort(*samPort, "7656")
|
||||
config.TunName = config.GetKeys(*tunName, "forwarder")
|
||||
config.InLength = config.GetInLength(*inLength, 3)
|
||||
config.OutLength = config.GetOutLength(*outLength, 3)
|
||||
config.InVariance = config.GetInVariance(*inVariance, 0)
|
||||
config.OutVariance = config.GetOutVariance(*outVariance, 0)
|
||||
config.InQuantity = config.GetInQuantity(*inQuantity, 6)
|
||||
config.OutQuantity = config.GetOutQuantity(*outQuantity, 6)
|
||||
config.InBackupQuantity = config.GetInBackups(*inBackupQuantity, 5)
|
||||
config.OutBackupQuantity = config.GetOutBackups(*outBackupQuantity, 5)
|
||||
config.EncryptLeaseSet = config.GetEncryptLeaseset(*encryptLeaseSet, false)
|
||||
config.InAllowZeroHop = config.GetInAllowZeroHop(*inAllowZeroHop, false)
|
||||
config.OutAllowZeroHop = config.GetOutAllowZeroHop(*outAllowZeroHop, false)
|
||||
config.UseCompression = config.GetUseCompression(*useCompression, true)
|
||||
config.ReduceIdle = config.GetReduceOnIdle(*reduceIdle, true)
|
||||
config.ReduceIdleTime = config.GetReduceIdleTime(*reduceIdleTime, 600000)
|
||||
config.ReduceIdleQuantity = config.GetReduceIdleQuantity(*reduceIdleQuantity, 2)
|
||||
config.AccessListType = config.GetAccessListType(*accessListType, "none")
|
||||
config.CloseIdle = config.GetCloseOnIdle(*closeIdle, false)
|
||||
config.CloseIdleTime = config.GetCloseIdleTime(*closeIdleTime, 600000)
|
||||
config.Type = config.GetType(*client, *udpMode, *injectHeaders, "server")
|
||||
config.TargetForPort443 = config.GetPort443(*targetPort443, "")
|
||||
|
||||
if config.Client {
|
||||
if *targetDestination == "none" {
|
||||
log.Fatal("Client mode requires you to specify a base32 or jump destination")
|
||||
} else {
|
||||
log.Println("Client mode is still experimental.")
|
||||
clientMode()
|
||||
}
|
||||
} else {
|
||||
serveMode()
|
||||
}
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
package main
|
||||
|
||||
import "log"
|
||||
|
||||
import "github.com/eyedeekay/sam-forwarder/config"
|
||||
|
||||
func serveMode() {
|
||||
if *udpMode {
|
||||
log.Println("Redirecting udp", *targetHost+":"+*targetPort, "to i2p")
|
||||
forwarder, err := i2ptunconf.NewSAMSSUForwarderFromConf(config)
|
||||
if err == nil {
|
||||
forwarder.Serve()
|
||||
} else {
|
||||
log.Println(err.Error())
|
||||
}
|
||||
} else {
|
||||
log.Println("Redirecting tcp", *targetHost+":"+*targetPort, "to i2p")
|
||||
forwarder, err := i2ptunconf.NewSAMForwarderFromConf(config)
|
||||
if err == nil {
|
||||
forwarder.Serve()
|
||||
} else {
|
||||
log.Println(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
28
manager/manager-conn.go
Normal file
28
manager/manager-conn.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package sammanager
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (s *SAMManager) Dial(network, address string) (net.Conn, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *SAMManager) DialContext(ctx context.Context, network, address string) (*net.Conn, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *SAMManager) DialTimeout(network, address string, timeout time.Duration) (net.Conn, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *SAMManager) FileConn(f *os.File) (c net.Conn, err error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *SAMManager) Pipe() (net.Conn, net.Conn) {
|
||||
return nil, nil
|
||||
}
|
136
manager/manager-options.go
Normal file
136
manager/manager-options.go
Normal file
@@ -0,0 +1,136 @@
|
||||
package sammanager
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
import "github.com/eyedeekay/sam-forwarder/config"
|
||||
|
||||
//ManagerOption is a SAMManager Option
|
||||
type ManagerOption func(*SAMManager) error
|
||||
|
||||
//SetManagerFilePath sets the host of the SAMManager's SAM bridge
|
||||
func SetManagerFilePath(s string) func(*SAMManager) error {
|
||||
return func(c *SAMManager) error {
|
||||
c.config.FilePath = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetManagerHost sets the host of the SAMManager's SAM bridge
|
||||
func SetManagerHost(s string) func(*SAMManager) error {
|
||||
return func(c *SAMManager) error {
|
||||
c.ServerHost = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetManagerWebUser sets the host of the SAMManager's SAM bridge
|
||||
func SetManagerWebUser(s string) func(*SAMManager) error {
|
||||
return func(c *SAMManager) error {
|
||||
c.config.UserName = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetManagerWebPass sets the host of the SAMManager's SAM bridge
|
||||
func SetManagerWebPass(s string) func(*SAMManager) error {
|
||||
return func(c *SAMManager) error {
|
||||
c.config.Password = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetManagerPort sets the port of the SAMManager's SAM bridge using a string
|
||||
func SetManagerPort(s string) func(*SAMManager) error {
|
||||
return func(c *SAMManager) error {
|
||||
port, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Invalid Manager Server Port %s; non-number ", s)
|
||||
}
|
||||
if port < 65536 && port > -1 {
|
||||
c.ServerPort = s
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid port")
|
||||
}
|
||||
}
|
||||
|
||||
//SetManagerSAMHost sets the host of the SAMManager's SAM bridge
|
||||
func SetManagerSAMHost(s string) func(*SAMManager) error {
|
||||
return func(c *SAMManager) error {
|
||||
c.SamHost = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetManagerSAMPort sets the port of the SAMManager's SAM bridge using a string
|
||||
func SetManagerSAMPort(s string) func(*SAMManager) error {
|
||||
return func(c *SAMManager) error {
|
||||
port, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Invalid Manager SAM Port %s; non-number", s)
|
||||
}
|
||||
if port < 65536 && port > -1 {
|
||||
c.SamPort = s
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid port")
|
||||
}
|
||||
}
|
||||
|
||||
//SetManagerWebHost sets the host of the SAMManager's SAM bridge
|
||||
func SetManagerWebHost(s string) func(*SAMManager) error {
|
||||
return func(c *SAMManager) error {
|
||||
c.WebHost = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetManagerWebPort sets the port of the SAMManager's SAM bridge using a string
|
||||
func SetManagerWebPort(s string) func(*SAMManager) error {
|
||||
return func(c *SAMManager) error {
|
||||
port, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Invalid Manager SAM Port %s; non-number", s)
|
||||
}
|
||||
if port < 65536 && port > -1 {
|
||||
c.WebPort = s
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid port")
|
||||
}
|
||||
}
|
||||
|
||||
//SetManagerConf sets the host of the SAMManager's SAM bridge
|
||||
func SetManagerConf(s *i2ptunconf.Conf) func(*SAMManager) error {
|
||||
return func(c *SAMManager) error {
|
||||
c.config = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetManagerStart sets the host of the SAMManager's SAM bridge
|
||||
func SetManagerStart(s bool) func(*SAMManager) error {
|
||||
return func(c *SAMManager) error {
|
||||
c.start = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetManagerWeb sets the host of the SAMManager's SAM bridge
|
||||
func SetManagerWeb(s bool) func(*SAMManager) error {
|
||||
return func(c *SAMManager) error {
|
||||
c.UseWeb = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetTunName sets the host of the SAMManager's SAM bridge
|
||||
func SetTunName(s string) func(*SAMManager) error {
|
||||
return func(c *SAMManager) error {
|
||||
c.tunName = s
|
||||
return nil
|
||||
}
|
||||
}
|
361
manager/manager.go
Normal file
361
manager/manager.go
Normal file
@@ -0,0 +1,361 @@
|
||||
package sammanager
|
||||
|
||||
import (
|
||||
//"fmt"
|
||||
"log"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"runtime"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
import (
|
||||
"github.com/eyedeekay/portcheck"
|
||||
"github.com/eyedeekay/sam-forwarder/config"
|
||||
"github.com/eyedeekay/sam-forwarder/config/helpers"
|
||||
"github.com/eyedeekay/sam-forwarder/handler"
|
||||
"github.com/justinas/nosurf"
|
||||
)
|
||||
|
||||
type SAMManager struct {
|
||||
start bool
|
||||
config *i2ptunconf.Conf
|
||||
|
||||
tunName string
|
||||
|
||||
ServerHost string
|
||||
ServerPort string
|
||||
SamHost string
|
||||
SamPort string
|
||||
UseWeb bool
|
||||
WebHost string
|
||||
WebPort string
|
||||
|
||||
cssFile string
|
||||
jsFile string
|
||||
|
||||
handlerMux *samtunnelhandler.TunnelHandlerMux
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
func (s *SAMManager) Cleanup() {
|
||||
for _, k := range s.handlerMux.Tunnels() {
|
||||
k.Cleanup()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SAMManager) UseWebUI() bool {
|
||||
return s.UseWeb
|
||||
}
|
||||
|
||||
func (s *SAMManager) Title() string {
|
||||
return s.config.UserName
|
||||
}
|
||||
|
||||
func (s *SAMManager) Width() int {
|
||||
return 800
|
||||
}
|
||||
|
||||
func (s *SAMManager) Height() int {
|
||||
return 600
|
||||
}
|
||||
|
||||
func (s *SAMManager) Resizable() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *SAMManager) URL() string {
|
||||
return "http://" + s.WebHost + ":" + s.WebPort
|
||||
}
|
||||
|
||||
func User() string {
|
||||
runningUser, _ := user.Current()
|
||||
if runtime.GOOS != "windows" {
|
||||
if runningUser.Uid == "0" {
|
||||
cmd := exec.Command("logname")
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
return string(out)
|
||||
}
|
||||
}
|
||||
return runningUser.Name
|
||||
}
|
||||
|
||||
var runningUser = User()
|
||||
|
||||
func NewSAMManagerFromOptions(opts ...func(*SAMManager) error) (*SAMManager, error) {
|
||||
var s SAMManager
|
||||
s.config = i2ptunconf.NewI2PBlankTunConf()
|
||||
s.config.FilePath = ""
|
||||
s.start = false
|
||||
s.UseWeb = true
|
||||
s.ServerHost = "localhost"
|
||||
s.ServerPort = "8081"
|
||||
s.SamHost = "localhost"
|
||||
s.SamPort = "7656"
|
||||
s.WebHost = "localhost"
|
||||
s.WebPort = "7957"
|
||||
s.tunName = "samcatd-"
|
||||
s.config.UserName = "samcatd"
|
||||
s.config.Password = ""
|
||||
s.cssFile = ""
|
||||
s.jsFile = ""
|
||||
for _, o := range opts {
|
||||
if err := o(&s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
log.Println("MANAGER INITIALIZING")
|
||||
if port, err := strconv.Atoi(s.WebPort); err != nil {
|
||||
log.Println("Error:", err)
|
||||
return nil, err
|
||||
} else {
|
||||
if pc.SCL(port) {
|
||||
log.Println("Service found, launching GUI")
|
||||
s.RunUI()
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
s.handlerMux = samtunnelhandler.NewTunnelHandlerMux(s.WebHost, s.WebPort, s.config.UserName, s.config.Password, s.cssFile, s.jsFile)
|
||||
log.Println("tunnel settings from", s.config.FilePath, "are", s.ServerHost, s.ServerPort, s.SamHost, s.SamPort)
|
||||
var err error
|
||||
if s.config.FilePath != "" {
|
||||
s.config, err = i2ptunconf.NewI2PTunConf(s.config.FilePath)
|
||||
s.config.TargetHost = s.config.GetHost(s.ServerHost, "127.0.0.1")
|
||||
s.config.TargetPort = s.config.GetPort(s.ServerPort, "8081")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Println("Manager found Labels", s.config.Labels)
|
||||
for _, label := range s.config.Labels {
|
||||
log.Println("Processing tunnel for label", label)
|
||||
if t, e := s.config.Get("type", label); e {
|
||||
switch t {
|
||||
case "http":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMForwarderFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
|
||||
log.Println("found http under", label)
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
case "httpclient":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMHTTPClientFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
|
||||
log.Println("found http under", label)
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
case "server":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMForwarderFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
|
||||
log.Println("found server under", label)
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
case "client":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMClientForwarderFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
|
||||
log.Println("found client under", label)
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
case "udpserver":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMDGForwarderFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
|
||||
log.Println("found udpserver under", label)
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
case "udpclient":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMDGClientForwarderFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
|
||||
log.Println("found udpclient under", label)
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
case "eephttpd":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewEepHttpdFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
|
||||
log.Println("found eephttpd under", label)
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
case "outproxy":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewOutProxyFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
|
||||
log.Println("found outproxy under", label)
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
case "outproxyhttp":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewHttpOutProxyFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
|
||||
log.Println("found outproxy under", label)
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
/*case "vpnserver":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(samforwardervpnserver.NewSAMVPNForwarderFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
|
||||
log.Println("found vpnserver under", label)
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
case "vpnclient":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(samforwardervpn.NewSAMVPNClientForwarderFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
|
||||
log.Println("found vpnclient under", label)
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}*/
|
||||
default:
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMForwarderFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
|
||||
log.Println("found server under", label)
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
t, b := s.config.Get("type")
|
||||
if !b {
|
||||
t = "httpclient"
|
||||
//return nil, fmt.Errorf("samcat was instructed to start a tunnel with insufficient default settings information.")
|
||||
}
|
||||
switch t {
|
||||
case "http":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMForwarderFromConf(s.config)); e == nil {
|
||||
log.Println("found default http")
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
case "httpclient":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMHTTPClientFromConf(s.config)); e == nil {
|
||||
log.Println("found default httpclient")
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
case "browserclient":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMBrowserClientFromConf(s.config)); e == nil {
|
||||
log.Println("found default browserclient")
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
case "server":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMForwarderFromConf(s.config)); e == nil {
|
||||
log.Println("found default server")
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
case "client":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMClientForwarderFromConf(s.config)); e == nil {
|
||||
log.Println("found default client")
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
case "udpserver":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMDGForwarderFromConf(s.config)); e == nil {
|
||||
log.Println("found default udpserver")
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
case "udpclient":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMDGClientForwarderFromConf(s.config)); e == nil {
|
||||
log.Println("found default udpclient")
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
case "eephttpd":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewEepHttpdFromConf(s.config)); e == nil {
|
||||
log.Println("found default udpclient")
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
case "outproxy":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewOutProxyFromConf(s.config)); e == nil {
|
||||
log.Println("found default udpclient")
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
case "outproxyhttp":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewHttpOutProxyFromConf(s.config)); e == nil {
|
||||
log.Println("found default udpclient")
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
/*case "vpnserver":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(samforwardervpnserver.NewSAMVPNForwarderFromConf(s.config)); e == nil {
|
||||
log.Println("found default vpnserver")
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
case "vpnclient":
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(samforwardervpn.NewSAMVPNClientForwarderFromConf(s.config)); e == nil {
|
||||
log.Println("found default vpnclient")
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}*/
|
||||
default:
|
||||
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMClientForwarderFromConf(s.config)); e == nil {
|
||||
log.Println("found default client")
|
||||
s.handlerMux = s.handlerMux.Append(f)
|
||||
} else {
|
||||
return nil, e
|
||||
}
|
||||
}
|
||||
}
|
||||
s.handlerMux.Handler = nosurf.New(s.handlerMux.Handler)
|
||||
return &s, nil
|
||||
}
|
||||
|
||||
func NewSAMManager(inifile, servhost, servport, samhost, samport, webhost, webport, cssfile, jsfile string, start, web bool, webuser, webpass string) (*SAMManager, error) {
|
||||
log.Println("tunnel settings", servhost, servport, samhost, samport)
|
||||
return NewSAMManagerFromOptions(
|
||||
SetManagerFilePath(inifile),
|
||||
SetManagerHost(servhost),
|
||||
SetManagerPort(servport),
|
||||
SetManagerSAMHost(samhost),
|
||||
SetManagerSAMPort(samport),
|
||||
SetManagerWebHost(webhost),
|
||||
SetManagerWebPort(webport),
|
||||
SetManagerStart(start),
|
||||
SetManagerWebUser(webuser),
|
||||
SetManagerWebPass(webpass),
|
||||
SetManagerWeb(web),
|
||||
)
|
||||
}
|
||||
|
||||
func NewSAMManagerFromConf(conf *i2ptunconf.Conf, servhost, servport, samhost, samport, webhost, webport, cssfile, jsfile string, start, web bool, webuser, webpass string) (*SAMManager, error) {
|
||||
log.Println("tunnel settings", servhost, servport, samhost, samport)
|
||||
return NewSAMManagerFromOptions(
|
||||
SetManagerConf(conf),
|
||||
SetManagerHost(servhost),
|
||||
SetManagerPort(servport),
|
||||
SetManagerSAMHost(samhost),
|
||||
SetManagerSAMPort(samport),
|
||||
SetManagerWebHost(webhost),
|
||||
SetManagerWebPort(webport),
|
||||
SetManagerStart(start),
|
||||
SetManagerWebUser(webuser),
|
||||
SetManagerWebPass(webpass),
|
||||
SetManagerWeb(web),
|
||||
)
|
||||
}
|
186
manager/manager_test.go
Normal file
186
manager/manager_test.go
Normal file
@@ -0,0 +1,186 @@
|
||||
package sammanager
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func stringify(s []string) string {
|
||||
var p string
|
||||
for _, x := range s {
|
||||
if x != "ntcpserver" && x != "httpserver" && x != "ssuserver" && x != "ntcpclient" && x != "ssuclient" {
|
||||
p += x + ","
|
||||
}
|
||||
}
|
||||
r := strings.Trim(strings.Trim(strings.Replace(p, ",,", ",", -1), " "), "\n")
|
||||
return r
|
||||
}
|
||||
|
||||
func (s *SAMManager) List(search ...string) *[]string {
|
||||
var r []string
|
||||
if search == nil {
|
||||
for index, element := range s.handlerMux.Tunnels() {
|
||||
r = append(r, fmt.Sprintf(" %v. %s", index, element.Print()))
|
||||
}
|
||||
return &r
|
||||
} else if len(search) > 0 {
|
||||
switch search[0] {
|
||||
case "":
|
||||
for index, element := range s.handlerMux.Tunnels() {
|
||||
r = append(r, fmt.Sprintf(" %v. %s", index, element.Print()))
|
||||
}
|
||||
return &r
|
||||
case "ntcpserver":
|
||||
for index, element := range s.handlerMux.Tunnels() {
|
||||
r = append(r, fmt.Sprintf(" %v. %s", index, element.Search(stringify(search))))
|
||||
}
|
||||
return &r
|
||||
case "httpserver":
|
||||
for index, element := range s.handlerMux.Tunnels() {
|
||||
if element.GetType() == "http" {
|
||||
r = append(r, fmt.Sprintf(" %v. %s", index, element.Search(stringify(search))))
|
||||
}
|
||||
}
|
||||
return &r
|
||||
case "ntcpclient":
|
||||
for index, element := range s.handlerMux.Tunnels() {
|
||||
r = append(r, fmt.Sprintf(" %v. %s", index, element.Search(stringify(search))))
|
||||
}
|
||||
return &r
|
||||
case "ssuserver":
|
||||
for index, element := range s.handlerMux.Tunnels() {
|
||||
r = append(r, fmt.Sprintf(" %v. %s", index, element.Search(stringify(search))))
|
||||
}
|
||||
return &r
|
||||
case "ssuclient":
|
||||
for index, element := range s.handlerMux.Tunnels() {
|
||||
r = append(r, fmt.Sprintf(" %v. %s", index, element.Search(stringify(search))))
|
||||
}
|
||||
return &r
|
||||
default:
|
||||
for index, element := range s.handlerMux.Tunnels() {
|
||||
if element.Search(stringify(search)) != "" {
|
||||
r = append(r, fmt.Sprintf(" %v. %s", index, element.Search(stringify(search))))
|
||||
}
|
||||
}
|
||||
for index, element := range s.handlerMux.Tunnels() {
|
||||
if element.Search(stringify(search)) != "" {
|
||||
r = append(r, fmt.Sprintf(" %v. %s", index, element.Search(stringify(search))))
|
||||
}
|
||||
}
|
||||
for index, element := range s.handlerMux.Tunnels() {
|
||||
if element.Search(stringify(search)) != "" {
|
||||
r = append(r, fmt.Sprintf(" %v. %s", index, element.Search(stringify(search))))
|
||||
}
|
||||
}
|
||||
for index, element := range s.handlerMux.Tunnels() {
|
||||
if element.Search(stringify(search)) != "" {
|
||||
r = append(r, fmt.Sprintf(" %v. %s", index, element.Search(stringify(search))))
|
||||
}
|
||||
}
|
||||
return &r
|
||||
}
|
||||
}
|
||||
return &r
|
||||
}
|
||||
|
||||
func TestOption0(t *testing.T) {
|
||||
client, err := NewSAMManagerFromOptions(
|
||||
SetManagerHost("127.0.0.1"),
|
||||
SetManagerSAMHost("127.0.0.1"),
|
||||
SetManagerPort("8080"),
|
||||
SetManagerSAMPort("7656"),
|
||||
SetManagerWebHost("127.0.0.1"),
|
||||
SetManagerWebPort("7958"),
|
||||
SetManagerFilePath("../etc/sam-forwarder/tunnels.ini"),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("NewSAMManager() Error: %q\n", err)
|
||||
}
|
||||
log.Println(client.List())
|
||||
}
|
||||
|
||||
func TestOption1(t *testing.T) {
|
||||
client, err := NewSAMManagerFromOptions(
|
||||
SetManagerHost("127.0.0.1"),
|
||||
SetManagerSAMHost("127.0.0.1"),
|
||||
SetManagerPort("8081"),
|
||||
SetManagerSAMPort("7656"),
|
||||
SetManagerWebHost("127.0.0.1"),
|
||||
SetManagerWebPort("7959"),
|
||||
SetManagerFilePath("../etc/sam-forwarder/tunnels.ini"),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("NewSAMManager() Error: %q\n", err)
|
||||
}
|
||||
log.Println(client.List(""))
|
||||
}
|
||||
|
||||
func TestOption2(t *testing.T) {
|
||||
client, err := NewSAMManagerFromOptions(
|
||||
SetManagerHost("127.0.0.1"),
|
||||
SetManagerSAMHost("127.0.0.1"),
|
||||
SetManagerPort("8082"),
|
||||
SetManagerSAMPort("7656"),
|
||||
SetManagerWebHost("127.0.0.1"),
|
||||
SetManagerWebPort("7960"),
|
||||
SetManagerFilePath("../etc/sam-forwarder/tunnels.ini"),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("NewSAMManager() Error: %q\n", err)
|
||||
}
|
||||
log.Println(client.List("asdgrepgbutwhrsgfbxv"))
|
||||
}
|
||||
|
||||
func TestOption3(t *testing.T) {
|
||||
client, err := NewSAMManagerFromOptions(
|
||||
SetManagerHost("127.0.0.1"),
|
||||
SetManagerSAMHost("127.0.0.1"),
|
||||
SetManagerPort("8083"),
|
||||
SetManagerSAMPort("7656"),
|
||||
SetManagerWebHost("127.0.0.1"),
|
||||
SetManagerWebPort("7961"),
|
||||
SetManagerFilePath("none"),
|
||||
SetManagerFilePath("../etc/sam-forwarder/tunnels.ini"),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("NewSAMManager() Error: %q\n", err)
|
||||
}
|
||||
log.Println(client.List("server"))
|
||||
}
|
||||
|
||||
func TestOption4(t *testing.T) {
|
||||
client, err := NewSAMManagerFromOptions(
|
||||
SetManagerHost("127.0.0.1"),
|
||||
SetManagerSAMHost("127.0.0.1"),
|
||||
SetManagerPort("8083"),
|
||||
SetManagerSAMPort("7656"),
|
||||
SetManagerWebHost("127.0.0.1"),
|
||||
SetManagerWebPort("7961"),
|
||||
SetManagerFilePath("none"),
|
||||
SetManagerFilePath("../etc/sam-forwarder/tunnels.ini"),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("NewSAMManager() Error: %q\n", err)
|
||||
}
|
||||
log.Println(client.List(""))
|
||||
}
|
||||
|
||||
func TestOption5(t *testing.T) {
|
||||
client, err := NewSAMManagerFromOptions(
|
||||
SetManagerHost("127.0.0.1"),
|
||||
SetManagerSAMHost("127.0.0.1"),
|
||||
SetManagerPort("8083"),
|
||||
SetManagerSAMPort("7656"),
|
||||
SetManagerWebHost("127.0.0.1"),
|
||||
SetManagerWebPort("7961"),
|
||||
SetManagerFilePath("none"),
|
||||
SetManagerFilePath("../etc/samcatd/tunnels.ini"),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("NewSAMManager() Error: %q\n", err)
|
||||
}
|
||||
log.Println(client.List(""))
|
||||
}
|
68
manager/nostatic.go
Normal file
68
manager/nostatic.go
Normal file
@@ -0,0 +1,68 @@
|
||||
// +build nostatic
|
||||
// +build !static !cli
|
||||
|
||||
package sammanager
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"time"
|
||||
)
|
||||
|
||||
import (
|
||||
. "github.com/eyedeekay/sam-forwarder/gui"
|
||||
"github.com/zserge/webview"
|
||||
)
|
||||
|
||||
var view webview.WebView
|
||||
|
||||
func (s *SAMManager) RunUI() {
|
||||
view, err = LaunchUI(s)
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
}
|
||||
//go
|
||||
view.Run()
|
||||
}
|
||||
|
||||
func (s *SAMManager) Serve() bool {
|
||||
log.Println("Starting Tunnels()")
|
||||
for _, element := range s.handlerMux.Tunnels() {
|
||||
log.Println("Starting service tunnel", element.ID())
|
||||
go element.Serve()
|
||||
}
|
||||
|
||||
if s.UseWebUI() == true {
|
||||
go s.handlerMux.ListenAndServe()
|
||||
if view, err = LaunchUI(s); err != nil {
|
||||
log.Println("UI Error:", err.Error())
|
||||
return false
|
||||
} else {
|
||||
view.Run()
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
return Exit()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func Exit() bool {
|
||||
Close := false
|
||||
for !Close {
|
||||
time.Sleep(1 * time.Second)
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
go func() {
|
||||
for sig := range c {
|
||||
log.Println(sig)
|
||||
if view != nil {
|
||||
view.Exit()
|
||||
}
|
||||
Close = true
|
||||
}
|
||||
}()
|
||||
}
|
||||
return Close
|
||||
}
|
41
manager/noui.go
Normal file
41
manager/noui.go
Normal file
@@ -0,0 +1,41 @@
|
||||
// +build cli
|
||||
// +build !nostatic !static
|
||||
|
||||
package sammanager
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (s *SAMManager) RunUI() {
|
||||
}
|
||||
|
||||
func (s *SAMManager) Serve() bool {
|
||||
log.Println("Starting Tunnels()")
|
||||
for _, element := range s.handlerMux.Tunnels() {
|
||||
log.Println("Starting service tunnel", element.ID())
|
||||
go element.Serve()
|
||||
}
|
||||
|
||||
return Exit()
|
||||
}
|
||||
|
||||
func Exit() bool {
|
||||
Close := false
|
||||
for !Close {
|
||||
time.Sleep(1 * time.Second)
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
go func() {
|
||||
for sig := range c {
|
||||
log.Println(sig)
|
||||
|
||||
Close = true
|
||||
}
|
||||
}()
|
||||
}
|
||||
return false
|
||||
}
|
65
manager/static.go
Normal file
65
manager/static.go
Normal file
@@ -0,0 +1,65 @@
|
||||
// +build static
|
||||
// +build !nostatic !cli
|
||||
|
||||
package sammanager
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"time"
|
||||
)
|
||||
|
||||
import (
|
||||
. "github.com/eyedeekay/sam-forwarder/gui"
|
||||
"github.com/zserge/lorca"
|
||||
)
|
||||
|
||||
var view lorca.UI
|
||||
|
||||
func (s *SAMManager) RunUI() {
|
||||
view, err = LaunchUI(s)
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SAMManager) Serve() bool {
|
||||
log.Println("Starting Tunnels()")
|
||||
for _, element := range s.handlerMux.Tunnels() {
|
||||
log.Println("Starting service tunnel", element.ID())
|
||||
go element.Serve()
|
||||
}
|
||||
|
||||
if s.UseWebUI() == true {
|
||||
go s.handlerMux.ListenAndServe()
|
||||
if view, err = LaunchUI(s); err != nil {
|
||||
log.Println(err.Error())
|
||||
return Exit()
|
||||
} else {
|
||||
return Exit()
|
||||
}
|
||||
} else {
|
||||
return Exit()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func Exit() bool {
|
||||
Close := false
|
||||
for !Close {
|
||||
time.Sleep(1 * time.Second)
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
go func() {
|
||||
for sig := range c {
|
||||
log.Println(sig)
|
||||
if view != nil {
|
||||
view.Close()
|
||||
}
|
||||
Close = true
|
||||
}
|
||||
}()
|
||||
}
|
||||
return Close
|
||||
}
|
450
options/options.go
Normal file
450
options/options.go
Normal file
@@ -0,0 +1,450 @@
|
||||
package samoptions
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/eyedeekay/sam-forwarder/interface"
|
||||
)
|
||||
|
||||
//Option is a SAMForwarder Option
|
||||
type Option func(samtunnel.SAMTunnel) error
|
||||
|
||||
//SetFilePath sets the path to save the config file at.
|
||||
func SetFilePath(s string) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
c.Config().FilePath = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetType sets the type of the forwarder server
|
||||
func SetType(s string) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if s == "http" {
|
||||
c.Config().Type = s
|
||||
return nil
|
||||
} else {
|
||||
c.Config().Type = "server"
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//SetSigType sets the type of the forwarder server
|
||||
func SetSigType(s string) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if s == "" {
|
||||
c.Config().SigType = ""
|
||||
} else if s == "DSA_SHA1" {
|
||||
c.Config().SigType = "DSA_SHA1"
|
||||
} else if s == "ECDSA_SHA256_P256" {
|
||||
c.Config().SigType = "ECDSA_SHA256_P256"
|
||||
} else if s == "ECDSA_SHA384_P384" {
|
||||
c.Config().SigType = "ECDSA_SHA384_P384"
|
||||
} else if s == "ECDSA_SHA512_P521" {
|
||||
c.Config().SigType = "ECDSA_SHA512_P521"
|
||||
} else if s == "EdDSA_SHA512_Ed25519" {
|
||||
c.Config().SigType = "EdDSA_SHA512_Ed25519"
|
||||
} else {
|
||||
c.Config().SigType = "EdDSA_SHA512_Ed25519"
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetSaveFile tells the router to save the tunnel's keys long-term
|
||||
func SetSaveFile(b bool) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
c.Config().SaveFile = b
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetHost sets the host of the service to forward
|
||||
func SetHost(s string) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
c.Config().TargetHost = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetPort sets the port of the service to forward
|
||||
func SetPort(s string) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
port, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Invalid TCP Server Target Port %s; non-number ", s)
|
||||
}
|
||||
if port < 65536 && port > -1 {
|
||||
c.Config().TargetPort = s
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid port")
|
||||
}
|
||||
}
|
||||
|
||||
//SetSAMHost sets the host of the SAMForwarder's SAM bridge
|
||||
func SetSAMHost(s string) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
c.Config().SamHost = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetSAMPort sets the port of the SAMForwarder's SAM bridge using a string
|
||||
func SetSAMPort(s string) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
port, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Invalid SAM Port %s; non-number", s)
|
||||
}
|
||||
if port < 65536 && port > -1 {
|
||||
c.Config().SamPort = s
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid port")
|
||||
}
|
||||
}
|
||||
|
||||
//SetName sets the host of the SAMForwarder's SAM bridge
|
||||
func SetName(s string) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
c.Config().TunName = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetInLength sets the number of hops inbound
|
||||
func SetInLength(u int) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if u < 7 && u >= 0 {
|
||||
c.Config().InLength = u
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid inbound tunnel length")
|
||||
}
|
||||
}
|
||||
|
||||
//SetOutLength sets the number of hops outbound
|
||||
func SetOutLength(u int) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if u < 7 && u >= 0 {
|
||||
c.Config().OutLength = u
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid outbound tunnel length")
|
||||
}
|
||||
}
|
||||
|
||||
//SetInVariance sets the variance of a number of hops inbound
|
||||
func SetInVariance(i int) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if i < 7 && i > -7 {
|
||||
c.Config().InVariance = i
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid inbound tunnel length")
|
||||
}
|
||||
}
|
||||
|
||||
//SetOutVariance sets the variance of a number of hops outbound
|
||||
func SetOutVariance(i int) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if i < 7 && i > -7 {
|
||||
c.Config().OutVariance = i
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid outbound tunnel variance")
|
||||
}
|
||||
}
|
||||
|
||||
//SetInQuantity sets the inbound tunnel quantity
|
||||
func SetInQuantity(u int) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if u <= 16 && u > 0 {
|
||||
c.Config().InQuantity = u
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid inbound tunnel quantity")
|
||||
}
|
||||
}
|
||||
|
||||
//SetOutQuantity sets the outbound tunnel quantity
|
||||
func SetOutQuantity(u int) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if u <= 16 && u > 0 {
|
||||
c.Config().OutQuantity = u
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid outbound tunnel quantity")
|
||||
}
|
||||
}
|
||||
|
||||
//SetInBackups sets the inbound tunnel backups
|
||||
func SetInBackups(u int) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if u < 6 && u >= 0 {
|
||||
c.Config().InBackupQuantity = u
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid inbound tunnel backup quantity")
|
||||
}
|
||||
}
|
||||
|
||||
//SetOutBackups sets the inbound tunnel backups
|
||||
func SetOutBackups(u int) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if u < 6 && u >= 0 {
|
||||
c.Config().OutBackupQuantity = u
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid outbound tunnel backup quantity")
|
||||
}
|
||||
}
|
||||
|
||||
//SetEncrypt tells the router to use an encrypted leaseset
|
||||
func SetEncrypt(b bool) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if b {
|
||||
c.Config().EncryptLeaseSet = true
|
||||
return nil
|
||||
}
|
||||
c.Config().EncryptLeaseSet = false
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetLeaseSetKey sets the host of the SAMForwarder's SAM bridge
|
||||
func SetLeaseSetKey(s string) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
c.Config().LeaseSetKey = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetLeaseSetPrivateKey sets the host of the SAMForwarder's SAM bridge
|
||||
func SetLeaseSetPrivateKey(s string) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
c.Config().LeaseSetPrivateKey = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetLeaseSetPrivateSigningKey sets the host of the SAMForwarder's SAM bridge
|
||||
func SetLeaseSetPrivateSigningKey(s string) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
c.Config().LeaseSetPrivateSigningKey = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetMessageReliability sets the host of the SAMForwarder's SAM bridge
|
||||
func SetMessageReliability(s string) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
c.Config().MessageReliability = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetAllowZeroIn tells the tunnel to accept zero-hop peers
|
||||
func SetAllowZeroIn(b bool) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if b {
|
||||
c.Config().InAllowZeroHop = true
|
||||
return nil
|
||||
}
|
||||
c.Config().InAllowZeroHop = false
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetAllowZeroOut tells the tunnel to accept zero-hop peers
|
||||
func SetAllowZeroOut(b bool) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if b {
|
||||
c.Config().OutAllowZeroHop = true
|
||||
return nil
|
||||
}
|
||||
c.Config().OutAllowZeroHop = false
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetCompress tells clients to use compression
|
||||
func SetCompress(b bool) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if b {
|
||||
c.Config().UseCompression = true
|
||||
return nil
|
||||
}
|
||||
c.Config().UseCompression = false
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetFastRecieve tells clients to use compression
|
||||
func SetFastRecieve(b bool) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if b {
|
||||
c.Config().FastRecieve = true
|
||||
return nil
|
||||
}
|
||||
c.Config().FastRecieve = false
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetReduceIdle tells the connection to reduce it's tunnels during extended idle time.
|
||||
func SetReduceIdle(b bool) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if b {
|
||||
c.Config().ReduceIdle = true
|
||||
return nil
|
||||
}
|
||||
c.Config().ReduceIdle = false
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetReduceIdleTime sets the time to wait before reducing tunnels to idle levels
|
||||
func SetReduceIdleTime(u int) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
c.Config().ReduceIdleTime = 300000
|
||||
if u >= 6 {
|
||||
c.Config().ReduceIdleTime = (u * 60) * 1000
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid reduce idle timeout(Measured in minutes) %v", u)
|
||||
}
|
||||
}
|
||||
|
||||
//SetReduceIdleTimeMs sets the time to wait before reducing tunnels to idle levels in milliseconds
|
||||
func SetReduceIdleTimeMs(u int) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
c.Config().ReduceIdleTime = 300000
|
||||
if u >= 300000 {
|
||||
c.Config().ReduceIdleTime = u
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid reduce idle timeout(Measured in milliseconds) %v", u)
|
||||
}
|
||||
}
|
||||
|
||||
//SetReduceIdleQuantity sets minimum number of tunnels to reduce to during idle time
|
||||
func SetReduceIdleQuantity(u int) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if u < 5 {
|
||||
c.Config().ReduceIdleQuantity = u
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid reduce tunnel quantity")
|
||||
}
|
||||
}
|
||||
|
||||
//SetCloseIdle tells the connection to close it's tunnels during extended idle time.
|
||||
func SetCloseIdle(b bool) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if b {
|
||||
c.Config().CloseIdle = true
|
||||
return nil
|
||||
}
|
||||
c.Config().CloseIdle = false
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetCloseIdleTime sets the time to wait before closing tunnels to idle levels
|
||||
func SetCloseIdleTime(u int) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
c.Config().CloseIdleTime = 300000
|
||||
if u >= 6 {
|
||||
c.Config().CloseIdleTime = (u * 60) * 1000
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid close idle timeout(Measured in minutes) %v", u)
|
||||
}
|
||||
}
|
||||
|
||||
//SetCloseIdleTimeMs sets the time to wait before closing tunnels to idle levels in milliseconds
|
||||
func SetCloseIdleTimeMs(u int) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
c.Config().CloseIdleTime = 300000
|
||||
if u >= 300000 {
|
||||
c.Config().CloseIdleTime = u
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid close idle timeout(Measured in milliseconds) %v", u)
|
||||
}
|
||||
}
|
||||
|
||||
//SetAccessListType tells the system to treat the AccessList as a allowlist
|
||||
func SetAccessListType(s string) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if s == "allowlist" {
|
||||
c.Config().AccessListType = "allowlist"
|
||||
return nil
|
||||
} else if s == "blocklist" {
|
||||
c.Config().AccessListType = "blocklist"
|
||||
return nil
|
||||
} else if s == "none" {
|
||||
c.Config().AccessListType = ""
|
||||
return nil
|
||||
} else if s == "" {
|
||||
c.Config().AccessListType = ""
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid Access list type(allowlist, blocklist, none)")
|
||||
}
|
||||
}
|
||||
|
||||
//SetAccessList tells the system to treat the AccessList as a allowlist
|
||||
func SetAccessList(s []string) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
if len(s) > 0 {
|
||||
for _, a := range s {
|
||||
c.Config().AccessList = append(c.Config().AccessList, a)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetTargetForPort sets the port of the SAMForwarder's SAM bridge using a string
|
||||
/*func SetTargetForPort443(s string) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
port, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Invalid Target Port %s; non-number ", s)
|
||||
}
|
||||
if port < 65536 && port > -1 {
|
||||
c.Config().TargetForPort443 = s
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Invalid port")
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//SetKeyFile sets
|
||||
func SetKeyFile(s string) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
c.Config().KeyFilePath = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func SetPassword(s string) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
c.Config().KeyFilePath = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func SetDestination(s string) func(samtunnel.SAMTunnel) error {
|
||||
return func(c samtunnel.SAMTunnel) error {
|
||||
c.Config().ClientDest = s
|
||||
return nil
|
||||
}
|
||||
}
|
261
samcatd/main.go
Normal file
261
samcatd/main.go
Normal file
@@ -0,0 +1,261 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
import (
|
||||
"crawshaw.io/littleboss"
|
||||
"github.com/eyedeekay/sam-forwarder/config"
|
||||
"github.com/eyedeekay/sam-forwarder/hashhash"
|
||||
"github.com/eyedeekay/sam-forwarder/manager"
|
||||
)
|
||||
|
||||
type flagOpts []string
|
||||
|
||||
func (f *flagOpts) String() string {
|
||||
r := ""
|
||||
for _, s := range *f {
|
||||
r += s + ","
|
||||
}
|
||||
return strings.TrimSuffix(r, ",")
|
||||
}
|
||||
|
||||
func (f *flagOpts) Set(s string) error {
|
||||
*f = append(*f, s)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *flagOpts) StringSlice() []string {
|
||||
var r []string
|
||||
for _, s := range *f {
|
||||
r = append(r, s)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
var (
|
||||
saveFile = flag.Bool("t", false,
|
||||
"Use saved file and persist tunnel(If false, tunnel will not persist after program is stopped.")
|
||||
startUp = flag.Bool("s", false,
|
||||
"Start a tunnel with the passed parameters(Otherwise, they will be treated as default values.)")
|
||||
encryptLeaseSet = flag.Bool("l", true,
|
||||
"Use an encrypted leaseset(true or false)")
|
||||
encryptKeyFiles = flag.String("cr", "",
|
||||
"Encrypt/decrypt the key files with a passfile")
|
||||
inAllowZeroHop = flag.Bool("zi", false,
|
||||
"Allow zero-hop, non-anonymous tunnels in(true or false)")
|
||||
outAllowZeroHop = flag.Bool("zo", false,
|
||||
"Allow zero-hop, non-anonymous tunnels out(true or false)")
|
||||
useCompression = flag.Bool("z", false,
|
||||
"Uze gzip(true or false)")
|
||||
reduceIdle = flag.Bool("r", false,
|
||||
"Reduce tunnel quantity when idle(true or false)")
|
||||
closeIdle = flag.Bool("x", false,
|
||||
"Close tunnel group after idle(true or false)")
|
||||
udpMode = flag.Bool("u", false,
|
||||
"UDP mode(true or false)")
|
||||
client = flag.Bool("c", false,
|
||||
"Client proxy mode(true or false)")
|
||||
injectHeaders = flag.Bool("ih", false,
|
||||
"Inject X-I2P-DEST headers")
|
||||
webAdmin = flag.Bool("w", true,
|
||||
"Start web administration interface")
|
||||
sigType = flag.String("st", "",
|
||||
"Signature type")
|
||||
webPort = flag.String("wp", "7957",
|
||||
"Web port")
|
||||
webUser = flag.String("webuser", "samcatd",
|
||||
"Web interface username")
|
||||
webPass = flag.String("webpass", "",
|
||||
"Web interface password")
|
||||
webCSS = flag.String("css", "css/styles.css",
|
||||
"custom CSS for web interface")
|
||||
webJS = flag.String("js", "js/scripts.js",
|
||||
"custom JS for web interface")
|
||||
webDir = flag.String("wwwdir", "./www",
|
||||
"Default www directory to serve if starting eephttpd")
|
||||
leaseSetKey = flag.String("k", "none",
|
||||
"key for encrypted leaseset")
|
||||
leaseSetPrivateKey = flag.String("pk", "none",
|
||||
"private key for encrypted leaseset")
|
||||
leaseSetPrivateSigningKey = flag.String("psk", "none",
|
||||
"private signing key for encrypted leaseset")
|
||||
targetDir = flag.String("d", "",
|
||||
"Directory to save tunnel configuration file in.")
|
||||
targetDest = flag.String("de", "",
|
||||
"Destination to connect client's to by default.")
|
||||
iniFile = flag.String("f", "none",
|
||||
"Use an ini file for configuration(config file options override passed arguments for now.)")
|
||||
/*targetDestination = flag.String("i", "none",
|
||||
"Destination for client tunnels. Ignored for service tunnels.")*/
|
||||
targetHost = flag.String("h", "127.0.0.1",
|
||||
"Target host(Host of service to forward to i2p)")
|
||||
targetPort = flag.String("p", "8081",
|
||||
"Target port(Port of service to forward to i2p)")
|
||||
targetPort443 = flag.String("tls", "",
|
||||
"(Currently inoperative. Target TLS port(HTTPS Port of service to forward to i2p)")
|
||||
peoplehash = flag.String("hashhash", "",
|
||||
"32-word mnemonic representing a .b32.i2p address(will output .b32.i2p address and quit)")
|
||||
samHost = flag.String("sh", "127.0.0.1",
|
||||
"SAM host")
|
||||
samPort = flag.String("sp", "7656",
|
||||
"SAM port")
|
||||
tunName = flag.String("n", "forwarder",
|
||||
"Tunnel name, this must be unique but can be anything.")
|
||||
accessListType = flag.String("a", "none",
|
||||
"Type of access list to use, can be \"allowlist\" \"blocklist\" or \"none\".")
|
||||
inLength = flag.Int("il", 3,
|
||||
"Set inbound tunnel length(0 to 7)")
|
||||
outLength = flag.Int("ol", 3,
|
||||
"Set outbound tunnel length(0 to 7)")
|
||||
inQuantity = flag.Int("iq", 6,
|
||||
"Set inbound tunnel quantity(0 to 15)")
|
||||
outQuantity = flag.Int("oq", 6,
|
||||
"Set outbound tunnel quantity(0 to 15)")
|
||||
inVariance = flag.Int("iv", 0,
|
||||
"Set inbound tunnel length variance(-7 to 7)")
|
||||
outVariance = flag.Int("ov", 0,
|
||||
"Set outbound tunnel length variance(-7 to 7)")
|
||||
inBackupQuantity = flag.Int("ib", 2,
|
||||
"Set inbound tunnel backup quantity(0 to 5)")
|
||||
outBackupQuantity = flag.Int("ob", 2,
|
||||
"Set outbound tunnel backup quantity(0 to 5)")
|
||||
reduceIdleTime = flag.Int("rt", 600000,
|
||||
"Reduce tunnel quantity after X (milliseconds)")
|
||||
closeIdleTime = flag.Int("ct", 600000,
|
||||
"Close tunnel group after X (milliseconds)")
|
||||
reduceIdleQuantity = flag.Int("rq", 3,
|
||||
"Reduce idle tunnel quantity to X (0 to 5)")
|
||||
readKeys = flag.String("conv", "", "Display the base32 and base64 values of a specified .i2pkeys file")
|
||||
)
|
||||
|
||||
var (
|
||||
err error
|
||||
accessList flagOpts
|
||||
config *i2ptunconf.Conf
|
||||
)
|
||||
|
||||
func main() {
|
||||
lb := littleboss.New("service-name")
|
||||
lb.Run(func(ctx context.Context) {
|
||||
lbMain(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
func lbMain(ctx context.Context) {
|
||||
flag.Var(&accessList, "accesslist", "Specify an access list member(can be used multiple times)")
|
||||
flag.Parse()
|
||||
|
||||
if *readKeys != "" {
|
||||
|
||||
}
|
||||
|
||||
if *peoplehash != "" {
|
||||
slice := strings.Split(*peoplehash, " ")
|
||||
if length, err := strconv.Atoi(slice[len(slice)-1]); err == nil {
|
||||
Hasher, err := hashhash.NewHasher(length)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
lhash, err := Hasher.Unfriendlyslice(slice[0 : len(slice)-2])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
log.Println(lhash + ".b32.i2p")
|
||||
} else {
|
||||
Hasher, err := hashhash.NewHasher(52)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
lhash, err := Hasher.Unfriendlyslice(slice)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
log.Println(lhash + ".b32.i2p")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
config = &i2ptunconf.Conf{}
|
||||
if *iniFile != "none" && *iniFile != "" {
|
||||
config, err = i2ptunconf.NewI2PTunConf(*iniFile)
|
||||
} else {
|
||||
config = i2ptunconf.NewI2PBlankTunConf()
|
||||
*startUp = true
|
||||
}
|
||||
config.TargetHost = config.GetHost(*targetHost, "127.0.0.1")
|
||||
config.TargetPort = config.GetPort(*targetPort, "8081")
|
||||
config.FilePath = *iniFile
|
||||
config.SaveFile = config.GetSaveFile(*saveFile, true)
|
||||
config.SaveDirectory = config.GetDir(*targetDir, "../")
|
||||
config.SamHost = config.GetSAMHost(*samHost, "127.0.0.1")
|
||||
config.SamPort = config.GetSAMPort(*samPort, "7656")
|
||||
config.TunName = config.GetKeys(*tunName, "forwarder")
|
||||
config.SigType = config.GetSigType(*sigType, "EdDSA_SHA512_Ed25519")
|
||||
config.InLength = config.GetInLength(*inLength, 3)
|
||||
config.OutLength = config.GetOutLength(*outLength, 3)
|
||||
config.InVariance = config.GetInVariance(*inVariance, 0)
|
||||
config.OutVariance = config.GetOutVariance(*outVariance, 0)
|
||||
config.InQuantity = config.GetInQuantity(*inQuantity, 6)
|
||||
config.OutQuantity = config.GetOutQuantity(*outQuantity, 6)
|
||||
config.InBackupQuantity = config.GetInBackups(*inBackupQuantity, 5)
|
||||
config.OutBackupQuantity = config.GetOutBackups(*outBackupQuantity, 5)
|
||||
config.EncryptLeaseSet = config.GetEncryptLeaseset(*encryptLeaseSet, false)
|
||||
config.LeaseSetKey = config.GetLeasesetKey(*leaseSetKey, "")
|
||||
config.LeaseSetPrivateKey = config.GetLeasesetPrivateKey(*leaseSetPrivateKey, "")
|
||||
config.LeaseSetPrivateSigningKey = config.GetLeasesetPrivateSigningKey(*leaseSetPrivateSigningKey, "")
|
||||
config.InAllowZeroHop = config.GetInAllowZeroHop(*inAllowZeroHop, false)
|
||||
config.OutAllowZeroHop = config.GetOutAllowZeroHop(*outAllowZeroHop, false)
|
||||
config.UseCompression = config.GetUseCompression(*useCompression, true)
|
||||
config.ReduceIdle = config.GetReduceOnIdle(*reduceIdle, true)
|
||||
config.ReduceIdleTime = config.GetReduceIdleTime(*reduceIdleTime, 600000)
|
||||
config.ReduceIdleQuantity = config.GetReduceIdleQuantity(*reduceIdleQuantity, 2)
|
||||
config.AccessListType = config.GetAccessListType(*accessListType, "none")
|
||||
config.CloseIdle = config.GetCloseOnIdle(*closeIdle, false)
|
||||
config.CloseIdleTime = config.GetCloseIdleTime(*closeIdleTime, 600000)
|
||||
config.Type = config.GetTypes(*client, *udpMode, *injectHeaders, "server")
|
||||
config.TargetForPort443 = config.GetPort443(*targetPort443, "")
|
||||
config.KeyFilePath = config.GetKeyFile(*encryptKeyFiles, "")
|
||||
config.ClientDest = config.GetClientDest(*targetDest, "", "")
|
||||
config.UserName = config.GetUserName(*webUser, "samcatd")
|
||||
config.Password = config.GetPassword(*webPass, "")
|
||||
config.ServeDirectory = config.GetWWWDir(*webDir, "./www")
|
||||
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
|
||||
if manager, err := sammanager.NewSAMManagerFromConf(
|
||||
config,
|
||||
config.TargetHost,
|
||||
config.TargetPort,
|
||||
config.SamHost,
|
||||
config.SamPort,
|
||||
"localhost",
|
||||
*webPort,
|
||||
*webCSS,
|
||||
*webJS,
|
||||
*startUp,
|
||||
*webAdmin,
|
||||
config.UserName,
|
||||
config.Password,
|
||||
); err == nil {
|
||||
go func() {
|
||||
for sig := range c {
|
||||
if sig == os.Interrupt {
|
||||
manager.Cleanup()
|
||||
}
|
||||
}
|
||||
}()
|
||||
manager.Serve()
|
||||
} else {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ctx.Done()
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user